diff --git a/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModel.kt b/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModel.kt index becb9761..d934156e 100644 --- a/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModel.kt +++ b/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModel.kt @@ -3,6 +3,7 @@ package cafe.adriel.voyager.core.model import androidx.compose.runtime.Composable import androidx.compose.runtime.DisallowComposableCalls import androidx.compose.runtime.remember +import cafe.adriel.voyager.core.lifecycle.ScreenLifecycleStore import cafe.adriel.voyager.core.screen.Screen import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope @@ -32,10 +33,14 @@ public val ScreenModel.screenModelScope: CoroutineScope public inline fun Screen.rememberScreenModel( tag: String? = null, crossinline factory: @DisallowComposableCalls () -> T -): T = - remember(ScreenModelStore.getKey(this, tag)) { - ScreenModelStore.getOrPut(this, tag, factory) +): T { + val screenModelStore = remember(this) { + ScreenLifecycleStore.register(this) { ScreenModelStore } } + return remember(screenModelStore.getKey(this, tag)) { + screenModelStore.getOrPut(this, tag, factory) + } +} public interface ScreenModel { diff --git a/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModelStore.kt b/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModelStore.kt index ae9869ca..7ed8c8d5 100644 --- a/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModelStore.kt +++ b/voyager-core/src/commonMain/kotlin/cafe/adriel/voyager/core/model/ScreenModelStore.kt @@ -2,6 +2,7 @@ package cafe.adriel.voyager.core.model import androidx.compose.runtime.DisallowComposableCalls import cafe.adriel.voyager.core.concurrent.ThreadSafeMap +import cafe.adriel.voyager.core.lifecycle.ScreenDisposable import cafe.adriel.voyager.core.platform.multiplatformName import cafe.adriel.voyager.core.screen.Screen import kotlinx.coroutines.flow.MutableStateFlow @@ -13,7 +14,7 @@ private typealias DependencyInstance = Any private typealias DependencyOnDispose = (Any) -> Unit private typealias Dependency = Pair -public object ScreenModelStore { +public object ScreenModelStore : ScreenDisposable { @PublishedApi internal val screenModels: MutableMap = ThreadSafeMap() @@ -66,7 +67,7 @@ public object ScreenModelStore { .first as T } - public fun remove(screen: Screen) { + override fun onDispose(screen: Screen) { screenModels.onEach(screen) { key -> screenModels[key]?.onDispose() screenModels -= key @@ -78,6 +79,14 @@ public object ScreenModelStore { } } + @Deprecated( + message = "Use 'onDispose' instead. Will be removed in 1.0.0.", + replaceWith = ReplaceWith("onDispose") + ) + public fun remove(screen: Screen) { + onDispose(screen) + } + private fun Map.onEach(screen: Screen, block: (String) -> Unit) = asSequence() .filter { it.key.startsWith(screen.key) } diff --git a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt index 1f085550..51688031 100644 --- a/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt +++ b/voyager-navigator/src/commonMain/kotlin/cafe/adriel/voyager/navigator/Navigator.kt @@ -177,7 +177,6 @@ public class Navigator @InternalVoyagerApi constructor( public fun dispose( screen: Screen ) { - ScreenModelStore.remove(screen) ScreenLifecycleStore.remove(screen) stateKeys .asSequence()