00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef SIGNAL_SLOT_H_
00028 #define SIGNAL_SLOT_H_
00029
00030 #include <vector>
00031
00032
00033 namespace utils
00034 {
00035
00036 struct empty {} ;
00037 typedef empty* UNUSABLE;
00038
00039 template < typename A1 = UNUSABLE,
00040 typename A2 = UNUSABLE,
00041 typename A3 = UNUSABLE,
00042 typename A4 = UNUSABLE,
00043 typename A5 = UNUSABLE>
00044 class SlotBase
00045 {
00046 public:
00047 SlotBase(){}
00048 virtual ~SlotBase(){}
00049 virtual void operator()() = 0;
00050 virtual void operator()(A1 arg1) = 0;
00051 virtual void operator()(A1 arg1, A2 arg2) = 0;
00052 virtual void operator()(A1 arg1, A2 arg2, A3 arg3) = 0;
00053 virtual void operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4) = 0;
00054 virtual void operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) = 0;
00055 virtual bool compare(SlotBase<A1, A2, A3, A4, A5> * p) = 0;
00056 };
00057
00058
00059 template < class T,
00060 typename A1 = UNUSABLE,
00061 typename A2 = UNUSABLE,
00062 typename A3 = UNUSABLE,
00063 typename A4 = UNUSABLE,
00064 typename A5 = UNUSABLE>
00065 class Slot : public SlotBase<A1, A2, A3, A4, A5>
00066 {
00067 private:
00068 typedef void (T::*Function0)();
00069 typedef void (T::*Function1)(A1);
00070 typedef void (T::*Function2)(A1, A2);
00071 typedef void (T::*Function3)(A1, A2, A3);
00072 typedef void (T::*Function4)(A1, A2, A3, A4);
00073 typedef void (T::*Function5)(A1, A2, A3, A4, A5);
00074 typedef Slot<T, A1, A2, A3, A4, A5>* SlotPtr;
00075
00076 public:
00077
00078 Slot(T *p, Function0 f0) : instance(p) { functor.func0_ = f0; }
00079 Slot(T *p, Function1 f1) : instance(p) { functor.func1_ = f1; }
00080 Slot(T *p, Function2 f2) : instance(p) { functor.func2_ = f2; }
00081 Slot(T *p, Function3 f3) : instance(p) { functor.func3_ = f3; }
00082 Slot(T *p, Function4 f4) : instance(p) { functor.func4_ = f4; }
00083 Slot(T *p, Function5 f5) : instance(p) { functor.func5_ = f5; }
00084 ~Slot() {}
00085
00086 void operator()()
00087 {
00088 (instance->*(functor.func0_))();
00089 }
00090
00091 void operator()(A1 arg1)
00092 {
00093 (instance->*(functor.func1_))(arg1);
00094 }
00095
00096 void operator()(A1 arg1, A2 arg2)
00097 {
00098 (instance->*(functor.func2_))(arg1, arg2);
00099 }
00100
00101 void operator()(A1 arg1, A2 arg2, A3 arg3)
00102 {
00103 (instance->*(functor.func3_))(arg1, arg2, arg3);
00104 }
00105
00106 void operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4)
00107 {
00108 (instance->*(functor.func4_))(arg1, arg2, arg3, arg4);
00109 }
00110
00111 void operator()(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
00112 {
00113 (instance->*(functor.func5_))(arg1, arg2, arg3, arg4, arg5);
00114 }
00115
00116
00117 bool compare(SlotBase<A1, A2, A3, A4, A5> * p)
00118 {
00119
00120 SlotPtr ptr = static_cast<SlotPtr>(p);
00121 return ( functor.func0_ == ptr->functor.func0_ &&
00122 instance == ptr->instance );
00123 }
00124
00125 private:
00126 T *instance;
00127 union Functor
00128 {
00129 Function0 func0_;
00130 Function1 func1_;
00131 Function2 func2_;
00132 Function3 func3_;
00133 Function4 func4_;
00134 Function5 func5_;
00135 }functor;
00136 };
00137
00138 template < typename A1 = UNUSABLE,
00139 typename A2 = UNUSABLE,
00140 typename A3 = UNUSABLE,
00141 typename A4 = UNUSABLE,
00142 typename A5 = UNUSABLE>
00143 class Signal
00144 {
00145 typedef SlotBase<A1, A2, A3, A4, A5>* SlotBasePtr;
00146
00147 public:
00148 Signal()
00149 {}
00150
00151 ~Signal(){clear();}
00152
00153 public:
00154
00155 template <class T>
00156 void add_slot(T* obj, void (T::*func)(void))
00157 {
00158 SlotBasePtr p = new Slot<T>(obj, func);
00159 receivers.push_back(p);
00160 }
00161
00162 template <class T>
00163 void add_slot(T* obj, void (T::*func)(A1))
00164 {
00165 SlotBasePtr p = new Slot<T, A1>(obj, func);
00166 receivers.push_back(p);
00167 }
00168
00169 template <class T>
00170 void add_slot(T* obj, void (T::*func)(A1, A2))
00171 {
00172 SlotBasePtr p = new Slot<T, A1, A2>(obj, func);
00173 receivers.push_back(p);
00174 }
00175
00176 template <class T>
00177 void add_slot(T* obj, void (T::*func)(A1, A2, A3))
00178 {
00179 SlotBasePtr p = new Slot<T, A1, A2, A3>(obj, func);
00180 receivers.push_back(p);
00181 }
00182
00183 template <class T>
00184 void add_slot(T* obj, void (T::*func)(A1, A2, A3, A4))
00185 {
00186 SlotBasePtr p = new Slot<T, A1, A2, A3, A4>(obj, func);
00187 receivers.push_back(p);
00188 }
00189
00190 template <class T>
00191 void add_slot(T* obj, void (T::*func)(A1, A2, A3, A4, A5))
00192 {
00193 SlotBasePtr p = new Slot<T, A1, A2, A3, A4, A5>(obj, func);
00194 receivers.push_back(p);
00195 }
00196
00197
00198 template <class T>
00199 bool remove_slot(T* p, void (T::*func)())
00200 {
00201 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00202 return remove_receiver(&func_obj);
00203 }
00204
00205 template <class T>
00206 bool remove_slot(T* p, void (T::*func)(A1 arg1))
00207 {
00208 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00209 return remove_receiver(&func_obj);
00210 }
00211
00212 template <class T>
00213 bool remove_slot(T* p, void (T::*func)(A1 arg1, A2 arg2))
00214 {
00215 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00216 return remove_receiver(&func_obj);
00217 }
00218
00219 template <class T>
00220 bool remove_slot(T* p, void (T::*func)(A1 arg1, A2 arg2, A3 arg3))
00221 {
00222 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00223 return remove_receiver(&func_obj);
00224 }
00225
00226 template <class T>
00227 bool remove_slot(T* p, void (T::*func)(A1 arg1, A2 arg2, A3 arg3, A4 arg4))
00228 {
00229 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00230 return remove_receiver(&func_obj);
00231 }
00232
00233 template <class T>
00234 bool remove_slot(T* p, void (T::*func)(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5))
00235 {
00236 Slot<T, A1, A2, A3, A4, A5> func_obj(p, func);
00237 return remove_receiver(&func_obj);
00238 }
00239
00240
00241 void broadcast()
00242 {
00243 ReceiversIter begin = receivers.begin();
00244 ReceiversIter end = receivers.end();
00245 for(ReceiversIter it= begin; it != end; ++it)
00246 {
00247 (*(*it))();
00248 }
00249 }
00250
00251 void broadcast(A1 arg1)
00252 {
00253 ReceiversIter begin = receivers.begin();
00254 ReceiversIter end = receivers.end();
00255 for(ReceiversIter it= begin; it != end; ++it)
00256 {
00257 (*(*it))(arg1);
00258 }
00259 }
00260
00261
00262
00263 void safe_broadcast(A1 arg1)
00264 {
00265 Signal<A1, A2, A3, A4, A5> object;
00266 object.receivers = receivers;
00267 object.broadcast(arg1);
00268 object.receivers.clear();
00269 }
00270
00271 void broadcast(A1 arg1, A2 arg2)
00272 {
00273 ReceiversIter begin = receivers.begin();
00274 ReceiversIter end = receivers.end();
00275 for(ReceiversIter it= begin; it != end; ++it)
00276 {
00277 (*(*it))(arg1, arg2);
00278 }
00279 }
00280
00281 void broadcast(A1 arg1, A2 arg2, A3 arg3)
00282 {
00283 ReceiversIter begin = receivers.begin();
00284 ReceiversIter end = receivers.end();
00285 for(ReceiversIter it= begin; it != end; ++it)
00286 {
00287 (*(*it))(arg1, arg2, arg3);
00288 }
00289 }
00290
00291 void broadcast(A1 arg1, A2 arg2, A3 arg3, A4 arg4)
00292 {
00293 ReceiversIter begin = receivers.begin();
00294 ReceiversIter end = receivers.end();
00295 for(ReceiversIter it= begin; it != end; ++it)
00296 {
00297 (*(*it))(arg1, arg2, arg3, arg4);
00298 }
00299 }
00300
00301 void broadcast(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5)
00302 {
00303 ReceiversIter begin = receivers.begin();
00304 ReceiversIter end = receivers.end();
00305 for(ReceiversIter it= begin; it != end; ++it)
00306 {
00307 (*(*it))(arg1, arg2, arg3, arg4, arg5);
00308 }
00309 }
00310
00311
00312 unsigned int count()
00313 {
00314 return static_cast<unsigned int>(receivers.size());
00315 }
00316
00317 private:
00318
00319 void clear()
00320 {
00321 ReceiversIter begin = receivers.begin();
00322 ReceiversIter end = receivers.end();
00323 for(ReceiversIter it = begin; it != end; ++it)
00324 {
00325 delete (*it);
00326 }
00327 receivers.clear();
00328 }
00329
00330
00331 bool remove_receiver(SlotBasePtr p)
00332 {
00333 ReceiversIter begin = receivers.begin();
00334 ReceiversIter end = receivers.end();
00335 for(ReceiversIter it = begin; it != end; ++it)
00336 {
00337 if ((*it)->compare(p))
00338 {
00339 delete (*it);
00340 receivers.erase(it);
00341 return true;
00342 }
00343 }
00344 return false;
00345 }
00346
00347 private:
00348 typedef std::vector<SlotBasePtr> Receivers;
00349 typedef typename std::vector<SlotBasePtr>::iterator ReceiversIter;
00350 Receivers receivers;
00351 };
00352
00353 };
00354
00355 #endif