question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Missing listener which reports state changes in an "atomic" way

See original GitHub issue

I have the following sample state machine:

  val machine = createStateMachine(name = "app") {
    initialState("init")
    state("main", childMode = ChildMode.PARALLEL) {
      state("main_screen") {
        initialState("idle")
      }
      state("bottom_bar") {
        initialState("bar_visible")
        state("bar_hidden")
      }
      state("bottom_sheet") {
        initialState("sheet_hidden")
        state("search")
        state("routing")
        state("bookmarks")
        state("more")
      }
    }

and the following listener:

  machine.addListener(object : StateMachine.Listener {
    override fun onStateChanged(newState: IState) {
      println("active states:\n${machine.activeStates().joinToString(",")}")
    }
  })

There are few problems with it. Before I list them I want to say that I think they are caused by the fact that this listener should simply have a different name, something like onStateEntered, because a “state change” usually means the machine arriving at the new state (or set of states) and is usually called after full transition has happened.

From the current name I expected it to behave as “active state change listener” and had the following problems:

  1. When entering the main state this listener reports 3 separate state changes:
    • change to main_screen.idle
    • change to bottom_bar.bar_visible
    • change to bottom_sheet.sheet.hidden But the parallel state change is one change, i.e machine goes from init state to all 3 parallel states as one transaction. I mean internally it may do several onEntry in order, but to the user this should be reported as a single state change (it just so happens that the next state consists of 3 sub-states, but it’s still one state);
  2. Also when used in non-parallel states, but with child states, this listener reports changes to “compound states”, but it should only report “leaf” states. That is if some event changes state from parent1.childA to parent1.parent2.parent3.childB, listener will be called with arguments parent2, parent3, childB while the actual “finalized” state changed only once, because single event moves machine from one state to another (=1 state change) and this listener should be called only once with argument childB. At least this is how all libs that I’ve used behave…
  3. It has only one argument which doesn’t “feel” right in presence of parallel state feature, I’d expect active states set to be passed there…

Perhaps one solution to this is to rename the existing listener somehow, but I’d also like to be able to use the actual state change listener implemented sometime.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
nsk90commented, Oct 7, 2022

I see that jetpack repo has 0.16.0, but maven central is still on 0.15.0 (reporting this in case it got out of sync somehow).

I will publish to maven central on next week

0reactions
nsk90commented, Oct 7, 2022

Try this workaround for your sample:

                targetState = {
                    val activeChild = event.state.activeStates().single()
                    val data = (activeChild as DataState<Int>).data
                    if (data == 3) s2 else s3
                }

It is easy to get data from DataState and put it into FinishedState at the moment of generation on library side. But I am not sure that it will work without casts on client side. (at least with current design)

Yes, let’s create new issue. I think it can be done some way.

Read more comments on GitHub >

github_iconTop Results From Across the Web

pmndrs/zustand: Bear necessities for state ... - GitHub
Select your state and the component will re-render on changes. ... with strict-equality (old === new) by default, this is efficient for atomic...
Read more >
Actions and reducers: updating state - Human Redux
In Redux all changes to the application state happen via an "action. ... But either way, the action is a self-contained, atomic thing...
Read more >
Saving state with fragments - Android Developers
The following table outlines the operations that cause your fragment to lose state, along with whether the various types of state persist ...
Read more >
JCR 2.0: 12 Observation (Content Repository for Java ...
Each event reports a single simple change to the structure of the persistent workspace in terms of an item added, changed, moved or...
Read more >
U.S. 'not fixated' on Iran answering queries on atomic work
U.S. Secretary of State John Kerry on Tuesday suggested that ... to atomic weapons research and that some sanctions relief under a possible ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found