chore: free'ing

This commit is contained in:
cha0s 2019-04-30 17:11:41 -05:00
parent 6143a76e0d
commit bdf3b313a3
13 changed files with 72 additions and 33 deletions

View File

@ -33,6 +33,12 @@ export class Behaved extends decorate(Trait) {
this.updateCurrentRoutine(); this.updateCurrentRoutine();
} }
destroy() {
this._context.clear();
this._currentRoutine = undefined;
this._routines = undefined;
}
get context() { get context() {
return this._context; return this._context;
} }

View File

@ -103,7 +103,7 @@ export class Entity extends decorate(Resource) {
// Let the Trait do its initialization. // Let the Trait do its initialization.
instance.initialize(); instance.initialize();
// Attach listeners. // Attach listeners.
const listeners = instance.listeners(); const listeners = instance.memoizedListeners();
for (const eventName in listeners) { for (const eventName in listeners) {
this.on(eventName, listeners[eventName]); this.on(eventName, listeners[eventName]);
} }
@ -243,7 +243,7 @@ export class Entity extends decorate(Resource) {
delete this[property]; delete this[property];
} }
// Remove all event listeners. // Remove all event listeners.
const listeners = instance.listeners(); const listeners = instance.memoizedListeners();
for (const eventName in listeners) { for (const eventName in listeners) {
this.off(eventName, listeners[eventName]); this.off(eventName, listeners[eventName]);
} }
@ -251,6 +251,8 @@ export class Entity extends decorate(Resource) {
this.state = this.state.delete(type); this.state = this.state.delete(type);
// Remove instance. // Remove instance.
delete this._traits[type]; delete this._traits[type];
// Unloop.
// instance.entity = undefined;
} }
removeTraits(types) { removeTraits(types) {

View File

@ -27,7 +27,7 @@ export class EntityPacketSynchronizer {
const mergedPackets = this._mergePackets(packets); const mergedPackets = this._mergePackets(packets);
flusher(entity, Array.from(mergedPackets.values())); flusher(entity, Array.from(mergedPackets.values()));
} }
this.packetsToSynchronize = new Map(); this.packetsToSynchronize.clear();
} }
_mergePackets(packets) { _mergePackets(packets) {

View File

@ -16,6 +16,7 @@ export class Trait extends decorate(class {}) {
this.entity = entity; this.entity = entity;
const ctor = this.constructor; const ctor = this.constructor;
this.isDirty = true; this.isDirty = true;
this._memoizedListeners = undefined;
this.params = I.fromJS(ctor.defaultParams()).merge(I.fromJS(params)); this.params = I.fromJS(ctor.defaultParams()).merge(I.fromJS(params));
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state)); this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
} }
@ -50,6 +51,13 @@ export class Trait extends decorate(class {}) {
return {}; return {};
} }
memoizedListeners() {
if (!this._memoizedListeners) {
this._memoizedListeners = this.listeners();
}
return this._memoizedListeners;
}
methods() { methods() {
return {}; return {};
} }

View File

