diff --git a/decompose/api/android/decompose.api b/decompose/api/android/decompose.api index 54a9c63a3..763701bc7 100644 --- a/decompose/api/android/decompose.api +++ b/decompose/api/android/decompose.api @@ -111,8 +111,7 @@ public abstract interface class com/arkivanov/decompose/router/children/NavState } public abstract interface class com/arkivanov/decompose/router/children/NavigationSource { - 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/router/children/SimpleChildNavState : com/arkivanov/decompose/router/children/ChildNavState { @@ -131,8 +130,7 @@ public final class com/arkivanov/decompose/router/children/SimpleChildNavState : public final class com/arkivanov/decompose/router/children/SimpleNavigation : com/arkivanov/decompose/router/children/NavigationSource { public fun ()V public final fun navigate (Ljava/lang/Object;)V - public fun subscribe (Lkotlin/jvm/functions/Function1;)V - public fun unsubscribe (Lkotlin/jvm/functions/Function1;)V + public fun subscribe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; } public final class com/arkivanov/decompose/router/pages/ChildPages { diff --git a/decompose/api/jvm/decompose.api b/decompose/api/jvm/decompose.api index 0fa02f181..1461b8525 100644 --- a/decompose/api/jvm/decompose.api +++ b/decompose/api/jvm/decompose.api @@ -95,8 +95,7 @@ public abstract interface class com/arkivanov/decompose/router/children/NavState } public abstract interface class com/arkivanov/decompose/router/children/NavigationSource { - 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/router/children/SimpleChildNavState : com/arkivanov/decompose/router/children/ChildNavState { @@ -115,8 +114,7 @@ public final class com/arkivanov/decompose/router/children/SimpleChildNavState : public final class com/arkivanov/decompose/router/children/SimpleNavigation : com/arkivanov/decompose/router/children/NavigationSource { public fun ()V public final fun navigate (Ljava/lang/Object;)V - public fun subscribe (Lkotlin/jvm/functions/Function1;)V - public fun unsubscribe (Lkotlin/jvm/functions/Function1;)V + public fun subscribe (Lkotlin/jvm/functions/Function1;)Lcom/arkivanov/decompose/Cancellation; } public final class com/arkivanov/decompose/router/pages/ChildPages { diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/Relay.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/Relay.kt index ffd3e5404..dad154d6b 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/Relay.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/Relay.kt @@ -50,11 +50,11 @@ internal class Relay( } } - fun subscribe(observer: (T) -> Unit) { + fun subscribe(observer: (T) -> Unit): Cancellation { lock.synchronized { observers += observer } - } - fun unsubscribe(observer: (T) -> Unit) { - lock.synchronized { observers -= observer } + return Cancellation { + lock.synchronized { observers -= observer } + } } } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/ChildrenFactory.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/ChildrenFactory.kt index f37345e69..fe801d5ef 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/ChildrenFactory.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/ChildrenFactory.kt @@ -166,8 +166,8 @@ fun , S : Any> ComponentContext.child mainBackHandler.register(backCallback) - val eventObserver: (E) -> Unit = - { event -> + val cancellation = + source.subscribe { event -> val oldState = navigator.navState navigator.navigate(navState = navTransformer(navigator.navState, event)) val newState = navigator.navState @@ -175,10 +175,8 @@ fun , S : Any> ComponentContext.child onEventComplete(event, newState, oldState) } - source.subscribe(eventObserver) - lifecycle.doOnDestroy { - source.unsubscribe(eventObserver) + cancellation.cancel() stateKeeper.unregister(key = key) mainBackHandler.unregister(backCallback) } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/NavigationSource.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/NavigationSource.kt index e29ac4926..539a79c73 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/NavigationSource.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/NavigationSource.kt @@ -1,5 +1,7 @@ package com.arkivanov.decompose.router.children +import com.arkivanov.decompose.Cancellation + /** * Represents a generic source of navigation events. * @@ -7,7 +9,5 @@ package com.arkivanov.decompose.router.children */ interface NavigationSource { - fun subscribe(observer: (T) -> Unit) - - fun unsubscribe(observer: (T) -> Unit) + fun subscribe(observer: (T) -> Unit): Cancellation } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/SimpleNavigation.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/SimpleNavigation.kt index de9d56774..6270f2660 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/SimpleNavigation.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/SimpleNavigation.kt @@ -1,5 +1,6 @@ package com.arkivanov.decompose.router.children +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Relay /** @@ -10,13 +11,8 @@ class SimpleNavigation : NavigationSource { private val relay = Relay(isMainThreadCheckEnabled = true) - override fun subscribe(observer: (T) -> Unit) { + override fun subscribe(observer: (T) -> Unit): Cancellation = relay.subscribe(observer) - } - - override fun unsubscribe(observer: (T) -> Unit) { - relay.unsubscribe(observer) - } /** * Broadcasts the navigation event to every subscribed observer. diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/DefaultPagesNavigation.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/DefaultPagesNavigation.kt index cbe2d0209..8a57af499 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/DefaultPagesNavigation.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/DefaultPagesNavigation.kt @@ -1,5 +1,6 @@ package com.arkivanov.decompose.router.pages +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Relay import com.arkivanov.decompose.router.pages.PagesNavigationSource.Event @@ -7,13 +8,8 @@ internal class DefaultPagesNavigation : PagesNavigation { private val relay = Relay>() - override fun subscribe(observer: (Event) -> Unit) { + override fun subscribe(observer: (Event) -> Unit): Cancellation = relay.subscribe(observer) - } - - override fun unsubscribe(observer: (Event) -> Unit) { - relay.unsubscribe(observer) - } override fun navigate(transformer: (Pages) -> Pages, onComplete: (newPages: Pages, oldPages: Pages) -> Unit) { relay.accept(Event(transformer, onComplete)) diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/slot/DefaultSlotNavigation.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/slot/DefaultSlotNavigation.kt index b0c2502e3..811825880 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/slot/DefaultSlotNavigation.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/slot/DefaultSlotNavigation.kt @@ -1,5 +1,6 @@ package com.arkivanov.decompose.router.slot +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Relay import com.arkivanov.decompose.router.slot.SlotNavigationSource.Event @@ -14,11 +15,6 @@ internal class DefaultSlotNavigation : SlotNavigation { relay.accept(Event(transformer, onComplete)) } - override fun subscribe(observer: (Event) -> Unit) { + override fun subscribe(observer: (Event) -> Unit): Cancellation = relay.subscribe(observer) - } - - override fun unsubscribe(observer: (Event) -> Unit) { - relay.unsubscribe(observer) - } } diff --git a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/stack/DefaultStackNavigation.kt b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/stack/DefaultStackNavigation.kt index 8105ff371..d62333b02 100644 --- a/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/stack/DefaultStackNavigation.kt +++ b/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/stack/DefaultStackNavigation.kt @@ -1,5 +1,6 @@ package com.arkivanov.decompose.router.stack +import com.arkivanov.decompose.Cancellation import com.arkivanov.decompose.Relay import com.arkivanov.decompose.router.stack.StackNavigationSource.Event @@ -11,11 +12,6 @@ internal class DefaultStackNavigation : StackNavigation { relay.accept(Event(transformer, onComplete)) } - override fun subscribe(observer: (Event) -> Unit) { + override fun subscribe(observer: (Event) -> Unit): Cancellation = relay.subscribe(observer) - } - - override fun unsubscribe(observer: (Event) -> Unit) { - relay.unsubscribe(observer) - } } diff --git a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/RelayTest.kt b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/RelayTest.kt index 41a9c761d..b4f3cde13 100644 --- a/decompose/src/commonTest/kotlin/com/arkivanov/decompose/RelayTest.kt +++ b/decompose/src/commonTest/kotlin/com/arkivanov/decompose/RelayTest.kt @@ -38,8 +38,7 @@ class RelayTest { val relay = Relay() var isEmitted = false val observer: (Int) -> Unit = { isEmitted = true } - relay.subscribe(observer) - relay.unsubscribe(observer) + relay.subscribe(observer).cancel() relay.accept(1)