IApplicationMainLoop.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #nullable enable
  2. using System.Collections.Concurrent;
  3. namespace Terminal.Gui.App;
  4. /// <summary>
  5. /// Interface for the main application loop that runs the core Terminal.Gui UI rendering and event processing.
  6. /// </summary>
  7. /// <remarks>
  8. /// This interface defines the contract for the main loop that coordinates:
  9. /// <list type="bullet">
  10. /// <item>Processing input events from the console</item>
  11. /// <item>Running user timeout callbacks</item>
  12. /// <item>Detecting UI changes that need redrawing</item>
  13. /// <item>Rendering UI updates to the console</item>
  14. /// </list>
  15. /// </remarks>
  16. /// <typeparam name="TInputRecord">Type of raw input events processed by the loop, e.g. <see cref="ConsoleKeyInfo"/> for cross-platform .NET driver</typeparam>
  17. public interface IApplicationMainLoop<TInputRecord> : IDisposable where TInputRecord : struct
  18. {
  19. /// <summary>
  20. /// Gets the <see cref="ITimedEvents"/> implementation that manages user-defined timeouts and periodic events.
  21. /// </summary>
  22. public ITimedEvents TimedEvents { get; }
  23. /// <summary>
  24. /// Gets the <see cref="IOutputBuffer"/> representing the desired screen state for console rendering.
  25. /// </summary>
  26. public IOutputBuffer OutputBuffer { get; }
  27. /// <summary>
  28. /// Gets the <see cref="IOutput"/> implementation responsible for rendering the <see cref="OutputBuffer"/> to the console using platform specific methods.
  29. /// </summary>
  30. public IOutput Output { get; }
  31. /// <summary>
  32. /// Gets <see cref="InputProcessor"/> implementation that processes the mouse and keyboard input populated by <see cref="IInput{TInputRecord}"/>
  33. /// implementations on the input thread and translating to events on the UI thread.
  34. /// </summary>
  35. public IInputProcessor InputProcessor { get; }
  36. /// <summary>
  37. /// Gets the class responsible for sending ANSI escape requests which expect a response
  38. /// from the remote terminal e.g. Device Attribute Request
  39. /// </summary>
  40. public AnsiRequestScheduler AnsiRequestScheduler { get; }
  41. /// <summary>
  42. /// Gets the <see cref="ISizeMonitor"/> implementation that tracks terminal size changes.
  43. /// </summary>
  44. public ISizeMonitor SizeMonitor { get; }
  45. /// <summary>
  46. /// Initializes the main loop with its required dependencies.
  47. /// </summary>
  48. /// <param name="timedEvents">
  49. /// The <see cref="ITimedEvents"/> implementation for managing user-defined timeouts and periodic callbacks
  50. /// (e.g., <see cref="Application.AddTimeout"/>).
  51. /// </param>
  52. /// <param name="inputQueue">
  53. /// The thread-safe queue containing raw input events populated by <see cref="IInput{TInputRecord}"/> on
  54. /// the input thread. This queue is drained by <see cref="InputProcessor"/> during each <see cref="Iteration"/>.
  55. /// </param>
  56. /// <param name="inputProcessor">
  57. /// The <see cref="IInputProcessor"/> that translates raw input records (e.g., <see cref="ConsoleKeyInfo"/>)
  58. /// into Terminal.Gui events (<see cref="Key"/>, <see cref="MouseEventArgs"/>) and raises them on the main UI thread.
  59. /// </param>
  60. /// <param name="output">
  61. /// The <see cref="IOutput"/> implementation responsible for rendering the <see cref="OutputBuffer"/> to the
  62. /// console using platform-specific methods (e.g., Win32 APIs, ANSI escape sequences).
  63. /// </param>
  64. /// <param name="componentFactory">
  65. /// The factory for creating driver-specific components. Used here to create the <see cref="ISizeMonitor"/>
  66. /// that tracks terminal size changes.
  67. /// </param>
  68. /// <remarks>
  69. /// <para>
  70. /// This method is called by <see cref="MainLoopCoordinator{TInputRecord}"/> during application startup
  71. /// to wire up all the components needed for the main loop to function. It must be called before
  72. /// <see cref="Iteration"/> can be invoked.
  73. /// </para>
  74. /// <para>
  75. /// <b>Initialization order:</b>
  76. /// </para>
  77. /// <list type="number">
  78. /// <item>Store references to <paramref name="timedEvents"/>, <paramref name="inputQueue"/>,
  79. /// <paramref name="inputProcessor"/>, and <paramref name="output"/></item>
  80. /// <item>Create <see cref="AnsiRequestScheduler"/> for managing ANSI requests/responses</item>
  81. /// <item>Initialize <see cref="OutputBuffer"/> size to match current console dimensions</item>
  82. /// <item>Create <see cref="ISizeMonitor"/> using the <paramref name="componentFactory"/></item>
  83. /// </list>
  84. /// <para>
  85. /// After initialization, the main loop is ready to process events via <see cref="Iteration"/>.
  86. /// </para>
  87. /// </remarks>
  88. void Initialize (
  89. ITimedEvents timedEvents,
  90. ConcurrentQueue<TInputRecord> inputQueue,
  91. IInputProcessor inputProcessor,
  92. IOutput output,
  93. IComponentFactory<TInputRecord> componentFactory
  94. );
  95. /// <summary>
  96. /// Perform a single iteration of the main loop then blocks for a fixed length
  97. /// of time, this method is designed to be run in a loop.
  98. /// </summary>
  99. public void Iteration ();
  100. }