Hello, so i'm designing a entity component based system for my engine (Based of Artemis design).
Most of the example code i watched, has static containers and static stuff. My question is, is that a good idea?, my design is an hybrid approach of both dynamic and static implementation since i can add and remove system from my plugins dynamic.
My current design is:
Component
-> isActive(), setActive(bool) [this is when the entity owner is sleeping]
-> isValid(), setInvalid() [When the entity owner removes the component or the entity is destroyed]
-> getId() [ID of the component class]
Componentable<T> : Component
-> static ID [This is for mapping]
-> Component::m_Id = typeid(T).hash_code() [Get ID of the class at compile time]
ComponentCollection<T>
-> addComponent, getComponents, disposeComponent [Store contiguous each component of the same type] for CPU cache.
ComponentManager (Map ComponentID To ComponentCollection)
-> addCollection<T> [Add a collection of components into a map]
-> getCollection<T> [Get a collection of components from a map]
ComponentHolder
-> addComponent<T>, getComponent<T>, hasComponent<T>, invalid(), removeComponent<T>
-> Holders contain a pointer to the components owned.
System<T>
-> Logic part of the component
-> Iterate over each component of the same type, those components invalidated will be removed from the collection, and those sleeping
will not be executed.
SystemManager
-> Contains every system registered
World
-> Contains a system manager and creates an entity (Component holder + ID)
How it works?
struct LifeManaComponent : Componentable<LifeManaComponent>
{
uint32_t m_Life, m_Mana;
};
struct DefenseComponent : Componentable<DefenseComponent>
{
uint32_t m_Defense, m_Attack, m_RecvDamage;
}
class AttackSystem : public System<LifeManaComponent, DefenseComponent>
{
void OnExecute(Entity & entity)
{
....
}
};
//////////////////////////////////////////////// Code /////////////////////////////////////////////////////////////////
World->AddComponentCollection<LifeManaComponent>();
World->AddComponentCollection<DefenseComponent>();
World->AddSystem<AttackSystem>();
auto & pHolder = World->CreateEntity();
pHolder.addComponent<LifeManaComponent>(30 /* Life */, 0 /* Mana */);
pHolder.addComponent<DefenseComponent>(0, 0, 0); // Now the entity will be eligable for attackSystem.
pHolder.hasComponent<LifeManaComponent>(); // Return true
pHolder.getComponent<LifeManaComponent>(); // Return attack component reference.
pHolder.invalidate(); // Invalid all components
World->RemoveSystem<AttackSystem();
World->RemoveComponentCollection<DefenseComponent>();
UPDATE: CODE