Question

I am working on an input system. In this system, objects can register a function to be called when a certain key is pressed. However the methods that are registered are members to that object, so my register function has to look something like this:

void register(EventType type, Class* object, void (Class::*function)()){ //save this }

The issue is that it won't always be the same class registering a function, so this won't work. Is there anyway round this?

Was it helpful?

Solution

You could store std::function<void()> in the class where you register the callbacks, and then add a function template register member function:

struct Foo
{
  template <typename F>
  void register(EventType type, F&& fun)
  {
    // make an std::function<void()> from fun and store
  }
};

Then, you do the binding of Class instance and Class member function on the caller's side.

struct Bar { void bar() {} };
void foobar() { std::cout << "foobar!\n"; }

Foo f;
Bar b;
f.register(event1, std::bind(&Bar::bar, b)); // will call b.bar()
f.register(event2, foobar);                  // will call foobar()

OTHER TIPS

This is a way to do it without templates and function pointer. You have a observer (callback) class like this:

class MyCallback {
    public:
    virtual void run(int abc)
    {
        cout << "MyCallback::run(" << abc << ")" << endl;
    }
};

Then you instantiate your observer class with a parent class MyCallback:

class Test : public MyCallback
{
    public:
    void run(int abc)
    {
        MyCallback::run(abc);
    }
};

The class that calls all observers:

class Subject
{

    vector<MyCallback*> observers;

    public:

    void reg_observer(MyCallback* cb)
    {
        observers.push_back(cb);
    }

    void call_out(int abc)
    {
        vector<MyCallback*>::iterator it;
        for(it=observers.begin();it!=observers.end();it++)
        {
            (*it)->run(abc);
        }

    }

};

A test code:

void testcb()
{
    Test ttt;
    Subject s;

    s.reg_observer(&ttt);
    s.call_out(123);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top