/* 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();
*                      }
*                      preinit_phase = {
*                              // this method defined by Jeff Liang's sysfuncs.t module
*                              magicIsUsedEvent.register(self);
*                      }
*              ;
*
*      When the event occurs, call the event's raise method.
*
*              castSpell: function(actor)
*              {
*                      // do the actual magic, then
*                      magicIsUsedEvent.raise;
*              }
*
*/

#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);
               }
       }
;