/* EVENT.T * Event handling module for TADS * * This module creates the class Event. Other objects can register interest * in an Event (or indicate that they are no longer interested). When the * Event is raised, an appropriate method will be called for each registered * object. By default, the receiveEvent method is called, but an Event may * specify a different callback method. * * While it would be fairly trivial to enable the user to pass arguments to * an Event when raised, I've decided to skip that for now. * * Copyright Shadow Wolf, 2003. All Rights Reserved. * * You may modify and use this file in any way you want, provided that * if you redistribute modified copies of this file in source form, the * copies must include the original copyright notice (including this * paragraph), and must be clearly marked as modified from the original * version. * */ /********************************************* * Using EVENT.T * * The Event class is very easy to use. For each type of event you wish to * handle, simply define a new Event object: * * magicIsUsedEvent: Event * callback = &magicIsUsed * ; * * In any objects that need to know about this event, define the callback * function you chose, and have the object register to be notified of the * event: * * evilVillian: Actor, initialization * magicSensed = 0 * magicIsUsed(e) = { * // The argument can be used if multiple events have the same * // callback, such as with the receiveEvent default * self.magicSensed++; * if (self.magicSensed > threshold) killPlayer(); * } * does_something = { * magicIsUsedEvent.register(self); * } * ; * * When the event occurs, call the event's raise method. * * castSpell: function(actor) * { * // do the actual magic, then * magicIsUsedEvent.raise; * } * * If an object is derived from EventListener, then you can specify a * registerForEvents list which will automatically register the object for the * events in question during the preinit phase. You do need to call * eventRegistration() from your preinit function (automatic if Jeff Liang's * sysfuncs module has been included.) * */ #ifndef EVENT_T_ #define EVENT_T_ #pragma C+ class Event: object observers = [] callback = &receiveEvent register(obj) = { observers += obj; } unregister(obj) = { observers -= obj; } raise = { local c, l = self.observers; while (l != []) { c = car(l); l = cdr(l); if (defined (c, self.callback)) // Safety first! c.(self.callback) (self); } } ; class EventListener: object registerForEvents = [] ; eventRegistration: function { local o, i; for (o = firstobj(EventListener); o != nil; o = nextobj(o,EventListener)) { for (i = 1; i <= length(o.registerForEvents); i++) { o.registerForEvents[i].register(o); } } } #ifdef SYSFUNCS // Take advantage of Jeff Liang's sysfuncs.t module if available initializeEventRegistration: initialization preinit_phase = {eventRegistration();} ; #endif #ifdef VERSION // Jeff Liang's version.t present eventLibraryVersion: versionTag author = 'Shadow Wolf' func = 'event handling' ver = '2.0; Aug 25, 2003' ; #endif // VERSION #endif // EVENT_T_