private void AttachState(State state)
		{
			state.Entered += OnStateEntered;
			state.Exited += OnStateExited;
			foreach (State child in state.Substates)
				AttachState(child);
		}
		public TimeoutEvent(int timeoutInMilliseconds, State state, Action<State> eventPoster)
		{
			this.timeoutPeriod = timeoutInMilliseconds;
			this.eventPoster = eventPoster;
			this.state = state;
			this.state.Entered += OnStateEntered;
			this.state.Exited += OnStateExited;
		}
		/// <summary>
		/// By returning the current state of the fsm, we nullify this event because nobody responded.
		/// </summary>
		/// <param name="eventToProcess"></param>
		/// <returns></returns>
		public override State ProcessEvent(State originalState, EventInstance eventToProcess)
		{
			Transition transition = transitions.MatchTransition(eventToProcess);
			if (transition != null)
				return TraverseDown(new TransitionEvent(this, transition, eventToProcess));

			return originalState;
		}
		public static State GetSubstatePath(this State s, State targetState)
		{
			foreach (State substate in s.Substates)
			{
				if (substate.ContainsState(targetState))
					return substate;
			}

			return null;
		}
Beispiel #5
0
		public State(object id, State parent)
		{
			this.id = id;
			this.parent = parent;
			this.substates = new List<State>();
			this.transitions = new TransitionDirector();

			Entered += delegate { };
			Exited += delegate { };
			Traversing += delegate { };
		}
		private void OnStateEntered(object sender, EventArgs args)
		{
			if (finishState != null)
				return;

			StateWatcherAction watcher = sender as StateWatcherAction;
			finishState = watcher.State;

			Cancel();

			// Notify of the completion
			callback(finishState.Id);
		}
		public void Initialize(StateMachine sm)
		{
			stateMachine = sm;
			stateMachine.Starting += delegate
			                         	{
											Log("Starting state machine");
											if (root == null)
											{
												root = stateMachine.RootNode;
												root.VisitChildren(AttachToState);
											}
			                         	};
			stateMachine.EventPosted += (s, e) => Log("Event posted: {0}", e.Event.Event);
			stateMachine.EventProcessed += (s, e) => Log("Event processed: {0}", e.Event.Event);
		}
		public void ProcessNextEvent(State currentState)
		{
			// Processing should not be re-entrant, on the same thread or otherwise
			if (NotProcessing == Interlocked.CompareExchange(ref processingIndicator, Processing, NotProcessing))
			{
				EventInstance eventToProcess = events.Dequeue();
				if (eventToProcess != null)
					currentState = currentState.ProcessEvent(currentState, eventToProcess);

				processingIndicator = NotProcessing;

				if (currentState == null || currentState.Substates.Count() > 0)
					throw new InvalidOperationException("Current state [" + currentState + "] is a superstate or null.");

				EventProcessed(this, new StateEventPostedArgs(currentState, eventToProcess));
			}
		}
		public override State Build(State parent)
		{
			RootState root = new RootState();
			((StateBuilderContext)Context).SetRootState(root);

			foreach (IStateBuilder substate in SubStates)
			{
				root.AddChildState(substate.Build(root));
			}

			foreach (Action<State> action in secondPassActions)
			{
				action(root);
			}

			this.VisitChildren(sb => sb.Build(root));

			return root;
		}
		public CompositeStateWatcherAction(
			StateMachine stateMachine, 
			IEnumerable<object> states,
			Action<object> callback)
		{
			this.stateMachine = stateMachine;
			this.stateActions = new List<StateWatcherAction>();
			this.finishState = null;
			this.callback = callback;
			
			foreach (object stateId in states)
			{
				State state = stateMachine[stateId];
				StateWatcherAction action = new StateWatcherAction(state);
				action.Performed += OnStateEntered;

				stateActions.Add(action);
			}
		}
Beispiel #11
0
		public virtual State ProcessEvent(State originalState, EventInstance eventToProcess)
		{
			Transition transition = transitions.MatchTransition(eventToProcess);
			if (transition != null)
			{
				var transitionEvent = new TransitionEvent(originalState, transition, eventToProcess);

				// If originating from substate
				if (!this.Equals(originalState))
					return originalState.TraverseUp(transitionEvent);
				else
				{
					Exit(transitionEvent);
					return parent.TraverseUp(transitionEvent);
				}
			}

			// Not handled, pass it up the chain
			return parent.ProcessEvent(originalState, eventToProcess);
		}
		public virtual State Build(State parent)
		{
			// Build is called twice, first time around we build just the state
			if (state == null)
			{
				state = CreateState(Id, parent);

				foreach (IBaseStateBuilder substate in substates)
				{
					state.AddChildState(substate.Build(state));
				}
			}
			else
			{
				foreach (Action<State> action in secondPassActions)
				{
					action(state);
				}
			}

			return state;
		}
		public SingleStateEventInstance(State targetState, object eventTarget)
			: base(eventTarget)
		{
			this.targetState = targetState;
		}
Beispiel #14
0
		public void AddChildState(State substate)
		{
			substates.Add(substate);
		}
		public HistoryState(State parent, HistoryFetchStrategy historyStrategy)
			: base(new HistoryStateId(parent.Id), parent)
		{
			historyFetcher = historyStrategy;
			Parent.Exited += OnParentExit;
		}
		public Transition(State sourceState, object eventTarget, State targetState)
		{
			this.sourceState = sourceState;
			this.eventTarget = eventTarget;
			this.targetState = targetState;
		}
		public State Build(State parent)
		{
			throw new InvalidOperationException("Not valid to Build from this context");
		}
		public void PostTimeout(State state, object transitionEvent)
		{
			stateMachine.PostEvent(new SingleStateEventInstance(state, transitionEvent));
		}
		public StateEventPostedArgs(State state, EventInstance eventPosted)
			: base(state)
		{
			Event = eventPosted;
		}
		public StateWatcherAction(State state)
		{
			State = state;
			enterAction = new EnterAction(State, Perform);
		}
		private void AttachToState(State state)
		{
			state.Entered += delegate { Log("Entered {0}", state); };
			state.Exited += delegate { Log("Exited {0}", state); };
		}
		public EnterAction(State state, Action<TransitionReceipt> action)
		{
			this.state = state;
			this.state.Entered += OnStateEntered;
			this.Action = action;
		}
		public ExitAction(State state, Action<TransitionReceipt> action)
		{
			this.state = state;
			this.state.Exited += OnStateExited;
			this.Action = action;
		}
		public virtual State CreateState(object stateId, State parent)
		{
			if (parent == null)
				throw new InvalidOperationException("Parent may not be null for state: " + stateId);
			return new State(stateId, parent);
		}
		public void PostTimeout(State state)
		{
			stateMachine.PostEvent(new SingleStateEventInstance(state, TimerBuilder.TimeoutEvent));
		}
		public GuardedTransition(State sourceState, object eventTarget, State targetState, Func<bool> guard)
			: base(sourceState, eventTarget, targetState)
		{
			this.guard = guard;
		}
		public State Build(State parent)
		{
			HistoryState state = new HistoryState(parent, historyStrategy);

			return state;
		}
		public StateEventArgs(State state)
		{
			State = state;
		}
		public TransitionEvent(State sourceState, Transition transition, EventInstance eventInstance)
		{
			this.sourceState = sourceState;
			this.transition = transition;
			this.eventInstance = eventInstance;
		}
		protected virtual void OnParentExit(object sender, StateTransitionEventArgs args)
		{
			lastState = historyFetcher(this, args.TransitionEvent);
		}