示例#1
0
        StateMachine_Trigger_TransitionFromCurrentToSame_ConfiggedNotToRaiseExcep_DoesNotRaiseTransitionChangeEvents()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");

            var state1 = new State <StubStateModel>("state1");
            TransitionEventArgs <StubStateModel> transitioningArgs = null;

            state1.Entered += (s, e) => { transitioningArgs = e; };
            TransitionEventArgs <StubStateModel> transitionedArgs = null;

            state1.Exiting += (s, e) => { transitionedArgs = e; };

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);

            // verify that no transition events occurred
            Assert.Null(transitioningArgs);
            Assert.Null(transitionedArgs);
        }
        public IFluentStateMachine <TStateModel> Compile(StateMachineConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            return(builder.Compile(configuration));
        }
示例#3
0
        public void StateMachine_ValidConfigPassed_SetsConfigAsCurrentConfig()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoTransition = true
            };
            var machine = new StateMachine <StubStateModel>(config);

            Assert.Same(config, machine.Configuration);
            Assert.True(machine.Configuration.RaiseExceptionOnTriggerMatchingNoTransition);
        }
    public StateMachine(StateMachineConfiguration config)
    {
        if (config == null)
        {
            throw new ArgumentNullException();
        }

        this.Configure(config.States);
        this.Allow(config.Triggers);
    }
示例#5
0
        public static StateMachine <TState, TTrigger> Create <TState, TTrigger>(TState initialState,
                                                                                StateMachineConfiguration <TState, TTrigger> config)
        {
            Contract.Requires <ArgumentNullException>(initialState != null);
            Contract.Requires <ArgumentNullException>(config != null);

            var sm = new StateMachine <TState, TTrigger>(initialState, config);

            sm.UnhandledTriggerExecuted += InvalidTriggerException <TTrigger, TState> .Throw;

            return(sm);
        }
示例#6
0
        internal StateMachine(TState initialState, StateMachineConfiguration<TState, TTrigger> configuration)
        {
            Contract.Requires(configuration != null);
            Contract.Requires(initialState != null);

            currentStateRepresentation = configuration.GetStateRepresentation(initialState);
            if (currentStateRepresentation == null)
            {
                throw new InvalidOperationException("StateMachine has no state");
            }

            IsEnabled = true;
        }
示例#7
0
        internal BlockingStateMachine(TState initialState, StateMachineConfiguration <TState, TTrigger> configuration)
        {
            Contract.Requires(configuration != null);
            Contract.Requires(initialState != null);

            CurrentStateRepresentation = configuration.GetInitialStateRepresentation(initialState);
            if (CurrentStateRepresentation == null)
            {
                throw new InvalidOperationException("StateMachine has an unreachable state");
            }

            configDictionary = configuration.Config;
        }
        public void FluentStateMachineBuilder_CompileConfig_ReturnsNewStateMachineWithDefinedParts_WithConfig()
        {
            var builder = new FluentStateMachineBuilder <StubStateModel>();

            builder.State("s1", null);
            builder.Initiates();
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = true
            };
            var machine = builder.Compile(config);

            Assert.NotNull(machine);
            Assert.Same(config, machine.Configuration);
            Assert.Equal(true, machine.Configuration.RaiseExceptionBeforeTransitionToSameState);
        }
示例#9
0
        StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransFalse_NotThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoTransition = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // no exception shoudl happen, and that's good enough for us.
            machine.Trigger(trigger2, model);
        }
示例#10
0
        public IFluentStateMachine <TStateModel> Compile(StateMachineConfiguration configuration)
        {
            if (CurrentState == initial)
            {
                throw new FluentSyntaxException(
                          "Cannot compile an empty state machine.  No statements have been made to define this state machine");
            }
            Trigger(compileTrigger);
            var stateMachine = new StateMachine <TStateModel>(configuration);

            return(new FluentStateMachine <TStateModel>(
                       stateMachine,
                       states.Values.ToList(),
                       workingInitialState,
                       workingGlobalTransitionings,
                       workingGlobalTransitioneds,
                       workingGlobalTransitions));
        }
示例#11
0
        StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoPassingTransition = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger1, model));
        }
示例#12
0
        StateMachine_Trigger_NoPassingTransitionOnTrigger_ConfigRaiseOnNoPassingTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoPassingTransition = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2, m => 1 == 2);
            model.CurrentState = state1;

            // set up so that there's a matching transition, but the guard would fail when run

            // no exceptions should happen, and that's good enough for us
            machine.Trigger(trigger1, model);
        }
示例#13
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger1, model));
        }
示例#14
0
        public void StateMachine_Trigger_TransitionsToSameState_ConfigRaiseOnSameStateTranFalse_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionBeforeTransitionToSameState = false
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state1);
            model.CurrentState = state1;

            // set up scenario where state would transition from current to same state.
            // so no true transition would not occur

            // should not throw exception and that's good enough for us
            machine.Trigger(trigger1, model);
        }
示例#15
0
        public static IStateMachine <TState, TTrigger> Create <TState, TTrigger>(TState initialState,
                                                                                 StateMachineConfiguration <TState, TTrigger> config, bool blocking = false)
        {
            Contract.Requires <ArgumentNullException>(initialState != null);
            Contract.Requires <ArgumentNullException>(config != null);

            IStateMachine <TState, TTrigger> sm;

            if (blocking)
            {
                sm = new BlockingStateMachine <TState, TTrigger>(initialState, config);
            }
            else
            {
                sm = new StateMachine <TState, TTrigger>(initialState, config);
            }

            sm.UnhandledTriggerExecuted += InvalidTriggerException <TTrigger, TState> .Throw;
            return(sm);
        }
示例#16
0
        public void StateMachine_Trigger_NoStateOrGlobalTransOnTrigger_ConfigRaiseOnNoTransTrue_ThrowsInvalidTrigger()
        {
            var config = new StateMachineConfiguration {
                RaiseExceptionOnTriggerMatchingNoTransition = true
            };
            var machine  = new StateMachine <StubStateModel>(config);
            var model    = new StubStateModel();
            var trigger1 = new Trigger("trigger1");
            var trigger2 = new Trigger("trigger2");
            var state1   = new State <StubStateModel>("state1");
            var state2   = new State <StubStateModel>("state2");

            state1.AddTransition(trigger1, state2);
            model.CurrentState = state1;

            // set up so that current state of state 1 doesn't' define a trans for "trigger2", only "trigger1"

            Assert.Throws <InvalidTriggerException>(() =>
                                                    machine.Trigger(trigger2, model));
        }
示例#17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="StateMachine{T}"/> class.
 /// </summary>
 /// <param name="config">configuration</param>
 /// <param name="name">state machine name</param>
 /// <param name="id">state machine id</param>
 public StateMachine(StateMachineConfiguration <T> config, string name, long id)
     : base(name, id)
 {
     this.Config = config;
 }