Skip to content

Commit

Permalink
Fixes #2921 - MainLoop refactoring (#2922)
Browse files Browse the repository at this point in the history
* Adds basic MainLoop unit tests

* Remove WinChange action from Curses

* Remove WinChange action from Curses

* Remove ProcessInput action from Windows MainLoop

* Simplified MainLoop/ConsoleDriver by making MainLoop internal and moving impt fns to Application

* Modernized Terminal resize events

* Modernized Terminal resize events

* Removed un used property

* for _isWindowsTerminal devenv->wininit; not sure what changed

* Modernized mouse/keyboard events (Action->EventHandler)

* Updated OnMouseEvent API docs

* Using WT_SESSION to detect WT

* removes hacky GetParentProcess

* Updates to fix #2634 (clear last line)

* removes hacky GetParentProcess2

* Addressed mac resize issue

* Addressed mac resize issue

* Removes ConsoleDriver.PrepareToRun, has Init return MainLoop

* Removes unneeded Attribute methods

* Removed GetProcesssName

* Removed GetProcesssName

* Refactored KeyEvent and KeyEventEventArgs into a single class

* Revert "Refactored KeyEvent and KeyEventEventArgs into a single class"

This reverts commit 88a0065.

* Fixed key repeat issue; reverted stupidity on 1049/1047 confusion

* Updated CSI API Docs

* merge
  • Loading branch information
