Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm currently making an Entity System, using C++, and I've questioned myself about how I should interface some methods. Specifically in my Entity and ComponentManager classes.

The ComponentManager, manages all components for all entities in a specific world. It can add/remove/determine if a Component exists, etc. Now to retrieve a component, I was thinking of using a template function, that way it looks neater and it doesn't have as many casts (outside the method). But then I want quick access to components through an Entity object. e.g.

entity.getComponent<VelocityComponent>().x = 30;

(and yes I know an Entity is just an ID, that's why I have my components in the ComponentManager class, and each Entity is represented by an ID).

i.e.

ComponentManager's get function: (Components are stored as a 2d array, with the first element being the ID of an entity and the 2nd element being the ID of a component's class type)

template <typename Comp> // Comp = Component
Comp* getComponent(Entity& e)
{
    return (Comp*)_components[e.getId()][Comp::GetClass().getId()];
}

And the Entity's get function:

template <typename Comp>
Comp* getComponent() 
{
      return getWorld().getComponentManager().getComponent<Comp>(*this); 
}

So if I was to use template functions I would just have 2 duplicates of template functions. Now of course, this goes the same for adding components to an Entity. So basically, is it a good idea to wrap a template function with another template function?

I can, alternatively make the the methods in the Entity system templates and make the methods in the component managers non-template functions, i.e.

Component* ComponentManager::getComponent(Entity& e, const Component::Class& componentClassType) const
{
     return _components[e.getId()][componentClassType.getId()];         
}

I'm confused on what I should do.:

share|improve this question
2  
If you've solved your problem, post an answer to the question in the answers section below, don't update your question with the answer or the title with "solved". Thanks. –  Byte56 Dec 2 '12 at 15:49
add comment

1 Answer

up vote 1 down vote accepted

There's nothing wrong with calling a templated routine within another templated routine, but you may want to just have one function that will give you a component instance from an entity ID so the interface is small and consistent (why have two routines that do the same thing?)

It's probably worth noting though that it's not safe to do things like this:

entity.getComponent<VelocityComponent>().x = 30;

unless all entities are guaranteed to have an instance of all components. You probably want to design your interface so that users do something like this.

VelocityComponent* velocity = entity.getComponent<VelocityComponent>();
if(velocity)
{
    // only do the lookup once and make sure this component exists.
    velocity->x = 30;
}

The component lookup that you're using now is pretty fast, but you may need to change it in the future to avoid the (numEntities * numComponentTypes) storage requirement.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.