00001
00002 #ifndef INCLUDED_CallbackThread_h_
00003 #define INCLUDED_CallbackThread_h_
00004
00005 #include "PollThread.h"
00006
00007
00008
00009
00010
00011 class CallbackThread : public Thread {
00012 public:
00013
00014 template<typename F>
00015 CallbackThread(const F& cb, bool autoStart=false) : Thread(), fun(new FunctorInstance<F,void>(cb)) { if(autoStart) start(); }
00016
00017
00018 template<typename F, typename C>
00019 CallbackThread(const F& cb, C& userdata, bool autoStart=false) : Thread(), fun(new FunctorInstance<F,C>(cb,userdata)) { if(autoStart) start(); }
00020
00021
00022 template<typename F, typename C>
00023 CallbackThread(const F& cb, const C& userdata, bool autoStart=false) : Thread(), fun(new FunctorInstance<F,C>(cb,userdata)) { if(autoStart) start(); }
00024
00025
00026 ~CallbackThread() { delete fun; fun=NULL; }
00027
00028 protected:
00029
00030
00031
00032
00033 struct FunctorAdapter {
00034 virtual ~FunctorAdapter() {}
00035 virtual void* operator()()=0;
00036 };
00037
00038
00039 template<typename F, typename C> struct FunctorInstance : public FunctorAdapter {
00040 FunctorInstance(const F& cb, const C& x) : fun(cb), data(x) {}
00041 virtual void* operator()() { fun(data); return NULL; }
00042 F fun;
00043 C data;
00044 private:
00045 FunctorInstance(const FunctorInstance&);
00046 FunctorInstance& operator=(const FunctorInstance&);
00047 };
00048
00049
00050 template<typename R, class C, class SUB> struct FunctorInstance<R (C::*)(),SUB> : public FunctorAdapter {
00051 FunctorInstance(R (C::*cb)(), SUB& x) : fun(cb), cl(x) {}
00052 virtual void* operator()() { (cl.*fun)(); return NULL; }
00053 R (C::*fun)();
00054 SUB& cl;
00055 };
00056
00057 template<typename R, class C, class SUB> struct FunctorInstance<R (C::*)() const,SUB> : public FunctorAdapter {
00058 FunctorInstance(R (C::*cb)() const, const SUB& x) : fun(cb), cl(x) {}
00059 virtual void* operator()() { (cl.*fun)(); return NULL; }
00060 R (C::*fun)() const;
00061 const SUB& cl;
00062 };
00063
00064 template<typename R> struct FunctorInstance<R (*)(),void> : public FunctorAdapter {
00065 FunctorInstance(R (*cb)()) : fun(cb) {}
00066 virtual void* operator()() { fun(); return NULL; }
00067 R (*fun)();
00068 };
00069
00070
00071 template<typename R, class C, class SUB> struct FunctorInstance<R* (C::*)(),SUB> : public FunctorAdapter {
00072 FunctorInstance(R* (C::*cb)(), SUB& x) : fun(cb), cl(x) {}
00073 virtual void* operator()() { return (cl.*fun)(); }
00074 R* (C::*fun)();
00075 SUB& cl;
00076 };
00077
00078 template<typename R, class C, class SUB> struct FunctorInstance<R* (C::*)() const,SUB> : public FunctorAdapter {
00079 FunctorInstance(R* (C::*cb)() const, const SUB& x) : fun(cb), cl(x) {}
00080 virtual void* operator()() { return (cl.*fun)(); }
00081 R* (C::*fun)() const;
00082 const SUB& cl;
00083 };
00084
00085 template<typename R> struct FunctorInstance<R* (*)(),void> : public FunctorAdapter {
00086 FunctorInstance(R* (*cb)()) : fun(cb) {}
00087 virtual void* operator()() { return fun(); }
00088 R* (*fun)();
00089 };
00090
00091
00092
00093 virtual void* run() {
00094 testCancel();
00095 return (*fun)();
00096 }
00097 FunctorAdapter * fun;
00098
00099 private:
00100 CallbackThread(const CallbackThread&);
00101 CallbackThread& operator=(const CallbackThread&);
00102 };
00103
00104
00105
00106
00107
00108
00109 class CallbackPollThread : public PollThread {
00110 public:
00111 enum ReturnHandle_t {
00112 IGNORE_RETURN,
00113 STOP_FALSE,
00114 STOP_TRUE
00115 };
00116
00117
00118 template<typename F>
00119 CallbackPollThread(const F& cb, const TimeET& initial, const TimeET& freq, bool countPollTime, ReturnHandle_t stopCond, bool autoStart=false)
00120 : PollThread(initial,freq,countPollTime), fun(NULL) {
00121 switch(stopCond) {
00122 case IGNORE_RETURN: fun=new FunctorInstance<F,void,IGNORE_RETURN>(cb); break;
00123 case STOP_FALSE: fun=new FunctorInstance<F,void,STOP_FALSE>(cb); break;
00124 case STOP_TRUE: fun=new FunctorInstance<F,void,STOP_TRUE>(cb); break;
00125 }
00126 if(autoStart)
00127 start();
00128 }
00129
00130
00131 template<typename F, typename C>
00132 CallbackPollThread(const F& cb, C& userdata, const TimeET& initial, const TimeET& freq, bool countPollTime, ReturnHandle_t stopCond, bool autoStart=false)
00133 : PollThread(initial,freq,countPollTime), fun(NULL) {
00134 switch(stopCond) {
00135 case IGNORE_RETURN: fun=new FunctorInstance<F,C,IGNORE_RETURN>(cb,userdata); break;
00136 case STOP_FALSE: fun=new FunctorInstance<F,C,STOP_FALSE>(cb,userdata); break;
00137 case STOP_TRUE: fun=new FunctorInstance<F,C,STOP_TRUE>(cb,userdata); break;
00138 }
00139 if(autoStart)
00140 start();
00141 }
00142
00143
00144 template<typename F, typename C>
00145 CallbackPollThread(const F& cb, const C& userdata, const TimeET& initial, const TimeET& freq, bool countPollTime, ReturnHandle_t stopCond, bool autoStart=false)
00146 : PollThread(initial,freq,countPollTime), fun(NULL) {
00147 switch(stopCond) {
00148 case IGNORE_RETURN: fun=new FunctorInstance<F,C,IGNORE_RETURN>(cb,userdata); break;
00149 case STOP_FALSE: fun=new FunctorInstance<F,C,STOP_FALSE>(cb,userdata); break;
00150 case STOP_TRUE: fun=new FunctorInstance<F,C,STOP_TRUE>(cb,userdata); break;
00151 }
00152 if(autoStart)
00153 start();
00154 }
00155
00156 ~CallbackPollThread() { delete fun; fun=NULL; }
00157
00158
00159 void resetPeriod(const TimeET& p, bool immediate=true) { period=p; if(immediate && isRunning()) { delay=p; interrupt(); } }
00160
00161 protected:
00162
00163
00164
00165
00166 struct FunctorAdapter {
00167 virtual ~FunctorAdapter() {}
00168 virtual bool operator()()=0;
00169 };
00170
00171
00172 template<typename F, typename C, ReturnHandle_t USE_RETURN> struct FunctorInstance : public FunctorAdapter {
00173 FunctorInstance(const F& cb, const C& x) : fun(cb), data(x) {}
00174 virtual bool operator()() {
00175 #ifdef DEBUG
00176 if(USE_RETURN==IGNORE_RETURN) std::cout << "CallbackPollThread should be ignoring return value, but is not" << std::endl;
00177 #endif
00178 return (fun(data)) ? (USE_RETURN==STOP_FALSE) : (USE_RETURN==STOP_TRUE);
00179 }
00180 F fun;
00181 C data;
00182 private:
00183 FunctorInstance(const FunctorInstance&);
00184 FunctorInstance& operator=(const FunctorInstance&);
00185 };
00186
00187 template<typename R, class C, class SUB, ReturnHandle_t USE_RETURN> struct FunctorInstance<R (C::*)(),SUB,USE_RETURN> : public FunctorAdapter {
00188 FunctorInstance(R (C::*cb)(), SUB& x) : fun(cb), cl(x) {}
00189 virtual bool operator()() {
00190 #ifdef DEBUG
00191 if(USE_RETURN==IGNORE_RETURN) std::cout << "CallbackPollThread should be ignoring return value, but is not" << std::endl;
00192 #endif
00193 return ((cl.*fun)()) ? (USE_RETURN==STOP_FALSE) : (USE_RETURN==STOP_TRUE);
00194 }
00195 R (C::*fun)();
00196 SUB& cl;
00197 };
00198
00199 template<typename R, class C, class SUB, ReturnHandle_t USE_RETURN> struct FunctorInstance<R (C::*)() const,SUB,USE_RETURN> : public FunctorAdapter {
00200 FunctorInstance(R (C::*cb)() const, const SUB& x) : fun(cb), cl(x) {}
00201 virtual bool operator()() {
00202 #ifdef DEBUG
00203 if(USE_RETURN==IGNORE_RETURN) std::cout << "CallbackPollThread should be ignoring return value, but is not" << std::endl;
00204 #endif
00205 return ((cl.*fun)()) ? (USE_RETURN==STOP_FALSE) : (USE_RETURN==STOP_TRUE);
00206 }
00207 R (C::*fun)() const;
00208 const SUB& cl;
00209 };
00210
00211 template<typename R, ReturnHandle_t USE_RETURN> struct FunctorInstance<R (*)(),void,USE_RETURN> : public FunctorAdapter {
00212 FunctorInstance(R (*cb)()) : fun(cb) {}
00213 virtual bool operator()() {
00214 #ifdef DEBUG
00215 if(USE_RETURN==IGNORE_RETURN) std::cout << "CallbackPollThread should be ignoring return value, but is not" << std::endl;
00216 #endif
00217 return (fun()) ? (USE_RETURN==STOP_FALSE) : (USE_RETURN==STOP_TRUE);
00218 }
00219 R (*fun)();
00220 };
00221
00222
00223 template<typename F, typename C> struct FunctorInstance<F,C,IGNORE_RETURN> : public FunctorAdapter {
00224 FunctorInstance(const F& cb, const C& x) : fun(cb), data(x) {}
00225 virtual bool operator()() { fun(data); return true; }
00226 F fun;
00227 C data;
00228 private:
00229 FunctorInstance(const FunctorInstance&);
00230 FunctorInstance& operator=(const FunctorInstance&);
00231 };
00232
00233 template<typename R, class C, class SUB> struct FunctorInstance<R (C::*)(),SUB,IGNORE_RETURN> : public FunctorAdapter {
00234 FunctorInstance(R (C::*cb)(), SUB& x) : fun(cb), cl(x) {}
00235 virtual bool operator()() { (cl.*fun)(); return true; }
00236 R (C::*fun)();
00237 SUB& cl;
00238 };
00239
00240 template<typename R, class C, class SUB> struct FunctorInstance<R (C::*)() const,SUB,IGNORE_RETURN> : public FunctorAdapter {
00241 FunctorInstance(R (C::*cb)() const, const SUB& x) : fun(cb), cl(x) {}
00242 virtual bool operator()() { (cl.*fun)(); return true; }
00243 R (C::*fun)() const;
00244 const SUB& cl;
00245 };
00246
00247 template<typename R> struct FunctorInstance<R (*)(),void,IGNORE_RETURN> : public FunctorAdapter {
00248 FunctorInstance(R (*cb)()) : fun(cb) {}
00249 virtual bool operator()() { fun(); return true; }
00250 R (*fun)();
00251 };
00252
00253
00254
00255 virtual bool poll() { return (*fun)(); }
00256
00257 FunctorAdapter* fun;
00258
00259 private:
00260 CallbackPollThread(const CallbackPollThread&);
00261 CallbackPollThread& operator=(const CallbackPollThread&);
00262 };
00263
00264
00265
00266
00267
00268
00269 #endif