Skip to content

Commit

Permalink
Merge pull request #657 from zsoltk/refactor-node-parentnode
Browse files Browse the repository at this point in the history
Rename ParentNode & Node to Node and LeafNode
  • Loading branch information
zsoltk authored Jan 19, 2024
2 parents 5fda841 + eba508c commit d5a2406
Show file tree
Hide file tree
Showing 87 changed files with 540 additions and 540 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ Please refer to [2.0.0-alpha10 – Migration guide](2.0.0-alpha10.md)
- [#642](https://github.com/bumble-tech/appyx/pull/642) – Renamings
- [#643](https://github.com/bumble-tech/appyx/pull/643) – Unify AppyxComponent composable between appyx-navigation and appyx-interactions modules
- [#651](https://github.com/bumble-tech/appyx/pull/651) - Keep only one instance of SaveStateMap typealias and moved it to `com.bumble.appyx.utils.multiplatform` package
- [#654](https://github.com/bumble-tech/appyx/pull/654) - Renamings
- [#652](https://github.com/bumble-tech/appyx/pull/652) - KSP processor renamed from `mutable-ui-processor` to `appyx-processor`
- [#654](https://github.com/bumble-tech/appyx/pull/654) - Renamings
- [#657](https://github.com/bumble-tech/appyx/pull/657) - Rename ParentNode & Node to Node and LeafNode

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.bumble.appyx.utils.testing.ui.rules.AppyxTestActivity
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

class AppyxTestScenario<T : Node>(
class AppyxTestScenario<T : Node<*>>(
private val composeTestRule: ComposeTestRule = createEmptyComposeRule(),
/** Add decorations like custom theme or CompositionLocalProvider. Do not forget to invoke `content()`. */
private val decorator: (@Composable (content: @Composable () -> Unit) -> Unit) = { content -> content() },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.bumble.appyx.navigation.AppyxTestScenario
import com.bumble.appyx.navigation.children.nodeOrNull
import com.bumble.appyx.navigation.composable.PermanentChild
import com.bumble.appyx.navigation.modality.NodeContext
import com.bumble.appyx.navigation.node.PermanentChildTest.TestParentNode.Child
import com.bumble.appyx.navigation.node.PermanentChildTest.TestNode.Child
import com.bumble.appyx.utils.multiplatform.Parcelable
import com.bumble.appyx.utils.multiplatform.Parcelize
import org.junit.Assert.assertEquals
Expand All @@ -22,8 +22,8 @@ import org.junit.Test

class PermanentChildTest {

var nodeFactory: (nodeContext: NodeContext) -> TestParentNode = {
TestParentNode(nodeContext = it)
var nodeFactory: (nodeContext: NodeContext) -> TestNode = {
TestNode(nodeContext = it)
}

@get:Rule
Expand Down Expand Up @@ -65,7 +65,7 @@ class PermanentChildTest {

private fun createPermanentAppyxComponentWithInteractionKey() {
nodeFactory = {
TestParentNode(
TestNode(
nodeContext = it,
permanentAppyxComponent = PermanentAppyxComponent(
savedStateMap = null,
Expand All @@ -76,11 +76,11 @@ class PermanentChildTest {

}

class TestParentNode(
class TestNode(
nodeContext: NodeContext,
private val permanentAppyxComponent: PermanentAppyxComponent<Child> =
PermanentAppyxComponent(savedStateMap = nodeContext.savedStateMap)
) : ParentNode<Child>(
) : Node<Child>(
nodeContext = nodeContext,
appyxComponent = permanentAppyxComponent
) {
Expand All @@ -90,7 +90,7 @@ class PermanentChildTest {

var renderPermanentChild by mutableStateOf(true)

override fun buildChildNode(navTarget: Child, nodeContext: NodeContext): Node =
override fun buildChildNode(navTarget: Child, nodeContext: NodeContext): Node<*> =
node(nodeContext) { modifier ->
BasicText(
text = navTarget.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import com.bumble.appyx.utils.customisations.NodeCustomisationDirectoryImpl


/**
* Composable function to host [Node].
* Composable function to host [Node<*>].
*
* This wrapper uses [LocalConfiguration] to provide [ScreenSize] automatically.
*/
@Suppress("ComposableParamOrder") // detekt complains as 'factory' param isn't a pure lambda
@Composable
fun <N : Node> NodeHost(
fun <N : Node<*>> NodeHost(
lifecycle: Lifecycle,
integrationPoint: IntegrationPoint,
modifier: Modifier = Modifier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package com.bumble.appyx.navigation.node

import com.bumble.appyx.navigation.platform.PlatformLifecycleRegistry

val Node.androidLifecycle: androidx.lifecycle.Lifecycle
val Node<*>.androidLifecycle: androidx.lifecycle.Lifecycle
get() = (lifecycle as PlatformLifecycleRegistry).androidLifecycleRegistry
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import com.bumble.appyx.navigation.node.Node
// Changing this to an interface would be a breaking change
@Suppress("UnnecessaryAbstractClass")
abstract class Builder<P> {
abstract fun build(nodeContext: NodeContext, payload: P): Node
abstract fun build(nodeContext: NodeContext, payload: P): Node<*>
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ import com.bumble.appyx.navigation.node.Node
// Changing this to an interface would be a breaking change
@Suppress("UnnecessaryAbstractClass")
abstract class SimpleBuilder {
abstract fun build(nodeContext: NodeContext): Node
abstract fun build(nodeContext: NodeContext): Node<*>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.bumble.appyx.navigation.node.Node
import com.bumble.appyx.navigation.plugin.NodeAware
import kotlin.reflect.KClass

interface ChildAware<N: Node> : NodeAware<N> {
interface ChildAware<N: Node<*>> : NodeAware<N> {

fun <T : Any> whenChildAttached(
child: KClass<T>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import kotlin.reflect.safeCast

internal sealed class ChildAwareCallbackInfo {

abstract fun onRegistered(activeNodes: List<Node>)
abstract fun onRegistered(activeNodes: List<Node<*>>)

class Single<T : Any>(
private val child: KClass<T>,
private val callback: ChildCallback<T>,
private val parentLifecycle: Lifecycle,
) : ChildAwareCallbackInfo() {

fun onNewNodeAppeared(newNode: Node) {
fun onNewNodeAppeared(newNode: Node<*>) {
if (parentLifecycle.isDestroyed) return
val castedNode = child.safeCast(newNode)
if (castedNode != null) {
Expand All @@ -31,7 +31,7 @@ internal sealed class ChildAwareCallbackInfo {
}
}

override fun onRegistered(activeNodes: List<Node>) {
override fun onRegistered(activeNodes: List<Node<*>>) {
activeNodes.forEach { node ->
onNewNodeAppeared(node)
}
Expand All @@ -47,17 +47,17 @@ internal sealed class ChildAwareCallbackInfo {
) : ChildAwareCallbackInfo() {

fun onNewNodeAppeared(
activeNodes: Collection<Node>,
newNode: Node,
ignoreNodes: Set<Node>,
activeNodes: Collection<Node<*>>,
newNode: Node<*>,
ignoreNodes: Set<Node<*>>,
) {
val second = getOther(newNode) ?: return
activeNodes
.filter { second.isInstance(it) && it != newNode && it !in ignoreNodes }
.forEach { notify(newNode, it) }
}

override fun onRegistered(activeNodes: List<Node>) {
override fun onRegistered(activeNodes: List<Node<*>>) {
activeNodes.forEachIndexed { index, node ->
onNewNodeAppeared(
// Do not include already handled nodes to avoid call duplication
Expand All @@ -68,7 +68,7 @@ internal sealed class ChildAwareCallbackInfo {
}
}

private fun notify(node1: Node, node2: Node) {
private fun notify(node1: Node<*>, node2: Node<*>) {
if (parentLifecycle.isDestroyed) return
val lifecycle =
MinimumCombinedLifecycle(
Expand All @@ -83,7 +83,7 @@ internal sealed class ChildAwareCallbackInfo {
}
}

private fun getOther(node: Node): KClass<*>? =
private fun getOther(node: Node<*>): KClass<*>? =
when {
child1.isInstance(node) -> child2
child2.isInstance(node) -> child1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package com.bumble.appyx.navigation.children

import com.bumble.appyx.navigation.node.Node

inline fun <reified T : Node> ChildAware<*>.whenChildAttached(
inline fun <reified T : Node<*>> ChildAware<*>.whenChildAttached(
noinline callback: ChildCallback<T>,
) {
whenChildAttached(T::class, callback)
}

inline fun <reified T1 : Node, reified T2 : Node> ChildAware<*>.whenChildrenAttached(
inline fun <reified T1 : Node<*>, reified T2 : Node<*>> ChildAware<*>.whenChildrenAttached(
noinline callback: ChildrenCallback<T1, T2>,
) {
whenChildrenAttached(T1::class, T2::class, callback)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import com.bumble.appyx.interactions.core.Element
import com.bumble.appyx.navigation.lifecycle.DefaultPlatformLifecycleObserver
import com.bumble.appyx.navigation.lifecycle.Lifecycle
import com.bumble.appyx.navigation.lifecycle.isDestroyed
import com.bumble.appyx.navigation.node.LeafNode
import com.bumble.appyx.navigation.node.Node
import com.bumble.appyx.navigation.node.ParentNode
import com.bumble.appyx.navigation.withPrevious
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -14,7 +14,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlin.reflect.KClass

class ChildAwareImpl<N : Node> : ChildAware<N> {
class ChildAwareImpl<N : Node<*>> : ChildAware<N> {

private val callbacks: MutableList<ChildAwareCallbackInfo> = ArrayList()

Expand All @@ -29,11 +29,11 @@ class ChildAwareImpl<N : Node> : ChildAware<N> {
this.node = node
lifecycle = node.lifecycle
coroutineScope = lifecycle.coroutineScope
if (node is ParentNode<*>) {
if (node is LeafNode) {
children = MutableStateFlow(emptyMap())
} else {
children = node.children
coroutineScope.launch { observeChanges() }
} else {
children = MutableStateFlow(emptyMap())
}
}

Expand All @@ -43,7 +43,7 @@ class ChildAwareImpl<N : Node> : ChildAware<N> {
.withPrevious()
.collect { (previous, current) ->
val newNodes = current - previous.orEmpty()
val visitedSet = HashSet<Node>()
val visitedSet = HashSet<Node<*>>()
newNodes.forEach { node ->
notifyWhenChanged(node, current, visitedSet)
visitedSet.add(node)
Expand Down Expand Up @@ -78,7 +78,7 @@ class ChildAwareImpl<N : Node> : ChildAware<N> {
callback.onRegistered(getCreatedNodes(children.value))
}

private fun notifyWhenChanged(child: Node, nodes: Collection<Node>, ignore: Set<Node>) {
private fun notifyWhenChanged(child: Node<*>, nodes: Collection<Node<*>>, ignore: Set<Node<*>>) {
for (callback in callbacks) {
when (callback) {
is ChildAwareCallbackInfo.Double<*, *> -> callback.onNewNodeAppeared(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ sealed class ChildEntry<T> {
/** All public APIs should return this type of child which is ready to work with. */
class Initialized<T>(
override val key: Element<T>,
val node: Node,
val node: Node<*>,
) : ChildEntry<T>()

class Suspended<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.bumble.appyx.navigation.children

import com.bumble.appyx.navigation.node.Node

val <T> ChildEntry<T>.nodeOrNull: Node?
val <T> ChildEntry<T>.nodeOrNull: Node<*>?
get() =
when (this) {
is ChildEntry.Initialized -> node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import com.bumble.appyx.navigation.node.Node

fun interface ChildNodeBuilder<NavTarget> {

fun buildChildNode(navTarget: NavTarget, nodeContext: NodeContext): Node
fun buildChildNode(navTarget: NavTarget, nodeContext: NodeContext): Node<*>
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.bumble.appyx.interactions.core.Element
import com.bumble.appyx.interactions.core.state.MutableSavedStateMap
import com.bumble.appyx.navigation.modality.AncestryInfo
import com.bumble.appyx.navigation.modality.NodeContext
import com.bumble.appyx.navigation.node.ParentNode
import com.bumble.appyx.navigation.node.Node
import com.bumble.appyx.navigation.node.build
import com.bumble.appyx.utils.multiplatform.SavedStateMap
import com.bumble.appyx.utils.customisations.NodeCustomisationDirectory
Expand All @@ -25,23 +25,23 @@ internal class ChildNodeCreationManager<NavTarget : Any>(
private val customisations: NodeCustomisationDirectory,
private val keepMode: ChildEntry.KeepMode,
) {
private lateinit var parentNode: ParentNode<NavTarget>
private lateinit var node: Node<NavTarget>
private val _children =
MutableStateFlow<Map<Element<NavTarget>, ChildEntry<NavTarget>>>(emptyMap())
val children: StateFlow<ChildEntryMap<NavTarget>> = _children.asStateFlow()

fun launch(parentNode: ParentNode<NavTarget>) {
this.parentNode = parentNode
fun launch(node: Node<NavTarget>) {
this.node = node
savedStateMap.restoreChildren()?.also { restoredMap ->
_children.update { restoredMap }
savedStateMap = null
}
syncAppyxComponentWithChildren(parentNode)
syncAppyxComponentWithChildren(node)
}

private fun syncAppyxComponentWithChildren(parentNode: ParentNode<NavTarget>) {
parentNode.lifecycle.coroutineScope.launch {
parentNode.appyxComponent.elements.collect { state ->
private fun syncAppyxComponentWithChildren(node: Node<NavTarget>) {
node.lifecycle.coroutineScope.launch {
node.appyxComponent.elements.collect { state ->
val appyxComponentKeepKeys: Set<Element<NavTarget>>
val appyxComponentSuspendKeys: Set<Element<NavTarget>>
val appyxComponentKeys: Set<Element<NavTarget>>
Expand Down Expand Up @@ -165,9 +165,9 @@ internal class ChildNodeCreationManager<NavTarget : Any>(

private fun childContext(savedState: SavedStateMap?): NodeContext =
NodeContext(
ancestryInfo = AncestryInfo.Child(parentNode),
ancestryInfo = AncestryInfo.Child(node),
savedStateMap = savedState,
customisations = customisations.getSubDirectoryOrSelf(parentNode::class),
customisations = customisations.getSubDirectoryOrSelf(node::class),
)

private fun childEntry(
Expand All @@ -180,7 +180,7 @@ internal class ChildNodeCreationManager<NavTarget : Any>(
} else {
ChildEntry.Initialized(
key = key,
node = parentNode
node = node
.buildChildNode(key.interactionTarget, childContext(savedState))
.build()
)
Expand All @@ -192,7 +192,7 @@ internal class ChildNodeCreationManager<NavTarget : Any>(
is ChildEntry.Suspended ->
ChildEntry.Initialized(
key = key,
node = parentNode.buildChildNode(
node = node.buildChildNode(
navTarget = key.interactionTarget,
nodeContext = childContext(savedState),
).build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.bumble.appyx.navigation.node.Node
import com.bumble.appyx.navigation.plugin.NodeAware
import com.bumble.appyx.navigation.plugin.NodeLifecycleAware

open class Interactor<N : Node>(
open class Interactor<N : Node<*>>(
private val childAwareImpl: ChildAware<N> = ChildAwareImpl()
) : NodeAware<N>,
NodeLifecycleAware,
Expand Down
Loading

0 comments on commit d5a2406

Please sign in to comment.