From a559bad3eb31bee4ff479d25fef84adcad80ef43 Mon Sep 17 00:00:00 2001 From: Arkadii Ivanov Date: Mon, 4 Dec 2023 21:42:12 +0000 Subject: [PATCH] Removed deprecated Value#subscribe and Value#unsubscribe methods, renamed Value#observe to Value#subscribe --- decompose/api/android/decompose.api | 8 ++-- decompose/api/jvm/decompose.api | 8 ++-- .../decompose/value/MutableValueBuilder.kt | 24 +++++------ .../com/arkivanov/decompose/value/Value.kt | 31 +------------- .../com/arkivanov/decompose/value/ValueExt.kt | 8 ++-- .../arkivanov/decompose/value/operator/Map.kt | 37 ++--------------- .../decompose/value/MutableValueTest.kt | 14 +++---- .../decompose/value/operator/ValueMapTest.kt | 38 +++++++++--------- .../com/arkivanov/decompose/router/Utils.kt | 2 +- .../AbstractMutableValueThreadingTest.kt | 8 ++-- .../operator/AbstractValueMapThreadingTest.kt | 2 +- .../android/stack/StackRouterView.kt | 4 +- .../compose/jetbrains/SubscribeAsState.kt | 2 +- .../UserInterfaceState.xcuserstate | Bin 27977 -> 27541 bytes .../DecomposeHelpers/ObservableValue.swift | 2 +- .../shared/counters/counter/CounterView.kt | 6 +-- .../arkivanov/sample/shared/root/RootView.kt | 4 +- .../com/arkivanov/sample/shared/Utils.kt | 5 +-- 18 files changed, 66 insertions(+), 137 deletions(-) diff --git a/decompose/api/android/decompose.api b/decompose/api/android/decompose.api index bbb26bb14..b03747386 100644 --- a/decompose/api/android/decompose.api +++ b/decompose/api/android/decompose.api @@ -364,15 +364,13 @@ public final class com/arkivanov/decompose/value/ObserveLifecycleMode : java/lan public abstract class com/arkivanov/decompose/value/Value { public fun ()V public abstract fun getValue ()Ljava/lang/Object; - public final fun observe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; - public abstract fun subscribe (Lkotlin/jvm/functions/Function1;)V - public abstract fun unsubscribe (Lkotlin/jvm/functions/Function1;)V + public abstract fun subscribe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; } public final class com/arkivanov/decompose/value/ValueExtKt { public static final fun getValue (Lcom/arkivanov/decompose/value/Value;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; - public static final fun observe (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;)V - public static synthetic fun observe$default (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static final fun subscribe (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun subscribe$default (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V } public final class com/arkivanov/decompose/value/operator/MapKt { diff --git a/decompose/api/jvm/decompose.api b/decompose/api/jvm/decompose.api index 97a65ab17..5d1632ca5 100644 --- a/decompose/api/jvm/decompose.api +++ b/decompose/api/jvm/decompose.api @@ -350,15 +350,13 @@ public final class com/arkivanov/decompose/value/ObserveLifecycleMode : java/lan public abstract class com/arkivanov/decompose/value/Value { public fun ()V public abstract fun getValue ()Ljava/lang/Object; - public final fun observe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; - public abstract fun subscribe (Lkotlin/jvm/functions/Function1;)V - public abstract fun unsubscribe (Lkotlin/jvm/functions/Function1;)V + public abstract fun subscribe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; } public final class com/arkivanov/decompose/value/ValueExtKt { public static final fun getValue (Lcom/arkivanov/decompose/value/Value;Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; - public static final fun observe (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;)V - public static synthetic fun observe$default (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static final fun subscribe (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun subscribe$default (Lcom/arkivanov/decompose/value/Value;Lcom/arkivanov/essenty/lifecycle/Lifecycle;Lcom/arkivanov/decompose/value/ObserveLifecycleMode;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V } public final class com/arkivanov/decompose/value/operator/MapKt { diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/MutableValueBuilder.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/MutableValueBuilder.kt index 622db28b5..36d146394 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/MutableValueBuilder.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/MutableValueBuilder.kt @@ -1,12 +1,12 @@ package com.arkivanov.decompose.value +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Lock import com.arkivanov.decompose.synchronized /** * Returns a new instance of [MutableValue] initialized with the provided [initialValue]. */ -@Suppress("FunctionName") // Factory function fun MutableValue(initialValue: T): MutableValue = MutableValueImpl(initialValue) private class MutableValueImpl(initialValue: T) : MutableValue() { @@ -70,13 +70,13 @@ private class MutableValueImpl(initialValue: T) : MutableValue() { } } - @Deprecated( - "Calling this method from Swift leaks the observer, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - override fun subscribe(observer: (T) -> Unit) { + override fun subscribe(observer: (T) -> Unit): Cancellation { + subscribeObserver(observer) + + return Cancellation { unsubscribeObserver(observer) } + } + + private fun subscribeObserver(observer: (T) -> Unit) { lock.synchronized { if (observer in observers) { return @@ -103,13 +103,7 @@ private class MutableValueImpl(initialValue: T) : MutableValue() { } } - @Deprecated( - "Calling this method from Swift doesn't have any effect, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - override fun unsubscribe(observer: (T) -> Unit) { + private fun unsubscribeObserver(observer: (T) -> Unit) { lock.synchronized { observers -= observer } } } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/Value.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/Value.kt index 4bc1e9331..a4f665a60 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/Value.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/Value.kt @@ -14,39 +14,10 @@ abstract class Value { */ abstract val value: T - /** - * Subscribes the provided [observer] for value updates. The current value is emitted synchronously on subscription. - */ - @Deprecated( - message = "Calling this method from Swift leaks the observer, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - abstract fun subscribe(observer: (T) -> Unit) - - /** - * Unsubscribes the provided [observer] from value updates. - */ - @Deprecated( - message = "Calling this method from Swift doesn't have any effect, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - abstract fun unsubscribe(observer: (T) -> Unit) - /** * Subscribes the provided [observer] for value updates. The current value is emitted synchronously on subscription. * - * Note: most likely this method will be renamed to `subscribe` in the next major release, once deprecated methods are removed. - * * @return [Cancellation] token to cancel the subscription. */ - @Suppress("DEPRECATION") - fun observe(observer: (T) -> Unit): Cancellation { - subscribe(observer) - - return Cancellation { unsubscribe(observer) } - } + abstract fun subscribe(observer: (T) -> Unit): Cancellation } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/ValueExt.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/ValueExt.kt index 9542f9773..df0437e65 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/ValueExt.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/ValueExt.kt @@ -7,7 +7,7 @@ import kotlin.reflect.KProperty operator fun Value.getValue(thisRef: Any?, property: KProperty<*>): T = value -fun Value.observe( +fun Value.subscribe( lifecycle: Lifecycle, mode: ObserveLifecycleMode = ObserveLifecycleMode.START_STOP, observer: (T) -> Unit, @@ -17,19 +17,19 @@ fun Value.observe( when (mode) { ObserveLifecycleMode.CREATE_DESTROY -> lifecycle.subscribe( - onCreate = { cancellation = observe(observer) }, + onCreate = { cancellation = subscribe(observer) }, onDestroy = { cancellation?.cancel() }, ) ObserveLifecycleMode.START_STOP -> lifecycle.subscribe( - onStart = { cancellation = observe(observer) }, + onStart = { cancellation = subscribe(observer) }, onStop = { cancellation?.cancel() }, ) ObserveLifecycleMode.RESUME_PAUSE -> lifecycle.subscribe( - onResume = { cancellation = observe(observer) }, + onResume = { cancellation = subscribe(observer) }, onPause = { cancellation?.cancel() }, ) }.let {} diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/operator/Map.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/operator/Map.kt index 40a761003..94b2d7da0 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/operator/Map.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/value/operator/Map.kt @@ -1,5 +1,6 @@ package com.arkivanov.decompose.value.operator +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Lock import com.arkivanov.decompose.synchronized import com.arkivanov.decompose.value.Value @@ -14,7 +15,6 @@ private class MappedValue( private val lock = Lock() private var lastUpstreamValue: T = upstream.value private var lastMappedValue: R = mapper(lastUpstreamValue) - private var observers = HashMap<(R) -> Unit, (T) -> Unit>() override val value: R get() = mapCached(upstream.value) @@ -28,37 +28,6 @@ private class MappedValue( lastMappedValue } - @Deprecated( - "Calling this method from Swift leaks the observer, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - override fun subscribe(observer: (R) -> Unit) { - val upstreamObserver: (T) -> Unit = { value -> observer(mapCached(value)) } - - lock.synchronized { - if (observer in observers) { - return - } - - observers[observer] = upstreamObserver - } - - @Suppress("DEPRECATION") - upstream.subscribe(upstreamObserver) - } - - @Deprecated( - "Calling this method from Swift doesn't have any effect, " + - "because Kotlin wraps the function passed from Swift every time the method is called. " + - "Please use the new `observe` method which returns `Disposable`.", - level = DeprecationLevel.WARNING, - ) - override fun unsubscribe(observer: (R) -> Unit) { - val upstreamObserver = lock.synchronized { observers.remove(observer) } ?: return - - @Suppress("DEPRECATION") - upstream.unsubscribe(upstreamObserver) - } + override fun subscribe(observer: (R) -> Unit): Cancellation = + upstream.subscribe { observer(mapCached(it)) } } diff --git a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/MutableValueTest.kt b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/MutableValueTest.kt index da8dfc1a5..41d54c11e 100644 --- a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/MutableValueTest.kt +++ b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/MutableValueTest.kt @@ -27,7 +27,7 @@ class MutableValueTest { fun WHEN_subscribe_THEN_current_value_emitted() { val values = ArrayList() - value.observe { values += it } + value.subscribe { values += it } assertContentEquals(listOf(0), values) } @@ -37,7 +37,7 @@ class MutableValueTest { val values = List(10) { ArrayList() } repeat(10) { index -> - value.observe { values[index] += it } + value.subscribe { values[index] += it } } value.value = 1 @@ -50,7 +50,7 @@ class MutableValueTest { @Test fun GIVEN_unsubscribed_WHEN_value_changed_THEN_not_emitted() { val values = ArrayList() - val cancellation = value.observe { values += it } + val cancellation = value.subscribe { values += it } cancellation.cancel() values.clear() @@ -62,8 +62,8 @@ class MutableValueTest { @Test fun GIVEN_multiple_subscribes_and_one_unsubscribed_WHEN_value_changed_THEN_value_emitted_to_subscribed() { val values = ArrayList() - val cancellation = value.observe {} - value.observe { values += it } + val cancellation = value.subscribe {} + value.subscribe { values += it } cancellation.cancel() values.clear() @@ -75,8 +75,8 @@ class MutableValueTest { @Test fun GIVEN_multiple_subscribes_and_one_unsubscribed_WHEN_value_changed_THEN_value_not_emitted_to_unsubscribed() { val values = ArrayList() - val cancellation = value.observe { values += it } - value.observe {} + val cancellation = value.subscribe { values += it } + value.subscribe {} cancellation.cancel() values.clear() diff --git a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/operator/ValueMapTest.kt b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/operator/ValueMapTest.kt index fbda96e89..d54834ac5 100644 --- a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/operator/ValueMapTest.kt +++ b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/value/operator/ValueMapTest.kt @@ -25,7 +25,7 @@ class ValueMapTest { @Test fun GIVEN_subscribed_WHEN_upstream_changed_THEN_value_mapped() { - mapped.observe {} + mapped.subscribe {} upstream.value = "abcd" val value = mapped.value @@ -37,7 +37,7 @@ class ValueMapTest { fun WHEN_subscribe_THEN_current_value_emitted() { val values = ArrayList() - mapped.observe { values += it } + mapped.subscribe { values += it } assertContentEquals(listOf(3), values) } @@ -47,7 +47,7 @@ class ValueMapTest { val values = List(10) { ArrayList() } repeat(10) { index -> - mapped.observe { values[index] += it } + mapped.subscribe { values[index] += it } } upstream.value = "abcd" @@ -60,7 +60,7 @@ class ValueMapTest { @Test fun GIVEN_unsubscribed_WHEN_value_changed_THEN_not_emitted() { val values = ArrayList() - val cancellation = mapped.observe { values += it } + val cancellation = mapped.subscribe { values += it } cancellation.cancel() values.clear() @@ -72,8 +72,8 @@ class ValueMapTest { @Test fun GIVEN_multiple_subscribes_and_one_unsubscribed_WHEN_value_changed_THEN_value_emitted_to_subscribed() { val values = ArrayList() - val cancellation = mapped.observe {} - mapped.observe { values += it } + val cancellation = mapped.subscribe {} + mapped.subscribe { values += it } cancellation.cancel() values.clear() @@ -85,8 +85,8 @@ class ValueMapTest { @Test fun GIVEN_multiple_subscribes_and_one_unsubscribed_WHEN_value_changed_THEN_value_not_emitted_to_unsubscribed() { val values = ArrayList() - val cancellation = mapped.observe { values += it } - mapped.observe {} + val cancellation = mapped.subscribe { values += it } + mapped.subscribe {} cancellation.cancel() values.clear() @@ -106,9 +106,9 @@ class ValueMapTest { it.length } - mapped.observe {} - mapped.observe {} - mapped.observe {} + mapped.subscribe {} + mapped.subscribe {} + mapped.subscribe {} assertEquals(1, count) } @@ -124,9 +124,9 @@ class ValueMapTest { it.length } - mapped.observe {} - mapped.observe {} - mapped.observe {} + mapped.subscribe {} + mapped.subscribe {} + mapped.subscribe {} count = 0 upstream.value = "abcd" @@ -145,11 +145,11 @@ class ValueMapTest { it.length } - mapped.observe {} - mapped.observe {} + mapped.subscribe {} + mapped.subscribe {} upstream.value = "abcd" count = 0 - mapped.observe {} + mapped.subscribe {} assertEquals(0, count) @@ -166,8 +166,8 @@ class ValueMapTest { it.length } - mapped.observe {} - mapped.observe {} + mapped.subscribe {} + mapped.subscribe {} upstream.value = "abcd" count = 0 requireNotNull(upstream.value) diff --git a/decompose/src/jsMain/kotlin/com/arkivanov/decompose/router/Utils.kt b/decompose/src/jsMain/kotlin/com/arkivanov/decompose/router/Utils.kt index d6ef3a180..b1fc31f31 100644 --- a/decompose/src/jsMain/kotlin/com/arkivanov/decompose/router/Utils.kt +++ b/decompose/src/jsMain/kotlin/com/arkivanov/decompose/router/Utils.kt @@ -34,7 +34,7 @@ internal fun List.findFirstDifferentIndex(other: List): Int { internal fun Value.subscribe(observer: (new: T, old: T) -> Unit) { var old = value - observe { new -> + subscribe { new -> val tmp = old old = new observer(new, tmp) diff --git a/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/AbstractMutableValueThreadingTest.kt b/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/AbstractMutableValueThreadingTest.kt index 4cad19ea9..31535a5a0 100644 --- a/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/AbstractMutableValueThreadingTest.kt +++ b/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/AbstractMutableValueThreadingTest.kt @@ -16,7 +16,7 @@ abstract class AbstractMutableValueThreadingTest : AbstractThreadingTest() { var lastValue = 0 var counter = 0 - value.observe { + value.subscribe { repeat(1000) { counter++ } lastValue = it repeat(1000) { counter-- } @@ -41,7 +41,7 @@ abstract class AbstractMutableValueThreadingTest : AbstractThreadingTest() { var lastValue = 0 var counter = 0 - value.observe { + value.subscribe { repeat(1000) { counter++ } lastValue = it repeat(1000) { counter-- } @@ -68,7 +68,7 @@ abstract class AbstractMutableValueThreadingTest : AbstractThreadingTest() { var counter = 0 repeat(3) { - value.observe {} + value.subscribe {} } race { threadIndex -> @@ -76,7 +76,7 @@ abstract class AbstractMutableValueThreadingTest : AbstractThreadingTest() { value.update { it + 1 } if ((threadIndex == 0) && (index == iterationCount / 2)) { - value.observe { + value.subscribe { repeat(1000) { counter++ } lastValue = it repeat(1000) { counter-- } diff --git a/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/operator/AbstractValueMapThreadingTest.kt b/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/operator/AbstractValueMapThreadingTest.kt index d80625e38..ca287d9dd 100644 --- a/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/operator/AbstractValueMapThreadingTest.kt +++ b/decompose/src/nonJsTest/kotlin/com/arkivanov/decompose/value/operator/AbstractValueMapThreadingTest.kt @@ -22,7 +22,7 @@ abstract class AbstractValueMapThreadingTest : AbstractThreadingTest() { val counters = IntArray(observerCount) repeat(observerCount) { index -> - value.observe { + value.subscribe { repeat(1000) { counters[index]++ } lastValues[index] = it repeat(1000) { counters[index]-- } diff --git a/extensions-android/src/main/java/com/arkivanov/decompose/extensions/android/stack/StackRouterView.kt b/extensions-android/src/main/java/com/arkivanov/decompose/extensions/android/stack/StackRouterView.kt index 82b068c6c..151ab0896 100644 --- a/extensions-android/src/main/java/com/arkivanov/decompose/extensions/android/stack/StackRouterView.kt +++ b/extensions-android/src/main/java/com/arkivanov/decompose/extensions/android/stack/StackRouterView.kt @@ -20,7 +20,7 @@ import com.arkivanov.decompose.hashString import com.arkivanov.decompose.lifecycle.MergedLifecycle import com.arkivanov.decompose.router.stack.ChildStack import com.arkivanov.decompose.value.Value -import com.arkivanov.decompose.value.observe +import com.arkivanov.decompose.value.subscribe import com.arkivanov.essenty.lifecycle.Lifecycle import com.arkivanov.essenty.lifecycle.LifecycleRegistry import com.arkivanov.essenty.lifecycle.destroy @@ -43,7 +43,7 @@ class StackRouterView @JvmOverloads constructor( lifecycle: Lifecycle, replaceChildView: ViewContext.(parent: ViewGroup, newStack: ChildStack, oldStack: ChildStack?) -> Unit, ) { - stack.observe(lifecycle) { + stack.subscribe(lifecycle) { onStackChanged(it, lifecycle, replaceChildView) } } diff --git a/extensions-compose-jetbrains/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/jetbrains/SubscribeAsState.kt b/extensions-compose-jetbrains/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/jetbrains/SubscribeAsState.kt index 67246b0b1..99856df1d 100644 --- a/extensions-compose-jetbrains/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/jetbrains/SubscribeAsState.kt +++ b/extensions-compose-jetbrains/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/jetbrains/SubscribeAsState.kt @@ -20,7 +20,7 @@ fun Value.subscribeAsState(policy: SnapshotMutationPolicy = stru val state = remember(this, policy) { mutableStateOf(value, policy) } DisposableEffect(this) { - val disposable = observe { state.value = it } + val disposable = subscribe { state.value = it } onDispose { disposable.cancel() } } diff --git a/sample/app-ios-compose/app-ios-compose.xcodeproj/project.xcworkspace/xcuserdata/arkivanov.xcuserdatad/UserInterfaceState.xcuserstate b/sample/app-ios-compose/app-ios-compose.xcodeproj/project.xcworkspace/xcuserdata/arkivanov.xcuserdatad/UserInterfaceState.xcuserstate index b320fa017b542ca48e1dc8f16d4b29d9bb95d607..95ab41aad3b2209ae50397fc46601da7abbdcc82 100644 GIT binary patch delta 14621 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 delta 14625 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 : ObservableObject { init(_ value: Value) { self.value = value.value - self.cancellation = value.observe { [weak self] value in self?.value = value } + self.cancellation = value.subscribe { [weak self] value in self?.value = value } } deinit { diff --git a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/counters/counter/CounterView.kt b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/counters/counter/CounterView.kt index 31410148f..ac27dd692 100644 --- a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/counters/counter/CounterView.kt +++ b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/counters/counter/CounterView.kt @@ -7,7 +7,7 @@ import com.arkivanov.decompose.ExperimentalDecomposeApi import com.arkivanov.decompose.extensions.android.ViewContext import com.arkivanov.decompose.extensions.android.context import com.arkivanov.decompose.extensions.android.layoutInflater -import com.arkivanov.decompose.value.observe +import com.arkivanov.decompose.value.subscribe import com.arkivanov.essenty.lifecycle.subscribe import com.arkivanov.sample.shared.R import com.arkivanov.sample.shared.dialog.DialogComponent @@ -28,7 +28,7 @@ internal fun ViewContext.CounterView(component: CounterComponent): View { nextButton.setOnClickListener { component.onNextClicked() } prevButton.setOnClickListener { component.onPrevClicked() } - component.model.observe(lifecycle) { model -> + component.model.subscribe(lifecycle) { model -> toolbar.title = model.title if (model.isBackEnabled) { @@ -42,7 +42,7 @@ internal fun ViewContext.CounterView(component: CounterComponent): View { } var dialog: AlertDialog? = null - component.dialogSlot.observe(lifecycle) { model -> + component.dialogSlot.subscribe(lifecycle) { model -> val dialogComponent: DialogComponent? = model.child?.instance if ((dialogComponent != null) && (dialog == null)) { dialog = showDialog(component = dialogComponent) diff --git a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/root/RootView.kt b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/root/RootView.kt index aabf1d599..fc79e1b27 100644 --- a/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/root/RootView.kt +++ b/sample/shared/shared/src/androidMain/kotlin/com/arkivanov/sample/shared/root/RootView.kt @@ -5,7 +5,7 @@ import com.arkivanov.decompose.ExperimentalDecomposeApi import com.arkivanov.decompose.extensions.android.ViewContext import com.arkivanov.decompose.extensions.android.layoutInflater import com.arkivanov.decompose.extensions.android.stack.StackRouterView -import com.arkivanov.decompose.value.observe +import com.arkivanov.decompose.value.subscribe import com.arkivanov.sample.shared.R import com.arkivanov.sample.shared.beginDelayedSlideTransition import com.arkivanov.sample.shared.counters.CountersView @@ -64,7 +64,7 @@ fun ViewContext.RootView(component: RootComponent): View { navigationView.setOnNavigationItemSelectedListener(listener) - component.childStack.observe(lifecycle) { state -> + component.childStack.subscribe(lifecycle) { state -> navigationView.setOnNavigationItemSelectedListener(null) navigationView.selectedItemId = diff --git a/sample/shared/shared/src/jsMain/kotlin/com/arkivanov/sample/shared/Utils.kt b/sample/shared/shared/src/jsMain/kotlin/com/arkivanov/sample/shared/Utils.kt index 94b286811..195102776 100644 --- a/sample/shared/shared/src/jsMain/kotlin/com/arkivanov/sample/shared/Utils.kt +++ b/sample/shared/shared/src/jsMain/kotlin/com/arkivanov/sample/shared/Utils.kt @@ -12,9 +12,8 @@ internal fun Value.useAsState(): StateInstance { val (_, set) = state useEffectOnce { - val observer: (T) -> Unit = { set(it) } - subscribe(observer) - cleanup { unsubscribe(observer) } + val cancellation = subscribe { set(it) } + cleanup { cancellation.cancel() } } return state