Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
components_manager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
10
11#include <concepts>
12#include <cstddef>
13#include <memory>
14#include <span>
15#include <type_traits>
16#include <unordered_map>
17#include <vector>
18
19namespace helios::ecs::details {
20
21/**
22 * @brief Base class for type-erased component storage.
23 * @details Provides a common interface for storing different component types
24 * in a heterogeneous container. Each derived ComponentStorage<T> manages
25 * components of a specific type T using a sparse set for efficient operations.
26 *
27 * @note Not thread-safe.
28 * All operations should be performed from the main thread.
29 */
31public:
32 virtual ~ComponentStorageBase() = default;
33
34 /**
35 * @brief Clears all components from storage.
36 * @details Removes all component instances and resets internal state.
37 */
38 virtual void Clear() noexcept = 0;
39
40 /**
41 * @brief Removes component for the specified entity.
42 * @details Removes the component associated with the entity.
43 * @warning Triggers assertion if entity doesn't have the component.
44 * @param entity Entity to remove component from
45 */
46 virtual void Remove(Entity entity) = 0;
47
48 /**
49 * @brief Attempts to remove component for the specified entity.
50 * @details Removes the component if it exists, otherwise does nothing.
51 * @param entity Entity to remove component from
52 * @return True if component was removed, false if entity didn't have the component
53 */
54 virtual bool TryRemove(Entity entity) = 0;
55
56 /**
57 * @brief Checks if entity has a component in this storage.
58 * @details Performs fast lookup to determine component presence.
59 * @param entity Entity to check
60 * @return True if entity has a component in this storage, false otherwise
61 */
62 [[nodiscard]] virtual bool Contains(Entity entity) const = 0;
63
64 /**
65 * @brief Gets the number of components in storage.
66 * @details Returns count of component instances currently stored.
67 * @return Number of components in storage
68 */
70
71 /**
72 * @brief Gets type information for the component type stored.
73 * @details Returns compile-time component metadata including size, alignment, etc.
74 * @return ComponentTypeInfo for the stored component type
75 */
77};
78
79/**
80 * @brief Type-specific component storage using sparse set.
81 * @details Manages components of type T using a sparse set data structure for
82 * O(1) insertion, removal, and lookup operations. Components are stored in
83 * dense arrays for cache-friendly iteration.
84 *
85 * Memory layout:
86 * - Sparse array: Entity index -> Dense index mapping
87 * - Dense array: Packed component instances
88 * - Reverse mapping: Dense index -> Entity index
89 *
90 * @tparam T Component type to store
91 * @note Not thread-safe.
92 * All operations should be performed from the main thread.
93 */
96public:
100
101 ComponentStorage() = default;
105
108
109 /**
110 * @brief Clears all components from this storage.
111 * @details Removes all component instances and resets sparse set state.
112 * Time complexity: O(sparse_capacity).
113 */
114 void Clear() noexcept override { storage_.Clear(); }
115
116 /**
117 * @brief Constructs component in-place for the specified entity.
118 * @details Creates a new component by forwarding arguments to T's constructor.
119 * If entity already has this component, it will be replaced.
120 * Time complexity: O(1) amortized.
121 * @warning Triggers assertion if entity is invalid.
122 * @tparam Args Argument types to forward to T's constructor
123 * @param entity Entity to add component to
124 * @param args Arguments to forward to component constructor
125 */
126 template <typename... Args>
127 requires std::constructible_from<T, Args...>
128 void Emplace(Entity entity, Args&&... args);
129
130 /**
131 * @brief Inserts component for the specified entity (copy version).
132 * @details Adds a copy of the component to the entity.
133 * If entity already has this component, it will be replaced.
134 * Time complexity: O(1) amortized.
135 * @warning Triggers assertion if entity is invalid.
136 * @param entity Entity to add component to
137 * @param component Component to copy
138 */
139 void Insert(Entity entity, const T& component);
140
141 /**
142 * @brief Inserts component for the specified entity (move version).
143 * @details Moves the component to the entity.
144 * If entity already has this component, it will be replaced.
145 * Time complexity: O(1) amortized.
146 * @warning Triggers assertion if entity is invalid.
147 * @param entity Entity to add component to
148 * @param component Component to move
149 */
150 void Insert(Entity entity, T&& component);
151
152 /**
153 * @brief Removes component from the specified entity.
154 * @details Removes the component using swap-and-pop for dense packing.
155 * Time complexity: O(1).
156 * @warning Triggers assertion if entity is invalid or doesn't have the component.
157 * @param entity Entity to remove component from
158 */
159 void Remove(Entity entity) override;
160
161 /**
162 * @brief Attempts to remove component from the specified entity.
163 * @details Removes the component if it exists, otherwise does nothing.
164 * Time complexity: O(1).
165 * @warning Triggers assertion if entity is invalid.
166 * @param entity Entity to remove component from
167 * @return True if component was removed, false if entity didn't have the component
168 */
169 bool TryRemove(Entity entity) override;
170
171 /**
172 * @brief Gets mutable reference to component for the specified entity.
173 * @details Returns direct reference to the stored component.
174 * Time complexity: O(1).
175 * @warning Triggers assertion if entity is invalid or doesn't have the component.
176 * @param entity Entity to get component from
177 * @return Mutable reference to the component
178 */
179 [[nodiscard]] T& Get(Entity entity);
180
181 /**
182 * @brief Gets const reference to component for the specified entity.
183 * @details Returns direct const reference to the stored component.
184 * Time complexity: O(1).
185 * @warning Triggers assertion if entity is invalid or doesn't have the component.
186 * @param entity Entity to get component from
187 * @return Const reference to the component
188 */
189 [[nodiscard]] const T& Get(Entity entity) const;
190
191 /**
192 * @brief Attempts to get mutable pointer to component for the specified entity.
193 * @details Returns pointer to component if it exists, nullptr otherwise.
194 * Time complexity: O(1).
195 * @param entity Entity to get component from
196 * @return Pointer to component, or nullptr if entity doesn't have the component
197 */
198 [[nodiscard]] T* TryGet(Entity entity);
199
200 /**
201 * @brief Attempts to get const pointer to component for the specified entity.
202 * @details Returns const pointer to component if it exists, nullptr otherwise.
203 * Time complexity: O(1).
204 * @param entity Entity to get component from
205 * @return Const pointer to component, or nullptr if entity doesn't have the component
206 */
207 [[nodiscard]] const T* TryGet(Entity entity) const;
208
209 /**
210 * @brief Checks if entity has a component in this storage.
211 * @details Performs comprehensive validation including entity validity and component presence.
212 * Time complexity: O(1).
213 * @warning Triggers assertion if entity is invalid.
214 * @param entity Entity to check
215 * @return True if entity has this component, false otherwise
216 */
217 [[nodiscard]] bool Contains(Entity entity) const override;
218
219 /**
220 * @brief Gets the number of components stored.
221 * @details Returns count of component instances currently in storage.
222 * Time complexity: O(1).
223 * @return Number of components in storage
224 */
225 [[nodiscard]] size_t Size() const noexcept override { return storage_.Size(); }
226
227 /**
228 * @brief Gets compile-time type information for component T.
229 * @details Returns metadata including type ID, size, alignment, and optimization flags.
230 * @return ComponentTypeInfo for type T
231 */
233 return ComponentTypeInfo::Create<T>();
234 }
235
236 /**
237 * @brief Gets mutable span over all stored components.
238 * @details Provides direct access to densely packed component array for efficient iteration.
239 * Components are stored in insertion order (with removal gaps filled by later insertions).
240 * Time complexity: O(1).
241 * @return Span over all components in storage
242 */
243 [[nodiscard]] std::span<T> Data() noexcept { return storage_.Data(); }
244
245 /**
246 * @brief Gets const span over all stored components.
247 * @details Provides direct read-only access to densely packed component array.
248 * Components are stored in insertion order (with removal gaps filled by later insertions).
249 * Time complexity: O(1).
250 * @return Const span over all components in storage
251 */
252 [[nodiscard]] std::span<const T> Data() const noexcept { return storage_.Data(); }
253
254 [[nodiscard]] Iterator begin() noexcept { return storage_.begin(); }
255 [[nodiscard]] ConstIterator begin() const noexcept { return storage_.begin(); }
256 [[nodiscard]] ConstIterator cbegin() const noexcept { return storage_.cbegin(); }
257
258 [[nodiscard]] Iterator end() noexcept { return storage_.end(); }
259 [[nodiscard]] ConstIterator end() const noexcept { return storage_.end(); }
260 [[nodiscard]] ConstIterator cend() const noexcept { return storage_.cend(); }
261
262private:
263 SparseSetType storage_; ///< Underlying sparse set storing components
264};
265
266template <ComponentTrait T>
267template <typename... Args>
268 requires std::constructible_from<T, Args...>
269inline void ComponentStorage<T>::Emplace(Entity entity, Args&&... args) {
270 HELIOS_ASSERT(entity.Valid(), "Failed to emplace component '{}': Entity with index '{}' is invalid!",
271 ComponentNameOf<T>(), entity.Index());
272 storage_.Emplace(entity.Index(), std::forward<Args>(args)...);
273}
274
275template <ComponentTrait T>
276inline void ComponentStorage<T>::Insert(Entity entity, const T& component) {
277 HELIOS_ASSERT(entity.Valid(), "Failed to insert component '{}': Entity with index '{}' is invalid!",
278 ComponentNameOf<T>(), entity.Index());
279 storage_.Insert(entity.Index(), component);
280}
281
282template <ComponentTrait T>
284 HELIOS_ASSERT(entity.Valid(), "Failed to insert component '{}': Entity with index '{}' is invalid!",
285 ComponentNameOf<T>(), entity.Index());
286 storage_.Insert(entity.Index(), std::move(component));
287}
288
289template <ComponentTrait T>
291 HELIOS_ASSERT(entity.Valid(), "Failed to remove component '{}': Entity with index '{}' is invalid!",
292 ComponentNameOf<T>(), entity.Index());
293 HELIOS_ASSERT(storage_.Contains(entity.Index()),
294 "Failed to remove component '{}': Entity with index '{}' does not have this component!",
295 ComponentNameOf<T>(), entity.Index());
296 storage_.Remove(entity.Index());
297}
298
299template <ComponentTrait T>
301 HELIOS_ASSERT(entity.Valid(), "Failed to try remove component '{}': Entity with index '{}' is invalid!",
302 ComponentNameOf<T>(), entity.Index());
303 if (!storage_.Contains(entity.Index())) {
304 return false;
305 }
306
307 storage_.Remove(entity.Index());
308 return true;
309}
310
311template <ComponentTrait T>
312inline bool ComponentStorage<T>::Contains(Entity entity) const {
313 HELIOS_ASSERT(entity.Valid(),
314 "Failed to check if '{}' component storage contains entity: Entity with index '{}' is invalid!",
315 ComponentNameOf<T>(), entity.Index());
316 return storage_.Contains(entity.Index());
317}
318
319template <ComponentTrait T>
321 HELIOS_ASSERT(entity.Valid(), "Failed to get component '{}': Entity with index '{}' is invalid!",
322 ComponentNameOf<T>(), entity.Index());
323 return storage_.Get(entity.Index());
324}
325
326template <ComponentTrait T>
327inline const T& ComponentStorage<T>::Get(Entity entity) const {
328 HELIOS_ASSERT(entity.Valid(), "Failed to get component '{}': Entity with index '{}' is invalid!",
329 ComponentNameOf<T>(), entity.Index());
330 return storage_.Get(entity.Index());
331}
332
333template <ComponentTrait T>
335 if (!entity.Valid()) {
336 return nullptr;
337 }
338 return storage_.TryGet(entity.Index());
339}
340
341template <ComponentTrait T>
342inline const T* ComponentStorage<T>::TryGet(Entity entity) const {
343 if (!entity.Valid()) {
344 return nullptr;
345 }
346 return storage_.TryGet(entity.Index());
347}
348
349/**
350 * @brief Manager for all component storages in the ECS world.
351 * @details Maintains a registry of type-erased component storages, providing
352 * a unified interface for component operations across all types. Each component
353 * type gets its own ComponentStorage<T> instance for type-safe operations.
354 *
355 * Key features:
356 * - Type-erased storage management for heterogeneous component types
357 * - Lazy storage creation - storages are created only when first component is added
358 * - Efficient component lookup and manipulation
359 * - Bulk operations for entity lifecycle management
360 *
361 * @note Not thread-safe. All operations should be performed from the main thread.
362 */
364public:
365 Components() = default;
366 Components(const Components&) = delete;
367 Components(Components&&) = default;
368 ~Components() = default;
369
370 Components& operator=(const Components&) = delete;
372
373 /**
374 * @brief Clears all component storages.
375 * @details Removes all components of all types and resets the manager state.
376 * Time complexity: O(1).
377 */
378 void Clear() noexcept { storages_.clear(); }
379
380 /**
381 * @brief Removes all components from the specified entity.
382 * @details Iterates through all component storages and removes entity's components.
383 * Used when destroying entities or clearing their component sets.
384 * Time complexity: O(S) where S is the number of component types.
385 * @warning Triggers assertion if entity is invalid.
386 * @param entity Entity to remove all components from
387 */
388 void RemoveAllComponents(Entity entity);
389
390 /**
391 * @brief Adds component to entity (move version).
392 * @details Moves the component into storage. Creates storage if needed.
393 * If entity already has this component type, it will be replaced.
394 * Time complexity: O(1) amortized.
395 * @warning Triggers assertion if entity is invalid.
396 * @tparam T Component type to add
397 * @param entity Entity to add component to
398 * @param component Component to move
399 */
400 template <ComponentTrait T>
401 void AddComponent(Entity entity, T&& component);
402
403 /**
404 * @brief Constructs component in-place for entity.
405 * @details Creates component by forwarding arguments to T's constructor.
406 * Creates storage if needed. If entity already has this component type, it will be replaced.
407 * Time complexity: O(1) amortized.
408 * @warning Triggers assertion if entity is invalid.
409 * @tparam T Component type to construct
410 * @tparam Args Argument types for T's constructor
411 * @param entity Entity to add component to
412 * @param args Arguments to forward to component constructor
413 */
414 template <ComponentTrait T, typename... Args>
415 requires std::constructible_from<T, Args...>
416 void EmplaceComponent(Entity entity, Args&&... args);
417
418 /**
419 * @brief Removes component from entity.
420 * @details Removes the specified component type from the entity.
421 * Time complexity: O(1).
422 * @warning Triggers assertion if entity is invalid or doesn't have the component.
423 * @tparam T Component type to remove
424 * @param entity Entity to remove component from
425 */
426 template <ComponentTrait T>
427 void RemoveComponent(Entity entity);
428
429 /**
430 * @brief Gets mutable reference to entity's component.
431 * @details Returns direct reference to the component for modification.
432 * Time complexity: O(1).
433 * @warning Triggers assertion if entity is invalid or doesn't have the component.
434 * @tparam T Component type to get
435 * @param entity Entity to get component from
436 * @return Mutable reference to the component
437 */
438 template <ComponentTrait T>
440 return GetStorage<T>().Get(entity);
441 }
442
443 /**
444 * @brief Gets const reference to entity's component.
445 * @details Returns direct const reference to the component for read-only access.
446 * Time complexity: O(1).
447 * @warning Triggers assertion if entity is invalid or doesn't have the component.
448 * @tparam T Component type to get
449 * @param entity Entity to get component from
450 * @return Const reference to the component
451 */
452 template <ComponentTrait T>
453 [[nodiscard]] const T& GetComponent(Entity entity) const {
454 return GetStorage<T>().Get(entity);
455 }
456
457 /**
458 * @brief Attempts to get mutable pointer to entity's component.
459 * @details Returns pointer to component if it exists, nullptr otherwise.
460 * Time complexity: O(1).
461 * @warning Triggers assertion if entity is invalid.
462 * @tparam T Component type to get
463 * @param entity Entity to get component from
464 * @return Pointer to component, or nullptr if entity doesn't have the component
465 */
466 template <ComponentTrait T>
467 [[nodiscard]] T* TryGetComponent(Entity entity);
468
469 /**
470 * @brief Attempts to get const pointer to entity's component.
471 * @details Returns const pointer to component if it exists, nullptr otherwise.
472 * Time complexity: O(1).
473 * @warning Triggers assertion if entity is invalid.
474 * @tparam T Component type to get
475 * @param entity Entity to get component from
476 * @return Const pointer to component, or nullptr if entity doesn't have the component
477 */
478 template <ComponentTrait T>
479 [[nodiscard]] const T* TryGetComponent(Entity entity) const;
480
481 /**
482 * @brief Checks if entity has the specified component type.
483 * @details Performs fast lookup to determine if entity has a component of type T.
484 * Time complexity: O(1) average case.
485 * @warning Triggers assertion if entity is invalid.
486 * @tparam T Component type to check
487 * @param entity Entity to check
488 * @return True if entity has component of type T, false otherwise
489 */
490 template <ComponentTrait T>
491 [[nodiscard]] bool HasComponent(Entity entity) const;
492
493 /**
494 * @brief Gets typed storage for component type T.
495 * @details Returns reference to the ComponentStorage<T> for direct access.
496 * Time complexity: O(1) average case.
497 * @warning Triggers assertion if storage doesn't exist for type T.
498 * @tparam T Component type
499 * @return Reference to ComponentStorage<T>
500 */
501 template <ComponentTrait T>
502 [[nodiscard]] ComponentStorage<T>& GetStorage();
503
504 /**
505 * @brief Gets const typed storage for component type T.
506 * @details Returns const reference to the ComponentStorage<T> for read-only access.
507 * Time complexity: O(1) average case.
508 * @warning Triggers assertion if storage doesn't exist for type T.
509 * @tparam T Component type
510 * @return Const reference to ComponentStorage<T>
511 */
512 template <ComponentTrait T>
513 [[nodiscard]] const ComponentStorage<T>& GetStorage() const;
514
515 /**
516 * @brief Gets all component types for the specified entity.
517 * @details Scans all storages to build list of component types present on entity.
518 * Used for archetype management and debugging.
519 * Time complexity: O(S) where S is the number of component types.
520 * @param entity Entity to get component types for
521 * @return Vector of ComponentTypeInfo for all components on the entity
522 */
523 [[nodiscard]] std::vector<ComponentTypeInfo> GetComponentTypes(Entity entity) const;
524
525private:
526 /**
527 * @brief Gets or creates storage for component type T.
528 * @details Finds existing storage or creates new ComponentStorage<T> if needed.
529 * Time complexity: O(1) average case.
530 * @tparam T Component type
531 * @return Reference to ComponentStorage<T> (existing or newly created)
532 */
533 template <ComponentTrait T>
534 [[nodiscard]] ComponentStorage<T>& GetOrCreateStorage();
535
536 /// Map from component type ID to type-erased storage
537 std::unordered_map<ComponentTypeId, std::unique_ptr<ComponentStorageBase>> storages_;
538};
539
541 HELIOS_ASSERT(entity.Valid(), "Failed to remove all components from entity: Entity with index '{}' is invalid!",
542 entity.Index());
543 for (auto& [_, storage] : storages_) {
544 storage->TryRemove(entity);
545 }
546}
547
548template <ComponentTrait T>
549inline void Components::AddComponent(Entity entity, T&& component) {
550 using ComponentType = std::decay_t<T>;
551 HELIOS_ASSERT(entity.Valid(), "Failed to add component '{}': Entity with index '{}' is invalid!",
553 GetOrCreateStorage<ComponentType>().Insert(entity, std::forward<T>(component));
554}
555
556template <ComponentTrait T, typename... Args>
557 requires std::constructible_from<T, Args...>
558inline void Components::EmplaceComponent(Entity entity, Args&&... args) {
559 HELIOS_ASSERT(entity.Valid(), "Failed to emplace component '{}': Entity with index '{}' is invalid!",
560 ComponentNameOf<T>(), entity.Index());
561 GetOrCreateStorage<T>().Emplace(entity, std::forward<Args>(args)...);
562}
563
564template <ComponentTrait T>
566 HELIOS_ASSERT(entity.Valid(), "Failed to remove component '{}': Entity with index '{}' is invalid!",
567 ComponentNameOf<T>(), entity.Index());
568 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
569 if (const auto it = storages_.find(type_id); it != storages_.end()) {
570 static_cast<ComponentStorage<T>&>(*it->second).Remove(entity);
571 } else {
572 HELIOS_ASSERT(false, "Failed to remove component '{}': Entity with index '{}' does not have this component!",
573 ComponentNameOf<T>(), entity.Index());
574 }
575}
576
577template <ComponentTrait T>
579 HELIOS_ASSERT(entity.Valid(), "Failed to try get component '{}': Entity with index '{}' is invalid!",
580 ComponentNameOf<T>(), entity.Index());
581 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
582 if (const auto it = storages_.find(type_id); it != storages_.end()) {
583 return static_cast<ComponentStorage<T>&>(*it->second).TryGet(entity);
584 }
585 return nullptr;
586}
587
588template <ComponentTrait T>
589inline const T* Components::TryGetComponent(Entity entity) const {
590 HELIOS_ASSERT(entity.Valid(), "Failed to try get component '{}': Entity with index '{}' is invalid!",
591 ComponentNameOf<T>(), entity.Index());
592 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
593 if (const auto it = storages_.find(type_id); it != storages_.end()) {
594 return static_cast<const ComponentStorage<T>&>(*it->second).TryGet(entity);
595 }
596 return nullptr;
597}
598
599template <ComponentTrait T>
600inline bool Components::HasComponent(Entity entity) const {
601 HELIOS_ASSERT(entity.Valid(), "Failed to check if entity has component '{}': Entity with index '{}' is invalid!",
602 ComponentNameOf<T>(), entity.Index());
603 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
604 if (const auto it = storages_.find(type_id); it != storages_.end()) {
605 return static_cast<const ComponentStorage<T>&>(*it->second).Contains(entity);
606 }
607 return false;
608}
609
610template <ComponentTrait T>
612 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
613 const auto it = storages_.find(type_id);
614 HELIOS_ASSERT(it != storages_.end(), "Failed to get storage: Component '{}' storage does not exist!",
616 return static_cast<ComponentStorage<T>&>(*it->second);
617}
618
619template <ComponentTrait T>
621 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
622 const auto it = storages_.find(type_id);
623 HELIOS_ASSERT(it != storages_.end(), "Failed to get storage: Component '{}' storage does not exist!",
625 return static_cast<const ComponentStorage<T>&>(*it->second);
626}
627
628inline std::vector<ComponentTypeInfo> Components::GetComponentTypes(Entity entity) const {
629 std::vector<ComponentTypeInfo> types;
630 types.reserve(storages_.size()); // Reserve worst-case size
631
632 for (const auto& [_, storage] : storages_) {
633 if (storage->Contains(entity)) {
634 types.push_back(storage->GetTypeInfo());
635 }
636 }
637
638 types.shrink_to_fit(); // Reduce to actual size
639 return types;
640}
641
642template <ComponentTrait T>
643inline ComponentStorage<T>& Components::GetOrCreateStorage() {
644 const ComponentTypeId type_id = ComponentTypeIdOf<T>();
645 const auto [it, inserted] = storages_.try_emplace(type_id, nullptr);
646 if (inserted) {
647 it->second = std::make_unique<ComponentStorage<T>>();
648 }
649 return static_cast<ComponentStorage<T>&>(*it->second);
650}
651
652} // namespace helios::ecs::details
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140
typename dense_container_type::iterator iterator
typename dense_container_type::const_iterator const_iterator
iterator begin() const
Gets iterator to first matching entity.
Definition query.hpp:2317
iterator end() const noexcept
Gets iterator past the last matching entity.
Definition query.hpp:1603
Component type info for runtime operations.
Unique identifier for entities with generation counter to handle recycling.
Definition entity.hpp:21
constexpr bool Valid() const noexcept
Checks if the entity is valid.
Definition entity.hpp:58
constexpr IndexType Index() const noexcept
Gets the index component of the entity.
Definition entity.hpp:75
Base class for type-erased component storage.
virtual ComponentTypeInfo GetTypeInfo() const noexcept=0
Gets type information for the component type stored.
virtual void Clear() noexcept=0
Clears all components from storage.
virtual bool Contains(Entity entity) const =0
Checks if entity has a component in this storage.
virtual void Remove(Entity entity)=0
Removes component for the specified entity.
virtual bool TryRemove(Entity entity)=0
Attempts to remove component for the specified entity.
virtual size_t Size() const noexcept=0
Gets the number of components in storage.
Type-specific component storage using sparse set.
typename SparseSetType::const_iterator ConstIterator
ComponentStorage(const ComponentStorage &)=default
T * TryGet(Entity entity)
Attempts to get mutable pointer to component for the specified entity.
T & Get(Entity entity)
Gets mutable reference to component for the specified entity.
size_t Size() const noexcept override
Gets the number of components stored.
std::span< T > Data() noexcept
Gets mutable span over all stored components.
ComponentStorage(ComponentStorage &&) noexcept=default
void Remove(Entity entity) override
Removes component from the specified entity.
void Emplace(Entity entity, Args &&... args)
Constructs component in-place for the specified entity.
constexpr ComponentTypeInfo GetTypeInfo() const noexcept override
Gets compile-time type information for component T.
ConstIterator cbegin() const noexcept
std::span< const T > Data() const noexcept
Gets const span over all stored components.
void Insert(Entity entity, const T &component)
Inserts component for the specified entity (copy version).
bool Contains(Entity entity) const override
Checks if entity has a component in this storage.
bool TryRemove(Entity entity) override
Attempts to remove component from the specified entity.
Manager for all component storages in the ECS world.
void RemoveAllComponents(Entity entity)
Removes all components from the specified entity.
Components & operator=(Components &&)=default
void EmplaceComponent(Entity entity, Args &&... args)
Constructs component in-place for entity.
const T & GetComponent(Entity entity) const
Gets const reference to entity's component.
Components(const Components &)=delete
void Clear() noexcept
Clears all component storages.
std::vector< ComponentTypeInfo > GetComponentTypes(Entity entity) const
Gets all component types for the specified entity.
ComponentStorage< T > & GetStorage()
Gets typed storage for component type T.
T & GetComponent(Entity entity)
Gets mutable reference to entity's component.
bool HasComponent(Entity entity) const
Checks if entity has the specified component type.
void AddComponent(Entity entity, T &&component)
Adds component to entity (move version).
Components & operator=(const Components &)=delete
void RemoveComponent(Entity entity)
Removes component from entity.
T * TryGetComponent(Entity entity)
Attempts to get mutable pointer to entity's component.
Components(Components &&)=default
Iterator for query results without entity information.
Definition query.hpp:129
Concept to check if a type can be used as a component.
Definition component.hpp:39
size_t ComponentTypeId
Type ID for components.
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481