internal static void MoveToStateCore <TState, TTrigger>(TState state, StateTransitionOption option, RawStateMachineBase <TState, TTrigger> machine, bool ignoreInvalidStates = false) { StateRepresentation <TState, TTrigger> targetRep; if (machine.Representations.TryGetValue(state, out targetRep)) { var currentRep = machine.CurrentStateRepresentation; machine.RaiseTransitionStarted(targetRep.State); var transition = new Transition <TState, TTrigger>(currentRep.State, state); if ((option & StateTransitionOption.CurrentStateExitTransition) == StateTransitionOption.CurrentStateExitTransition) { currentRep.OnExitAction?.Invoke(transition); } if ((option & StateTransitionOption.NewStateEntryTransition) == StateTransitionOption.NewStateEntryTransition) { targetRep.OnEntryAction?.Invoke(transition); } var pastState = currentRep.State; machine.CurrentStateRepresentation = targetRep; machine.RaiseTransitionExecuted(pastState); } else { if (!ignoreInvalidStates) { machine.RaiseInvalidState(state); } } }
internal static bool CanHandleTrigger <TState, TTrigger>(TTrigger trigger, RawStateMachineBase <TState, TTrigger> machine, bool exactMatch = false) { var res = FindAndEvaluateTriggerRepresentation(trigger, machine, false); if (res == null) { return(false); } if (StateConfigurationHelper.CheckFlag(res.TransitionFlags, TransitionFlag.DynamicState)) { var dynamicState = ((Func <DynamicState <TState> >)res.NextStateRepresentationWrapper)(); if (!dynamicState.CanTransition) { return(false); } } if (!exactMatch) { return(true); } return(res.OnTriggerAction.GetType() == typeof(Action <Transition <TState, TTrigger> >)); }
internal static IEnumerable <TTrigger> EnumeratePermittedTriggers <TState, TTrigger>( RawStateMachineBase <TState, TTrigger> machine) { foreach (var triggerRepresentation in machine.CurrentStateRepresentation.Triggers) { yield return(triggerRepresentation.Trigger); } }
internal static TriggerRepresentation <TTrigger> FindAndEvaluateTriggerRepresentation <TState, TTrigger>( TTrigger trigger, RawStateMachineBase <TState, TTrigger> machine, bool raiseInvalidTriggers = true) { var triggerRep = StateConfigurationHelper.FindTriggerRepresentation(trigger, machine.CurrentStateRepresentation); if (triggerRep == null) { if (raiseInvalidTriggers) { machine.RaiseInvalidTrigger(trigger); } return(null); } var predicate = triggerRep.ConditionalTriggerPredicate; if (predicate != null) { if (!predicate()) { if (raiseInvalidTriggers) { machine.RaiseInvalidTrigger(trigger); } return(null); } } // Handle ignored trigger if (triggerRep.NextStateRepresentationWrapper == null) { return(null); } return(triggerRep); }
internal static bool CanHandleTrigger <TState, TTrigger>(TTrigger trigger, RawStateMachineBase <TState, TTrigger> machine, Type argumentType) { var res = FindAndEvaluateTriggerRepresentation(trigger, machine, false); if (res == null) { return(false); } if (StateConfigurationHelper.CheckFlag(res.TransitionFlags, TransitionFlag.DynamicState)) { var dynamicState = ((Func <DynamicState <TState> >)res.NextStateRepresentationWrapper)(); if (!dynamicState.CanTransition) { return(false); } } var type = typeof(Action <,>).MakeGenericType(typeof(Transition <TState, TTrigger>), argumentType); return(res.OnTriggerAction.GetType() == type); }
internal static void FireCore <TState, TTrigger>(TTrigger trigger, RawStateMachineBase <TState, TTrigger> machine, bool raiseInvalidStateOrTrigger = true) { var currentStateRepresentation = machine.CurrentStateRepresentation; var triggerRep = DiagnosticsHelper.FindAndEvaluateTriggerRepresentation(trigger, machine, raiseInvalidStateOrTrigger); if (triggerRep == null) { return; } // Catch invalid parameters before execution. Action <Transition <TState, TTrigger> > triggerAction = null; try { triggerAction = (Action <Transition <TState, TTrigger> >)triggerRep.OnTriggerAction; } catch (InvalidCastException) { if (raiseInvalidStateOrTrigger) { machine.RaiseInvalidTrigger(trigger); } return; } StateRepresentation <TState, TTrigger> nextStateRep = null; if (StateConfigurationHelper.CheckFlag(triggerRep.TransitionFlags, TransitionFlag.DynamicState)) { var dynamicState = ((Func <DynamicState <TState> >)triggerRep.NextStateRepresentationWrapper)(); if (!dynamicState.CanTransition) { return; } var state = dynamicState.ResultingState; nextStateRep = StateConfigurationHelper.FindStateRepresentation(state, machine.Representations); if (nextStateRep == null) { if (raiseInvalidStateOrTrigger) { machine.RaiseInvalidState(state); } return; } } else { nextStateRep = (StateRepresentation <TState, TTrigger>)triggerRep.NextStateRepresentationWrapper; } var transition = new Transition <TState, TTrigger>(currentStateRepresentation.State, nextStateRep.State, trigger); machine.RaiseTransitionStarted(nextStateRep.State); // Current exit var currentExit = currentStateRepresentation.OnExitAction; currentExit?.Invoke(transition); // Trigger entry triggerAction?.Invoke(transition); // Next entry var nextEntry = nextStateRep.OnEntryAction; nextEntry?.Invoke(transition); var pastState = machine.CurrentState; machine.CurrentStateRepresentation = nextStateRep; machine.RaiseTransitionExecuted(pastState); }