Skip to content

Commit

Permalink
Cache identifier
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-the-edwards committed Dec 12, 2022
1 parent a39c288 commit 57aeebf
Show file tree
Hide file tree
Showing 22 changed files with 73 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.squareup.workflow1.RenderContext
import com.squareup.workflow1.Sink
import com.squareup.workflow1.StatefulWorkflow
import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.computeIdentifier
import com.squareup.workflow1.ui.ViewEnvironment
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
import com.squareup.workflow1.ui.compose.ComposeScreen
Expand Down Expand Up @@ -48,6 +50,8 @@ abstract class ComposeWorkflow<in PropsT, out OutputT : Any> :

override fun asStatefulWorkflow(): StatefulWorkflow<PropsT, *, OutputT, ComposeScreen> =
ComposeWorkflowImpl(this)

override val identifier: WorkflowIdentifier = computeIdentifier()
}

/**
Expand Down
5 changes: 4 additions & 1 deletion workflow-core/api/workflow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public final class com/squareup/workflow1/Snapshots {
public abstract class com/squareup/workflow1/StatefulWorkflow : com/squareup/workflow1/Workflow {
public fun <init> ()V
public final fun asStatefulWorkflow ()Lcom/squareup/workflow1/StatefulWorkflow;
public fun getIdentifier ()Lcom/squareup/workflow1/WorkflowIdentifier;
public abstract fun initialState (Ljava/lang/Object;Lcom/squareup/workflow1/Snapshot;)Ljava/lang/Object;
public fun onPropsChanged (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun render (Ljava/lang/Object;Ljava/lang/Object;Lcom/squareup/workflow1/StatefulWorkflow$RenderContext;)Ljava/lang/Object;
Expand All @@ -144,6 +145,7 @@ public final class com/squareup/workflow1/StatefulWorkflow$RenderContext : com/s
public abstract class com/squareup/workflow1/StatelessWorkflow : com/squareup/workflow1/Workflow {
public fun <init> ()V
public final fun asStatefulWorkflow ()Lcom/squareup/workflow1/StatefulWorkflow;
public fun getIdentifier ()Lcom/squareup/workflow1/WorkflowIdentifier;
public abstract fun render (Ljava/lang/Object;Lcom/squareup/workflow1/StatelessWorkflow$RenderContext;)Ljava/lang/Object;
}

Expand Down Expand Up @@ -191,6 +193,7 @@ public final class com/squareup/workflow1/Worker$DefaultImpls {
public abstract interface class com/squareup/workflow1/Workflow {
public static final field Companion Lcom/squareup/workflow1/Workflow$Companion;
public abstract fun asStatefulWorkflow ()Lcom/squareup/workflow1/StatefulWorkflow;
public abstract fun getIdentifier ()Lcom/squareup/workflow1/WorkflowIdentifier;
}

public final class com/squareup/workflow1/Workflow$Companion {
Expand Down Expand Up @@ -283,8 +286,8 @@ public final class com/squareup/workflow1/Workflows {
public static synthetic fun action$default (Lcom/squareup/workflow1/StatelessWorkflow;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow1/WorkflowAction;
public static synthetic fun action$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/squareup/workflow1/WorkflowAction;
public static final fun applyTo (Lcom/squareup/workflow1/WorkflowAction;Ljava/lang/Object;Ljava/lang/Object;)Lkotlin/Pair;
public static final fun computeIdentifier (Lcom/squareup/workflow1/Workflow;)Lcom/squareup/workflow1/WorkflowIdentifier;
public static final fun contraMap (Lcom/squareup/workflow1/Sink;Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow1/Sink;
public static final fun getIdentifier (Lcom/squareup/workflow1/Workflow;)Lcom/squareup/workflow1/WorkflowIdentifier;
public static final fun mapRendering (Lcom/squareup/workflow1/Workflow;Lkotlin/jvm/functions/Function1;)Lcom/squareup/workflow1/Workflow;
public static final fun renderChild (Lcom/squareup/workflow1/BaseRenderContext;Lcom/squareup/workflow1/Workflow;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;
public static final fun renderChild (Lcom/squareup/workflow1/BaseRenderContext;Lcom/squareup/workflow1/Workflow;Ljava/lang/String;)Ljava/lang/Object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import kotlin.jvm.JvmName
public interface ImpostorWorkflow {
/**
* The [WorkflowIdentifier] of another workflow to be combined with the identifier of this
* workflow, as obtained by [Workflow.identifier].
* workflow, as obtained by [Workflow.computeIdentifier].
*
* For workflows that implement operators, this should be the identifier of the upstream
* [Workflow] that this workflow wraps.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ public abstract class StatefulWorkflow<
context: RenderContext
): RenderingT

override val identifier: WorkflowIdentifier by lazy {
computeIdentifier()
}

/**
* Called whenever the state changes to generate a new [Snapshot] of the state.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public abstract class StatelessWorkflow<in PropsT, out OutputT, out RenderingT>
context: RenderContext
): RenderingT

override val identifier: WorkflowIdentifier by lazy {
computeIdentifier()
}

/**
* Satisfies the [Workflow] interface by wrapping `this` in a [StatefulWorkflow] with `Unit`
* state.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public interface Workflow<in PropsT, out OutputT, out RenderingT> {
*/
public fun asStatefulWorkflow(): StatefulWorkflow<PropsT, *, OutputT, RenderingT>

