public void EnqueueAction(IPipelineAction action)
        {
            lock (this._queueLock)
            {
                this._actionQueue.Enqueue(action);

                this.Start();
            }
        }
        private bool CheckForActionToBegin()
        {
            if (this._pendingAction != null && this._pendingActionNeedsBegun)
            {
                if (this._pendingAction.RequireIdleToPerform && REPlugin.Instance.MonitorManager.CharacterState.Busy.WaitOne(0))
                {
                    // Can't begin invoke yet because this action wants us to wait until we are idle to invoke
                    return true;
                }

                if (!_pendingAction.Ready())
                {
                    // The action has said that for some reason it is not ready to be performed yet.
                    return true;
                }

                try
                {
                    // First begin invoke the action
                    this._pendingAction.Perform();

                    this._backgroundDispatcher.EnqueueAction(this._pendingAction.WaitForOutcome);
                    return true;
                }
                catch
                {
                    // If we hit an exception, we don't want to leave VT in an undesired state.  That could lead to a bot getting killed or something
                    if (this._cachedVTRunScope != null)
                    {
                        this._cachedVTRunScope.Dispose();
                        this._cachedVTRunScope = null;
                    }

                    // If any exceptions, need to reset our state.
                    this._pendingAction = null;
                    this._backgroundAction = null;
                    throw;
                }
                finally
                {
                    this._pendingActionNeedsBegun = false;
                }
            }

            // We didn't do anything
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns>Returns true if the current processing stage should break</returns>
        private bool CheckForReadyToEndOrRetry()
        {
            if (this._pendingAction != null && !this._pendingActionNeedsBegun)
            {
                if (!this._pendingAction.IsComplete)
                {
                    // nothing to do yet, we are still waiting on the action to complete.  Return
                    return true;
                }

                if (this._pendingAction.Retry)
                {
                    Debug.WriteLine("[PDispatcher] - Resetting Action for Retry");

                    try
                    {
                        // The action as requested that we retry it.
                        this._pendingAction.ResetForRetry();

                        this._pendingActionNeedsBegun = true;

                        // We don't want to process it on this cycle, so return true to signal a break
                        return true;
                    }
                    catch
                    {
                        // If there are any exceptions we need to reset our state
                        this._pendingAction.Dispose();
                        this._pendingAction = null;
                        this._backgroundAction = null;

                        this.DisposeOfVTScopeIfEmptyQueue(false);
                        throw;
                    }
                }

                // The pending action has completed.  We need to finalize it
                try
                {
                    this._pendingAction.End();

                    // Need to deal VT Scope.  Only restore if the queue is empty.
                    // if the queue is not empty, we will deal with it when we go to invoke the next
                    // action.
                    this.DisposeOfVTScopeIfEmptyQueue(false);

                    return true;
                }
                finally
                {
                    this._pendingAction.Dispose();
                    this._pendingAction = null;
                    this._backgroundAction = null;
                }
            }

            // There are no pending actions.
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns>Returns true if the current processing stage should break</returns>
        private bool CheckForNewActionToInit()
        {
            if (this._pendingAction == null)
            {
                IPipelineAction actionToBegin = null;
                // Don't hold the lock any longer than necessary.
                lock (this._queueLock)
                {
                    if (this._actionQueue.Count == 0)
                    {
                        this.Stop();
                        return true;
                    }

                    actionToBegin = this._actionQueue.Dequeue();
                }

                if (actionToBegin.RequiresExplicitVTState)
                {
                    // Support VT on/off toggling.  The cached scope will not be null when rolling over from a previous action.
                    // In that case, if multiple actions were queued up and both want VT disabled, don't bother turning it back on in between.
                    if (this._cachedVTRunScope != null)
                    {
                        // The next action wants a different VTState, so we need to dispose of the current one
                        if (this._cachedVTRunScope.DesiredState != actionToBegin.DesiredVTRunState)
                        {
                            this._cachedVTRunScope.Dispose();
                            this._cachedVTRunScope = null;
                        }
                    }

                    // If we get here and the sached VT scope is null, it means we need to initialize it
                    if (this._cachedVTRunScope == null)
                    {
                        this._cachedVTRunScope = VTRunScope.Enter(actionToBegin.DesiredVTRunState);
                    }
                }

                actionToBegin.Init();

                this._pendingActionNeedsBegun = true;

                // If we get this far without any exceptions, then store the action as the pending action.
                // If any exceptions happen before this, we want to make sure we are not stuck in some state where we are waiting
                // on a bugged action to finish
                this._pendingAction = actionToBegin;

                // Don't Begin invoke on the same cycle as init
                return true;
            }

            // We didn't do anything
            return false;
        }
        public void Clear()
        {
            lock (this._queueLock)
            {
                try
                {
                    // Nothing to do if the queue is empty
                    if (this.QueueCount == 0)
                    {
                        return;
                    }

                    this._actionQueue.Clear();

                    if (this._pendingAction != null && !this._pendingActionNeedsBegun)
                    {
                        // There is a pending action, let's try and clean it up
                        try
                        {
                            this._pendingAction.End();
                        }
                        finally
                        {
                            this._pendingAction.Dispose();
                            this._pendingAction = null;
                            this._backgroundAction = null;
                        }
                    }
                }
                finally
                {
                    this.DisposeOfVTScopeIfEmptyQueue(true);
                }
            }
        }