00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _CALLBACK_H
00019 #define _CALLBACK_H
00020
00021 namespace freesecs
00022 {
00029 class callback_t
00030 {
00031 private:
00032 class callback_base_t
00033 {
00034 public:
00035 virtual ~callback_base_t(){};
00036 virtual callback_base_t *clone() = 0;
00037 virtual int operator ()() = 0;
00038 };
00039
00040 template<class T>
00041 class callback_impl_t : public callback_base_t
00042 {
00043 public:
00044 typedef int (T::*F)();
00045
00046 T *p_this;
00047 F p_func;
00048
00049 callback_impl_t(T *pthis, F pfunc)
00050 {
00051 p_this = pthis;
00052 p_func = pfunc;
00053 }
00054
00055 callback_impl_t<T> & operator = (const callback_impl_t& cb)
00056 {
00057 p_this = cb.p_this;
00058 p_func = cb.p_func;
00059
00060 return *this;
00061 }
00062
00063 callback_impl_t<T> *clone()
00064 {
00065 return new callback_impl_t<T>(p_this, p_func);
00066 }
00067
00068 int operator()()
00069 {
00070 return (p_this->*p_func)();
00071 }
00072 };
00073
00074 callback_base_t *base;
00075
00076 public:
00077 virtual int operator()()
00078 {
00079 if(base)
00080 {
00081 return (*base)();
00082 }
00083 return -1;
00084 }
00085
00086 callback_t(const callback_t &cb)
00087 {
00088 base = cb.base->clone();
00089 }
00090
00091 virtual ~callback_t()
00092 {
00093 if(base)
00094 {
00095 delete base;
00096 }
00097 };
00098
00099 callback_t &operator = (const callback_t& cb)
00100 {
00101 if(base)
00102 {
00103 delete base;
00104 }
00105 base = cb.base->clone();
00106 return *this;
00107 }
00108
00109 callback_t():base(NULL){}
00110
00111 template<class T>
00112 callback_t(T *pclass, int (T::*pfunc)())
00113 {
00114 base = new callback_impl_t<T>(pclass, pfunc);
00115 }
00116
00117 template<class T>
00118 bool operator == (const callback_t &other)
00119 {
00120 callback_impl_t<T> *base_impl = (callback_impl_t<T>*)base;
00121 callback_impl_t<T> *other_base_impl = (callback_impl_t<T>*)other.base;
00122 return base_impl->p_this == other_base_impl->p_this
00123 && base_impl->p_func == other_base_impl->p_func;
00124 }
00125 };
00126
00133 template<class Arg>
00134 class callback_1arg_t
00135 {
00136 private:
00137 class callback_1arg_base_t
00138 {
00139 public:
00140 virtual ~callback_1arg_base_t(){};
00141 virtual callback_1arg_base_t *clone() = 0;
00142 virtual int operator ()(const Arg&) = 0;
00143 };
00144
00145 template<class T>
00146 class callback_1arg_impl_t : public callback_1arg_base_t
00147 {
00148 public:
00149 typedef int (T::*F)(const Arg&);
00150
00151 T *p_this;
00152 F p_func;
00153
00154 callback_1arg_impl_t(T *pthis, F pfunc)
00155 {
00156 p_this = pthis;
00157 p_func = pfunc;
00158 }
00159
00160 virtual ~callback_1arg_impl_t(){}
00161
00162 callback_1arg_impl_t<T> & operator = (const callback_1arg_impl_t& cb)
00163 {
00164 p_this = cb.p_this;
00165 p_func = cb.p_func;
00166
00167 return *this;
00168 }
00169
00170 callback_1arg_impl_t<T> *clone()
00171 {
00172 return new callback_1arg_impl_t<T>(p_this, p_func);
00173 }
00174
00175 int operator()(const Arg &a)
00176 {
00177 return (p_this->*p_func)(a);
00178 }
00179 };
00180
00181 callback_1arg_base_t *base;
00182
00183 public:
00184
00185 virtual int operator()(const Arg &a)
00186 {
00187 if(base)
00188 {
00189 return (*base)(a);
00190 }
00191 return -1;
00192 }
00193
00194 callback_1arg_t(const callback_1arg_t &cb)
00195 {
00196 base = cb.base->clone();
00197 }
00198
00199 virtual ~callback_1arg_t()
00200 {
00201 if(base)
00202 {
00203 delete base;
00204 }
00205 }
00206
00207 callback_1arg_t &operator = (const callback_1arg_t& cb)
00208 {
00209 if(base)
00210 {
00211 delete base;
00212 }
00213 base = cb.base->clone();
00214 return *this;
00215 }
00216
00217 callback_1arg_t():base(NULL){}
00218
00219 template<class T>
00220 callback_1arg_t(T *pclass, int (T::*pfunc)(const Arg&))
00221 {
00222 base = new callback_1arg_impl_t<T>(pclass, pfunc);
00223 }
00224
00225 template<class T>
00226 bool operator == (const callback_1arg_t &other)
00227 {
00228 callback_1arg_impl_t<T> *base_impl = (callback_1arg_impl_t<T>*)base;
00229 callback_1arg_impl_t<T> *other_base_impl = (callback_1arg_impl_t<T>*)other.base;
00230 return base_impl->p_this == other_base_impl->p_this
00231 && base_impl->p_func == other_base_impl->p_func;
00232 }
00233 };
00234
00235 }
00236
00237 #endif//_CALLBACK_H