public val identifier: WorkflowIdentifier

/**
* Empty companion serves as a hook point to allow us to create `Workflow.foo`
* extension methods elsewhere.
Expand All @@ -120,7 +122,7 @@ Workflow<PropsT, OutputT, FromRenderingT>.mapRendering(
transform: (FromRenderingT) -> ToRenderingT
): Workflow<PropsT, OutputT, ToRenderingT> =
object : StatelessWorkflow<PropsT, OutputT, ToRenderingT>(), ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier get() = this@mapRendering.identifier
override val realIdentifier: WorkflowIdentifier = this@mapRendering.identifier

override fun render(
renderProps: PropsT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,14 @@ public class WorkflowIdentifier internal constructor(
/**
* The [WorkflowIdentifier] that identifies this [Workflow].
*/
public val Workflow<*, *, *>.identifier: WorkflowIdentifier
get() {
val maybeImpostor = this as? ImpostorWorkflow
return WorkflowIdentifier(
type = Snapshottable(this::class),
proxiedIdentifier = maybeImpostor?.realIdentifier,
description = maybeImpostor?.let { it::describeRealIdentifier }
)
}
public fun Workflow<*, *, *>.computeIdentifier(): WorkflowIdentifier {
val maybeImpostor = this as? ImpostorWorkflow
return WorkflowIdentifier(
type = Snapshottable(this::class),
proxiedIdentifier = maybeImpostor?.realIdentifier,
description = maybeImpostor?.let { it::describeRealIdentifier }
)
}

