27 void DestroyEntity(
EntityId entityId);
29 [[nodiscard]]
bool IsAlive(
EntityId entityId)
const
31 return entityId.Index() < entities_.size() && entities_[entityId.Index()] == entityId;
34 [[nodiscard]] std::vector<EntityId> GetEntities()
const
36 std::vector<EntityId> entities;
37 entities.reserve(entities_.size());
38 for (
const EntityId entity : entities_)
42 entities.push_back(entity);
48 template <
typename T,
typename... Args>
49 T& AddComponent(
EntityId entityId, Args&&... args)
51 ASSERT(IsAlive(entityId),
"Cannot add component to stale or invalid entity");
52 auto storage = GetOrCreateComponentStorage<T>();
53 T component{ std::forward<Args>(args)... };
54 storage->set.Insert(entityId.Index(), component);
55 return storage->set.Get(entityId.Index());
59 void RemoveComponent(
EntityId entityId)
61 ASSERT(IsAlive(entityId),
"Cannot remove component from stale or invalid entity");
62 auto storage = GetOrCreateComponentStorage<T>();
63 storage->set.Erase(entityId.Index());
67 bool HasComponent(
EntityId entityId)
const
69 if (!IsAlive(entityId))
74 const auto typeId = std::type_index(
typeid(T));
75 auto it = component_storage_.find(typeId);
76 if (it != component_storage_.end())
79 return storage->set.Has(entityId.Index());
85 void RegisterComponent(std::string_view serializationName)
87 RegisterComponentType(
88 std::type_index(
typeid(T)), std::string(serializationName), []() {
return std::make_unique<ComponentStorage<T>>(); },
true);
94 ASSERT(IsAlive(entityId),
"Cannot get component from stale or invalid entity");
95 auto storage = GetOrCreateComponentStorage<T>();
96 return storage->set.Get(entityId.Index());
100 const T& GetComponent(
EntityId entityId)
const
102 ASSERT(IsAlive(entityId),
"Cannot get component from stale or invalid entity");
103 const auto* storage = TryGetComponentStorage<T>();
104 ASSERT(storage,
"Component not found");
105 return storage->set.Get(entityId.Index());
108 template <
typename T>
111 const auto typeId = std::type_index(
typeid(T));
112 auto it = component_storage_.find(typeId);
113 if (it != component_storage_.end())
118 throw std::runtime_error(
"Component not found");
121 template <
typename T,
typename Func>
122 void Each(Func&& func)
124 auto* storage = TryGetComponentStorage<T>();
130 for (
const auto& entry : storage->set)
132 if (entry.id >= entities_.size())
137 const EntityId entity = entities_[entry.id];
143 func(entity, storage->set.Get(entry.id));
147 template <
typename T,
typename Func>
148 void Each(Func&& func)
const
150 const auto* storage = TryGetComponentStorage<T>();
156 for (
const auto& entry : storage->set)
158 if (entry.id >= entities_.size())
163 const EntityId entity = entities_[entry.id];
169 func(entity, storage->set.Get(entry.id));
173 template <
typename T,
typename U,
typename Func>
174 void Each(Func&& func)
176 auto* primary = TryGetComponentStorage<T>();
177 auto* secondary = TryGetComponentStorage<U>();
178 if (!primary || !secondary)
183 if (secondary->set.Size() < primary->set.Size())
185 for (
const auto& entry : secondary->set)
187 if (entry.id >= entities_.size())
192 const EntityId entity = entities_[entry.id];
193 if (!entity || !primary->set.Has(entry.id))
198 func(entity, primary->set.Get(entry.id), secondary->set.Get(entry.id));
203 for (
const auto& entry : primary->set)
205 if (entry.id >= entities_.size())
210 const EntityId entity = entities_[entry.id];
211 if (!entity || !secondary->set.Has(entry.id))
216 func(entity, primary->set.Get(entry.id), secondary->set.Get(entry.id));
220 template <
typename T,
typename U,
typename Func>
221 void Each(Func&& func)
const
223 const auto* primary = TryGetComponentStorage<T>();
224 const auto* secondary = TryGetComponentStorage<U>();
225 if (!primary || !secondary)
230 if (secondary->set.Size() < primary->set.Size())
232 for (
const auto& entry : secondary->set)
234 if (entry.id >= entities_.size())
239 const EntityId entity = entities_[entry.id];
240 if (!entity || !primary->set.Has(entry.id))
245 func(entity, primary->set.Get(entry.id), secondary->set.Get(entry.id));
250 for (
const auto& entry : primary->set)
252 if (entry.id >= entities_.size())
257 const EntityId entity = entities_[entry.id];
258 if (!entity || !secondary->set.Has(entry.id))
263 func(entity, primary->set.Get(entry.id), secondary->set.Get(entry.id));
268 friend const Node& operator>>(
const Node& node,
Scene& scene);
272 using ComponentTypeId = std::type_index;
273 using ComponentStorageFactory = std::function<std::unique_ptr<ComponentStorageBase>()>;
275 struct ComponentRegistration
278 ComponentStorageFactory factory;
279 bool is_explicit =
false;
282 void Serialize(
Node& node)
const;
283 void Deserialize(
const Node& node);
284 void ClearSceneState();
285 void RegisterBuiltInComponents();
286 void RegisterComponentType(ComponentTypeId typeId, std::string serializationName, ComponentStorageFactory factory,
287 bool explicitRegistration);
288 ComponentStorageBase* FindOrCreateStorage(ComponentTypeId typeId, std::string_view serializationName);
289 [[nodiscard]]
const ComponentRegistration* FindComponentRegistration(ComponentTypeId typeId)
const;
292 std::vector<EntityId> entities_;
293 std::vector<uint8_t> entity_versions_;
294 std::vector<uint32_t> free_entities_;
295 std::unordered_map<ComponentTypeId, std::unique_ptr<ComponentStorageBase>> component_storage_;
296 std::unordered_map<ComponentTypeId, ComponentRegistration> component_registrations_;
297 std::unordered_map<std::string, ComponentTypeId> component_types_by_name_;
298 std::unordered_map<std::string, ComponentStorageFactory> component_storage_factories_by_name_;
301 template <
typename T>
304 EnsureComponentRegistered<T>();
306 const auto typeId = std::type_index(
typeid(T));
307 auto it = component_storage_.find(typeId);
308 if (it != component_storage_.end())
314 auto storage = std::make_unique<ComponentStorage<T>>();
316 component_storage_[typeId] = std::move(storage);
321 template <
typename T>
324 const auto typeId = std::type_index(
typeid(T));
325 auto it = component_storage_.find(typeId);
326 if (it == component_storage_.end())
333 template <
typename T>
336 const auto typeId = std::type_index(
typeid(T));
337 auto it = component_storage_.find(typeId);
338 if (it == component_storage_.end())
345 template <
typename T>
346 void EnsureComponentRegistered()
348 const auto typeId = std::type_index(
typeid(T));
349 if (component_registrations_.find(typeId) != component_registrations_.end())
354 RegisterComponentType(
355 typeId,
typeid(T).name(), []() {
return std::make_unique<ComponentStorage<T>>(); },
false);