Skip to main content

SpawnManager Class

Manager for processing spawn and despawn commands. More...

Declaration

class helios::engine::runtime::spawn::SpawnManager { ... }

Base classes

classManager

Abstract base class for managers that process deferred operations. More...

classSpawnCommandHandler

Interface for handlers that process spawn and despawn commands. More...

Public Constructors Index

SpawnManager ()=default

Default constructor. More...

Public Member Functions Index

boolsubmit (const helios::engine::runtime::spawn::commands::SpawnCommand &command) noexcept override

Submits a spawn command for deferred processing. More...

boolsubmit (const helios::engine::runtime::spawn::commands::DespawnCommand &command) noexcept override

Submits a despawn command for deferred processing. More...

boolsubmit (const helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand &scheduledSpawnPlanCommand) noexcept override

Submits a scheduled spawn plan command for deferred processing. More...

voidflush (helios::engine::runtime::world::GameWorld &gameWorld, helios::engine::runtime::world::UpdateContext &updateContext) noexcept override

Flushes pending commands, processing despawns then spawns. More...

SpawnManager &addSpawnProfile (const helios::engine::core::data::SpawnProfileId &spawnProfileId, std::unique_ptr< const helios::engine::runtime::spawn::SpawnProfile > spawnProfile)

Adds a spawn profile for a profile ID. More...

const helios::engine::runtime::spawn::SpawnProfile *spawnProfile (const helios::engine::core::data::SpawnProfileId &spawnProfileId) const

Returns a spawn profile by ID. More...

voidinit (helios::engine::runtime::world::GameWorld &gameWorld) noexcept override

Initializes the manager with the game world. More...

Private Member Functions Index

voidensureBounds (helios::engine::ecs::GameObject go, helios::math::aabbf &bounds)

Ensures that the bounds are properly computed.. More...

voidexecuteScheduledSpawnPlanCommands (std::span< helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand > commands, helios::engine::runtime::world::GameWorld &gameWorld, helios::engine::runtime::world::UpdateContext &updateContext)

Processes scheduled spawn plan commands. More...

voidspawnObjects (std::span< helios::engine::runtime::spawn::commands::SpawnCommand > commands, helios::engine::runtime::world::GameWorld &gameWorld, helios::engine::runtime::world::UpdateContext &updateContext)

Processes spawn commands, acquiring and initializing objects. More...

voiddespawnObjects (std::span< helios::engine::runtime::spawn::commands::DespawnCommand > commands, helios::engine::runtime::world::GameWorld &gameWorld, helios::engine::runtime::world::UpdateContext &updateContext)

Processes despawn commands, releasing objects back to pools. More...

Private Member Attributes Index

std::vector< helios::engine::runtime::spawn::commands::SpawnCommand >spawnCommands_

Queue of pending spawn commands. More...

std::vector< helios::engine::runtime::spawn::commands::DespawnCommand >despawnCommands_

Queue of pending despawn commands. More...

std::vector< helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand >scheduledSpawnPlanCommands_

Queue of pending scheduled spawn plan commands. More...

helios::engine::runtime::pooling::GameObjectPoolManager *gameObjectPoolManager_ = nullptr

Pointer to the pool manager for acquire/release operations. More...

std::unordered_map< helios::engine::core::data::SpawnProfileId, std::unique_ptr< const helios::engine::runtime::spawn::SpawnProfile > >spawnProfiles_

Map from profile IDs to their spawn profiles. More...

Description

Manager for processing spawn and despawn commands.

SpawnManager is a Manager that handles the lifecycle of pooled GameObjects. It receives commands via SpawnCommandHandler::submit() and queues them for deferred processing during the manager flush phase.

## Command Processing Order

During flush(), commands are processed in this order: 1. **Despawn commands** — Entities are returned to their pools 2. **Spawn commands** — Single entities are acquired and initialized 3. **Scheduled spawn plan commands** — Batch spawns from scheduler

## Spawn Profiles

Each spawn profile defines:

  • Which pool to acquire entities from
  • How to position spawned entities (SpawnPlacer)
  • How to initialize spawned entities (SpawnInitializer)

## Integration

