예제 #1
0
        /// <summary>
        /// Convert the builder into an immutable state machinee.
        /// </summary>
        /// <returns>Immutable state machine.</returns>
        /// <exception cref="InvalidOperationException">Thrown when there is no registered initial state.<br/>
        /// Or when there are no registered states.<br/>
        /// Or when a transition refers to a non-registered state.</exception>
        public StateMachine <TState, TEvent, TParameter> Build()
        {
            if (!hasInitialState)
            {
                throw new InvalidOperationException("The state machine builder doesn't have registered an initial state.");
            }

            if (this.states.Count == 0)
            {
                throw new InvalidOperationException("The state machine builder doesn't have registered any state.");
            }

            Dictionary <TState, int> statesMap = new Dictionary <TState, int>();
            int i = 0;

            foreach (KeyValuePair <TState, StateBuilder <TState, TEvent, TParameter> > kv in this.states)
            {
                statesMap.Add(kv.Key, i++);
            }

            List <State <TState, TEvent> >          states      = new List <State <TState, TEvent> >();
            ListSlot <Transition <TState, TEvent> > transitions = new ListSlot <Transition <TState, TEvent> >(new List <Transition <TState, TEvent> >());

            // TODO: Use deconstruction pattern when upload to .Net Standard 2.1
            foreach (KeyValuePair <TState, StateBuilder <TState, TEvent, TParameter> > kv in this.states)
            {
                states.Add(kv.Value.ToState(kv.Key, transitions, statesMap));
            }

            return(new StateMachine <TState, TEvent, TParameter>(initialState.TryGetStateIndex(statesMap), states, transitions.Extract()));
        }
예제 #2
0
        internal State <TState, TEvent> ToState(TState state, ListSlot <Transition <TState, TEvent> > transitions, Dictionary <TState, int> statesMap)
        {
            Dictionary <TEvent, int> trans = new Dictionary <TEvent, int>();

            // TODO: Use deconstruction pattern when upload to .Net Standard 2.1
            foreach (KeyValuePair <TEvent, TransitionBuilder <TState, TEvent, TParameter> > kv in this.transitions)
            {
                int slot = transitions.Reserve();
                trans.Add(kv.Key, slot);
                if (kv.Value is null)
                {
                    transitions.Store(new Transition <TState, TEvent>(-1, null, (0, 0)), slot);
                }
                else
                {
                    transitions.Store(kv.Value.ToTransition(transitions, statesMap, State), slot);
                }
            }

            return(new State <TState, TEvent>(
                       state,
                       Helper.Combine(ref onEntry, ref onEntryWithParameter),
                       Helper.Combine(ref onExit, ref onExitWithParameter),
                       Helper.Combine(ref onUpdate, ref onUpdateWithParameter),
                       trans
                       ));
        }
예제 #3
0
        internal override Transition <TState, TEvent> ToTransition(ListSlot <Transition <TState, TEvent> > transitions, Dictionary <TState, int> statesMap, TState currentState)
        {
            if (slaves == null)
            {
                return(new Transition <TState, TEvent>(GetGoto(statesMap, currentState), GetDo(), (0, 0), guard));
            }
            (int from, int to)range = transitions.Reserve(slaves.Count);

            int i = range.from;

            foreach (SlaveTransitionBuilder <TState, TEvent, TParameter, SlaveTransitionBuilder <TState, TEvent, TParameter, TParent> > slave in slaves)
            {
                transitions.Store(slave.ToTransition(transitions, statesMap, currentState), i);
                i++;
            }
            Debug.Assert(i == range.to);

            return(new Transition <TState, TEvent>(GetGoto(statesMap, currentState), GetDo(), range, guard));
        }
예제 #4
0
 internal abstract Transition <TState, TEvent> ToTransition(ListSlot <Transition <TState, TEvent> > transitions, Dictionary <TState, int> statesMap, TState currentState);