Workiva / state_machine

Easily create a finite state machine and define legal state transitions. Listen to state entrances, departures, and transitions.
Other
61 stars 24 forks source link

Entering next state before leaving previous, in 2 states at once? #91

Open macasas opened 6 months ago

macasas commented 6 months ago

Hi, trying to use your state package in a dart test project.
Code is below, but first here is the output with added comments as to where things are not as expected. It's a traffic light in the UK, red, redamber, green, amber, red

Any suggestions as to what I am doing wrong would be grateful.

Entered: red
Exit: red
Entered: redamber
Exit: redamber
Entered: green.      // okay so far
Entered: amber     // but then enters amber before leaving green
Exit: green
Entered: red.         // then enters red before leaving amber
Exit: amber

Code

import 'package:state_machine/state_machine.dart';

init()  {
  StateMachine trafficlight = StateMachine('trafficlight');

  //states
  State red = trafficlight.newState('red');
  State redamber = trafficlight.newState('redamber');
  State amber = trafficlight.newState('amber');
  State green = trafficlight.newState('green');

  //transitions
  StateTransition readyToGo = trafficlight.newStateTransition('readyToGo', [red], redamber);
  StateTransition go = trafficlight.newStateTransition('go', [redamber], green);
  StateTransition readyToStop = trafficlight.newStateTransition('readyToStop', [green], amber);
  StateTransition stop = trafficlight.newStateTransition('stop', [amber], red);

  red.onEnter.listen((StateChange change) { 
    print('Entered: red'); 
    readyToGo();
  });
  red.onLeave.listen((StateChange change) { 
    print('Exit: red'); 
  });
  redamber.onEnter.listen((StateChange change) { 
    print('Entered: redamber'); 
    go();
  });
  redamber.onLeave.listen((StateChange change) { 
    print('Exit: redamber'); 
  });
  green.onEnter.listen((StateChange change) { 
    print('Entered: green'); 
    readyToStop();
  });
  green.onLeave.listen((StateChange change) { 
    print('Exit: green'); 
  });
  amber.onEnter.listen((StateChange change) { 
    print('Entered: amber'); 
    stop();
  });
  amber.onLeave.listen((StateChange change) { 
    print('Exit: amber'); 
  });

  // RUN
  trafficlight.start(red);
}

I also tried this format, but onDone is never called

  red.onEnter.listen(
    (StateChange change) { 
      print('Entered: red'); 
    },
    onDone: () {
      readyToGo();
    }
  );