private void DrainPaints() { if (paintRequests.Count > 0) { PaintInternal(); TaskCompletionSource <bool>[] paintRequestsCopy; lock (paintRequests) { paintRequestsCopy = paintRequests.ToArray(); paintRequests.Clear(); } for (var i = 0; i < paintRequestsCopy.Length; i++) { paintRequestsCopy[i].SetResult(true); } paintRateMeter.Increment(); } }
private void Cycle() { cycleRateMeter.Increment(); // todo - if evaluation showed up on a profile. Consider checking this at most twice per second. if ((lastConsoleWidth != this.console.BufferWidth || lastConsoleHeight != this.console.WindowHeight)) { DebounceResize(); WindowResized.Fire(); } if (this.console.KeyAvailable) { var info = this.console.ReadKey(true); var effectiveMinTimeBetweenKeyPresses = MinTimeBetweenKeyPresses; if (KeyThrottlingEnabled && info.Key == lastKey && DateTime.UtcNow - lastKeyPressTime < effectiveMinTimeBetweenKeyPresses) { // the user is holding the key down and throttling is enabled OnKeyInputThrottled.Fire(); } else { lastKeyPressTime = DateTime.UtcNow; lastKey = info.Key; InvokeNextCycle(() => HandleKeyInput(info)); } } if (sendKeys.Count > 0) { var request = sendKeys.Dequeue(); InvokeNextCycle(() => { HandleKeyInput(request.Info); request.TaskSource.SetResult(true); }); } }
private void Pump() { try { bool stopRequested = false; frameRateMeter = new FrameRateMeter(); paintRateMeter = new FrameRateMeter(); while (true) { if ((lastConsoleWidth != this.console.BufferWidth || lastConsoleHeight != this.console.WindowHeight)) { DebounceResize(); WindowResized.Fire(); } bool idle = true; List <PumpMessage> iterationQueue; PaintMessage iterationPaintMessage = null; lock (pumpMessageQueue) { iterationQueue = new List <PumpMessage>(pumpMessageQueue); pumpMessageQueue.Clear(); } foreach (var message in iterationQueue) { idle = false; if (message is StopPumpMessage) { stopRequested = true; break; } else if (message is PaintMessage) { iterationPaintMessage = message as PaintMessage; } else { TryWork(message); } } if (iterationPaintMessage != null) { TryWork(iterationPaintMessage); paintRateMeter.Increment(); #if PROFILING CliProfiler.Instance.PaintMessagesProcessed++; #endif } if (stopRequested) { break; } if (this.console.KeyAvailable) { idle = false; var info = this.console.ReadKey(true); QueueAction(() => { HandleKeyInput(info); }); } frameRateMeter.Increment(); if (idle) { Thread.Sleep(0); } #if PROFILING else { CliProfiler.Instance.TotalNonIdleIterations++; } #endif } runDeferred.Resolve(); } catch (Exception ex) { runDeferred.Reject(ex); } finally { IsRunning = false; runDeferred = null; } }
private void Pump() { try { OnThredStart(); SynchronizationContext.SetSynchronizationContext(new CustomSyncContext(this)); bool stopRequested = false; cycleRateMeter = new FrameRateMeter(); paintRateMeter = new FrameRateMeter(); while (true) { cycleRateMeter.Increment(); if ((lastConsoleWidth != this.console.BufferWidth || lastConsoleHeight != this.console.WindowHeight)) { DebounceResize(); WindowResized.Fire(); } bool idle = true; List <PumpMessage> iterationQueue; PaintMessage iterationPaintMessage = null; var paintDeferreds = new List <Deferred>(); lock (pumpMessageQueue) { iterationQueue = new List <PumpMessage>(pumpMessageQueue); pumpMessageQueue.Clear(); } foreach (var message in iterationQueue) { idle = false; if (message is StopPumpMessage) { stopRequested = true; break; } else if (message is PaintMessage) { if (message.Deferred != null) { paintDeferreds.Add(message.Deferred); } iterationPaintMessage = message as PaintMessage; } else { TryWork(message); } } if (iterationPaintMessage != null) { TryWork(iterationPaintMessage); // since we debounce paints, make sure the paints // that got debounced get resolved foreach (var deferred in paintDeferreds) { if (deferred != iterationPaintMessage.Deferred) { deferred.Resolve(); } } paintRateMeter.Increment(); } if (stopRequested) { break; } if (this.console.KeyAvailable) { idle = false; var info = this.console.ReadKey(true); var effectiveMinTimeBetweenKeyPresses = MinTimeBetweenKeyPresses; if (KeyThrottlingEnabled && info.Key == lastKey && DateTime.UtcNow - lastKeyPressTime < effectiveMinTimeBetweenKeyPresses) { // the user is holding the key down and throttling is enabled } else { lastKeyPressTime = DateTime.UtcNow; lastKey = info.Key; QueueAction(() => HandleKeyInput(info)); } } else if (sendKeys.Count > 0) { idle = false; var info = sendKeys.Dequeue(); QueueAction(() => HandleKeyInput(info)); } if (idle) { Thread.Sleep(1); } } runDeferred.Resolve(); } catch (Exception ex) { runDeferred.Reject(ex); } finally { IsRunning = false; runDeferred = null; } }