#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 (); }
}