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