/**
* Creates a [WorkflowIdentifier] that is not capable of being snapshotted and will cause any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,17 +172,22 @@ internal class WorkflowIdentifierTest {
public object TestWorkflow1 : Workflow<Nothing, Nothing, Nothing> {
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()

override val identifier: WorkflowIdentifier = computeIdentifier()
}

public object TestWorkflow2 : Workflow<Nothing, Nothing, Nothing> {
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()

override val identifier: WorkflowIdentifier = computeIdentifier()
}

public class TestImpostor1(
private val proxied: Workflow<*, *, *>
) : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = proxied.identifier
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun describeRealIdentifier(): String =
"TestImpostor1(${WorkflowIdentifierTypeNamer.uniqueName(proxied::class)})"
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
Expand All @@ -193,6 +198,7 @@ internal class WorkflowIdentifierTest {
proxied: Workflow<*, *, *>
) : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = proxied.identifier
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()
}
Expand All @@ -201,6 +207,7 @@ internal class WorkflowIdentifierTest {
type: KType
) : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = unsnapshottableIdentifier(type)
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class NativeWorkflowIdentifierTest {
fun `impostor identifier toString uses full chain when describeRealIdentifier returns null`() {
class TestImpostor : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = TestWorkflow1.identifier
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun describeRealIdentifier(): String? = null

override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal class JsWorkflowIdentifierTest {
fun impostor_identifier_toString_uses_full_chain_when_describeRealIdentifier_returns_null() {
class TestImpostor : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = TestWorkflow1.identifier
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun describeRealIdentifier(): String? = null

override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ package com.squareup.workflow1.mocks.workflows1

import com.squareup.workflow1.StatefulWorkflow
import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.computeIdentifier

public class JsMockWorkflow1 : Workflow<Nothing, Nothing, Nothing> {
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()

override val identifier: WorkflowIdentifier = computeIdentifier()
}

public class JsMockWorkflow2 : Workflow<Nothing, Nothing, Nothing> {
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
throw NotImplementedError()

override val identifier: WorkflowIdentifier = computeIdentifier()
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package com.squareup.workflow1.mocks.workflows2

import com.squareup.workflow1.StatefulWorkflow
import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.computeIdentifier

// This is purposely duplicated to be like com.squareup.workflow1.mocks.workflows1.JsMockWorkflow1,
// but with a slightly different Output.
public class JsMockWorkflow1 : Workflow<Nothing, String, Nothing> {
override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, String, Nothing> =
throw NotImplementedError()

override val identifier: WorkflowIdentifier = computeIdentifier()
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class JvmWorkflowIdentifierTest {
fun `impostor identifier toString uses full chain when describeRealIdentifier returns null`() {
class TestImpostor : Workflow<Nothing, Nothing, Nothing>, ImpostorWorkflow {
override val realIdentifier: WorkflowIdentifier = TestWorkflow1.identifier
override val identifier: WorkflowIdentifier = computeIdentifier()
override fun describeRealIdentifier(): String? = null

override fun asStatefulWorkflow(): StatefulWorkflow<Nothing, *, Nothing, Nothing> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowAction
import com.squareup.workflow1.WorkflowInterceptor
import com.squareup.workflow1.WorkflowInterceptor.WorkflowSession
import com.squareup.workflow1.identifier
import kotlinx.coroutines.selects.SelectBuilder
import kotlin.coroutines.CoroutineContext

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.squareup.workflow1.internal

import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.identifier
import com.squareup.workflow1.readByteStringWithLength
import com.squareup.workflow1.readUtf8WithLength
import com.squareup.workflow1.writeByteStringWithLength
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,23 @@ internal class TreeSnapshotTest {

private object Workflow1 : Workflow<Unit, Nothing, Unit> {
override fun asStatefulWorkflow(): StatefulWorkflow<Unit, *, Nothing, Unit> = fail()
override val identifier: WorkflowIdentifier = computeIdentifier()
}

private object Workflow2 : Workflow<Unit, Nothing, Unit> {
override fun asStatefulWorkflow(): StatefulWorkflow<Unit, *, Nothing, Unit> = fail()
override val identifier: WorkflowIdentifier = computeIdentifier()
}

private object UnsnapshottableWorkflow1 : Workflow<Unit, Nothing, Unit>, ImpostorWorkflow {
override val realIdentifier = unsnapshottableIdentifier(typeOf<String>())
override fun asStatefulWorkflow(): StatefulWorkflow<Unit, *, Nothing, Unit> = fail()
override val identifier: WorkflowIdentifier = computeIdentifier()
}

private object UnsnapshottableWorkflow2 : Workflow<Unit, Nothing, Unit>, ImpostorWorkflow {
override val realIdentifier = unsnapshottableIdentifier(typeOf<String>())
override fun asStatefulWorkflow(): StatefulWorkflow<Unit, *, Nothing, Unit> = fail()
override val identifier: WorkflowIdentifier = computeIdentifier()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.WorkflowInterceptor
import com.squareup.workflow1.WorkflowInterceptor.RenderContextInterceptor
import com.squareup.workflow1.WorkflowInterceptor.WorkflowSession
import com.squareup.workflow1.identifier
import com.squareup.workflow1.parse
import com.squareup.workflow1.rendering
import kotlinx.coroutines.CoroutineScope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import com.squareup.workflow1.WorkflowAction
import com.squareup.workflow1.WorkflowOutput
import com.squareup.workflow1.action
import com.squareup.workflow1.applyTo
import com.squareup.workflow1.identifier
import com.squareup.workflow1.internal.SubtreeManagerTest.TestWorkflow.Rendering
import kotlinx.coroutines.Dispatchers.Unconfined
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import com.squareup.workflow1.WorkflowInterceptor.WorkflowSession
import com.squareup.workflow1.WorkflowOutput
import com.squareup.workflow1.action
import com.squareup.workflow1.contraMap
import com.squareup.workflow1.identifier
import com.squareup.workflow1.parse
import com.squareup.workflow1.readUtf8WithLength
import com.squareup.workflow1.renderChild
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import com.squareup.workflow1.WorkflowIdentifierType.Snapshottable
import com.squareup.workflow1.WorkflowIdentifierType.Unsnapshottable
import com.squareup.workflow1.WorkflowOutput
import com.squareup.workflow1.applyTo
import com.squareup.workflow1.identifier
import com.squareup.workflow1.testing.RealRenderTester.Expectation
import com.squareup.workflow1.testing.RealRenderTester.Expectation.ExpectedSideEffect
import com.squareup.workflow1.testing.RealRenderTester.Expectation.ExpectedWorker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.squareup.workflow1.Workflow
import com.squareup.workflow1.WorkflowAction
import com.squareup.workflow1.WorkflowIdentifier
import com.squareup.workflow1.WorkflowOutput
import com.squareup.workflow1.identifier
import com.squareup.workflow1.testing.RenderTester.ChildWorkflowMatch
import com.squareup.workflow1.workflowIdentifier
import kotlin.reflect.KClass
Expand Down
Loading

0 comments on commit 57aeebf

Please sign in to comment.