@ -24,23 +24,7 @@ class PositionedBase extends Trait {
} }
initialize() { initialize() {
this.on('_positionChanged', (oldPosition, newPosition) => { this.on('_positionChanged', this.on_positionChanged, this);
if (AVOCADO_SERVER) {
const x = Math.floor(newPosition[0]) * 4;
const y = Math.floor(newPosition[1]) * 4;
this.state = this.state.withMutations((state) => {
state.set('x', x).set('y', y);
});
this.isDirty = true;
}
if (oldPosition[0] !== newPosition[0]) {
this.entity.emit('xChanged', oldPosition[0], newPosition[0]);
}
if (oldPosition[1] !== newPosition[1]) {
this.entity.emit('yChanged', oldPosition[1], newPosition[1]);
}
this.entity.emit('positionChanged', oldPosition, newPosition);
});
const x = this.state.get('x') / 4; const x = this.state.get('x') / 4;
const y = this.state.get('y') / 4; const y = this.state.get('y') / 4;
this._position = [x, y]; this._position = [x, y];
@ -48,12 +32,39 @@ class PositionedBase extends Trait {
this._relaxServerPositionConstraintIfNearerThan = 0; this._relaxServerPositionConstraintIfNearerThan = 0;
this.serverPosition = this._position; this.serverPosition = this._position;
this.serverPositionDirty = false; this.serverPositionDirty = false;
this.on('serverPositionChanged', () => { this.on('serverPositionChanged', this.onServerPositionChanged, this);
this.serverPositionDirty = true;
});
} }
} }
destroy() {
this.off('_positionChanged', this.on_positionChanged);
if (AVOCADO_CLIENT) {
this.off('serverPositionChanged', this.onServerPositionChanged);
}
}
on_positionChanged(oldPosition, newPosition) {
if (AVOCADO_SERVER) {
const x = Math.floor(newPosition[0]) * 4;
const y = Math.floor(newPosition[1]) * 4;
this.state = this.state.withMutations((state) => {
state.set('x', x).set('y', y);
});
this.isDirty = true;
}
if (oldPosition[0] !== newPosition[0]) {
this.entity.emit('xChanged', oldPosition[0], newPosition[0]);
}
if (oldPosition[1] !== newPosition[1]) {
this.entity.emit('yChanged', oldPosition[1], newPosition[1]);
}
this.entity.emit('positionChanged', oldPosition, newPosition);
}
onServerPositionChanged() {
this.serverPositionDirty = true;
}
patchStateStep(key, step) { patchStateStep(key, step) {
if ('state' !== key) { if ('state' !== key) {
return; return;

View File

@ -72,7 +72,7 @@ export class Spawner extends decorate(Trait) {
} }
const spawn = new Entity().fromJSON(merge(spawnJSON, json)); const spawn = new Entity().fromJSON(merge(spawnJSON, json));
this.children.push(spawn); this.children.push(spawn);
spawn.on('destroy', () => { spawn.once('destroy', () => {
const index = this.children.indexOf(spawn); const index = this.children.indexOf(spawn);
this.children.splice(index, 1); this.children.splice(index, 1);
}) })

View File

@ -30,12 +30,12 @@ export class Container extends Renderable {
} }
destroy() { destroy() {
this.container.filters = [];
this.children.forEach((child) => { this.children.forEach((child) => {
this.removeChild(child); this.removeChild(child);
child.destroy(); child.destroy();
}); });
super.destroy(); super.destroy();
this.container.filters = [];
} }
get internal() { get internal() {

View File

@ -11,10 +11,6 @@ export class Sprite extends Renderable {
this.anchor = [0.5, 0.5]; this.anchor = [0.5, 0.5];
} }
destroy() {
this.sprite.destroy();
}
get internal() { get internal() {
return this.sprite; return this.sprite;
} }

View File

@ -62,6 +62,7 @@ export class Emitter extends decorate(Trait) {
this.ticker.tick(elapsed); this.ticker.tick(elapsed);
if (!emitter.hasParticles()) { if (!emitter.hasParticles()) {
emitter.destroy(); emitter.destroy();
this.constructor.removeEmitter(emitter);
delete this.emitters[key]; delete this.emitters[key];
} }
} }

View File

@ -35,6 +35,7 @@ export class Pictured extends decorate(Trait) {
for (const key in this.sprites) { for (const key in this.sprites) {
this.hideImage(key); this.hideImage(key);
const sprite = this.sprites[key]; const sprite = this.sprites[key];
sprite.image.destroy();
sprite.destroy(); sprite.destroy();
} }
} }

View File

@ -12,6 +12,14 @@ export class QuadTree {
this.quadTree.add(datum); this.quadTree.add(datum);
} }
clear() {
const data = this.quadTree.data();
for (let i = 0; i < data.length; i++) {
const datum = data[i];
this.quadTree.remove(datum);
}
}
remove(datum) { remove(datum) {
this.quadTree.remove(datum); this.quadTree.remove(datum);
} }

View File

@ -24,6 +24,7 @@ export class Shaped extends decorate(Trait) {
if (this.shapeView) { if (this.shapeView) {
this.shapeView.destroy(); this.shapeView.destroy();
} }
this.shapeView = undefined;
} }
get shape() { get shape() {

View File

@ -18,14 +18,20 @@ export class Followed extends Trait {
this.onRoomSizeChanged(); this.onRoomSizeChanged();
} }
destroy() {
if (!this.entity.is('roomed')) {
const room = this.entity.room;
if (room) {
room.off('sizeChanged', this.onRoomSizeChanged);
}
}
}
get camera() { get camera() {
return this._camera; return this._camera;
} }
onRoomSizeChanged() { onRoomSizeChanged() {
if (!this.entity.is('roomed')) {
return;
}
this._camera.areaSize = this.entity.room.size; this._camera.areaSize = this.entity.room.size;
} }
@ -39,7 +45,6 @@ export class Followed extends Trait {
listeners() { listeners() {
return { return {
// TODO won't catch initial room size changes.
addedToRoom: () => { addedToRoom: () => {
this.onRoomSizeChanged(); this.onRoomSizeChanged();
this.entity.room.on('sizeChanged', this.onRoomSizeChanged, this); this.entity.room.on('sizeChanged', this.onRoomSizeChanged, this);