Skip to content

Commit 60eb39d

Browse files
committed
Added ignoreEqual to beforeUpdate/afterUpdate/withSetter/toMutable
1 parent bcaa8d1 commit 60eb39d

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* Added `MutableStateFlow<T>.collectAsMutableStateWithLifecycle()`.
2222
* Added `childReactiveState` variant which takes an arbitrary event handler, so the parent ReactiveState doesn't have to implement the whole events interface.
2323
* Changed `MutableState.beforeUpdate`, `MutableState.afterUpdate` and `MutableState.withSetter` and `State.toMutable` to not be `@Composable`.
24+
* Added `ignoreEqual` (default true) to `MutableStateFlow.beforeUpdate`, `MutableStateFlow.afterUpdate` and `MutableStateFlow.withSetter` and `StateFlow.toMutable`.
2425
* Removed direct dependency on JUnit 4, so you can choose more freely which JUnit version to use.
2526
* Added `ifTake` and `unlessTake` inversions of `takeIf` and `takeUnless`.
2627
* Added `runIf` and `applyIf`.

reactivestate-core/src/commonMain/kotlin/com/ensody/reactivestate/StateFlowInterceptor.kt

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ import kotlinx.coroutines.sync.Mutex
1212
* The value is set automatically for you after [setter] has been called. For more control use [withSetter].
1313
* This can be used to wrap a [StateFlow]/[MutableStateFlow] with extra update logic.
1414
*/
15-
public fun <T> MutableStateFlow<T>.beforeUpdate(setter: (T) -> Unit): MutableStateFlow<T> =
16-
withSetter {
15+
public fun <T> MutableStateFlow<T>.beforeUpdate(
16+
ignoreEqual: Boolean = true,
17+
setter: (T) -> Unit,
18+
): MutableStateFlow<T> =
19+
withSetter(ignoreEqual = ignoreEqual) {
1720
setter(it)
1821
value = it
1922
}
@@ -24,8 +27,11 @@ public fun <T> MutableStateFlow<T>.beforeUpdate(setter: (T) -> Unit): MutableSta
2427
* The value is set automatically for you before [setter] has been called. For more control use [withSetter].
2528
* This can be used to wrap a [StateFlow]/[MutableStateFlow] with extra update logic.
2629
*/
27-
public fun <T> MutableStateFlow<T>.afterUpdate(setter: (T) -> Unit): MutableStateFlow<T> =
28-
withSetter {
30+
public fun <T> MutableStateFlow<T>.afterUpdate(
31+
ignoreEqual: Boolean = true,
32+
setter: (T) -> Unit,
33+
): MutableStateFlow<T> =
34+
withSetter(ignoreEqual = ignoreEqual) {
2935
value = it
3036
setter(it)
3137
}
@@ -40,29 +46,37 @@ public fun <T> MutableStateFlow<T>.afterUpdate(setter: (T) -> Unit): MutableStat
4046
* For simpler use cases you might prefer [beforeUpdate]/[afterUpdate] instead.
4147
*/
4248
public fun <T> MutableStateFlow<T>.withSetter(
49+
ignoreEqual: Boolean = true,
4350
setter: MutableStateFlow<T>.(T) -> Unit,
4451
): MutableStateFlow<T> =
45-
MutableStateFlowInterceptor(this, setter)
52+
MutableStateFlowInterceptor(this, ignoreEqual, setter)
4653

4754
/**
4855
* Converts this [StateFlow] to a [MutableStateFlow] that calls [setter] for doing the actual value update.
4956
*/
5057
public fun <T> StateFlow<T>.toMutable(
58+
ignoreEqual: Boolean = true,
5159
setter: StateFlow<T>.(T) -> Unit,
5260
): MutableStateFlow<T> =
53-
StateFlowInterceptor(this, setter)
61+
StateFlowInterceptor(this, ignoreEqual, setter)
5462

5563
private class MutableStateFlowInterceptor<T>(
5664
private val delegate: MutableStateFlow<T>,
65+
private val ignoreEqual: Boolean = true,
5766
private val setter: MutableStateFlow<T>.(T) -> Unit,
5867
) : MutableStateFlow<T> by delegate {
5968
override var value: T
6069
get() = delegate.value
61-
set(value) { delegate.setter(value) }
70+
set(value) {
71+
if (!ignoreEqual || this.value != value) {
72+
delegate.setter(value)
73+
}
74+
}
6275
}
6376

6477
private class StateFlowInterceptor<T>(
6578
private val delegate: StateFlow<T>,
79+
private val ignoreEqual: Boolean = true,
6680
private val setter: StateFlow<T>.(T) -> Unit,
6781
) : MutableStateFlow<T> {
6882

@@ -74,7 +88,11 @@ private class StateFlowInterceptor<T>(
7488

7589
override var value: T
7690
get() = delegate.value
77-
set(value) { delegate.setter(value) }
91+
set(value) {
92+
if (!ignoreEqual || this.value != value) {
93+
delegate.setter(value)
94+
}
95+
}
7896

7997
override suspend fun collect(collector: FlowCollector<T>): Nothing {
8098
subscriptionCount.increment()

0 commit comments

Comments
 (0)