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); } } }