You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
called each time your proxied machine updates UI state or explicitly when calling [updateUi](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MultiMachineState.kt#L69).
1194
+
Here you take a decision on changes and build a common resulting UI state. See the dedicated section below.
runs machines with additional [MachineLifecycle](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/lifecycle/MachineLifecycle.kt)
1213
+
management. You could make some machines active and dormant with [ActiveMachineContainer](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/ProxyMachineContainer.kt#L65)
1214
+
methods.
1215
+
1216
+

1217
+
1218
+
Container is initialized with a collection of [MachineInit](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MachineInit.kt)
1219
+
structures:
1220
+
1221
+
```kotlin
1222
+
/**
1223
+
* Proxy machine initialization record
1224
+
*/
1225
+
interfaceMachineInit<G:Any, U:Any> {
1226
+
/**
1227
+
* Machine key to find a machine among the others
1228
+
*/
1229
+
val key:MachineKey<G, U>
1230
+
1231
+
/**
1232
+
* Initial UI state for the machine
1233
+
*/
1234
+
val initialUiState:U
1235
+
1236
+
/**
1237
+
* Creates initial child state
1238
+
* [MachineLifecycle] passed to the factory determines the activity of
1239
+
* the machine within the machine group. For example, for a paging screen
1240
+
* you may want to stop some pending operations when active machine is not
The `init` function is called each time the container needs to create a new machine. The [MachineLifecycle](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/lifecycle/MachineLifecycle.kt)
1248
+
interface passed to initialization may be used by your states to determine if the machine is suspended
1249
+
or active. If you use coroutines you could use [asFlow](coroutines/src/commonMain/kotlin/com/motorro/commonstatemachine/coroutines/lifecycle/lifecycleStateFlow.kt)
1250
+
function to convert it to `Flow`. See [example](examples/timer/src/commonMain/kotlin/com/motorro/statemachine/timer/state/TimerState.kt) on how to start/stop
1251
+
your pending operations that are not needed when your machine is inactive: gps tracking, server messaging, etc.
1252
+
For example:
1253
+
1254
+
```kotlin
1255
+
1256
+
privatesealedclassMultiGesture {
1257
+
data classIntGesture(valdata:Int) : MultiGesture()
1258
+
data classStringGesture(valdata:String) : MultiGesture()
-[Parallel](examples/multi/parallel/src/main/java/com/motorro/statemachine/parallel/model/state/ParallelState.kt) - two machines running in parallel in one proxy state
1290
+
-[Navbar](examples/multi/navbar/src/main/java/com/motorro/statemachine/navbar/model/state/NavbarState.kt) - several machines running in proxy state, one of them active at a time
1291
+
1292
+
### Mapping UI states
1293
+
1294
+
The gesture/ui type systems for each machine in composition are different, so we need some kind of
1295
+
type casting to be on a safe side. Binding machines with keys in `MachineInit` makes sure the machine type
1296
+
corresponds to the key and is used to map key to correct UI-state in [mapUiState](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MultiMachineState.kt#L97)
1297
+
method of `MultiMachineState`. To be able to do it, take the [UiStateProvider](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MachineAccess.kt#L21)
1298
+
provided to the method to get the correct ui-state type:
1299
+
1300
+
```kotlin
1301
+
1302
+
privatesealedclassMultiGesture {
1303
+
data classIntGesture(valdata:Int) : MultiGesture()
1304
+
data classStringGesture(valdata:String) : MultiGesture()
val i:Int= provider.getValue(IntKey) // Cast to Int
1316
+
val s:String= provider.getValue(StringKey) // Cast to String
1317
+
return"$i - $s"// Combined state of any kind you like
1318
+
}
1319
+
}
1320
+
```
1321
+
1322
+
Check example states for use cases:
1323
+
1324
+
-[Parallel](examples/multi/parallel/src/main/java/com/motorro/statemachine/parallel/model/state/ParallelState.kt) - two machines running in parallel in one proxy state
1325
+
-[Navbar](examples/multi/navbar/src/main/java/com/motorro/statemachine/navbar/model/state/NavbarState.kt) - several machines running in proxy state, one of them active at a time
1326
+
1327
+
### Dispatching gestures
1328
+
1329
+
As with UI-state mapping, binding machines with keys in `MachineInit` makes sure the machine type
1330
+
corresponds to the key and is used to map key to correct gesture processor. Whenever the proxy receives
1331
+
a gesture it calls [mapGesture](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MultiMachineState.kt#L91).
1332
+
Using the provided [GestureProcessor](commonstatemachine/src/commonMain/kotlin/com/motorro/commonstatemachine/multi/MachineAccess.kt#L48)
1333
+
and a key you can get access to the proxied machine instance to map and process your gesture:
1334
+
1335
+
```kotlin
1336
+
1337
+
privatesealedclassMultiGesture {
1338
+
data classIntGesture(valdata:Int) : MultiGesture()
1339
+
data classStringGesture(valdata:String) : MultiGesture()
Check example states and test class for use cases:
1362
+
1363
+
-[Parallel](examples/multi/parallel/src/main/java/com/motorro/statemachine/parallel/model/state/ParallelState.kt) - two machines running in parallel in one proxy state
1364
+
-[Navbar](examples/multi/navbar/src/main/java/com/motorro/statemachine/navbar/model/state/NavbarState.kt) - several machines running in proxy state, one of them active at a time
1365
+
-[MultiMachineStateTest](commonstatemachine/src/commonTest/kotlin/com/motorro/commonstatemachine/multi/MultiMachineStateTest.kt) - unit test
1366
+
1367
+
### MachineLifecyle bonus
1368
+
1369
+
The interface used to pass the machine activity to proxied state machine could also be used as an
1370
+
view lifecycle monitor for your app. Pass [UiMachineLifecycle](commonstatemachine/src/androidMain/kotlin/com/motorro/commonstatemachine/lifecycle/UiMachineLifecycle.kt)
1371
+
to your model initialization to by able to suspend your machines when app is not in use.
1372
+
Similar to [state collection methods](https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda) optimized with lificycle.
1373
+
Check the [example](examples/lifecycle) to get the details.
1374
+
1166
1375
## Conclusion
1167
1376
1168
1377
I hope someone finds the article (and the library if you like to take it as-is) helpful in building
0 commit comments