Skip to content

Commit c4b6756

Browse files
Fix ComposeWorkflowChildNode rendering the wrong props.
1 parent 60716fd commit c4b6756

File tree

1 file changed

+13
-14
lines changed

1 file changed

+13
-14
lines changed

workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/compose/ComposeWorkflowChildNode.kt

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ package com.squareup.workflow1.internal.compose
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.DisposableEffect
5-
import androidx.compose.runtime.collection.mutableVectorOf
5+
import androidx.compose.runtime.collection.MutableVector
66
import androidx.compose.runtime.currentRecomposeScope
77
import androidx.compose.runtime.getValue
88
import androidx.compose.runtime.key
9-
import androidx.compose.runtime.mutableStateOf
109
import androidx.compose.runtime.remember
1110
import androidx.compose.runtime.rememberCoroutineScope
1211
import androidx.compose.runtime.rememberUpdatedState
1312
import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
1413
import androidx.compose.runtime.saveable.SaveableStateRegistry
15-
import androidx.compose.runtime.setValue
1614
import com.squareup.workflow1.ActionApplied
1715
import com.squareup.workflow1.ActionProcessingResult
1816
import com.squareup.workflow1.NoopWorkflowInterceptor
@@ -77,12 +75,12 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
7775
override val renderKey: String get() = id.name
7876
override val sessionId: Long = idCounter.createId()
7977

80-
private var lastProps by mutableStateOf(initialProps)
81-
8278
/** This does not need to be a snapshot state object, it's only set again by [snapshot]. */
8379
private var snapshotCache = snapshot?.childTreeSnapshots
8480
private val saveableStateRegistry: SaveableStateRegistry
85-
private val childNodes = mutableVectorOf<ComposeChildNode<*, *, *>>()
81+
82+
// Don't allocate childNodes list until a child is rendered, leaf node optimization.
83+
private var childNodes: MutableVector<ComposeChildNode<*, *, *>>? = null
8684

8785
private val outputsChannel = Channel<OutputT>(capacity = OUTPUT_QUEUE_LIMIT)
8886

@@ -130,8 +128,7 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
130128
snapshot = workflowSnapshot,
131129
workflowScope = this,
132130
session = this,
133-
proceed = { innerProps, innerSnapshot, _ ->
134-
lastProps = innerProps
131+
proceed = { _, innerSnapshot, _ ->
135132
restoredRegistry = restoreSaveableStateRegistryFromSnapshot(innerSnapshot)
136133
ComposeWorkflowState
137134
}
@@ -157,7 +154,7 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
157154
LocalWorkflowComposableRenderer provides this
158155
) {
159156
interceptor.onRenderComposeWorkflow(
160-
renderProps = lastProps,
157+
renderProps = props,
161158
emitOutput = onEmitOutput,
162159
session = this,
163160
proceed = { innerProps, innerEmitOutput ->
@@ -228,11 +225,11 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
228225

229226
@OptIn(ExperimentalCoroutinesApi::class, DelicateCoroutinesApi::class)
230227
override fun onNextAction(selector: SelectBuilder<ActionProcessingResult>): Boolean {
231-
var empty = childNodes.fold(true) { empty, child ->
228+
var empty = childNodes?.fold(true) { empty, child ->
232229
// Do this separately so the compiler doesn't avoid it if empty is already false.
233230
val childEmpty = child.onNextAction(selector)
234231
empty && childEmpty
235-
}
232+
} ?: true
236233

237234
empty = empty && (outputsChannel.isEmpty || outputsChannel.isClosedForReceive)
238235
with(selector) {
@@ -307,15 +304,17 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
307304
}
308305

309306
private fun addChildNode(childNode: ComposeChildNode<*, *, *>) {
310-
childNodes += childNode
307+
(childNodes ?: MutableVector<ComposeChildNode<*, *, *>>().also { childNodes = it }) += childNode
311308
}
312309

313310
private fun removeChildNode(childNode: ComposeChildNode<*, *, *>) {
314-
childNodes -= childNode
311+
val childNodes = childNodes
312+
?: throw AssertionError("removeChildNode called before addChildNode")
313+
childNodes.remove(childNode)
315314
}
316315

317316
private fun createChildSnapshots(): Map<WorkflowNodeId, TreeSnapshot> = buildMap {
318-
childNodes.forEach { child ->
317+
childNodes?.forEach { child ->
319318
put(child.id, child.snapshot())
320319
}
321320
}

0 commit comments

Comments
 (0)