diff --git a/README.md b/README.md index ffa739c..48a0b43 100644 --- a/README.md +++ b/README.md @@ -173,19 +173,71 @@ in order to create the `ViewState`. There are several implementations provided by VICE that cover common use cases. +### StateSource + +`StateSource` simply makes `ViceSource` implement Compose's `State` type, and by default provides [currentState] +with its value. + +`StateSource` can be used instead of the other `State` based sources if the stricter rules of an `abstract class` aren't needed. + +```kotlin +internal sealed interface MyFeatureDialogState { + data object None : MyFeatureDialogState + data class Error(val message: String) : MyFeatureDialogState +} + +internal class MyFeatureDialogSource : StateSource { + override var value: MyFeatureDialogState by mutableStateOf(MyFeatureDialogState.None) + private set + + fun clearError() { + value = MyFeatureDialogState.None + } + + fun showError(message: String) { + value = MyFeatureDialogState.Error(message) + } +} +``` + +`StateSource` can also be used to define a custom interface, and abstract +implementors of it (e.g. `MutableStateSource`, etc...) can be used to provide the implementation. + +```kotlin +internal sealed interface MyFeatureDialogState { + data object None : MyFeatureDialogState + data class Error(val message: String) : MyFeatureDialogState +} + +internal interface MyFeatureDialogSource : StateSource + +internal class RealMyFeatureDialogSource : MyFeatureDialogSource, MutableStateSource() { + override val initial = MyFeatureDialogState.None + + fun clearError() { + update(MyFeatureDialogState.None) + } + + fun showError(message: String) { + update( + MyFeatureDialogState.Error(message) + ) + } +} +``` + ### MutableStateSource `MutableStateSource` wraps a `MutableState`, and provides an `update` function for implementations to mutate it. Useful for encapsulating behavior around the `MutableState` instead of managing it in the `ViceCompositor`. - ```kotlin internal sealed interface MyFeatureDialogState { data object None : MyFeatureDialogState data class Error(val message: String) : MyFeatureDialogState } -internal class MyFeatureDialogSource : MutableStateSource { +internal class MyFeatureDialogSource : MutableStateSource() { override val initial = MyFeatureDialogState.None fun clearError() { @@ -207,7 +259,7 @@ internal class MyFeatureDialogSource : MutableStateSource ```kotlin -internal class MyCounterSource : SaveableMutableStateSource { +internal class MyCounterSource : SaveableMutableStateSource() { override val initial = 0 fun reset() { @@ -227,7 +279,7 @@ internal class MyCounterSource : SaveableMutableStateSource { ```kotlin internal class MyDerivedStateSource( private val fastChangingStateSource: FastChangingStateSource, -) : DerivedStateSource { +) : DerivedStateSource() { override fun deriveState(): MyDerivedState { val fastChangingState by fastChangingStateSource @@ -247,7 +299,7 @@ internal class MyDerivedStateSource( ```kotlin internal class MyFlowSource( private val featureRepo: MyFeatureRepository, -) : FlowSource> { +) : FlowSource>() { override val initial = emptyList() override val flow = featureRepo @@ -323,7 +375,7 @@ fun TodoListView( allows you to modify the `StateFlow` (which is usually implemented as a `MutableStateFlow`). ```kotlin -internal class TimerFlowSource : StateFlowSource { +internal class TimerFlowSource : StateFlowSource() { override val flow = MutableStateFlow(0) override suspend fun onAttached(scope: CoroutineScope) { diff --git a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/DerivedStateSource.kt b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/DerivedStateSource.kt index 5c37004..9871a18 100644 --- a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/DerivedStateSource.kt +++ b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/DerivedStateSource.kt @@ -2,13 +2,11 @@ package com.eygraber.vice.sources import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.runtime.State import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.snapshotFlow -import com.eygraber.vice.ViceSource import kotlinx.coroutines.flow.Flow -public abstract class DerivedStateSource : ViceSource, State { +public abstract class DerivedStateSource : StateSource { protected abstract fun deriveState(): T private val state by lazy { diff --git a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/MutableStateSource.kt b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/MutableStateSource.kt index 808fe80..324853f 100644 --- a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/MutableStateSource.kt +++ b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/MutableStateSource.kt @@ -2,13 +2,11 @@ package com.eygraber.vice.sources import androidx.compose.runtime.Composable import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshotFlow -import com.eygraber.vice.ViceSource import kotlinx.coroutines.flow.Flow -public abstract class MutableStateSource : ViceSource, State { +public abstract class MutableStateSource : StateSource { private val state by lazy { mutableStateOf(initial) } diff --git a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/SaveableMutableStateSource.kt b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/SaveableMutableStateSource.kt index afd4197..8cc25c3 100644 --- a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/SaveableMutableStateSource.kt +++ b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/SaveableMutableStateSource.kt @@ -1,17 +1,15 @@ package com.eygraber.vice.sources import androidx.compose.runtime.Composable -import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.Saver import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.snapshotFlow -import com.eygraber.vice.ViceSource import kotlinx.coroutines.flow.Flow public abstract class SaveableMutableStateSource( private val saver: Saver? = null, -) : ViceSource, State { +) : StateSource { private val state by lazy { mutableStateOf(initial) } diff --git a/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/StateSource.kt b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/StateSource.kt new file mode 100644 index 0000000..543cfd9 --- /dev/null +++ b/vice-sources/src/commonMain/kotlin/com/eygraber/vice/sources/StateSource.kt @@ -0,0 +1,12 @@ +package com.eygraber.vice.sources + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.State +import com.eygraber.vice.ViceSource + +public interface StateSource : ViceSource, State { + @Composable + @ReadOnlyComposable + override fun currentState(): T = value +}