chore: remove event listeners on shape destroy
This commit is contained in:
parent
093b7d7572
commit
3e2e85faf3
|
@ -12,9 +12,7 @@ export class CircleShape extends decorate(Shape) {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.on('radiusChanged', () => {
|
this.on('radiusChanged', this.onAabbChanged, this);
|
||||||
this.emit('aabbChanged');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get aabb() {
|
get aabb() {
|
||||||
|
@ -28,6 +26,11 @@ export class CircleShape extends decorate(Shape) {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
super.destroy();
|
||||||
|
this.off('radiusChanged', this.onAabbChanged);
|
||||||
|
}
|
||||||
|
|
||||||
fromJSON(json) {
|
fromJSON(json) {
|
||||||
super.fromJSON(json);
|
super.fromJSON(json);
|
||||||
if (json.radius) {
|
if (json.radius) {
|
||||||
|
@ -36,6 +39,10 @@ export class CircleShape extends decorate(Shape) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAabbChanged() {
|
||||||
|
this.emit('aabbChanged');
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
...super.toJSON(),
|
...super.toJSON(),
|
||||||
|
|
|
@ -8,29 +8,22 @@ export class ShapeList extends Shape {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this._shapes = [];
|
this._shapes = [];
|
||||||
this.on('shapesChanged', () => {
|
this.on('shapesChanged', this.onShapesChanged, this);
|
||||||
this._shapes.forEach((shape) => {
|
this.on('originChanged', this.onOriginChanged, this);
|
||||||
shape.off('aabbChanged');
|
this.on('rotationChanged', this.onRotationChanged, this);
|
||||||
shape.on('aabbChanged', () => {
|
this.on('scaleChanged', this.onScaleChanged, this);
|
||||||
this.emit('aabbChanged');
|
}
|
||||||
});
|
|
||||||
});
|
destroy() {
|
||||||
});
|
super.destroy();
|
||||||
this.on('originChanged', (oldOrigin) => {
|
this.off('shapesChanged', this.onShapesChanged);
|
||||||
this._shapes.forEach((shape) => {
|
this.off('originChanged', this.onOriginChanged);
|
||||||
shape.emit('parentOriginChanged', oldOrigin, this.origin);
|
this.off('rotationChanged', this.onRotationChanged);
|
||||||
});
|
this.off('scaleChanged', this.onScaleChanged);
|
||||||
});
|
for (let i = 0; i < this._shapes.length; i++) {
|
||||||
this.on('rotationChanged', (oldRotation) => {
|
const shape = this._shapes[i];
|
||||||
this._shapes.forEach((shape) => {
|
shape.destroy();
|
||||||
shape.emit('parentRotationChanged', oldRotation, this.rotation);
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
this.on('scaleChanged', (oldScale) => {
|
|
||||||
this._shapes.forEach((shape) => {
|
|
||||||
shape.emit('parentScaleChanged', oldScale, this.scale);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*[Symbol.iterator]() {
|
*[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) {
|
fromJSON(json) {
|
||||||
super.fromJSON(json);
|
super.fromJSON(json);
|
||||||
if (json.shapes) {
|
if (json.shapes) {
|
||||||
|
@ -65,17 +64,13 @@ export class ShapeList extends Shape {
|
||||||
json.shapes.forEach((shape) => {
|
json.shapes.forEach((shape) => {
|
||||||
shapes.push(shapeFromJSON(shape));
|
shapes.push(shapeFromJSON(shape));
|
||||||
});
|
});
|
||||||
|
const oldShapes = [...this._shapes];
|
||||||
this._shapes = shapes;
|
this._shapes = shapes;
|
||||||
this.emit('shapesChanged');
|
this.emit('shapesChanged', oldShapes, this._shapes);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addShape(shape) {
|
|
||||||
this._shapes.push(shape);
|
|
||||||
this.emit('shapesChanged');
|
|
||||||
}
|
|
||||||
|
|
||||||
intersects(list) {
|
intersects(list) {
|
||||||
if (0 === this._shapes.length) {
|
if (0 === this._shapes.length) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -97,6 +92,37 @@ export class ShapeList extends Shape {
|
||||||
return false;
|
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() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
...super.toJSON(),
|
...super.toJSON(),
|
||||||
|
|
|
@ -16,18 +16,20 @@ export class PolygonShape extends Shape {
|
||||||
'rotationChanged',
|
'rotationChanged',
|
||||||
'scaleChanged',
|
'scaleChanged',
|
||||||
'verticesChanged',
|
'verticesChanged',
|
||||||
], () => {
|
], this.onRecalculateVertices, this);
|
||||||
const parentOrigin = this.parent ? this.parent.origin : [0, 0];
|
}
|
||||||
const origin = Vector.add(this.origin, parentOrigin);
|
|
||||||
const parentRotation = this.parent ? this.parent.rotation : 0;
|
destroy() {
|
||||||
const rotation = this.rotation + parentRotation;
|
super.destroy();
|
||||||
const parentScale = this.parent ? this.parent.scale : 1;
|
this.off([
|
||||||
const scale = this.scale * parentScale;
|
'parentOriginChanged',
|
||||||
this._translatedVertices = this._vertices.map((vertice) => {
|
'parentRotationChanged',
|
||||||
return Vertice.translate(vertice, origin, rotation, scale);
|
'parentScaleChanged',
|
||||||
});
|
'originChanged',
|
||||||
this.emit('aabbChanged');
|
'rotationChanged',
|
||||||
});
|
'scaleChanged',
|
||||||
|
'verticesChanged',
|
||||||
|
], this.onRecalculateVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
*[Symbol.iterator]() {
|
*[Symbol.iterator]() {
|
||||||
|
@ -62,6 +64,19 @@ export class PolygonShape extends Shape {
|
||||||
return this;
|
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() {
|
get vertices() {
|
||||||
return this._vertices;
|
return this._vertices;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,18 +14,12 @@ export class RectangleShape extends decorate(PolygonShape) {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.on(['positionChanged', 'sizeChanged'], () => {
|
this.on(['positionChanged', 'sizeChanged'], this.onVerticesChanged, this);
|
||||||
const halfSize = Vector.scale(this.size, 0.5);
|
}
|
||||||
const width = this.width - 0.001;
|
|
||||||
const height = this.height - 0.001;
|
destroy() {
|
||||||
const position = Vector.add(this.position, Vector.scale(halfSize, -1));
|
super.destroy();
|
||||||
this.vertices = [
|
this.off(['positionChanged', 'sizeChanged'], this.onVerticesChanged);
|
||||||
position,
|
|
||||||
Vector.add(position, [width, 0]),
|
|
||||||
Vector.add(position, [width, height]),
|
|
||||||
Vector.add(position, [0, height]),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fromJSON(json) {
|
fromJSON(json) {
|
||||||
|
@ -41,6 +35,19 @@ export class RectangleShape extends decorate(PolygonShape) {
|
||||||
return this;
|
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() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
...super.toJSON(),
|
...super.toJSON(),
|
||||||
|
|
|
@ -12,15 +12,11 @@ export class ShapeView extends Renderable {
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
if (shape instanceof PolygonShape) {
|
if (shape instanceof PolygonShape) {
|
||||||
this.redrawPolygonLines();
|
this.redrawPolygonLines();
|
||||||
shape.on('aabbChanged', () => {
|
shape.on('aabbChanged', this.onPolygonShapeAabbChanged, this);
|
||||||
this.redrawPolygonLines();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (shape instanceof CircleShape) {
|
if (shape instanceof CircleShape) {
|
||||||
this.redrawCircle();
|
this.redrawCircle();
|
||||||
shape.on('aabbChanged', () => {
|
shape.on('aabbChanged', this.onCircleShapeAabbChanged, this);
|
||||||
this.redrawCircle();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (shape instanceof ShapeList) {
|
if (shape instanceof ShapeList) {
|
||||||
for (const child of shape) {
|
for (const child of shape) {
|
||||||
|
@ -29,15 +25,36 @@ export class ShapeView extends Renderable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.container.position = shape.position;
|
this.container.position = shape.position;
|
||||||
shape.on('positionChanged', () => {
|
shape.on('positionChanged', this.onShapePositionChanged, this);
|
||||||
this.container.position = shape.position;
|
}
|
||||||
})
|
|
||||||
|
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() {
|
get internal() {
|
||||||
return this.container.internal;
|
return this.container.internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onPolygonShapeAabbChanged() {
|
||||||
|
this.redrawPolygonLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
onCircleShapeAabbChanged() {
|
||||||
|
this.redrawCircle();
|
||||||
|
}
|
||||||
|
|
||||||
|
onShapePositionChanged() {
|
||||||
|
this.container.position = shape.position;
|
||||||
|
}
|
||||||
|
|
||||||
redrawCircle() {
|
redrawCircle() {
|
||||||
const primitives = new Primitives();
|
const primitives = new Primitives();
|
||||||
primitives.drawCircle(
|
primitives.drawCircle(
|
||||||
|
|
|
@ -30,15 +30,21 @@ export class Shape extends decorate(class {}) {
|
||||||
'originChanged',
|
'originChanged',
|
||||||
'rotationChanged',
|
'rotationChanged',
|
||||||
'scaleChanged',
|
'scaleChanged',
|
||||||
], () => {
|
], this.onAabbChanged, this);
|
||||||
this.emit('aabbChanged');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get aabb() {
|
get aabb() {
|
||||||
return [0, 0, 0, 0];
|
return [0, 0, 0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.off([
|
||||||
|
'originChanged',
|
||||||
|
'rotationChanged',
|
||||||
|
'scaleChanged',
|
||||||
|
], this.onAabbChanged);
|
||||||
|
}
|
||||||
|
|
||||||
fromJSON(json) {
|
fromJSON(json) {
|
||||||
const keys = [
|
const keys = [
|
||||||
'origin',
|
'origin',
|
||||||
|
@ -54,6 +60,10 @@ export class Shape extends decorate(class {}) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAabbChanged() {
|
||||||
|
this.emit('aabbChanged');
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
origin: this.origin,
|
origin: this.origin,
|
||||||
|
|
|
@ -21,10 +21,11 @@ export class Shaped extends decorate(Trait) {
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
this._shape.destroy();
|
||||||
if (this.shapeView) {
|
if (this.shapeView) {
|
||||||
this.shapeView.destroy();
|
this.shapeView.destroy();
|
||||||
|
this.shapeView = undefined;
|
||||||
}
|
}
|
||||||
this.shapeView = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get shape() {
|
get shape() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user