Cleanup rememberMemorized
This commit is contained in:
1 parent
407c55dbdc
commit
3f6abd6380
2 files changed
+16
-43
No files matched your search
@@ -32,8 +32,6 @@ import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.paging.Pager
|
||||
@@ -70,10 +68,7 @@ import kotlinx.coroutines.launch
|
||||
import moe.tarsin.coroutines.runSuspendCatching
|
||||
import my.nanihadesuka.compose.LazyGridScrollbar
|
||||
|
||||
class VMStorage1 : ViewModel()
|
||||
|
||||
class GalleryPreviewScreen : Fragment() {
|
||||
private val vm: VMStorage1 by viewModels()
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = ComposeView(inflater.context).apply {
|
||||
setMD3Content {
|
||||
val galleryDetail = remember { requireArguments().getParcelableCompat<GalleryDetail>(KEY_GALLERY_DETAIL)!! }
|
||||
@@ -128,7 +123,7 @@ class GalleryPreviewScreen : Fragment() {
|
||||
}
|
||||
override val jumpingSupported = true
|
||||
}
|
||||
}.flow.cachedIn(vm.viewModelScope)
|
||||
}.flow.cachedIn(viewModelScope)
|
||||
}.collectAsLazyPagingItems()
|
||||
|
||||
Scaffold(
|
||||
|
||||
@@ -2,54 +2,32 @@ package com.hippo.ehviewer.ui.tools
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.currentCompositeKeyHash
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
|
||||
private val remembered = hashMapOf<String, Any>()
|
||||
class StateMapViewModel : ViewModel() {
|
||||
val states: MutableMap<Int, ArrayDeque<Any>> = mutableMapOf()
|
||||
}
|
||||
|
||||
// This works mostly like [rememberSaveable], but saves data in global hashmap, to avoid [TransactionTooLargeException]
|
||||
@Composable
|
||||
fun <T : Any> rememberMemorized(
|
||||
vararg inputs: Any?,
|
||||
key: String? = null,
|
||||
init: () -> T,
|
||||
init: ViewModel.() -> T,
|
||||
): T {
|
||||
// key is the one provided by the user or the one generated by the compose runtime
|
||||
val finalKey = if (!key.isNullOrEmpty()) {
|
||||
key
|
||||
} else {
|
||||
// currentCompositeKeyHash is unreliable here
|
||||
// Is this Composable inlined or its groups elided?
|
||||
// Or a compose compiler bug?
|
||||
init.javaClass.toString()
|
||||
}
|
||||
|
||||
val registry = LocalSaveableStateRegistry.current
|
||||
// value is restored using the registry or created via [init] lambda
|
||||
val vm: StateMapViewModel = viewModel()
|
||||
val key = currentCompositeKeyHash
|
||||
val value = remember(*inputs) {
|
||||
val states = vm.states[key] ?: ArrayDeque<Any>().also { vm.states[key] = it }
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val restored = registry?.consumeRestored(finalKey)?.let {
|
||||
remembered.remove(it as String)
|
||||
} as T?
|
||||
restored ?: init()
|
||||
states.removeFirstOrNull() as T? ?: init(vm)
|
||||
}
|
||||
|
||||
// re-register if the registry or key has been changed
|
||||
if (registry != null) {
|
||||
// we want to use the latest instances of saver and value in the valueProvider lambda
|
||||
// without restarting DisposableEffect as it would cause re-registering the provider in
|
||||
// the different order. so we use rememberUpdatedState.
|
||||
val valueState = rememberUpdatedState(value)
|
||||
|
||||
DisposableEffect(registry, finalKey) {
|
||||
val valueProvider = {
|
||||
finalKey.also { remembered[it] = valueState.value }
|
||||
}
|
||||
val entry = registry.registerProvider(finalKey, valueProvider)
|
||||
onDispose {
|
||||
entry.unregister()
|
||||
}
|
||||
val valueState = rememberUpdatedState(value)
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
vm.states[key]?.addFirst(valueState.value)
|
||||
}
|
||||
}
|
||||
return value
|
||||
|
||||
Reference in new issue
Block a user