Own ordered settings changes independently of the Compose screen
This commit is contained in:
1 parent
299518e866
commit
a95245e272
3 files changed
+42
No files matched your search
@@ -42,6 +42,7 @@ data class RadioCompressorSettings(val enabled: Boolean = true, val maxGainDb: I
|
||||
* При формировании конфига настройки и keys.conf читаются один раз; чтение/запись utun.cfg сериализованы.
|
||||
*/
|
||||
class ConfigProvider(private val context: Context) {
|
||||
val changes = SettingsOperations()
|
||||
private val configFiles = ConfigFileStore { level, message -> LogManager.addLog(level, "CFG", message) }
|
||||
private val bleFlags = intPreferencesKey("bluetooth_flags")
|
||||
fun getBleFlags(): Int = runBlocking { context.dataStore.data.first()[bleFlags] ?: 0 }
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.utun.chat.data
|
||||
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Deferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
/** Очередь Application на main: сохранить выбор, затем применить runtime без зависимости от UI scope.
|
||||
* submit принимает неизменный снимок аргументов caller; отмена await не отменяет запись.
|
||||
* awaitIdle ставит барьер после принятых изменений перед формированием restart-конфига. */
|
||||
class SettingsOperations(private val scope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate),
|
||||
private val log: (String, String) -> Unit = { level, message -> LogManager.addLog(level, "Settings", message) }) {
|
||||
private val mutex = Mutex()
|
||||
private val _failed = MutableStateFlow(false)
|
||||
val failed = _failed.asStateFlow()
|
||||
|
||||
fun submit(name: String, operation: suspend () -> Unit): Deferred<Unit> = scope.async(start = CoroutineStart.UNDISPATCHED) {
|
||||
mutex.withLock {
|
||||
try {
|
||||
operation()
|
||||
log("INFO", "Setting applied name=$name")
|
||||
} catch (e: CancellationException) { throw e }
|
||||
catch (e: Exception) { reportFailure(name, e); throw e }
|
||||
}
|
||||
}
|
||||
|
||||
fun reportFailure(name: String, error: Exception) {
|
||||
_failed.value = true
|
||||
log("ERROR", "Setting failed name=$name: ${error.javaClass.simpleName}: ${error.message}")
|
||||
}
|
||||
fun dismissFailure() { _failed.value = false }
|
||||
suspend fun awaitIdle() { mutex.withLock { } }
|
||||
}
|
||||
@@ -28,6 +28,7 @@ kotlin {
|
||||
"com/utun/chat/data/CallPlaybackBuffer.kt", "com/utun/chat/data/CallOutputRecovery.kt",
|
||||
"com/utun/chat/data/CallState.kt", "com/utun/chat/data/CallAudioHost.kt")
|
||||
kotlin.include("com/utun/chat/data/ConversationSubmissions.kt", "com/utun/chat/data/ConversationTarget.kt")
|
||||
kotlin.include("com/utun/chat/data/SettingsOperations.kt")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user