Grimoire Transfusion

The Grimoire's transfusion spell allows you to channel your resources unidirectionally

Лицензия

Лицензия

Группа

Группа

com.skoumal.grimoire
Идентификатор

Идентификатор

transfusion-environment
Последняя версия

Последняя версия

1.1.0-alpha01
Дата

Дата

Тип

Тип

aar
Описание

Описание

Grimoire Transfusion
The Grimoire's transfusion spell allows you to channel your resources unidirectionally
Ссылка на сайт

Ссылка на сайт

https://github.com/skoumalcz/grimoire-transfusion
Система контроля версий

Система контроля версий

https://github.com/skoumalcz/grimoire-transfusion

Скачать transfusion-environment

Как подключить последнюю версию

<!-- https://jarcasting.com/artifacts/com.skoumal.grimoire/transfusion-environment/ -->
<dependency>
    <groupId>com.skoumal.grimoire</groupId>
    <artifactId>transfusion-environment</artifactId>
    <version>1.1.0-alpha01</version>
    <type>aar</type>
</dependency>
// https://jarcasting.com/artifacts/com.skoumal.grimoire/transfusion-environment/
implementation 'com.skoumal.grimoire:transfusion-environment:1.1.0-alpha01'
// https://jarcasting.com/artifacts/com.skoumal.grimoire/transfusion-environment/
implementation ("com.skoumal.grimoire:transfusion-environment:1.1.0-alpha01")
'com.skoumal.grimoire:transfusion-environment:aar:1.1.0-alpha01'
<dependency org="com.skoumal.grimoire" name="transfusion-environment" rev="1.1.0-alpha01">
  <artifact name="transfusion-environment" type="aar" />
</dependency>
@Grapes(
@Grab(group='com.skoumal.grimoire', module='transfusion-environment', version='1.1.0-alpha01')
)
libraryDependencies += "com.skoumal.grimoire" % "transfusion-environment" % "1.1.0-alpha01"
[com.skoumal.grimoire/transfusion-environment "1.1.0-alpha01"]

Зависимости

compile (3)

Идентификатор библиотеки Тип Версия
androidx.databinding » databinding-common jar 4.1.1
androidx.databinding » databinding-runtime jar 4.1.1
androidx.databinding » databinding-adapters jar 4.1.1

runtime (3)

Идентификатор библиотеки Тип Версия
org.jetbrains.kotlin : kotlin-stdlib jar 1.4.20
org.jetbrains.kotlin : kotlin-reflect jar 1.4.20
org.jetbrains.kotlinx : kotlinx-coroutines-android jar 1.4.1

Модули Проекта

Данный проект не имеет модулей.

GrimoireTransfusion

Why Transfusion?

  • :)

    Well you need some parts of your app to talk to each other.

Observer

Observer works as a drop-in utility to bindable objects. The main benefit is that you don't need to use heavy ObservableFields which collect listeners within them - often overlapping with other ObservableFields.

With observer you're able to use native kotlin delegation for pretty syntax and improved performance.

class MyBindableObject : Observer by Observer.getDefault() {

    @get:Bindable
    var myVariable by observable(Any(), BR.myVariable)
        private set

    fun onStateChanged() {
        // todo mutate myVariable
    }

}

Transfusion + extensions

Transfusion offers unidirectional communication within a specific scope of items provided. One object always serves as provider, other as consumer. Default implementation allows multiple consumers, however you should be aware that this can bring undesired consequences.

data class MyState(
    val isExpanded: Boolean = false
)

class MyViewModel : ViewModel(), Transfusion<MyState> by Transfusion.getDefault() {

    private var state = MyState()

    fun onExpand() {
        state = state.copy(isExpanded = true)
        state.offer()
    }

}

class MyFragment : Fragment() {

    private val viewModel: MyViewModel by viewModels()

    override fun onViewCreated(/**/) {
        lifecycleScope.launch {
            viewModel.openFlow().collect { /* it: MyState -> */ }
        }
    }

}

What's shown above is a very raw example. However that's not the way you're gonna be using transfusion since we provide extensions Here's how to use them.

class MyViewModel : ViewModel(), Transfusion<Cell> by Transfusion.getDefault() {

    fun onExpand() = MyFragment.Expand().offer()

}

class MyFragment : Fragment() {

    private val viewModel: MyViewModel by viewModels()
    private lateinit var consumer: TransfusionFlowConsumer<Cell>

    override fun onViewCreated(/**/) {
        consumer = viewModel.openFlow().consumeIn(this)
    }

    override fun onDestroyView() {
        consumer.stop()
    }

    private fun doExpand() {}

    class Expand : Cell(), InFragment {
        override fun invoke(fragment: Fragment) {
            if(fragment !is MyFragment) return
            fragment.doExpand()
        }
    }

}

Notice that by using this pattern of having Cell classes inside the Fragment, we are able to use private methods. This is very much beneficial for keeping consumers of MyFragment accidentally calling public method that's not supposed to be called directly.

Also you can use InActivity, InContext, InFragment. Consult the documentation for each interface to learn the caveats of using each of them.

LiveTransfusionHost

You might be consuming LiveData outside lifecycle and accidentally leaking precious resources. Then the easy way out is to use LiveTransfusionHost. It gets implemented just as easy as the rest of the utilities mentioned here and is just as powerful.

class MyViewModel : ViewModel(), LiveTransfusionHost by LiveTransfusionHost.getDefault() {

    private val databaseWindow: LiveData<List<String>> = getFromSomewhere()

    init {
        databaseWindow.transfusion { /* it: List<String> -> */ }
    }

    override fun onCleared() {
        clearTransfusions()
    }

}

Logo by smalllikeart

com.skoumal.grimoire

SKOUMAL

Версии библиотеки

Версия
1.1.0-alpha01