Callbacks in C++


manual polymorphism

//----------------------------------------
// 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:
  void operator()(P1 p1_) const
  {_thunk(_data, p1_);}

protected:
  typedef void (*THUNK)(const CallbackData&, P1); 
  Callback1Base(THUNK thunk_, const void* pClient_, const void* ppMemfunc_):
    _thunk(thunk_),
    _data(pClient_,ppMemfunc_)
  {} 

private:
  CallbackData _data;
  THUNK _thunk;
};
//----------------------------------------
template <class P1, class Client, class PMemfunc>
class Callback1:
  public Callback1Base<P1>
{
public:
  Callback1(Client& client_, PMemfunc pMemfunc_):
    Callback1Base<P1>(thunk,&client_,&pMemfunc_)
  {}

private:
  static void thunk(const CallbackData& data_, P1 parm_)
  {
    Client* pClient = (Client*) data_.pClient();
    PMemfunc& pMemfunc = (*(PMemfunc*)(data_.ppMemfunc()));
    (pClient->*pMemfunc)(parm_);
  }
};
//----------------------------------------
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 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 Callback1<P1,Callee,PMEMFUNC>(client_, memFunc_);
}
//----------------------------------------
class Button
{
public:
  Button(const Callback1Base<Button*>& callback_):
    _callback(callback_)
  {}

  void push() {_callback(this);}
private:
  const Callback1Base<Button*> _callback;
};
//----------------------------------------
// 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;
  Button playButton
  (
    make_callback
    ((Callback1Base<Button*>*)0, aCdPlayer, &CdPlayer::playButtonPushed)
  );

  Button stopButton
  (
    make_callback
    ((Callback1Base<Button*>*)0, aCdPlayer, &CdPlayer::stopButtonPushed)
  );

  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