Exemple #1
0
        /// <summary>
        /// <see cref="Transition"/>クラスの新しいインスタンスを初期化する.
        /// </summary>
        /// <param name="nextState">遷移先の状態.
        /// nullを指定すると, この遷移は内部遷移となる.(NotImplemented)</param>
        /// <param name="transitionMethod">遷移時に実行する処理.
        /// <see cref="Execute"/>を実行したときに, ここで指定した処理が実行される.
        /// 実行する処理が無い場合は, nullを指定する</param>
        public Transition(State nextState, TransitionMethodDelegate transitionMethod)
        {
            if (nextState == null)
            {
                throw new NotImplementedException();
            }

            NextState = nextState;
            TransitionMethod = transitionMethod;
        }
        private void GeroMachineSampleForm_Load(object sender, EventArgs e)
        {
            AllTriggers = new Trigger[3]
            {
                new Trigger(),
                new Trigger(),
                new Trigger()
            };
            State[] all_states = new State[3]
            {
                new NormalState(AllTriggers),
                new NormalState(AllTriggers),
                new NormalState(AllTriggers)
            };
            all_states[0].StateName = "State 1";
            all_states[1].StateName = "State 2";
            all_states[2].StateName = "State 3";
            var matrixData = new Dictionary<State, Dictionary<Trigger, ITransition>>
            {
                {
                    all_states[0],
                    new Dictionary<Trigger, ITransition>
                    {
                        { AllTriggers[0], new Transition(all_states[1], null) },
                        { AllTriggers[1], new Transition(all_states[2], null) },
                    }
                },
                {
                    all_states[1],
                    new Dictionary<Trigger, ITransition>
                    {
                        { AllTriggers[0], new Transition(all_states[2], null) },
                        { AllTriggers[1], new Transition(all_states[2], null) },
                        { AllTriggers[2], new Transition(all_states[0], null) }
                    }
                },
                {
                    all_states[2],
                    new Dictionary<Trigger, ITransition>
                    {
                        { AllTriggers[0], new Transition(all_states[2], null) },
                        { AllTriggers[2], new Transition(all_states[0], null) }
                    }
                }
            };

            TransitionMatrix transitino_matrix = new TransitionMatrix(matrixData);

            MainStateMachine = new StateMachine(all_states[0], transitino_matrix);
            CurrentStateNameLabel.Text = MainStateMachine.CurrentStateName;
        }
        /// <summary>
        /// 初期状態と状態遷移表を指定し,
        /// <see cref="StateMachine"/>クラスのインスタンスを初期化する.
        /// </summary>
        /// <param name="initialState">初期状態</param>
        /// <param name="matrixData">状態遷移表</param>
        /// <exception cref="ArgumentNullException">引数<paramref name="initialState"/>がnull,
        /// または引数<paramref name="matrixData"/>がnull.</exception>
        public StateMachine(State initialState, ITransitionMatrix matrixData)
        {
            if (initialState == null)
            {
                throw new ArgumentNullException("initialState");
            }
            if (matrixData == null)
            {
                throw new ArgumentNullException("matrixData");
            }

            CurrentState = initialState;
            TransitionMatrixData = matrixData;
        }
            public void TestConstructor(State setting_NextState, State expected_NextState,
				Transition.TransitionMethodDelegate setting_TransitionMethod,
				Transition.TransitionMethodDelegate expected_TransitionMethod)
            {
                // Execute
                Transition transition = new Transition(setting_NextState, setting_TransitionMethod);

                // Get result
                Type type = typeof(Transition);
                FieldInfo field_info = type.GetField("NextState",
                    BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
                State actual_NextState = (State)field_info.GetValue(transition);
                field_info = type.GetField("TransitionMethod",
                    BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
                var actual_TransitionMethod = (Transition.TransitionMethodDelegate)field_info.GetValue(transition);

                // Validate
                Assert.Equal(expected_NextState, actual_NextState);
                Assert.Equal(expected_TransitionMethod, actual_TransitionMethod);
            }
        /// <summary>
        /// 状態が<paramref name="currentState"/>のときにトリガ<paramref name="trigger"/>が発生した場合の,
        /// 起こる遷移を取得する.
        /// </summary>
        /// <param name="currentState">現在の状態</param>
        /// <param name="trigger">発生したトリガ</param>
        /// <returns><paramref name="currentState"/>で<paramref name="trigger"/>が発生したときに起こる遷移.
        /// 起こる遷移が無ければ, nullが返る.</returns>
        /// <exception cref="ArgumentNullException">引数<paramref name="currentState"/>がnull,
        /// または引数<paramref name="trigger"/>がnull.</exception>
        /// <exception cref="ArgumentOutOfRangeException">引数<paramref name="currentState"/>が,
        /// 状態遷移表に存在しない.</exception>
        public ITransition SearchTransition(State currentState, Trigger trigger)
        {
            if (currentState == null)
            {
                throw new ArgumentNullException("currentState");
            }
            if (trigger == null)
            {
                throw new ArgumentNullException("trigger");
            }
            if (MatrixData.ContainsKey(currentState) == false)
            {
                throw new ArgumentOutOfRangeException("currentState");
            }

            if (MatrixData[currentState].ContainsKey(trigger))
            {
                return MatrixData[currentState][trigger];
            }

            return null;
        }
        /// <summary>
        /// このステートマシンにトリガーを入力する
        /// </summary>
        /// <remarks>
        /// ステートマシンにトリガーを入力すると,
        /// このステートマシンが持っている状態遷移表に従って遷移が発生し,
        /// 現在の状態が遷移後の状態に更新される.
        /// トリガーに対する遷移が定義されていない場合は, 何もしない.
        /// </remarks>
        /// <param name="trigger">入力するトリガー</param>
        /// <exception cref="ArgumentNullException">引数<paramref name="trigger"/>がnull.</exception>
        /// <exception cref="InvalidOperationException">現在の状態が状態遷移表に存在しない.
        /// 状態遷移表の設定ミスなどによる.</exception>
        public void InputTrigger(Trigger trigger)
        {
            if (trigger == null)
            {
                throw new ArgumentNullException("trigger");
            }

            System.Diagnostics.Debug.Assert(CurrentState != null);

            ITransition transition;
            try
            {
                transition = TransitionMatrixData.SearchTransition(CurrentState, trigger);
            }
            catch (ArgumentOutOfRangeException e)
            {
                throw new InvalidOperationException("現在の状態は, 状態遷移表に登録されていません.", e);
            }

            if (transition != null)
            {
                CurrentState = transition.Execute();
            }
        }
 public void TestNullParameter(State setting_NextState, Transition.TransitionMethodDelegate setting_TransitionMethod)
 {
     // Execute, Validate
     Assert.Throws<NotImplementedException>(() => new Transition(setting_NextState, setting_TransitionMethod));
 }
            public RegularInstanceTest()
            {
                calledFlag = false;

                setting_NextState = new NormalState(new Trigger[1] { new Trigger() });
                setting_TransitionMethod = () => {
                    calledFlag = true;
                    return;
                };

                transition = new Transition(setting_NextState, setting_TransitionMethod);
            }
 public NoTransitionMethodInstanceTest()
 {
     setting_NextState = new NormalState(new Trigger[1] { new Trigger() });
     transition = new Transition(setting_NextState, null);
 }
            public void TestConstructor()
            {
                // Prepare datas
                Trigger[] all_triggers = new Trigger[5]
                {
                    new Trigger(),
                    new Trigger(),
                    new Trigger(),
                    new Trigger(),
                    new Trigger()
                };
                TriggerSet1 = new Trigger[3]
                {
                    all_triggers[0],
                    all_triggers[1],
                    all_triggers[2]
                };
                TriggerSet2 = new Trigger[3]
                {
                    all_triggers[0],
                    all_triggers[2],
                    all_triggers[4]
                };
                TriggerSet3 = new Trigger[3]
                {
                    all_triggers[2],
                    all_triggers[3],
                    all_triggers[4]
                };
                State[] states = new State[3]
                {
                    new NormalState(TriggerSet1),
                    new NormalState(TriggerSet2),
                    new NormalState(TriggerSet3)
                };
                var input_transitionMatrix = new Dictionary<State, Dictionary<Trigger, ITransition>>()
                {
                    {
                        states[0],
                        new Dictionary<Trigger, ITransition>()
                        {
                            { TriggerSet1[0], new Transition(states[2], null) },
                            { TriggerSet1[1], new Transition(states[2], null) },
                            { TriggerSet1[2], new Transition(states[1], null) }
                        }
                    },
                    {
                        states[1],
                        new Dictionary<Trigger, ITransition>()
                        {
                            { TriggerSet2[0], new Transition(states[0], null) },
                            { TriggerSet2[1], new Transition(states[1], null) },
                            { TriggerSet2[2], new Transition(states[2], null) }
                        }
                    },
                    {
                        states[2],
                        new Dictionary<Trigger, ITransition>()
                        {
                            { TriggerSet3[0], new Transition(states[2], null) },
                            { TriggerSet3[1], new Transition(states[2], null) },
                            { TriggerSet3[2], new Transition(states[0], null) }
                        }
                    }
                };
                var expected_MatrixData = new Dictionary<State, Dictionary<Trigger, ITransition>>(input_transitionMatrix);

                // Execute
                TransitionMatrix transition_matrix = new TransitionMatrix(input_transitionMatrix);

                // Get result
                FieldInfo field_info = transition_matrix.GetType().GetField("MatrixData",
                    BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
                var actual_MatrixData = (Dictionary<State, Dictionary<Trigger, ITransition>>)field_info.GetValue(transition_matrix);

                // Validate
                Assert.Same(input_transitionMatrix, actual_MatrixData);
                Assert.Equal(expected_MatrixData, actual_MatrixData);
            }