diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index 5bfa5f2cc6..037cb03dbf 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -522,6 +522,11 @@ public static bool RunIteration (ref RunState state, bool firstIteration = false return firstIteration; } + internal static void RaiseIteration () + { + Iteration?.Invoke (null, new IterationEventArgs ()); + } + /// Stops the provided , causing or the if provided. /// The to stop. /// diff --git a/Terminal.Gui/Application/Application.cs b/Terminal.Gui/Application/Application.cs index 9ea1b45040..4b8ada306a 100644 --- a/Terminal.Gui/Application/Application.cs +++ b/Terminal.Gui/Application/Application.cs @@ -26,6 +26,15 @@ public static partial class Application /// Gets all cultures supported by the application without the invariant language. public static List? SupportedCultures { get; private set; } = GetSupportedCultures (); + /// + /// Maximum number of iterations of the main loop (and hence draws) + /// to allow to occur per second. Defaults to 25 which is a 40ms sleep + /// after iteration (factoring in how long iteration took to run). + /// Note that not ever iteration draws (see ). + /// Only affects v2 drivers. + /// + public static ushort MaximumIterationsPerSecond = 25; + /// /// Gets a string representation of the Application as rendered by . /// diff --git a/Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs b/Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs index 08575a1ba3..4a9351ab14 100644 --- a/Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs @@ -99,14 +99,17 @@ public void Initialize (ITimedEvents timedEvents, ConcurrentQueue inputBuffer public void Iteration () { DateTime dt = Now (); + int timeAllowed = 1000 / Math.Max(1,(int)Application.MaximumIterationsPerSecond); IterationImpl (); TimeSpan took = Now () - dt; - TimeSpan sleepFor = TimeSpan.FromMilliseconds (50) - took; + TimeSpan sleepFor = TimeSpan.FromMilliseconds (timeAllowed) - took; Logging.TotalIterationMetric.Record (took.Milliseconds); + Application.RaiseIteration (); + if (sleepFor.Milliseconds > 0) { Task.Delay (sleepFor).Wait (); diff --git a/UICatalog/Scenario.cs b/UICatalog/Scenario.cs index e45e269f7d..431cc56b7c 100644 --- a/UICatalog/Scenario.cs +++ b/UICatalog/Scenario.cs @@ -229,13 +229,20 @@ private void OnApplicationOnIteration (object? s, IterationEventArgs a) } } + private HashSet _scenariosRun = new HashSet (); private void OnApplicationNotifyNewRunState (object? sender, RunStateEventArgs e) { + // We are just returning to the same scenario + if (!_scenariosRun.Add (this)) + { + return; + } + SubscribeAllSubviews (Application.Top!); _currentDemoKey = 0; _demoKeys = GetDemoKeyStrokes (); - + Application.AddTimeout ( new TimeSpan (0, 0, 0, 0, BENCHMARK_KEY_PACING), () => diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index e661097d60..d9eeba1ab4 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -527,6 +527,7 @@ void ApplicationOnInitializedChanged (object? sender, EventArgs e) private static void BenchmarkAllScenarios () { + Application.MaximumIterationsPerSecond = ushort.MaxValue; List resultsList = new (); var maxScenarios = 5;