Skip to main content

EntityRegistry Class Template

Generic registry for creating and managing strongly-typed entity handles. More...

Declaration

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY> class helios::ecs::EntityRegistry<TStrongId, TLookupStrategy, TAllowRemoval, TCapacity> { ... }

Public Constructors Index

template < ... >
EntityRegistry (const size_t capacity=TCapacity)

Constructs a registry with pre-allocated capacity. More...

Public Member Functions Index

template < ... >
auto create (TStrongId strongId=TStrongId{}) -> EntityHandle< TStrongId >

Creates a new entity and returns its handle. More...

template < ... >
VersionIdversion (const EntityId entityId) const

Looks up the version for an EntityId. More...

template < ... >
TStrongIdstrongId (const EntityId entityId) const

Looks up the strong ID for an entity index. More...

template < ... >
boolisValid (const EntityHandle< TStrongId > handle) const noexcept

Checks whether the given handle refers to a currently alive entity. More...

template < ... >
booldestroy (const EntityHandle< TStrongId > handle)

Destroys the entity referenced by the given handle. More...

Private Member Attributes Index

template < ... >
std::vector< EntityId >freeList_

Free list of recycled entity indices available for reuse. More...

template < ... >
std::vector< VersionId >versions_

Version numbers for each entity slot. More...

template < ... >
std::vector< StrongId_t >strongIds_

Strong ID values for each entity slot. More...

template < ... >
TLookupStrategylookupStrategy_

Lookup strategy instance for strong ID collision detection. More...

template < ... >
size_tstrongIdCounter_ = 0

Auto-increment counter for generating strong IDs when none is provided. More...

Description

Generic registry for creating and managing strongly-typed entity handles.

`EntityRegistry` serves as the authoritative source for entity lifecycle management. It is responsible for:

  • **Handle Creation:** Generates unique `EntityHandle` instances with versioned IDs and domain-specific strong IDs.
  • **Validation:** Determines whether a given handle refers to a currently alive entity.
  • **Destruction:** Marks entities as destroyed by incrementing their version and recycling the index for future use (when `TAllowRemoval` is true).

## Versioning

Each entity slot maintains a version number. When an entity is destroyed, its version is incremented. This allows the registry to detect stale handles — handles that reference an entity that has been destroyed and potentially replaced by a new entity at the same index.

## Index Recycling

Destroyed entity indices are added to a free list and reused when creating new entities. This keeps the dense version array compact and minimizes memory growth.

## Strong ID Collision Detection

The registry delegates collision checks to a configurable `TLookupStrategy`, which tracks which strong IDs are currently in use. The default strategy (`HashedLookupStrategy`) provides O(1) amortized lookups.

Template Parameters
TStrongId

A strong ID type carrying domain semantics.

TLookupStrategy

The strategy used for strong ID collision detection.

TAllowRemoval

If false, `destroy()` triggers an assertion instead of removing.

TCapacity

Default initial capacity for pre-allocation.

See Also

EntityHandle

See Also

HashedLookupStrategy

See Also

LinearLookupStrategy

Definition at line 74 of file EntityRegistry.ixx.

Public Constructors

EntityRegistry()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::EntityRegistry (const size_t capacity=TCapacity)
inline explicit

Constructs a registry with pre-allocated capacity.

Reserving capacity upfront can improve performance when the approximate number of entities is known in advance.

Parameters
capacity

The initial capacity to reserve.

Definition at line 117 of file EntityRegistry.ixx.

117 explicit EntityRegistry(const size_t capacity = TCapacity)
118 : lookupStrategy_(capacity) {
119 versions_.reserve(capacity);
120 strongIds_.reserve(capacity);
121 freeList_.reserve(capacity);
122 }

Public Member Functions

create()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
EntityHandle< TStrongId > helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::create (TStrongId strongId=TStrongId{})
inline

Creates a new entity and returns its handle.

If recycled indices are available in the free list, one is reused. Otherwise, a new index is allocated at the end of the version vector. If the provided `strongId` is invalid, one is auto-assigned from the entity index.

Parameters
strongId

Optional domain-specific strong ID. Defaults to auto-assignment.

Returns

A valid `EntityHandle` for the newly created entity.

Definition at line 137 of file EntityRegistry.ixx.

137 EntityHandle<TStrongId> create(TStrongId strongId = TStrongId{}) {
138
139 EntityId idx;
141
142 if (freeList_.empty()) {
143 idx = static_cast<EntityId>(versions_.size());
145 versions_.push_back(version);
146 strongIds_.push_back(StrongId_t{});
147 } else {
148 idx = freeList_.back();
149 freeList_.pop_back();
150
151 // version was already incremented in destroy
152 version = versions_[idx];
153 }
154
155 if (!strongId.isValid()) {
156 strongId = TStrongId{static_cast<StrongId_t>(++strongIdCounter_)};
157 }
158 assert(strongId.isValid() && "EntityRegistry: invalid strongId");
159
160 assert(!lookupStrategy_.has(strongId.value()) && "EntityRegistry: strongId collision");
161
162 strongIds_[idx] = strongId.value();
163
164 const bool added = lookupStrategy_.add(strongId.value());
165
166 assert(added && "EntityRegistry: failed to add strongId to lookupStrategy");
167
168 return {idx, version, strongId};
169
170 }