SpawnManager registers itself with the GameWorld for each profile ID, allowing commands to route to the correct handler.

Example: ```cpp auto spawnManager = std::make_unique<SpawnManager>();

spawnManager->addSpawnProfile(bulletProfileId, std::make_unique<SpawnProfile>( SpawnProfile{ .gameObjectPoolId = bulletPoolId, .spawnPlacer = std::make_unique<EmitterSpawnPlacer>(), .spawnInitializer = std::make_unique<EmitterInitializer>() } ));

gameWorld.addManager(std::move(spawnManager)); ```

See Also

SpawnCommand

See Also

DespawnCommand

See Also

ScheduledSpawnPlanCommand

See Also

SpawnProfile

See Also

SpawnCommandHandler

Definition at line 96 of file SpawnManager.ixx.

Public Constructors

SpawnManager()

helios::engine::runtime::spawn::SpawnManager::SpawnManager ()
default

Default constructor.

Definition at line 356 of file SpawnManager.ixx.

Referenced by addSpawnProfile.

Public Member Functions

addSpawnProfile()

SpawnManager & helios::engine::runtime::spawn::SpawnManager::addSpawnProfile (const helios::engine::core::data::SpawnProfileId & spawnProfileId, std::unique_ptr< const helios::engine::runtime::spawn::SpawnProfile > spawnProfile)
inline

Adds a spawn profile for a profile ID.

Registers a spawn profile that defines how entities should be spawned for this profile. The profile contains the pool ID, placer, and initializer.

Parameters
spawnProfileId

The unique ID for this profile.

spawnProfile

The profile configuration. Ownership transferred.

Returns

Reference to this manager for chaining.

Precondition

No profile is already registered for this ID.

Definition at line 438 of file SpawnManager.ixx.

440 std::unique_ptr<const helios::engine::runtime::spawn::SpawnProfile> spawnProfile) {
441
442 assert(!spawnProfiles_.contains(spawnProfileId) && "SpawnProfileId already added");
443
444 spawnProfiles_[spawnProfileId] = std::move(spawnProfile);
445
446 return *this;
447 }

References SpawnManager and spawnProfile.

flush()

void helios::engine::runtime::spawn::SpawnManager::flush (helios::engine::runtime::world::GameWorld & gameWorld, helios::engine::runtime::world::UpdateContext & updateContext)
inline noexcept virtual

Flushes pending commands, processing despawns then spawns.

Parameters
gameWorld

The game world.

updateContext

The current update context.

Definition at line 403 of file SpawnManager.ixx.

403 void flush(
406 ) noexcept override {
407 if (!despawnCommands_.empty()) {
408 despawnObjects(despawnCommands_, gameWorld, updateContext);
409 despawnCommands_.clear();
410 }
411
412 if (!spawnCommands_.empty()) {
413 spawnObjects(spawnCommands_, gameWorld, updateContext);
414 spawnCommands_.clear();
415 }
416
417 if (!scheduledSpawnPlanCommands_.empty()) {
418 executeScheduledSpawnPlanCommands(scheduledSpawnPlanCommands_, gameWorld, updateContext);
419 scheduledSpawnPlanCommands_.clear();
420 }
421 };

init()

void helios::engine::runtime::spawn::SpawnManager::init (helios::engine::runtime::world::GameWorld & gameWorld)
inline noexcept virtual

Initializes the manager with the game world.

Acquires a reference to the GameObjectPoolManager and registers this manager as the SpawnCommandHandler for all configured spawn profiles.

Parameters
gameWorld

The game world to initialize with.

Definition at line 475 of file SpawnManager.ixx.

475 void init(helios::engine::runtime::world::GameWorld& gameWorld) noexcept override {
476
477 gameObjectPoolManager_ = gameWorld.getManager<helios::engine::runtime::pooling::GameObjectPoolManager>();
478
479 for (const auto& [spawnProfileId, _]: spawnProfiles_) {
480 gameWorld.registerSpawnCommandHandler(spawnProfileId, *this);
481 }
482
483 }

References helios::engine::runtime::world::GameWorld::getManager and helios::engine::runtime::world::GameWorld::registerSpawnCommandHandler.

spawnProfile()

