Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 2
0
        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> >));
        }
Exemplo n.º 3
0
 internal static IEnumerable <TTrigger> EnumeratePermittedTriggers <TState, TTrigger>(
     RawStateMachineBase <TState, TTrigger> machine)
 {
     foreach (var triggerRepresentation in machine.CurrentStateRepresentation.Triggers)
     {
         yield return(triggerRepresentation.Trigger);
     }
 }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }