Skip to main content

EntityPoolManager.ixx File

Manager for Entity pooling and lifecycle management. More...

Included Headers

#include <cassert> #include <memory> #include <optional> #include <stdexcept> #include <unordered_map> #include <cstddef> #include <helios.engine.runtime.world.tags> #include <helios.engine.core.types> #include <helios.ecs.types.EntityHandle> #include <helios.engine.runtime.pooling.components.PrefabIdComponent> #include <helios.engine.runtime.pooling.EntityPoolRegistry> #include <helios.engine.runtime.pooling.EntityPoolSnapshot> #include <helios.engine.runtime.pooling.EntityPool> #include <helios.engine.runtime.messaging.command.CommandHandlerRegistry> #include <helios.engine.runtime.pooling.EntityPoolConfig> #include <helios.engine.runtime.world.EngineWorld> #include <helios.engine.runtime.world.UpdateContext> #include <helios.engine.runtime.pooling.types.EntityPoolId> #include <helios.ecs.Entity>

Namespaces Index

namespacehelios
namespaceengine
namespaceruntime
namespacepooling

Classes Index

classEntityPoolManager<TEntity>

High-level manager for Entity pooling operations. More...

Description

Manager for Entity pooling and lifecycle management.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <cassert>
8#include <memory>
9#include <optional>
10#include <stdexcept>
11#include <unordered_map>
12#include <cstddef>
13
14
15export module helios.engine.runtime.pooling.EntityPoolManager;
16
17import helios.ecs.Entity;
18import helios.engine.runtime.pooling.types.EntityPoolId;
19
20import helios.engine.runtime.world.UpdateContext;
21
22import helios.engine.runtime.world.EngineWorld;
23import helios.engine.runtime.pooling.EntityPool;
24import helios.engine.runtime.pooling.EntityPoolRegistry;
25
26import helios.engine.runtime.pooling.EntityPoolConfig;
27import helios.engine.runtime.pooling.components.PrefabIdComponent;
28
29import helios.engine.runtime.messaging.command.CommandHandlerRegistry;
30
31
32import helios.ecs.types.EntityHandle;
33import helios.engine.core.types;
34import helios.engine.runtime.world.tags;
35
36import helios.engine.runtime.pooling.EntityPoolSnapshot;
37
40
110 template<typename TEntity>
112
113 using Handle_type = typename TEntity::Handle_type;
114 using Entity_type = TEntity;
115
123
130 helios::engine::runtime::world::EngineWorld* engineWorld_ = nullptr;
131
138 std::unordered_map<
140 std::unique_ptr<EntityPoolConfig>> poolConfigs_;
141
162 void fillPool(
165 ) {
166 Handle_type entityHandle{};
167
168 auto* entityPool = pool(entityPoolId);
169
170 const size_t used = entityPool->activeCount() + entityPool->inactiveCount();
171 const size_t space = used < entityPool->size() ? entityPool->size() - used : 0;
172
173 for (size_t i = 0; i < space; i++) {
174 Entity_type go = engineWorld_->clone(entityPrefab.handle());
175 go.setActive(false);
176 go.onRelease();
177 entityPool->addInactive(go.handle());
178 }
179
180 entityPool->lock();
181 }
182
183 public:
185
186
187 explicit EntityPoolManager(helios::engine::runtime::world::EngineWorld& engineWorld) : engineWorld_(&engineWorld) {}
188
201 EntityPoolManager& addPoolConfig(std::unique_ptr<EntityPoolConfig> entityPoolConfig) {
202
203 if (poolConfigs_.contains(entityPoolConfig->entityPoolId)) {
204 throw std::runtime_error("Pool already registered with this manager");
205 }
206
207 poolConfigs_[entityPoolConfig->entityPoolId] = std::move(entityPoolConfig);
208
209 return *this;
210 }
211
224 ) const {
225 auto* entityPool = pool(entityPoolId);
226
227 return {
228 entityPool->activeCount(), entityPool->inactiveCount()
229 };
230 }
231
245 std::optional<TEntity> release(
247 const Handle_type& entityHandle
248 ) {
249 auto* entityPool = pool(entityPoolId);
250
251 auto worldGo = engineWorld_->find<Handle_type>(entityHandle);
252
253 if (worldGo) {
254 if (entityPool->release(entityHandle)) {
255 worldGo->onRelease();
256 worldGo->setActive(false);
257 }
258 }
259
260 return worldGo;
261 }
262
278 [[nodiscard]] std::optional<TEntity> acquire(
280 ) {
281 Handle_type entityHandle{};
282
283 auto* entityPool = pool(entityPoolId);
284
285 while (entityPool->acquire(entityHandle)) {
286
287 auto worldGo = engineWorld_->find(entityHandle);
288
289 if (worldGo) {
290 worldGo->onAcquire();
291 return worldGo;
292 }
293
294 // we assume the pool is owned by this gameWorld,
295 // so removing this entityHandle does not impact another gameWorld that is
296 // using this pool
297 entityPool->releaseAndRemove(entityHandle);
298 }
299
300 return std::nullopt;
301
302 }
303
312 void init(CommandHandlerRegistry& commandHandlerRegistry) {
313
314
315 for (const auto& [entityPoolId, poolConfig] : poolConfigs_) {
316
317 auto pool = std::make_unique<helios::engine::runtime::pooling::EntityPool<Handle_type>>(
318 poolConfig->amount);
319
320 pools_.addPool(entityPoolId, std::move(pool));
321
322 for (auto [entity, pic] : engineWorld_->view<
323 Handle_type,
325 if (pic->prefabId() == poolConfig->prefabId) {
326 fillPool(entityPoolId, entity);
327 break;
328 }
329 }
330
331 }
332
333 };
334
344 void flush(
346 ) noexcept {
347
348 }
349
361 ) const {
362 assert(pools_.has(entityPoolId) && "EntityPoolId not registered with this manager");
363 return pools_.pool(entityPoolId);
364 }
365
378 void reset() {
379 for (auto& [poolId, _] : pools_.pools()) {
381 }
382 }
383
394
395 const auto poolPtr = pool(poolId);
396
397 auto activeSpan = poolPtr->activeEntities();
398 auto toRelease = std::vector(activeSpan.begin(), activeSpan.end());
399 for (auto entityHandle : toRelease) {
401 }
402 }
403 };
404
405}
406

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.