const helios::engine::runtime::spawn::SpawnProfile * helios::engine::runtime::spawn::SpawnManager::spawnProfile (const helios::engine::core::data::SpawnProfileId & spawnProfileId)
inline nodiscard

Returns a spawn profile by ID.

Parameters
spawnProfileId

The profile ID to look up.

Returns

Pointer to the profile, or nullptr if not found.

Definition at line 456 of file SpawnManager.ixx.

457 const helios::engine::core::data::SpawnProfileId& spawnProfileId) const {
458
459 if (!spawnProfiles_.contains(spawnProfileId)) {
460 return nullptr;
461 }
462
463 return spawnProfiles_.find(spawnProfileId)->second.get();
464 }

Referenced by addSpawnProfile.

submit()

bool helios::engine::runtime::spawn::SpawnManager::submit (const helios::engine::runtime::spawn::commands::SpawnCommand & command)
inline noexcept virtual

Submits a spawn command for deferred processing.

Parameters
command

The spawn command to queue.

Returns

Always returns true.

Definition at line 365 of file SpawnManager.ixx.

365 bool submit(const helios::engine::runtime::spawn::commands::SpawnCommand& command) noexcept override {
366 spawnCommands_.push_back(command);
367 return true;
368 }

submit()

bool helios::engine::runtime::spawn::SpawnManager::submit (const helios::engine::runtime::spawn::commands::DespawnCommand & command)
inline noexcept virtual

Submits a despawn command for deferred processing.

Parameters
command

The despawn command to queue.

Returns

Always returns true.

Definition at line 377 of file SpawnManager.ixx.

378 despawnCommands_.push_back(command);
379 return true;
380 }

submit()

bool helios::engine::runtime::spawn::SpawnManager::submit (const helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand & scheduledSpawnPlanCommand)
inline noexcept virtual

Submits a scheduled spawn plan command for deferred processing.

Parameters
scheduledSpawnPlanCommand

The scheduled plan command to queue.

Returns

Always returns true.

Definition at line 390 of file SpawnManager.ixx.

390 bool submit(
392 ) noexcept override {
393 scheduledSpawnPlanCommands_.push_back(scheduledSpawnPlanCommand);
394 return true;
395 }

Private Member Functions

despawnObjects()

void helios::engine::runtime::spawn::SpawnManager::despawnObjects (std::span< helios::engine::runtime::spawn::commands::DespawnCommand > commands, helios::engine::runtime::world::GameWorld & gameWorld, helios::engine::runtime::world::UpdateContext & updateContext)
inline

Processes despawn commands, releasing objects back to pools.

Parameters
commands

Span of despawn commands to process.

gameWorld

The game world.

updateContext

The current update context.

Definition at line 332 of file SpawnManager.ixx.

332 void despawnObjects(
333 std::span<helios::engine::runtime::spawn::commands::DespawnCommand> commands,
336
337 for (auto& despawnCommand : commands) {
338 const auto spawnProfileId = despawnCommand.spawnProfileId();
339
340 const auto it = spawnProfiles_.find(spawnProfileId);
341 assert(it != spawnProfiles_.end() && "SpawnProfile not part of SpawnManager");
342 const auto spawnProfile = it->second.get();
343 auto gameObjectPoolId = spawnProfile->gameObjectPoolId;
344
345 gameObjectPoolManager_->release(gameObjectPoolId, despawnCommand.entityHandle());
346
347 }
348 }

ensureBounds()

void helios::engine::runtime::spawn::SpawnManager::ensureBounds (helios::engine::ecs::GameObject go, helios::math::aabbf & bounds)
inline

Ensures that the bounds are properly computed..

Checks if the bounding box was initialized (i.e. has valid min/max values: min <= max). If the bounds are inverted (min > max), it recomputes the world AABB using the GameObject's components (ModelAabb, ScaleState, RotationState, SceneNode, TranslationState).

Parameters
go

The GameObject to compute bounds for.

bounds

The bounding box to check and potentially update.

See Also

helios::engine::modules::physics::collision::Bounds::computeWorldAabb

Definition at line 140 of file SpawnManager.ixx.

