private void RemoveActiveBookmark(ActivityContext context) { StateMachineEventManager eventManager = this.EventManager.Get(context); Bookmark bookmark = _evaluateConditionBookmark.Get(context); if (bookmark != null) { eventManager.RemoveActiveBookmark(bookmark); } }
/// <summary> /// Execution of StateMachine /// </summary> /// <param name="context">NativeActivityContext reference</param> //[SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", //Justification = "The context is used by workflow runtime. The parameter should be fine.")] protected override void Execute(NativeActivityContext context) { // We view the duration before moving to initial state is on transition. StateMachineEventManager localEventManager = _eventManager.Get(context); localEventManager.OnTransition = true; localEventManager.CurrentBeingProcessedEvent = null; int index = StateMachineIdHelper.GetChildStateIndex(RootId, this.InitialState.StateId); context.ScheduleFunc <StateMachineEventManager, string>( _internalStateFuncs[index], localEventManager, _onStateComplete); }
private void TakeTransition(NativeActivityContext context, StateMachineEventManager eventManager, int triggerId) { this.EventManager.Get(context).OnTransition = true; InternalTransition transition = this.GetInternalTransition(triggerId); if (transition.IsUnconditional) { Fx.Assert(-1 == eventManager.CurrentConditionIndex, "CurrentConditionIndex should be -1, if the transition is unconditional."); this.PrepareForExit(context, this.GetTo(triggerId)); } else { Fx.Assert(-1 != eventManager.CurrentConditionIndex, "CurrentConditionIndex should not be -1, if the transition is conditional."); this.PrepareForExit(context, this.GetTo(triggerId, eventManager.CurrentConditionIndex)); } }
private void ScheduleAction(NativeActivityContext context) { StateMachineEventManager eventManager = this.EventManager.Get(context); if (eventManager.IsReferredByBeingProcessedEvent(_evaluateConditionBookmark.Get(context))) { InternalTransition transition = this.GetInternalTransition(eventManager.CurrentBeingProcessedEvent.TriggedId); Activity action = transition.TransitionDataList[-1 == eventManager.CurrentConditionIndex ? 0 : eventManager.CurrentConditionIndex].Action; if (action != null) { context.ScheduleActivity(action); } } this.RemoveBookmarks(context); }
private void StartEvaluateCondition(NativeActivityContext context, Bookmark bookmark, object value) { // Start to evaluate conditions of the trigger which represented by currentTriggerIndex StateMachineEventManager eventManager = this.EventManager.Get(context); int triggerId = eventManager.CurrentBeingProcessedEvent.TriggedId; InternalTransition transition = this.GetInternalTransition(triggerId); if (transition.IsUnconditional) { eventManager.CurrentConditionIndex = -1; this.TakeTransition(context, eventManager, triggerId); } else { eventManager.CurrentConditionIndex = 0; context.ScheduleActivity <bool>( this.GetCondition( triggerId, eventManager.CurrentConditionIndex), _onConditionComplete, null); } }
private static void ProcessNextTriggerCompletedEvent(NativeActivityContext context, StateMachineEventManager eventManager) { eventManager.CurrentBeingProcessedEvent = null; eventManager.OnTransition = false; TriggerCompletedEvent completedEvent = eventManager.GetNextCompletedEvent(); if (completedEvent != null) { StateMachineExtension extension = context.GetExtension <StateMachineExtension>(); Fx.Assert(extension != null, "Failed to obtain a StateMachineExtension."); extension.ResumeBookmark(completedEvent.Bookmark); } }
/// <summary> /// Used for Dynamic Update: after the instance is updated, if the statemachine is already transitioning, the index of the to-be-scheduled state /// would need to be updated. /// </summary> /// <param name="updateContext">Dynamic Update context</param> /// <param name="eventManager">Internal StateMachineEventManager</param> /// <returns>True, 1. if update is successful and the instanced is updated with the new indexes, and 2 all the trigger ID in the queue are updated; /// false otherwise and the update should fail.</returns> private bool UpdateEventManager( NativeActivityUpdateContext updateContext, StateMachineEventManager eventManager) { Fx.Assert(null != eventManager.CurrentBeingProcessedEvent, "The eventManager must have some info that needs to be updated during transition."); int updatedEventsInQueue = 0; int originalTriggerId = int.MinValue; int originalConditionIndex = int.MinValue; bool updateCurrentEventSucceed = null == eventManager.CurrentBeingProcessedEvent ? true : false; foreach (InternalTransition transition in this.internalTransitions) { object savedTriggerIndex = updateContext.GetSavedOriginalValue(transition.Trigger); if (savedTriggerIndex != null) { Fx.Assert(!updateContext.IsNewlyAdded(transition.Trigger), "the trigger in transition already exist."); if (null != eventManager.CurrentBeingProcessedEvent && eventManager.CurrentBeingProcessedEvent.TriggedId == (int)savedTriggerIndex) { // found a match of the running trigger update the current processed event // Don't match the trigger ID, match only when the Condition is also matched. if (eventManager.CurrentConditionIndex == -1) { if (transition.IsUnconditional) { // executing transition before persist is unconditional originalTriggerId = eventManager.CurrentBeingProcessedEvent.TriggedId; originalConditionIndex = 0; eventManager.CurrentBeingProcessedEvent.TriggedId = transition.InternalTransitionIndex; if (updateContext.GetValue(this.isExiting)) { Fx.Assert(eventManager.OnTransition, "The state is transitioning."); updateContext.SetValue(this.Result, GetTo(transition.InternalTransitionIndex)); } updateCurrentEventSucceed = true; } else { updateContext.DisallowUpdate(SR.ChangeTransitionTypeDuringTransitioningBlockDU); return(false); } } else if (eventManager.CurrentConditionIndex >= 0) { Fx.Assert(!transition.IsUnconditional, "Cannot update a running conditional transition with a unconditional one."); if (!transition.IsUnconditional) { // executing transition before and after are conditional for (int updatedIndex = 0; updatedIndex < transition.TransitionDataList.Count; updatedIndex++) { Activity condition = transition.TransitionDataList[updatedIndex].Condition; Fx.Assert(null != condition, "Conditional transition must have Condition activity."); int?savedCondIndex = updateContext.GetSavedOriginalValue(condition) as int?; if (eventManager.CurrentConditionIndex == savedCondIndex) { originalTriggerId = eventManager.CurrentBeingProcessedEvent.TriggedId; originalConditionIndex = eventManager.CurrentConditionIndex; eventManager.CurrentBeingProcessedEvent.TriggedId = transition.InternalTransitionIndex; eventManager.CurrentConditionIndex = updatedIndex; if (updateContext.GetValue(this.isExiting)) { Fx.Assert(eventManager.OnTransition, "The state is transitioning."); updateContext.SetValue(this.Result, this.GetTo(transition.InternalTransitionIndex, (int)updatedIndex)); } updateCurrentEventSucceed = true; break; } } } } } foreach (TriggerCompletedEvent completedEvent in eventManager.Queue) { if ((int)savedTriggerIndex == completedEvent.TriggedId) { completedEvent.TriggedId = transition.InternalTransitionIndex; updatedEventsInQueue++; } } } } return(eventManager.Queue.Count() == updatedEventsInQueue ? updateCurrentEventSucceed : false); }