#nullable enable // // LegacyMainLoopDriver.cs: IMainLoopDriver and MainLoop for legacy v1 driver based applications // // Authors: // Miguel de Icaza (miguel@gnome.org) // using System.Collections.ObjectModel; namespace Terminal.Gui.App; /// /// The main event loop of legacy v1 driver based applications. /// /// /// /// This class is provided for backward compatibility with the legacy FakeDriver implementation. /// New code should use the modern architecture instead. /// /// /// Monitoring of file descriptors is only available on Unix, there does not seem to be a way of supporting this /// on Windows. /// /// [Obsolete ("This class is for legacy FakeDriver compatibility only. Use ApplicationMainLoop for new code.")] public class MainLoop : IDisposable { /// /// Gets the class responsible for handling timeouts /// public ITimedEvents TimedEvents { get; } = new TimedEvents(); /// Creates a new MainLoop. /// Use to release resources. /// /// The instance (one of the implementations FakeMainLoop, UnixMainLoop, /// NetMainLoop or WindowsMainLoop). /// internal MainLoop (IMainLoopDriver driver) { MainLoopDriver = driver; driver.Setup (this); } /// The current in use. /// The main loop driver. internal IMainLoopDriver? MainLoopDriver { get; private set; } /// Used for unit tests. internal bool Running { get; set; } /// public void Dispose () { GC.SuppressFinalize (this); Stop (); Running = false; MainLoopDriver?.TearDown (); MainLoopDriver = null; } /// Determines whether there are pending events to be processed. /// /// You can use this method if you want to probe if events are pending. Typically used if you need to flush the /// input queue while still running some of your own code in your main thread. /// internal bool EventsPending () { return MainLoopDriver!.EventsPending (); } /// Runs the . Used only for unit tests. internal void Run () { bool prev = Running; Running = true; while (Running) { EventsPending (); RunIteration (); } Running = prev; } /// Runs one iteration of timers and file watches /// /// Use this to process all pending events (timers handlers and file watches). /// /// while (main.EventsPending ()) RunIteration (); /// /// internal void RunIteration () { RunAnsiScheduler (); MainLoopDriver?.Iteration (); TimedEvents.RunTimers (); } private void RunAnsiScheduler () { Application.Driver?.GetRequestScheduler ().RunSchedule (); } /// Stops the main loop driver and calls . Used only for unit tests. internal void Stop () { Running = false; Wakeup (); } /// Wakes up the that might be waiting on input. internal void Wakeup () { MainLoopDriver?.Wakeup (); } }