Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

CallbackThread.h

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #ifndef INCLUDED_CallbackThread_h_
00003 #define INCLUDED_CallbackThread_h_
00004 
00005 #include "PollThread.h"
00006 
00007 //! A simple adapter to cause a callback under a new thread
00008 /*! The constructor is designed to take just about anything, with zero or one arguments.
00009  *  If the functor returns a pointer type, this will be passed as the result of the run()
00010  *  call, accessible via join() or getReturnValue(). */
00011 class CallbackThread : public Thread {
00012 public:
00013   //! constructor, pass zero-argument callback function
00014   template<typename F>
00015   CallbackThread(const F& cb, bool autoStart=false) : Thread(), fun(new FunctorInstance<F,void>(cb)) { if(autoStart) start(); }
00016   
00017   //! constructor, pass the user data and single argument callback function
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   //! constructor, pass the user data and single argument callback function
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   //! destructor
00026   ~CallbackThread() { delete fun; fun=NULL; }
00027   
00028 protected:
00029   /*! @cond INTERNAL */
00030 
00031   //! generic base case, supplies a functor interface with no arguments
00032   /*! (subclasses must store the arguments passed to CallbackThread constructor) */
00033   struct FunctorAdapter {
00034     virtual ~FunctorAdapter() {}
00035     virtual void* operator()()=0;
00036   };
00037   
00038   //! generic template instance, handles std::mem_fun_t and such class based functors (ignores return value)
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&); //!< don't call
00046     FunctorInstance& operator=(const FunctorInstance&); //!< don't call
00047   };
00048   
00049   //! partial specialization, handles non-const member functions (ignores return value)
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   //! partial specialization, handles const member functions (ignores return value)
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   //! partial specialization, handles zero-argument functors (ignores return value)
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   //! partial specialization, handles non-const member functions (pass through return value)
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   //! partial specialization, handles const member functions (pass through return value)
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   //! partial specialization, handles zero-argument member functions (pass through return value)
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   /*! @endcond */
00092 
00093   virtual void* run() {
00094     testCancel();
00095     return (*fun)();
00096   }
00097   FunctorAdapter * fun;
00098   
00099 private:
00100   CallbackThread(const CallbackThread&); //!< don't call
00101   CallbackThread& operator=(const CallbackThread&); //!< don't call
00102 };
00103 
00104 
00105 // A simple adapter to cause a periodic callback under a new thread
00106 /*! Templates specify the type of user data (C) and the type of the callback function (F).
00107  *  F defaults to take a std::mem_fun call on C, so that it is used with a class method, but
00108  *  you could just as well use a standard c-style static function. */
00109 class CallbackPollThread : public PollThread {
00110 public:
00111   enum ReturnHandle_t {
00112     IGNORE_RETURN,
00113     STOP_FALSE,
00114     STOP_TRUE
00115   };
00116   
00117   // constructor, pass the user data and callback function
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   // constructor, pass the user data and callback function
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   // constructor, pass the user data and callback function
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   //! sets the polling frequency to @a p, if @a immediate is set then it will call interrupt() so the period takes effect on the current cycle
00159   void resetPeriod(const TimeET& p, bool immediate=true) { period=p; if(immediate && isRunning()) { delay=p; interrupt(); } }
00160 
00161 protected:
00162   /*! @cond INTERNAL */
00163   
00164   //! generic base case, supplies a functor interface with no arguments
00165   /*! (subclasses must store the arguments passed to CallbackThread constructor) */
00166   struct FunctorAdapter {
00167     virtual ~FunctorAdapter() {}
00168     virtual bool operator()()=0;
00169   };
00170   
00171   //! generic template instance, handles std::mem_fun_t and such class based functors (pass through return value)
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&); //!< don't call
00184     FunctorInstance& operator=(const FunctorInstance&); //!< don't call
00185   };
00186   //! partial specialization, handles non-const member functions (pass through return value)
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   //! partial specialization, handles const member functions (pass through return value)
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   //! partial specialization, handles zero-argument functors (pass through return value)
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   //! partial specialization, handles std::mem_fun_t and such class based functors (ignores return value)
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&); //!< don't call
00230     FunctorInstance& operator=(const FunctorInstance&); //!< don't call
00231   };
00232   //! partial specialization, handles non-const member functions (ignores return value)
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   //! partial specialization, handles const member functions (ignores return value)
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   //! partial specialization, handles zero-argument member functions (ignores return value)
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   /*! @endcond */
00254   
00255   virtual bool poll() { return (*fun)(); }
00256 
00257   FunctorAdapter* fun; //!< function to be called from within new thread
00258 
00259 private:
00260   CallbackPollThread(const CallbackPollThread&); //!< don't call
00261   CallbackPollThread& operator=(const CallbackPollThread&); //!< don't call
00262 };
00263 
00264 /*! @file
00265  * @brief 
00266  * @author Ethan Tira-Thompson (ejt) (Creator)
00267  */
00268 
00269 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:36 2016 by Doxygen 1.6.3