Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: only call init functions of objects once #416

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const filesToCache = [
`${prefix}/assets/styles.css`
];

const staticCacheName = 'kontra-docs-v10.0.0';
const staticCacheName = 'kontra-docs-v10.0.2';

// cache the application shell
self.addEventListener('install', event => {
Expand Down
1 change: 1 addition & 0 deletions src/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class Button extends SpriteClass {
*/
destroy() {
this._dn.remove();
this.textNode.destroy();
}

_p() {
Expand Down
17 changes: 12 additions & 5 deletions src/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ export let callbacks = {};
*
* @param {String} event - Name of the event.
* @param {Function} callback - Function that will be called when the event is emitted.
* @param {Boolean} [once=false] - If the callback should only be called the first time the event is emitted.
*/
export function on(event, callback) {
export function on(event, callback, once = false) {
callbacks[event] = callbacks[event] || [];
callbacks[event].push(callback);
callbacks[event].push({ fn: callback, once });
}

/**
Expand All @@ -44,10 +45,11 @@ export function on(event, callback) {
*
* @param {String} event - Name of the event.
* @param {Function} callback - The function that was passed during registration.
* @param {Boolean} [once=false] - If the callback was added as a one time function or not.
*/
export function off(event, callback) {
export function off(event, callback, once = false) {
callbacks[event] = (callbacks[event] || []).filter(
fn => fn != callback
({ fn, once: _once }) => !(fn == callback && _once == once)
);
}

Expand All @@ -59,7 +61,12 @@ export function off(event, callback) {
* @param {...*} args - Comma separated list of arguments passed to all callbacks.
*/
export function emit(event, ...args) {
(callbacks[event] || []).map(fn => fn(...args));
(callbacks[event] || []).map(({ fn, once }) => {
fn(...args);
if (once) {
off(event, fn, once);
}
});
}

// expose for testing
Expand Down
10 changes: 7 additions & 3 deletions src/gameLoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,13 @@ export default function GameLoop({
});
}

on('init', () => {
loop.context ??= getContext();
});
on(
'init',
() => {
loop.context ??= getContext();
},
true
);

/**
* Called every frame of the game loop.
Expand Down
19 changes: 16 additions & 3 deletions src/gameObject.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getContext } from './core.js';
import Updatable from './updatable.js';
import { on } from './events.js';
import { on, off } from './events.js';
import { rotatePoint, clamp } from './helpers.js';
import { noop, removeFromArray } from './utils.js';

Expand Down Expand Up @@ -267,9 +267,22 @@ class GameObject extends Updatable {
// uf = update function
this._uf = update;

on('init', () => {
// in = init
this._in = () => {
this.context ??= getContext();
});
};
if (!this.context) {
on('init', this._in, true);
}
}

/**
* Clean up the GameObject object.
* @memberof Text
* @function destroy
*/
destroy() {
off('init', this._in, true);
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,9 @@ class Scene {

if (this.context) {
this._i();
} else {
on('init', this._i, true);
}

on('init', this._i);
}

set objects(value) {
Expand Down Expand Up @@ -317,9 +317,10 @@ class Scene {
* @function destroy
*/
destroy() {
off('init', this._i);
off('init', this._i, true);
this._dn.remove();
this._o.map(object => object.destroy && object.destroy());
this.camera.destroy();
}

/**
Expand Down
30 changes: 21 additions & 9 deletions src/text.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GameObjectClass } from './gameObject.js';
import { on } from './events.js';
import { on, off } from './events.js';
import { getContext } from './core.js';

let fontSizeRegex = /(\d+)(\w+)/;
Expand Down Expand Up @@ -115,15 +115,18 @@ class Text extends GameObjectClass {
...props
});

// p = prerender
if (this.context) {
this._p();
}

on('init', () => {
// i = init
this._i = () => {
this.font ??= getContext().font;
// p = prerender
this._p();
});
};

if (this.context) {
this._i();
} else {
on('init', this._i, true);
}
}

// keep width and height getters/settings so we can set _w and _h
Expand Down Expand Up @@ -171,6 +174,16 @@ class Text extends GameObjectClass {
this._lh = value;
}

/**
* Clean up the Text object.
* @memberof Text
* @function destroy
*/
destroy() {
super.destroy();
off('init', this._i, true);
}

render() {
if (this._d) {
this._p();
Expand Down Expand Up @@ -267,7 +280,6 @@ class Text extends GameObjectClass {
context.fillStyle = this.color;
context.font = this.font;


// @ifdef TEXT_STROKE
if (this.strokeColor) {
context.strokeStyle = this.strokeColor;
Expand Down
26 changes: 19 additions & 7 deletions src/tileEngine.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getCanvas, getContext } from './core.js';
import { on } from './events.js';
import { on, off } from './events.js';
import { clamp, getWorldRect } from './helpers.js';
import { removeFromArray } from './utils.js';

Expand Down Expand Up @@ -230,15 +230,27 @@ class TileEngine {
...properties
});

// p = prerender
if (this.context) {
// i = init
this._i = () => {
this.context ??= getContext();
// p = prerender
this._p();
};

if (this.context) {
this._i();
} else {
on('init', this._i, true);
}
}

on('init', () => {
this.context ??= getContext();
this._p();
});
/**
* Clean up the TileEngine object.
* @memberof TileEngine
* @function destroy
*/
destroy() {
off('init', this._i, true);
}

// @ifdef TILEENGINE_CAMERA
Expand Down
3 changes: 3 additions & 0 deletions test/typings/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@ kontra.emit('myEvent');
kontra.on('myEvent', (num, str, bool, obj) => {
console.log({num, str, bool, obj});
});
kontra.on('myEvent', (num, str, bool, obj) => {
console.log({num, str, bool, obj});
}, true);
kontra.emit('myEvent', 1, 'string', true, {});
1 change: 1 addition & 0 deletions test/typings/gameObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ gameObject.render();
gameObject.draw();
gameObject.setScale(1);
gameObject.setScale(1, 2);
gameObject.destroy();

// options
kontra.GameObject({
Expand Down
1 change: 1 addition & 0 deletions test/typings/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ text.x += 20;
text.rotation = Math.PI;
text.advance();
text.render();
text.destroy();

// options
kontra.Text({
Expand Down
1 change: 1 addition & 0 deletions test/typings/tileEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const { x, y, row, col } = tileEngine.getPosition({x: 100, y: 200})
tileEngine.getPosition({x: 100, y: 200} as PointerEvent)
tileEngine.setTileAtLayer('ground', { x, y }, 5);
tileEngine.setTileAtLayer('ground', { row, col }, 5);
tileEngine.destroy();

// options
kontra.TileEngine({
Expand Down
7 changes: 7 additions & 0 deletions test/unit/button.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,13 @@ describe('button', () => {

expect(document.body.contains(button._dn)).to.be.false;
});

it('should call destroy on the textNode', () => {
sinon.spy(button.textNode, 'destroy');
button.destroy();

expect(button.textNode.destroy.called).to.be.true;
});
});

// --------------------------------------------------
Expand Down
Loading
Loading