00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef TSE3_NOTIFIER_H
00018 #define TSE3_NOTIFIER_H
00019
00020 #include <iostream>
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 namespace TSE3
00045 {
00046 template <class interface_type> class Listener;
00047
00048
00049
00050
00051
00069 namespace Impl
00070 {
00077 class def_type
00078 {
00079 };
00080
00089 template <typename T>
00090 struct arg_count
00091 {
00092 enum { count=1 };
00093 };
00094 template <>
00095 struct arg_count<def_type>
00096 {
00097 enum { count=0 };
00098 };
00099
00107 template<unsigned>
00108 class num_type
00109 {
00110 };
00111
00125 class void_list
00126 {
00127 public:
00128
00129 void_list();
00130 void_list(const void_list &);
00131 ~void_list();
00132
00143 bool push_back(void *p);
00144
00151 bool erase(void *p);
00152
00158 unsigned int size() const;
00159
00166 void *operator[](unsigned int index);
00167
00174 bool contains(void *p) const;
00175
00176 private:
00177
00178 void_list &operator=(const void_list &);
00179
00180 class impl;
00181 impl *pimpl;
00182 };
00183
00199 template <class interface_type, typename listener_func,
00200 typename p1_type = def_type,
00201 typename p2_type = def_type,
00202 typename p3_type = def_type,
00203 typename p4_type = def_type>
00204 class Event
00205 {
00206 public:
00207
00213 explicit Event(listener_func func,
00214 const p1_type &p1 = p1_type(),
00215 const p2_type &p2 = p2_type(),
00216 const p3_type &p3 = p3_type(),
00217 const p4_type &p4 = p4_type())
00218 : func(func), p1(p1), p2(p2), p3(p3), p4(p4) {}
00219
00227 void callOnEvery(void_list &listeners)
00228 {
00229 const unsigned int argCount = arg_count<p1_type>::count
00230 + arg_count<p2_type>::count
00231 + arg_count<p3_type>::count
00232 + arg_count<p4_type>::count;
00233
00234 void_list copy_list(listeners);
00235 for (unsigned int i = 0; i < copy_list.size(); ++i)
00236 {
00237 if (listeners.contains(copy_list[i]))
00238 {
00239 typedef Listener<interface_type> listener_type;
00240 interface_type *listener
00241 = static_cast<listener_type*>(copy_list[i]);
00242 invokeImpl(listener, num_type<argCount>());
00243 }
00244 }
00245 }
00246
00247 private:
00248
00260 template <class T>
00261 void invokeImpl(T *listener, num_type<0>) const
00262 {
00263 (void)(listener->*func)();
00264 }
00265 template <class T>
00266 void invokeImpl(T *listener, num_type<1>) const
00267 {
00268 (void)(listener->*func)(p1);
00269 }
00270 template <class T>
00271 void invokeImpl(T *listener, num_type<2>) const
00272 {
00273 (void)(listener->*func)(p1, p2);
00274 }
00275 template <class T>
00276 void invokeImpl(T *listener, num_type<3>) const
00277 {
00278 (void)(listener->*func)(p1, p2, p3);
00279 }
00280 template <class T>
00281 void invokeImpl(T *listener, num_type<4>) const
00282 {
00283 (void)(listener->*func)(p1, p2, p3, p4);
00284 }
00285
00286 const listener_func func;
00287 const p1_type &p1;
00288 const p2_type &p2;
00289 const p3_type &p3;
00290 const p4_type &p4;
00291 };
00292
00293 };
00294
00295
00296
00297
00298
00360 template <class interface_type>
00361 class Notifier
00362 {
00363 public:
00364
00368 typedef Listener<interface_type> listener_type;
00369
00370 friend class listener_type;
00371
00372 protected:
00373
00381 Notifier() {}
00382
00387 typedef typename interface_type::notifier_type c_notifier_type;
00388
00408 template <typename func_type>
00409 void notify(func_type func)
00410 {
00411 typedef
00412 Impl::Event<interface_type, func_type, c_notifier_type*>
00413 event_type;
00414 event_type(func, static_cast<c_notifier_type*>(this))
00415 .callOnEvery(listeners);
00416 }
00417
00421 template <typename func_type, typename p1_type>
00422 void notify(func_type func, const p1_type &p1)
00423 {
00424 typedef
00425 Impl::Event<interface_type, func_type, c_notifier_type *,
00426 p1_type>
00427 event_type;
00428 event_type(func, static_cast<c_notifier_type*>(this), p1)
00429 .callOnEvery(listeners);
00430 }
00431
00435 template <typename func_type, typename p1_type, typename p2_type>
00436 void notify(func_type func, const p1_type &p1, const p2_type &p2)
00437 {
00438 typedef
00439 Impl::Event<interface_type, func_type, c_notifier_type *,
00440 p1_type, p2_type>
00441 event_type;
00442 event_type(func, static_cast<c_notifier_type*>(this), p1, p2)
00443 .callOnEvery(listeners);
00444 }
00445
00449 template <typename func_type, typename p1_type, typename p2_type,
00450 typename p3_type>
00451 void notify(func_type func, const p1_type &p1, const p2_type &p2,
00452 const p3_type &p3)
00453 {
00454 typedef
00455 Impl::Event<interface_type, func_type, c_notifier_type *,
00456 p1_type, p2_type, p3_type>
00457 event_type;
00458 event_type
00459 (func, static_cast<c_notifier_type*>(this), p1, p2, p3)
00460 .callOnEvery(listeners);
00461 }
00462
00467 virtual ~Notifier()
00468 {
00469
00470 for (unsigned int i = 0; i < listeners.size(); ++i)
00471 {
00472 listener_type *l
00473 = static_cast<listener_type*>(listeners[i]);
00474 l->NotifierImpl_Deleted
00475 (static_cast<c_notifier_type*>(this));
00476 }
00477 }
00478
00479 unsigned int numListeners() const { return listeners.size(); }
00480
00481 private:
00482
00499 bool attach(listener_type *listener)
00500 {
00501
00502 return listeners.push_back(listener);
00503 }
00504
00515 void detach(listener_type *listener)
00516 {
00517
00518 listeners.erase(listener);
00519 }
00520
00521 typedef Notifier<interface_type> self_type;
00522
00523 Notifier(const self_type &);
00524 self_type &operator=(const self_type &);
00525
00526 Impl::void_list listeners;
00527 };
00528
00567 template <class interface_type>
00568 class Listener : public interface_type
00569 {
00570 public:
00571
00575 typedef Notifier<interface_type> notifier_type;
00576
00587 void attachTo(notifier_type *notifier)
00588 {
00589 if (notifier->attach(this)) notifiers.push_back(notifier);
00590 }
00591
00600 void detachFrom(notifier_type *notifier)
00601 {
00602 if (notifiers.erase(notifier)) notifier->detach(this);
00603 }
00604
00605 friend class notifier_type;
00606
00607 protected:
00608
00617 Listener() {}
00618
00623 typedef typename interface_type::notifier_type c_notifier_type;
00624
00638 virtual void Notifier_Deleted(c_notifier_type * ) {}
00639
00648 virtual ~Listener()
00649 {
00650
00651 for (unsigned int i = 0; i < notifiers.size(); ++i)
00652 {
00653 notifier_type *n
00654 = static_cast<notifier_type*>(notifiers[i]);
00655 n->detach(this);
00656 }
00657 }
00658
00659 private:
00660
00671 void NotifierImpl_Deleted(c_notifier_type *src)
00672 {
00673 notifiers.erase(static_cast<notifier_type*>(src));
00674 this->Notifier_Deleted(src);
00675 }
00676
00677 typedef Listener<interface_type> self_type;
00678
00679 Listener(const self_type &);
00680 self_type &operator=(const self_type &);
00681
00682 Impl::void_list notifiers;
00683 };
00684 }
00685
00686 #endif