3
3
4
4
package com.squareup.workflow1
5
5
6
- import kotlin.LazyThreadSafetyMode.NONE
7
6
import kotlin.jvm.JvmMultifileClass
8
7
import kotlin.jvm.JvmName
9
8
@@ -33,11 +32,43 @@ public abstract class StatelessWorkflow<in PropsT, out OutputT, out RenderingT>
33
32
) : BaseRenderContext<@UnsafeVariance PropsT, Nothing, @UnsafeVariance OutputT> by
34
33
baseContext as BaseRenderContext <PropsT , Nothing , OutputT >
35
34
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
+ }
41
72
42
73
/* *
43
74
* 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>
69
100
/* *
70
101
* Satisfies the [Workflow] interface by wrapping `this` in a [StatefulWorkflow] with `Unit`
71
102
* 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.
75
103
*/
76
104
final override fun asStatefulWorkflow (): StatefulWorkflow <PropsT , * , OutputT , RenderingT > =
77
105
statefulWorkflow
@@ -123,9 +151,9 @@ public fun <RenderingT> Workflow.Companion.rendering(
123
151
*/
124
152
public fun <PropsT , OutputT , RenderingT >
125
153
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)
129
157
130
158
/* *
131
159
* Convenience to create a [WorkflowAction] with parameter types matching those
@@ -139,9 +167,9 @@ public fun <PropsT, OutputT, RenderingT>
139
167
*/
140
168
public fun <PropsT , OutputT , RenderingT >
141
169
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 >() {
145
173
override val debuggingName: String
146
174
get() = name()
147
175
0 commit comments