From 416959a855dc09501e4c83b6f410d79836cbb0d5 Mon Sep 17 00:00:00 2001 From: forhad013 Date: Thu, 26 Oct 2023 10:28:48 +0800 Subject: [PATCH] Added function to retrieve instance from backstack --- decompose-router/build.gradle.kts | 1 + .../github/xxfast/decompose/router/Router.kt | 40 +++++++++++++++++++ gradle/libs.versions.toml | 1 + 3 files changed, 42 insertions(+) diff --git a/decompose-router/build.gradle.kts b/decompose-router/build.gradle.kts index 0a32093..a4757e3 100644 --- a/decompose-router/build.gradle.kts +++ b/decompose-router/build.gradle.kts @@ -36,6 +36,7 @@ kotlin { implementation(libs.essenty.parcelable) implementation(libs.decompose) implementation(libs.decompose.compose.multiplatform) + implementation(libs.kotlin.reflect) } } diff --git a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/Router.kt b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/Router.kt index 48b9aa7..7cc0ea4 100644 --- a/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/Router.kt +++ b/decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/Router.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.staticCompositionLocalOf +import com.arkivanov.decompose.Child import com.arkivanov.decompose.router.stack.ChildStack import com.arkivanov.decompose.router.stack.StackNavigation import com.arkivanov.decompose.router.stack.childStack @@ -119,3 +120,42 @@ fun rememberOnRoute( return instance } + +/*** + * Retrieve a instance of [V] that is scoped to the current route + * + * @param type of [V] instance + * @param childClass class of stack child[T] + * @param keyBlock lambda to configure the key [which was used to save the instance [T]] by default [type].key + */ + +private inline fun Router.getInstanceFromBackStack( + type: KClass, + childClass: KClass, + keyBlock: ((childConfiguration: T) -> Any?) = { null } +): V { + val child: Child.Created? = this.stack.value.backStack + .firstOrNull { it.configuration is T } + + require(child != null) { + "Couldn't find the ${T::class} in the backstack" + } + + val configuration: C = child.configuration + require(configuration is T) { + "Couldn't find the ${T::class} in the backstack" + } + + val childConfiguration: T = configuration + val key: Any? = keyBlock(childConfiguration) + val keyInstance: String = if (key == null) "${type.key}.instance" + else "${key}.instance" + + val viewModelInstance: Instance? = child.instance.instanceKeeper.get(keyInstance) + + require(viewModelInstance is V) { + "Couldn't find the viewModel for ${T::class} in the backstack" + } + + return viewModelInstance +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ca35220..e4034ca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ decompose-compose-multiplatform = { module = "com.arkivanov.decompose:extensions essenty-parcelable = { module = "com.arkivanov.essenty:parcelable", version.ref = "essenty" } horologist-compose-layouts = { module = "com.google.android.horologist:horologist-compose-layout", version.ref = "horologist" } kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlinx-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } wear-compose-foundation = { module = "androidx.wear.compose:compose-foundation", version.ref = "wear-compose" } wear-compose-material = { module = "androidx.wear.compose:compose-material", version.ref = "wear-compose" }