1
0
Fork 0

Bernie Bright:

- Major rewrite making it more member function friendly.
This commit is contained in:
curt 2002-04-25 20:31:38 +00:00
parent d15d3652b1
commit 7b69f0cbb4

View file

@ -22,169 +22,126 @@
#ifndef _FG_CALLBACK_HXX
#define _FG_CALLBACK_HXX
#include <stdlib.h>
// -dw- need size_t for params() function
#ifdef __MWERKS__
typedef unsigned long size_t;
#endif
//-----------------------------------------------------------------------------
//
// Abstract base class for all FlightGear callbacks.
//
/**
* Abstract base class for all FlightGear callbacks.
*/
class fgCallback
{
public:
/**
*
*/
virtual ~fgCallback() {}
/**
*
*/
virtual fgCallback* clone() const = 0;
virtual void* call( void** ) = 0;
size_t params() const { return n_params; }
/**
* Execute the callback function.
*/
virtual void operator()() = 0;
protected:
fgCallback( size_t params )
: n_params(params) {}
protected:
// The number of parameters to pass to the callback routine.
size_t n_params;
/**
*
*/
fgCallback() {}
private:
// Not implemented.
void operator=( const fgCallback& );
};
//-----------------------------------------------------------------------------
//
// Callback for invoking a file scope function.
//
/**
* Callback for invoking a file scope function.
*/
template< typename Fun >
class fgFunctionCallback : public fgCallback
{
public:
// Pointer to function taking no arguments and returning void.
typedef void (*Proc0v)();
/**
*
*/
fgFunctionCallback( const Fun& fun )
: fgCallback(), f_(fun) {}
// A callback instance to invoke the function 'p'
fgFunctionCallback( Proc0v p );
fgCallback* clone() const
{
return new fgFunctionCallback( *this );
}
// Create a clone on the heap.
virtual fgCallback* clone() const;
private:
void* call( void** in );
inline void* call0v( void** );
void operator()() { f_(); }
private:
// Not defined.
fgFunctionCallback();
private:
typedef void* (fgFunctionCallback::*DoPtr)( void** );
DoPtr doPtr;
Proc0v proc0v;
Fun f_;
};
inline
fgFunctionCallback::fgFunctionCallback( Proc0v p )
: fgCallback(0),
doPtr(&fgFunctionCallback::call0v),
proc0v(p)
{
// empty
}
inline fgCallback*
fgFunctionCallback::clone() const
{
return new fgFunctionCallback( *this );
}
inline void*
fgFunctionCallback::call( void** in )
{
return (this->*doPtr)( in );
}
inline void*
fgFunctionCallback::call0v( void** )
{
(*proc0v)();
return (void*) NULL;
}
//-----------------------------------------------------------------------------
//
// Callback for invoking a member function.
//
//template< typename Ret, class T >
template< class T >
/**
* Callback for invoking a member function.
*/
template< class ObjPtr, typename MemFn >
class fgMethodCallback : public fgCallback
{
public:
// Pointer to method taking no arguments and returning void.
typedef void (T::*Method0v)();
typedef void (T::*Method0vc)() const;
// A callback instance to invoke method 'm' of object 'o'
fgMethodCallback( T* o, Method0v m )
: fgCallback(0),
object(o),
method0v(m),
doPtr(&fgMethodCallback<T>::call0v) {}
/**
*
*/
fgMethodCallback( const ObjPtr& pObj, MemFn pMemFn )
: fgCallback(),
pObj_(pObj),
pMemFn_(pMemFn)
{
}
// A callback instance to invoke a const method 'm' of object 'o'
fgMethodCallback( T* o, Method0vc m )
: fgCallback(0),
object(o),
method0vc(m),
doPtr(&fgMethodCallback<T>::call0v) {}
/**
*
*/
fgCallback* clone() const
{
return new fgMethodCallback( *this );
}
// Create a clone on the heap.
fgCallback* clone() const;
private:
//
void* call( void** in );
//
void* call0v( void** );
/**
*
*/
void operator()()
{
((*pObj_).*pMemFn_)();
}
private:
// Not defined.
fgMethodCallback();
private:
T* object;
union {
Method0v method0v;
Method0vc method0vc;
};
// typedef void * (fgMethodCallback::*DoPtr)( void ** );
typedef void * (fgMethodCallback<T>::*DoPtr)( void ** );
DoPtr doPtr;
ObjPtr pObj_;
MemFn pMemFn_;
};
template< class T > inline fgCallback*
fgMethodCallback<T>::clone() const
/**
* Helper template functions.
*/
template< typename Fun >
fgCallback*
make_callback( const Fun& fun )
{
return new fgMethodCallback( *this );
return new fgFunctionCallback<Fun>(fun);
}
template< class T > inline void*
fgMethodCallback<T>::call( void** in )
template< class ObjPtr, typename MemFn >
fgCallback*
make_callback( const ObjPtr& pObj, MemFn pMemFn )
{
return (this->*doPtr)( in );
}
template< class T > inline void*
fgMethodCallback<T>::call0v( void** )
{
(object->*method0v)();
return (void*) NULL;
return new fgMethodCallback<ObjPtr,MemFn>(pObj, pMemFn );
}
#endif // _FG_CALLBACK_HXX