public override void Rebuild()
        {
            lock (this)
            {
                _isValid = false;
                try
                {
                    _transitionPath.TargetID = TransitionTargetID;
                    _transitionPath.Initialize(this, true);

                    //if(!this.HasChildren)
                    //{
                    //    return;
                    //}

                    if (TransitionTargetID == "")
                    {
                        HasProblem = true;
                        return;
                    }

                    if (this.HasChildren)
                    {
                        foreach (CompBase comp in this.ChildArray)
                        {
                            if (comp is SMSubCondBase)
                            {
                                (comp as SMSubCondBase).Rebuild();
                            }
                        }
                    }
                    _isValid = true;
                }
                catch (Exception ex)
                {
                    HasProblem = true;
                    U.LogPopup(ex, String.Format("Stae Machine '{0}' Unable to create Transition", this.StateMachine.Name));
                }

                if (waitHandle == null)
                {
                    waitHandle = new ManualResetEvent(false);
                }
                else
                {
                    waitHandle.Reset();
                }
            }
        }
        public override SMPathOut Run()
        {
            lock (this)
            {
                if (HasChildren)
                {
                    do
                    {
                        var waitDelay = Task.Delay(10);

                        if (TransTimeOut > 0 && !_stopWatch.IsRunning)
                        {
                            _stopWatch.Restart();
                        }

                        try
                        {
                            if (this.HasChildren)
                            {
                                ValidationResult = (this.ChildArray[0] as SMSubCondBase).Validate();
                            }

                            //For dry run
                            if (CompMachine.s_machine.IsDryRun && this.UseDryRunTrans && this.DryRunTransitionTargetID != "")
                            {
                                ValidationResult     = true;
                                _dryRunPath.TargetID = this.DryRunTransitionTargetID;
                                _dryRunPath.Initialize(this, true);
                                return(_dryRunPath);
                            }


                            if (ValidationResult && _transitionPath.TargetID != "")
                            {
                                return(_transitionPath);
                            }
                        }
                        catch (Exception ex)
                        {
                            _stopWatch.Stop();
                            _timeoutHandle.Reset();

                            // We found at least one exception.  Store it with the SMPathOutError
                            SMPathOutError pathError = this[typeof(SMPathOutError)] as SMPathOutError;
                            if (pathError != null)
                            {
                                pathError.Exceptions.Add(ex);
                                return(pathError);
                            }
                        }

                        //Validate Timeout
                        if (TransTimeOut > 0 && !ValidationResult && (_stopWatch.ElapsedMilliseconds > TransTimeOut))
                        {
                            SMPathOut stopPath = this[typeof(SMPathOutStop)];

                            //Display message in case no path error connected
                            if (stopPath == null || !stopPath.HasTargetID || !FlowTimeoutToStopPath)
                            {
                                string caption = TimeOutCaption;
                                if (caption == "")
                                {
                                    caption = "Transition TimeOut";
                                }
                                string msg = TimeOutMessage;
                                if (msg == "")
                                {
                                    msg = String.Format("Transition TimeOut [{0}] on state [{1}]", this.PathText, this.StateMachine);
                                }

                                _stopWatch.Stop();
                                _timeoutHandle.Reset();

                                DisplayAsynchMsg(msg, caption);

                                _timeoutHandle.WaitOne();
                                _timeoutHandle.Reset();
                            }
                            else
                            {
                                _stopWatch.Stop();
                                _timeoutHandle.Reset();
                                return(this[typeof(SMPathOutStop)]);
                            }
                        }
                        waitDelay.Wait();
                    } while (!ValidationResult && LoopTransition && !StateMachine.ReceivedStop);

                    _stopWatch.Stop();
                    _timeoutHandle.Reset();
                }
                //Always true if no any condition in child array
                else
                {
                    ValidationResult = true;
                    if (ValidationResult && _transitionPath.TargetID != "")
                    {
                        return(_transitionPath);
                    }
                }
            }

            // Only one out
            return(this[typeof(SMPathOut)]);
        }
        /// <summary>
        /// Returns the path to take from here
        /// </summary>
        /// <returns></returns>
        public override SMPathOut Run()
        {
            lock (this)
            {
                if (HasChildren || HasTransition)
                {
                    if (NeedsRebuild)
                    {
                        //Rebuild();
                    }

                    if (HasMethod)
                    {
                        //For dry run
                        if (CompMachine.s_machine.IsDryRun && this.DryRunSkipActions)
                        {
                            // Do no action
                        }
                        else
                        {
                            //Run All Method
                            //validMethods.ForEach(c => c.RunAsync());
                            Parallel.ForEach(validMethods, method => method.RunAsync());

                            //// Wait until they all complete
                            WaitHandle.WaitAll(waitHandles);
                        }
                    }



                    // Look for any exceptions made by the methods
                    List <Exception> exceptions = new List <Exception>();
                    foreach (SMMethod method in validMethods)
                    {
                        if (method.methodResults.Exception != null)
                        {
                            exceptions.Add(method.methodResults.Exception);
                        }
                    }

                    //Parallel.ForEach(validMethods, method =>
                    //{
                    //    if (method.methodResults.Exception != null)
                    //    {
                    //        exceptions.Add(method.methodResults.Exception);
                    //    }
                    //});


                    if (exceptions.Count > 0)
                    {
                        // We found at least one exception.  Store it with the SMPathOutError
                        SMPathOutError pathError = this[typeof(SMPathOutError)] as SMPathOutError;
                        if (pathError != null)
                        {
                            pathError.Exceptions = exceptions;
                            return(pathError);
                        }
                    }


                    if (HasTransition)
                    {
                        bool anyTransPassValidate = false;
                        do
                        {
                            var waitDelay = Task.Delay(10);
                            if (TransTimeOut > 0 && !_stopWatch.IsRunning)
                            {
                                _stopWatch.Restart();
                            }
                            //Run All Transition
                            validTransitions.ForEach(c => c.RunAsync());
                            //Parallel.ForEach(validTransitions, transition => transition.RunAsync());

                            //Wait until all transition run complete
                            WaitHandle.WaitAll(waitHandlesTransitions, 1000);

                            foreach (SMTransition transition in validTransitions)
                            {
                                anyTransPassValidate = anyTransPassValidate || transition.ValidationResult;
                                if (transition.TransitionResults.Exception != null)
                                {
                                    exceptions.Add(transition.TransitionResults.Exception);
                                }
                            }

                            //Parallel.ForEach(validTransitions, transition =>
                            //{
                            //    anyTransPassValidate = anyTransPassValidate || transition.ValidationResult;
                            //    if (transition.TransitionResults.Exception != null)
                            //    {
                            //        exceptions.Add(transition.TransitionResults.Exception);
                            //    }
                            //});



                            //For dry run
                            if (CompMachine.s_machine.IsDryRun && this.UseDryRunTrans && this.DryRunTransitionTargetID != "")
                            {
                                anyTransPassValidate = true;
                            }


                            if (exceptions.Count > 0)
                            {
                                // We found at least one exception.  Store it with the SMPathOutError
                                SMPathOutError pathError = this[typeof(SMPathOutError)] as SMPathOutError;
                                if (pathError != null)
                                {
                                    pathError.Exceptions = exceptions;
                                    return(pathError);
                                }
                            }


                            //Validate Timeout
                            if (TransTimeOut > 0 && !anyTransPassValidate && (_stopWatch.ElapsedMilliseconds > TransTimeOut))
                            {
                                SMPathOut stopPath = this[typeof(SMPathOutStop)];

                                //Display message in case no path error connected
                                if (stopPath == null || !stopPath.HasTargetID || !FlowTimeoutToStopPath)
                                {
                                    string caption = TimeOutCaption;
                                    if (caption == "")
                                    {
                                        caption = "Transition TimeOut";
                                    }
                                    string msg = TimeOutMessage;
                                    if (msg == "")
                                    {
                                        msg = String.Format("Transition TimeOut [{0}] on state [{1}]", this.PathText, this.StateMachine);
                                    }

                                    _stopWatch.Stop();
                                    _timeoutHandle.Reset();

                                    DisplayAsynchMsg(msg, caption);

                                    _timeoutHandle.WaitOne();
                                    _timeoutHandle.Reset();
                                }
                                else
                                {
                                    _stopWatch.Stop();
                                    _timeoutHandle.Reset();
                                    return(this[typeof(SMPathOutStop)]);
                                }
                            }
                            waitDelay.Wait();
                        }while (!anyTransPassValidate && LoopTransitions && !StateMachine.ReceivedStop);
                    }

                    _stopWatch.Stop();
                    _timeoutHandle.Reset();
                }

                if (!StateMachine.ReceivedStop)
                {
                    //For dry run
                    if (CompMachine.s_machine.IsDryRun && this.UseDryRunTrans && this.DryRunTransitionTargetID != "")
                    {
                        _dryRunPath.TargetID = this.DryRunTransitionTargetID;
                        _dryRunPath.Initialize(this, true);
                        return(_dryRunPath);
                    }

                    //Check First OK Transition Path Out
                    foreach (SMTransition transition in validTransitions)
                    {
                        if (transition.ValidationResult && transition.TransitionPath.TargetID != "")
                        {
                            return(transition.TransitionPath);
                        }
                    }
                }
            }

            // Only one out
            return(this[typeof(SMPathOut)]);
        }
