Handler objects are the preferred way to deal with window event callbacks. Handler objects may also be used to bind (tcl) script commands to C++. Obviously, when employing objects you need not rely on global variables, static storage or explicit type casts. In the hush packages, both widgets and items are derived from the handler class, which means that they can be declared to be their own handler.
Handler objects may also be used to register resources that must be deleted when the handler is deleted. Since almost everything in hush is a handler, the user has ample opportunities to choose a scope suitable for any particular resource. See garbage(4).
Each handler may have handler attached to it. In this way a partcular event may be process by a chain of attached or dependent handlers. See hush/events.c.
interface handler { <hush/handler.h>
<hush/handler.idl>
sources/java/hush.dv.api.handler
virtual event* dispatch(event*); for dispatching
virtual int operator()(); for overriding
// Default functions -- for (canvas) widgets
virtual void press( event& ) { }
virtual void release( event& ) { }
virtual void keypress( event& ) { }
virtual void keyrelease( event& ) { }
virtual void motion( event& ) { }
virtual void enter( event& ) { }
virtual void leave( event& ) { }
virtual void other( event& ) { }
// Garbage collection -- registering resources
void _register(handler* x);
void _register(garbage<T>* g); for any garbage collector for T
// To attach and process dependent handlers
void dependent(handler* h); to attach a handler
void process(event* e); to process a particular event
protected:
kit* tk;
event* _event;
};
event* handler::dispatch(event* e) {
_event = e;
if (e) tk = e->thekit();
int result = this->operator()();
if (!result) return 0;
else return _event;
}
int operator()() {
event& e = * _event;
if ( e.type() == ButtonPress ) press(e);
else if ( e.type() == ButtonRelease ) release(e);
else if ( e.type() == KeyPress ) keypress(e);
else if ( e.type() == KeyRelease ) keyrelease(e);
else if ( e.type() == MotionNotify ) motion(e);
else if ( e.type() == EnterNotify ) enter(e);
else if ( e.type() == LeaveNotify ) leave(e);
else other(e);
return OK;
}
Handler objects provide a type-secure way to deal with client data. Handler objects may only be created as instances of classes derived from the class handler. The information that needed to be passed around when using plain functions, can conveniently be stored in the instance variables of the (derived) handler class. Dynamic information is typically stored in the event object that is passed to the handler. The most important (member) function of a handler object is the dispatch function. The dispatch function is typically called when an action is invoked either to execute a tcl script command or as a callback in response to a window event. In its turn the dispatch functions calls the operator() function. This indirection has been introduced to facilitate derivation by inheritance. In addition, the class handler defines a number of other member functions, corresponding to the event types related common user actions. A class derived from handler may redefine these functions and rely on the original dispatch function to call the proper member in response to an event. The original handler::dispatch, shown above, stores the event object in the (protected) _event instance variable. of handler object and indirectly calls the operator() function which in its turn calls a member function dependent on the type of the event. (See canvas(5) for an example.) The handler class knows only virtual functions. Each function, including the dispatch function and operator() function may be redefined, according to the programmers needs. Handler classes may be also be conveniently used for actions that do not involve (window) events by redefining the dispatch function.
Handlers are the central concept around which hush is built. Look at the various examples carefully. Widgets, for example, and items are derived from the handler class and may, consequently be handlers themselves. For this reason also, handlers may be used to register resources that must be freed when the handler object is deleted. The user must choose the scope within which an object lives with care. Possible scopes include the session, a kit, a widget, an item, or an arbitrary handler defined for resource management only.
hush -- file <hush/handler.h>
|
Hush Online Technology
hush@cs.vu.nl
09/24/99 |
|
|