@@ -10,7 +10,8 @@ import kotlinx.coroutines.flow.StateFlow
1010import kotlinx.coroutines.flow.flowOf
1111
1212/* *
13- * Creates a [BackStackWorkflow].
13+ * Creates a [BackStackWorkflow]. See the docs on [BackStackWorkflow.runBackStack] for more
14+ * information about what [block] can do.
1415 */
1516public inline fun <PropsT , OutputT > backStackWorkflow (
1617 crossinline block : suspend BackStackScope <OutputT >.(props: StateFlow <PropsT >) -> Unit
@@ -25,62 +26,65 @@ public inline fun <PropsT, OutputT> backStackWorkflow(
2526 * Returns a [Workflow] that renders a [BackStackScreen] whose frames are controlled by the code
2627 * in [runBackStack].
2728 *
28- * [runBackStack] can render child workflows by calling [BackStackScope.showWorkflow]. It can emit
29- * outputs to its parent by calling [BackStackScope.emitOutput], and access its props via
30- * the parameter passed to [runBackStack].
31- *
32- * # Examples
33- *
34- * The backstack is represented by _nesting_ `showWorkflow` calls. Consider this example:
35- * ```
36- * backStackWorkflow {
37- * showWorkflow(child1) {
38- * showWorkflow(child2) {
39- * showWorkflow(child3) {
40- * // goBack()
41- * }
42- * }
43- * }
44- * }
45- * ```
46- * This eventually represents a backstack of `[child1, child2, child3]`. `child2` will be pushed
47- * onto the stack when `child1` emits an output, and `child3` pushed when `child2` emits. The
48- * lambdas for `child2` and `child3` can call `goBack` to pop the stack and cancel the lambdas that
49- * called their `showWorkflow`, until the next output is emitted.
50- *
51- * Contrast with calls in series:
52- * ```
53- * backStackWorkflow {
54- * showWorkflow(child1) { finishWith(Unit) }
55- * showWorkflow(child2) { finishWith(Unit) }
56- * showWorkflow(child3) { }
57- * }
58- * ```
59- * `child1` will be shown immediately, but when it emits an output, instead of pushing `child2` onto
60- * the stack, `child1` will be removed from the stack and replaced with `child2`.
61- *
62- * These can be combined:
63- * ```
64- * backStackWorkflow {
65- * showWorkflow(child1) {
66- * showWorkflow(child2) {
67- * // goBack(), or
68- * finishWith(Unit)
69- * }
70- * showWorkflow(child3) {
71- * // goBack()
72- * }
73- * }
74- * }
75- * ```
76- * This code will show `child1` immediately, then when it emits an output show `child2`. When
77- * `child2` emits an output, it can decide to call `goBack` to show `child1` again, or call
78- * `finishWith` to replace itself with `child3`. `child3` can also call `goBack` to show `child`
79- * again.
29+ * [runBackStack] can show renderings and render child workflows, as well as emit outputs to this
30+ * workflow's parent. See the docs on that method for more info.
8031 */
8132public abstract class BackStackWorkflow <PropsT , OutputT > :
8233 Workflow <PropsT , OutputT , BackStackScreen <Screen >> {
8334
35+ /* *
36+ * Show renderings by calling [BackStackScope.showScreen]. Show child workflows by calling
37+ * [BackStackScope.showWorkflow]. Emit outputs by calling [BackStackScope.emitOutput].
38+ *
39+ * # Examples
40+ *
41+ * The backstack is represented by _nesting_ `showWorkflow` calls. Consider this example:
42+ * ```
43+ * backStackWorkflow {
44+ * showWorkflow(child1) {
45+ * showWorkflow(child2) {
46+ * showWorkflow(child3) {
47+ * // goBack()
48+ * }
49+ * }
50+ * }
51+ * }
52+ * ```
53+ * This eventually represents a backstack of `[child1, child2, child3]`. `child2` will be pushed
54+ * onto the stack when `child1` emits an output, and `child3` pushed when `child2` emits. The
55+ * lambdas for `child2` and `child3` can call `goBack` to pop the stack and cancel the lambdas that
56+ * called their `showWorkflow`, until the next output is emitted.
57+ *
58+ * Contrast with calls in series:
59+ * ```
60+ * backStackWorkflow {
61+ * showWorkflow(child1) { finishWith(Unit) }
62+ * showWorkflow(child2) { finishWith(Unit) }
63+ * showWorkflow(child3) { }
64+ * }
65+ * ```
66+ * `child1` will be shown immediately, but when it emits an output, instead of pushing `child2` onto
67+ * the stack, `child1` will be removed from the stack and replaced with `child2`.
68+ *
69+ * These can be combined:
70+ * ```
71+ * backStackWorkflow {
72+ * showWorkflow(child1) {
73+ * showWorkflow(child2) {
74+ * // goBack(), or
75+ * finishWith(Unit)
76+ * }
77+ * showWorkflow(child3) {
78+ * // goBack()
79+ * }
80+ * }
81+ * }
82+ * ```
83+ * This code will show `child1` immediately, then when it emits an output show `child2`. When
84+ * `child2` emits an output, it can decide to call `goBack` to show `child1` again, or call
85+ * `finishWith` to replace itself with `child3`. `child3` can also call `goBack` to show `child`
86+ * again.
87+ */
8488 abstract suspend fun BackStackScope<OutputT>.runBackStack (props : StateFlow <PropsT >)
8589
8690 final override fun asStatefulWorkflow ():
@@ -116,15 +120,25 @@ public sealed interface BackStackScope<OutputT> : CoroutineScope {
116120 * that is relevant within a backstack, and it's not possible to know whether the parent supports
117121 * back. What you probably want is to emit an output instead to tell the parent to go back.
118122 *
119- * @param props The props passed to [workflow] when rendering it. This method will suspend until
120- * the first value is emitted. Consider transforming the [BackStackWorkflow.runBackStack] props
121- * [StateFlow] or using [flowOf].
123+ * @param props The props passed to [workflow] when rendering it. [showWorkflow] will suspend
124+ * until the first value is emitted. Consider transforming the [BackStackWorkflow.runBackStack]
125+ * props [StateFlow] or using [flowOf].
122126 */
123127 suspend fun <ChildPropsT , ChildOutputT , R > showWorkflow (
124128 workflow : Workflow <ChildPropsT , ChildOutputT , Screen >,
129+ // TODO revert this back to a single value – can use the same trick to update props as for
130+ // emitting new screens.
125131 props : Flow <ChildPropsT >,
126132 onOutput : suspend BackStackNestedScope <OutputT , R >.(output: ChildOutputT ) -> Unit
127133 ): R
134+
135+ /* *
136+ * Shows the screen produced by [screenFactory]. Suspends until [BackStackNestedScope.finishWith]
137+ * or [BackStackNestedScope.goBack] is called.
138+ */
139+ suspend fun <R > showScreen (
140+ screenFactory : BackStackNestedScope <OutputT , R >.() -> Screen
141+ ): R
128142}
129143
130144/* *
@@ -140,14 +154,14 @@ public sealed interface BackStackNestedScope<OutputT, R> : BackStackScope<Output
140154 * [value] and cancels any output handlers still running for that workflow. The workflow is
141155 * removed from the stack and will no longer be rendered.
142156 */
143- fun finishWith (value : R ): Nothing
157+ suspend fun finishWith (value : R ): Nothing
144158
145159 /* *
146160 * Removes all workflows started by the parent workflow's handler that invoked this [showWorkflow]
147161 * from the stack, and cancels that parent output handler coroutine (and thus all child workflow
148162 * coroutines as well).
149163 */
150- fun goBack (): Nothing
164+ suspend fun goBack (): Nothing
151165}
152166
153167public suspend inline fun <OutputT , ChildOutputT , R > BackStackScope<OutputT>.showWorkflow (
0 commit comments