Pool¶
Overview¶
PROTOTYPE version for better support
Object pooling mixin, for cases where creating new objects is expensive, and we'd rather mark some objects as able to be reused (i.e. 'in the pool'). This provides a pool of objects for each type it is invoked on. It allows for getting "new" objects that can either be constructed OR pulled in from a pool, and requires that the objects are essentially able to "re-run" the constructor. Then when putting the object back in the pool, references should be released, so memory isn't leaked.
With this style of pooling, the following should be standard boilerplate within the class:
public freeToPool(): void { MyType.pool.freeToPool( this ); }
public static readonly pool = new Pool( MyType );
and can additionally implement TPoolable to make it clear that the type is pooled
@author Jonathan Olson <jonathan.olson@colorado.edu>
Class Pool¶
Constructor¶
new Pool( type : T, ...providedOptionsSpread : PossiblyRequiredParameterSpread<PoolableOptions<T>> )¶
Instance Methods¶
fetch() : InstanceType<T>¶
Returns an object with arbitrary state (possibly constructed with the default arguments).
create( ...args : ConstructorParameters<T> ) : InstanceType<T>¶
Returns an object that behaves as if it was constructed with the given arguments. May result in a new object being created (if the pool is empty), or it may use the constructor to mutate an object from the pool.
freeToPool( object : InstanceType<T> )¶
forEach( callback : ( object: InstanceType<T> ) => void )¶
Type PoolableOptions¶
- defaultArguments?: ConstructorParameters<T>
If an object needs to be created without a direct call (say, to fill the pool initially), these are the arguments that will be passed into the constructor - initialize?: PoolableInitializer<T>
The function to call on the objects to reinitialize them (that is either the constructor, or acts like the constructor). NOTE: This should return the object itself! - maxSize?: number
A limit for the pool size (so we don't leak memory by growing the pool faster than we take things from it). Can be customized by setting Type.maxPoolSize - initialSize?: number
The initial size of the pool. To fill it, objects will be created with the default arguments. - useDefaultConstruction?: boolean
If true, when constructing the default arguments will always be used (and then initialized with the initializer) instead of just providing the arguments straight to the constructor. - & ( InstanceType<T> extends { initialize: PoolableInitializer<T> } ? unknown : { // Require initialize if our type doesn't have a compatible initialize method. initialize: PoolableInitializer<T>; } )
Type PossiblyRequiredParameterSpread¶
Our linter complains that {} should be either Record<string, unknown>, unknown, or Record<string, never>. However in this case, we actually want it to be any type of non-nullish structural type, to see if there is anything required.
( {} extends T ? [ T? ] : [ T ] )
Type TPoolable¶
- freeToPool: () => void
Adds this object into the pool, so that it can be reused elsewhere. Generally when this is done, no other references to the object should be held (since they should not be used at all).