Class StateMachine<T>

java.lang.Object
com.amalgamasimulation.engine.StateMachine<T>
Type Parameters:
T - type of this state machine's states, typically a enumeration
All Implemented Interfaces:
Timeable

public class StateMachine<T> extends Object implements Timeable
State machine is a key element of simulation models' logic. State machine has states and transitions between them. States are associated with instances of the generic type StateMachine, typically a enumeration or just Object. A transition can connect a state to a different state or to itself. Transitions are directed, i.e. if a transition connects state A with state B, it only allows to change state from A to B, but not vice versa. Transitions are executed when state machine receives messages receiveMessage(Object).

Actions can be executed when states are entered and exited. The actions can be added by methods like addEnterAction(Object, Consumer) and addExitAction(Object, Consumer).

State machine is always in exactly one state, even inside the code of handling any action. The state can be retrieved by currentState() method.

Transitions may be of 2 types:

  • A default transition is a transition that is triggered by message of the target state. For example, if a state machine has only two states - A and B, the default transition from A to B would be transition triggered by the message B.
  • A transition with predicate is a transition that calculates the boolean expression over the message sent to this state machine and executes if the result of the calculation is true

Author:
Andrey Malykhanov
  • Field Details

  • Constructor Details

    • StateMachine

      public StateMachine(T[] states, T initialState, Engine engine)
      Creates a new instance of a state machine with the specified states and sets it to the specified initial state.
      Parameters:
      states - states of this state machine
      initialState - initial state, this state machine will be in this state immediately after creation. Must be one of the states passed in the first argument of this constructor
      engine - Engine with which this state machine will be executed
  • Method Details

    • addAllTransitions

      public StateMachine<T> addAllTransitions()
      Adds all default transitions between all pairs of different states. A default transition is a transition that is triggered by message of the target state. For example, if a state machine has only two states - A and B, the default transition from A to B would be transition triggered by the message B.
      Returns:
      reference this object, for support of builder pattern
    • addState

      public StateMachine<T> addState(T state)
      Adds the specified state to this state machine.
      Parameters:
      state - specified state
      Returns:
      reference this object, for support of builder pattern
    • addTransition

      public StateMachine<T> addTransition(T fromState, T toState, Predicate<Object> predicate)
      Adds a transition with predicate to this state machine.

      A transition with predicate is a transition that calculates the boolean expression over the message sent to this state machine and executes if the result of the calculation is true

      Parameters:
      fromState - source state of the transition
      toState - target state of the transition
      predicate - predicate that will be evaluated to decide whether to execute the transition. The argument is the message sent to this state machine
      Returns:
      reference this object, for support of builder pattern
    • addTransition

      public StateMachine<T> addTransition(T fromState, T toState)
      Adds a default transition to this state machine.

      A default transition is a transition that is triggered by message of the target state. For example, if a state machine has only two states - A and B, the default transition from A to B would be transition triggered by the message B.

      Parameters:
      fromState - source state of the transition
      toState - target state of the transition
      Returns:
      reference this object, for support of builder pattern
    • addEnterAction

      public StateMachine<T> addEnterAction(T state, Consumer<Object> action)
      Adds an action that will be executed every time after the specified state is entered. This state machine will be in the specified state during the execution of the action. The action being added will be executed before all previously added actions.
      Parameters:
      state - specified state
      action - action to be executed. The argument is the message sent to this state machine that lead to execution of transition that resulted in entering the specified state
      Returns:
      reference this object, for support of builder pattern
    • addEnterAction

      public StateMachine<T> addEnterAction(BiConsumer<T,Object> action)
      Adds an action that will be executed every time this state machine enters any state. This state machine will be in the specified state during the execution of the action. The action being added will be executed before all previously added actions.
      Parameters:
      action - action to be executed. First argument of the action is the state that has just been entered. The second argument is the message sent to this state machine that lead to execution of transition that resulted in entering the state
      Returns:
      reference this object, for support of builder pattern
    • addEnterAction

      public StateMachine<T> addEnterAction(T state, StateMachine.HandlerOrder handlerOrder, Consumer<Object> action)
      Adds an action that will be executed every time after the specified state is entered. Allows to specify the order of execution across all other actions on entering the specified state. This state machine will be in the specified state during the execution of the action.
      Parameters:
      state - specified state
      handlerOrder - StateMachine.HandlerOrder enum item that specifies where to add the action in the list of previously added actions
      action - action to be executed. The argument is the message sent to this state machine that lead to execution of transition that resulted in entering the specified state
      Returns:
      reference this object, for support of builder pattern
    • addExitAction

      public StateMachine<T> addExitAction(T state, StateMachine.HandlerOrder handlerOrder, Consumer<Object> action)
      Adds an action that will be executed every time before the specified state is exited. Allows to specify the order of execution across all other actions on exiting the specified state. This state machine will be in the specified state during the execution of the action.
      Parameters:
      state - specified state
      handlerOrder - StateMachine.HandlerOrder enum item that specifies where to add the action in the list of previously added actions
      action - action to be executed. The argument is the message sent to this state machine that lead to execution of transition that resulted in exiting the specified state
      Returns:
      reference this object, for support of builder pattern
    • addExitAction

      public StateMachine<T> addExitAction(T state, Consumer<Object> action)
      Adds an action that will be executed every time before the specified state is exited. This state machine will be in the specified state during the execution of the action. The action being added will be executed before all previously added actions.
      Parameters:
      state - specified state
      action - action to be executed. The argument is the message sent to this state machine that lead to execution of transition that resulted in exiting the specified state
      Returns:
      reference this object, for support of builder pattern
    • addSingleEnterActionHandler

      public StateMachine<T> addSingleEnterActionHandler(T state, Consumer<Object> action)
      Adds an action that will be executed at most once after the specified state is entered. This state machine will be in the specified state during the execution of the action. After the first execution, the handler will be deleted
      Parameters:
      state - specified state
      action - action to be executed. The argument is the message sent to this state machine that lead to execution of transition that resulted in entering the specified state
      Returns:
      reference this object, for support of builder pattern
    • currentState

      public T currentState()
      Returns the current state of this state machine.
      Returns:
      current state of this state machine.
    • statistics

      public SingleStateStatistics<T> statistics()
      Returns a SingleStateStatistics object that contains statistical data about time this state machine spent in its states.
      Returns:
      SingleStateStatistics object containing the statistical data about this state machine
    • receiveMessage

      public void receiveMessage(Object message)
      Makes this state machine receive and process the specified message. Receiving a message can result in executing a transition and changing this machine's state. If there are no suitable transitions from the current state, the message will be discarded.
      Parameters:
      message - specified message
    • states

      public List<T> states()
      Returns an unmodifiable list of all states of this state machine.
      Returns:
      unmodifiable list of all states of this state machine
    • outgoingTransitions

      public List<Pair<Predicate<Object>,T>> outgoingTransitions(T fromState)
      Returns an unmodifiable list of all transitions starting at the specified state.
      Parameters:
      fromState - the specified state
      Returns:
      unmodifiable list of all transitions starting at the specified state
    • setCurrentState

      public void setCurrentState(T currentState)
      Directly and immediately changes the current state of this state machine. This method must be used with caution as it does not result in calling any actions and handlers. State changes made by this method are also not reflected correctly in statistics returned by statistics() method.

      Typical case for using this method is immediately after initialization of the state machine when its initial state can only be calculated after calling the constructor.

      Parameters:
      currentState - state to be set to this state machine
    • currentStateBeginTime

      public double currentStateBeginTime()
      Returns the simulation time when the current state was last time entered.
      Returns:
      simulation time when the current state was last time entered
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • beginDate

      public LocalDateTime beginDate()
      Description copied from interface: Timeable
      Returns the begin date, i.e. the simulation date that corresponds to zero simulation time
      Specified by:
      beginDate in interface Timeable
      Returns:
      simulation date that corresponding to zero simulation time
    • timeUnit

      public ChronoUnit timeUnit()
      Description copied from interface: Timeable
      Returns the simulation time unit, i.e. period unit that corresponds to one unit of simulation time
      Specified by:
      timeUnit in interface Timeable
      Returns:
      period unit that corresponds to one unit of simulation time
    • time

      public double time()
      Returns the current simulation time, i.e. time of the Engine that is used to simulate this state machine.
      Returns:
      current simulation time
    • throwsExceptionForUnusedMessages

      public boolean throwsExceptionForUnusedMessages()
      Returns true if this state machine is configured to throw exceptions on unused messages, and false otherwise.

      If this method returns true then a RuntimeException will be thrown if this state machine receives a message that does not cause it to activate any transition.

      The default setting is false, so by default, a state machine silently swallows the unused messages.

      Returns:
      true if this state machine is configured to throw exceptions on unused messages, and false otherwise
    • setThrowExceptionForUnusedMessages

      public StateMachine<T> setThrowExceptionForUnusedMessages(boolean throwExceptionForUnusedMessages)
      Specifies if this state machine should throw a RuntimeException if it receives a message that does not cause it to immediately activate any transition. Such behavior can be useful if the state machine is designed to always change state as result of receiving messages. Swallowing messages without activating the transitions in this case can be a source of bugs.

      The default setting is false, so by default, a state machine silently swallows the unused messages.

      Parameters:
      throwExceptionForUnusedMessages - whether or not to throw the exception for unused message
      Returns:
      reference this object, for support of builder pattern