140 void ensureBounds(helios::engine::ecs::GameObject go, helios::math::aabbf& bounds) {
141 if (bounds.min()[0] > bounds.max()[0]) {
147
148 assert(mab && scn && tsc && sca && rsc && "Missing Components for AABB computation");
150 *mab, *scn, *tsc, *sca, *rsc
151 );
152 }
153 }

executeScheduledSpawnPlanCommands()

void helios::engine::runtime::spawn::SpawnManager::executeScheduledSpawnPlanCommands (std::span< helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand > commands, helios::engine::runtime::world::GameWorld & gameWorld, helios::engine::runtime::world::UpdateContext & updateContext)
inline

Processes scheduled spawn plan commands.

Iterates through each plan, acquires entities from the pool, positions them using the profile's placer, initializes them using the profile's initializer, and pushes a frame event for confirmation.

Parameters
commands

Span of scheduled spawn plan commands to process.

gameWorld

The game world.

updateContext

The current update context.

Definition at line 166 of file SpawnManager.ixx.

166 void executeScheduledSpawnPlanCommands(
167 std::span<helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand> commands,
170 ) {
171
172 for (auto& scheduledSpawnPlanCommand: commands) {
173
174 const auto& spawnPlan = scheduledSpawnPlanCommand.spawnPlan();
175
176 const auto spawnProfileId = scheduledSpawnPlanCommand.spawnProfileId();
177 const auto spawnRuleId = spawnPlan.spawnRuleId;
178 const auto amount = spawnPlan.amount;
179
180 const auto it = spawnProfiles_.find(spawnProfileId);
181 assert(it != spawnProfiles_.end() && "SpawnProfile not part of SpawnManager");
182
183 const auto spawnProfile = it->second.get();
184
185 const auto gameObjectPoolId = spawnProfile->gameObjectPoolId;
186
187
188
189 const auto poolSnapshot = gameObjectPoolManager_->poolSnapshot(gameObjectPoolId);
190
191 if (amount == 0) {
192 assert(false && "Amount must not be 0");
193 }
194 if (!spawnProfiles_.contains(spawnProfileId)) {
195 assert(false && "SpawnManager does not manage this SpawnProfileId");
196 }
197
198
199
200 const auto spawnCount = std::min(amount, poolSnapshot.inactiveCount);
201 for (size_t i = 0; i < spawnCount; i++) {
202
203 auto go = gameObjectPoolManager_->acquire(gameObjectPoolId);
204 assert(go && "Failed to acquire GameObject");
205
207
209 assert(sbp && "unexpected missing SpawnedByProfileComponent");
210
212 assert(aabb && "unexpected missing AabbColliderComponent");
213
214 auto spawnCursor = helios::engine::runtime::spawn::SpawnPlanCursor{spawnCount, i};
215 const auto& spawnContext = scheduledSpawnPlanCommand.spawnContext();
216
217 const auto& emitter = spawnContext.emitterContext;
219 if (emitter.has_value() && ebc) {
220 ebc->setSource(emitter.value().source);
221 }
222
223 if (tsc) {
224
225 auto bounds = aabb->bounds();
226 ensureBounds(go.value(), bounds);
227
228 const auto position = spawnProfile->spawnPlacer->getPosition(
229 go->entityHandle(),
230 bounds,
231 gameWorld_->level().bounds(),
232 spawnCursor,
233 spawnContext
234
235 );
236 tsc->setTranslation(position);
237 }
238
239 assert(spawnProfile->spawnInitializer && "Unexpected missing spawn initializer");
240
241 spawnProfile->spawnInitializer->initialize(*go, spawnCursor, spawnContext);
242 sbp->setSpawnProfileId(spawnProfileId);
243 go->setActive(true);
244 }
245
247 spawnRuleId, spawnCount
248 );
249 }
250 }

spawnObjects()

void helios::engine::runtime::spawn::SpawnManager::spawnObjects (std::span< helios::engine::runtime::spawn::commands::SpawnCommand > commands, helios::engine::runtime::world::GameWorld & gameWorld, helios::engine::runtime::world::UpdateContext & updateContext)
inline

Processes spawn commands, acquiring and initializing objects.

Parameters
commands

