@@ -2,15 +2,20 @@ package com.squareup.workflow1.internal.compose
22
33import androidx.compose.runtime.Composable
44import androidx.compose.runtime.DisposableEffect
5+ import androidx.compose.runtime.NonRestartableComposable
6+ import androidx.compose.runtime.ReadOnlyComposable
57import androidx.compose.runtime.collection.MutableVector
68import androidx.compose.runtime.currentRecomposeScope
79import androidx.compose.runtime.getValue
810import androidx.compose.runtime.key
11+ import androidx.compose.runtime.mutableStateOf
912import androidx.compose.runtime.remember
1013import androidx.compose.runtime.rememberCoroutineScope
1114import androidx.compose.runtime.rememberUpdatedState
1215import androidx.compose.runtime.saveable.LocalSaveableStateRegistry
1316import androidx.compose.runtime.saveable.SaveableStateRegistry
17+ import androidx.compose.runtime.setValue
18+ import androidx.compose.runtime.snapshots.Snapshot
1419import com.squareup.workflow1.ActionApplied
1520import com.squareup.workflow1.ActionProcessingResult
1621import com.squareup.workflow1.NoopWorkflowInterceptor
@@ -29,8 +34,8 @@ import com.squareup.workflow1.compose.WorkflowComposableRenderer
2934import com.squareup.workflow1.identifier
3035import com.squareup.workflow1.internal.IdCounter
3136import com.squareup.workflow1.internal.WorkflowNodeId
32- import com.squareup.workflow1.internal.requireSend
3337import com.squareup.workflow1.internal.createId
38+ import com.squareup.workflow1.internal.requireSend
3439import com.squareup.workflow1.workflowSessionToString
3540import kotlinx.coroutines.CoroutineName
3641import kotlinx.coroutines.CoroutineScope
@@ -96,6 +101,8 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
96101 }
97102 }
98103
104+ private var lastProps by mutableStateOf(initialProps)
105+
99106 /* *
100107 * Function invoked when [onNextAction] receives an output from [outputsChannel].
101108 */
@@ -149,6 +156,9 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
149156 // inside a renderChild call and renderChild does the keying.
150157 log(" rendering workflow: props=$props " )
151158 workflow as ComposeWorkflow
159+
160+ notifyInterceptorWhenPropsChanged(props)
161+
152162 return withCompositionLocals(
153163 LocalSaveableStateRegistry provides saveableStateRegistry,
154164 LocalWorkflowComposableRenderer provides this
@@ -167,6 +177,26 @@ internal class ComposeWorkflowChildNode<PropsT, OutputT, RenderingT>(
167177 }
168178 }
169179
180+ @ReadOnlyComposable
181+ @NonRestartableComposable
182+ @Composable
183+ private fun notifyInterceptorWhenPropsChanged (newProps : PropsT ) {
184+ // Don't both asking the composition to track reads of lastProps since this is the only function
185+ // that will every write to it.
186+ Snapshot .withoutReadObservation {
187+ if (lastProps != newProps) {
188+ interceptor.onPropsChanged(
189+ old = lastProps,
190+ new = newProps,
191+ state = ComposeWorkflowState ,
192+ session = this ,
193+ proceed = { _, _, _ -> ComposeWorkflowState },
194+ )
195+ lastProps = newProps
196+ }
197+ }
198+ }
199+
170200 @Composable
171201 override fun <ChildPropsT , ChildOutputT , ChildRenderingT > renderChild (
172202 childWorkflow : Workflow <ChildPropsT , ChildOutputT , ChildRenderingT >,
0 commit comments