00001 
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   
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