chore: remove event listeners on shape destroy

This commit is contained in:
cha0s 2019-05-03 01:21:35 -05:00
parent 093b7d7572
commit 3e2e85faf3
7 changed files with 152 additions and 69 deletions

View File

@ -12,9 +12,7 @@ export class CircleShape extends decorate(Shape) {
constructor() {
super();
this.on('radiusChanged', () => {
this.emit('aabbChanged');
});
this.on('radiusChanged', this.onAabbChanged, this);
}
get aabb() {
@ -28,6 +26,11 @@ export class CircleShape extends decorate(Shape) {
];
}
destroy() {
super.destroy();
this.off('radiusChanged', this.onAabbChanged);
}
fromJSON(json) {
super.fromJSON(json);
if (json.radius) {
@ -36,6 +39,10 @@ export class CircleShape extends decorate(Shape) {
return this;
}
onAabbChanged() {
this.emit('aabbChanged');
}
toJSON() {
return {
...super.toJSON(),

View File

@ -8,29 +8,22 @@ export class ShapeList extends Shape {
constructor() {
super();
this._shapes = [];
this.on('shapesChanged', () => {
this._shapes.forEach((shape) => {
shape.off('aabbChanged');
shape.on('aabbChanged', () => {
this.emit('aabbChanged');
});
});
});
this.on('originChanged', (oldOrigin) => {
this._shapes.forEach((shape) => {
shape.emit('parentOriginChanged', oldOrigin, this.origin);
});
});
this.on('rotationChanged', (oldRotation) => {
this._shapes.forEach((shape) => {
shape.emit('parentRotationChanged', oldRotation, this.rotation);
});
});
this.on('scaleChanged', (oldScale) => {
this._shapes.forEach((shape) => {
shape.emit('parentScaleChanged', oldScale, this.scale);
});
});
this.on('shapesChanged', this.onShapesChanged, this);
this.on('originChanged', this.onOriginChanged, this);
this.on('rotationChanged', this.onRotationChanged, this);
this.on('scaleChanged', this.onScaleChanged, this);
}
destroy() {
super.destroy();
this.off('shapesChanged', this.onShapesChanged);
this.off('originChanged', this.onOriginChanged);
this.off('rotationChanged', this.onRotationChanged);
this.off('scaleChanged', this.onScaleChanged);
for (let i = 0; i < this._shapes.length; i++) {
const shape = this._shapes[i];
shape.destroy();
}
}
*[Symbol.iterator]() {
@ -58,6 +51,12 @@ export class ShapeList extends Shape {
);
}
addShape(shape) {
const oldShapes = [...this._shapes];
this._shapes.push(shape);
this.emit('shapesChanged', oldShapes, this._shapes);
}
fromJSON(json) {
super.fromJSON(json);
if (json.shapes) {
@ -65,17 +64,13 @@ export class ShapeList extends Shape {
json.shapes.forEach((shape) => {
shapes.push(shapeFromJSON(shape));
});
const oldShapes = [...this._shapes];
this._shapes = shapes;
this.emit('shapesChanged');
this.emit('shapesChanged', oldShapes, this._shapes);
}
return this;
}
addShape(shape) {
this._shapes.push(shape);
this.emit('shapesChanged');
}
intersects(list) {
if (0 === this._shapes.length) {
return false;
@ -97,6 +92,37 @@ export class ShapeList extends Shape {
return false;
}
onChildAabbChanged() {
this.emit('aabbChanged');
}
onOriginChanged(oldOrigin) {
this._shapes.forEach((shape) => {
shape.emit('parentOriginChanged', oldOrigin, this.origin);
});
}
onRotationChanged(oldRotation) {
this._shapes.forEach((shape) => {
shape.emit('parentRotationChanged', oldRotation, this.rotation);
});
}
onScaleChanged(oldScale) {
this._shapes.forEach((shape) => {
shape.emit('parentScaleChanged', oldScale, this.scale);
});
}
onShapesChanged(oldShapes) {
oldShapes.forEach((shape) => {
shape.off('aabbChanged');
});
this._shapes.forEach((shape) => {
shape.on('aabbChanged', this.onChildAabbChanged, this);
});
}
toJSON() {
return {
...super.toJSON(),

View File

@ -16,18 +16,20 @@ export class PolygonShape extends Shape {
'rotationChanged',
'scaleChanged',
'verticesChanged',
], () => {
const parentOrigin = this.parent ? this.parent.origin : [0, 0];
const origin = Vector.add(this.origin, parentOrigin);
const parentRotation = this.parent ? this.parent.rotation : 0;
const rotation = this.rotation + parentRotation;
const parentScale = this.parent ? this.parent.scale : 1;
const scale = this.scale * parentScale;
this._translatedVertices = this._vertices.map((vertice) => {
return Vertice.translate(vertice, origin, rotation, scale);
});
this.emit('aabbChanged');
});
], this.onRecalculateVertices, this);
}
destroy() {
super.destroy();
this.off([
'parentOriginChanged',
'parentRotationChanged',
'parentScaleChanged',
'originChanged',
'rotationChanged',
'scaleChanged',
'verticesChanged',
], this.onRecalculateVertices);
}
*[Symbol.iterator]() {
@ -62,6 +64,19 @@ export class PolygonShape extends Shape {
return this;
}
onRecalculateVertices() {
const parentOrigin = this.parent ? this.parent.origin : [0, 0];
const origin = Vector.add(this.origin, parentOrigin);
const parentRotation = this.parent ? this.parent.rotation : 0;
const rotation = this.rotation + parentRotation;
const parentScale = this.parent ? this.parent.scale : 1;
const scale = this.scale * parentScale;
this._translatedVertices = this._vertices.map((vertice) => {
return Vertice.translate(vertice, origin, rotation, scale);
});
this.emit('aabbChanged');
}
get vertices() {
return this._vertices;
}

View File

@ -14,18 +14,12 @@ export class RectangleShape extends decorate(PolygonShape) {
constructor() {
super();
this.on(['positionChanged', 'sizeChanged'], () => {
const halfSize = Vector.scale(this.size, 0.5);
const width = this.width - 0.001;
const height = this.height - 0.001;
const position = Vector.add(this.position, Vector.scale(halfSize, -1));
this.vertices = [
position,
Vector.add(position, [width, 0]),
Vector.add(position, [width, height]),
Vector.add(position, [0, height]),
];
});
this.on(['positionChanged', 'sizeChanged'], this.onVerticesChanged, this);
}
destroy() {
super.destroy();
this.off(['positionChanged', 'sizeChanged'], this.onVerticesChanged);
}
fromJSON(json) {
@ -41,6 +35,19 @@ export class RectangleShape extends decorate(PolygonShape) {
return this;
}
onVerticesChanged() {
const halfSize = Vector.scale(this.size, 0.5);
const width = this.width - 0.001;
const height = this.height - 0.001;
const position = Vector.add(this.position, Vector.scale(halfSize, -1));
this.vertices = [
position,
Vector.add(position, [width, 0]),
Vector.add(position, [width, height]),
Vector.add(position, [0, height]),
];
}
toJSON() {
return {
...super.toJSON(),

View File

@ -12,15 +12,11 @@ export class ShapeView extends Renderable {
this.shape = shape;
if (shape instanceof PolygonShape) {
this.redrawPolygonLines();
shape.on('aabbChanged', () => {
this.redrawPolygonLines();
});
shape.on('aabbChanged', this.onPolygonShapeAabbChanged, this);
}
if (shape instanceof CircleShape) {
this.redrawCircle();
shape.on('aabbChanged', () => {
this.redrawCircle();
});
shape.on('aabbChanged', this.onCircleShapeAabbChanged, this);
}
if (shape instanceof ShapeList) {
for (const child of shape) {
@ -29,15 +25,36 @@ export class ShapeView extends Renderable {
}
}
this.container.position = shape.position;
shape.on('positionChanged', () => {
this.container.position = shape.position;
})
shape.on('positionChanged', this.onShapePositionChanged, this);
}
destroy() {
super.destroy();
if (shape instanceof PolygonShape) {
this.shape.off('aabbChanged', this.onPolygonShapeAabbChanged);
}
if (shape instanceof CircleShape) {
this.shape.off('aabbChanged', this.onCircleShapeAabbChanged);
}
this.shape.off('aabbChanged', this.onShapePositionChanged);
}
get internal() {
return this.container.internal;
}
onPolygonShapeAabbChanged() {
this.redrawPolygonLines();
}
onCircleShapeAabbChanged() {
this.redrawCircle();
}
onShapePositionChanged() {
this.container.position = shape.position;
}
redrawCircle() {
const primitives = new Primitives();
primitives.drawCircle(

View File

@ -30,15 +30,21 @@ export class Shape extends decorate(class {}) {
'originChanged',
'rotationChanged',
'scaleChanged',
], () => {
this.emit('aabbChanged');
});
], this.onAabbChanged, this);
}
get aabb() {
return [0, 0, 0, 0];
}
destroy() {
this.off([
'originChanged',
'rotationChanged',
'scaleChanged',
], this.onAabbChanged);
}
fromJSON(json) {
const keys = [
'origin',
@ -54,6 +60,10 @@ export class Shape extends decorate(class {}) {
return this;
}
onAabbChanged() {
this.emit('aabbChanged');
}
toJSON() {
return {
origin: this.origin,

View File

@ -21,11 +21,12 @@ export class Shaped extends decorate(Trait) {
}
destroy() {
this._shape.destroy();
if (this.shapeView) {
this.shapeView.destroy();
}
this.shapeView = undefined;
}
}
get shape() {
return this._shape;