Code tweaks

This commit is contained in:
vfsfitvnm
2022-09-26 21:36:05 +02:00
parent f981725062
commit 82c2a952aa
15 changed files with 284 additions and 337 deletions

View File

@@ -1,102 +0,0 @@
package it.vfsfitvnm.vimusic.utils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import it.vfsfitvnm.vimusic.savers.ListSaver
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.flowOn
@Composable
fun <T> produceSaveableListState(
flowProvider: () -> Flow<List<T>>,
stateSaver: ListSaver<T, List<Any?>>,
): State<List<T>> {
val state = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(emptyList())
}
var hasToRecollect by rememberSaveable {
mutableStateOf(true)
}
LaunchedEffect(Unit) {
flowProvider()
.flowOn(Dispatchers.IO)
.drop(if (hasToRecollect) 0 else 1)
.collect {
hasToRecollect = false
state.value = it
}
}
return state
}
@Composable
fun <T> produceSaveableListState(
flowProvider: () -> Flow<List<T>>,
stateSaver: ListSaver<T, List<Any?>>,
key1: Any?,
): State<List<T>> {
val state = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(emptyList())
}
var hasToRecollect by rememberSaveable(key1) {
// println("hasToRecollect: $sortBy, $sortOrder")
mutableStateOf(true)
}
LaunchedEffect(key1) {
// println("[${System.currentTimeMillis()}] LaunchedEffect, $hasToRecollect, $sortBy, $sortOrder")
flowProvider()
.flowOn(Dispatchers.IO)
.drop(if (hasToRecollect) 0 else 1)
.collect {
hasToRecollect = false
// println("[${System.currentTimeMillis()}] collecting... ")
state.value = it
}
}
return state
}
@Composable
fun <T> produceSaveableListState(
flowProvider: () -> Flow<List<T>>,
stateSaver: ListSaver<T, List<Any?>>,
key1: Any?,
key2: Any?,
): State<List<T>> {
val state = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(emptyList())
}
// var hasToRecollect by rememberSaveable(key1, key2) {
//// println("hasToRecollect: $sortBy, $sortOrder")
// mutableStateOf(true)
// }
LaunchedEffect(key1, key2) {
// println("[${System.currentTimeMillis()}] LaunchedEffect, $hasToRecollect, $sortBy, $sortOrder")
flowProvider()
.flowOn(Dispatchers.IO)
// .drop(if (hasToRecollect) 0 else 1)
.collect {
// hasToRecollect = false
// println("[${System.currentTimeMillis()}] collecting... ")
state.value = it
}
}
return state
}

View File

