mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-09-18 06:49:20 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
a91006132f | |||
5028f130e9 | |||
77fa019651 | |||
9715da9384 | |||
f6d5035c1a | |||
43e782ab6f | |||
f3f9920bfb | |||
2bfd615812 | |||
ebfacb3659 |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.20.19
|
||||||
|
|
||||||
|
* `Versions`:
|
||||||
|
* `Ktor`: `2.3.6` -> `2.3.7`
|
||||||
|
|
||||||
|
## 0.20.18
|
||||||
|
|
||||||
|
* `Coroutines`:
|
||||||
|
* `SpecialMutableStateFlow` now extends `MutableStateFlow`
|
||||||
|
* `Compose`:
|
||||||
|
* Deprecate `FlowState` due to its complexity in fixes
|
||||||
|
|
||||||
## 0.20.17
|
## 0.20.17
|
||||||
|
|
||||||
* `Versions`:
|
* `Versions`:
|
||||||
|
@@ -1,10 +1,7 @@
|
|||||||
package dev.inmo.micro_utils.coroutines.compose
|
package dev.inmo.micro_utils.coroutines.compose
|
||||||
|
|
||||||
import androidx.compose.runtime.MutableState
|
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.SpecialMutableStateFlow
|
||||||
import dev.inmo.micro_utils.coroutines.doInUI
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|
||||||
@@ -12,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
* This type works like [MutableState], [kotlinx.coroutines.flow.StateFlow] and [kotlinx.coroutines.flow.MutableSharedFlow].
|
* This type works like [MutableState], [kotlinx.coroutines.flow.StateFlow] and [kotlinx.coroutines.flow.MutableSharedFlow].
|
||||||
* Based on [SpecialMutableStateFlow]
|
* Based on [SpecialMutableStateFlow]
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Will be removed soon")
|
||||||
class FlowState<T>(
|
class FlowState<T>(
|
||||||
initial: T,
|
initial: T,
|
||||||
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
@@ -25,9 +23,9 @@ class FlowState<T>(
|
|||||||
tryEmit(value)
|
tryEmit(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun onChange(value: T) {
|
override fun onChangeWithoutSync(value: T) {
|
||||||
internalValue = value
|
internalValue = value
|
||||||
super.onChange(value)
|
super.onChangeWithoutSync(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun component1(): T = value
|
override fun component1(): T = value
|
||||||
|
@@ -3,10 +3,14 @@ package dev.inmo.micro_utils.coroutines
|
|||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.BufferOverflow
|
import kotlinx.coroutines.channels.BufferOverflow
|
||||||
import kotlinx.coroutines.flow.FlowCollector
|
import kotlinx.coroutines.flow.FlowCollector
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.internal.SynchronizedObject
|
||||||
|
import kotlinx.coroutines.internal.synchronized
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
* Works like [StateFlow], but guarantee that latest value update will always be delivered to
|
||||||
@@ -15,7 +19,9 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
open class SpecialMutableStateFlow<T>(
|
open class SpecialMutableStateFlow<T>(
|
||||||
initialValue: T,
|
initialValue: T,
|
||||||
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
internalScope: CoroutineScope = CoroutineScope(Dispatchers.Default)
|
||||||
) : StateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
) : MutableStateFlow<T>, FlowCollector<T>, MutableSharedFlow<T> {
|
||||||
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
|
private val syncObject = SynchronizedObject()
|
||||||
protected val internalSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
protected val internalSharedFlow: MutableSharedFlow<T> = MutableSharedFlow(
|
||||||
replay = 0,
|
replay = 0,
|
||||||
extraBufferCapacity = 2,
|
extraBufferCapacity = 2,
|
||||||
@@ -28,16 +34,13 @@ open class SpecialMutableStateFlow<T>(
|
|||||||
)
|
)
|
||||||
|
|
||||||
protected var _value: T = initialValue
|
protected var _value: T = initialValue
|
||||||
override val value: T
|
override var value: T
|
||||||
get() = _value
|
get() = _value
|
||||||
protected open suspend fun onChange(value: T) {
|
set(value) {
|
||||||
_value = value
|
doOnChangeAction(value)
|
||||||
publicSharedFlow.emit(value)
|
|
||||||
}
|
|
||||||
protected val job = internalSharedFlow.subscribe(internalScope) {
|
|
||||||
if (_value != it) {
|
|
||||||
onChange(it)
|
|
||||||
}
|
}
|
||||||
|
protected val job = internalSharedFlow.subscribe(internalScope) {
|
||||||
|
doOnChangeAction(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val replayCache: List<T>
|
override val replayCache: List<T>
|
||||||
@@ -45,6 +48,29 @@ open class SpecialMutableStateFlow<T>(
|
|||||||
override val subscriptionCount: StateFlow<Int>
|
override val subscriptionCount: StateFlow<Int>
|
||||||
get() = publicSharedFlow.subscriptionCount
|
get() = publicSharedFlow.subscriptionCount
|
||||||
|
|
||||||
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
|
override fun compareAndSet(expect: T, update: T): Boolean {
|
||||||
|
return synchronized(syncObject) {
|
||||||
|
if (expect == _value && update != _value) {
|
||||||
|
doOnChangeAction(update)
|
||||||
|
}
|
||||||
|
expect == _value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun onChangeWithoutSync(value: T) {
|
||||||
|
_value = value
|
||||||
|
publicSharedFlow.tryEmit(value)
|
||||||
|
}
|
||||||
|
@OptIn(InternalCoroutinesApi::class)
|
||||||
|
protected open fun doOnChangeAction(value: T) {
|
||||||
|
synchronized(syncObject) {
|
||||||
|
if (_value != value) {
|
||||||
|
onChangeWithoutSync(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ExperimentalCoroutinesApi
|
@ExperimentalCoroutinesApi
|
||||||
override fun resetReplayCache() = publicSharedFlow.resetReplayCache()
|
override fun resetReplayCache() = publicSharedFlow.resetReplayCache()
|
||||||
|
|
||||||
|
@@ -15,5 +15,5 @@ crypto_js_version=4.1.1
|
|||||||
# Project data
|
# Project data
|
||||||
|
|
||||||
group=dev.inmo
|
group=dev.inmo
|
||||||
version=0.20.17
|
version=0.20.19
|
||||||
android_code_version=223
|
android_code_version=225
|
||||||
|
@@ -13,7 +13,7 @@ jb-dokka = "1.9.10"
|
|||||||
korlibs = "4.0.10"
|
korlibs = "4.0.10"
|
||||||
uuid = "0.8.2"
|
uuid = "0.8.2"
|
||||||
|
|
||||||
ktor = "2.3.6"
|
ktor = "2.3.7"
|
||||||
|
|
||||||
gh-release = "2.4.1"
|
gh-release = "2.4.1"
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ koin = "3.5.0"
|
|||||||
okio = "3.6.0"
|
okio = "3.6.0"
|
||||||
|
|
||||||
ksp = "1.9.21-1.0.15"
|
ksp = "1.9.21-1.0.15"
|
||||||
kotlin-poet = "1.15.2"
|
kotlin-poet = "1.15.3"
|
||||||
|
|
||||||
versions = "0.50.0"
|
versions = "0.50.0"
|
||||||
|
|
||||||
|
@@ -68,18 +68,14 @@ publishing {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
|
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
|
||||||
maven {
|
maven {
|
||||||
name = "Gitea"
|
name = "InmoNexus"
|
||||||
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
||||||
|
|
||||||
credentials(HttpHeaderCredentials) {
|
credentials {
|
||||||
name = "Authorization"
|
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
|
||||||
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
|
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
|
||||||
}
|
|
||||||
|
|
||||||
authentication {
|
|
||||||
header(HttpHeaderAuthentication)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -121,4 +117,21 @@ if (project.hasProperty("signing.gnupg.keyName")) {
|
|||||||
def signingTasks = project.getTasks().withType(Sign.class)
|
def signingTasks = project.getTasks().withType(Sign.class)
|
||||||
mustRunAfter(signingTasks)
|
mustRunAfter(signingTasks)
|
||||||
}
|
}
|
||||||
|
// Workaround to make test tasks use sign
|
||||||
|
project.getTasks().withType(Sign.class).configureEach { signTask ->
|
||||||
|
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
|
||||||
|
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
|
||||||
|
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
|
||||||
|
|
||||||
|
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||||
|
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
|
||||||
|
if (debugTestTask != null) {
|
||||||
|
signTask.mustRunAfter(debugTestTask)
|
||||||
|
}
|
||||||
|
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||||
|
def testTask = tasks.findByName("compileTestKotlin$pubName")
|
||||||
|
if (testTask != null) {
|
||||||
|
signTask.mustRunAfter(testTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1 +1 @@
|
|||||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}
|
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"InmoNexus","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}
|
@@ -57,18 +57,14 @@ publishing {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
|
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
|
||||||
maven {
|
maven {
|
||||||
name = "Gitea"
|
name = "InmoNexus"
|
||||||
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
||||||
|
|
||||||
credentials(HttpHeaderCredentials) {
|
credentials {
|
||||||
name = "Authorization"
|
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
|
||||||
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
|
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
|
||||||
}
|
|
||||||
|
|
||||||
authentication {
|
|
||||||
header(HttpHeaderAuthentication)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -109,4 +105,21 @@ if (project.hasProperty("signing.gnupg.keyName")) {
|
|||||||
def signingTasks = project.getTasks().withType(Sign.class)
|
def signingTasks = project.getTasks().withType(Sign.class)
|
||||||
mustRunAfter(signingTasks)
|
mustRunAfter(signingTasks)
|
||||||
}
|
}
|
||||||
|
// Workaround to make test tasks use sign
|
||||||
|
project.getTasks().withType(Sign.class).configureEach { signTask ->
|
||||||
|
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
|
||||||
|
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
|
||||||
|
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
|
||||||
|
|
||||||
|
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||||
|
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
|
||||||
|
if (debugTestTask != null) {
|
||||||
|
signTask.mustRunAfter(debugTestTask)
|
||||||
|
}
|
||||||
|
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
|
||||||
|
def testTask = tasks.findByName("compileTestKotlin$pubName")
|
||||||
|
if (testTask != null) {
|
||||||
|
signTask.mustRunAfter(testTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1 +1 @@
|
|||||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/MicroUtils/blob/master/LICENSE"}],"mavenConfig":{"name":"${project.name}","description":"It is set of projects with micro tools for avoiding of routines coding","url":"https://github.com/InsanusMokrassar/MicroUtils/","vcsUrl":"https://github.com/InsanusMokrassar/MicroUtils.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"},{"id":"000Sanya","name":"Syrov Aleksandr","eMail":"000sanya.000sanya@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/MicroUtils"},{"name":"InmoNexus","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
Reference in New Issue
Block a user