KStateMachine / kstatemachine

KStateMachine is a Kotlin DSL library for creating state machines and statecharts.
https://kstatemachine.github.io/kstatemachine/
Boost Software License 1.0
339 stars 19 forks source link

State machine and Android lifecycle #80

Closed ayanyev closed 6 months ago

ayanyev commented 6 months ago

I tried to tie state machine to Android lifecycle:

  1. sm.stop() called at onStop() lifecycle callback
    • consideration 1: events are not handled when activity is in background
  2. sm.destroy() called at onDestroy() lifecycle callback
    • consideration: object/singleton events are released and can be reused

But failed because stop() causes that DestroyEvent is not handled. And it is not clear, how can I call only destroy() without stop() if they bound to callbacks.

I know about stop parameter in destroy() but it is useless it in my case.

Any thoughts? May be I misuse these calls?

ayanyev commented 6 months ago

A small change can help

    override suspend fun processEvent(event: Event, argument: Any?): ProcessingResult {
        return coroutineAbstraction.withContext {
            checkNotDestroyed()
            check(isRunning || **event is DestroyEvent**) { "$this is not started, call start() first" }
nsk90 commented 6 months ago

Hi! The fact that you cannot effectively call destroy() on stopped StateMachine is a bug. It was possible on older library versions but it was broken when I moved destroy() method to event-processing mechanism. And missed such case.

As a workaround you can try using start() + destroy() combination in Activity::onDestroy().

I will check how I can fix this and make destroy() working on stopped StateMachine. Thank You!

nsk90 commented 6 months ago

consideration: object/singleton events are released and can be reused

I suppose you meant States (not Events)

nsk90 commented 6 months ago

Actually, in your usecase you don't have to use destroy() in Activity::onDestroy(). As createStateMachine() has autoDestroyOnStatesReuse argument. But looks it is broken for the same reason, as implemented through same destroy() call.

ayanyev commented 6 months ago

Ha! This might be the reason as well

nsk90 commented 6 months ago

fixed https://github.com/nsk90/kstatemachine/releases/tag/v0.24.1