00001
00002
00003
00004
00005 #ifndef SIGNAL_H
00006 #define SIGNAL_H
00007
00008 #include "Platform.h"
00009
00010 #include <map>
00011 #include <list>
00012 #include <iostream>
00013
00014 namespace RC {
00015
00016 template<class A, class B, class T> class TSignal;
00017 template<class A, class T> class SignalSender;
00018
00026 class Signal
00027 {
00028 public:
00029 virtual void transmit() = 0;
00030
00031 #ifdef TEMPLATE_SPECIALIZATION_SUPPORTED
00032
00033 template<class A, class SA, class B, class SB, class T>
00034 inline static void connect(A *a, T (SA:: *getPtr)() const, B *b, void (SB:: *setPtr)(T t))
00035 {
00036
00037 SignalSender<SA, T>::connect(a, getPtr, static_cast<SB *>(b), setPtr);
00038 };
00039
00041 template<class A, class SA, class B, class SB>
00042 inline static void connect(A *a, void (SA:: *getPtr)() const, B *b, void (SB:: *setPtr)())
00043 {
00044
00045 SignalSender<SA, void>::connect(a, getPtr, static_cast<SB *>(b), setPtr);
00046 };
00047
00049 template<class A, class SA, class B, class SB, class T>
00050 inline static void disconnect(A *a, T (SA:: *getPtr)() const, B *b, void (SB:: *setPtr)(T t))
00051 {
00052
00053 SignalSender<SA, T>::disconnect(a, getPtr, static_cast<SB *>(b), setPtr);
00054 };
00055
00057 template<class A, class SA, class B, class SB>
00058 inline static void disconnect(A *a, void (SA:: *getPtr)() const, B *b, void (SB:: *setPtr)())
00059 {
00060
00061 SignalSender<SA, void>::disconnect(a, getPtr, static_cast<SB *>(b), setPtr);
00062 };
00063
00066 template<class A, class SA, class T>
00067 inline static void send(A *a, T (SA:: *getPtr)() const)
00068 {
00069 SignalSender<SA, T>::send(a, getPtr);
00070 };
00071 #endif
00072 };
00073
00074 #ifdef TEMPLATE_SPECIALIZATION_SUPPORTED
00075
00078
00079 template<class A, class T>
00080 class SignalSender
00081 {
00082 private:
00083 typedef std::list<std::pair<void (A:: *)() const, Signal *> > SignalMap;
00084 typedef std::map<A *, SignalMap> SignalMapMap;
00085
00086 public:
00087 template<class B>
00088 static void connect(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t));
00089
00090 template<class B>
00091 static void disconnect(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t));
00092
00093 static void send(A *a, T (A:: *getPtr)() const);
00094
00095 private:
00096 static SignalMapMap _signalMap;
00097 };
00098
00099 template<class A>
00100 class SignalSender<A, void>
00101 {
00102 private:
00103 typedef std::list<std::pair<void (A:: *)() const, Signal *> > SignalMap;
00104 typedef std::map<A *, SignalMap> SignalMapMap;
00105
00106 public:
00107 template<class B>
00108 static void connect(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)());
00109
00110 template<class B>
00111 static void disconnect(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)());
00112
00113 static void send(A *a, void (A:: *getPtr)() const);
00114
00115 private:
00116 static SignalMapMap _signalMap;
00117 };
00118
00121
00122 template<class A, class B, class T>
00123 class TSignal : public Signal
00124 {
00125 template<class X, class Y> friend class SignalSender;
00126 public:
00127 TSignal(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t));
00128
00129 void transmit();
00130
00131 private:
00132 A *_a;
00133 T (A:: *_getPtr)() const;
00134 B *_b;
00135 void (B:: *_setPtr)(T t);
00136 };
00137
00138 template<class A, class B>
00139 class TSignal<A, B, void> : public Signal
00140 {
00141 template<class X, class Y> friend class SignalSender;
00142 public:
00143 TSignal(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)());
00144
00145 void transmit();
00146
00147 private:
00148 A *_a;
00149 void (A:: *_getPtr)() const;
00150 B *_b;
00151 void (B:: *_setPtr)();
00152 };
00153
00154
00155 template<class A, class T>
00156 template<class B>
00157 void SignalSender<A, T>::connect(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t))
00158 {
00159 Signal *r = new TSignal<A, B, T>(a, getPtr, b, setPtr);
00160 _signalMap[a].push_back(std::pair<void (A:: *)() const, Signal *>(reinterpret_cast<void (A:: *)() const>(getPtr), r));
00161 }
00162
00163 template<class A, class T>
00164 template<class B>
00165 void SignalSender<A, T>::disconnect(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t))
00166 {
00167 for (typename SignalMap::iterator it = _signalMap[a].begin(); it != _signalMap[a].end(); ++it)
00168 {
00169 if ((*it).first == reinterpret_cast<void (A:: *)() const>(getPtr))
00170 {
00171 TSignal<A, B, T> *tr = dynamic_cast<TSignal<A, B, T> *>((*it).second);
00172
00173 if ((tr != 0)
00174 && (b == tr->_b)
00175 && (setPtr == tr->_setPtr))
00176 {
00177 _signalMap[a].erase(it);
00178 delete tr;
00179 if (_signalMap[a].empty())
00180 _signalMap.erase(a);
00181 return;
00182 }
00183 }
00184 }
00185 }
00186
00187 template<class A, class T>
00188 void SignalSender<A, T>::send(A *a, T (A:: *getPtr)() const)
00189 {
00190
00191 for (typename SignalMap::iterator it = _signalMap[a].begin(); it != _signalMap[a].end(); ++it)
00192 {
00193 if ((*it).first == reinterpret_cast<void (A:: *)() const>(getPtr))
00194 (*it).second->transmit();
00195 }
00196 }
00197
00198 template<class A>
00199 template<class B>
00200 void SignalSender<A, void>::connect(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)())
00201 {
00202 Signal *r = new TSignal<A, B, void>(a, getPtr, b, setPtr);
00203 _signalMap[a].push_back(std::pair<void (A:: *)() const, Signal *>(reinterpret_cast<void (A:: *)() const>(getPtr), r));
00204 }
00205
00206 template<class A>
00207 template<class B>
00208 void SignalSender<A, void>::disconnect(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)())
00209 {
00210 for (typename SignalMap::iterator it = _signalMap[a].begin(); it != _signalMap[a].end(); ++it)
00211 {
00212 if ((*it).first == reinterpret_cast<void (A:: *)() const>(getPtr))
00213 {
00214 TSignal<A, B, void> *tr = dynamic_cast<TSignal<A, B, void> *>((*it).second);
00215
00216 if ((tr != 0)
00217 && (b == tr->_b)
00218 && (setPtr == tr->_setPtr))
00219 {
00220 _signalMap[a].erase(it);
00221 delete tr;
00222 if (_signalMap[a].empty())
00223 _signalMap.erase(a);
00224 return;
00225 }
00226 }
00227 }
00228 }
00229
00230 template<class A>
00231 void SignalSender<A, void>::send(A *a, void (A:: *getPtr)() const)
00232 {
00233
00234 for (typename SignalMap::iterator it = _signalMap[a].begin(); it != _signalMap[a].end(); ++it)
00235 {
00236 if ((*it).first == reinterpret_cast<void (A:: *)() const>(getPtr))
00237 (*it).second->transmit();
00238 }
00239 }
00240
00241 template<class A, class T>
00242 typename SignalSender<A, T>::SignalMapMap SignalSender<A, T>::_signalMap;
00243
00244 template<class A>
00245 typename SignalSender<A, void>::SignalMapMap SignalSender<A, void>::_signalMap;
00246
00249
00250 template<class A, class B, class T>
00251 TSignal<A, B, T>::TSignal(A *a, T (A:: *getPtr)() const, B *b, void (B:: *setPtr)(T t))
00252 : _a(a), _getPtr(getPtr), _b(b), _setPtr(setPtr)
00253 {
00254 }
00255
00256 template<class A, class B, class T>
00257 void TSignal<A, B, T>::transmit()
00258 {
00259
00260 (_b->*_setPtr)((_a->*_getPtr)());
00261 }
00262
00263 template<class A, class B>
00264 TSignal<A, B, void>::TSignal(A *a, void (A:: *getPtr)() const, B *b, void (B:: *setPtr)())
00265 : _a(a), _getPtr(getPtr), _b(b), _setPtr(setPtr)
00266 {
00267 }
00268
00269 template<class A, class B>
00270 void TSignal<A, B, void>::transmit()
00271 {
00272
00273 (_a->*_getPtr)();
00274 (_b->*_setPtr)();
00275 }
00276
00277 #endif
00278
00279 }
00280
00281 #endif
00282