Skip to content

Commit a4b6c2c

Browse files
committed
Remove SavedStateHandle API
1 parent d0ec2e0 commit a4b6c2c

16 files changed

Lines changed: 60 additions & 109 deletions

File tree

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,25 @@
11
package io.github.xxfast.decompose.router.screens.stack.list
22

3-
import com.arkivanov.essenty.instancekeeper.InstanceKeeper.Instance
4-
import io.github.xxfast.decompose.SavedStateHandle
3+
import io.github.xxfast.decompose.router.RouterContext
4+
import io.github.xxfast.decompose.router.state
55
import io.github.xxfast.decompose.router.screens.stack.Item
66
import kotlinx.coroutines.CoroutineScope
77
import kotlinx.coroutines.Dispatchers
8-
import kotlinx.coroutines.cancel
98
import kotlinx.coroutines.flow.MutableStateFlow
109
import kotlinx.coroutines.flow.StateFlow
1110
import kotlinx.coroutines.launch
1211
import kotlin.coroutines.CoroutineContext
1312

14-
class ListInstance(private val savedStateHandle: SavedStateHandle) : Instance, CoroutineScope {
15-
private val initialState: ListState = savedStateHandle.get() ?: ListState()
16-
13+
class ListInstance(context: RouterContext) : CoroutineScope {
14+
private val initialState: ListState = context.state(ListState()) { states.value }
1715
private val _state: MutableStateFlow<ListState> = MutableStateFlow(initialState)
18-
val state: StateFlow<ListState> = _state
16+
val states: StateFlow<ListState> = _state
1917

2018
override val coroutineContext: CoroutineContext = Dispatchers.Main
2119

2220
fun add(item: Item = Item(_state.value.screens.size)) = launch {
2321
val previous: ListState = _state.value
2422
val updated: ListState = previous.copy(screens = previous.screens.plus(item))
2523
_state.emit(updated)
26-
savedStateHandle.set(updated)
27-
}
28-
29-
override fun onDestroy() {
30-
coroutineContext.cancel()
3124
}
3225
}

app/src/commonMain/kotlin/io/github/xxfast/decompose/router/screens/stack/list/ListScreen.kt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,15 @@ import io.github.xxfast.decompose.router.screens.TOOLBAR_TAG
4040
import io.github.xxfast.decompose.router.screens.stack.Item
4141
import kotlinx.coroutines.CoroutineScope
4242
import kotlinx.coroutines.launch
43-
import kotlinx.serialization.InternalSerializationApi
44-
import kotlinx.serialization.serializer
4543

46-
@OptIn(ExperimentalMaterial3Api::class, InternalSerializationApi::class)
44+
@OptIn(ExperimentalMaterial3Api::class)
4745
@Composable
4846
fun ListScreen(
4947
onSelect: (screen: Item) -> Unit,
5048
) {
51-
val instance: ListInstance = rememberOnRoute(
52-
type = ListInstance::class,
53-
strategy = ListState::class.serializer()
54-
) { savedState ->
55-
ListInstance(savedState)
56-
}
49+
val instance: ListInstance = rememberOnRoute(ListInstance::class) { context -> ListInstance(context) }
5750

58-
val state: ListState by instance.state.collectAsState()
51+
val state: ListState by instance.states.collectAsState()
5952
val listState: LazyListState = rememberLazyListState()
6053
val coroutineScope: CoroutineScope = rememberCoroutineScope()
6154

decompose-router/api/android/decompose-router.api

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
1-
public final class io/github/xxfast/decompose/KeyKt {
2-
public static final fun getKey (Lkotlin/reflect/KClass;)Ljava/lang/String;
3-
}
4-
5-
public final class io/github/xxfast/decompose/SavedStateHandle : com/arkivanov/essenty/instancekeeper/InstanceKeeper$Instance {
6-
public static final field $stable I
7-
public fun <init> (Ljava/lang/Object;)V
8-
public final fun get ()Ljava/lang/Object;
9-
public final fun getValue ()Ljava/lang/Object;
10-
public fun onDestroy ()V
11-
public final fun set (Ljava/lang/Object;)V
12-
}
13-
141
public final class io/github/xxfast/decompose/router/DefaultRouterContextKt {
152
public static final fun defaultRouterContext (Landroidx/activity/ComponentActivity;)Lio/github/xxfast/decompose/router/RouterContext;
163
public static final fun defaultRouterContext (Landroidx/fragment/app/Fragment;Landroidx/activity/OnBackPressedDispatcher;)Lio/github/xxfast/decompose/router/RouterContext;
174
}
185

6+
public final class io/github/xxfast/decompose/router/KeyKt {
7+
public static final fun getKey (Lkotlin/reflect/KClass;)Ljava/lang/String;
8+
}
9+
1910
public final class io/github/xxfast/decompose/router/RememberOnRouteKt {
20-
public static final fun rememberOnRoute (Lkotlin/reflect/KClass;Lkotlinx/serialization/KSerializer;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Lcom/arkivanov/essenty/instancekeeper/InstanceKeeper$Instance;
11+
public static final fun rememberOnRoute (Lkotlin/reflect/KClass;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Ljava/lang/Object;
2112
}
2213

2314
public final class io/github/xxfast/decompose/router/RouterContext : com/arkivanov/decompose/ComponentContext {

decompose-router/api/desktop/decompose-router.api

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1-
public final class io/github/xxfast/decompose/KeyKt {
2-
public static final fun getKey (Lkotlin/reflect/KClass;)Ljava/lang/String;
3-
}
4-
5-
public final class io/github/xxfast/decompose/SavedStateHandle : com/arkivanov/essenty/instancekeeper/InstanceKeeper$Instance {
6-
public static final field $stable I
7-
public fun <init> (Ljava/lang/Object;)V
8-
public final fun get ()Ljava/lang/Object;
9-
public final fun getValue ()Ljava/lang/Object;
10-
public fun onDestroy ()V
11-
public final fun set (Ljava/lang/Object;)V
12-
}
13-
141
public final class io/github/xxfast/decompose/router/DefaultRouterContextKt {
152
public static final fun defaultRouterContext (Lcom/arkivanov/essenty/backhandler/BackDispatcher;Lcom/arkivanov/essenty/lifecycle/LifecycleRegistry;Landroidx/compose/ui/window/WindowState;Landroidx/compose/runtime/Composer;II)Lio/github/xxfast/decompose/router/RouterContext;
163
}
174

5+
public final class io/github/xxfast/decompose/router/KeyKt {
6+
public static final fun getKey (Lkotlin/reflect/KClass;)Ljava/lang/String;
7+
}
8+
189
public final class io/github/xxfast/decompose/router/RememberOnRouteKt {
19-
public static final fun rememberOnRoute (Lkotlin/reflect/KClass;Lkotlinx/serialization/KSerializer;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Lcom/arkivanov/essenty/instancekeeper/InstanceKeeper$Instance;
10+
public static final fun rememberOnRoute (Lkotlin/reflect/KClass;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)Ljava/lang/Object;
2011
}
2112

2213
public final class io/github/xxfast/decompose/router/RouterContext : com/arkivanov/decompose/ComponentContext {

decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/Key.kt renamed to decompose-router/src/androidMain/kotlin/io/github/xxfast/decompose/router/Key.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.xxfast.decompose
1+
package io.github.xxfast.decompose.router
22

33
import kotlin.reflect.KClass
44

decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/SavedState.kt

Lines changed: 0 additions & 15 deletions
This file was deleted.

decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/Key.kt renamed to decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/Key.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.xxfast.decompose
1+
package io.github.xxfast.decompose.router
22

33
import kotlin.reflect.KClass
44

decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/RememberOnRoute.kt

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,33 @@ package io.github.xxfast.decompose.router
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.DisallowComposableCalls
5-
import androidx.compose.runtime.LaunchedEffect
65
import androidx.compose.runtime.remember
76
import com.arkivanov.essenty.instancekeeper.InstanceKeeper
8-
import com.arkivanov.essenty.instancekeeper.getOrCreate
9-
import com.arkivanov.essenty.statekeeper.StateKeeper
10-
import io.github.xxfast.decompose.SavedStateHandle
11-
import io.github.xxfast.decompose.key
12-
import kotlinx.serialization.KSerializer
13-
import kotlinx.serialization.Serializable
147
import kotlin.reflect.KClass
158

169
/***
17-
* Creates an instance of [T] that is scoped to the current route
10+
* Scopes instance of [T] to the current route
1811
*
1912
* @param type class of [T] instance
2013
* @param key key to remember the instance with. Defaults to [type]'s key
21-
* @param block lambda to create an instance of [T] with a given [SavedStateHandle]
14+
* @param block lambda to create an instance of [T] with a given [RouterContext]
2215
*/
2316
@Composable
24-
fun <T : InstanceKeeper.Instance, C: @Serializable Any> rememberOnRoute(
17+
fun <T: Any> rememberOnRoute(
2518
type: KClass<T>,
26-
strategy: KSerializer<C>,
2719
key: Any = type.key,
28-
block: @DisallowComposableCalls (savedState: SavedStateHandle) -> T
20+
block: @DisallowComposableCalls (context: RouterContext) -> T
2921
): T {
30-
val component: RouterContext = LocalRouterContext.current
31-
val stateKeeper: StateKeeper = component.stateKeeper
32-
val instanceKeeper: InstanceKeeper = component.instanceKeeper
33-
val instanceKey = "$key.instance"
34-
val stateKey = "$key.state"
35-
val (instance, savedState) = remember(key) {
36-
val savedState: SavedStateHandle = instanceKeeper
37-
.getOrCreate(stateKey) { SavedStateHandle(stateKeeper.consume(stateKey, strategy)) }
38-
var instance: T? = instanceKeeper.get(instanceKey) as T?
22+
class RouteInstance(val instance: T): InstanceKeeper.Instance
23+
val routerContext: RouterContext = LocalRouterContext.current
24+
val instanceKeeper: InstanceKeeper = routerContext.instanceKeeper
25+
val routeInstance: RouteInstance = remember(key) {
26+
var instance: RouteInstance? = instanceKeeper.get(key) as RouteInstance?
3927
if (instance == null) {
40-
instance = block(savedState)
41-
instanceKeeper.put(instanceKey, instance)
28+
instance = RouteInstance(block(routerContext))
29+
instanceKeeper.put(key, instance)
4230
}
43-
instance to savedState
31+
instance
4432
}
45-
46-
LaunchedEffect(Unit) {
47-
if (!stateKeeper.isRegistered(stateKey))
48-
stateKeeper.register(stateKey, strategy) { savedState.value as C? }
49-
}
50-
51-
return instance
33+
return routeInstance.instance
5234
}

decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/RouterContext.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import com.arkivanov.essenty.backhandler.BackHandler
88
import com.arkivanov.essenty.instancekeeper.InstanceKeeper
99
import com.arkivanov.essenty.lifecycle.Lifecycle
1010
import com.arkivanov.essenty.statekeeper.StateKeeper
11+
import kotlinx.serialization.InternalSerializationApi
12+
import kotlinx.serialization.KSerializer
13+
import kotlinx.serialization.Serializable
14+
import kotlinx.serialization.serializer
1115

1216
class RouterContext(
1317
private val delegate: ComponentContext,
@@ -23,7 +27,7 @@ class RouterContext(
2327
val storage: MutableMap<Any, Any> = HashMap()
2428
}
2529

26-
inline fun <reified T : Any> RouterContext.getOrCreate(key: Any, factory: () -> T) : T {
30+
inline fun <reified T : Any> RouterContext.getOrCreate(key: Any, factory: () -> T): T {
2731
var instance: T? = storage[key] as T?
2832
if (instance == null) {
2933
instance = factory()
@@ -41,3 +45,15 @@ inline fun <reified T : Any> RouterContext.getOrCreate(key: Any, factory: () ->
4145
*/
4246
val LocalRouterContext: ProvidableCompositionLocal<RouterContext> =
4347
staticCompositionLocalOf { error("Root RouterContext was not provided") }
48+
49+
@OptIn(InternalSerializationApi::class)
50+
inline fun <reified T : @Serializable Any> RouterContext.state(
51+
initial: T,
52+
key: String = T::class.key,
53+
serializer: KSerializer<T> = T::class.serializer(),
54+
noinline supplier: () -> T,
55+
): T {
56+
val state: T = stateKeeper.consume(key, serializer) ?: initial
57+
if (!stateKeeper.isRegistered(key)) stateKeeper.register(key, serializer, supplier)
58+
return state
59+
}

decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/State.kt renamed to decompose-router/src/commonMain/kotlin/io/github/xxfast/decompose/router/State.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.github.xxfast.decompose
1+
package io.github.xxfast.decompose.router
22

33
import androidx.compose.runtime.State
44
import androidx.compose.runtime.mutableStateOf

0 commit comments

Comments
 (0)