All pastes #2124822 Raw Edit

Unnamed

public cpp v1 · immutable
#2124822 ·published 2012-03-06 14:12 UTC
rendered paste body
#include <iostream>template <typename rettype>class BaseCallbackConnection0{public:    BaseCallbackConnection0() {}    virtual rettype call() = 0;};template <typename rettype, typename arg1type>class BaseCallbackConnection1{public:    BaseCallbackConnection1() {}    virtual rettype call(arg1type arg) = 0;};template <class T, typename rettype>class CallbackConnection0 : public BaseCallbackConnection0<rettype>{public:    CallbackConnection0()        : BaseCallbackConnection0<rettype>()    {        m_obj = NULL;        m_fn = NULL;    }    CallbackConnection0(T *obj, rettype (T::*fn)())        : BaseCallbackConnection0<rettype>()    {        m_obj = obj;        m_fn = fn;    }    rettype call()    {        if (m_obj)            return (m_obj->*m_fn)();        return rettype();    }    T *m_obj;    rettype (T::*m_fn)();};template <class T, typename rettype, typename arg1type>class CallbackConnection1 : public BaseCallbackConnection1<rettype, arg1type>{public:    CallbackConnection1()        : BaseCallbackConnection1<rettype, arg1type>()    {        m_obj = NULL;        m_fn = NULL;    }    CallbackConnection1(T *obj, rettype (T::*fn)(arg1type))        : BaseCallbackConnection1<rettype, arg1type>()    {        m_obj = obj;        m_fn = fn;    }    rettype call(arg1type arg1)    {        if (m_obj)            return (m_obj->*m_fn)(arg1);        return rettype();    }    T *m_obj;    rettype (T::*m_fn)(arg1type);};template <typename rettype>class Connection0{public:    Connection0() { m_conn = 0; }    template <typename T>    void setCallback(T *obj, rettype (T::*fn)())    {        if (m_conn)            delete m_conn;        m_conn = new CallbackConnection0<T, rettype>(obj, fn);    }    rettype call()    {        if (m_conn)            return m_conn->call();        return rettype();    }    BaseCallbackConnection0<rettype> *m_conn;};template <typename rettype, typename arg1type>class Connection1{public:    Connection1() { m_conn = 0; }    template <typename T>    void setCallback(T *obj, rettype (T::*fn)(arg1type))    {        if (m_conn)            delete m_conn;        m_conn = new CallbackConnection1<T, rettype, arg1type>(obj, fn);    }    rettype call(arg1type arg)    {        if (m_conn)            return m_conn->call(arg);        return rettype();    }    BaseCallbackConnection1<rettype, arg1type> *m_conn;};class BaseFoo{public:    BaseFoo() {}    void callFoo()    {        fooFn.call();    }    void callFoo1(int bar)    {        foo1Fn.call(bar);    }    int callFoo2(int bar)    {        return foo2Fn.call(bar);    }    template <class T>    void setImplementation(T *obj)    {        fooFn.setCallback(obj, &T::doFoo);        foo1Fn.setCallback(obj, &T::doFoo1);        foo2Fn.setCallback(obj, &T::doFoo2);    }    Connection0<void> fooFn;    Connection1<void, int> foo1Fn;    Connection1<int, int> foo2Fn;};class BaseFooBarInterface{public:    BaseFooBarInterface() {}    void callFooBar(int *bar)    {        fooBarFn.call(bar);    }    template <class T>    void setImplementation(T *obj)    {        fooBarFn.setCallback(obj, &T::doFooBar);    }    Connection1<void, int*> fooBarFn;};class FooImpl : public BaseFoo, public BaseFooBarInterface{public:    FooImpl()        : BaseFoo(), BaseFooBarInterface()    {        /* either use convenience methods to auto connect this to all "slots"         * using pre defined method names */        BaseFoo::setImplementation(this);        BaseFooBarInterface::setImplementation(this);        /* ... or specify slots manually with whatever name comes to mind */        //fooFn.setCallback(this, &FooImpl::doFoo);        //foo1Fn.setCallback(this, &FooImpl::doFoo1);        //foo2Fn.setCallback(this, &FooImpl::doFoo2);        //fooBarFn.setCallback(this, &FooImpl::doFooBar);    }    void doFoo() { std::cout << "FooImpl::doFoo called" << std::endl; }    void doFoo1(int bar) { std::cout << "FooImpl::doFoo1 called with arg=" << bar << std::endl; }    int doFoo2(int bar) { std::cout << "FooImpl::doFoo2 called with arg=" << bar << std::endl; return bar; }    void doFooBar(int *barOut) { std::cout << "FooImpl::doFooBar called" << std::endl; if (barOut) *barOut = 0xff; }};int main(int argc, char **argv){    FooImpl impl;    impl.callFoo();    impl.callFoo1(1);    std::cout << "doFoo2 return=" << impl.callFoo2(2) << std::endl;    int bar;    impl.callFooBar(&bar);    std::cout << "doFooBar return=" << bar << std::endl;    return 0;}