diff --git a/.changeset/blue-trains-serve.md b/.changeset/blue-trains-serve.md new file mode 100644 index 0000000..cc7de53 --- /dev/null +++ b/.changeset/blue-trains-serve.md @@ -0,0 +1,5 @@ +--- +'@tedengine/ted': minor +--- + +Add simple actor pool with preallocation diff --git a/packages/ted/src/core/actor-pool.ts b/packages/ted/src/core/actor-pool.ts new file mode 100644 index 0000000..6c90d41 --- /dev/null +++ b/packages/ted/src/core/actor-pool.ts @@ -0,0 +1,68 @@ +import type TActor from './actor'; + +export interface TPoolableActor extends TActor { + /** + * Resets the actor to its initial state + */ + reset(): void; + + pool: TActorPool; +} + +export default class TActorPool { + private actors: T[] = []; + + constructor( + // Function that creates a new actor + private readonly actor: () => T, + startingInstances: number, + ) { + // Prefill the pool with instances + for (let i = 0; i < startingInstances; i++) { + const actor = this.actor(); + actor.pool = this; + + this.actors.push(actor); + } + } + + /** + * Acquires an actor from the pool, and initializes a new one if necessary + * @returns + */ + public acquire(): T | undefined { + if (this.actors.length === 0) { + const actor = this.actor(); + actor.pool = this; + return actor; + } + + return this.actors.pop(); + } + + /** + * Releases actor back to the pool, resets and removes it from the world + * @param actor + */ + public release(actor: T): void { + actor.reset(); + + if (actor.world) { + actor.world.removeActor(actor); + } + + this.actors.push(actor); + } + + /** + * Runs destroy all actors remaining in the pool. + * This will not destroy actors that have been acquired. + */ + public destroy(): void { + for (const actor of this.actors) { + actor.destroy(); + } + + this.actors = []; + } +} diff --git a/packages/ted/src/index.ts b/packages/ted/src/index.ts index 5bc6b47..eee15fb 100644 --- a/packages/ted/src/index.ts +++ b/packages/ted/src/index.ts @@ -31,6 +31,9 @@ export { default as TFollowComponentCameraController } from './cameras/follow-co export { default as TActor } from './core/actor'; export * from './core/actor'; +export { default as TActorPool } from './core/actor-pool'; +export * from './core/actor-pool'; + export { default as TEventQueue } from './core/event-queue'; export * from './core/event-queue';