33
44package com.squareup.workflow1
55
6- import kotlin.LazyThreadSafetyMode.NONE
76import kotlin.jvm.JvmMultifileClass
87import kotlin.jvm.JvmName
98
@@ -33,11 +32,43 @@ public abstract class StatelessWorkflow<in PropsT, out OutputT, out RenderingT>
3332 ) : BaseRenderContext<@UnsafeVariance PropsT, Nothing, @UnsafeVariance OutputT> by
3433 baseContext as BaseRenderContext <PropsT , Nothing , OutputT >
3534
36- @Suppress(" UNCHECKED_CAST" )
37- private val statefulWorkflow = Workflow .stateful<PropsT , Unit , OutputT , RenderingT >(
38- initialState = { Unit },
39- render = { props, _ -> render(props, RenderContext (this , this @StatelessWorkflow)) }
40- )
35+ private val statefulWorkflow: StatefulWorkflow <PropsT , Unit , OutputT , RenderingT > =
36+ object : StatefulWorkflow <PropsT , Unit , OutputT , RenderingT >() {
37+ // We want to cache the render context so that we don't have to recreate it each time
38+ // render() is called.
39+ private var cachedStatelessRenderContext:
40+ StatelessWorkflow <PropsT , OutputT , RenderingT >.RenderContext ? = null
41+
42+ // We must know if the RenderContext we are passed (which is a StatefulWorkflow.RenderContext)
43+ // has changed, so keep track of it.
44+ private var canonicalStatefulRenderContext:
45+ StatefulWorkflow <PropsT , Unit , OutputT , RenderingT >.RenderContext ? = null
46+
47+ override fun initialState (
48+ props : PropsT ,
49+ snapshot : Snapshot ?
50+ ) = Unit
51+
52+ override fun render (
53+ renderProps : PropsT ,
54+ renderState : Unit ,
55+ context : RenderContext
56+ ): RenderingT {
57+ // The `RenderContext` used *might* change - primarily in the case of our tests. E.g., The
58+ // `RenderTester` uses a special NoOp context to render twice to test for idempotency.
59+ // In order to support a changed render context but keep caching, we check to see if the
60+ // instance passed in has changed.
61+ if (cachedStatelessRenderContext == null || context != = canonicalStatefulRenderContext) {
62+ // Recreate it if the StatefulWorkflow.RenderContext we are passed has changed.
63+ cachedStatelessRenderContext = RenderContext (context, this @StatelessWorkflow)
64+ }
65+ canonicalStatefulRenderContext = context
66+ // Pass the StatelessWorkflow.RenderContext to our StatelessWorkflow.
67+ return render(renderProps, cachedStatelessRenderContext!! )
68+ }
69+
70+ override fun snapshotState (state : Unit ): Snapshot ? = null
71+ }
4172
4273 /* *
4374 * Called at least once any time one of the following things happens:
@@ -69,9 +100,6 @@ public abstract class StatelessWorkflow<in PropsT, out OutputT, out RenderingT>
69100 /* *
70101 * Satisfies the [Workflow] interface by wrapping `this` in a [StatefulWorkflow] with `Unit`
71102 * state.
72- *
73- * This method is called a few times per instance, but we don't need to allocate a new
74- * [StatefulWorkflow] every time, so we store it in a private property.
75103 */
76104 final override fun asStatefulWorkflow (): StatefulWorkflow <PropsT , * , OutputT , RenderingT > =
77105 statefulWorkflow
@@ -123,9 +151,9 @@ public fun <RenderingT> Workflow.Companion.rendering(
123151 */
124152public fun <PropsT , OutputT , RenderingT >
125153 StatelessWorkflow <PropsT , OutputT , RenderingT >.action (
126- name : String ,
127- update : WorkflowAction <PropsT , * , OutputT >.Updater .() -> Unit
128- ): WorkflowAction <PropsT , Nothing , OutputT > = action({ name }, update)
154+ name : String ,
155+ update : WorkflowAction <PropsT , * , OutputT >.Updater .() -> Unit
156+ ): WorkflowAction <PropsT , Nothing , OutputT > = action({ name }, update)
129157
130158/* *
131159 * Convenience to create a [WorkflowAction] with parameter types matching those
@@ -139,9 +167,9 @@ public fun <PropsT, OutputT, RenderingT>
139167 */
140168public fun <PropsT , OutputT , RenderingT >
141169 StatelessWorkflow <PropsT , OutputT , RenderingT >.action (
142- name : () -> String ,
143- update : WorkflowAction <PropsT , * , OutputT >.Updater .() -> Unit
144- ): WorkflowAction <PropsT , Nothing , OutputT > = object : WorkflowAction <PropsT , Nothing , OutputT >() {
170+ name : () -> String ,
171+ update : WorkflowAction <PropsT , * , OutputT >.Updater .() -> Unit
172+ ): WorkflowAction <PropsT , Nothing , OutputT > = object : WorkflowAction <PropsT , Nothing , OutputT >() {
145173 override val debuggingName: String
146174 get() = name()
147175
0 commit comments