5.3. Event Handling

An event is a change to which the system responds. Events include interprocess communication (message exchanging between processes) events, signals, timer events (execution of a block of code at specified time), Graphical User Interface events (clicking on the screen buttons), and DataHub exceptions (a change in value of a DataHub point).

The Gamma language provides a generalized event handling capability which processes all these events. A Gamma function that responds to an event is called an event handler, or a callback. A pair of functions, next_event and next_event_nb, invoke the event handler, that is, any callback function(s) that have been attached to the event. For example, the simple construct:

while ( t) 
{
    next_event ( );
}
	  

placed at the end of the file, together with the set of callback functions defined in the application to handle all the required events, creates a purely event-driven Gamma program. However, unlike typical event-driven systems applications (such as many GUI-based applications), the user has here the opportunity to further process the events, providing a conditional which is more complex than an infinite loop, or even choosing not to receive events. The events will not be processed (or callbacks invoked) until one of the next_event calls are made.

The result of next_event is the result of executing the callbacks, or nil if no event handler has been defined (that is, no callbacks have been attached). The result of next_event_nb (nb stands for non-blocking) is the same except that nil is also returned if no event was available.

Attaching callbacks and receiving events depends on the type of event. For example, in Photon the function PtAttachCallback is used to attach actions to clicking on buttons. Normally one does not wait for an explicit event type, that is, the next_event call will process ANY event defined within the system. The following sections describe how some common event types are handled.

5.3.1. Interprocess Communication Message Events

The Gamma language uses a send/receive/reply (SRR) mechanism to provide interprocess communication via messages. In this context, a message is any valid Gamma or Lisp expression passed synchronously from one process to another, using the send function. The engine treats the message as a null-terminated character string in Lisp syntax (the Gamma internal representation), which it parses and evaluates. Any expression may be transmitted in this way, including function definitions, function calls, variable names and complex blocks of code. The reply returned is the result of the evaluation.

This process is transparent to the application. The Gamma engine evaluates the incoming message inside an implicit try/catch block to ensure that externally originated expressions cannot accidentally affect the running program. Any errors that occur while the message is being evaluated will be indicated in the return value for the message, but the overall running status of the engine will not be otherwise affected.

For more information see the Interprocess Communication section in the Special Topics chapter.