Main Page | Modules | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members | Related Pages

Route.h

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

Generated on Wed Apr 7 12:15:20 2004 for X3DToolKit by doxygen 1.3.3