@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalTypeInference::class)
package it.vfsfitvnm.vimusic.utils
import androidx.compose.runtime.Composable
@@ -14,27 +16,23 @@ import kotlin.coroutines.CoroutineContext
import kotlin.experimental.ExperimentalTypeInference
import kotlinx.coroutines.suspendCancellableCoroutine
@OptIn(ExperimentalTypeInference::class)
@Composable
fun <T> produceSaveableState(
initialValue: T,
stateSaver: Saver<T, out Any>,
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
): State<T> {
val result = rememberSaveable(stateSaver = stateSaver) { mutableStateOf(initialValue) }
var hasToFetch by rememberSaveable { mutableStateOf(true) }
val result = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(initialValue)
}
LaunchedEffect(Unit) {
if (hasToFetch) {
ProduceSaveableStateScope(result, coroutineContext).producer()
hasToFetch = false
}
ProduceSaveableStateScope(result, coroutineContext).producer()
}
return result
}
@OptIn(ExperimentalTypeInference::class)
@Composable
fun <T> produceSaveableState(
initialValue: T,
@@ -42,20 +40,42 @@ fun <T> produceSaveableState(
key1: Any?,
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
): State<T> {
val result = rememberSaveable(stateSaver = stateSaver) { mutableStateOf(initialValue) }
var hasToFetch by rememberSaveable(key1) { mutableStateOf(true) }
val state = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(initialValue)
}
LaunchedEffect(key1) {
if (hasToFetch) {
ProduceSaveableStateScope(result, coroutineContext).producer()
hasToFetch = false
}
ProduceSaveableStateScope(state, coroutineContext).producer()
}
return result
return state
}
@Composable
fun <T> produceSaveableOneShotState(
initialValue: T,
stateSaver: Saver<T, out Any>,
key1: Any?,
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
): State<T> {
val state = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(initialValue)
}
var produced by rememberSaveable(key1) {
mutableStateOf(false)
}
LaunchedEffect(key1) {
if (!produced) {
ProduceSaveableStateScope(state, coroutineContext).producer()
produced = true
}
}
return state
}
@OptIn(ExperimentalTypeInference::class)
@Composable
fun <T> produceSaveableState(
initialValue: T,
@@ -64,42 +84,42 @@ fun <T> produceSaveableState(
key2: Any?,
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
): State<T> {
val result = rememberSaveable(stateSaver = stateSaver) { mutableStateOf(initialValue) }
val result = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(initialValue)
}
var hasToFetch by rememberSaveable(key1, key2) { mutableStateOf(true) }
LaunchedEffect(Unit) {
if (hasToFetch) {
ProduceSaveableStateScope(result, coroutineContext).producer()
hasToFetch = false
}
LaunchedEffect(key1, key2) {
ProduceSaveableStateScope(result, coroutineContext).producer()
}
return result
}
@OptIn(ExperimentalTypeInference::class)
@Composable
fun <T> produceSaveableRelaunchableState(
fun <T> produceSaveableRelaunchableOneShotState(
initialValue: T,
stateSaver: Saver<T, out Any>,
key1: Any?,
key2: Any?,
@BuilderInference producer: suspend ProduceStateScope<T>.() -> Unit
): Pair<State<T>, () -> Unit> {
val result = rememberSaveable(stateSaver = stateSaver) { mutableStateOf(initialValue) }
val result = rememberSaveable(stateSaver = stateSaver) {
mutableStateOf(initialValue)
}
var hasToFetch by rememberSaveable(key1, key2) { mutableStateOf(true) }
var produced by rememberSaveable(key1, key2) {
mutableStateOf(false)
}
val relaunchableEffect = relaunchableEffect(key1, key2) {
if (hasToFetch) {
if (!produced) {
ProduceSaveableStateScope(result, coroutineContext).producer()
hasToFetch = false
produced = true
}
}
return result to {
hasToFetch = true
produced = false
relaunchableEffect()
}
}

View File

@@ -1,61 +0,0 @@
package it.vfsfitvnm.vimusic.utils
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.saveable.listSaver
import androidx.compose.runtime.saveable.rememberSaveable
@Composable
fun rememberLazyListStates(count: Int): List<LazyListState> {
return rememberSaveable(
saver = listSaver(
save = { states: List<LazyListState> ->
List(states.size * 2) {
when (it % 2) {
0 -> states[it / 2].firstVisibleItemIndex
1 -> states[it / 2].firstVisibleItemScrollOffset
else -> error("unreachable")
}
}
},
restore = { states ->
List(states.size / 2) {
LazyListState(
firstVisibleItemIndex = states[it * 2],
firstVisibleItemScrollOffset = states[it * 2 + 1]
)
}
}
)
) {
List(count) { LazyListState(0, 0) }
}
}
@Composable
fun rememberLazyGridStates(count: Int): List<LazyGridState> {
return rememberSaveable(
saver = listSaver(
save = { states: List<LazyGridState> ->
List(states.size * 2) {
when (it % 2) {
0 -> states[it / 2].firstVisibleItemIndex
1 -> states[it / 2].firstVisibleItemScrollOffset
else -> error("unreachable")
}
}
},
restore = { states ->
List(states.size / 2) {
LazyGridState(
firstVisibleItemIndex = states[it * 2],
firstVisibleItemScrollOffset = states[it * 2 + 1]
)
}
}
)
) {
List(count) { LazyGridState(0, 0) }
}
}