Skip to content

Commit b264715

Browse files
Merge pull request #700 from square/sedwards/699-benchmark-sample
699: Refactor Poetry Workflows into Common; Add Performance Poetry App
2 parents 4860a4e + 9bdeb99 commit b264715

File tree

14 files changed

+149
-22
lines changed

14 files changed

+149
-22
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public final class com/squareup/benchmarks/performance/poetry/PerformancePoetryActivity : androidx/appcompat/app/AppCompatActivity {
2+
public static final field Companion Lcom/squareup/benchmarks/performance/poetry/PerformancePoetryActivity$Companion;
3+
public fun <init> ()V
4+
}
5+
6+
public final class com/squareup/benchmarks/performance/poetry/PerformancePoetryActivity$Companion {
7+
}
8+
9+
public final class com/squareup/benchmarks/performance/poetry/PerformancePoetryActivityKt {
10+
}
11+
12+
public final class com/squareup/benchmarks/performance/poetry/PoetryModel : androidx/lifecycle/ViewModel {
13+
public fun <init> (Landroidx/lifecycle/SavedStateHandle;)V
14+
public final fun getRenderings ()Lkotlinx/coroutines/flow/StateFlow;
15+
}
16+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
plugins {
2+
id("com.android.application")
3+
kotlin("android")
4+
}
5+
6+
apply(from = rootProject.file(".buildscript/android-sample-app.gradle"))
7+
apply(from = rootProject.file(".buildscript/android-ui-tests.gradle"))
8+
9+
android {
10+
defaultConfig {
11+
applicationId = "com.squareup.benchmarks.performance.poetry"
12+
}
13+
}
14+
15+
dependencies {
16+
debugImplementation(libs.squareup.leakcanary.android)
17+
18+
implementation(project(":samples:containers:android"))
19+
implementation(project(":samples:containers:poetry"))
20+
implementation(project(":workflow-ui:core-android"))
21+
22+
implementation(libs.androidx.activity.ktx)
23+
implementation(libs.androidx.recyclerview)
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.squareup.benchmarks.performance.poetry">
5+
6+
<application
7+
android:allowBackup="false"
8+
android:label="@string/app_name"
9+
android:theme="@style/AppTheme"
10+
tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon">
11+
<activity
12+
android:name=".PerformancePoetryActivity"
13+
android:exported="true">
14+
<intent-filter>
15+
<action android:name="android.intent.action.MAIN" />
16+
17+
<category android:name="android.intent.category.LAUNCHER" />
18+
</intent-filter>
19+
</activity>
20+
</application>
21+
22+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.squareup.benchmarks.performance.poetry
2+
3+
import android.os.Bundle
4+
import androidx.activity.viewModels
5+
import androidx.appcompat.app.AppCompatActivity
6+
import androidx.lifecycle.SavedStateHandle
7+
import androidx.lifecycle.ViewModel
8+
import androidx.lifecycle.viewModelScope
9+
import com.squareup.sample.container.SampleContainers
10+
import com.squareup.sample.poetry.PoemsBrowserWorkflow
11+
import com.squareup.sample.poetry.model.Poem
12+
import com.squareup.workflow1.ui.WorkflowLayout
13+
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
14+
import com.squareup.workflow1.ui.backstack.BackStackContainer
15+
import com.squareup.workflow1.ui.plus
16+
import com.squareup.workflow1.ui.renderWorkflowIn
17+
import kotlinx.coroutines.flow.StateFlow
18+
import timber.log.Timber
19+
20+
@OptIn(WorkflowUiExperimentalApi::class)
21+
private val viewRegistry = SampleContainers + BackStackContainer
22+
23+
public class PerformancePoetryActivity : AppCompatActivity() {
24+
@OptIn(WorkflowUiExperimentalApi::class)
25+
override fun onCreate(savedInstanceState: Bundle?) {
26+
super.onCreate(savedInstanceState)
27+
28+
val model: PoetryModel by viewModels()
29+
setContentView(
30+
WorkflowLayout(this).apply { start(lifecycle, model.renderings, viewRegistry) }
31+
)
32+
}
33+
34+
public companion object {
35+
init {
36+
Timber.plant(Timber.DebugTree())
37+
}
38+
}
39+
}
40+
41+
public class PoetryModel(savedState: SavedStateHandle) : ViewModel() {
42+
@OptIn(WorkflowUiExperimentalApi::class)
43+
public val renderings: StateFlow<Any> by lazy {
44+
renderWorkflowIn(
45+
workflow = PoemsBrowserWorkflow,
46+
scope = viewModelScope,
47+
prop = Poem.allPoems,
48+
savedStateHandle = savedState
49+
)
50+
}
51+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<string name="app_name">Performance Poetry</string>
3+
</resources>

samples/containers/app-poetry/src/main/java/com/squareup/sample/poetryapp/PoetryActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import androidx.lifecycle.SavedStateHandle
77
import androidx.lifecycle.ViewModel
88
import androidx.lifecycle.viewModelScope
99
import com.squareup.sample.container.SampleContainers
10+
import com.squareup.sample.poetry.PoemsBrowserWorkflow
1011
import com.squareup.sample.poetry.model.Poem
1112
import com.squareup.workflow1.ui.WorkflowLayout
1213
import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
<resources>
22
<string name="app_name">Poetry</string>
3-
<string name="poems">Poems</string>
43
</resources>
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.squareup.sample.poetryapp
1+
package com.squareup.sample.poetry
22

33
import android.view.LayoutInflater
44
import android.view.View
@@ -9,7 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
99
import androidx.recyclerview.widget.RecyclerView
1010
import com.squareup.sample.container.overviewdetail.OverviewDetailConfig
1111
import com.squareup.sample.container.overviewdetail.OverviewDetailConfig.Overview
12-
import com.squareup.sample.container.poetryapp.R
12+
import com.squareup.sample.container.poetry.R
1313
import com.squareup.sample.poetry.model.Poem
1414
import com.squareup.workflow1.ui.AndroidViewRendering
1515
import com.squareup.workflow1.ui.LayoutRunner
@@ -20,12 +20,16 @@ import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
2020
data class PoemListRendering(
2121
val poems: List<Poem>,
2222
val onPoemSelected: (Int) -> Unit,
23-
val selection: Int = -1
23+
val selection: Int = NO_POEM_SELECTED
2424
) : AndroidViewRendering<PoemListRendering> {
2525
override val viewFactory = LayoutRunner.bind(
2626
R.layout.list,
2727
::PoemListLayoutRunner
2828
)
29+
30+
companion object {
31+
const val NO_POEM_SELECTED: Int = -1
32+
}
2933
}
3034

3135
@OptIn(WorkflowUiExperimentalApi::class)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
package com.squareup.sample.poetryapp
1+
package com.squareup.sample.poetry
22

33
import com.squareup.sample.poetry.model.Poem
44
import com.squareup.workflow1.StatelessWorkflow
55

66
/**
7-
* Renders a given ordered list of [Poem]s. Reports the index of any that are clicked.
7+
* Renders a given ordered list of [Poem]s. Reports the index of any that are clicked via Output.
88
*/
9-
object PoemListWorkflow : StatelessWorkflow<List<Poem>, Int, PoemListRendering>() {
9+
object PoemListWorkflow : StatelessWorkflow<List<Poem>, SelectedPoem, PoemListRendering>() {
1010

1111
override fun render(
1212
renderProps: List<Poem>,

samples/containers/poetry/src/main/java/com/squareup/sample/poetry/PoemWorkflow.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,32 @@ import com.squareup.workflow1.ui.WorkflowUiExperimentalApi
2020
import com.squareup.workflow1.ui.backstack.BackStackScreen
2121
import com.squareup.workflow1.ui.backstack.toBackStackScreen
2222

23+
typealias SelectedStanza = Int
24+
2325
/**
2426
* Renders a [Poem] as a [OverviewDetailScreen], whose overview is a [StanzaListRendering]
2527
* for the poem, and whose detail traverses through [StanzaRendering]s.
2628
*/
27-
object PoemWorkflow : StatefulWorkflow<Poem, Int, ClosePoem, OverviewDetailScreen>() {
29+
object PoemWorkflow : StatefulWorkflow<Poem, SelectedStanza, ClosePoem, OverviewDetailScreen>() {
2830
object ClosePoem
31+
public const val NO_SELECTED_STANZA = -1
2932

3033
override fun initialState(
3134
props: Poem,
3235
snapshot: Snapshot?
3336
): Int {
3437
return snapshot?.bytes?.parse { source -> source.readInt() }
35-
?: -1
38+
?: NO_SELECTED_STANZA
3639
}
3740

3841
@OptIn(WorkflowUiExperimentalApi::class)
3942
override fun render(
4043
renderProps: Poem,
41-
renderState: Int,
44+
renderState: SelectedStanza,
4245
context: RenderContext
4346
): OverviewDetailScreen {
4447
val previousStanzas: List<StanzaRendering> =
45-
if (renderState == -1) emptyList()
48+
if (renderState == NO_SELECTED_STANZA) emptyList()
4649
else renderProps.stanzas.subList(0, renderState)
4750
.mapIndexed { index, _ ->
4851
context.renderChild(StanzaWorkflow, Props(renderProps, index), "$index") {
@@ -88,7 +91,7 @@ object PoemWorkflow : StatefulWorkflow<Poem, Int, ClosePoem, OverviewDetailScree
8891
sink.writeInt(state)
8992
}
9093

91-
private sealed class Action : WorkflowAction<Poem, Int, ClosePoem>() {
94+
private sealed class Action : WorkflowAction<Poem, SelectedStanza, ClosePoem>() {
9295
object ClearSelection : Action()
9396
object SelectPrevious : Action()
9497
object SelectNext : Action()
@@ -97,11 +100,11 @@ object PoemWorkflow : StatefulWorkflow<Poem, Int, ClosePoem, OverviewDetailScree
97100

98101
override fun Updater.apply() {
99102
when (this@Action) {
100-
ClearSelection -> state = -1
103+
ClearSelection -> state = NO_SELECTED_STANZA
101104
SelectPrevious -> state -= 1
102105
SelectNext -> state += 1
103106
is HandleStanzaListOutput -> {
104-
if (selection == -1) setOutput(ClosePoem)
107+
if (selection == NO_SELECTED_STANZA) setOutput(ClosePoem)
105108
state = selection
106109
}
107110
ExitPoem -> setOutput(ClosePoem)

0 commit comments

Comments
 (0)