Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

event.H

Go to the documentation of this file.
00001 #ifndef GLUE_EVENT_H
00002 #define GLUE_EVENT_H
00003 
00004 #include "std/list.H"
00005 #include "std/strings.H"
00006 #include "std/typedobj.H"
00007 
00008 
00009 //
00010 // EVENTsource - an identifier of a source of EVENTs
00011 //   Whenever an EVENT is created, an EVENTsource must be provided.
00012 // The EVENTsource describes the static characteristics of the object
00013 // that triggered the EVENT.  This EVENTsource description is then typically
00014 // used by EVENT consumers to identify only those EVENTs from specific
00015 // EVENT producers (EVENTsources).  For example, multiple producers,
00016 // such as a mouse or tablet, may produce 2D EVENTs, and so the EVENTsource
00017 // of each 2D EVENT allows a consumer to distinguish the mouse from the
00018 // tablet.
00019 //
00020 typedef const class EVENTsource cEVENTsource;
00021 class DllImpExp EVENTsource {
00022  protected:
00023      str_list              _tags;
00024      ARRAY<void *>         _vals;
00025      ARRAY<cEVENTsource *> _sources;
00026      str_ptr               _evt_name;
00027 
00028      bool     find_tag(Cstr_ptr &tag, void *&v) const;
00029 
00030  public :
00031            EVENTsource(Cstr_ptr &tag, void *v=0){ _evt_name=tag; add_tag(tag,v); }
00032   virtual ~EVENTsource() {}
00033 
00034   void         add_source(cEVENTsource *s)      {_sources += s; }
00035   EVENTsource* add_tag(Cstr_ptr &t, void *v=0)  {if (_tags.contains(t))
00036                                                    _vals[_tags.get_index(t)]=v;
00037                                                  else {
00038                                                     _tags+=t;_vals+=v;}
00039                                                  return this;}
00040   int          operator == (cEVENTsource &)      const { assert(0); return 0; }
00041   int          test(cEVENTsource &e)             const;
00042   void         print_data()                      const;
00043   void         print()                           const;
00044   Cstr_ptr    &evt_name()                        const { return _evt_name; }
00045 virtual void   debug(ostream &os)                const { os << "evt = " << _evt_name; }
00046 };
00047 
00048 
00049 //
00050 // EVENT - base class for an event, typically generated by a device
00051 //
00052 //   EVENT is a base class for system EVENTs, typically generated by a
00053 // device.  Each device may associate specific device data with an EVENT
00054 // by generating sub-classes of EVENTs that provide data accessors.  In 
00055 // addition, sub-classes will have to fill-in the protected compare() 
00056 // virtual method so that the device-specific information can be compared 
00057 // when EVENT's are compared with the public test() method.
00058 //   EVENTs created by devices contain EVENTsource descriptions of the 
00059 // device.  However, consumers of EVENTs need to provide an EVENTsource
00060 // description only if they need to distinguish between EVENTs of the
00061 // same type that come from different EVENTsources.
00062 //
00063 MAKE_PTR_BASEC(EVENT);
00064 class DllImpExp EVENT: public REFcounter, public TYPEDOBJ {
00065   protected:
00066 static bool       _debug;
00067     cEVENTsource *_source;
00068     virtual bool   compare(cEVENTptr &) const = 0;
00069     virtual void  debug_data(ostream &/*o*/)   const { }
00070 
00071   public:
00072 
00073 static void       set_debug(bool f)         { _debug = f; }
00074     bool          debug_on() const;
00075   
00076                   EVENT(cEVENTsource *s=0):_source(s)     { }
00077 
00078     cEVENTsource *source()            const { return _source; }
00079 
00080     virtual void  debug(ostream &o)   const { o << class_name() << "(";
00081                                               if (_source) _source->debug(o);
00082                                               else o << str_ptr("<none>");
00083                                               debug_data(o);
00084                                               o <<")"; }
00085     virtual bool  test(cEVENTptr &)   const;
00086     virtual double time()             const { return 0; }
00087 
00088     /* ------- TYPEDOBJ methods ----------- */ 
00089     DEFINE_BASE_TYPE(EVENT, cEVENTptr);
00090    static EVENTptr cast(cEVENTptr &e)       { return e; } // for fsa templates
00091 };
00092 
00093 
00094 //
00095 // EVENTset - is a set of EVENTs
00096 //   An EVENTset is used to describe a logically OR'ed set of EVENTs.
00097 // The primary use of an EVENTset is to test whether a generated 
00098 // EVENT matches any of a set of similar EVENTs, such as different
00099 // buttons on the same device, or equivalent buttons on different
00100 // devices.
00101 //
00102 MAKE_PTR_SUBC(EVENTset, EVENT);
00103 class EVENTset: public EVENT
00104 {
00105    protected:
00106     LIST<EVENTptr> _events;
00107 
00108        /* ------- EVENT methods ----------- */ 
00109     virtual bool compare(cEVENTptr &) const { return true; }
00110 
00111    public:
00112                  EVENTset()               { }
00113             void add (cEVENTptr &e)       { _events += e; }
00114             void rem (cEVENTptr &e)       { _events -= e; }
00115 
00116        /* ------- EVENT methods ----------- */ 
00117     virtual void debug(ostream &o)  const { if (!_events.num()) return;
00118                                             _events[0]->debug(o);
00119                                             for (int i=1;i<_events.num();i++){
00120                                                o<<"|";_events[i]->debug(o); }}
00121 
00122        /* ------- EVENT methods ----------- */ 
00123     virtual bool test(cEVENTptr &e) const { for (int i=0; i<_events.num();i++)
00124                                               if (_events[i]->test(e))
00125                                                  return true;
00126                                             return false; }
00127 };
00128 
00129 
00130 //
00131 // EVENTmsg - is a generic message EVENT
00132 //   EVENTmsg's are used to send message strings through the EVENT
00133 // distribution mechanism.
00134 //
00135 MAKE_PTR_SUBC(EVENTmsg, EVENT);
00136 class EVENTmsg : public EVENT {
00137   protected:
00138    Cstr_ptr _msg;
00139 
00140        /* ------- EVENT methods ----------- */ 
00141    virtual bool compare(cEVENTptr &e) const { EVENTmsg *m = (EVENTmsg *) &*e;
00142                                               return m->_msg == _msg; }
00143   public:
00144                 EVENTmsg(Cstr_ptr &m, cEVENTsource *s=0):EVENT(s),_msg(m) { }
00145 
00146    virtual void debug(ostream &o)     const { o << class_name() 
00147                                                 << "(" << _msg << ")"; }
00148          Cstr_ptr &msg()              const { return _msg; }
00149 
00150        /* ------- TYPEDOBJ methods ----------- */ 
00151    DEFINE_DERIVED_TYPE(EVENTmsg, EVENT, cEVENTptr);
00152    static EVENTmsgptr cast(cEVENTptr &e) { return EVENTmsg::isa(e) ? 
00153                                                  (EVENTmsg *)&*e : 0; }
00154 };
00155 
00156 
00157 
00158 //
00159 //
00160 //  EVENThandler - callback class for observing device events
00161 //     
00162 //  All events are distributed to registered EVENThandlers
00163 //  by calling the handler's abstract handle_event() interface.  Any
00164 //  given class that wants to observe device events must inherit
00165 //  and implement the EVENThandler interface.
00166 //
00167 class EVENThandler {
00168   public:
00169    virtual     ~EVENThandler() { }
00170 
00171    virtual void handle_event( cEVENTptr & ) = 0;
00172 };
00173 
00174 
00175 class EVENTfilter {
00176    public:
00177       virtual EVENTptr filter(cEVENTptr &) = 0;
00178 };
00179 
00180 
00181 //
00182 //
00183 //  EVENTmgr - a unique instance for distributing EVENTs
00184 //     
00185 //     All system events should be distributed through the EVENTmgr.
00186 //  Thus, anyone who wants to listen to a specific device event 
00187 //  registers their EVENThandler with the EVENTmgr and then uses a
00188 //  template EVENT's 'test()' method to filter out unwanted EVENTs.
00189 //
00190 class DllImpExp EVENTmgr {
00191 
00192   static ARRAY<EVENThandler *> *_hdlrs;
00193   static ARRAY<EVENThandler *> &hdlrs();
00194   static ARRAY<EVENTfilter  *> *_filters;
00195   static ARRAY<EVENTfilter  *> &filters();
00196   
00197 public :
00198   
00199   static void add_filter (EVENTfilter  *f) { filters() += f; }
00200   static void rem_filter (EVENTfilter  *f) { filters() -= f; }
00201   static void add_handler(EVENThandler *h) { hdlrs() += h; }
00202   static void rem_handler(EVENThandler *h) { hdlrs() -= h; }
00203 
00204   static void distrib(cEVENTptr &e) { 
00205     if (e->debug_on()) {
00206       e->debug(cerr);
00207       cerr << endl;
00208     }
00209     EVENTptr evt = e;
00210     for (int f=0;f<filters().num();f++) {
00211       EVENTptr nevt = filters()[f]->filter(evt);
00212       if (nevt != evt) {
00213     evt = nevt;
00214     if (evt->debug_on()) {
00215       cerr << "EVENT remapped:";
00216       evt->debug(cerr);
00217       cerr << endl;
00218     }
00219       }
00220     }
00221     for (int i=0;i<hdlrs().num();i++)
00222       hdlrs()[i]->handle_event(evt);
00223   }
00224   
00225 };
00226 
00227 
00228 #endif

Generated on Mon Sep 15 16:25:56 2003 for gluebase by doxygen1.2.18