SimoneS93
SimoneS93

Reputation: 115

C++ - Polymorphic pointer to member functions

I'm not very good at C++ (but I'm familiar with OOP/Java), but I have to create a game for my C++ class. I want to setup a kind of game engine like that used for Flash games written in ActionScript.

I wrote this two classes, where Actor is meant as a base class (probably will be abstract) and Player should actually implement it.

The problem is that I want to avoid duplicate code in the functions addEventListener and handle and re-declaring _handlerMap, since I want to achieve data hiding and such things.

The problem, I guess, is that _eventMap should contain handler values that can change class Actor::*handler and Player::*handler. Is it possible?

    class Actor {
    protected:
        typedef void(Actor::*handler)(Event);
        map<int, handler> _handlerMap;
    public:
        virtual void addEventListener(int ID, handler h) {
            _handlerMap.insert(std::make_pair(ID, h));
        };
        virtual void handle(int ID) {
            handler h = _handlerMap[ID];
            Event e;
            if (h)
                (this->*h)(e);
        }
        virtual void onUpdate(Event e) {
            cout << "Actor::onUpdate()" << endl;
        };
    };

class Player : public Actor {
    typedef void(Player::*handler)(Event);
    map<int, handler> _handlerMap;
public:
    void addEventListener(int ID, handler h) {
        _handlerMap.insert(std::make_pair(ID, h));
    };
    void handle(int ID) {
        handler h = _handlerMap[ID];
        Event e;
        if (h)
            (this->*h)(e);
    }
    void onKeydown(Event e) {
        cout << "Player::onKeyDown()" << endl;
    };
};

I wish it was possible to declare Player as:

class Player : public Actor {
        typedef void(Player::*handler)(Event);
 public:
        void onWhateverEvent(Event e);
 }

I hope you understand.

Upvotes: 5

Views: 664

Answers (2)

SimoneS93
SimoneS93

Reputation: 115

What do you think of this? (Dispatcher is the same as DispatcherImpl above)

template <class T>
class Entity {
    T *_instance;
    Dispatcher<T> *_dispatcher;
public:
    Entity() {
        _instance = new T();
        _dispatcher = new Dispatcher<T>(_instance);
    }
};
class Actor {
    //attirbutes and methods
};
class Player : public Actor {
    //attirbutes and methods
};

To use it just:

Entity<Actor> *actor = new Entity<Actor>();
Entity<Player> *player = new Entity<Player>();
actor->getDispatcher()->addEventListener(0, &Actor::foo);
player->getDispatcher()->addEventListener(1, &Player::bar);
player->getDispatcher()->addEventListener(0, &Actor::foo); //inheritance

Upvotes: 0

n. m. could be an AI
n. m. could be an AI

Reputation: 120079

You need something like this (not tested):

class Dispatcher {
  public:
    virtual void dispatchEvent(Event*) = 0;
};

template <class C>
class DispatcherImpl : public Dispatcher
{
    typedef void(C::*handler)(Event* e);
    std::map<int, handler> _handlerMap;
    C* _owner;
  public:
    DispatcherImpl (C* c) : _owner(c) {}
    addEventListener(int ID, handler h) {
        _handlerMap.insert(std::make_pair(ID, h));
    }        
    void dispatchEvent(Event*)
    {
      handler h = handlerMap[e->id];
      if (h) (_owner->*h)(e);
    }
}

Now let each type T of actor own a DispatcherImpl<T>, and you are all set. You may also have e.g. Player inherit from DispatcherImpl<Player>.

Upvotes: 2

Related Questions