Callbacks in C++
factor template
//----------------------------------------
// l i b r a r y c o d e
//----------------------------------------
#include <string.h> //for memcpy, memcmp
class CallbackData
{
public:
typedef void (CallbackData::*PMEMFUNC)();
CallbackData(const void* pClient_, const void* ppMemfunc_):
_pClient(pClient_)
{memcpy(_ppMemfunc,ppMemfunc_,sizeof(PMEMFUNC));}
const void* pClient() const {return _pClient;}
const void* ppMemfunc() const {return _ppMemfunc;}
private:
char _ppMemfunc[sizeof(PMEMFUNC)];
const void* _pClient;
};
//----------------------------------------
template <class P1>
class Callback1Base
{
public:
virtual void operator()(P1) const = 0;
virtual Callback1Base<P1>* clone() const = 0;
protected:
Callback1Base(const void* pClient_, const void* ppMemfunc_):
_data(pClient_,ppMemfunc_)
{}
const CallbackData& data() const {return _data;}
private:
CallbackData _data;
};
//----------------------------------------
template <class P1, class Client, class PMemfunc>
class Callback1:
public Callback1Base<P1>
{
public:
Callback1(Client& client_, PMemfunc pMemfunc_):
Callback1Base<P1>(&client_,&pMemfunc_)
{}
/*virtual*/ void operator()(P1 parm_) const
{
Client* pClient = (Client*) data().pClient();
PMemfunc& pMemfunc = (*(PMemfunc*)(data().ppMemfunc()));
(pClient->*pMemfunc)(parm_);
}
/*virtual*/ Callback1<P1,Client,PMemfunc>* clone() const
{return new Callback1<P1,Client,PMemfunc>(*this);}
};
//----------------------------------------
template <class P1, class Client, class TRT, class CallType, class TP1>
inline Callback1<P1,Client,TRT(CallType::*)(TP1)>*
make_callback(Callback1Base<P1>*,
Client& client_,
TRT (CallType::* const& memFunc_)(TP1))
{
typedef TRT (CallType::*PMEMFUNC)(TP1);
return new Callback1<P1,Client,PMEMFUNC>(client_, memFunc_);
}
//----------------------------------------
template <class P1, class Client, class TRT, class CallType, class TP1>
inline Callback1<P1,Client,TRT(CallType::*)(TP1)const>*
make_callback(Callback1Base<P1>*,
Client& client_,
TRT (CallType::* const& memFunc_)(TP1) const)
{
typedef TRT (CallType::*PMEMFUNC)(TP1) const;
return new Callback1<P1,Callee,PMEMFUNC>(client_, memFunc_);
}
//----------------------------------------
class Button
{
public:
Button(Callback1Base<Button*>& callback_):
_pCallback(callback_.clone()){}
~Button() {delete _pCallback;}
void push() {(*_pCallback)(this);}
private:
Callback1Base<Button*>* _pCallback;
};
//----------------------------------------
// c l i e n t c o d e
//----------------------------------------
#include <iostream.h>
class CdPlayer
{
public:
void playButtonPushed(Button*) {cout << "PLAY" << endl;}
void stopButtonPushed(Button*) {cout << "STOP" << endl;}
};
//----------------------------------------
main()
{
CdPlayer aCdPlayer;
Callback1Base<Button*>* pPlayCallback =
make_callback
((Callback1Base<Button*>*)0, aCdPlayer, &CdPlayer::playButtonPushed);
Callback1Base<Button*>* pStopCallback =
make_callback
((Callback1Base<Button*>*)0, aCdPlayer, &CdPlayer::stopButtonPushed);
Button playButton(*pPlayCallback);
delete pPlayCallback;
Button stopButton(*pStopCallback);
delete pStopCallback;
playButton.push();
stopButton.push();
return 0;
};
[View/Add Comments]
Callbacks in C++
Copyright © 1996-2000 Paul Jakubik
Created: 26 July 1996. Last update: 26 November 2000.
pauljakubik@yahoo.com