All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.io.github.takahirom.rin.RinExtensions.kt Maven / Gradle / Ivy

// Copyright (C) 2024 takahirom
// Copyright (C) 2022 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
package io.github.takahirom.rin

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.ProduceStateScope
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

private class ProduceRetainedStateScopeImpl(
    state: MutableState,
    override val coroutineContext: CoroutineContext,
) : ProduceStateScope, MutableState by state {

    override suspend fun awaitDispose(onDispose: () -> Unit): Nothing {
        try {
            suspendCancellableCoroutine {}
        } finally {
            onDispose()
        }
    }
}

@Composable
public fun  produceRetainedState(
    initialValue: T,
    producer: suspend ProduceStateScope.() -> Unit,
): State {
    val result = rememberRetained { mutableStateOf(initialValue) }
    LaunchedEffect(Unit) { ProduceRetainedStateScopeImpl(result, coroutineContext).producer() }
    return result
}

@Composable
public fun  Flow.collectAsRetainedState(
    initial: R,
    context: CoroutineContext = EmptyCoroutineContext,
): State =
    produceRetainedState(initial, this, context) {
        if (context == EmptyCoroutineContext) {
            collect { value = it }
        } else withContext(context) { collect { value = it } }
    }

@Composable
public fun  produceRetainedState(
    initialValue: T,
    key1: Any?,
    key2: Any?,
    producer: suspend ProduceStateScope.() -> Unit,
): State {
    val result = rememberRetained { mutableStateOf(initialValue) }
    LaunchedEffect(key1, key2) { ProduceRetainedStateScopeImpl(result, coroutineContext).producer() }
    return result
}

@Composable
public fun  StateFlow.collectAsRetainedState(
    context: CoroutineContext = EmptyCoroutineContext
): State = collectAsRetainedState(value, context)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy