Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members

multiplexer.h

00001 //-*- C++ -*-
00002 //
00003 #ifndef __IGSLISTENER__multiplexer_h__
00004 #define __IGSLISTENER__multiplexer_h__
00005 
00006 #include "common.h"
00007 #include "listener.h"
00008 #include "publisher.h"
00009 #include "subscriber.h"
00010 #include "utils/functions.h"
00011 #include <map>
00012 
00013 
00014 #define igs_functor(S,M)   basic::bind(&M, S)
00015 #define igs_function(F)    basic::bind(F)
00016 #define IGS_CONNECT(P,S,M) igs_connect(P,S,igs_functor(S,M))
00017 
00018 
00019 namespace listener { 
00020 
00021   class EventMultiplexer ;
00022 
00088   /*__LICENCE_HERE__*/
00089 
00090   class IGSLISTENER MultiplexerListener: public Listener {
00091   public:
00092     MultiplexerListener(unsigned int priority = 0) ;
00093     MultiplexerListener(Publisher* p, unsigned int priority = 0) ;
00094     virtual ~MultiplexerListener() ;
00095 
00111     template <typename E>
00112     void connect(const basic::function1<void, E*>& f) {multiplexer()->connect<E>(f) ;}
00113 
00118     template <typename E>
00119     static Listener::ID connect(Publisher* p, Subscriber* s, 
00120                                 const basic::function1<void, E*>& f, 
00121                                 unsigned int priority=0) 
00122     {
00123       MultiplexerListener* m = new MultiplexerListener(p, priority) ;
00124       m->connect(f) ;
00125       s->add_listener(m) ;
00126       return m->get_id() ;
00127     }
00128 
00129     template <typename E1, typename E2>
00130     static Listener::ID connect(Publisher* p, Subscriber* s, 
00131                                 const basic::function1<void, E1*>& f1, 
00132                                 const basic::function1<void, E2*>& f2,
00133                                 unsigned int priority=0) 
00134     {
00135       MultiplexerListener* m = new MultiplexerListener(p,priority) ;
00136       m->connect(f1) ;
00137       m->connect(f2) ;
00138       s->add_listener(m) ;
00139       return m->get_id() ;
00140     }
00141 
00142     template <typename E1, typename E2, typename E3>
00143     static Listener::ID connect(Publisher* p, Subscriber* s, 
00144                                 const basic::function1<void, E1*>& f1, 
00145                                 const basic::function1<void, E2*>& f2,
00146                                 const basic::function1<void, E3*>& f3,
00147                                 unsigned int priority=0) 
00148     {
00149       MultiplexerListener* m = new MultiplexerListener(p,priority) ;
00150       m->connect(f1) ;
00151       m->connect(f2) ;
00152       m->connect(f3) ;
00153       s->add_listener(m) ;
00154       return m->get_id() ;
00155     }
00156 
00160     template <typename E>
00161     static bool disconnect(Publisher* p, Subscriber* s, const basic::function1<void, E*>& f) {
00162       Subscriber::const_iterator it = s->begin_listeners() ;
00163       for (; it != s->end_listeners(); it++) {
00164         MultiplexerListener* ml = dynamic_cast<MultiplexerListener*>(*it) ;
00165         if (ml && ml->publisher()==p) {
00166           if (ml->multiplexer()->disconnect(f)) {
00167             s->remove_listener_with_id(ml->get_id()) ;
00168             return true ;
00169           }
00170         }
00171       }
00172       return false ;
00173     }
00174 
00178     template <typename E>
00179     static Listener* get_listener(Publisher* p, Subscriber* s, const basic::function1<void, E*>& f) {
00180       Subscriber::const_iterator it = s->begin_listeners() ;
00181       for (; it != s->end_listeners(); it++) {
00182         MultiplexerListener* ml = dynamic_cast<MultiplexerListener*>(*it) ;
00183         if (ml && ml->publisher()==p) {
00184           if (ml->multiplexer()->has_function(f)) {
00185             return ml ;
00186           }
00187         }
00188       }
00189       return NULL ;
00190     }
00191 
00195     virtual void dump_listener(std::ostream&, int spaces=0) ;
00196     
00197   protected:
00198     bool process_event(Event* e) ;
00199 
00200   private:
00201     EventMultiplexer* multiplexer() ;
00202     EventMultiplexer* multiplexer_ ;
00203   } ;
00204 
00214   template <typename E>
00215   Listener::ID igs_connect(Publisher* p, Subscriber* s, 
00216                            const basic::function1<void, E*>& f, 
00217                            unsigned int priority=0) 
00218   {
00219     return MultiplexerListener::connect(p,s,f,priority) ;
00220   }
00221 
00222   template <typename E1, typename E2>
00223   Listener::ID igs_connect(Publisher* p, Subscriber* s, 
00224                            const basic::function1<void, E1*>& f1, 
00225                            const basic::function1<void, E2*>& f2,
00226                            unsigned int priority=0) 
00227   {
00228     return MultiplexerListener::connect(p,s,f1,f2,priority) ;
00229   }
00230 
00231   template <typename E1, typename E2, typename E3>
00232   Listener::ID igs_connect(Publisher* p, Subscriber* s, 
00233                            const basic::function1<void, E1*>& f1, 
00234                            const basic::function1<void, E2*>& f2,
00235                            const basic::function1<void, E3*>& f3,
00236                            unsigned int priority=0) 
00237   {
00238     return MultiplexerListener::connect(p,s,f1,f2,f3,priority) ;
00239   }
00240   
00250   template <typename E>
00251   bool igs_disconnect(Publisher* p, Subscriber* s, const basic::function1<void, E*>& f) {
00252     return MultiplexerListener::disconnect(p,s,f) ;
00253   }
00254 
00265   template <typename E>
00266   Listener* igs_get_listener(Publisher* p, Subscriber* s, const basic::function1<void, E*>& f) {
00267     return MultiplexerListener::get_listener(p,s,f) ;
00268   }
00269   
00270 
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297   // ========================================================
00298 
00299   class IGSLISTENER EventMultiplexer {
00300   public:
00301     template <typename E>
00302     void connect(const basic::function1<void, E*>& f) {c_.bind<E>(f) ;}
00303 
00304     template <typename E>
00305     bool disconnect(const basic::function1<void, E*>& f) {return c_.disconnect<E>(f);}
00306 
00307     template <typename E>
00308     bool has_function(const basic::function1<void, E*>& f) {return c_.has_function<E>(f);}
00309 
00310     void proceed(Event* e) ;
00311 
00312     void dump(std::ostream&, int spaces=0) ;
00313     
00314   private:
00315     struct IGSLISTENER caller {
00316       virtual ~caller() ;
00317       virtual void call(Event*) = 0 ;
00318       virtual void dump(std::ostream&, int spaces=0) = 0 ;
00319     } ;
00320     
00321     template <typename E>
00322     struct real_caller: public caller {
00323       real_caller(const basic::function1<void, E*>&) ;
00324       virtual void call(Event* e) ;
00325       virtual void dump(std::ostream&, int spaces=0) ;
00326       basic::function1<void, E*> f_ ;
00327     } ;
00328     
00329     class IGSLISTENER Calls {
00330     public:
00331       ~Calls() ;
00332       template <typename E>
00333       void bind(const basic::function1<void, E*>& f) {v_.push_back(new real_caller<E>(f)) ;}
00334       template <typename E>
00335       void call(E* e) {
00336         for (V::iterator it = v_.begin(); it != v_.end(); it++) {
00337           (*it)->call(e) ;
00338         }
00339       }
00340       void dump(std::ostream&, int spaces=0) ;
00341       template <typename E>
00342       bool disconnect(const basic::function1<void, E*>& f) {
00343         for (V::iterator it = v_.begin(); it != v_.end(); it++) {
00344           const real_caller<E>* rc = dynamic_cast<const real_caller<E>*>(*it) ;
00345           if (rc && (rc->f_ == f)) {
00346             v_.erase(it) ;
00347             return true ;
00348           }
00349         }
00350         return false ;
00351       }
00352       template <typename E>
00353       bool has_function(const basic::function1<void, E*>& f) {
00354         for (V::iterator it = v_.begin(); it != v_.end(); it++) {
00355           const real_caller<E>* rc = dynamic_cast<const real_caller<E>*>(*it) ;
00356           if (rc && (rc->f_ == f))
00357             return true ;
00358         }
00359         return false ;
00360       }
00361     private:
00362       typedef std::vector<caller*> V ;
00363       V v_ ;
00364     } ;
00365     
00366     Calls c_ ;
00367   } ;
00368 
00369 
00370 
00371 }
00372 
00373 #include "inline_src/multiplexer.hxx"
00374 #endif

Generated on Mon Jan 30 11:57:50 2006 for EventListener by  doxygen 1.3.9.1