-
Notifications
You must be signed in to change notification settings - Fork 2
Event Processing
Sharpie abstracts away dealing with user and system events through the use of the Event class. Event is the base class used by a number of derivatives:
- StartEvent, emitted right after the event processing starts. Useful indicator that application can start initializing other async structures,
- StopEvent, emitted right after the event processing stops,
- TerminalAboutToResizeEvent, emitted when the terminal is about to be resized. Applications should not rely on this event much as it might not be emitted as expected,
- TerminalResizeEvent, emitted when the terminal has been resized. Applications are expected to recalculate their windows and redraw the affected areas when this event is encountered,
- KeyEvent, emitted when a key has been pressed. Use this event to interact with the user's keyboard input,
- MouseMoveEvent is triggered when the mouse is moved over the terminal screen (only if the mouse has been enabled),
- MouseActionEvent is triggered when the user presses any button on the mouse or uses the mouse wheel (only if the mouse has been enabled).
To read these events, an application can create an "event loop" using the EventPump.ProcessEvents:
foreach (var @event in terminal.Events.Listen(CancellationToken.None))
{
terminal.Screen.WriteText($"{@event}\n");
if (@event is KeyEvent { Char.Value: 'C', Modifiers: ModifierKey.Ctrl })
{
break;
}
}In the example above the events are listened to on the main window called Screen. If the application has other windows created, it can choose to process events on those windows instead. Developers will need to provide a CancellationToken in order to be able to interrupt the execution of the Listen loop.
Note, that this method of processing events is referred to as raw or unsynchronized. In this mode, Sharpie does not try to ensure that all operations are synchronized against a thread/context. See Thread Safety for more details on this topic.
In order to make the most of the event processing in Sharpie one needs to understand which events are useful and when. This section describes these events.
These two events are generated by the event loop itself when the loop starts and ends. The reason these events were introduced is to give the developer the ability to run application-specific initialization code that can only be performed after the listening process started. This is not likely to be used in conjunction with EventPump.Listen though. It's most useful when combined with synchronized mode by the use of Terminal.Run method.
Once the Terminal.Run or EventPump.Listen are run, the main thread is essentially locked and used by event management routines. This means that any post-start initialization would need to be carried on another thread. To simplify this need, these two events were introduced.
The TerminalAboutToResizeEvent is an interesting one. On some OSes this event is triggered before any internal data structures have been updated within NCurses. Application developers do not need to concern themselves with this event in most cases. In very specific cases, custom pre-processing code might be needed to lock down some asynchronous code in preparation for the actual resize. Note that it's not guaranteed that this event is actually properly received.
The TerminalResizeEvent is an important event and needs to be processed by the application developers. The event carries with itself the size of the screen post-resize. Developers are expected to redraw the contents of their windows and do any other adjustments (such as sizes). Sharpie, in conjunction with NCurses will apply default logic in order to most accurately resize windows on the developer's behalf.