Reference helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::strongId.

destroy()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
bool helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::destroy (const EntityHandle< TStrongId > handle)
inline

Destroys the entity referenced by the given handle.

If the handle is valid, the entity's version is incremented (invalidating all existing handles to it), the strong ID is unregistered, and the index is added to the free list for recycling.

If `TAllowRemoval` is false, triggers an assertion failure.

Parameters
handle

The handle of the entity to destroy.

Returns

True if the entity was successfully destroyed, false if the handle was already invalid.

Definition at line 240 of file EntityRegistry.ixx.

240 bool destroy(const EntityHandle<TStrongId> handle) {
241
242 if constexpr (!TAllowRemoval) {
243 assert(false && "EntityRegistry: Entity removal is not allowed");
244 return false;
245 }
246
247 if (!isValid(handle)) {
248 return false;
249 }
250
251 const auto index = handle.entityId;
252
253 versions_[index] += 1;
254 strongIds_[index] = 0;
255
256 const bool removed = lookupStrategy_.remove(handle.strongId.value());
257 assert(removed && "EntityRegistry: failed to remove strongId from lookupStrategy");
258
259 freeList_.push_back(index);
260
261 return true;
262 }

References helios::ecs::types::EntityHandle< TStrongId >::entityId, helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::isValid and helios::ecs::types::EntityHandle< TStrongId >::strongId.

isValid()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
bool helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::isValid (const EntityHandle< TStrongId > handle)
inline nodiscard noexcept

Checks whether the given handle refers to a currently alive entity.

A handle is valid if its index is within bounds, its version matches the current version stored in the registry, and its strong ID matches the registered value.

Parameters
handle

The handle to validate.

Returns

True if the handle is valid and the entity is alive.

Definition at line 213 of file EntityRegistry.ixx.

213 [[nodiscard]] bool isValid(const EntityHandle<TStrongId> handle) const noexcept {
214 const auto index = handle.entityId;
215
216 if (index >= static_cast<EntityId>(versions_.size())) {
217 return false;
218 }
219
220 return handle.strongId.value() == strongIds_[index] &&
221 handle.versionId == versions_[index] &&
222 handle.strongId.isValid();
223 }

Referenced by helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::destroy.

strongId()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
TStrongId helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::strongId (const EntityId entityId)
inline nodiscard

Looks up the strong ID for an entity index.

Parameters
entityId

The entity index to retrieve the strong ID for.

Returns

The strong ID for the entity, or a default-constructed (invalid) `TStrongId` if out of bounds.

Definition at line 194 of file EntityRegistry.ixx.

194 [[nodiscard]] TStrongId strongId(const EntityId entityId) const {
195 if (entityId >= static_cast<EntityId>(strongIds_.size())) {
196 return TStrongId{};
197 }
198 return static_cast<TStrongId>(strongIds_[entityId]);
199 }

Referenced by helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::create.

version()

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
VersionId helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::version (const EntityId entityId)
inline nodiscard

Looks up the version for an EntityId.

Parameters
entityId

The entity to retrieve the version for.

Returns

The version for the EntityId, or `InvalidVersion` if not found.

Definition at line 179 of file EntityRegistry.ixx.

179 [[nodiscard]] VersionId version(const EntityId entityId) const {
180 if (entityId >= static_cast<EntityId>(versions_.size())) {
181 return InvalidVersion;
182 }
183 return versions_[entityId];
184 }

Reference helios::ecs::types::InvalidVersion.

Private Member Attributes

freeList_

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
std::vector<EntityId> helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::freeList_

Free list of recycled entity indices available for reuse.

Definition at line 80 of file EntityRegistry.ixx.

80 std::vector<EntityId> freeList_;

lookupStrategy_

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
TLookupStrategy helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::lookupStrategy_

Lookup strategy instance for strong ID collision detection.

Definition at line 100 of file EntityRegistry.ixx.

100 TLookupStrategy lookupStrategy_;

strongIdCounter_

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
size_t helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::strongIdCounter_ = 0

Auto-increment counter for generating strong IDs when none is provided.

Definition at line 105 of file EntityRegistry.ixx.

105 size_t strongIdCounter_ = 0;

strongIds_

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
std::vector<StrongId_t> helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::strongIds_

Strong ID values for each entity slot.

Definition at line 95 of file EntityRegistry.ixx.

95 std::vector<StrongId_t> strongIds_;

versions_

template <typename TStrongId, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
std::vector<VersionId> helios::ecs::EntityRegistry< TStrongId, TLookupStrategy, TAllowRemoval, TCapacity >::versions_

Version numbers for each entity slot.

The version is incremented when an entity at that index is destroyed, allowing detection of stale handles.

Definition at line 89 of file EntityRegistry.ixx.

89 std::vector<VersionId> versions_;

The documentation for this class was generated from the following file:


Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.