浏览代码

Moved CheckTimers to MainLoop

Tigger Kindel 1 年之前
父节点
当前提交
bf606c4179

+ 4 - 4
Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs

@@ -186,8 +186,8 @@ namespace Terminal.Gui {
 		{
 			long now = DateTime.UtcNow.Ticks;
 
-			if (mainLoop.timeouts.Count > 0) {
-				pollTimeout = (int)((mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
+			if (mainLoop._timeouts.Count > 0) {
+				pollTimeout = (int)((mainLoop._timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 				if (pollTimeout < 0) {
 					// This avoids 'poll' waiting infinitely if 'pollTimeout < 0' until some action is detected
 					// This can occur after IMainLoopDriver.Wakeup is executed where the pollTimeout is less than 0
@@ -210,8 +210,8 @@ namespace Terminal.Gui {
 				pollTimeout = 0;
 
 			int ic;
-			lock (mainLoop.idleHandlers) {
-				ic = mainLoop.idleHandlers.Count;
+			lock (mainLoop._idleHandlers) {
+				ic = mainLoop._idleHandlers.Count;
 			}
 
 			return ic > 0;

+ 4 - 4
Terminal.Gui/ConsoleDrivers/NetDriver.cs

@@ -1390,8 +1390,8 @@ internal class NetMainLoop : IMainLoopDriver {
 	{
 		var now = DateTime.UtcNow.Ticks;
 
-		if (_mainLoop.timeouts.Count > 0) {
-			waitTimeout = (int)((_mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
+		if (_mainLoop._timeouts.Count > 0) {
+			waitTimeout = (int)((_mainLoop._timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 			if (waitTimeout < 0) {
 				return true;
 			}
@@ -1404,8 +1404,8 @@ internal class NetMainLoop : IMainLoopDriver {
 		}
 
 		int ic;
-		lock (_mainLoop.idleHandlers) {
-			ic = _mainLoop.idleHandlers.Count;
+		lock (_mainLoop._idleHandlers) {
+			ic = _mainLoop._idleHandlers.Count;
 		}
 
 		return ic > 0;

+ 3 - 30
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -1840,13 +1840,12 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		//tokenSource.Cancel ();
 		_eventReady.Set ();
 	}
-
+	
 	bool IMainLoopDriver.EventsPending (bool wait)
 	{
 		_waitForProbe.Set ();
 		_winChange.Set ();
-
-		if (CheckTimers (wait, out var waitTimeout)) {
+		if (_mainLoop.CheckTimers (wait, out var waitTimeout)) {
 			return true;
 		}
 
@@ -1861,7 +1860,7 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		}
 
 		if (!_eventReadyTokenSource.IsCancellationRequested) {
-			return _resultQueue.Count > 0 || CheckTimers (wait, out _) || _winChanged;
+			return _resultQueue.Count > 0 || _mainLoop.CheckTimers (wait, out _) || _winChanged;
 		}
 
 		_eventReadyTokenSource.Dispose ();
@@ -1869,33 +1868,7 @@ internal class WindowsMainLoop : IMainLoopDriver {
 		return true;
 	}
 	
-	bool CheckTimers (bool wait, out int waitTimeout)
-	{
-		long now = DateTime.UtcNow.Ticks;
 
-		if (_mainLoop?.timeouts.Count > 0) {
-			waitTimeout = (int)((_mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
-			if (waitTimeout < 0)
-				return true;
-		} else {
-			waitTimeout = -1;
-		}
-
-		if (!wait) {
-			waitTimeout = 0;
-		}
-
-		if (_mainLoop == null) {
-			return false;
-		}
-		
-		int ic;
-		lock (_mainLoop.idleHandlers) {
-			ic = _mainLoop.idleHandlers.Count;
-		}
-
-		return ic > 0;
-	}
 
 	void IMainLoopDriver.Iteration ()
 	{

+ 50 - 19
Terminal.Gui/MainLoop.cs

@@ -47,21 +47,21 @@ namespace Terminal.Gui {
 	/// </remarks>
 	public class MainLoop {
 
-		internal SortedList<long, Timeout> timeouts = new SortedList<long, Timeout> ();
+		internal SortedList<long, Timeout> _timeouts = new SortedList<long, Timeout> ();
 		object _timeoutsLockToken = new object ();
 
 		/// <summary>
 		/// The idle handlers and lock that must be held while manipulating them
 		/// </summary>
 		object _idleHandlersLock = new object ();
-		internal List<Func<bool>> idleHandlers = new List<Func<bool>> ();
+		internal List<Func<bool>> _idleHandlers = new List<Func<bool>> ();
 
 		/// <summary>
 		/// Gets the list of all timeouts sorted by the <see cref="TimeSpan"/> time ticks./>.
 		/// A shorter limit time can be added at the end, but it will be called before an
 		///  earlier addition that has a longer limit time.
 		/// </summary>
-		public SortedList<long, Timeout> Timeouts => timeouts;
+		public SortedList<long, Timeout> Timeouts => _timeouts;
 
 		/// <summary>
 		/// Gets a copy of the list of all idle handlers.
@@ -69,7 +69,7 @@ namespace Terminal.Gui {
 		public ReadOnlyCollection<Func<bool>> IdleHandlers {
 			get {
 				lock (_idleHandlersLock) {
-					return new List<Func<bool>> (idleHandlers).AsReadOnly ();
+					return new List<Func<bool>> (_idleHandlers).AsReadOnly ();
 				}
 			}
 		}
@@ -125,7 +125,7 @@ namespace Terminal.Gui {
 		public Func<bool> AddIdle (Func<bool> idleHandler)
 		{
 			lock (_idleHandlersLock) {
-				idleHandlers.Add (idleHandler);
+				_idleHandlers.Add (idleHandler);
 			}
 
 			MainLoopDriver.Wakeup ();
@@ -141,7 +141,7 @@ namespace Terminal.Gui {
 		public bool RemoveIdle (Func<bool> token)
 		{
 			lock (_idleHandlersLock) {
-				return idleHandlers.Remove (token);
+				return _idleHandlers.Remove (token);
 			}
 		}
 
@@ -149,7 +149,7 @@ namespace Terminal.Gui {
 		{
 			lock (_timeoutsLockToken) {
 				var k = (DateTime.UtcNow + time).Ticks;
-				timeouts.Add (NudgeToUniqueKey (k), timeout);
+				_timeouts.Add (NudgeToUniqueKey (k), timeout);
 				TimeoutAdded?.Invoke (this, new TimeoutEventArgs (timeout, k));
 			}
 		}
@@ -189,11 +189,11 @@ namespace Terminal.Gui {
 		public bool RemoveTimeout (object token)
 		{
 			lock (_timeoutsLockToken) {
-				var idx = timeouts.IndexOfValue (token as Timeout);
+				var idx = _timeouts.IndexOfValue (token as Timeout);
 				if (idx == -1) {
 					return false;
 				}
-				timeouts.RemoveAt (idx);
+				_timeouts.RemoveAt (idx);
 			}
 			return true;
 		}
@@ -208,8 +208,8 @@ namespace Terminal.Gui {
 			// we have allocated a new list (which would
 			// result in lost timeouts or errors during enumeration)
 			lock (_timeoutsLockToken) {
-				copy = timeouts;
-				timeouts = new SortedList<long, Timeout> ();
+				copy = _timeouts;
+				_timeouts = new SortedList<long, Timeout> ();
 			}
 
 			foreach (var t in copy) {
@@ -221,22 +221,52 @@ namespace Terminal.Gui {
 					}
 				} else {
 					lock (_timeoutsLockToken) {
-						timeouts.Add (NudgeToUniqueKey (k), timeout);
+						_timeouts.Add (NudgeToUniqueKey (k), timeout);
 					}
 				}
 			}
 		}
 
+		/// <summary>
+		/// Checks if there are any outstanding timers that need to be processed. Called from the driver's <see cref="IMainLoopDriver"/>.
+		/// </summary>
+		/// <param name="wait">If <see langword="false"/> <paramref name="waitTimeout"/> will be set to 0.</param>
+		/// <param name="waitTimeout">Returns the number of milliseconds remaining in the current timer.</param>
+		/// <returns></returns>
+		public bool CheckTimers (bool wait, out int waitTimeout)
+		{
+			long now = DateTime.UtcNow.Ticks;
+
+			if (_timeouts.Count > 0) {
+				waitTimeout = (int)((_timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
+				if (waitTimeout < 0)
+					return true;
+			} else {
+				waitTimeout = -1;
+			}
+
+			if (!wait) {
+				waitTimeout = 0;
+			}
+
+			int ic;
+			lock (_idleHandlers) {
+				ic = _idleHandlers.Count;
+			}
+
+			return ic > 0;
+		}
+		
 		/// <summary>
 		/// Finds the closest number to <paramref name="k"/> that is not
-		/// present in <see cref="timeouts"/> (incrementally).
+		/// present in <see cref="_timeouts"/> (incrementally).
 		/// </summary>
 		/// <param name="k"></param>
 		/// <returns></returns>
 		private long NudgeToUniqueKey (long k)
 		{
 			lock (_timeoutsLockToken) {
-				while (timeouts.ContainsKey (k)) {
+				while (_timeouts.ContainsKey (k)) {
 					k++;
 				}
 			}
@@ -248,14 +278,14 @@ namespace Terminal.Gui {
 		{
 			List<Func<bool>> iterate;
 			lock (_idleHandlersLock) {
-				iterate = idleHandlers;
-				idleHandlers = new List<Func<bool>> ();
+				iterate = _idleHandlers;
+				_idleHandlers = new List<Func<bool>> ();
 			}
 
 			foreach (var idle in iterate) {
 				if (idle ()) {
 					lock (_idleHandlersLock) {
-						idleHandlers.Add (idle);
+						_idleHandlers.Add (idle);
 					}
 				}
 			}
@@ -299,7 +329,7 @@ namespace Terminal.Gui {
 		/// </remarks>
 		public void RunIteration ()
 		{
-			if (timeouts.Count > 0) {
+			if (_timeouts.Count > 0) {
 				RunTimers ();
 			}
 
@@ -307,8 +337,9 @@ namespace Terminal.Gui {
 
 			bool runIdle = false;
 			lock (_idleHandlersLock) {
-				runIdle = idleHandlers.Count > 0;
+				runIdle = _idleHandlers.Count > 0;
 			}
+			
 			if (runIdle) {
 				RunIdle ();
 			}

+ 2 - 2
UnitTests/Application/MainLoopTests.cs

@@ -505,8 +505,8 @@ namespace Terminal.Gui.ApplicationTests {
 		{
 			var testMainloop = new TestMainloop ();
 			var mainloop = new MainLoop (testMainloop);
-			Assert.Empty (mainloop.timeouts);
-			Assert.Empty (mainloop.idleHandlers);
+			Assert.Empty (mainloop._timeouts);
+			Assert.Empty (mainloop._idleHandlers);
 			Assert.NotNull (new Timeout () {
 				Span = new TimeSpan (),
 				Callback = (_) => true

+ 7 - 7
UnitTests/Views/SpinnerViewTests.cs

@@ -20,30 +20,30 @@ namespace Terminal.Gui.ViewsTests {
 		{
 			var view = GetSpinnerView ();
 
-			Assert.Empty (Application.MainLoop.timeouts);
+			Assert.Empty (Application.MainLoop._timeouts);
 			view.AutoSpin = true;
-			Assert.NotEmpty (Application.MainLoop.timeouts);
+			Assert.NotEmpty (Application.MainLoop._timeouts);
 			Assert.True (view.AutoSpin);
 
 			//More calls to AutoSpin do not add more timeouts
-			Assert.Single (Application.MainLoop.timeouts);
+			Assert.Single (Application.MainLoop._timeouts);
 			view.AutoSpin = true;
 			view.AutoSpin = true;
 			view.AutoSpin = true;
 			Assert.True (view.AutoSpin);
-			Assert.Single (Application.MainLoop.timeouts);
+			Assert.Single (Application.MainLoop._timeouts);
 
 			if (callStop) {
 				view.AutoSpin = false;
-				Assert.Empty (Application.MainLoop.timeouts);
+				Assert.Empty (Application.MainLoop._timeouts);
 				Assert.False (view.AutoSpin);
 			} else {
-				Assert.NotEmpty (Application.MainLoop.timeouts);
+				Assert.NotEmpty (Application.MainLoop._timeouts);
 			}
 
 			// Dispose clears timeout
 			view.Dispose ();
-			Assert.Empty (Application.MainLoop.timeouts);
+			Assert.Empty (Application.MainLoop._timeouts);
 		}
 
 		[Fact, AutoInitShutdown]