Skip to main content

 

 class Entity{
public:
    Entity(unsigned int id):
    id_(id)
    {};
    void handleMessage(BaseMessage &message&message){
        for(auto element: components_){
            element.second->handleMessage>handleMessage(message);
        }
    }
    template<classtemplate<class T>T>
    void attachComponent(T *component){
        //Consider making safer in case someone tries to attach same component type twice
        components_[typeid(T).hash_code()] = component;
    }
    template<classtemplate<class T>T>
    void detachComponent(void){
        components_.erase(typeid(T).hash_code());
    }
    template<classtemplate<class T>T>
    T* getComponent(void)const{
        return *components_.find(typeid(T).hash_code());
    }
    unsigned int getInstanceID(void)const{
        return id_;
    }
private:
    unsigned int id_;
    std::map<size_tmap<size_t, BaseComponent*>BaseComponent*> components_;
};
 

 

 

 class BaseComponent{
public:
    virtual void handleMessage(BaseMessage &message&message){};
};
 

class BaseMessage{
public:
    virtual int getType(void) = 0;
};
 

 

 
template<classtemplate<class T>T>
handleMessage(T&T& message){};

 

My thought was to create an InputHandlerComponent which registers with the keyboard class to listen to specific key presses defined possibly in some file. For example, keyboard.register( player.getComponent<InputHandler>() , 'W') .

keyboard.register( player.getComponent<InputHandler>() , 'W')

 

 class Entity{
public:
    Entity(unsigned int id):
    id_(id)
    {};
    void handleMessage(BaseMessage &message){
        for(auto element: components_){
            element.second->handleMessage(message);
        }
    }
    template<class T>
    void attachComponent(T *component){
        //Consider making safer in case someone tries to attach same component type twice
        components_[typeid(T).hash_code()] = component;
    }
    template<class T>
    void detachComponent(void){
        components_.erase(typeid(T).hash_code());
    }
    template<class T>
    T* getComponent(void)const{
        return *components_.find(typeid(T).hash_code());
    }
    unsigned int getInstanceID(void)const{
        return id_;
    }
private:
    unsigned int id_;
    std::map<size_t, BaseComponent*> components_;
};
 

 

 

 class BaseComponent{
public:
    virtual void handleMessage(BaseMessage &message){};
};
 

class BaseMessage{
public:
    virtual int getType(void) = 0;
};
 

 

 
template<class T>
handleMessage(T& message){};

 

My thought was to create an InputHandlerComponent which registers with the keyboard class to listen to specific key presses defined possibly in some file. For example, keyboard.register( player.getComponent<InputHandler>() , 'W') .

class Entity{
public:
    Entity(unsigned int id):
    id_(id)
    {};
    void handleMessage(BaseMessage &message){
        for(auto element: components_){
            element.second->handleMessage(message);
        }
    }
    template<class T>
    void attachComponent(T *component){
        //Consider making safer in case someone tries to attach same component type twice
        components_[typeid(T).hash_code()] = component;
    }
    template<class T>
    void detachComponent(void){
        components_.erase(typeid(T).hash_code());
    }
    template<class T>
    T* getComponent(void)const{
        return *components_.find(typeid(T).hash_code());
    }
    unsigned int getInstanceID(void)const{
        return id_;
    }
private:
    unsigned int id_;
    std::map<size_t, BaseComponent*> components_;
};
class BaseComponent{
public:
    virtual void handleMessage(BaseMessage &message){};
};

class BaseMessage{
public:
    virtual int getType(void) = 0;
};
template<class T>
handleMessage(T& message){};

My thought was to create an InputHandlerComponent which registers with the keyboard class to listen to specific key presses defined possibly in some file. For example

keyboard.register( player.getComponent<InputHandler>() , 'W')
Tweeted twitter.com/#!/StackGameDev/status/291440210372333568
Source Link
Grieverheart
  • 1.2k
  • 3
  • 15
  • 26

Tips for Component Based Entity System message handling

I'm trying to implement a component-based entity system but am a bit confused on how I should handle the messaging. There are two problems I'd like to resolve so I can test the system. Below is the code I have so far,

The Entity class:



class Entity{
public:
    Entity(unsigned int id):
    id_(id)
    {};
    void handleMessage(BaseMessage &message){
        for(auto element: components_){
            element.second->handleMessage(message);
        }
    }
    template<class T>
    void attachComponent(T *component){
        //Consider making safer in case someone tries to attach same component type twice
        components_[typeid(T).hash_code()] = component;
    }
    template<class T>
    void detachComponent(void){
        components_.erase(typeid(T).hash_code());
    }
    template<class T>
    T* getComponent(void)const{
        return *components_.find(typeid(T).hash_code());
    }
    unsigned int getInstanceID(void)const{
        return id_;
    }
private:
    unsigned int id_;
    std::map<size_t, BaseComponent*> components_;
};


The Base Component and Message classes:



class BaseComponent{
public:
    virtual void handleMessage(BaseMessage &message){};
};


class BaseMessage{
public:
    virtual int getType(void) = 0;
};


##1. Message Type Handling ##

My first question is how I should handle the different (derived from BaseMessage) message types.

I have thought of two ways for handling the message types of the derived message types. One is to generate a hash (i.e. using FNV) from a string that names the message type and use that hash to determine the message type. So the handleMessage(BaseMessage &message) function, would first extract this hash from the message and then do a static_cast to the appropriate type.

The second method is to use a template as follows (similar to the attachComponent methods of the entity class),


template<class T>
handleMessage(T& message){};

and make specializations for each message type the specific component is going to make.

Are there any drawbacks using the second method? What about performance-wise, why don't I see this kind of use more often?

##2. Input Handling ##

My second question is what would be the optimal (in terms of latency and ease of use) way to handle input?

My thought was to create an InputHandlerComponent which registers with the keyboard class to listen to specific key presses defined possibly in some file. For example, keyboard.register( player.getComponent<InputHandler>() , 'W') .

I wish there was a more concise guide to component based systems but I guess there are many different ways to do the same things. I have more questions but I think it'd be wiser to first try implementing what I can.