Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

fsa.H

Go to the documentation of this file.
00001 #ifndef FSA_H_IS_INCLUDED
00002 #define FSA_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file fsa.H
00006  *  \brief Contains the definition of FSA (finite state automata) classes.
00007  *
00008  *  \note Some other classes are in here as well, but they should probably be
00009  *  moved elsewhere.
00010  *
00011  *  \sa fsa.C
00012  *
00013  */
00014 
00015 #include "std/support.H"
00016 #include "disp/view.H"
00017 #include "dev/dev.H"
00018 
00019 template <class EVENT>
00020 class State_t;
00021 
00022 /*!
00023  *  \brief A generic callback Interface for testing a guard condition for an
00024  *  FSA arc.
00025  *
00026  */
00027 template <class EVENT>
00028 class Guard_t {
00029       
00030    public:
00031    
00032       Guard_t()                      { }
00033       Guard_t(const EVENT &e):_e(e)  { }
00034       virtual ~Guard_t()             { }
00035       
00036       virtual int exec(const EVENT &e) { return (e == _e); }
00037       virtual int none() const         { return 1; }
00038       const EVENT& event() const       { return _e; }
00039    
00040    private:
00041    
00042       EVENT _e;
00043 
00044 };
00045 
00046 /*!
00047  *  \brief Test EVENTs with a given function.
00048  *
00049  */
00050 template <class EVENT>
00051 class GuardFunc_t: public Guard_t<EVENT> {
00052    
00053    public:
00054    
00055       typedef bool (*func_t)(const EVENT &);
00056    
00057       GuardFunc_t(const EVENT &e, func_t f) : Guard_t<EVENT>(e), _func(f) {}
00058       
00059       virtual int exec(const EVENT &e) { return Guard_t<EVENT>::exec(e) &&
00060                                                             (*_func)(e); }
00061       virtual int none()  const        { return 0; }
00062       
00063    private:
00064    
00065       func_t _func;
00066 
00067 };
00068 
00069 /*!
00070  *  \brief Test EVENTs with a given method on an object.
00071  *
00072  */
00073 template <class T, class EVENT>
00074 class GuardMeth_t: public Guard_t<EVENT> {
00075    
00076    public:
00077    
00078       typedef bool (T::*_method)(const EVENT &);
00079    
00080       GuardMeth_t(const EVENT &e, T *o, _method m)
00081          : Guard_t<EVENT>(e),_obj(o),_meth(m) {}
00082       
00083       virtual int exec(const EVENT &e)
00084          { return Guard_t<EVENT>::exec(e) && (_obj->*_meth)(e); }
00085       
00086       virtual int none()  const        { return 0; }
00087    
00088    private:
00089    
00090        T      *_obj;
00091        _method _meth;
00092 
00093 };
00094 
00095 /*!
00096  *  \brief A generic callback Interface for whenever an Arc_t of an FSA is
00097  *  traversed.
00098  *  
00099  *  The callBack function is passed the Event which triggered the Arc and the
00100  *  default next State of the FSA.  The callBack can change the FSA's next
00101  *  state by assigning a different value.   This class is templated so that it
00102  *  can be used with any Event type that the application wants.
00103  *
00104  */
00105 template <class EVENT>
00106 class CallBack_t {
00107     
00108    public:
00109    
00110       CallBack_t():_next(0)                  { }
00111       CallBack_t(State_t<EVENT> *n):_next(n) { }
00112       virtual ~CallBack_t() {}
00113       
00114       virtual int exec(const EVENT &, State_t<EVENT> *&, State_t<EVENT> *) = 0;
00115       
00116       const State_t<EVENT> *next() const { return _next; }
00117    
00118    protected:
00119    
00120       State_t<EVENT>  *_next;
00121 
00122 };
00123 
00124 /*!
00125  *  \brief A subclass of a CallBack that contains a function to call.
00126  *
00127  */
00128 template <class EVENT>
00129 class CallFunc_t: public CallBack_t<EVENT> {
00130    
00131    public: 
00132    
00133       typedef int (*_functor)(const EVENT &, State_t<EVENT> *&);
00134     
00135       CallFunc_t(_functor f)
00136          : _func(f) { }
00137       CallFunc_t(_functor f, State_t<EVENT> *n)
00138          : CallBack_t<EVENT>(n),_func(f) { }
00139       
00140       int exec(const EVENT &e, State_t<EVENT> *&s, State_t<EVENT> *start)
00141          { assert(_func); if (_next == (State_t<EVENT> *)-1) s = start;
00142            if (_next) s = _next; int ret = _func(e,s); 
00143            if (s == (State_t<EVENT> *)-1) s = start; return ret; }
00144    
00145    protected: 
00146    
00147       _functor  _func;
00148       using CallBack_t<EVENT>::_next;
00149 
00150 };
00151 
00152 /*!
00153  *  \brief A subclass of a CallBack that contains an object and one if its
00154  *  methods to call.
00155  *
00156  */
00157 template <class T, class EVENT>
00158 class CallMeth_t : public CallBack_t<EVENT> {
00159    
00160    public:
00161    
00162       typedef int (T::*_method)(const EVENT &, State_t<EVENT> *&);
00163 
00164       CallMeth_t(T *obj, _method meth): _obj(obj), _meth(meth){ }
00165       CallMeth_t(T *obj, _method meth, State_t<EVENT> *n): 
00166                   CallBack_t<EVENT>(n), _obj(obj), _meth(meth){ }
00167 
00168       int exec(const EVENT &e, State_t<EVENT> *&s, State_t<EVENT> *start)
00169          {
00170 // VC++ 5.0 can't deal with the following line of code
00171 #ifndef WIN32
00172             assert(_obj && _meth); 
00173 #endif
00174             if (_next) s = _next; int ret = (_obj->*_meth)(e,s);
00175             if (s == (State_t<EVENT> *)-1) s = start; return ret; }
00176 
00177       int equals(_method meth) {return meth == _meth;}
00178       _method get_method() {return _meth;}
00179    
00180    protected:
00181    
00182        T       *_obj;
00183        _method  _meth;
00184 
00185       using CallBack_t<EVENT>::_next;
00186 
00187 };
00188 
00189 /*!
00190  *  \brief Represents an Arc of an FSA.
00191  *
00192  *  An Arc is traversed when its specific Event is generated.  Traversing an
00193  *  Arc results in the Callback associated with the Arc being executed.  The
00194  *  next state of the FSA is returned by the callback.
00195  *
00196  */
00197 template <class EVENT>
00198 class Arc_t {
00199    
00200    public: 
00201  
00202       Arc_t():_c(0), _guard(new Guard_t<EVENT>()) { }
00203       Arc_t(const EVENT &e, CallBack_t<EVENT> *c):_c(c),
00204                                                 _guard(new Guard_t<EVENT>(e)){ }
00205       Arc_t(Guard_t<EVENT> *g, CallBack_t<EVENT> *c): _c(c),_guard(g)   { }
00206 
00207       int execute (State_t<EVENT> *&s, const EVENT &e, 
00208                                  State_t<EVENT> *start) const
00209                                           { return _c->exec(e, s, start);}
00210       
00211       int match    (const EVENT  &e)
00212                                    const  { return _guard->exec(e); }
00213       int guarded  () const  { return !_guard->none(); }
00214       
00215       const Guard_t<EVENT>   * guard    () const  { return _guard; }
00216       const State_t<EVENT>   * next     () const  { return _c->next(); }
00217       const EVENT&             event    () const  { return _guard->event(); }
00218       const CallBack_t<EVENT>* callback () const  { return _c;    }
00219       CallBack_t<EVENT>* get_callback ()    { return _c;    }
00220       
00221       int   operator ==   (const Arc_t<EVENT> &a) const 
00222          { cerr << "Nooo ... don't compare Arcs" << endl;
00223            return _c == a._c && _guard == a._guard; }
00224    
00225    protected:
00226 
00227       CallBack_t<EVENT> *_c;     // must be a pointer since we allow subclasses
00228       Guard_t<EVENT>    *_guard; // must be a pointer since we allow subclasses
00229 
00230 };
00231 
00232 // #define CState_t const State_t
00233 
00234 /*!
00235  *  \brief A State in an FSA.
00236  *
00237  *  The State may contain multiple Arcs.  Only one Arc out of a State will be
00238  *  traversed.  When an Event is passed to a state, each Arc will be matched to
00239  *  the Event.  The first Arc that matches the Event is traversed.
00240  *
00241  */
00242 template <class EVENT>
00243 class State_t {
00244 
00245    public:
00246    
00247       typedef Arc_t<EVENT> arc_type;
00248    
00249       State_t()                     { }
00250       State_t(Cstr_ptr &n):_name(n) { }
00251       
00252       int is_empty() { return !_arcs.num(); }
00253       
00254       void operator+=(const State_t<EVENT> &s);
00255       void operator-=(const State_t<EVENT> &s);
00256       
00257       void operator+=(const Arc_t<EVENT> &a)
00258          { if (a.guarded()) _arcs.push(a);    // first for priority
00259            else _arcs += a; }
00260       void operator -=(const Arc_t<EVENT> &a) { _arcs -= a; }
00261       
00262       int consumes(const EVENT   &e) const
00263          { for(int i = 0; i < _arcs.num(); ++i) if(_arcs[i].match(e)) return 1;
00264            return 0; }
00265 
00266       //! \brief Process the event, returning the next state. If
00267       //! requested, return the result of the callback in ret.
00268       State_t<EVENT> *event(const EVENT& e, State_t<EVENT>* start=0,
00269                             int* ret=0) const;
00270 
00271       void clear() { _arcs.clear(); }
00272       
00273       const ARRAY<arc_type> &arcs() const { return _arcs; }
00274       ARRAY<arc_type> &arcs()             { return _arcs; }
00275       
00276       Cstr_ptr &name() const { return _name; }
00277       void set_name(Cstr_ptr &n) { _name = n; }
00278       
00279       int operator == (const State_t<EVENT> &a) const
00280          { cerr << "XXX: Dummy State_t::operator== got called\n"; return 0; }
00281 
00282    private:
00283    
00284       ARRAY<arc_type> _arcs;
00285       str_ptr         _name;
00286 
00287 };
00288 
00289 template <class EVENT>
00290 void
00291 State_t<EVENT>::operator+=(const State_t<EVENT>&s)
00292 {
00293    
00294    for(int i = 0; i < s._arcs.num(); ++i){
00295       
00296       int j = 0;
00297       
00298       for(; j < _arcs.num(); ++j){
00299          
00300          if(_arcs[j].match(s._arcs[i].event())){
00301             
00302             _arcs[j] = s._arcs[i]; 
00303             break;
00304          
00305          }
00306          
00307       }
00308       
00309       if(j == _arcs.num()){
00310          
00311          if(!s._arcs[i].guarded()) {
00312             
00313             _arcs += s._arcs[i];
00314             
00315          } else {
00316             
00317             // arcs w/guards come first for priority
00318             // over more general arcs
00319             _arcs.push(s._arcs[i]); 
00320             
00321          }
00322          
00323       }
00324       
00325    }
00326    
00327 }
00328 
00329 template <class EVENT>
00330 void
00331 State_t<EVENT>::operator-=(const State_t<EVENT>&s)
00332 {
00333 
00334    for(int i = 0; i < s._arcs.num(); i++){
00335       
00336       int j = _arcs.num() - 1;
00337       
00338       for(; j >= 0; j--){
00339          
00340          if(_arcs[j].match(s._arcs[i].event())){
00341             
00342             _arcs.remove(j);
00343             break;
00344             
00345          }
00346          
00347       }
00348       
00349    }
00350       
00351 }
00352 
00353 template <class EVENT>
00354 State_t<EVENT>*
00355 State_t<EVENT>::event(const EVENT& e, State_t<EVENT>* start, int* ret) const
00356 {
00357    
00358    State_t<EVENT> *next = (State_t<EVENT>*)this;
00359    
00360    for(int i = 0; i < _arcs.num(); i++){
00361       
00362       if(_arcs[i].match(e)){
00363          
00364          int k = _arcs[i].execute(next, e, start);
00365          if (ret) *ret = k;
00366          break;
00367          
00368       }
00369       
00370    }
00371    
00372    return next;
00373 
00374 }
00375 
00376 /*!
00377  *  \brief A convenience class that makes it easy for an object that has
00378  *  CallBack functions to generate the proper CallBack data structure.
00379  *
00380  *  \todo Try to remove use of TYPENAME macro if possible.
00381  *
00382  */
00383 template <class T, class EVENT, class STATE>
00384 class Interactor {
00385    
00386    public:
00387    
00388       typedef CallMeth_t<T,EVENT>  _callb;
00389       typedef GuardMeth_t<T,EVENT> _guard;
00390    
00391       virtual ~Interactor() { }
00392       
00393       _callb *Cb(TYPENAME _callb::_method m)
00394          { return new _callb((T*)this,m);  }
00395          
00396       _callb *Cb(TYPENAME _callb::_method m,State_t<EVENT> *s)
00397          { return new _callb((T*)this,m,s);}
00398                                         
00399       _guard *Gd(const EVENT &e, TYPENAME _guard::_method m)
00400          { return new _guard(e,(T*)this,m);}
00401                                         
00402       STATE *entry() { return &_entry; }
00403       const STATE *entry() const { return &_entry; }
00404    
00405    protected:
00406       
00407       STATE _entry;
00408 
00409 };
00410 
00411 
00412 
00413 #ifdef WIN32
00414 #define Arc JOTArc
00415 #endif
00416 
00417 class WINSYS;
00418 
00419 class Event;
00420 typedef const Event CEvent;
00421 
00422 /*!
00423  *  \brief Wraps up the raw event data with the view that the event occurs in.
00424  *
00425  */
00426 class Event : public Evd {
00427 
00428    public:
00429    
00430       Event()
00431          : _view(0) { }
00432       Event(VIEWptr v, DEVice *d, DEVact a=MOV, DEVmod m=NONE)
00433          : Evd(d,a,m),_view(v) { }
00434       Event(DEVice *d, DEVact a=MOV, DEVmod m=NONE)
00435          : Evd(d,a,m),_view(0) { }
00436       Event(CEvd &e)
00437          : _view(0) { *(static_cast<Evd*>(this)) = e; }
00438       Event(VIEWptr p, CEvd &e)
00439          : _view(p) { *(static_cast<Evd*>(this)) = e; }
00440       
00441       const VIEWptr&  view () const      { return _view; }
00442       
00443       Event &operator=(CEvent &e)
00444          { *(static_cast<Evd*>(this)) = e; _view = e._view; return *this; }
00445       
00446    private:
00447    
00448       VIEWptr  _view;
00449 
00450 };
00451 
00452 
00453 //--------------------------------------------------------
00454 // These type definitions are here as a convenience.
00455 // Since the generic FSA class doesn't know anything
00456 // about DEV's events, these types don't really belong
00457 // here.  However, DEV doesn't know anything about FSA's
00458 // either, so it doesn't belong there.   Perhaps there
00459 // should be an event.H or something that wraps FSA's and
00460 // DEV events together....
00461 //--------------------------------------------------------
00462 typedef Arc_t<Event>   Arc  ;
00463 typedef State_t<Event> State;
00464 typedef Guard_t<Event> Guard;
00465 
00466 
00467 /*!
00468  *  \brief Provides a simple interface to the events that can be generated
00469  *  by a Mouse object (or an equivalent combination of a 2 DOF device and a
00470  *  buttons device).
00471  *
00472  */
00473 class ButtonMapper 
00474 {
00475       DEVice_buttons  *_btn;
00476       DEVice_2d       *_ptr;
00477    public:
00478       ButtonMapper():_btn(0), _ptr(0) {}
00479       ButtonMapper(Mouse *m):_btn(&m->buttons()), _ptr(&m->pointer()){}
00480       ButtonMapper(DEVice_2d *p, DEVice_buttons *b):_btn(b), _ptr(p){}
00481 
00482       DEVice_buttons  *buttons()                 { return _btn; }
00483       DEVice_2d       *pointer()                 { return _ptr; }
00484 
00485       void  set_devs(DEVice_2d *p, DEVice_buttons *b) { _btn = b; _ptr = p; }
00486 
00487       Event b1d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B1D,mods);}
00488       Event b1u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B1U,mods);}
00489       Event b1dS ()                              { return b1d(Evd::SHIFT); }
00490       Event b1uS ()                              { return b1u(Evd::SHIFT);}
00491       Event b1dC ()                              { return b1d(Evd::CONTROL);}
00492       Event b1uC ()                              { return b1u(Evd::CONTROL);}
00493       Event b1dM1()                              { return b1d(Evd::MOD1);}
00494       Event b1uM1()                              { return b1u(Evd::MOD1);}
00495       Event b1dM2()                              { return b1d(Evd::MOD2);}
00496       Event b1uM2()                              { return b1u(Evd::MOD2);}
00497       Event b1dM3()                              { return b1d(Evd::MOD3);}
00498       Event b1uM3()                              { return b1u(Evd::MOD3);}
00499 
00500       Event b2d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B2D,mods);}
00501       Event b2u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B2U,mods);}
00502       Event b2dS ()                              { return b2d(Evd::SHIFT); }
00503       Event b2uS ()                              { return b2u(Evd::SHIFT);}
00504       Event b2dC ()                              { return b2d(Evd::CONTROL);}
00505       Event b2uC ()                              { return b2u(Evd::CONTROL);}
00506       Event b2dM1()                              { return b2d(Evd::MOD1);}
00507       Event b2uM1()                              { return b2u(Evd::MOD1);}
00508       Event b2dM2()                              { return b2d(Evd::MOD2);}
00509       Event b2uM2()                              { return b2u(Evd::MOD2);}
00510       Event b2dM3()                              { return b2d(Evd::MOD3);}
00511       Event b2uM3()                              { return b2u(Evd::MOD3);}
00512 
00513       Event b3d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B3D,mods);}
00514       Event b3u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B3U,mods);}
00515       Event b3dS ()                              { return b3d(Evd::SHIFT); }
00516       Event b3uS ()                              { return b3u(Evd::SHIFT);}
00517       Event b3dC ()                              { return b3d(Evd::CONTROL);}
00518       Event b3uC ()                              { return b3u(Evd::CONTROL);}
00519       Event b3dM1()                              { return b3d(Evd::MOD1);}
00520       Event b3uM1()                              { return b3u(Evd::MOD1);}
00521       Event b3dM2()                              { return b3d(Evd::MOD2);}
00522       Event b3uM2()                              { return b3u(Evd::MOD2);}
00523       Event b3dM3()                              { return b3d(Evd::MOD3);}
00524       Event b3uM3()                              { return b3u(Evd::MOD3);}
00525 
00526       Event b4d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B4D,mods);}
00527       Event b4u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B4U,mods);}
00528       Event b4dS ()                              { return b4d(Evd::SHIFT); }
00529       Event b4uS ()                              { return b4u(Evd::SHIFT);}
00530       Event b4dC ()                              { return b4d(Evd::CONTROL);}
00531       Event b4uC ()                              { return b4u(Evd::CONTROL);}
00532       Event b4dM1()                              { return b4d(Evd::MOD1);}
00533       Event b4uM1()                              { return b4u(Evd::MOD1);}
00534       Event b4dM2()                              { return b4d(Evd::MOD2);}
00535       Event b4uM2()                              { return b4u(Evd::MOD2);}
00536       Event b4dM3()                              { return b4d(Evd::MOD3);}
00537       Event b4uM3()                              { return b4u(Evd::MOD3);}
00538 
00539       Event b5d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B5D,mods);}
00540       Event b5u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B5U,mods);}
00541       Event b5dS ()                              { return b5d(Evd::SHIFT); }
00542       Event b5uS ()                              { return b5u(Evd::SHIFT);}
00543       Event b5dC ()                              { return b5d(Evd::CONTROL);}
00544       Event b5uC ()                              { return b5u(Evd::CONTROL);}
00545       Event b5dM1()                              { return b5d(Evd::MOD1);}
00546       Event b5uM1()                              { return b5u(Evd::MOD1);}
00547       Event b5dM2()                              { return b5d(Evd::MOD2);}
00548       Event b5uM2()                              { return b5u(Evd::MOD2);}
00549       Event b5dM3()                              { return b5d(Evd::MOD3);}
00550       Event b5uM3()                              { return b5u(Evd::MOD3);}
00551 
00552       Event b6d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B6D,mods);}
00553       Event b6u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B6U,mods);}
00554       Event b6dS ()                              { return b6d(Evd::SHIFT); }
00555       Event b6uS ()                              { return b6u(Evd::SHIFT);}
00556       Event b6dC ()                              { return b6d(Evd::CONTROL);}
00557       Event b6uC ()                              { return b6u(Evd::CONTROL);}
00558       Event b6dM1()                              { return b6d(Evd::MOD1);}
00559       Event b6uM1()                              { return b6u(Evd::MOD1);}
00560       Event b6dM2()                              { return b6d(Evd::MOD2);}
00561       Event b6uM2()                              { return b6u(Evd::MOD2);}
00562       Event b6dM3()                              { return b6d(Evd::MOD3);}
00563       Event b6uM3()                              { return b6u(Evd::MOD3);}
00564 
00565       Event b7d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B7D,mods);}
00566       Event b7u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B7U,mods);}
00567       Event b7dS ()                              { return b7d(Evd::SHIFT); }
00568       Event b7uS ()                              { return b7u(Evd::SHIFT);}
00569       Event b7dC ()                              { return b7d(Evd::CONTROL);}
00570       Event b7uC ()                              { return b7u(Evd::CONTROL);}
00571       Event b7dM1()                              { return b7d(Evd::MOD1);}
00572       Event b7uM1()                              { return b7u(Evd::MOD1);}
00573       Event b7dM2()                              { return b7d(Evd::MOD2);}
00574       Event b7uM2()                              { return b7u(Evd::MOD2);}
00575       Event b7dM3()                              { return b7d(Evd::MOD3);}
00576       Event b7uM3()                              { return b7u(Evd::MOD3);}
00577    
00578       Event b8d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B8D,mods);}
00579       Event b8u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B8U,mods);}
00580       Event b8dS ()                              { return b8d(Evd::SHIFT); }
00581       Event b8uS ()                              { return b8u(Evd::SHIFT);}
00582       Event b8dC ()                              { return b8d(Evd::CONTROL);}
00583       Event b8uC ()                              { return b8u(Evd::CONTROL);}
00584       Event b8dM1()                              { return b8d(Evd::MOD1);}
00585       Event b8uM1()                              { return b8u(Evd::MOD1);}
00586       Event b8dM2()                              { return b8d(Evd::MOD2);}
00587       Event b8uM2()                              { return b8u(Evd::MOD2);}
00588       Event b8dM3()                              { return b8d(Evd::MOD3);}
00589       Event b8uM3()                              { return b8u(Evd::MOD3);}
00590 
00591       Event b9d  (Evd::DEVmod mods=Evd::NONE)    { return Event(_btn,B9D,mods);}
00592       Event b9u  (Evd::DEVmod mods=Evd::ANY)     { return Event(_btn,B9U,mods);}
00593       Event b9dS ()                              { return b9d(Evd::SHIFT); }
00594       Event b9uS ()                              { return b9u(Evd::SHIFT);}
00595       Event b9dC ()                              { return b9d(Evd::CONTROL);}
00596       Event b9uC ()                              { return b9u(Evd::CONTROL);}
00597       Event b9dM1()                              { return b9d(Evd::MOD1);}
00598       Event b9uM1()                              { return b9u(Evd::MOD1);}
00599       Event b9dM2()                              { return b9d(Evd::MOD2);}
00600       Event b9uM2()                              { return b9u(Evd::MOD2);}
00601       Event b9dM3()                              { return b9d(Evd::MOD3);}
00602       Event b9uM3()                              { return b9u(Evd::MOD3);}
00603 
00604       Event mov  (Evd::DEVmod mods=Evd::ANY)     { return Event(_ptr,MOV,mods);}
00605       Event movC ()                              { return mov(Evd::CONTROL); }
00606       Event movS ()                              { return mov(Evd::SHIFT); }
00607       Event movM1()                              { return mov(Evd::MOD1); }
00608       Event movM2()                              { return mov(Evd::MOD2); }
00609       Event movM3()                              { return mov(Evd::MOD3); }
00610 
00611       Event shiftD()                             { return Event(0,SHIFT_D); }
00612       Event ctrlD ()                             { return Event(0,CTL_D); }
00613       Event shiftU()                             { return Event(0,SHIFT_U); }
00614       Event ctrlU ()                             { return Event(0,CTL_U); }
00615 };
00616 
00617 // When using clip plane, this allows certain objects to be excluded from
00618 // clipping
00619 extern hashvar<int> DONOT_CLIP_OBJ;
00620 
00621 //
00622 // FSA Template:
00623 //
00624 template <class EVENT>
00625 class FSAT {
00626    protected:
00627      State_t<EVENT>  *_cur;
00628      State_t<EVENT>  *_start;
00629 
00630    public:
00631      FSAT():_cur(0), _start(0)                   { }
00632      FSAT(State_t<EVENT> *x):_cur(x), _start(x)  { }
00633 
00634      State_t<EVENT> *cur()                      { return _cur; }
00635      State_t<EVENT> *start()                    { return _start; }
00636      void   set_cur(State_t<EVENT> *x)          { _cur = x; }
00637      void   reset()                             { _cur = _start; }
00638      bool   is_reset()                  const   { return _cur == _start; }
00639 
00640      // Try to handle the event. If so, return the result of
00641      // the callback function.
00642      bool handle_event(const EVENT &e) {
00643         int ret=0;
00644         _cur = _cur->event(e, _start, &ret);
00645         return (ret != 0);
00646      }
00647 };
00648 
00649 typedef FSAT<Event> FSA;
00650 
00651 class VIEWint : public DEVhandler {
00652    protected:
00653      VIEWptr      _view;
00654      ARRAY<Evd>   _events;        // events posted by application
00655      ARRAY<FSA*>  _cur_states;    // interactors listening to events on view
00656 
00657    public:
00658               VIEWint(CVIEWptr &v)          { _view = v; }
00659 
00660      VIEWptr  view() const                  { return _view;} 
00661      VIEWptr  view()                        { return _view;} 
00662 
00663      void     handle_event(CEvd &e);
00664      void     post_event  (CEvd &e)         { _events += e; }
00665 
00666      void     add_interactor(FSA* fsa)      { _cur_states += fsa; }
00667      void     rem_interactor(FSA* fsa)      { _cur_states -= fsa; }
00668 
00669      void     add_interactor(State *s)      { add_interactor(new FSA(s)); }
00670      void     rem_interactor(State *s);
00671      void     clear_interactors()           { _cur_states.clear();   }
00672 };
00673 
00674 class VIEWint_list {
00675    protected:
00676      static HASH *_dhash; // hash map from VIEW to VIEWint
00677 
00678      static HASH    *dhash()  { return _dhash ? _dhash : (_dhash=new HASH(16));}
00679 
00680      static VIEWint *find(CVIEWptr &v)             { return (VIEWint *)
00681                                                      dhash()->find((long) &*v);}
00682      static void     add (CVIEWptr &v, VIEWint *d) { dhash()->add((long)&*v,d);}
00683      static VIEWint *make(CVIEWptr &v)             { if(find(v)) return find(v);
00684                                                      VIEWint *x=new VIEWint(v);
00685                                                      add(v, x); return x; }
00686      static void     del (CVIEWptr &v)             { if (find(v))
00687                                                      dhash()->del((long) &*v); }
00688    public:
00689      static VIEWint *get(CVIEWptr &v)            { return make(v); }
00690      static void     set(CVIEWptr &v, VIEWint *d){ del(v); add(v, d); }
00691      static void     add(CVIEWptr &v, State *s)  { get(v)->add_interactor(s); }
00692      static void     rem(CVIEWptr &v, State *s)  { get(v)->rem_interactor(s); }
00693      static void     clear(CVIEWptr &v)          { get(v)->clear_interactors();}
00694 };
00695 
00696 
00697 #endif

Generated on Mon Sep 18 11:39:29 2006 for jot by  doxygen 1.4.4