 |
EV_eventLoop |
Function (ROM Call 0x158) |
Enters the loop in which main event messages are collected and dispatched.
EV_eventLoop enters the (endless) loop in which main events are collected and dispatched to
the current application. In the normal operation of the calculator (i.e. when no user
program is running), the TIOS is just in this loop. Calling this function in the user program
makes sense (and may be very useful if you are happy with set of events which are processed in
this function) only if the program installs a custom event handler using
EV_captureEvents function, so the events may be trapped by
the user program.
Here is the exact description what happens in the each iteration of this loop (not in
exact order, but this is not important):
- If there are no activities (keypresses etc.) for a long time, and if the
timer APD_TIMER expires (see
OSRegisterTimer), the calculator is
turned off.
- If a key is pressed, the event CM_KEYPRESS is
send (using EV_sendEvent) to the current application. Note
if the current application is "Home screen", this may cause evaluation of the input
line (if the pressed key was ENTER key), including execution of user programs, etc.
This may also cause changing of the current application (for example, if the user pressed
APPS key).
- If there is a string in the event paste buffer (see EV_sendString),
the content of the buffer is processed exactly as if all codes in the buffer are typed from
the keyboard (i.e. a sequence of CM_KEYPRESS events
are send to the current application).
- If there is no keypress, if the cursor is enabled (see CU_start)
and if CURSOR_TIMER expires (see
OSRegisterTimer),
CM_BLINK event is send to the current application.
- If a global variable which contains the error code is non-zero, an error dialog is
displayed (using ERD_dialog).
- If there are twin symbols (see SymAddTwin) in the VAT
table, they are deleted. This performs cleaning up the RAM after executing of archived
programs.
- If painting is enabled (see EV_suspendPainting and
EV_restorePainting), event CM_WPAINT
is send using EV_paintOneWindow function.
- If there are no other activities, CM_IDLE event is send to the
current application, and the function idle is called.
Note that when an user ASM program is started, the current application is always "Home screen",
until the user changes the current application using EV_startApp or
installs thier own event driven "task" using EV_captureEvents.
So, if you simply call EV_eventLoop in the your program, without previous usage of
EV_captureEvents or EV_startApp,
you will have an illusion that you are not in the your program but in the home screen, because
all collected events will be dispatched to the "Home screen" application. Note that in this
case, there is no way to exit this loop, and your program will stay "resident" and
"locked" in the memory forever, although you will not be aware of the fact that your program
is still "running" - you will be able to execute everything,
including running other programs etc.
As EV_eventLoop enters the endless loop, the only method (and this is the proposed method in
TIOS) to exit the loop is to throw an error from the user event handler installed using
EV_captureEvents. This is possible because in the event loop
there are no error handlers in place, so ER_throw passes
control to the previous level of error handler. In terms of normal operation (i.e. while you
are typing in the home screen) this is handled
by EV_centralDispatcher, which restarts the event loop.
However, in custom event handling it is used to return from the event loop to the calling code.
To achieve this, you need to catch errors using ER_catch
or using TRY...ONERR...ENDTRY
construction. So, the typical usage of EV_eventLoop function in user programs is:
EV_captureEvents (UserHandler);
TRY
EV_eventLoop (); // The only way to exit from this is
ONERR // to throw an error from the event handler!
EV_captureEvents (NULL);
ENDTRY
Of course, user handler must decide what to do with events dispatched by EV_eventLoop. Very
nice example of usage of this methodology is given in textedit.h
header file. Another example may be found with the description of
CAT_dialog function.
These principles are used often in the TIOS. For example, error dialogs are principally
implemented as follows (although there are no obvious reasons why events are used in this
example):
void ERD_EventHandler(EVENT *ev)
{
if (ev->Type == CM_KEYPRESS)
switch (ev->Key.Code)
{
case KEY_ENTER: ER_throw (1);
// Exit from event loop: ENTER key pressed
case KEY_ESC: ER_throw (2);
// Another exit: ESC key pressed
case KEY_OFF: EV_defaultHandler (ev);
// OFF key pressed: allow the machine to be switched off
}
}
short ERD_dialog(short err_no, short prog_flag)
{
EV_captureEvents (ERD_EventHandler);
// Display the dialog
TRY
EV_eventLoop();
ONERR
switch(errCode)
{
case 1: // Restore the screen and return KEY_ENTER code
case 2: // Restore the screen and return KEY_ESC code
}
ENDTRY
}
To exit from EV_eventLoop, the best idea is to throw error codes less than 8, as they are
never used as error codes in normal error handling.
Uses: EV_paintOneWindow, EV_sendEvent, EV_sendEventSide, ERD_dialog, HToESI, kbhit, ngetchx, ST_busy, CU_cursorState, idle, off, OSClearBreak, OSEnableBreak, OSTimerExpired, OSTimerRestart, XR_stringPtr, ERD_dismissNotice, ERD_notice, EV_currentApp, EV_errorCode, LoadSymFromFindHandle, OO_firstACB, SymDelTwin, SymFindFirst, SymFindNext, ROM Call 0x424, ROM Call 0x471
Used by: EV_centralDispatcher, EV_defaultHandler, cmd_input, cmd_inputstr, cmd_prompt, Dialog, ERD_dialog, EV_quit, GT_Trace