Closed eonarheim closed 3 years ago
Maybe use kill
and revive
? That way actors could be IPoolable if needed.
This will give us a boon on Vector types
Best to wait until #722 is merged to do this. Example of possible poolable interfaces are in my comments in PR, copied here:
Here is a full working example using props, mapped types, and pools:
interface VectorProps {
x: number;
y: number;
}
function extend(...o) {
return o.reduce((p, c, i) => {
return { ...p, ...c };
});
}
function mixin<T, T2>(instance: T, methods: T2): T & T2 {
for (var k in methods) {
(<any>instance)[k] = methods[k];
}
return <T & T2>instance;
}
abstract class Class<TProps> {
abstract defaults: TProps;
set(props: Partial<TProps>) {
mixin(this, props);
}
reset() {
this.set(this.defaults);
}
}
class Vector extends Class<VectorProps> implements VectorProps {
defaults = { x: 0, y: 0 };
x: number;
y: number;
constructor(props?: Partial<VectorProps>) {
super();
this.set(extend(this.defaults, props));
}
}
interface Poolable<T extends TProps, TProps> {
create<T extends TProps>(props?: Partial<TProps>): T & PooledInstance;
}
interface PooledInstance {
poolInstanceMethod();
}
class Pool<T extends Class<TProps>, TProps> {
constructor(private _ctor: { new (props?: Partial<TProps>): T }) {
}
static create<T extends Class<TProps>, TProps>(ctor: { new (props?: Partial<TProps>): T }): Pool<T, TProps> {
var pooled = new Pool<T, TProps>(ctor);
// do pool stuff
return pooled;
}
create(props?: Partial<TProps>): T & PooledInstance {
var ins = new this._ctor(props);
// do pooling stuff
return mixin(ins, Pool._Mixins);
};
// statically define pool mixin functions
private static _Mixins: PooledInstance = {
poolInstanceMethod: function () {
console.log(this, 'pool instance method');
}
}
}
var v = new Vector();
var vp = Pool.create<Vector, VectorProps>(Vector);
var v2 = vp.create({ x: 1, y: 1 });
console.log(v, v.x, v.y);
console.log(vp, v2, v2.x, v2.y);
No real pool instance methods are in the example, but it shows we could add new pool instance methods if need be.
Benefits:
ex.Class
)static Defaults: VectorProps = { }
)You can play with it by using the Playground.
There was an implementation of this put into #1425
Context
Object pooling would bring significant improvements to the memory usage of Excalibur, as well as performance gains related to the construction/destruction of objects.
Proposal
// Creates a new actor pool var pool = new ex.Pool(100);
// must implement IPoolable interface IPoolable{ public reset(): void; public dispose(): void; }
var myActor = pool.getInstance();
// reset and dispose will be called on actor and returned to the pool pool.returnInstance(myActor);