/* $Id: callback.h,v 1.6 2002/12/16 19:09:54 ksterker Exp $ (C) Copyright 2000 Joel Vennin Part of the Adonthell Project http://adonthell.linuxgames.com Special Thanks to Rich Hickey This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. See the COPYING file for more details */ #ifndef _CALL_BACK_H_ #define _CALL_BACK_H_ #include #include class FunctorBase { protected: typedef void (FunctorBase::*PMemFunc)(); typedef void (*PFunc)(); enum {MEM_FUNC_SIZE = sizeof(PMemFunc)}; union{ PFunc func; char memFunc[MEM_FUNC_SIZE]; }; void *callee; FunctorBase():func(0),callee(0){} FunctorBase(const void *c,PFunc f, const void *mf,size_t sz):callee((void *)c) { if(c) { memcpy(memFunc,mf,sz); if(sz class MemberTranslator0:public Functor0{ public: MemberTranslator0(Callee &c, MemFunc &m):Functor0(thunk,&c,0,&m,sizeof(MemFunc)){} static void thunk(const FunctorBase &ftor) { Callee *callee = (Callee *)ftor.getCallee(); MemFunc &memFunc = (*(MemFunc*)(void *)(ftor.getMemFunc())); (callee->*memFunc)(); } }; template class FunctionTranslator0:public Functor0{ public: FunctionTranslator0(Func f):Functor0(thunk,0,(PFunc)f,0,0){} static void thunk(const FunctorBase &ftor) { (Func(ftor.getFunc()))(); } }; template inline MemberTranslator0 makeFunctor(Callee &c,TRT (CallType::* f)()) { typedef TRT (CallType::*MemFunc)(); return MemberTranslator0(c,f); } template inline MemberTranslator0 makeFunctor(const Callee &c, TRT (CallType::* f)()const) { typedef TRT (CallType::*MemFunc)()const; return MemberTranslator0(c,f); } template inline FunctionTranslator0 makeFunctor(TRT (*f)()) { return FunctionTranslator0(f); } //NO ARG WITH RETURN template class Functor0wRet:public FunctorBase{ public: Functor0wRet(){} RT operator()()const { return thunk(*this); } protected: typedef RT (*Thunk)(const FunctorBase &); Functor0wRet(Thunk t,const void *c,PFunc f,const void *mf,size_t sz): FunctorBase(c,f,mf,sz),thunk(t){} private: Thunk thunk; }; template class MemberTranslator0wRet:public Functor0wRet{ public: MemberTranslator0wRet(Callee &c,MemFunc &m): Functor0wRet(thunk,&c,0,&m,sizeof(MemFunc)){} static RT thunk(const FunctorBase &ftor) { Callee *callee = (Callee *)ftor.getCallee(); MemFunc &memFunc = (*(MemFunc*)(void *)(ftor.getMemFunc())); return ((callee->*memFunc)()); } }; template class FunctionTranslator0wRet:public Functor0wRet{ public: FunctionTranslator0wRet(Func f):Functor0wRet(thunk,0,(typename FunctionTranslator0wRet::PFunc)f,0,0){} static RT thunk(const FunctorBase &ftor) { return (Func(ftor.getFunc()))(); } }; template inline MemberTranslator0wRet makeFunctor(Functor0wRet*,Callee &c,TRT (CallType::* f)()) { typedef TRT (CallType::*MemFunc)(); return MemberTranslator0wRet(c,f); } template inline MemberTranslator0wRet makeFunctor(Functor0wRet*,const Callee &c, TRT (CallType::* f)()const) { typedef TRT (CallType::*MemFunc)()const; return MemberTranslator0wRet(c,f); } template inline FunctionTranslator0wRet makeFunctor(Functor0wRet*,TRT (*f)()) { return FunctionTranslator0wRet(f); } // 1 Argument, no return value template class Functor1 : public FunctorBase { public: Functor1() {} void operator () (P1 p1) const { thunk (*this, p1); } protected: typedef void (*Thunk) (const FunctorBase &, P1); Functor1 (Thunk t, const void *c, PFunc f, const void *mf, size_t sz) : FunctorBase (c, f, mf, sz), thunk (t) { } private: Thunk thunk; }; template class MemberTranslator1 : public Functor1 { public: MemberTranslator1 (Callee & c, MemFunc & m) : Functor1 (thunk, &c, 0, &m, sizeof (MemFunc)) { } static void thunk (const FunctorBase & ftor, P1 p1) { Callee *callee = (Callee *) ftor.getCallee (); MemFunc & memFunc (*(MemFunc *) (void *)(ftor.getMemFunc ())); (callee->*memFunc) (p1); } }; template class FunctionTranslator1 : public Functor1 { public: FunctionTranslator1 (Func f) : Functor1 (thunk, 0, f, 0, 0) { } static void thunk (const FunctorBase & ftor, P1 p1) { (Func (ftor.func)) (p1); } }; template inline MemberTranslator1 makeFunctor (Callee & c, TRT (CallType::* f) (P1)) { typedef TRT (CallType::*MemFunc) (P1); return MemberTranslator1 (c, f); } template inline MemberTranslator1 makeFunctor (const Callee & c, TRT (CallType::*const &f) (TP1) const) { typedef TRT (CallType::*MemFunc) (TP1) const; return MemberTranslator1 (c, f); } template inline FunctionTranslator1 makeFunctor (TRT (*f) (TP1)) { return FunctionTranslator1 (f); } template class MemberOf1stArgTranslator1 : public Functor1 { public: MemberOf1stArgTranslator1 (MemFunc & m) : Functor1 < P1 > (thunk, (void *)1, 0, &m, sizeof (MemFunc)) { } static void thunk (const FunctorBase & ftor, P1 p1) { MemFunc & memFunc (*(MemFunc *) (void *)(ftor.memFunc)); (p1.*memFunc) (); } }; template inline MemberOf1stArgTranslator1 makeFunctor (TRT (CallType::* &f) ()) { typedef TRT (CallType::*MemFunc) (); return MemberOf1stArgTranslator1 (f); } template inline MemberOf1stArgTranslator1 < P1, TRT (CallType::*)() const> makeFunctor (TRT (CallType::*const &f) () const) { typedef TRT (CallType::*MemFunc) () const; return MemberOf1stArgTranslator1 (f); } #endif