Переглянути джерело

Fixes #1763. Allowing read console inputs before idle handlers. (#1764)

* Fixes #1763. Allowing read console inputs before idle handlers.

* Locking FakeConsole.MockKeyPresses after the Application.Init.

* Adding scenario checking failed for iterations.
BDisp 3 роки тому
батько
коміт
67ab11044a

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

@@ -174,12 +174,12 @@ namespace Terminal.Gui {
 
 
 		bool IMainLoopDriver.EventsPending (bool wait)
 		bool IMainLoopDriver.EventsPending (bool wait)
 		{
 		{
+			UpdatePollMap ();
+
 			if (CheckTimers (wait, out var pollTimeout)) {
 			if (CheckTimers (wait, out var pollTimeout)) {
 				return true;
 				return true;
 			}
 			}
 
 
-			UpdatePollMap ();
-
 			var n = poll (pollmap, (uint)pollmap.Length, pollTimeout);
 			var n = poll (pollmap, (uint)pollmap.Length, pollTimeout);
 
 
 			if (n == KEY_RESIZE) {
 			if (n == KEY_RESIZE) {

+ 21 - 6
Terminal.Gui/ConsoleDrivers/FakeDriver/FakeMainLoop.cs

@@ -58,24 +58,39 @@ namespace Terminal.Gui {
 		}
 		}
 
 
 		bool IMainLoopDriver.EventsPending (bool wait)
 		bool IMainLoopDriver.EventsPending (bool wait)
+		{
+			keyResult = null;
+			waitForProbe.Set ();
+
+			if (CheckTimers (wait, out var waitTimeout)) {
+				return true;
+			}
+
+			keyReady.WaitOne (waitTimeout);
+			return keyResult.HasValue;
+		}
+
+		bool CheckTimers (bool wait, out int waitTimeout)
 		{
 		{
 			long now = DateTime.UtcNow.Ticks;
 			long now = DateTime.UtcNow.Ticks;
 
 
-			int waitTimeout;
 			if (mainLoop.timeouts.Count > 0) {
 			if (mainLoop.timeouts.Count > 0) {
 				waitTimeout = (int)((mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 				waitTimeout = (int)((mainLoop.timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
 				if (waitTimeout < 0)
 				if (waitTimeout < 0)
 					return true;
 					return true;
-			} else
+			} else {
 				waitTimeout = -1;
 				waitTimeout = -1;
+			}
 
 
 			if (!wait)
 			if (!wait)
 				waitTimeout = 0;
 				waitTimeout = 0;
 
 
-			keyResult = null;
-			waitForProbe.Set ();
-			keyReady.WaitOne (waitTimeout);
-			return keyResult.HasValue;
+			int ic;
+			lock (mainLoop.idleHandlers) {
+				ic = mainLoop.idleHandlers.Count;
+			}
+
+			return ic > 0;
 		}
 		}
 
 
 		void IMainLoopDriver.MainIteration ()
 		void IMainLoopDriver.MainIteration ()

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

@@ -1840,13 +1840,13 @@ namespace Terminal.Gui {
 
 
 		bool IMainLoopDriver.EventsPending (bool wait)
 		bool IMainLoopDriver.EventsPending (bool wait)
 		{
 		{
+			waitForProbe.Set ();
+			winChange.Set ();
+
 			if (CheckTimers (wait, out var waitTimeout)) {
 			if (CheckTimers (wait, out var waitTimeout)) {
 				return true;
 				return true;
 			}
 			}
 
 
-			waitForProbe.Set ();
-			winChange.Set ();
-
 			try {
 			try {
 				if (!tokenSource.IsCancellationRequested) {
 				if (!tokenSource.IsCancellationRequested) {
 					eventReady.Wait (waitTimeout, tokenSource.Token);
 					eventReady.Wait (waitTimeout, tokenSource.Token);

+ 10 - 7
UnitTests/ScenarioTests.cs

@@ -48,15 +48,16 @@ namespace Terminal.Gui {
 			List<Type> scenarioClasses = Scenario.GetDerivedClasses<Scenario> ();
 			List<Type> scenarioClasses = Scenario.GetDerivedClasses<Scenario> ();
 			Assert.NotEmpty (scenarioClasses);
 			Assert.NotEmpty (scenarioClasses);
 
 
-			lock (FakeConsole.MockKeyPresses) {
-				foreach (var scenarioClass in scenarioClasses) {
+			foreach (var scenarioClass in scenarioClasses) {
 
 
-					// Setup some fake keypresses 
-					// Passing empty string will cause just a ctrl-q to be fired
-					FakeConsole.MockKeyPresses.Clear ();
-					int stackSize = CreateInput ("");
+				// Setup some fake keypresses 
+				// Passing empty string will cause just a ctrl-q to be fired
+				FakeConsole.MockKeyPresses.Clear ();
+				int stackSize = CreateInput ("");
 
 
-					Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+				Application.Init (new FakeDriver (), new FakeMainLoop (() => FakeConsole.ReadKey (true)));
+
+				lock (FakeConsole.MockKeyPresses) {
 
 
 					int iterations = 0;
 					int iterations = 0;
 					Application.Iteration = () => {
 					Application.Iteration = () => {
@@ -96,6 +97,8 @@ namespace Terminal.Gui {
 
 
 					if (abortCount != 0) {
 					if (abortCount != 0) {
 						output.WriteLine ($"Scenario {scenarioClass} had abort count of {abortCount}");
 						output.WriteLine ($"Scenario {scenarioClass} had abort count of {abortCount}");
+					} else if (iterations > 1) {
+						output.WriteLine ($"Scenario {scenarioClass} had iterations count of {iterations}");
 					}
 					}
 
 
 					Assert.Equal (0, abortCount);
 					Assert.Equal (0, abortCount);