Classes | |
| struct | EventDevice |
| struct | EventHandlerCallback |
| This represents a given event handler callback. More... | |
| struct | EventQueue |
| This represents a Event Queue. More... | |
Defines | |
| #define | EQHANDLER_PROCESS_NAME "EventQueueHandler" |
| String name given to Event Queue Handler thread. | |
| #define | EQ_MAX_DEVICES 128 |
| #define | MAX_EVENTS 128 |
| #define | EHCO_LAST INT_MAX |
| This is maximum order value. | |
| #define | EHCO_FIRST 0 |
| This is minimum order value. | |
| #define | EHCO_DONT_CARE -1 |
| This is "don't care" order value. | |
Typedefs | |
| typedef void(* | PollDevice )(void *) |
| typedef EHReturn(* | EventHandler )(const VGIS_Event *e, int mouse[2], vgis_boolean_t alreadyHandled, void *callback_data) |
| This is the function prototype for an event handler (see also EventQueue_addHandler ). | |
| typedef int | EHCallOrder |
| This is the type for the call order. | |
Enumerations | |
| enum | EHReturn { EH_HANDLED_EVENT, EH_IGNORED_EVENT, EH_POST_QUIT } |
| This is the return value from an EventHandler (see also EventQueue_addHandler ). More... | |
Functions | |
| CONTROLLERS_EXPORT void | EventQueue_init (EventQueue *) |
| Initialize the EventQueue 'eq'. | |
| CONTROLLERS_EXPORT void | EventQueue_addDevice (EventQueue *, void *device, PollDevice pollDevice) |
| Add PollDevice callback 'pollDevice' to the EventQueue 'eq's list of polled devices. | |
| CONTROLLERS_EXPORT void | EventQueue_pollDevices (const EventQueue *) |
| Call the 'pollDevice' callback for all poll devices registered with the EventQueue 'eq'. | |
| CONTROLLERS_EXPORT void | EventQueue_putEvent (EventQueue *eq, const VGIS_Event *e) |
| Add the event 'e' to the event queue 'eq'. | |
| CONTROLLERS_EXPORT void | EventQueue_setMouse (EventQueue *, int x, int y) |
| Set the current mouse location of the event queue 'eq'. | |
| CONTROLLERS_EXPORT void | EventQueue_addHandler (EventQueue *eq, EventHandler eh, EHCallOrder co, void *data) |
| The event handler 'eh' to the event queue 'eq' with callback data 'd' with call order 'co'. | |
| CONTROLLERS_EXPORT VGIS_Key | Event_translateKey (int virtual_key) |
| [WIN32] Tranlates Win32 key to VGIS key | |
Variables | |
| CONTROLLERS_EXPORT EventQueue | eventQueue |
|
|
|
|
|
String name given to Event Queue Handler thread.
|
|
|
|
|
|
This is the function prototype for an event handler (see also EventQueue_addHandler ).
|
|
|
|
|
|
This is the return value from an EventHandler (see also EventQueue_addHandler ).
|
|
|
[WIN32] Tranlates Win32 key to VGIS key
|
|
||||||||||||||||
|
Add PollDevice callback 'pollDevice' to the EventQueue 'eq's list of polled devices. 'device' is arbirary device data that is passed to 'pollDevice' |
|
||||||||||||||||||||
|
The event handler 'eh' to the event queue 'eq' with callback data 'd' with call order 'co'. All event handlers are called from a single thread forked for the EventQueue 'eq' when 'eq' is initialized. Event handlers are called continuously even if no event was issued. This allows an event handler to perform other interaction related computation (such as direct manipulation) without having to needlessly fork even more threads (see [F1] and [F2]). EventHandlers have an associated callOrder value in range EHCO_FIRST to EHCO_LAST or EHCO_DONT_CARE. Handlers are called in order of of their callOrder value with all EHCO_DONT_CARE's being before EHCO_LAST but after any non-EHCO_DONT_CARE's. EventHandlers return a value EHReturn to indicate whether the handler handled the event, ignored it, or whether it decided the application should quit. If the handler returns EH_POST_QUIT, the event handler thread will add a VGIS_QUIT event to the event queue 'eq'. Soon, all event handlers will recieve this event and should respond as necessary. The Event Handler thread main loop will actually terminate the process after all event handlers have received the VGIS_QUIT. Event Handler handlers themselves generally should not terminate the process. A canonical handler should look like this:
EHReturn MyEventHandler ( const VGIS_Event* e, int mouse[2], vgis_boolean_t alreadyHandled, void* callback_data) { EHReturn ret=EH_HANDLED_EVENT; switch (e->type) { # Optional: include this case only if your handler has no code to run when no events # are available case VGIS_NO_EVENT: return EH_IGNORED_EVENT; # Optional: this is an example of how you might want to signal quiting an application case VGIS_KEY: switch (e->key.key) { case VGIS_Q: if (e->key.pressed) return EH_POST_QUIT; else break; default: ret=EH_IGNORED_EVENT; } break; # Required: This is how you respond to the quit event case VGIS_QUIT // do any clean up work associated with this event handler break; # Required: always include this default: ret=EH_IGNORED_EVENT; } # Optional: Put code that should run regardless of the type of event here. ... return ret; } EventQueue code looks at the return value and will print a error log message if more than one handler claims to have handled the same event. Also 'alreadyHandled' will be true if a previously called handler handled this event. Your event handler may want to do specific things in this case. This mechanisms are mainly for developer debugging purposes to help catch cases where multiple handlers responded to the same keypress, etc (see [F1]). Footnotes: [F1] Wartell: I've used and/or written at least a dozen GUI event handling libraries. I am well aware this mechanism is very simplistic. The motivation for adding this mechanism was that originally there was a single navigation thread that received events. Unfortunately as a result, people we putting all sorts of non-navigation related code deep inside originally purely navigation code. This was creating all sorts of sortware maintainence and modularity problems. I needed to add some very basic modularity for event handling to clean up this mess and curb further dumping of non-navigation interaction code into the original navigation code. I needed this to be done (including rewriting old code) in a few days. This is my solution. [F2] Don't worry about adding handlers that do nothing in the VGIS_NO_EVENT case and that the EventQueue's forked thread will be needlessly sucking up gobs of CPU in these handlers. In practice VGIS has at least one built-in handler for view navigation and this handler has significant computation to perform in the VGIS_NO_EVENT case. In practice CPU time for this common thread is always usefully employed for navigation. |
|
|
Initialize the EventQueue 'eq'.
|
|
|
Call the 'pollDevice' callback for all poll devices registered with the EventQueue 'eq'.
|
|
||||||||||||
|
Add the event 'e' to the event queue 'eq'.
|
|
||||||||||||||||
|
Set the current mouse location of the event queue 'eq'.
|
|
|
|
written by Dimitri van Heesch,
© 1997-2001