TSdlEvents
Event queue management.
It's extremely common--often required--that an app deal with SDL's event queue. Almost all useful information about interactions with the real world flow through here: the user interacting with the computer and app, hardware coming and going, the system changing in some way, etc.
An app generally takes a moment, perhaps at the start of a new frame, to examine any events that have occured since the last time and process or ignore them. This is generally done by overriding TSdlApp.Event.
There is other forms of control, too: Peep has more functionality at the cost of more complexity, and Wait can block the process until something interesting happens, which might be beneficial for certain types of programs on low-power hardware. One may also call AddWatch to set a callback when new events arrive.
The app is free to generate their own events, too: Push allows the app to put events onto the queue for later retrieval; Register can guarantee that these events have a kind that isn't in use by other parts of the system.
Definition
Unit: Neslib.Sdl3.Events
Methods
Name | Description |
---|---|
AddWatch | Add a callback to be triggered when an event is added to the event queue. |
Filter | Run a specific filter function on the current event queue, removing any events for which the filter returns false. |
Flush(TSdlEventKind, TSdlEventKind) | Clear events of a range of kinds from the event queue. |
Flush(TSdlEventKind) | Clear events of a specific kind from the event queue. |
GetFilter | Query the current event filter. |
Has(TSdlEventKind, TSdlEventKind) | Check for the existence of certain event kind in the event queue. |
Has(TSdlEventKind) | Check for the existence of a certain event kind in the event queue. |
IsEnabled | Query the state of processing events by kind. |
Peep(PSdlEvent, Integer, TSdlEventAction, TSdlEventKind, TSdlEventKind) | Check the event queue for messages and optionally return them. |
Peep(TArray<TSdlEvent>, TSdlEventAction, TSdlEventKind, TSdlEventKind) | Check the event queue for messages and optionally return them. |
Poll(TSdlEvent) | |
Poll | Poll for currently pending events. |
Pump | Pump the event loop, gathering events from the input devices. |
Push | Add an event to the event queue. |
Register | Registers a user-defined events. |
RemoveWatch | Remove an event watch callback added with AddWatch. |
SetEnabled | Set the state of processing events by kind. |
SetFilter | Set up a filter to process all events before they are added to the internal event queue. |
Wait(Integer, TSdlEvent) | |
Wait(Integer) | Wait until the specified timeout (in milliseconds) for the next available event. |
Wait(TSdlEvent) | |
Wait | Wait indefinitely for the next available event. |
Method Descriptions
AddWatch(TSdlEventFilter)
Add a callback to be triggered when an event is added to the event queue.
AFilter
will be called when an event happens, and its return value is ignored.
WARNING: Be very careful of what you do in the event filter function, as it may run in a different thread!
If the quit event is generated by a signal (e.g. SIGINT), it will bypass the internal queue and be delivered to the watch callback immediately, and arrive at the next event poll.
Note: the callback is called for events posted by the user through Push, but not for disabled events, nor for events by a filter callback set with SetFilter, nor for events posted by the user through Peep.
class procedure AddWatch(const AFilter: TSdlEventFilter); static
Exceptions
ESdlError
: Raised on failure.
Parameters
AFilter
: TSdlEventFilter
: Function to call when an event happens.
See Also
Remarks
It is safe to call this function from any thread.
Filter(TSdlEventFilter)
Run a specific filter function on the current event queue, removing any events for which the filter returns false.
See SetFilter for more information. Unlike SetFilter, this method does not change the filter permanently, it only uses the supplied filter until this function returns.
class procedure Filter(const AFilter: TSdlEventFilter); static
Parameters
AFilter
: TSdlEventFilter
: The function to call when an event happens.
See Also
Remarks
It is safe to call this function from any thread.
Flush(TSdlEventKind, TSdlEventKind)
Clear events of a range of kinds from the event queue.
This will unconditionally remove any events from the queue that are in the range of AMinKind
to AMaxKind
, inclusive. If you need to remove a single event kind, use the other overload instead.
It's also normal to just ignore events you don't care about in your event loop without calling this function.
This function only affects currently queued events. If you want to make sure that all pending OS events are flushed, you can call Pump on the main thread immediately before the flush call.
class procedure Flush(const AMinKind, AMaxKind: TSdlEventKind); overload; inline; static
Parameters
AMinKind
: TSdlEventKind
: The low end of event kind to be cleared.
AMaxKind
: TSdlEventKind
: The high end of event kind to be cleared, inclusive.
Remarks
This function is available since SDL 3.2.0.
Flush(TSdlEventKind)
Clear events of a specific kind from the event queue.
This will unconditionally remove any events from the queue that match AKind
. If you need to remove a range of event types, use the other overload instead.
It's also normal to just ignore events you don't care about in your event loop without calling this function.
This function only affects currently queued events. If you want to make sure that all pending OS events are flushed, you can call Pump on the main thread immediately before the flush call.
If you have user events with custom data that needs to be freed, you should use Peep to remove and clean up those events before calling this function.
class procedure Flush(const AKind: TSdlEventKind); overload; inline; static
Parameters
AKind
: TSdlEventKind
: The kind of event to be cleared.
Remarks
It is safe to call this function from any thread.
GetFilter(TSdlEventFilter)
Query the current event filter.
This function can be used to "chain" filters, by saving the existing filter before replacing it with a function that will call that saved filter.
class function GetFilter(out AFilter: TSdlEventFilter): Boolean; static
Parameters
AFilter
: TSdlEventFilter
: The current callback function will be stored here.
Returns
Boolean
: True on success or False if there is no event filter set.
See Also
Remarks
It is safe to call this function from any thread.
Has(TSdlEventKind, TSdlEventKind)
Check for the existence of certain event kind in the event queue.
If you need to check for a single event kind, use the other overload instead.
class function Has(const AMinKind, AMaxKind: TSdlEventKind): Boolean; overload; inline; static
Parameters
AMinKind
: TSdlEventKind
: The low end of event kind to be queried, inclusive.
AMaxKind
: TSdlEventKind
Returns
Boolean
: True if events with type >= AMinKind
and aminkind
and >are present, or False if not.aminkind
and >
Has(TSdlEventKind)
Check for the existence of a certain event kind in the event queue.
If you need to check for a range of event types, use the other overload instead.
class function Has(const AKind: TSdlEventKind): Boolean; overload; inline; static
Parameters
AKind
: TSdlEventKind
: The kind of event to be queried.
Returns
Boolean
: True if events matching AKind
are present, or False if events matching AKind
are not present.
Remarks
It is safe to call this function from any thread.
IsEnabled(TSdlEventKind)
Query the state of processing events by kind.
class function IsEnabled(const AKind: TSdlEventKind): Boolean; inline; static
Parameters
AKind
: TSdlEventKind
: The kind of event.
Returns
Boolean
: True if the event is being processed, False otherwise.
See Also
Remarks
It is safe to call this function from any thread.
Peep(PSdlEvent, Integer, TSdlEventAction, TSdlEventKind, TSdlEventKind)
Check the event queue for messages and optionally return them.
AAction
may be any of the following:
TSdlEventAction.Add
: up toANumEvents
events will be added to the back of the event queue.TSdlEventAction.Peek
:ANumEvents
events at the front of the event queue, within the specified minimum and maximum type, will be returned to the caller and will not be removed from the queue. If you pass nil forAEvents
, thenANumEvents
is ignored and the total number of matching events will be returned.TSdlEventAction.Get
: up toANumEvents
events at the front of the event queue, within the specified minimum and maximum type, will be returned to the caller and will be removed from the queue.
You may have to call Pump before calling this function. Otherwise, the events may not be ready to be filtered when you call Peep.
class function Peep(const AEvents: PSdlEvent; const ANumEvents: Integer; const AAction: TSdlEventAction; const AMinKind: TSdlEventKind = TSdlEventKind.First; const AMaxKind: TSdlEventKind = TSdlEventKind.Last): Integer; overload; inline; static
Exceptions
ESdlError
: Raised on failure.
Parameters
AEvents
: PSdlEvent
: Destination buffer for the retrieved events, may be nil to leave the events in the queue and return the number of events that would have been stored.
ANumEvents
: Integer
: If action is TSdlEventAction.Add, the number of events to add back to the event queue; if action is TSdlEventAction.Peek or TSdlEventAction.Get, the maximum number of events to retrieve.
AAction
: TSdlEventAction
: Action to take.
AMinKind
: TSdlEventKind = TSdlEventKind.First
: (Optional) Minimum value of the event kind to be considered; TSdlEventKind.First is a safe choice.
AMaxKind
: TSdlEventKind = TSdlEventKind.Last
Returns
Integer
: The number of events actually stored.
See Also
Remarks
It is safe to call this function from any thread.
Peep(TArray<TSdlEvent>, TSdlEventAction, TSdlEventKind, TSdlEventKind)
Check the event queue for messages and optionally return them.
AAction
may be any of the following:
TSdlEventAction.Add
: up toANumEvents
events will be added to the back of the event queue.TSdlEventAction.Peek
:ANumEvents
events at the front of the event queue, within the specified minimum and maximum type, will be returned to the caller and will not be removed from the queue. If you pass nil forAEvents
, thenANumEvents
is ignored and the total number of matching events will be returned.TSdlEventAction.Get
: up toANumEvents
events at the front of the event queue, within the specified minimum and maximum type, will be returned to the caller and will be removed from the queue.
You may have to call Pump before calling this function. Otherwise, the events may not be ready to be filtered when you call Peep.
class function Peep(const AEvents: TArray<TSdlEvent>; const AAction: TSdlEventAction; const AMinKind: TSdlEventKind = TSdlEventKind.First; const AMaxKind: TSdlEventKind = TSdlEventKind.Last): Integer; overload; inline; static
Exceptions
ESdlError
: Raised on failure.
Parameters
AEvents
: TArray<TSdlEvent>
: Destination buffer for the retrieved events, may be nil to leave the events in the queue and return the number of events that would have been stored.
AAction
: TSdlEventAction
: Action to take.
AMinKind
: TSdlEventKind = TSdlEventKind.First
: (Optional) Minimum value of the event kind to be considered; TSdlEventKind.First is a safe choice.
AMaxKind
: TSdlEventKind = TSdlEventKind.Last
Returns
Integer
: The number of events actually stored.
See Also
Remarks
It is safe to call this function from any thread.
Poll(TSdlEvent)
class function Poll(out AEvent: TSdlEvent): Boolean; overload; inline; static
Parameters
AEvent
: TSdlEvent
Returns
Boolean
Poll
Poll for currently pending events.
If AEvent
is given, the next event is removed from the queue and stored in this record. It returns True if there was an event.
If AEvent
is not given, it simply returns True if there is an event in the queue, but will not remove it from the queue.
As this function may implicitly call Pump, you can only call this function in the thread that set the video mode.
Either using TSdlApp.Event or Poll are the favored ways of receiving system events since it can be done from the main loop and does not suspend the main loop while waiting on an event to be posted.
The common practice is to fully process the event queue once every frame, usually as a first step before updating the game's state. This is done automatically if you override TSdlApp.Poll.
class function Poll: Boolean; overload; inline; static
Returns
Boolean
: True if this got an event or False if there are none available.
See Also
Remarks
This function should only be called on the main thread.
Pump
Pump the event loop, gathering events from the input devices.
This function updates the event queue and internal input device state.
Pump gathers all the pending input information from devices and places it in the event queue. Without calls to Pump no events would ever be placed on the queue. Often the need for calls to Pump is hidden from the user since TSdlApp.Event, Poll and Wait implicitly call Pump. However, if you are not polling or waiting for events (e.g. you are filtering them), then you must call Pump to force an event queue update.
class procedure Pump; inline; static
See Also
Remarks
This function should only be called on the main thread.
Push(TSdlEvent)
Add an event to the event queue.
The event queue can actually be used as a two way communication channel. Not only can events be read from the queue, but the user can also push their own events onto it. AEvent
is the event record you wish to push onto the queue. The event is copied into the queue.
Note: Pushing device input events onto the queue doesn't modify the state of the device within SDL.
Note: Events pushed onto the queue with Push get passed through the event filter but events added with Peep do not.
For pushing application-specific events, please use Register to get an event kind that does not conflict with other code that also wants its own custom event kinds.
class function Push(const AEvent: TSdlEvent): Boolean; inline; static
Exceptions
ESdlError
: Raised on failure.
Parameters
AEvent
: TSdlEvent
: The event to be added to the queue.
Returns
Boolean
: True on success, False if the event was filtered.
See Also
Remarks
It is safe to call this function from any thread.
Register
Registers a user-defined events.
class function Register: TSdlEventKind; inline; static
Returns
TSdlEventKind
: A new TSdlEventKind value, or TSdlEventKind.First if there are not enough user-defined events left.
See Also
Remarks
It is safe to call this function from any thread.
The returned value is outside of the standard TSdlEventKind enum range, but can still be used with all event functionality.
RemoveWatch(TSdlEventFilter)
Remove an event watch callback added with AddWatch.
This function takes the same input as AddWatch to identify and delete the corresponding callback.
class procedure RemoveWatch(const AFilter: TSdlEventFilter); static
Parameters
AFilter
: TSdlEventFilter
: The function originally passed to AddWatch.
See Also
Remarks
It is safe to call this function from any thread.
SetEnabled(TSdlEventKind, Boolean)
Set the state of processing events by kind.
class procedure SetEnabled(const AKind: TSdlEventKind; const AEnabled: Boolean); inline; static
Parameters
AKind
: TSdlEventKind
: The kind of event.
AEnabled
: Boolean
: Whether to process the event or not.
See Also
Remarks
It is safe to call this function from any thread.
SetFilter(TSdlEventFilter)
Set up a filter to process all events before they are added to the internal event queue.
If you just want to see events without modifying them or preventing them from being queued, you should use AddWatch instead.
If the filter function returns True when called, then the event will be added to the internal queue. If it returns False, then the event will be dropped from the queue, but the internal state will still be updated. This allows selective filtering of dynamically arriving events.
WARNING: Be very careful of what you do in the event filter function, as it may run in a different thread!
On platforms that support it, if the quit event is generated by an interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the application at the next event poll.
Note: Disabled events never make it to the event filter function; see SetEnabled.
Note: Events pushed onto the queue with Push get passed through the event filter, but events pushed onto the queue with Peep do not.
class procedure SetFilter(const AFilter: TSdlEventFilter); static
Parameters
AFilter
: TSdlEventFilter
: Filter function to call when an event happens.
See Also
Remarks
It is safe to call this function from any thread.
Wait(Integer, TSdlEvent)
class function Wait(const ATimeoutMS: Integer; out AEvent: TSdlEvent): Boolean; overload; inline; static
Parameters
ATimeoutMS
: Integer
AEvent
: TSdlEvent
Returns
Boolean
Wait(Integer)
Wait until the specified timeout (in milliseconds) for the next available event.
If AEvent
is not given, the next event is removed from the queue and stored in this record.
As this function may implicitly call Pump, you can only call this function in the thread that initialized the video subsystem.
The timeout is not guaranteed, the actual wait time could be longer due to system scheduling.
class function Wait(const ATimeoutMS: Integer): Boolean; overload; inline; static
Parameters
ATimeoutMS
: Integer
: the maximum number of milliseconds to wait for the next available event.
Returns
Boolean
: True if this got an event or False if the timeout elapsed without any events available.
See Also
Remarks
This function should only be called on the main thread.
Wait(TSdlEvent)
class procedure Wait(out AEvent: TSdlEvent); overload; inline; static
Parameters
AEvent
: TSdlEvent
Wait
Wait indefinitely for the next available event.
If AEvent
is not given, the next event is removed from the queue and stored in this record.
As this function may implicitly call Pump, you can only call this function in the thread that initialized the video subsystem.
class procedure Wait; overload; inline; static
Exceptions
ESdlError
: If there was an error while waiting for events.
See Also
Remarks
This function should only be called on the main thread.