/// <summary> /// Clone this component /// </summary> /// <param name="name"></param> /// <param name="bRecursivley"></param> /// <returns></returns> public override CompBase Clone(string name, bool bRecursivley) { SMDecision newComp = base.Clone(name, bRecursivley) as SMDecision; newComp._ignoreIDChange = true; newComp.ConditionID = ConditionID; newComp._ignoreIDChange = false; return(newComp); }
/// <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()); } }