Skip to content

Commit 56ff556

Browse files
committedFeb 27, 2024
fix: Correctly create child coroutine scopes
1 parent 8d1f92b commit 56ff556

File tree

6 files changed

+25
-19
lines changed

6 files changed

+25
-19
lines changed
 

‎common/src/commonMain/kotlin/com/artemchep/keyguard/common/usecase/impl/WindowCoroutineScopeImpl.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.artemchep.keyguard.common.model.NoAnalytics
44
import com.artemchep.keyguard.common.model.ToastMessage
55
import com.artemchep.keyguard.common.usecase.ShowMessage
66
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
7+
import com.artemchep.keyguard.common.util.newChildScope
78
import com.artemchep.keyguard.platform.recordException
89
import kotlinx.coroutines.CoroutineExceptionHandler
910
import kotlinx.coroutines.CoroutineScope
@@ -48,7 +49,7 @@ class WindowCoroutineScopeImpl(
4849
showMessage.copy(msg)
4950
}
5051

51-
private val internalScope = scope + SupervisorJob() + handler
52+
private val internalScope = scope.newChildScope(::SupervisorJob) + handler
5253

5354
override val coroutineContext: CoroutineContext
5455
get() = internalScope.coroutineContext
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.artemchep.keyguard.common.util
2+
3+
import kotlinx.coroutines.CoroutineScope
4+
import kotlinx.coroutines.Job
5+
import kotlinx.coroutines.plus
6+
7+
val CoroutineScope.job
8+
get() = coroutineContext[Job]
9+
10+
inline fun CoroutineScope.newChildScope(
11+
builder: (Job?) -> Job,
12+
): CoroutineScope = this + builder(job)

‎common/src/commonMain/kotlin/com/artemchep/keyguard/feature/auth/login/LoginStateProducer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.artemchep.keyguard.common.usecase.CipherUnsecureUrlCheck
1616
import com.artemchep.keyguard.common.util.flow.EventFlow
1717
import com.artemchep.keyguard.common.util.flow.combineToList
1818
import com.artemchep.keyguard.common.util.flow.persistingStateIn
19+
import com.artemchep.keyguard.common.util.newChildScope
1920
import com.artemchep.keyguard.feature.auth.common.TextFieldModel2
2021
import com.artemchep.keyguard.feature.auth.common.Validated
2122
import com.artemchep.keyguard.feature.auth.common.util.REGEX_US_ASCII
@@ -54,7 +55,6 @@ import kotlinx.coroutines.flow.map
5455
import kotlinx.coroutines.flow.scan
5556
import kotlinx.coroutines.flow.shareIn
5657
import kotlinx.coroutines.flow.update
57-
import kotlinx.coroutines.plus
5858
import org.kodein.di.compose.localDI
5959
import org.kodein.di.direct
6060
import org.kodein.di.instance
@@ -1018,7 +1018,7 @@ fun <T, Argument> RememberStateFlowScope.foo(
10181018
}
10191019
}
10201020
if (shouldAdd) {
1021-
val itemCoroutineScope = screenScope + Job()
1021+
val itemCoroutineScope = screenScope.newChildScope(::Job)
10221022
val itemDefaultArg = inMemoryArguments[perst.key]
10231023
out += Foo2Scoped(
10241024
perst = perst,

‎common/src/commonMain/kotlin/com/artemchep/keyguard/feature/navigation/NavigationEntry.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.artemchep.keyguard.feature.navigation
22

33
import androidx.compose.runtime.staticCompositionLocalOf
4+
import com.artemchep.keyguard.common.util.job
45
import com.artemchep.keyguard.feature.navigation.backpress.BackPressInterceptorHost
56
import com.artemchep.keyguard.feature.navigation.backpress.BackPressInterceptorRegistration
67
import com.artemchep.keyguard.feature.navigation.state.FlowHolderViewModel
@@ -49,7 +50,7 @@ data class NavigationEntryImpl(
4950
) : NavigationEntry {
5051
override val type: String = route::class.simpleName.orEmpty()
5152

52-
private val job = Job()
53+
private val job = Job(parent = parent.job)
5354

5455
override val scope = parent + job
5556

‎common/src/commonMain/kotlin/com/artemchep/keyguard/feature/navigation/state/FlowHolderViewModel.kt

+5-14
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import com.artemchep.keyguard.common.usecase.PutScreenState
88
import com.artemchep.keyguard.common.usecase.ShowMessage
99
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
1010
import com.artemchep.keyguard.common.usecase.impl.WindowCoroutineScopeImpl
11+
import com.artemchep.keyguard.common.util.job
1112
import com.artemchep.keyguard.feature.navigation.NavigationController
1213
import com.artemchep.keyguard.feature.navigation.NavigationEntry
1314
import com.artemchep.keyguard.platform.LeBundle
1415
import com.artemchep.keyguard.platform.LeContext
1516
import com.artemchep.keyguard.platform.leBundleOf
16-
import kotlinx.coroutines.Dispatchers
1717
import kotlinx.coroutines.Job
1818
import kotlinx.coroutines.SupervisorJob
1919
import kotlinx.coroutines.plus
@@ -49,9 +49,9 @@ class FlowHolderViewModel(
4949
init: RememberStateFlowScopeZygote.() -> T,
5050
): T = synchronized(this) {
5151
store.getOrPut(key) {
52-
val vmCoroutineScopeJob = SupervisorJob()
52+
val vmCoroutineScopeJob = SupervisorJob(parent = scope.job)
5353
val vmCoroutineScope = WindowCoroutineScopeImpl(
54-
scope = scope + vmCoroutineScopeJob + Dispatchers.Default,
54+
scope = scope + vmCoroutineScopeJob,
5555
showMessage = showMessage,
5656
)
5757
val vmScope = RememberStateFlowScopeImpl(
@@ -87,18 +87,9 @@ class FlowHolderViewModel(
8787
}
8888
}
8989

90-
private var isDestroyed = false
91-
9290
fun destroy() {
93-
synchronized(this) {
94-
if (!isDestroyed) {
95-
isDestroyed = true
96-
//
97-
store.keys.toSet().forEach {
98-
clear(it)
99-
}
100-
}
101-
}
91+
// Do nothing. We do not want to clear all of the screens
92+
// because there still might be a screen exit animation running.
10293
}
10394

10495
fun persistedState(): LeBundle {

‎common/src/commonMain/kotlin/com/artemchep/keyguard/feature/navigation/state/RememberStateFlowScopeImpl.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import com.artemchep.keyguard.common.usecase.GetScreenState
1111
import com.artemchep.keyguard.common.usecase.PutScreenState
1212
import com.artemchep.keyguard.common.usecase.ShowMessage
1313
import com.artemchep.keyguard.common.usecase.WindowCoroutineScope
14+
import com.artemchep.keyguard.common.util.newChildScope
1415
import com.artemchep.keyguard.feature.loading.LoadingTask
1516
import com.artemchep.keyguard.feature.loading.getErrorReadableMessage
1617
import com.artemchep.keyguard.feature.localization.textResource
@@ -72,7 +73,7 @@ class RememberStateFlowScopeImpl(
7273
sink: MutableStateFlow<T>,
7374
) {
7475
private val collectScope by lazy {
75-
scope + Dispatchers.Main + Job()
76+
scope.newChildScope(::Job) + Dispatchers.Main
7677
}
7778

7879
val mutableState by lazy {

0 commit comments

Comments
 (0)
Please sign in to comment.