Compare commits

..

16 Commits

5 changed files with 54 additions and 22 deletions

View File

@@ -1,5 +1,25 @@
# Changelog # Changelog
## 0.10.5
* `Versions`
* `Compose`: `1.2.0-alpha01-dev683` -> `1.2.0-alpha01-dev686`
* `Repos`
* `Android`:
* New function `SharedPreferencesKeyValueRepo`
## 0.10.4
* `Versions`:
* `Serialization`: `1.3.2` -> `1.3.3`
## 0.10.3
* `Versions`:
* `Compose`: `1.2.0-alpha01-dev682` -> `1.2.0-alpha01-dev683`
* `Coroutines`:
* Fixes in `AccumulatorFlow`
## 0.10.2 ## 0.10.2
* `Versions`: * `Versions`:

View File

@@ -6,11 +6,12 @@ import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlin.coroutines.cancellation.CancellationException
private sealed interface AccumulatorFlowStep private sealed interface AccumulatorFlowStep<T>
private data class DataRetrievedAccumulatorFlowStep(val data: Any) : AccumulatorFlowStep private data class DataRetrievedAccumulatorFlowStep<T>(val data: T) : AccumulatorFlowStep<T>
private data class SubscribeAccumulatorFlowStep(val channel: Channel<Any>) : AccumulatorFlowStep private data class SubscribeAccumulatorFlowStep<T>(val channel: Channel<T>) : AccumulatorFlowStep<T>
private data class UnsubscribeAccumulatorFlowStep(val channel: Channel<Any>) : AccumulatorFlowStep private data class UnsubscribeAccumulatorFlowStep<T>(val channel: Channel<T>) : AccumulatorFlowStep<T>
/** /**
* This [Flow] will have behaviour very similar to [SharedFlow], but there are several differences: * This [Flow] will have behaviour very similar to [SharedFlow], but there are several differences:
@@ -26,12 +27,12 @@ class AccumulatorFlow<T>(
private val subscope = scope.LinkedSupervisorScope() private val subscope = scope.LinkedSupervisorScope()
private val activeData = ArrayDeque<T>() private val activeData = ArrayDeque<T>()
private val dataMutex = Mutex() private val dataMutex = Mutex()
private val channelsForBroadcast = mutableListOf<Channel<Any>>() private val channelsForBroadcast = mutableListOf<Channel<T>>()
private val channelsMutex = Mutex() private val channelsMutex = Mutex()
private val steps = subscope.actor<AccumulatorFlowStep> { step -> private val steps = subscope.actor<AccumulatorFlowStep<T>> { step ->
when (step) { when (step) {
is DataRetrievedAccumulatorFlowStep -> { is DataRetrievedAccumulatorFlowStep -> {
if (activeData.first() === step.data) { if (activeData.firstOrNull() === step.data) {
dataMutex.withLock { dataMutex.withLock {
activeData.removeFirst() activeData.removeFirst()
} }
@@ -42,7 +43,7 @@ class AccumulatorFlow<T>(
dataMutex.withLock { dataMutex.withLock {
val dataToSend = activeData.toList() val dataToSend = activeData.toList()
safelyWithoutExceptions { safelyWithoutExceptions {
dataToSend.forEach { step.channel.send(it as Any) } dataToSend.forEach { step.channel.send(it) }
} }
} }
} }
@@ -58,24 +59,29 @@ class AccumulatorFlow<T>(
channelsMutex.withLock { channelsMutex.withLock {
channelsForBroadcast.forEach { channel -> channelsForBroadcast.forEach { channel ->
safelyWithResult { safelyWithResult {
channel.send(it as Any) channel.send(it)
} }
} }
} }
} }
override suspend fun collectSafely(collector: FlowCollector<T>) { override suspend fun collectSafely(collector: FlowCollector<T>) {
val channel = Channel<Any>(Channel.UNLIMITED, BufferOverflow.SUSPEND) val channel = Channel<T>(Channel.UNLIMITED, BufferOverflow.SUSPEND)
steps.send(SubscribeAccumulatorFlowStep(channel)) steps.send(SubscribeAccumulatorFlowStep(channel))
for (data in channel) { val result = runCatchingSafely {
try { for (data in channel) {
collector.emit(data as T) val emitResult = runCatchingSafely {
steps.send(DataRetrievedAccumulatorFlowStep(data)) collector.emit(data)
} finally { }
channel.cancel() if (emitResult.isSuccess || emitResult.exceptionOrNull() is CancellationException) {
steps.send(UnsubscribeAccumulatorFlowStep(channel)) steps.send(DataRetrievedAccumulatorFlowStep(data))
}
emitResult.getOrThrow()
} }
} }
channel.cancel()
steps.send(UnsubscribeAccumulatorFlowStep(channel))
result.getOrThrow()
} }
} }

View File

@@ -14,5 +14,5 @@ crypto_js_version=4.1.1
# Project data # Project data
group=dev.inmo group=dev.inmo
version=0.10.2 version=0.10.5
android_code_version=117 android_code_version=120

View File

@@ -1,10 +1,10 @@
[versions] [versions]
kt = "1.6.21" kt = "1.6.21"
kt-serialization = "1.3.2" kt-serialization = "1.3.3"
kt-coroutines = "1.6.1" kt-coroutines = "1.6.1"
jb-compose = "1.2.0-alpha01-dev682" jb-compose = "1.2.0-alpha01-dev686"
jb-exposed = "0.38.2" jb-exposed = "0.38.2"
jb-dokka = "1.6.21" jb-dokka = "1.6.21"
@@ -16,7 +16,7 @@ ktor = "2.0.1"
gh-release = "2.3.7" gh-release = "2.3.7"
android-gradle = "7.0.4" android-gradle = "7.0.4"
dexcount = "3.0.1" dexcount = "3.1.0"
android-coreKtx = "1.7.0" android-coreKtx = "1.7.0"
android-recyclerView = "1.2.1" android-recyclerView = "1.2.1"

View File

@@ -160,3 +160,9 @@ class KeyValueStore<T : Any> internal constructor (
} }
} }
} }
inline fun <T : Any> SharedPreferencesKeyValueRepo(
context: Context,
name: String = "default",
cacheValues: Boolean = false
) = context.keyValueStore<T>(name, cacheValues)