tig authored Oct 21, 2023
1 parent 8ea6b10 commit 6851b42
Show file tree
Hide file tree
Showing 94 changed files with 3,027 additions and 2,946 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ The [Microsoft .NET Framework Design Guidelines](https://docs.microsoft.com/en-u
> ✔️ DO name event argument classes with the "EventArgs" suffix.
1. We follow the naming guidelines provided in https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN
2. We use the `event Action<T>` idiom.
2. We use the `event EventHandler<T>` idiom.
3. For public APIs, the class that can raise the event will implement:
- A `virtual` event raising function, named as `OnEventToRaise`. Typical implementations will simply do a `EventToRaise?.Invoke(this, eventArgs)`.
- An `event` as in `public event Action<EventArgs> EventToRaise`
- Consumers of the event can do `theobject.EventToRaise += (args) => {};`
- An `event` as in `public event EventHandler<EventArgs> EventToRaise`
- Consumers of the event can do `theobject.EventToRaise += (sender, args) => {};`
- Sub-classes of the class implementing `EventToRaise` can override `OnEventToRaise` as needed.
4. Where possible, a subclass of `EventArgs` should be provided and the old and new state should be included. By doing this, event handler methods do not have to query the sender for state.

Expand Down
6 changes: 3 additions & 3 deletions ReactiveExample/TerminalScheduler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public override IDisposable Schedule<TState> (
IDisposable PostOnMainLoop() {
var composite = new CompositeDisposable(2);
var cancellation = new CancellationDisposable();
Application.MainLoop.Invoke (() => {
Application.Invoke (() => {
if (!cancellation.Token.IsCancellationRequested)
composite.Add(action(this, state));
});
Expand All @@ -25,11 +25,11 @@ IDisposable PostOnMainLoop() {

IDisposable PostOnMainLoopAsTimeout () {
var composite = new CompositeDisposable (2);
var timeout = Application.MainLoop.AddTimeout (dueTime, args => {
var timeout = Application.AddTimeout (dueTime, () => {
composite.Add(action (this, state));
return false;
});
composite.Add (Disposable.Create (() => Application.MainLoop.RemoveTimeout (timeout)));
composite.Add (Disposable.Create (() => Application.RemoveTimeout (timeout)));
return composite;
}

Expand Down
443 changes: 271 additions & 172 deletions Terminal.Gui/Application.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Terminal.Gui/Configuration/ConfigurationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public static void OnUpdated ()

/// <summary>
/// Resets the state of <see cref="ConfigurationManager"/>. Should be called whenever a new app session
/// (e.g. in <see cref="Application.Init(ConsoleDriver, IMainLoopDriver)"/> starts. Called by <see cref="Load"/>
/// (e.g. in <see cref="Application.Init(ConsoleDriver)"/> starts. Called by <see cref="Load"/>
/// if the <c>reset</c> parameter is <see langword="true"/>.
/// </summary>
/// <remarks>
Expand Down
124 changes: 81 additions & 43 deletions Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

namespace Terminal.Gui;


/// <summary>
/// Base class for Terminal.Gui ConsoleDriver implementations.
/// </summary>
Expand All @@ -32,20 +31,31 @@ public abstract class ConsoleDriver {
/// </summary>
internal static bool RunningUnitTests { get; set; }

#region Setup & Teardown

/// <summary>
/// Initializes the driver
/// </summary>
/// <returns>Returns an instance of <see cref="MainLoop"/> using the <see cref="IMainLoopDriver"/> for the driver.</returns>
internal abstract MainLoop Init ();

/// <summary>
/// Prepare the driver and set the key and mouse events handlers.
/// Ends the execution of the console driver.
/// </summary>
/// <param name="mainLoop">The main loop.</param>
/// <param name="keyHandler">The handler for ProcessKey</param>
/// <param name="keyDownHandler">The handler for key down events</param>
/// <param name="keyUpHandler">The handler for key up events</param>
/// <param name="mouseHandler">The handler for mouse events</param>
public abstract void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler);
internal abstract void End ();

#endregion

/// <summary>
/// The handler fired when the terminal is resized.
/// The event fired when the terminal is resized.
/// </summary>
protected Action TerminalResized;
public event EventHandler<SizeChangedEventArgs> SizeChanged;

/// <summary>
/// Called when the terminal size changes. Fires the <see cref="SizeChanged"/> event.
/// </summary>
/// <param name="args"></param>
public void OnSizeChanged (SizeChangedEventArgs args) => SizeChanged?.Invoke (this, args);

/// <summary>
/// The number of columns visible in the terminal.
Expand Down Expand Up @@ -90,12 +100,6 @@ public abstract class ConsoleDriver {
///// </summary>
public Cell [,] Contents { get; internal set; }

/// <summary>
/// Initializes the driver
/// </summary>
/// <param name="terminalResized">Method to invoke when the terminal is resized.</param>
public abstract void Init (Action terminalResized);

/// <summary>
/// Gets the column last set by <see cref="Move"/>. <see cref="Col"/> and <see cref="Row"/>
/// are used by <see cref="AddRune(Rune)"/> and <see cref="AddStr"/> to determine where to add content.
Expand Down Expand Up @@ -411,23 +415,14 @@ public Attribute SetAttribute (Attribute c)
return prevAttribute;
}

/// <summary>
/// Make the attribute for the foreground and background colors.
/// </summary>
/// <param name="fore">Foreground.</param>
/// <param name="back">Background.</param>
/// <returns></returns>
public virtual Attribute MakeAttribute (Color fore, Color back)
{
return MakeColor (fore, back);
}

/// <summary>
/// Gets the current <see cref="Attribute"/>.
/// </summary>
/// <returns>The current attribute.</returns>
public Attribute GetAttribute () => CurrentAttribute;


// TODO: This is only overridden by CursesDriver. Once CursesDriver supports 24-bit color, this virtual method can be
// removed (and Attribute can lose the platformColor property).
/// <summary>
/// Makes an <see cref="Attribute"/>.
/// </summary>
Expand All @@ -445,6 +440,64 @@ public virtual Attribute MakeColor (Color foreground, Color background)
}


#endregion

#region Mouse and Keyboard

/// <summary>
/// Event fired after a key has been pressed and released.
/// </summary>
public event EventHandler<KeyEventEventArgs> KeyPressed;

/// <summary>
/// Called after a key has been pressed and released. Fires the <see cref="KeyPressed"/> event.
/// </summary>
/// <param name="a"></param>
public void OnKeyPressed (KeyEventEventArgs a) => KeyPressed?.Invoke(this, a);

/// <summary>
/// Event fired when a key is released.
/// </summary>
public event EventHandler<KeyEventEventArgs> KeyUp;

/// <summary>
/// Called when a key is released. Fires the <see cref="KeyUp"/> event.
/// </summary>
/// <param name="a"></param>
public void OnKeyUp (KeyEventEventArgs a) => KeyUp?.Invoke (this, a);

/// <summary>
/// Event fired when a key is pressed.
/// </summary>
public event EventHandler<KeyEventEventArgs> KeyDown;

/// <summary>
/// Called when a key is pressed. Fires the <see cref="KeyDown"/> event.
/// </summary>
/// <param name="a"></param>
public void OnKeyDown (KeyEventEventArgs a) => KeyDown?.Invoke (this, a);

/// <summary>
/// Event fired when a mouse event occurs.
/// </summary>
public event EventHandler<MouseEventEventArgs> MouseEvent;

/// <summary>
/// Called when a mouse event occurs. Fires the <see cref="MouseEvent"/> event.
/// </summary>
/// <param name="a"></param>
public void OnMouseEvent (MouseEventEventArgs a) => MouseEvent?.Invoke (this, a);

/// <summary>
/// Simulates a key press.
/// </summary>
/// <param name="keyChar">The key character.</param>
/// <param name="key">The key.</param>
/// <param name="shift">If <see langword="true"/> simulates the Shift key being pressed.</param>
/// <param name="alt">If <see langword="true"/> simulates the Alt key being pressed.</param>
/// <param name="ctrl">If <see langword="true"/> simulates the Ctrl key being pressed.</param>
public abstract void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool ctrl);

#endregion

/// <summary>
Expand Down Expand Up @@ -479,16 +532,6 @@ public enum DiagnosticFlags : uint {
/// <remarks>This is only implemented in <see cref="CursesDriver"/>.</remarks>
public abstract void Suspend ();

/// <summary>
/// Simulates a key press.
/// </summary>
/// <param name="keyChar">The key character.</param>
/// <param name="key">The key.</param>
/// <param name="shift">If <see langword="true"/> simulates the Shift key being pressed.</param>
/// <param name="alt">If <see langword="true"/> simulates the Alt key being pressed.</param>
/// <param name="ctrl">If <see langword="true"/> simulates the Ctrl key being pressed.</param>
public abstract void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool ctrl);

// TODO: Move FillRect to ./Drawing
/// <summary>
/// Fills the specified rectangle with the specified rune.
Expand All @@ -513,11 +556,6 @@ public void FillRect (Rect rect, Rune rune = default)
/// <param name="c"></param>
public void FillRect (Rect rect, char c) => FillRect (rect, new Rune (c));

/// <summary>
/// Ends the execution of the console driver.
/// </summary>
public abstract void End ();

/// <summary>
/// Returns the name of the driver and relevant library version information.
/// </summary>
Expand Down
Loading

0 comments on commit 6851b42

Please sign in to comment.