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

Generated on Thu Jun 3 10:12:09 2004 for X3DToolKit by doxygen 1.3.6