R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
ECSWorld.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** rtype
4** File description:
5** ECSWorld implementation
6*/
7
8#include "ECSWorld.hpp"
9#include <algorithm>
10#include "../Logger/Logger.hpp"
11
12namespace ecs::wrapper {
13
14 std::string_view systemIdToName(SystemId id) {
15 switch (id) {
17 return "MovementSystem";
19 return "CollisionSystem";
21 return "HealthSystem";
22 case SystemId::Spawn:
23 return "SpawnSystem";
24 case SystemId::AI:
25 return "AISystem";
27 return "BoundarySystem";
29 return "WeaponSystem";
30 default:
31 return "UnknownSystem";
32 }
33 }
34
35 // Entity implementation
36
37 Entity::Entity(Address address, Registry *registry) : _address(address), _registry(registry) {}
38
40 return _address;
41 }
42
43 bool Entity::isValid() const {
44 if (!_registry || _address == 0) {
45 return false;
46 }
47
48 // Check if entity exists in registry by checking its signature
49 try {
51 return true;
52 } catch (...) {
53 return false;
54 }
55 }
56
57 Entity::operator Address() const {
58 return _address;
59 }
60
61 // ECSWorld implementation
62
63 ECSWorld::ECSWorld() : _registry(std::make_unique<Registry>()) {}
64
65 ECSWorld::~ECSWorld() = default;
66
68 Address address = _registry->newEntity();
69 return Entity(address, _registry.get());
70 }
71
72 std::vector<Entity> ECSWorld::createEntities(size_t count) {
73 std::vector<Entity> entities;
74 entities.reserve(count);
75
76 for (size_t i = 0; i < count; ++i) {
77 entities.push_back(createEntity());
78 }
79
80 return entities;
81 }
82
84 return Entity(address, _registry.get());
85 }
86
87 void ECSWorld::destroyEntity(const Entity &entity) {
88 if (entity.isValid()) {
89 _registry->destroyEntity(entity.getAddress());
90 }
91 }
92
94 _registry->destroyEntity(address);
95 }
96
97 void ECSWorld::removeSystem(const std::string &name) {
98 auto it = _systems.find(name);
99 if (it != _systems.end()) {
100 _systems.erase(it);
101
102 // Remove from order list
103 auto orderIt = std::find(_systemsOrder.begin(), _systemsOrder.end(), name);
104 if (orderIt != _systemsOrder.end()) {
105 _systemsOrder.erase(orderIt);
106 }
107 }
108 }
109
111 removeSystem(std::string(systemIdToName(id)));
112 }
113
114 void ECSWorld::update(float deltaTime) {
115 for (const auto &systemName : _systemsOrder) {
116 auto it = _systems.find(systemName);
117 if (it != _systems.end()) {
118 try {
119 it->second->update(*_registry, deltaTime);
120 } catch (const std::exception &e) {
121 LOG_ERROR("ECSWorld::update - Error in system '", systemName, "': ", e.what());
122 }
123 }
124 }
125 }
126
127 bool ECSWorld::updateSystem(const std::string &name, float deltaTime) {
128 auto it = _systems.find(name);
129 if (it == _systems.end()) {
130 return false;
131 }
132
133 try {
134 it->second->update(*_registry, deltaTime);
135 return true;
136 } catch (const std::exception &e) {
137 LOG_ERROR("ECSWorld::updateSystem - Error in system '", name, "': ", e.what());
138 return false;
139 }
140 }
141
142 bool ECSWorld::updateSystem(SystemId id, float deltaTime) {
143 return updateSystem(std::string(systemIdToName(id)), deltaTime);
144 }
145
147 return *_registry;
148 }
149
151 return *_registry;
152 }
153
155 // Get all entity addresses and destroy them
156 auto allEntities = _registry->view<>();
157 for (auto address : allEntities) {
158 _registry->destroyEntity(address);
159 }
160 }
161
163 return _systems.size();
164 }
165
166} // namespace ecs::wrapper
#define LOG_ERROR(...)
Definition Logger.hpp:183
Manages entities, their signatures and component type registrations.
Definition Registry.hpp:68
std::vector< Address > view()
Get all entities that have a specific set of components.
Signature getSignature(Address address)
Retrieve the Signature for a given entity address.
Definition Registry.cpp:70
Entity createEntity()
Create a new entity.
Definition ECSWorld.cpp:67
std::unordered_map< std::string, std::unique_ptr< ISystem > > _systems
Definition ECSWorld.hpp:125
Entity getEntity(Address address)
Get an entity wrapper from an address.
Definition ECSWorld.cpp:83
void update(float deltaTime)
Update all registered systems.
Definition ECSWorld.cpp:114
~ECSWorld()
Destroy the ECSWorld and cleanup resources.
std::unique_ptr< Registry > _registry
Definition ECSWorld.hpp:124
std::vector< Entity > createEntities(size_t count)
Create multiple entities at once.
Definition ECSWorld.cpp:72
Registry & getRegistry()
Get direct access to the underlying registry.
Definition ECSWorld.cpp:146
void destroyEntity(const Entity &entity)
Destroy an entity and remove it from the world.
Definition ECSWorld.cpp:87
void clear()
Clear all entities from the world.
Definition ECSWorld.cpp:154
ECSWorld()
Construct a new ECSWorld.
Definition ECSWorld.cpp:63
std::vector< std::string > _systemsOrder
Definition ECSWorld.hpp:126
bool updateSystem(const std::string &name, float deltaTime)
Update a specific system by name.
Definition ECSWorld.cpp:127
void removeSystem(const std::string &name)
Remove a system from the world.
Definition ECSWorld.cpp:97
size_t getSystemCount() const
Get the number of systems registered.
Definition ECSWorld.cpp:162
High-level entity wrapper providing fluent interface.
Definition ECSWorld.hpp:33
Registry * _registry
Definition ECSWorld.hpp:36
Entity(Address address, Registry *registry)
Construct an Entity wrapper.
Definition ECSWorld.cpp:37
Address getAddress() const
Get the entity's address.
Definition ECSWorld.cpp:39
bool isValid() const
Check if this entity is valid.
Definition ECSWorld.cpp:43
std::string_view systemIdToName(SystemId id)
Definition ECSWorld.cpp:14
std::uint32_t Address
Type used to represent an entity address/ID.