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