Skip to main content

EntityRegistry Class Template

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

Declaration

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY> class helios::ecs::EntityRegistry<TDomainTag, 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 (StrongId< TDomainTag > strongId=StrongId< TDomainTag >{}) -> EntityHandle< TDomainTag >

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

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

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

template < ... >
auto strongId (const EntityId entityId) const -> StrongId< TDomainTag >

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

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

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

template < ... >
booldestroy (const EntityHandle< TDomainTag > 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<TDomainTag> 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).

Definition at line 76 of file EntityRegistry.ixx.

Public Constructors

EntityRegistry()

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
helios::ecs::EntityRegistry< TDomainTag, 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 119 of file EntityRegistry.ixx.

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

Public Member Functions

create()

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
EntityHandle< TDomainTag > helios::ecs::EntityRegistry< TDomainTag, TLookupStrategy, TAllowRemoval, TCapacity >::create (StrongId< TDomainTag > strongId=StrongId< TDomainTag >{})
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 139 of file EntityRegistry.ixx.

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

destroy()

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
bool helios::ecs::EntityRegistry< TDomainTag, TLookupStrategy, TAllowRemoval, TCapacity >::destroy (const EntityHandle< TDomainTag > 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 242 of file EntityRegistry.ixx.

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

References helios::ecs::types::EntityHandle< TDomainTag >::entityId, helios::ecs::EntityRegistry< TDomainTag, TLookupStrategy, TAllowRemoval, TCapacity >::isValid, helios::ecs::types::EntityHandle< TDomainTag >::strongId and helios::ecs::types::StrongId< Tag >::value.

isValid()

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
bool helios::ecs::EntityRegistry< TDomainTag, TLookupStrategy, TAllowRemoval, TCapacity >::isValid (const EntityHandle< TDomainTag > handle)
inline 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 215 of file EntityRegistry.ixx.

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

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

strongId()

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

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) StrongId<TDomainTag> if out of bounds.

Definition at line 196 of file EntityRegistry.ixx.

196 [[nodiscard]] StrongId<TDomainTag> strongId(const EntityId entityId) const {
197 if (entityId >= static_cast<EntityId>(strongIds_.size())) {
198 return StrongId<TDomainTag>{};
199 }
200 return static_cast<StrongId<TDomainTag>>(strongIds_[entityId]);
201 }

version()

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

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 181 of file EntityRegistry.ixx.

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

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

Private Member Attributes

freeList_

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

Free list of recycled entity indices available for reuse.

Definition at line 82 of file EntityRegistry.ixx.

82 std::vector<EntityId> freeList_;

lookupStrategy_

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

Lookup strategy instance for strong ID collision detection.

Definition at line 102 of file EntityRegistry.ixx.

102 TLookupStrategy lookupStrategy_;

strongIdCounter_

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

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

Definition at line 107 of file EntityRegistry.ixx.

107 size_t strongIdCounter_ = 0;

strongIds_

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

Strong ID values for each entity slot.

Definition at line 97 of file EntityRegistry.ixx.

97 std::vector<StrongId_t> strongIds_;

versions_

template <typename TDomainTag, typename TLookupStrategy = HashedLookupStrategy, bool TAllowRemoval = true, size_t TCapacity = DEFAULT_ENTITY_MANAGER_CAPACITY>
std::vector<VersionId> helios::ecs::EntityRegistry< TDomainTag, 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 91 of file EntityRegistry.ixx.

91 std::vector<VersionId> versions_;

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


Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.