Signal.h

Go to the documentation of this file.
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     //std::cout << "connecting..." << std::endl;
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     //std::cout << "connecting..." << std::endl;
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     //std::cout << "disconnecting...";
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     //std::cout << "disconnecting...";
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   //std::cout << "sending..." << std::endl;      
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   //std::cout << "sending void..." << std::endl;    
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   //std::cout << "transmitting..." << std::endl;
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   //std::cout << "transmitting..." << std::endl;
00273   (_a->*_getPtr)();
00274   (_b->*_setPtr)();
00275 }
00276 
00277 #endif
00278 
00279 }
00280 
00281 #endif
00282 

Generated on Fri Aug 27 13:16:22 2004 for X3DToolKit by doxygen 1.3.6