Пример #4
0
        public void ChangeExit(SMPathOut pathOut, int x, int y)
        {
            int  directionVal = 0;
            eDir dirThis      = this[pathOut];

            switch (dirThis)
            {
            case eDir.Num:
                return;

            case eDir.Up:
                directionVal = Math.Sign(x);
                break;

            case eDir.Down:
                directionVal = -Math.Sign(x);
                break;

            case eDir.Right:
                directionVal = Math.Sign(y);
                break;

            case eDir.Left:
                directionVal = -Math.Sign(y);
                break;
            }
            if (directionVal == 0)
            {
                return;
            }
            // Loop to find next or previous empty spot
            eDir dirSwap = dirThis;

            do
            {
                if (directionVal > 0)
                {
                    dirSwap++;
                    if (dirSwap == eDir.Num)
                    {
                        dirSwap = eDir.Up;
                    }
                }
                else
                {
                    if (dirSwap == eDir.Up)
                    {
                        dirSwap = eDir.Left;
                    }
                    else
                    {
                        dirSwap--;
                    }
                }
                if (this[dirSwap] is SMPathOutPlug)
                {
                    // Got it
                    this[dirThis] = this[dirSwap];
                    this[dirSwap] = pathOut;
                    switch (dirSwap)
                    {
                    case eDir.Up:
                        pathOut.GridDistance = -Math.Abs(pathOut.GridDistance);
                        break;

                    case eDir.Down:
                        pathOut.GridDistance = Math.Abs(pathOut.GridDistance);
                        break;

                    case eDir.Right:
                        pathOut.GridDistance = Math.Abs(pathOut.GridDistance);
                        break;

                    case eDir.Left:
                        pathOut.GridDistance = -Math.Abs(pathOut.GridDistance);
                        break;
                    }
                    pathOut.Initialize(this, IsVertical(dirSwap));
                    return;
                }
            } while (dirSwap != dirThis);
        }