Objects Pooling
The dependency manager also serves as an object pool, allowing you to allocate and release instances of classes efficiently. This is particularly useful for managing resources in a game environment where performance is critical. This document provides a guide to object pooling in Spinorium, including how to use the dependency manager for this purpose.
Registration and Creation of Objects
The DepencencyManager class allows allocation of objects with three different methods: allocate, allocateByName and allocateBySubtype, depending on how you built dependency graph. When you call these methods, the DependencyManager will:
- Check if there's an available object in the pool.
- If an object is available, return it from the pool.
- If no object is available, create a new instance.
The DependencyManager does not reset instances when they enter or leave the pool. You must clear transforms, signals, and any transient state before releasing objects back.
Working With Objects Pool
The example below shows a common lifecycle: allocate, reuse, then release.
// Allocate a new instance or get an instance from the pool.
const sprite = System.dependency.allocate(Sprite);
// Do something with an object
Tweens.move(sprite, 0.5, { x: 100, y: 100 });
// Release an object and return it to the pool
System.dependency.release(sprite);
// ... or the same inside timeline
Actions.utils.releaseObject(sprite);
Animations Factory
Spinorium also provides the AnimationFactory factory that maintains dedicated pools per animation type. Similar to DependencyManager, AnimationsFactory do nothing with animations when they enter or leave pool. It's on the developer side to clean up all transformations and state if needed.
// Allocate a new instance or get an instance from the pool.
const animation = System.resources.animations.compose(AnimationType.SPINE, 'character')
// Do something with an object
animation.play('idle', true, 1);
// Release an animation and return it to the pool
System.resources.animations.dispose(animation);
// ... or the same inside timeline
Actions.utils.disposeObject(animation);
Scatter Collect Feature Example
The feature below composes a Spine animation for every scatter symbol, animates it toward the target, then disposes the animation so it becomes available for the next trigger.
export class ScatterCollectFeature extends Feature {
public override process():IAction {
const slotMachine = System.scenes.obtainChildByPath<SlotMachine>('viewport/reels_wrapper/reels');
const targetPosition = { x: 200, y: 200 };
const scatters = slotMachine.obtainSymbols([ SpecialSymbolType.SCATTER ]);
const actionsList:IAction[] = [];
for (const scatter of scatters) {
// Allocating "scatter_collect" animation for each symbol
const animation = System.resources.animations.compose(AnimationType.SPINE, 'scatter_collect');
actionsList.push(
Actions.waitDelay(scatters.length * 0.15)
.stage.addObject(slotMachine, animation)
.stage.changeProperty(animation.position, scatter)
.tweens.move(animation, 0.5, targetPosition)
.stage.removeObject(animation)
// Returning the animation back to the pool
.utils.disposeObject(animation)
);
}
return Actions.waitActionsGroup(actionsList);
}
}