arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

Callbacks.h

Go to the documentation of this file.
00001 //
00002 //------------------------------------------------------------------------
00003 //
00004 // File   : Callbacks.h
00005 // Author : Patrick McCormick (pat@acl.lanl.gov)
00006 //
00007 // $Date: 2003/08/01 04:27:06 $
00008 // $Revision: 1.4 $
00009 //
00010 //
00011 // This header contains some simple wrapper classes around function and
00012 // method pointers.  As it now stands, the code only supports functions 
00013 // and methods which don't return values and take a single void pointer
00014 // as an argument.  Note that the method (member function pointer) class
00015 // uses a template to correctly wrap a method.  The syntax for creating 
00016 // a Method object looks something like:
00017 //
00018 //    MyObjectType *obj = new MyObjectType;
00019 //    Method<MyObjectType> *my_method = 
00020 //      new Method<MyObjectType>(obj, MyObjectType::MyMethod);
00021 //
00022 // Both function and method objects make sure of an overloaded () 
00023 // operator which allows the function/method to be invoked. 
00024 //
00025 // These classes are built in support of active messages -- or any other
00026 // callback-like behavior that is required. 
00027 //
00028 // TODO: It would be nice to implement a flexible way to handler
00029 //       parameters other than the standard void * approach. 
00030 //
00031 // This code is based on the VIF (Visualization Interconnection Framework)
00032 // that helped to drive TRex -- back when there were such beasts... 
00033 // 
00034 //------------------------------------------------------------------------
00035 
00036 #ifndef _KOKO_CALLBACK_H_
00037 #define _KOKO_CALLBACK_H_
00038 
00039 class KokoBuffer;
00040 
00041 class Callback
00042 {
00043   public:
00044     inline Callback(void) {};
00045     inline Callback(const Callback &cb) {};
00046     inline ~Callback(void) {};
00047 
00048     // We can't have virutal constructors so we have to 
00049     // use the following method to pull it off.  Subclasses
00050     // will have to implement the detials...
00051     virtual Callback *clone(void) = 0;
00052 
00053     // Anything that is a true callback type will impement the 
00054     // () operator to support invocation. 
00055     virtual void operator()(KokoBuffer &databuf) const = 0;                                                     
00056 };
00057 
00058 
00059 class Function : public Callback
00060 {
00061   public:
00062 
00063     inline Function(const Function &fobj)
00064     {
00065       fp = fobj.fp;
00066     };
00067 
00068     inline Function(void (*funcp)(KokoBuffer &databuf))
00069     {
00070       fp = funcp;
00071     };
00072 
00073     inline ~Function(void)
00074     { 
00075       fp = 0; // For complete sanity, let's just make sure we can't do
00076     };        // something bad by mistake.  Odds of this are likely 
00077               // very slim but I've seen it happen... 
00078 
00079     inline virtual Callback *clone(void) 
00080     { return new Function(*this); };
00081 
00082     // Finally, we can get around to invoking the function.
00083     void operator()(KokoBuffer &databuf) const
00084     {
00085       if (fp) { // Check before we get carried away...
00086         (*fp)(databuf);
00087       }
00088     };
00089 
00090   protected:
00091     void (*fp)(KokoBuffer 
00092       &databuf); // Function pointer.
00093 };
00094 
00095 
00096 template <class ObjType>
00097 class Method : public Callback
00098 {
00099   public:
00100     
00101     inline Method(const Method &meth)
00102     {
00103       obj = meth.obj;
00104       mfp = meth.mfp;
00105     };
00106 
00107     inline Method(ObjType &inobj, void (ObjType::* meth)(KokoBuffer &databuf))
00108     {
00109       obj = &inobj;
00110       mfp = meth;
00111     };
00112 
00113     inline Method(ObjType *inobj, void (ObjType::* meth)(KokoBuffer &databuf))
00114     {
00115       obj = inobj;
00116       mfp = meth;
00117     };
00118 
00119     inline ~Method(void)
00120     {
00121       obj = 0;  // Once again for complete sanity, make sure we can't 
00122       mfp = 0;  // do something bad by mistake. 
00123     };
00124 
00125     inline virtual Callback *clone(void) 
00126     { return new Method(*this); };
00127 
00128 
00129     void operator()(KokoBuffer &databuf) const 
00130     {
00131       if (obj && mfp) { // Check before we get carried away...
00132         (obj->*mfp)(databuf);
00133       }
00134     };
00135 
00136   private:
00137     ObjType        *obj;
00138     void (ObjType::* mfp)(KokoBuffer &databuf);
00139 };
00140 
00141 #endif

Send questions, comments, and bug reports to:
jmk