@@ -161,16 +161,16 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
161
161
}
162
162
163
163
/* *
164
- * If [runtimeConfig] contains [RuntimeConfigOptions.RENDER_ONLY_WHEN_STATE_CHANGES] then
165
- * send any output, but return true which means restart the runtime loop and process another
166
- * action.
164
+ * If [runtimeConfig] contains [RuntimeConfigOptions.RENDER_ONLY_WHEN_STATE_CHANGES] and
165
+ * we have not changed state, then return true to short circuit.
167
166
*/
168
- suspend fun shortCircuitForUnchangedState (actionResult : ActionProcessingResult ): Boolean {
167
+ fun shortCircuitForUnchangedState (
168
+ actionResult : ActionProcessingResult
169
+ ): Boolean {
169
170
if (runtimeConfig.contains(RENDER_ONLY_WHEN_STATE_CHANGES ) &&
170
171
actionResult is ActionApplied <* > && ! actionResult.stateChanged
171
172
) {
172
173
// Possibly send output and process more actions. No state change so no re-render.
173
- sendOutput(actionResult, onOutput)
174
174
return true
175
175
}
176
176
return false
@@ -183,35 +183,48 @@ public fun <PropsT, OutputT, RenderingT> renderWorkflowIn(
183
183
// launched.
184
184
var actionResult: ActionProcessingResult = runner.processAction()
185
185
186
- if (shortCircuitForUnchangedState(actionResult)) continue
186
+ if (shortCircuitForUnchangedState(actionResult)) {
187
+ sendOutput(actionResult, onOutput)
188
+ continue
189
+ }
190
+
191
+ // Most often a list of one, but with CONFLATE_STALE_RENDERINGS, we may build up others.
192
+ val listOfOutputs = mutableListOf (actionResult)
187
193
188
194
// After resuming from runner.processAction() our coroutine could now be cancelled, check so
189
195
// we don't surprise anyone with an unexpected rendering pass. Show's over, go home.
190
196
if (! isActive) return @launch
191
197
198
+ // Next Render Pass.
192
199
var nextRenderAndSnapshot: RenderingAndSnapshot <RenderingT > = runner.nextRendering()
193
200
194
201
if (runtimeConfig.contains(CONFLATE_STALE_RENDERINGS )) {
195
- // Only null will allow us to continue processing actions and conflating stale renderings.
196
- // If this is not null, then we had an Output and we want to send it with the Rendering
197
- // (stale or not).
198
- while (actionResult is ActionApplied <* > && actionResult.output == null ) {
199
- // We have more actions we can process, so this rendering is stale.
202
+ while (isActive && actionResult is ActionApplied <* >) {
203
+ // We may have more actions we can process, this rendering could be stale.
200
204
actionResult = runner.processAction(waitForAnAction = false )
201
205
202
- if (! isActive) return @launch
203
-
204
- // If no actions processed, then no new rendering needed.
206
+ // If no actions processed, then no new rendering needed. Pass on to UI.
205
207
if (actionResult == ActionsExhausted ) break
206
208
209
+ if (shortCircuitForUnchangedState(actionResult)) {
210
+ listOfOutputs.add(actionResult)
211
+ continue
212
+ }
213
+
214
+ // Make sure the runtime has not been cancelled.
215
+ if (! isActive) return @launch
216
+
207
217
nextRenderAndSnapshot = runner.nextRendering()
208
218
}
209
219
}
210
220
211
- // Pass on to the UI.
221
+ // Pass on the rendering to the UI.
212
222
renderingsAndSnapshots.value = nextRenderAndSnapshot
213
- // And emit the Output.
214
- sendOutput(actionResult, onOutput)
223
+
224
+ // Emit the Output(s).
225
+ listOfOutputs.forEach { actionApplied ->
226
+ sendOutput(actionApplied, onOutput)
227
+ }
215
228
}
216
229
}
217
230
0 commit comments