public void InitialState() { m_pMachine = new TStateMachine <ACharactor>(this); if (null == m_pStates || 0 == m_pStates.Length) { m_pStates = new CharactorState[(int)ECharactorState.EPS_Max]; } }
/// <summary> /// Act on an event, return the new state or null if there are no transitions possible (even inherited) /// </summary> public async Task <State?> OnEvent(TStateMachine stateMachine, TEvent @event, TContext context) { StateDefinition?selfOrAncestor = this.stateDefinition; int safety = 1000; // just cautious code to ensure a bad data structure can't crash app while (selfOrAncestor != null && --safety > 0) { if (selfOrAncestor.transitions.TryGetValue(@event, out Func <TStateMachine, State, TEvent, TContext, Task <State> >?transition)) { // Execute the transition to get the new state State newState = await transition !(stateMachine, this, @event, context); if (newState != this) { // Entry and exit actions only fire when CHANGING state // Exit actions happen from the innermost state to the outermost state var oStates = this.stateDefinition.SelfAndAncestorsInAscendingOrder; foreach (var n in oStates) { if (newState.Is(n.GetState())) { break; // Stop if we reach a common ancestor - we are NOT exiting that state } if (!(n.ExitAction is null)) { await n.ExitAction(stateMachine, newState, @event, context); } } // Entry actions happen from the base-most state to the innermost state (like Constructors) var nStates = newState.stateDefinition.SelfAndAncestorsInAscendingOrder.Reverse(); foreach (var n in nStates) { if (this.Is(n.GetState())) { continue; // If the old state is already a descendant of that state we don't enter it } if (!(n.EntryAction is null)) { await n.EntryAction(stateMachine, @event, newState, context); } } } return(newState); } // otherwise, try parent, see if they have a transition we can use [inheritance] selfOrAncestor = selfOrAncestor.Parent; } return(null); }
public CommandDispatcher(TStateMachine owner) { m_Owner = owner; }
public virtual void Execute(TStateMachine owner) { m_CommandState = ECommandState.Running; }