public void Start(PfcExecutionContext parentPfcec) { Debug.Assert(!parentPfcec.IsStepCentric); // Must be called with parent. Debug.Assert(parentPfcec.PFC.Equals(MyStep.Parent)); #region Create a context under the parent PFCEC to run this iteration of this step. SsmData ssmData = GetSsmData(parentPfcec); // This will create a new SSMData element. if (ssmData.ExecutionInstanceCount == 0) { ssmData.InitializeExecutionInstanceUid(parentPfcec.Guid, MyStep.Guid); } Guid myExecutionInstanceGuid = ssmData.GetNextExecutionInstanceUid(); PfcExecutionContext myPfcec = new PfcExecutionContext(m_myStep, m_myStep.Name, null, myExecutionInstanceGuid, parentPfcec); myPfcec.InstanceCount = ssmData.ExecutionInstanceCount - 1; ssmData.ActiveStepInstanceEc = myPfcec; if (s_diagnostics) { Console.WriteLine("PFCEC " + myPfcec.Name + "(instance " + myPfcec.InstanceCount + ") created."); } #endregion if (s_diagnostics) { Console.WriteLine("Starting step " + m_myStep.Name + " with ec " + myPfcec.Name + "."); } GetStartPermission(myPfcec); // Once we have permission to start (based on state), we will create a new execContext for this execution. DoTransition(StepState.Running, myPfcec); }
private void DoTransition(StepState toState, PfcExecutionContext myPfcec) { SsmData ssmData = GetSsmData(myPfcec); StepState fromState = ssmData.State; if (s_transition_Matrix[(int)fromState, (int)toState]) { ssmData.State = toState; bool timePeriodContainer = myPfcec.TimePeriod is Scheduling.TimePeriodEnvelope; if (!timePeriodContainer) { if (fromState == StepState.Running && toState == StepState.Complete) { myPfcec.TimePeriod.EndTime = myPfcec.Model.Executive.Now; } } // Get permission from Step to run. if (fromState == StepState.Idle && toState == StepState.Running) { m_myStep.GetPermissionToStart(myPfcec, this); } //Console.WriteLine("{2} from {0} to {1}", fromState, toState, this.Name); if (!timePeriodContainer) { if (fromState == StepState.Idle && toState == StepState.Running) { myPfcec.TimePeriod.StartTime = myPfcec.Model.Executive.Now; } } if (fromState == StepState.Complete && toState == StepState.Idle) { ssmData.ActiveStepInstanceEc = null; } StateChangeCompleted(myPfcec); if (fromState == StepState.Idle && toState == StepState.Running) { DoRunning(myPfcec); } StepState followOnState = s_follow_On_States[(int)toState]; if (followOnState != toState) { DoTransition(followOnState, myPfcec); } } else { string msg = string.Format("Illegal attempt to transition from {0} to {1} in step state machine for {2}.", fromState, toState, Name); throw new ApplicationException(msg); } }
private void StateChangeCompleted(PfcExecutionContext pfcec) { if (StepStateChanged != null) { StepStateChanged(this, pfcec); } SuccessorStateMachines.ForEach(delegate(TransitionStateMachine tsm) { tsm.PredecessorStateChange(pfcec); }); SsmData ssmData = GetSsmData(pfcec); if ((ssmData.State == StepState.Idle) && (ssmData.QueueIdec.Count > 0)) { ssmData.QueueIdec.Dequeue().Resume(); } }
private SsmData GetSsmData(PfcExecutionContext pfcec) { if (MyStep.Equals(pfcec.Step)) { pfcec = (PfcExecutionContext)pfcec.Parent; } if (!pfcec.Contains(this)) { SsmData retval = new SsmData(); pfcec.Add(this, retval); } return((SsmData)pfcec[this]); }
private void DoRunning(PfcExecutionContext pfcec) { if (s_diagnostics) { string msg = "Starting to run {0} action{1} under step {2} with ec {3}."; string nKids = "1"; string plural = ""; string stepName = m_myStep.Name; string ecName = pfcec.Name; int nActions = (m_myStep.Actions?.Count ?? 0) + m_myStep.LeafLevelAction.GetInvocationList().Length; nKids = nActions.ToString(); plural = nActions == 1 ? "" : "s"; if (nActions == 0) { msg = "There are no actions to run under step {2} with ec {3}."; } Console.WriteLine(msg, nKids, plural, stepName, ecName); } IModel model = m_myStep.Model; SsmData ssmData = GetSsmData(pfcec); Debug.Assert(model.Executive.CurrentEventType == ExecEventType.Detachable); if (model != null && model.Executive != null) { if (m_myStep.Actions != null && m_myStep.Actions.Count > 0) { IProcedureFunctionChart[] kids; PfcExecutionContext[] kidContexts; CreateChildContexts(ssmData.ActiveStepInstanceEc, out kids, out kidContexts); foreach (IProcedureFunctionChart action in m_myStep.Actions.Values) { for (int i = 0; i < kidContexts.Length; i++) { model.Executive.RequestEvent(new ExecEventReceiver(kids[i].Run), model.Executive.Now, 0.0, kidContexts[i], ExecEventType.Detachable); } } new PfcStepJoiner(ssmData.ActiveStepInstanceEc, kids).RunAndWait(); } else { //PfcExecutionContext iterPfc = CreateIterationContext(pfcec); m_myStep.LeafLevelAction(pfcec, this); } } DoTransition(StepState.Complete, pfcec); }
internal void GetStartPermission(PfcExecutionContext pfcec) { IDetachableEventController currentEventController = m_myStep.Model.Executive.CurrentEventController; SsmData ssmData = GetSsmData(pfcec); if (!ssmData.State.Equals(StepState.Idle)) { ssmData.QueueIdec.Enqueue(currentEventController); if (s_diagnostics) { Console.WriteLine(m_myStep.Model.Executive.Now + " : suspending awaiting start of " + m_myStep.Name + " ..."); } currentEventController.Suspend(); if (s_diagnostics) { Console.WriteLine(m_myStep.Model.Executive.Now + " : resuming the starting of " + m_myStep.Name + " ..."); } } }
/// <summary> /// Gets a value indicating whether this step state machine is in a quiescent state - Held or Paused. /// </summary> /// <value> /// <c>true</c> if this instance is in quiescent state; otherwise, <c>false</c>. /// </value> public bool IsInQuiescentState(PfcExecutionContext pfcec) { SsmData ssmData = GetSsmData(pfcec); return(ssmData.State == StepState.Held || ssmData.State == StepState.Paused); }
/// <summary> /// Gets a value indicating whether this step state machine is in a final state - Aborted, Stopped or Complete. /// </summary> /// <value> /// <c>true</c> if this instance is in final state; otherwise, <c>false</c>. /// </value> public bool IsInFinalState(PfcExecutionContext pfcec) { SsmData ssmData = GetSsmData(pfcec); return(ssmData.State == StepState.Complete || ssmData.State == StepState.Aborted || ssmData.State == StepState.Stopped); }
/// <summary> /// Gets the state of this step. /// </summary> /// <value>The state.</value> public StepState GetState(PfcExecutionContext parentPfcec) { SsmData ssmData = GetSsmData(parentPfcec); return(ssmData.State); }