Example #1
0
        /// <summary>
        /// Invokes the next step in the step sequence.
        /// </summary>
        public bool MoveNext()
        {
            AssumeCanStep();
            _current = null;

            try
            {
                // this is running
                _RunningInstance = this;

                // done with steps?
                if (_StepIndex >= _steps.Count)
                {
                    // event
                    UnitCompleted?.Invoke(this, null);

                    // remove user data
                    if (_Data != null)
                    {
                        _Data.Clear();
                    }

                    // done with units?
                    if (++_UnitIndex >= _units.Count)
                    {
                        // state
                        State = StepperState.Completed;
                        _continuation?.Invoke(null);
                        return(false);
                    }

                    // state
                    State = StepperState.Loading;

                    // reset steps
                    _steps.Clear();
                    _StepIndex = 0;

                    // get steps from the unit
                    Collection <PSObject> steps;
                    var path = _units[_UnitIndex];
                    using (var ps = A.Psf.NewPowerShell())
                        steps = ps.AddCommand(path).Invoke();

                    // no steps? 'continue'
                    if (steps.Count == 0)
                    {
                        return(true);
                    }

                    // add steps and start
                    InsertRange(0, steps);
                }

                // state
                State = StepperState.Stepping;

                // counter
                ++_StepCount;

                // next step object
                object it = _steps[_StepIndex];
                if (it == null)
                {
                    Throw("Step is null.");
                }

                // show
                if (Ask)
                {
                    string text  = it.ToString();
                    string title = "Step " + (_StepIndex + 1) + "/" + _steps.Count;
                    if (_units.Count > 0)
                    {
                        if (_UnitIndex >= 0)
                        {
                            text = _units[_UnitIndex].ToString().Trim() + "\r" + text;
                        }
                        title += " Unit " + (_UnitIndex + 1) + "/" + _units.Count;
                    }

                    var args = new MessageArgs()
                    {
                        Text     = text,
                        Caption  = title,
                        Options  = MessageOptions.LeftAligned,
                        Buttons  = new string[] { "Step", "Continue", "Cancel" },
                        Position = new Point(int.MaxValue, 1)
                    };
                    switch (Far.Api.Message(args))
                    {
                    case 0:
                        break;

                    case 1:
                        Ask = false;
                        break;

                    default:
                        return(false);
                    }
                }

                // invoke the next step
                ScriptBlock block = Cast <ScriptBlock> .From(it);

                if (block != null)
                {
                    // invoke the step script
                    Collection <PSObject> result = null;
                    try
                    {
                        result = block.Invoke();
                    }
                    catch (RuntimeException ex)
                    {
                        Throw(block, "Step failed: " + ex.Message, ex);
                    }

                    // extra script, normally starts modal UI
                    ScriptBlock script;
                    if (result.Count == 1 && null != (script = result[0].BaseObject as ScriptBlock))
                    {
                        ++_StepIndex;
                        _current = new Action(delegate { script.Invoke(); });
                        return(true);
                    }

                    // unexpected output
                    if (result.Count != 0)
                    {
                        Throw(block, string.Format(null,
                                                   "Unexpected step output: {0} item(s): [{1}]...",
                                                   result.Count, TypeName(result[0])), null);
                    }
                }
                else
                {
                    // post macro
                    _current = it;
                }

                // post
                ++_StepIndex;
                return(true);
            }
            catch (Exception error)
            {
                _Error = error;
                State  = StepperState.Failed;
                if (_continuation == null)
                {
                    throw;
                }

                _continuation(error);
                return(false);
            }
            finally
            {
                // step is over
                _RunningInstance = null;
            }
        }