Classes and Inheritance Problem in Entity-Component Design.

Hello guys,
Me and my friend are trying to program a Entity Component system to get used to C++ and also to use it in our further projects. Below, you see that we have CEntity class which holds its Components in "std::unordered_map mComponents" and you see how we defined CComponents and inherited a InputComponent from it. In input component we have SetKey function which sets a variable inside.

We also defined System class which does its job in every period of time(every frame in game). Using query function in CEntity we find that there is a InputComponent in Entity and then using getComponentAdress we return the address of the component to a "CComponent* c". However, after that we cant use c->SetKey() function because it says "This function not defined for CComponet".

How should we solve this problem. What are the alternatives?

Thank you very much.

Oğuzhan D.
( Also I guess there are some design problems in terms of Entity-Component System implementation, ignore those for now :) )

CEntity.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CEntity
{
protected:
	unsigned int mID;
	std::unordered_map<std::string, CComponent*> mComponents;
public:
	CEntity(unsigned int);
	unsigned int getID();
	void addComponent(CComponent &c);
	void removeComponent(std::string);
	bool componentQuery(std::string);

	CComponent* getComponentAddress(std::string);
};


CComponent.h
1
2
3
4
5
6
7
class CComponent
{
protected:
	std::string mName;
public:
	std::string getName();
};


ComponentInput.h
1
2
3
4
5
6
7
8
9
class ComponentInput : public CComponent
{
protected:
	sf::Keyboard::Key pressedKey;
public:
	ComponentInput();
	void SetKey(sf::Keyboard::Key);
	sf::Keyboard::Key GetActiveKey();
};


SystemInput.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void SystemInput::Work()
{
	std::vector<CEntity*>::iterator it;
	for(it = mEntityCache.begin();it != mEntityCache.end();it++)
	{
		CEntity* entity = *it;
		if(entity->componentQuery("ComponentInput"))
		{
			CComponent* c = entity->getComponentAddress("ComponentInput");
			sf::Event event;
			sf::Window window;
			while (window.pollEvent(event))
			{
				if ((event.type == sf::Event::KeyPressed))
				{
					c->SetKey(event.key.code); // PROBLEM HERE
				}
			}
		}
	}
}
One solution would be to make CComponent an abstract class and define SetKey as a pure virtual function in CComponent. You may not want to do this if other classes derived from CComponet would not have a SetKey function or SetKey would make no sense in those other derived classes.

Another solution is to cast the CComponent pointer to a ComponentInput pointer, but to do this, you need to be sure that what CComponent really points to is an object of type ComponentInput. You do seem to have allowed for this by retrieving entity by name.

Second solution looks good to me. Thanks for the answer.

Oğuzhan D.
Topic archived. No new replies allowed.