Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State machine's dontTransition() method #6

Open
uburoiubu opened this issue Oct 11, 2018 · 8 comments
Open

State machine's dontTransition() method #6

uburoiubu opened this issue Oct 11, 2018 · 8 comments

Comments

@uburoiubu
Copy link

Hi, I really appreciate your implementation of state machine.

I have one question though: you have this method called dontTransition() which makes the state machine reenter the same state. What would be the way to workaround this and not reenter the same state? Is there something like ignoreEvent() method?

Thanks.

@zhxnlai
Copy link
Collaborator

zhxnlai commented Oct 15, 2018

@uburoiubu Did you want to stay in the same state without emitting a transition?

@uburoiubu
Copy link
Author

@zhxnlai, yes, I did.

@zhxnlai
Copy link
Collaborator

zhxnlai commented Oct 15, 2018

@uburoiubu I don't think we need an ignoreEvent method because

  1. although dontTransition returns an identity transition, it can be filtered afterwards.
onTransition {
        logger.d("received unexpected event ${validTransition.event}")
        val validTransition = it as? StateMachine.Transition.Valid ?: return@onTransition
        if (validTransition.from == validTransition.to) {
                logger.d("received expected event ${validTransition.event} but did not change state")
                return@onTransition
        }
        logger.d("received expected event ${validTransition.event} and changed state")
        // ...
}
  1. ignoreEvent is less debuggable because you would need to write more code to intercept events

@uburoiubu
Copy link
Author

uburoiubu commented Oct 17, 2018

@zhxnlai, thanks. Could you elaborate more on the convenience ofdontTransition() command? as far as I understood, it is more like reenterThisState(). Or not?

Suppose I don't write the following declaration:

on<Event.OnConfigChanged> { dontTransition() }

then it is an invalid transition for state graph, but on the other hand, we stay in the same state.

If I write it, I reenter the same state, although I write dontTransition(). It is a little misleading in terms of naming.

Thanks again.

@bbaldino
Copy link

bbaldino commented Jan 2, 2019

I had the same reaction and was surprised when dontTransition ends up causing an identity transition. I eventually ended up doing the filtering suggested above, but fixing things this way did make me wish that StateDefinitionBuilder.on had some overloads with varying amounts of generic values for the handled events; I have a lot of situations like the following:

state<MyState.SomeState> {
  on<Event.InterestingEvent> {
    transitionTo(MyState.OtherState)
  }
  on<Event.NoOpEvent1> {
    dontTransition()
  }
  on<Event.NoOpEvent2> {
    dontTransition()
  }
  on<Event.NoOpEvent3> {
    dontTransition()
  }
}

where it'd be nice to be able to do:

state<MyState.SomeState> {
  on<Event.InterestingEvent> {
    transitionTo(MyState.OtherState)
  }
  on<Event.NoOpEvent1, Event.NoOpEvent2, Event.NoOpEvent3> {
    dontTransition()
  }
}

I tried to accomplish something like this using Matcher, but since its constructor is private I couldn't. Maybe there's another way I'm missing?

@bbaldino
Copy link

bbaldino commented Jan 2, 2019

Actually, I was just looking at Scarlet's usages of the state machine and saw this usage

private fun lifecycleStart() =
            any<Event, Event.OnLifecycle.StateChange<*>>().where { state == Lifecycle.State.Started }

which looks like that should make this possible, so I'll play with that a bit.

@ThomasDotCodes
Copy link

ThomasDotCodes commented Oct 10, 2019

unfortunately it seems that the dontTransition() method also causes the onEnter to be called for the state. Haven't found a great way around this yet.

@kunalpowar
Copy link

kunalpowar commented Nov 8, 2021

I am with you @ThomasDotCodes, I do have events in my state machine, where I need to execute some code but not transition. This behaviour triggering the onEnter is making it hard to achieve what I want. I am having to write all the onEnter code under onTransition when I detect a state change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants