33 explicit Scene(SceneComponentDefaults defaults = SceneComponentDefaults::Engine);
36 void DestroyEntity(
EntityId entity_id);
38 [[nodiscard]]
bool IsAlive(
EntityId entity_id)
const
40 return entity_id.Index() < entities_.size() && entities_[entity_id.Index()] == entity_id;
43 [[nodiscard]] std::vector<EntityId> GetEntities()
const
45 std::vector<EntityId> entities;
46 entities.reserve(entities_.size());
47 for (
const EntityId entity : entities_)
51 entities.push_back(entity);
57 template <
typename T,
typename... Args>
58 T& AddComponent(
EntityId entity_id, Args&&... args)
60 ASSERT(IsAlive(entity_id),
"Cannot add component to stale or invalid entity");
61 auto storage = GetOrCreateComponentStorage<T>();
62 T& component = storage->components.emplace(entity_id.Index(), std::forward<Args>(args)...);
63 ++mutation_generation_;
68 void RemoveComponent(
EntityId entity_id)
70 ASSERT(IsAlive(entity_id),
"Cannot remove component from stale or invalid entity");
71 auto* storage = TryGetComponentStorage<T>();
72 if (storage && storage->components.erase(entity_id.Index()))
74 ++mutation_generation_;
79 bool HasComponent(
EntityId entity_id)
const
81 if (!IsAlive(entity_id))
86 const auto type_id = std::type_index(
typeid(T));
87 auto it = component_storage_.find(type_id);
88 if (it != component_storage_.end())
91 return storage->components.contains(entity_id.Index());
97 void RegisterComponent(std::string_view serialization_name)
99 auto safe_deserialize = [](T& component,
const Node& node,
const std::string_view diagnostic_path) ->
SerializationResult
104 if (!TryReadNode(node, component, reader))
106 return reader.ToResult();
116 "Component type '" + std::string(
typeid(T).name()) +
"' does not support safe deserialization.",
118 .message =
"Component type does not support safe deserialization." } },
122 RegisterComponentType(std::type_index(
typeid(T)), std::string(serialization_name),
123 [safe_deserialize]() {
return std::make_unique<ComponentStorage<T>>(safe_deserialize); });
126 void RegisterComponentTypesFrom(
const Scene& source);
127 [[nodiscard]] std::vector<std::string> GetRegisteredComponentNames()
const;
129 template <
typename T>
132 T* component = TryGetComponent<T>(entity_id);
133 ASSERT(component,
"Component not found");
137 template <
typename T>
138 const T& GetComponent(
EntityId entity_id)
const
140 const T* component = TryGetComponent<T>(entity_id);
141 ASSERT(component,
"Component not found");
145 template <
typename T>
146 T* TryGetComponent(
EntityId entity_id)
148 if (!IsAlive(entity_id))
153 auto* storage = TryGetComponentStorage<T>();
154 if (!storage || !storage->components.contains(entity_id.Index()))
159 return &storage->components.at(entity_id.Index());
162 template <
typename T>
163 const T* TryGetComponent(
EntityId entity_id)
const
165 if (!IsAlive(entity_id))
170 const auto* storage = TryGetComponentStorage<T>();
171 if (!storage || !storage->components.contains(entity_id.Index()))
176 return &storage->components.at(entity_id.Index());
179 template <
typename T>
182 const auto type_id = std::type_index(
typeid(T));
183 auto it = component_storage_.find(type_id);
184 if (it != component_storage_.end())
187 return storage->components;
189 throw std::runtime_error(
"Component not found");
192 template <
typename T,
typename Func>
193 void Each(Func&& func)
195 auto* storage = TryGetComponentStorage<T>();
201 for (
const auto& entry : storage->components)
203 if (entry.id >= entities_.size())
208 const EntityId entity = entities_[entry.id];
214 func(entity, storage->components.at(entry.id));
218 template <
typename T,
typename Func>
219 void Each(Func&& func)
const
221 const auto* storage = TryGetComponentStorage<T>();
227 for (
const auto& entry : storage->components)
229 if (entry.id >= entities_.size())
234 const EntityId entity = entities_[entry.id];
240 func(entity, storage->components.at(entry.id));
246 return environment_settings_;
251 return environment_settings_;
256 environment_settings_ = std::move(settings);
257 ++mutation_generation_;
260 [[nodiscard]] uint64_t GetMutationGeneration()
const noexcept
262 return mutation_generation_;
265 template <
typename T,
typename U,
typename Func>
266 void Each(Func&& func)
268 auto* primary = TryGetComponentStorage<T>();
269 auto* secondary = TryGetComponentStorage<U>();
270 if (!primary || !secondary)
275 if (secondary->components.size() < primary->components.size())
277 for (
const auto& entry : secondary->components)
279 if (entry.id >= entities_.size())
284 const EntityId entity = entities_[entry.id];
285 if (!entity || !primary->components.contains(entry.id))
290 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
295 for (
const auto& entry : primary->components)
297 if (entry.id >= entities_.size())
302 const EntityId entity = entities_[entry.id];
303 if (!entity || !secondary->components.contains(entry.id))
308 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
312 template <
typename T,
typename U,
typename Func>
313 void Each(Func&& func)
const
315 const auto* primary = TryGetComponentStorage<T>();
316 const auto* secondary = TryGetComponentStorage<U>();
317 if (!primary || !secondary)
322 if (secondary->components.size() < primary->components.size())
324 for (
const auto& entry : secondary->components)
326 if (entry.id >= entities_.size())
331 const EntityId entity = entities_[entry.id];
332 if (!entity || !primary->components.contains(entry.id))
337 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
342 for (
const auto& entry : primary->components)
344 if (entry.id >= entities_.size())
349 const EntityId entity = entities_[entry.id];
350 if (!entity || !secondary->components.contains(entry.id))
355 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
359 friend Node& operator<<(
Node& node,
const Scene& scene);
360 friend const Node& operator>>(
const Node& node, Scene& scene);
361 friend class SceneSerializer;
364 using ComponentTypeId = std::type_index;
365 using ComponentStorageFactory = std::function<std::unique_ptr<ComponentStorageBase>()>;
367 struct ComponentRegistration
370 ComponentStorageFactory factory;
373 void ClearSceneState();
374 void RegisterComponentType(ComponentTypeId type_id, std::string serialization_name, ComponentStorageFactory factory);
375 ComponentStorageBase* FindOrCreateStorage(ComponentTypeId type_id, std::string_view serialization_name);
376 [[nodiscard]]
const ComponentRegistration* FindComponentRegistration(ComponentTypeId type_id)
const;
379 std::vector<EntityId> entities_;
380 std::vector<uint32_t> entity_generations_;
381 std::vector<uint32_t> free_entities_;
382 std::unordered_map<ComponentTypeId, std::unique_ptr<ComponentStorageBase>> component_storage_;
383 std::unordered_map<ComponentTypeId, ComponentRegistration> component_registrations_;
384 std::unordered_map<std::string, ComponentTypeId> component_types_by_name_;
385 std::unordered_map<std::string, ComponentStorageFactory> component_storage_factories_by_name_;
387 uint64_t mutation_generation_ = 1;
390 template <
typename T>
393 const auto type_id = std::type_index(
typeid(T));
394 auto it = component_storage_.find(type_id);
395 if (it != component_storage_.end())
401 auto storage = std::make_unique<ComponentStorage<T>>();
403 component_storage_[type_id] = std::move(storage);
408 template <
typename T>
411 const auto type_id = std::type_index(
typeid(T));
412 auto it = component_storage_.find(type_id);
413 if (it == component_storage_.end())
420 template <
typename T>
423 const auto type_id = std::type_index(
typeid(T));
424 auto it = component_storage_.find(type_id);
425 if (it == component_storage_.end())