mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2024-06-01 23:45:28 +00:00
commit
f91599e9c6
|
@ -1,5 +1,14 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.20.16
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Exposed`: `0.44.1` -> `0.45.0`
|
||||||
|
* `Coroutines`:
|
||||||
|
* Add `SpecialMutableStateFlow`
|
||||||
|
* `Compose`:
|
||||||
|
* Add `FlowState`
|
||||||
|
|
||||||
## 0.20.15
|
## 0.20.15
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package dev.inmo.micro_utils.coroutines.compose
|
||||||
|
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
|
import dev.inmo.micro_utils.coroutines.SpecialMutableStateFlow
|
||||||
|
import dev.inmo.micro_utils.coroutines.doInUI
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type works like [MutableState], [kotlinx.coroutines.flow.StateFlow] and [kotlinx.coroutines.flow.MutableSharedFlow].
|
||||||
|
* Based on [SpecialMutableStateFlow]
|
||||||
|
*/
|
||||||
|
class FlowState<T>(
|
||||||
|
initial: T,
|
||||||
|
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
) : MutableState<T>,
|
||||||
|
SpecialMutableStateFlow<T>(initial, internalScope) {
|
||||||
|
private var internalValue: T = initial
|
||||||
|
override var value: T
|
||||||
|
get() = internalValue
|
||||||
|
set(value) {
|
||||||
|
internalValue = value
|
||||||
|
tryEmit(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onChange(value: T) {
|
||||||
|
internalValue = value
|
||||||
|
super.onChange(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun component1(): T = value
|
||||||
|
|
||||||
|
override fun component2(): (T) -> Unit = { tryEmit(it) }
|
||||||
|
|
||||||
|
override fun tryEmit(value: T): Boolean {
|
||||||
|
internalValue = value
|
||||||
|
return super.tryEmit(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun emit(value: T) {
|
||||||
|
internalValue = value
|
||||||
|
super.emit(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//fun <T> MutableState<T>.asFlowState(scope: CoroutineScope = CoroutineScope(Dispatchers.Main)) = FlowState(this, scope)
|
|
@ -0,0 +1,60 @@
|
||||||
|
package dev.inmo.micro_utils.coroutines
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
|
import kotlinx.coroutines.flow.FlowCollector
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
||||||
|
* each active subscriber
|
||||||
|
*/
|
||||||
|
open class SpecialMutableStateFlow<T>(
|
||||||
|
initialValue: T,
|
||||||
|
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
|
) : StateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
||||||
|
protected val internalSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
||||||
|
replay = 0,
|
||||||
|
extraBufferCapacity = 2,
|
||||||
|
onBufferOverflow = BufferOverflow.DROP_OLDEST
|
||||||
|
)
|
||||||
|
protected val publicSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
||||||
|
replay = 1,
|
||||||
|
extraBufferCapacity = 1,
|
||||||
|
onBufferOverflow = BufferOverflow.DROP_OLDEST
|
||||||
|
)
|
||||||
|
|
||||||
|
protected var _value: T = initialValue
|
||||||
|
override val value: T
|
||||||
|
get() = _value
|
||||||
|
protected open suspend fun onChange(value: T) {
|
||||||
|
_value = value
|
||||||
|
publicSharedFlow.emit(value)
|
||||||
|
}
|
||||||
|
protected val job = internalSharedFlow.subscribe(internalScope) {
|
||||||
|
if (_value != it) {
|
||||||
|
onChange(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val replayCache: List<T>
|
||||||
|
get() = publicSharedFlow.replayCache
|
||||||
|
override val subscriptionCount: StateFlow<Int>
|
||||||
|
get() = publicSharedFlow.subscriptionCount
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
override fun resetReplayCache() = publicSharedFlow.resetReplayCache()
|
||||||
|
|
||||||
|
override fun tryEmit(value: T): Boolean {
|
||||||
|
return internalSharedFlow.tryEmit(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun emit(value: T) {
|
||||||
|
internalSharedFlow.emit(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun collect(collector: FlowCollector<T>) = publicSharedFlow.collect(collector)
|
||||||
|
}
|
|
@ -15,5 +15,5 @@ crypto_js_version=4.1.1
|
||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.20.15
|
version=0.20.16
|
||||||
android_code_version=221
|
android_code_version=222
|
||||||
|
|
|
@ -7,7 +7,7 @@ kt-coroutines = "1.7.3"
|
||||||
kslog = "1.3.1"
|
kslog = "1.3.1"
|
||||||
|
|
||||||
jb-compose = "1.5.11"
|
jb-compose = "1.5.11"
|
||||||
jb-exposed = "0.44.1"
|
jb-exposed = "0.45.0"
|
||||||
jb-dokka = "1.9.10"
|
jb-dokka = "1.9.10"
|
||||||
|
|
||||||
korlibs = "4.0.10"
|
korlibs = "4.0.10"
|
||||||
|
@ -21,7 +21,7 @@ koin = "3.5.0"
|
||||||
|
|
||||||
okio = "3.6.0"
|
okio = "3.6.0"
|
||||||
|
|
||||||
ksp = "1.9.20-1.0.14"
|
ksp = "1.9.21-1.0.15"
|
||||||
kotlin-poet = "1.15.1"
|
kotlin-poet = "1.15.1"
|
||||||
|
|
||||||
versions = "0.50.0"
|
versions = "0.50.0"
|
||||||
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,5 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package dev.inmo.micro_utils.matrix
|
package dev.inmo.micro_utils.matrix
|
||||||
|
|
||||||
class MatrixBuilder<T> {
|
open class MatrixBuilder<T> {
|
||||||
private val mutMatrix: MutableList<List<T>> = ArrayList()
|
private val mutMatrix: MutableList<List<T>> = ArrayList()
|
||||||
val matrix: Matrix<T>
|
val matrix: Matrix<T>
|
||||||
get() = mutMatrix
|
get() = mutMatrix
|
||||||
|
|
||||||
fun row(t: List<T>) = mutMatrix.add(t)
|
fun row(t: List<T>) = mutMatrix.add(t)
|
||||||
|
fun add(t: List<T>) = mutMatrix.add(t)
|
||||||
operator fun List<T>.unaryPlus() = row(this)
|
operator fun List<T>.unaryPlus() = row(this)
|
||||||
|
operator fun plus(t: List<T>) = add(t)
|
||||||
|
operator fun T.unaryPlus() = add(listOf(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> MatrixBuilder<T>.row(block: RowBuilder<T>.() -> Unit) = +RowBuilder<T>().also(block).row
|
fun <T> MatrixBuilder<T>.row(block: RowBuilder<T>.() -> Unit) = +RowBuilder<T>().also(block).row
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
package dev.inmo.micro_utils.matrix
|
package dev.inmo.micro_utils.matrix
|
||||||
|
|
||||||
class RowBuilder<T> {
|
open class RowBuilder<T> {
|
||||||
private val mutRow: MutableList<T> = ArrayList()
|
private val mutRow: MutableList<T> = ArrayList()
|
||||||
val row: Row<T>
|
val row: Row<T>
|
||||||
get() = mutRow
|
get() = mutRow
|
||||||
|
|
||||||
fun column(t: T) = mutRow.add(t)
|
fun add(t: T) = mutRow.add(t)
|
||||||
operator fun T.unaryPlus() = column(this)
|
operator fun T.unaryPlus() = column(this)
|
||||||
|
fun column(t: T) = mutRow.add(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> row(block: RowBuilder<T>.() -> Unit): List<T> = RowBuilder<T>().also(block).row
|
fun <T> row(block: RowBuilder<T>.() -> Unit): List<T> = RowBuilder<T>().also(block).row
|
||||||
|
|
Loading…
Reference in New Issue
Block a user