32 explicit Scene(SceneComponentDefaults defaults = SceneComponentDefaults::Engine);
35 void DestroyEntity(
EntityId entity_id);
37 [[nodiscard]]
bool IsAlive(
EntityId entity_id)
const
39 return entity_id.Index() < entities_.size() && entities_[entity_id.Index()] == entity_id;
42 [[nodiscard]] std::vector<EntityId> GetEntities()
const
44 std::vector<EntityId> entities;
45 entities.reserve(entities_.size());
46 for (
const EntityId entity : entities_)
50 entities.push_back(entity);
56 template <
typename T,
typename... Args>
57 T& AddComponent(
EntityId entity_id, Args&&... args)
59 ASSERT(IsAlive(entity_id),
"Cannot add component to stale or invalid entity");
60 auto storage = GetOrCreateComponentStorage<T>();
61 T& component = storage->components.emplace(entity_id.Index(), std::forward<Args>(args)...);
62 ++mutation_generation_;
67 void RemoveComponent(
EntityId entity_id)
69 ASSERT(IsAlive(entity_id),
"Cannot remove component from stale or invalid entity");
70 auto storage = GetOrCreateComponentStorage<T>();
71 storage->components.erase(entity_id.Index());
72 ++mutation_generation_;
76 bool HasComponent(
EntityId entity_id)
const
78 if (!IsAlive(entity_id))
83 const auto type_id = std::type_index(
typeid(T));
84 auto it = component_storage_.find(type_id);
85 if (it != component_storage_.end())
88 return storage->components.contains(entity_id.Index());
94 void RegisterComponent(std::string_view serialization_name)
96 RegisterComponentType(std::type_index(
typeid(T)), std::string(serialization_name),
97 []() {
return std::make_unique<ComponentStorage<T>>(); });
100 void RegisterComponentTypesFrom(
const Scene& source);
101 [[nodiscard]] std::vector<std::string> GetRegisteredComponentNames()
const;
103 template <
typename T>
106 ASSERT(IsAlive(entity_id),
"Cannot get component from stale or invalid entity");
107 auto storage = GetOrCreateComponentStorage<T>();
108 return storage->components.at(entity_id.Index());
111 template <
typename T>
112 const T& GetComponent(
EntityId entity_id)
const
114 ASSERT(IsAlive(entity_id),
"Cannot get component from stale or invalid entity");
115 const auto* storage = TryGetComponentStorage<T>();
116 ASSERT(storage,
"Component not found");
117 return storage->components.at(entity_id.Index());
120 template <
typename T>
123 const auto type_id = std::type_index(
typeid(T));
124 auto it = component_storage_.find(type_id);
125 if (it != component_storage_.end())
128 return storage->components;
130 throw std::runtime_error(
"Component not found");
133 template <
typename T,
typename Func>
134 void Each(Func&& func)
136 auto* storage = TryGetComponentStorage<T>();
142 for (
const auto& entry : storage->components)
144 if (entry.id >= entities_.size())
149 const EntityId entity = entities_[entry.id];
155 func(entity, storage->components.at(entry.id));
159 template <
typename T,
typename Func>
160 void Each(Func&& func)
const
162 const auto* storage = TryGetComponentStorage<T>();
168 for (
const auto& entry : storage->components)
170 if (entry.id >= entities_.size())
175 const EntityId entity = entities_[entry.id];
181 func(entity, storage->components.at(entry.id));
187 return environment_settings_;
192 return environment_settings_;
197 environment_settings_ = std::move(settings);
198 ++mutation_generation_;
201 [[nodiscard]] uint64_t GetMutationGeneration()
const noexcept
203 return mutation_generation_;
206 template <
typename T,
typename U,
typename Func>
207 void Each(Func&& func)
209 auto* primary = TryGetComponentStorage<T>();
210 auto* secondary = TryGetComponentStorage<U>();
211 if (!primary || !secondary)
216 if (secondary->components.size() < primary->components.size())
218 for (
const auto& entry : secondary->components)
220 if (entry.id >= entities_.size())
225 const EntityId entity = entities_[entry.id];
226 if (!entity || !primary->components.contains(entry.id))
231 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
236 for (
const auto& entry : primary->components)
238 if (entry.id >= entities_.size())
243 const EntityId entity = entities_[entry.id];
244 if (!entity || !secondary->components.contains(entry.id))
249 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
253 template <
typename T,
typename U,
typename Func>
254 void Each(Func&& func)
const
256 const auto* primary = TryGetComponentStorage<T>();
257 const auto* secondary = TryGetComponentStorage<U>();
258 if (!primary || !secondary)
263 if (secondary->components.size() < primary->components.size())
265 for (
const auto& entry : secondary->components)
267 if (entry.id >= entities_.size())
272 const EntityId entity = entities_[entry.id];
273 if (!entity || !primary->components.contains(entry.id))
278 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
283 for (
const auto& entry : primary->components)
285 if (entry.id >= entities_.size())
290 const EntityId entity = entities_[entry.id];
291 if (!entity || !secondary->components.contains(entry.id))
296 func(entity, primary->components.at(entry.id), secondary->components.at(entry.id));
300 friend Node& operator<<(
Node& node,
const Scene& scene);
301 friend const Node& operator>>(
const Node& node, Scene& scene);
302 friend class SceneSerializer;
305 using ComponentTypeId = std::type_index;
306 using ComponentStorageFactory = std::function<std::unique_ptr<ComponentStorageBase>()>;
308 struct ComponentRegistration
311 ComponentStorageFactory factory;
314 void ClearSceneState();
315 void RegisterComponentType(ComponentTypeId type_id, std::string serialization_name, ComponentStorageFactory factory);
316 ComponentStorageBase* FindOrCreateStorage(ComponentTypeId type_id, std::string_view serialization_name);
317 [[nodiscard]]
const ComponentRegistration* FindComponentRegistration(ComponentTypeId type_id)
const;
320 std::vector<EntityId> entities_;
321 std::vector<uint8_t> entity_versions_;
322 std::vector<uint32_t> free_entities_;
323 std::unordered_map<ComponentTypeId, std::unique_ptr<ComponentStorageBase>> component_storage_;
324 std::unordered_map<ComponentTypeId, ComponentRegistration> component_registrations_;
325 std::unordered_map<std::string, ComponentTypeId> component_types_by_name_;
326 std::unordered_map<std::string, ComponentStorageFactory> component_storage_factories_by_name_;
328 uint64_t mutation_generation_ = 1;
331 template <
typename T>
334 const auto type_id = std::type_index(
typeid(T));
335 auto it = component_storage_.find(type_id);
336 if (it != component_storage_.end())
342 auto storage = std::make_unique<ComponentStorage<T>>();
344 component_storage_[type_id] = std::move(storage);
349 template <
typename T>
352 const auto type_id = std::type_index(
typeid(T));
353 auto it = component_storage_.find(type_id);
354 if (it == component_storage_.end())
361 template <
typename T>
364 const auto type_id = std::type_index(
typeid(T));
365 auto it = component_storage_.find(type_id);
366 if (it == component_storage_.end())