protected virtual void PreRun() { try { if (!_isAlreadyPreRun) { if (stateMachine == null) { stateMachine = StateMachine; } _timeoutHandle.Reset(); waitHandle = stateMachine.WaitHandle; decisionWaitHandle = stateMachine.DecisionWaitHandle; decisionLoopList = stateMachine.DecisionLoopList; pathOut = null; flowItemForPathOut = null; _decisionTimeout = -1; ExitFlowItem(); FindStart(); EnterFlowItem(); _isAlreadyPreRun = true; } } catch { _isAlreadyPreRun = false; } }
/// <summary> /// Clone this component /// </summary> /// <param name="name"></param> /// <param name="bRecursivley"></param> /// <returns></returns> public override CompBase Clone(string name, bool bRecursivley) { SMFlowBase newComp = base.Clone(name, bRecursivley) as SMFlowBase; _shallowCopyTo(newComp); return(newComp); }
/// <summary> /// Get the flow item for the target in the specified pathOut /// </summary> /// <param name="pathOut"></param> /// <returns></returns> public SMFlowBase GetFlowTarget(SMPathOut pathOut) { if (pathOut.HasTargetID) { SMFlowBase[] list = null; if (!pathOut.TargetID.Contains(".")) { //list = FilterByType<SMFlowBase>(); list = pathOut.Owner.Parent.FilterByType <SMFlowBase>(); } //Sport Transition else { SMFlowBase smPathOut = U.GetComponent(pathOut.TargetID) as SMFlowBase; return(smPathOut); } if (list.Length > 0) { try { return(list.First(c => c.Name == pathOut.TargetID)); } catch { pathOut.DeletedTarget(); } } } return(null); }
private void FindStart() { _currentFlowItem = ChildArray.ToList().Find(c => c is SMStart) as SMFlowBase; if (_currentFlowItem == null) { throw new Exception("Unable to find the Start Flow chart element"); } }
/// <summary> /// Find the target at the specified endpoint /// </summary> /// <param name="searcher"></param> /// <param name="endGridPt"></param> /// <returns></returns> public SMFlowBase FindTarget(SMFlowBase searcher, PointF endGridPt) { foreach (SMFlowBase flowItem in ChildArray) { if (!object.ReferenceEquals(searcher, flowItem) && flowItem.Contains(endGridPt)) { return(flowItem); } } return(null); }
private bool FindStop() { SMFlowBase exitFlowItem = ChildArray.ToList().Find(c => c is SMReturnStop) as SMFlowBase; if (exitFlowItem != null) { _currentFlowItem = exitFlowItem; return(true); } return(false); }
private void _shallowCopyTo(CompBase compTo) { SMFlowBase flowTo = compTo as SMFlowBase; flowTo.Text = Text; flowTo.GridLoc = GridLoc; for (int i = 0; i < 4; i++) { flowTo._pathList[i] = _pathList[i].Clone() as SMPathOut; } }
/// <summary> /// Evaluate specific path for target /// </summary> /// <param name="pathOut"></param> public void DetermineTarget(SMPathOut pathOut) { if (!(pathOut is SMPathOutPlug)) { // Allow us to loop back to self only if there is more than one segment SMFlowBase searcher = pathOut.Next != null ? this : null; SMFlowBase flowItem = ParentContainer.FindTarget(searcher, FindEndPoint(pathOut)); if (flowItem != null) { pathOut.TargetID = flowItem.Name; } else { pathOut.TargetID = string.Empty; } } }
/// <summary> /// Run method for the main state machine thread /// </summary> /// <returns></returns> public override SMPathOut Run() { //SMStateMachine stateMachine = StateMachine; try { //_timeoutHandle.Reset(); //ManualResetEvent waitHandle = stateMachine.WaitHandle; //ManualResetEvent decisionWaitHandle = stateMachine.DecisionWaitHandle; //List<SMDecision> decisionLoopList = stateMachine.DecisionLoopList; //SMPathOut pathOut = null; //SMFlowBase flowItemForPathOut = null; //_decisionTimeout = -1; //ExitFlowItem(); //FindStart(); //// Hightlight start //EnterFlowItem(); PreRun(); while (true) { Thread.Sleep(0); // If Reset will block thread (Pause) until Step or Run (Set) if (stateMachine.Mode == SMStateMachine.eMode.Pause) { waitHandle.Reset(); // Wait until(Pause) until Step or Run (Set) EnterFlowItem(); waitHandle.WaitOne(); ExitFlowItem(); } if (_currentFlowItem is SMDecision) { SMDecision decisionItem = _currentFlowItem as SMDecision; if (decisionLoopList.Contains(decisionItem)) { // We have closed the loop of nothing but decision items EnterFlowItem(); //stateMachine.EnterPathItem(flowItemForPathOut, flowItemForPathOut.OutgoingPath); // Modify by Kasem 12-Feb-2018 if (decisionItem.WaitTimeoutMS <= 0) { decisionWaitHandle.WaitOne(_decisionTimeout); } else { Boolean signal = false; signal = decisionWaitHandle.WaitOne(decisionItem.WaitTimeoutMS); //Trigger Timeout if (!signal) { _timeoutHandle.Set(); } } //-------------------------------- _decisionTimeout = -1; //stateMachine.ExitPathItem(flowItemForPathOut, flowItemForPathOut.OutgoingPath); ExitFlowItem(); stateMachine.ClearDecisionList(); } else { if (decisionLoopList.Count == 0) { // First one. Reset early in case something changes quickly decisionWaitHandle.Reset(); } decisionItem.AddNotifier(StateMachine.OnDecisionChanged); stateMachine.AddToDecisionList(decisionItem, flowItemForPathOut, pathOut); } } else { stateMachine.ClearDecisionList(); } // // Run this item // //Dump Process Usage Timing if (CompMachine.s_machine.ProcessUsageTrigger) { if (!(_currentFlowItem is SMFlowContainer)) { StateMachine.AddTimingElement(">Run: " + _currentFlowItem.Text); } else { StateMachine.AddTimingElement(">Enter: " + _currentFlowItem.Text); } } EnterFlowItem(); pathOut = _currentFlowItem.Run(); ExitFlowItem(); //Dump Process Usage Timing if (CompMachine.s_machine.ProcessUsageTrigger) { if (!(_currentFlowItem is SMFlowContainer)) { StateMachine.AddTimingElement("<Run: " + _currentFlowItem.Text); } else { StateMachine.AddTimingElement("<Exit: " + _currentFlowItem.Text); } } //Add by Kasem 12-Feb-2018 if (_currentFlowItem is SMDecision) { //Determine Start to Capture Timeout SMDecision decisionItem = _currentFlowItem as SMDecision; //No Partout Meaning Waiting Condition if (pathOut != null && !pathOut.HasTargetID && decisionItem.WaitTimeoutMS > 0) { //Start Stop watch if Nested Condition if (!_stopWatch.IsRunning && _currentFlowItem.HasChildren) { _stopWatch.Restart(); } else if (_stopWatch.IsRunning && !_currentFlowItem.HasChildren) { _stopWatch.Stop(); } else { if ((_currentFlowItem.HasChildren) && (_stopWatch.ElapsedMilliseconds > decisionItem.WaitTimeoutMS) || (!_currentFlowItem.HasChildren) && _timeoutHandle.WaitOne(0)) { //Check Stop Path and Flow to Timeout Flag SMPathOut stopPath = _currentFlowItem[typeof(SMPathOutStop)]; //Popup in case no path for Timeout if (!decisionItem.FlowTimeoutToStopPath || stopPath == null || !stopPath.HasTargetID) { U.LogWarning("Decision Wait Time Out [{0}] on state [{1}]", decisionItem.PathText, this.StateMachine); string msg = String.Format("Decision Wait Time Out [{0}] on state [{1}]", decisionItem.PathText, this.StateMachine); _stopWatch.Stop(); _timeoutHandle.Reset(); DisplayAsynchMsg(msg); _timeoutHandle.WaitOne(); _timeoutHandle.Reset(); } //Case Timeout path available else { _stopWatch.Stop(); _timeoutHandle.Reset(); pathOut = stopPath; } } } } //Force pathout to null incase of pathout is stop path but we use FlowTimeoutToStopPath option else if (pathOut is SMPathOutStop && decisionItem.FlowTimeoutToStopPath) { pathOut = null; _stopWatch.Stop(); } //Stop capture time in case decision meet wait condition else { _stopWatch.Stop(); } } //Modify by Kasem 13-Feb-2018 if (stateMachine.ReceivedStop) { if (!(_currentFlowItem is SMDecision) && !(_currentFlowItem is SMTransition) && !(_currentFlowItem is SMActTransFlow)) { stateMachine.ReceivedStop = false; // Redirect the path to the PathOutStop pathOut = _currentFlowItem[typeof(SMPathOutStop)]; } else { stateMachine.ReceivedStop = false; _stopWatch.Stop(); if (_currentFlowItem is SMDecision) { if (!(_currentFlowItem as SMDecision).FlowTimeoutToStopPath) { pathOut = _currentFlowItem[typeof(SMPathOutStop)]; } else { pathOut = null; } } else if (_currentFlowItem is SMTransition) { if (!(_currentFlowItem as SMTransition).FlowTimeoutToStopPath) { pathOut = _currentFlowItem[typeof(SMPathOutStop)]; } else { pathOut = null; } } else if (_currentFlowItem is SMActTransFlow) { if (!(_currentFlowItem as SMActTransFlow).FlowTimeoutToStopPath) { pathOut = _currentFlowItem[typeof(SMPathOutStop)]; } else { pathOut = null; } } } } //-------------------------------- if (pathOut == null) { // Will stop the whole State Machine return(null); } SMPathOutError pathOutError = pathOut as SMPathOutError; if (pathOutError != null) { pathOutError.ProcessErrors(); } if (pathOut.HasTargetID) { flowItemForPathOut = _currentFlowItem; // We are on the target path. _currentFlowItem = GetFlowTarget(pathOut); _currentFlowItem.IncomingPath = pathOut; } else if ((_currentFlowItem is SMDecision) && !(pathOut is SMPathOutStop) && !(pathOut is SMPathOutError)) { // Keep same current flow item. Let it loop to itself } else { // No target to go to // Will stop the whole State Machine if ((pathOut is SMPathOutStop) || (pathOut is SMPathOutError)) { if (!FindStop()) { FindStart(); } EnterFlowItem(); } _currentFlowItem.IncomingPath = null; return(null); } if (_currentFlowItem == null) { throw new Exception(string.Format("Could not locate Flowitem from ID '{0}' in StateMachine '{1}'. State Machine has paused.", pathOut.TargetID, Text)); } if (_currentFlowItem is SMExit) { EnterFlowItem(); if (this is SMDecision) { foreach (SMPathOut path in PathArray) { if (_currentFlowItem is SMReturnNo) { if (path is SMPathOutBool && !(path as SMPathOutBool).True) { return(path); } } else if (_currentFlowItem is SMReturnYes) { if (path is SMPathOutBool && (path as SMPathOutBool).True) { return(path); } } else if (_currentFlowItem is SMReturnStop) { if (path is SMPathOutStop) { return(path); } } } } if (this is SMSubroutine && _currentFlowItem is SMReturnStop) { return(this[typeof(SMPathOutStop)]); } return(this[typeof(SMPathOut)]); } }//End While True; } finally { stateMachine.ClearDecisionList(); _isAlreadyPreRun = false; System.Threading.Tasks.Task.Run(() => PreRun()); } }
/// <summary> /// Add Flow Item /// </summary> /// <param name="flowItemAdded"></param> public void AddFlowItem(SMFlowBase flowItemAdded) { Add(flowItemAdded); flowItemAdded.Initialize(); }