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
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
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
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
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
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
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
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
00265 (_a->*_getPtr)();
00266 (_b->*_setPtr)();
00267 }
00268
00269 #endif
00270
00271 }
00272
00273 #endif
00274