The Registry class serves as the central manager for entities and their associated components in an Entity-Component-System (ECS) architecture.
It handles the registration, retrieval, and management of components, entities, and systems.
namespace ecs {
class Registry {
public:
template <class Component>
SparseArray<Component> ®ister_component()
{
auto type = std::type_index(typeid(SparseArray<Component>));
if (_componentsArrays.find(type) == _componentsArrays.end()) {
_componentsArrays[type] = SparseArray<Component>();
}
return std::any_cast<SparseArray<Component> &>(_componentsArrays[type]);
}
template <class Component>
SparseArray<Component> &get_components()
{
return std::any_cast<SparseArray<Component> &>(
_componentsArrays[std::type_index(typeid(SparseArray<Component>))]
);
}
template <class Component>
SparseArray<Component> ®ister_if_not_exist()
{
auto type = std::type_index(typeid(SparseArray<Component>));
if (_componentsArrays.find(type) == _componentsArrays.end()) {
return register_component<Component>();
}
return std::any_cast<SparseArray<Component> &>(_componentsArrays[type]);
}
Entity spawn_entity()
{
return Entity(_entityCount++);
}
void remove_component(Entity const &from)
{
std::size_t idx = 0;
for (const auto &i : _componentsArrays) {
if (from.getId() == idx) {
_componentsArrays.erase(i.first);
break;
}
idx += 1;
}
}
void erase(const std::size_t &entityIdx)
{
auto &positions = register_component<ecs::component::Position>();
auto &drawable = register_component<ecs::component::Drawable>();
auto &sprite = register_component<ecs::component::Sprite>();
auto &animation = register_component<ecs::component::Animations>();
auto ¶llax = register_component<ecs::component::Parallax>();
auto &size = register_component<ecs::component::Size>();
positions.erase(entityIdx);
drawable.erase(entityIdx);
sprite.erase(entityIdx);
animation.erase(entityIdx);
parallax.erase(entityIdx);
size.erase(entityIdx);
_entitys.erase(entityIdx);
}
template <typename Function>
void add_system(Function &&f)
{
_systems.push_back(f);
}
void run_systems()
{
for (auto &system : _systems) {
system(*this);
}
}
EntityManager _entitys;
private:
std::vector<std::function<void(Registry &)>> _systems;
std::unordered_map<std::type_index, std::any> _componentsArrays;
std::size_t _entityCount = 0;
};
} // namespace ecs
template <class Component> SparseArray<Component> ®ister_component()
SparseArray for that component type and stores it.SparseArray for the registered component type.template <class Component> SparseArray<Component> &get_components()
SparseArray of the specified component type.SparseArray of the specified component.template <class Component> SparseArray<Component> ®ister_if_not_exist()
SparseArray for that component.Entity spawn_entity()
Entity object, which is a unique identifier for each entity.void remove_component(Entity const &from)
void erase(const std::size_t &entityIdx)
erase() on the relevant component arrays to clean up components._entitys (entity manager).template <typename Function> void add_system(Function &&f)
run_systems().void run_systems()
EntityManager _entitys
std::vector<std::function<void(Registry &)>> _systems
std::unordered_map<std::type_index, std::any> _componentsArrays
std::any to store the arrays, allowing different component types to be handled generically.