00001
00002
00003
00004
00005
00006 #ifndef __WVCALLBACK_H
00007 #define __WVCALLBACK_H
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 struct Fake { virtual void silly() {} };
00019
00020 template <class RET>
00021 class WvCallbackBase
00022 {
00023 protected:
00024 public:
00025
00026
00027
00028
00029 typedef RET (Fake::*FakeFunc)();
00030 typedef RET (*FakeGlobalFunc)();
00031
00032 Fake *obj;
00033
00034 union {
00035 FakeFunc func;
00036 FakeGlobalFunc globalfunc;
00037 };
00038
00039 WvCallbackBase(void *_obj, FakeFunc _func)
00040 : obj((Fake *)_obj), func(_func)
00041 { }
00042
00043 WvCallbackBase(FakeGlobalFunc _func)
00044 : obj(0), globalfunc(_func)
00045 { }
00046
00047 bool operator== (const WvCallbackBase &cb) const
00048 { if (obj)
00049 return obj==cb.obj && func==cb.func;
00050 else
00051 return !cb.obj && globalfunc == cb.globalfunc;
00052 }
00053
00054 operator bool () const
00055 { return obj || globalfunc; }
00056 };
00057
00058
00059
00060
00061
00062
00063 #define __MakeWvCallback(n, decls, parms) \
00064 class WvCallback##n : public WvCallbackBase<RET> \
00065 { \
00066 protected: \
00067 public: \
00068 typedef typename WvCallbackBase<RET>::FakeFunc FakeFunc; \
00069 typedef typename WvCallbackBase<RET>::FakeGlobalFunc FakeGlobalFunc; \
00070 typedef RET (Fake::*Func) decls; \
00071 typedef RET (*GlobalFunc) decls; \
00072 WvCallback##n(Fake *_obj, Func _func) \
00073 : WvCallbackBase<RET>(_obj, (FakeFunc)_func) { } \
00074 WvCallback##n(GlobalFunc _func) \
00075 : WvCallbackBase<RET>((FakeGlobalFunc)_func) { } \
00076 public: \
00077 RET operator() decls const \
00078 { \
00079 if (obj) \
00080 return ((*obj).*(Func)func) parms; \
00081 else \
00082 return ((GlobalFunc)globalfunc) parms; \
00083 } \
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093 #define __MakeWvBoundCallback(n, decls, basetype...) \
00094 class WvCallback##n##_bound : public basetype \
00095 { \
00096 public: \
00097 typedef typename basetype::Func Func; \
00098 typedef RET (T::*BoundFunc) decls; \
00099 WvCallback##n##_bound(T &_obj, BoundFunc _func) \
00100 : basetype((Fake *)&_obj, reinterpret_cast<Func>(_func)) { } \
00101 }
00102
00103
00104
00105
00106
00107
00108 template <class RET>
00109 __MakeWvCallback(0, (), ());
00110 template <class RET, class T>
00111 __MakeWvBoundCallback(0, (), WvCallback0<RET>);
00112
00113 template <class RET, class P1>
00114 __MakeWvCallback(1, (P1 p1), (p1));
00115 template <class RET, class T, class P1>
00116 __MakeWvBoundCallback(1, (P1 p1), WvCallback1<RET, P1>);
00117
00118 template <class RET, class P1, class P2>
00119 __MakeWvCallback(2, (P1 p1, P2 p2), (p1, p2));
00120 template <class RET, class T, class P1, class P2>
00121 __MakeWvBoundCallback(2, (P1 p1, P2 p2), WvCallback2<RET, P1, P2>);
00122
00123 template <class RET, class P1, class P2, class P3>
00124 __MakeWvCallback(3, (P1 p1, P2 p2, P3 p3), (p1, p2, p3));
00125 template <class RET, class T, class P1, class P2, class P3>
00126 __MakeWvBoundCallback(3, (P1 p1, P2 p2, P3 p3),
00127 WvCallback3<RET, P1, P2, P3>);
00128
00129 template <class RET, class P1, class P2, class P3, class P4>
00130 __MakeWvCallback(4, (P1 p1, P2 p2, P3 p3, P4 p4), (p1, p2, p3, p4));
00131 template <class RET, class T, class P1, class P2, class P3, class P4>
00132 __MakeWvBoundCallback(4, (P1 p1, P2 p2, P3 p3, P4 p4),
00133 WvCallback4<RET, P1, P2, P3, P4>);
00134
00135 template <class RET, class P1, class P2, class P3, class P4, class P5>
00136 __MakeWvCallback(5, (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5),
00137 (p1, p2, p3, p4, p5));
00138 template <class RET, class T, class P1, class P2, class P3, class P4, class P5>
00139 __MakeWvBoundCallback(5, (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5),
00140 WvCallback5<RET, P1, P2, P3, P4, P5>);
00141
00142 template <class RET, class P1, class P2, class P3, class P4, class P5, class P6>
00143 __MakeWvCallback(6, (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6),
00144 (p1, p2, p3, p4, p5, p6));
00145 template <class RET, class T, class P1, class P2, class P3, class P4, class P5,
00146 class P6>
00147 __MakeWvBoundCallback(6, (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6),
00148 WvCallback6<RET, P1, P2, P3, P4, P5, P6>);
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 #define DeclareWvCallback(n, ret, type, parms...) \
00169 typedef WvCallback##n<ret , ## parms> type; \
00170 \
00171 template <class T> \
00172 class type##_bound : public WvCallback##n##_bound<ret,T , ## parms> \
00173 { \
00174 public: \
00175 typedef typename \
00176 WvCallback##n##_bound<ret,T , ## parms>::BoundFunc BoundFunc; \
00177 type##_bound(T &_obj, BoundFunc _func) \
00178 : WvCallback##n##_bound<ret,T , ## parms>(_obj, _func) {} \
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 #define wvcallback(cbname, instance, func) \
00193 cbname##_bound<typeof(instance)>(instance, &func)
00194
00195
00196
00197
00198 DeclareWvCallback(0, void, VoidCallback);
00199
00200 #endif // __WVCALLBACK_H