Span of spawn commands to process.

gameWorld

The game world.

updateContext

The current update context.

Definition at line 260 of file SpawnManager.ixx.

260 void spawnObjects(
261 std::span<helios::engine::runtime::spawn::commands::SpawnCommand> commands,
264
265 for (auto& spawnCommand: commands) {
266 const auto spawnProfileId = spawnCommand.spawnProfileId();
267 const auto spawnContext = spawnCommand.spawnContext();
268
269 const auto it = spawnProfiles_.find(spawnProfileId);
270 assert(it != spawnProfiles_.end() && "SpawnProfile not part of SpawnManager");
271
272 const auto spawnProfile = it->second.get();
273 const auto gameObjectPoolId = spawnProfile->gameObjectPoolId;
274
275 if (gameObjectPoolManager_->poolSnapshot(gameObjectPoolId).inactiveCount == 0) {
276 /**
277 * @todo log
278 */
279 continue;
280 }
281
282 auto go = gameObjectPoolManager_->acquire(gameObjectPoolId);
283 assert(go && "Failed to acquire GameObject");
284
287 assert(sbp && "unexpected missing SpawnedByProfileComponent");
288
290 assert(aabb && "unexpected missing AabbColliderComponent");
291
292 const auto& emitter = spawnContext.emitterContext;
294 if (emitter.has_value() && ebc) {
295 ebc->setSource(emitter.value().source);
296 }
297
298 if (tsc) {
299
300 auto bounds = aabb->bounds();
301 ensureBounds(go.value(), bounds);
302
303 const auto position = spawnProfile->spawnPlacer->getPosition(
304 go->entityHandle(),
305 bounds,
306 gameWorld_->level().bounds(),
307 {1, 1},
308 spawnContext
309
310 );
311 tsc->setTranslation(position);
312 }
313
314
315 assert(spawnProfile->spawnInitializer && "Unexpected missing spawn initializer");
316
317 spawnProfile->spawnInitializer->initialize(*go, {1, 1}, spawnContext);
318 sbp->setSpawnProfileId(spawnProfileId);
319
320 go->setActive(true);
321 }
322 }

Private Member Attributes

despawnCommands_

std::vector<helios::engine::runtime::spawn::commands::DespawnCommand> helios::engine::runtime::spawn::SpawnManager::despawnCommands_

Queue of pending despawn commands.

Definition at line 107 of file SpawnManager.ixx.

107 std::vector<helios::engine::runtime::spawn::commands::DespawnCommand> despawnCommands_;

gameObjectPoolManager_

helios::engine::runtime::pooling::GameObjectPoolManager* helios::engine::runtime::spawn::SpawnManager::gameObjectPoolManager_ = nullptr

Pointer to the pool manager for acquire/release operations.

Definition at line 117 of file SpawnManager.ixx.

117 helios::engine::runtime::pooling::GameObjectPoolManager* gameObjectPoolManager_ = nullptr;

scheduledSpawnPlanCommands_

std::vector<helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand> helios::engine::runtime::spawn::SpawnManager::scheduledSpawnPlanCommands_

Queue of pending scheduled spawn plan commands.

Definition at line 112 of file SpawnManager.ixx.

112 std::vector<helios::engine::runtime::spawn::commands::ScheduledSpawnPlanCommand> scheduledSpawnPlanCommands_;

spawnCommands_

std::vector<helios::engine::runtime::spawn::commands::SpawnCommand> helios::engine::runtime::spawn::SpawnManager::spawnCommands_

Queue of pending spawn commands.

Definition at line 102 of file SpawnManager.ixx.

102 std::vector<helios::engine::runtime::spawn::commands::SpawnCommand> spawnCommands_;

spawnProfiles_

std::unordered_map< helios::engine::core::data::SpawnProfileId, std::unique_ptr<const helios::engine::runtime::spawn::SpawnProfile> > helios::engine::runtime::spawn::SpawnManager::spawnProfiles_

Map from profile IDs to their spawn profiles.

Definition at line 124 of file SpawnManager.ixx.

124 std::unique_ptr<const helios::engine::runtime::spawn::SpawnProfile>> spawnProfiles_;

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


Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.