diff --git a/packages/math/src/Rect.ts b/packages/math/src/Rect.ts index 415779fce4..70dfda4374 100644 --- a/packages/math/src/Rect.ts +++ b/packages/math/src/Rect.ts @@ -1,6 +1,9 @@ import { IClone } from "./IClone"; import { ICopy } from "./ICopy"; +// Empty function for initialization of _onValueChangedCallback . +function emptyFunc(): void {} + // A 2d rectangle defined by x and y position, width and height. export class Rect implements IClone, ICopy { /** @internal */ @@ -12,8 +15,20 @@ export class Rect implements IClone, ICopy { /** @internal */ _height: number; /** @internal */ - _onValueChanged: () => void = null; - + get _onValueChanged(): () => void { + if (this._onValueChangedCallback === emptyFunc) { + return null; + } + return this._onValueChangedCallback; + } + set _onValueChanged(callback: () => void | null | undefined) { + if (callback && typeof callback === "function") { + this._onValueChangedCallback = callback; + } else { + this._onValueChangedCallback = emptyFunc; + } + } + private _onValueChangedCallback: () => void = emptyFunc; /** * The x coordinate of the rectangle. */ @@ -23,7 +38,7 @@ export class Rect implements IClone, ICopy { set x(value: number) { this._x = value; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); } /** @@ -35,7 +50,7 @@ export class Rect implements IClone, ICopy { set y(value: number) { this._y = value; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); } /** @@ -47,7 +62,7 @@ export class Rect implements IClone, ICopy { set width(value: number) { this._width = value; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); } /** @@ -59,7 +74,7 @@ export class Rect implements IClone, ICopy { set height(value: number) { this._height = value; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); } /** @@ -89,7 +104,7 @@ export class Rect implements IClone, ICopy { this._y = y; this._width = width; this._height = height; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); return this; } @@ -111,7 +126,7 @@ export class Rect implements IClone, ICopy { this._y = source.y; this._width = source.width; this._height = source.height; - this._onValueChanged && this._onValueChanged(); + this._onValueChangedCallback(); return this; } } diff --git a/tests/src/math/Rect.test.ts b/tests/src/math/Rect.test.ts index 3be1fdb019..34ec869206 100644 --- a/tests/src/math/Rect.test.ts +++ b/tests/src/math/Rect.test.ts @@ -29,4 +29,73 @@ describe("Rect test", () => { expect(a.width).to.eq(b.width); expect(a.height).to.eq(b.height); }); + it("_onValueChanged", () => { + const a = new Rect(0, 0, 1, 2); + expect(a._onValueChanged).to.eq(null); + let countChange = 0; + const _onValueChanged = () => { + countChange += 1; + }; + a._onValueChanged = _onValueChanged + expect(a._onValueChanged).to.eq(_onValueChanged); + a.x = 1; + expect(countChange).to.eq(1); + a.y = 1; + expect(countChange).to.eq(2); + a.width = 1; + expect(countChange).to.eq(3); + a._onValueChanged = null + expect(a._onValueChanged).to.eq(null); + }); + it("x", () => { + let countChange = 0; + const _onValueChanged = () => { + countChange += 1; + }; + const a = new Rect(0, 0, 1, 2); + a._onValueChanged = _onValueChanged + a.x = 9; + expect(a.x).to.eq(9); + expect(countChange).to.eq(1); + a.x = 10; + expect(a.x).to.eq(10); + expect(countChange).to.eq(2); + }); + it("y", () => { + const a = new Rect(0, 0, 1, 2); + a._onValueChanged = undefined; + expect(a._onValueChanged).to.eq(null); + // Test non-function value + a._onValueChanged = "not a function" as any; + expect(a._onValueChanged).to.eq(null); + + // Test multiple assignments + const callback1 = () => {}; + const callback2 = () => {}; + a._onValueChanged = callback1; + expect(a._onValueChanged).to.eq(callback1); + a._onValueChanged = callback2; + expect(a._onValueChanged).to.eq(callback2); + let countChange = 0; + const _onValueChanged = () => { + countChange += 1; + }; + a._onValueChanged = _onValueChanged + a.y = 1; + expect(countChange).to.eq(1); + expect(a.y).to.eq(1); + a.y = 2 + expect(a.y).to.eq(2); + expect(countChange).to.eq(2); + }); + it("width", () => { + const a = new Rect(0, 0, 1, 2); + a.width = 5; + expect(a.width).to.eq(5); + }); + it("height", () => { + const a = new Rect(0, 0, 1, 2); + a.height = 6; + expect(a.height).to.eq(6); + }); });