Skip to content

Commit

Permalink
Added STARTED status to ChildNavState
Browse files Browse the repository at this point in the history
  • Loading branch information
arkivanov committed Dec 5, 2023
1 parent 9ed0381 commit 7b4634d
Show file tree
Hide file tree
Showing 14 changed files with 860 additions and 245 deletions.
5 changes: 3 additions & 2 deletions decompose/api/android/decompose.api
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,10 @@ public abstract interface class com/arkivanov/decompose/router/children/ChildNav
}

public final class com/arkivanov/decompose/router/children/ChildNavState$Status : java/lang/Enum {
public static final field ACTIVE Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field CREATED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field DESTROYED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field INACTIVE Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field RESUMED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field STARTED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static fun values ()[Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
Expand Down
5 changes: 3 additions & 2 deletions decompose/api/jvm/decompose.api
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ public abstract interface class com/arkivanov/decompose/router/children/ChildNav
}

public final class com/arkivanov/decompose/router/children/ChildNavState$Status : java/lang/Enum {
public static final field ACTIVE Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field CREATED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field DESTROYED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field INACTIVE Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field RESUMED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static final field STARTED Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
public static fun values ()[Lcom/arkivanov/decompose/router/children/ChildNavState$Status;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,26 @@ interface ChildNavState<out C : Any> {
enum class Status {
/**
* The child component is destroyed but still managed, e.g. it's state may be saved and restored later.
* The state of the component is saved when it switches from any status to `DESTROYED` status.
*/
DESTROYED,

/**
* The child component is instantiated and inactive. Its maximum lifecycle state is `CREATED`,
* depending on the parent's lifecycle state. An inactive component cannot handle back button presses.
* The child component is instantiated and its maximum lifecycle state is `CREATED`,
* depending on the parent's lifecycle state. A `CREATED` component cannot handle back button presses.
*/
INACTIVE,
CREATED,

/**
* The child component is instantiated and active. Its maximum lifecycle state is `RESUMED`,
* depending on the parent's lifecycle state. An active component can handle back button presses.
* The state of the component is saved when it switches from `ACTIVE` to any other status.
* The child component is instantiated and its maximum lifecycle state is `STARTED`,
* depending on the parent's lifecycle state. An `STARTED` component can handle back button presses.
*/
ACTIVE,
STARTED,

/**
* The child component is instantiated and its maximum lifecycle state is `RESUMED`,
* depending on the parent's lifecycle state. A `RESUMED` component can handle back button presses.
*/
RESUMED,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import com.arkivanov.essenty.lifecycle.Lifecycle
import com.arkivanov.essenty.lifecycle.create
import com.arkivanov.essenty.lifecycle.destroy
import com.arkivanov.essenty.lifecycle.doOnDestroy
import com.arkivanov.essenty.lifecycle.pause
import com.arkivanov.essenty.lifecycle.resume
import com.arkivanov.essenty.lifecycle.start
import com.arkivanov.essenty.lifecycle.stop
import com.arkivanov.essenty.statekeeper.SerializableContainer

Expand Down Expand Up @@ -69,7 +71,7 @@ internal class ChildrenNavigator<out C : Any, out T : Any, N : NavState<C>>(
when (childNavState.status) {
Status.DESTROYED -> ChildItem.Destroyed(configuration = childNavState.configuration, savedState = savedState)

Status.INACTIVE -> {
Status.CREATED -> {
childItemFactory(
configuration = childNavState.configuration,
savedState = savedState,
Expand All @@ -80,7 +82,19 @@ internal class ChildrenNavigator<out C : Any, out T : Any, N : NavState<C>>(
}
}

Status.ACTIVE ->
Status.STARTED -> {
childItemFactory(
configuration = childNavState.configuration,
savedState = savedState,
instanceKeeperDispatcher = retainedChildren.remove(childNavState.configuration)?.instanceKeeperDispatcher,
).also {
it.backHandler.start()
retainedInstance.items += it
it.lifecycleRegistry.start()
}
}

Status.RESUMED ->
childItemFactory(
configuration = childNavState.configuration,
savedState = savedState,
Expand Down Expand Up @@ -134,37 +148,25 @@ internal class ChildrenNavigator<out C : Any, out T : Any, N : NavState<C>>(
when (state.status) {
Status.DESTROYED -> child to state.status

Status.INACTIVE ->
Status.CREATED,
Status.STARTED,
Status.RESUMED ->
Pair(
first = childItemFactory(
configuration = state.configuration,
savedState = child.savedState
).apply { lifecycleRegistry.create() },
second = state.status,
)

Status.ACTIVE ->
Pair(
first = childItemFactory(
configuration = state.configuration,
savedState = child.savedState,
).apply { lifecycleRegistry.create() },
second = state.status,
)
}

null ->
when (state.status) {
Status.DESTROYED -> ChildItem.Destroyed(configuration = state.configuration) to state.status

Status.INACTIVE ->
Pair(
first = childItemFactory(configuration = state.configuration)
.apply { lifecycleRegistry.create() },
second = state.status,
)

Status.ACTIVE ->
Status.CREATED,
Status.STARTED,
Status.RESUMED ->
Pair(
first = childItemFactory(configuration = state.configuration)
.apply { lifecycleRegistry.create() },
Expand Down Expand Up @@ -204,28 +206,43 @@ internal class ChildrenNavigator<out C : Any, out T : Any, N : NavState<C>>(
ChildItem.Destroyed(configuration = item.configuration, savedState = savedState)
}

Status.INACTIVE -> {
Status.CREATED -> {
retainedInstance.items += item

if (item.lifecycleRegistry.state != Lifecycle.State.CREATED) {
item.backHandler.stop()
item.lifecycleRegistry.stop()
}

item
.takeIf { it.lifecycleRegistry.state != Lifecycle.State.CREATED }
?.apply {
backHandler.stop()
lifecycleRegistry.stop()
}

Status.STARTED -> {
retainedInstance.items += item

when {
item.lifecycleRegistry.state < Lifecycle.State.STARTED -> {
item.backHandler.start()
item.lifecycleRegistry.start()
}

item.lifecycleRegistry.state > Lifecycle.State.STARTED -> {
item.lifecycleRegistry.pause()
}
?: item
}

item
}

Status.ACTIVE -> {
Status.RESUMED -> {
retainedInstance.items += item

if (item.lifecycleRegistry.state != Lifecycle.State.RESUMED) {
item.backHandler.start()
item.lifecycleRegistry.resume()
}

item
.takeIf { it.lifecycleRegistry.state != Lifecycle.State.RESUMED }
?.apply {
backHandler.start()
lifecycleRegistry.resume()
}
?: item
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import kotlinx.serialization.Serializable
* @param key a key of the list, must be unique if there are multiple Child Pages used in
* the same component.
* @param pageStatus a function that returns a [Status] of a page at a given index.
* By default, the currently selected page is [Status.ACTIVE], its two neighbours
* are [Status.INACTIVE], and the rest are [Status.DESTROYED]. You can implement your own
* By default, the currently selected page is [Status.RESUMED], its two neighbours
* are [Status.CREATED], and the rest are [Status.DESTROYED]. You can implement your own
* logic, for example with circular behaviour.
* @param handleBackButton determines whether the previous component should be automatically
* selected on back button press or not, default is `false`.
Expand Down Expand Up @@ -94,8 +94,8 @@ private class SerializablePages<out C : Any>(
* @param key a key of the list, must be unique if there are multiple Child Pages used in
* the same component.
* @param pageStatus a function that returns a [Status] of a page at a given index.
* By default, the currently selected page is [Status.ACTIVE], its two neighbours
* are [Status.INACTIVE], and the rest are [Status.DESTROYED]. You can implement your own
* By default, the currently selected page is [Status.RESUMED], its two neighbours
* are [Status.CREATED], and the rest are [Status.DESTROYED]. You can implement your own
* logic, for example with circular behaviour.
* @param handleBackButton determines whether the previous component should be automatically
* selected on back button press or not, default is `false`.
Expand Down Expand Up @@ -158,8 +158,8 @@ fun <C : Any, T : Any> ComponentContext.childPages(
@PublishedApi
internal fun getDefaultPageStatus(index: Int, pages: Pages<*>): Status =
when (index) {
pages.selectedIndex -> Status.ACTIVE
in (pages.selectedIndex - 1)..(pages.selectedIndex + 1) -> Status.INACTIVE
pages.selectedIndex -> Status.RESUMED
in (pages.selectedIndex - 1)..(pages.selectedIndex + 1) -> Status.CREATED
else -> Status.DESTROYED
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ private data class SlotNavState<out C : Any>(
if (configuration == null) {
emptyList()
} else {
listOf(SimpleChildNavState(configuration = configuration, status = Status.ACTIVE))
listOf(SimpleChildNavState(configuration = configuration, status = Status.RESUMED))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private data class StackNavState<out C : Any>(
configurations.mapIndexed { index, configuration ->
SimpleChildNavState(
configuration = configuration,
status = if (index == configurations.lastIndex) Status.ACTIVE else Status.INACTIVE,
status = if (index == configurations.lastIndex) Status.RESUMED else Status.CREATED,
)
}
}
Loading

0 comments on commit 7b4634d

Please sign in to comment.