@@ -71,6 +71,8 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
71
71
override val identifier: WorkflowIdentifier get() = id.identifier
72
72
override val renderKey: String get() = id.name
73
73
override val sessionId: Long = idCounter.createId()
74
+ private var cachedWorkflowInstance: StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >
75
+ private var interceptedWorkflowInstance: StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >
74
76
75
77
private val subtreeManager = SubtreeManager (
76
78
snapshotCache = snapshot?.childTreeSnapshots,
@@ -99,8 +101,9 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
99
101
init {
100
102
interceptor.onSessionStarted(this , this )
101
103
102
- state = interceptor.intercept(workflow, this )
103
- .initialState(initialProps, snapshot?.workflowSnapshot, this )
104
+ cachedWorkflowInstance = workflow
105
+ interceptedWorkflowInstance = interceptor.intercept(cachedWorkflowInstance, this )
106
+ state = interceptedWorkflowInstance.initialState(initialProps, snapshot?.workflowSnapshot, this )
104
107
}
105
108
106
109
override fun toString (): String {
@@ -132,10 +135,10 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
132
135
fun snapshot (workflow : StatefulWorkflow <* , * , * , * >): TreeSnapshot {
133
136
@Suppress(" UNCHECKED_CAST" )
134
137
val typedWorkflow = workflow as StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >
138
+ updateCachedWorkflowInstance(typedWorkflow)
135
139
return interceptor.onSnapshotStateWithChildren({
136
140
val childSnapshots = subtreeManager.createChildSnapshots()
137
- val rootSnapshot = interceptor.intercept(typedWorkflow, this )
138
- .snapshotState(state)
141
+ val rootSnapshot = interceptedWorkflowInstance.snapshotState(state)
139
142
TreeSnapshot (
140
143
workflowSnapshot = rootSnapshot,
141
144
// Create the snapshots eagerly since subtreeManager is mutable.
@@ -202,6 +205,20 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
202
205
coroutineContext.cancel(cause)
203
206
}
204
207
208
+ /* *
209
+ * Call this after we have been passed any workflow instance, in [render] or [snapshot]. It may
210
+ * have changed and we should check to see if we need to update our cached instances.
211
+ */
212
+ private fun updateCachedWorkflowInstance (
213
+ workflow : StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >
214
+ ) {
215
+ if (workflow != = cachedWorkflowInstance) {
216
+ // The instance has changed.
217
+ cachedWorkflowInstance = workflow
218
+ interceptedWorkflowInstance = interceptor.intercept(cachedWorkflowInstance, this )
219
+ }
220
+ }
221
+
205
222
/* *
206
223
* Contains the actual logic for [render], after we've casted the passed-in [Workflow]'s
207
224
* state type to our `StateT`.
@@ -210,11 +227,11 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
210
227
workflow : StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >,
211
228
props : PropsT
212
229
): RenderingT {
213
- updatePropsAndState(workflow, props)
230
+ updateCachedWorkflowInstance(workflow)
231
+ updatePropsAndState(props)
214
232
215
233
baseRenderContext.unfreeze()
216
- val rendering = interceptor.intercept(workflow, this )
217
- .render(props, state, context)
234
+ val rendering = interceptedWorkflowInstance.render(props, state, context)
218
235
baseRenderContext.freeze()
219
236
220
237
workflowTracer.trace(" UpdateRuntimeTree" ) {
@@ -230,12 +247,10 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
230
247
}
231
248
232
249
private fun updatePropsAndState (
233
- workflow : StatefulWorkflow <PropsT , StateT , OutputT , RenderingT >,
234
250
newProps : PropsT
235
251
) {
236
252
if (newProps != lastProps) {
237
- val newState = interceptor.intercept(workflow, this )
238
- .onPropsChanged(lastProps, newProps, state)
253
+ val newState = interceptedWorkflowInstance.onPropsChanged(lastProps, newProps, state)
239
254
state = newState
240
255
}
241
256
lastProps = newProps
0 commit comments