diff --git a/GDJS/Runtime/InGameEditor/InGameEditor.tsx b/GDJS/Runtime/InGameEditor/InGameEditor.tsx index ebfecdaaba11..bfeceb8b0c2c 100644 --- a/GDJS/Runtime/InGameEditor/InGameEditor.tsx +++ b/GDJS/Runtime/InGameEditor/InGameEditor.tsx @@ -366,13 +366,17 @@ namespace gdjs { }; let hasWindowFocus = true; + // References for cleanup + const _onWindowFocus = () => { + hasWindowFocus = true; + }; + const _onWindowBlur = () => { + hasWindowFocus = false; + }; + if (typeof window !== 'undefined') { - window.addEventListener('focus', () => { - hasWindowFocus = true; - }); - window.addEventListener('blur', () => { - hasWindowFocus = false; - }); + window.addEventListener('focus', _onWindowFocus); + window.addEventListener('blur', _onWindowBlur); } function isDefined(value: T | null | undefined): value is NonNullable { @@ -962,6 +966,10 @@ namespace gdjs { this._unregisterContextLostListener(); this._unregisterContextLostListener = null; } + if (typeof window !== 'undefined') { + window.removeEventListener('focus', _onWindowFocus); + window.removeEventListener('blur', _onWindowBlur); + } } private _applyInGameEditorSettings() { diff --git a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts index 3930778ec4cb..adfe4c6e480c 100644 --- a/GDJS/Runtime/debugger-client/abstract-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/abstract-debugger-client.ts @@ -499,6 +499,8 @@ namespace gdjs { } } + abstract dispose(): void; + /** * Should be re-implemented by derived class to send a stringified message object * to the debugger server. diff --git a/GDJS/Runtime/debugger-client/minimal-debugger-client.ts b/GDJS/Runtime/debugger-client/minimal-debugger-client.ts index 2da441a5fbb2..4a5e82c93f2d 100644 --- a/GDJS/Runtime/debugger-client/minimal-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/minimal-debugger-client.ts @@ -8,6 +8,8 @@ namespace gdjs { super(runtimeGame); } + dispose(): void {} + protected _sendMessage(message: string) {} } diff --git a/GDJS/Runtime/debugger-client/websocket-debugger-client.ts b/GDJS/Runtime/debugger-client/websocket-debugger-client.ts index a6462acad739..7af40df5a111 100644 --- a/GDJS/Runtime/debugger-client/websocket-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/websocket-debugger-client.ts @@ -86,6 +86,13 @@ namespace gdjs { } private hasLoggedError: boolean = false; + + dispose(): void { + if (this._ws) { + this._ws.close(); + } + } + protected _sendMessage(message: string) { if (!this._ws) { // The error can be logged only once, since logger.warn will call this function again, diff --git a/GDJS/Runtime/debugger-client/window-message-debugger-client.ts b/GDJS/Runtime/debugger-client/window-message-debugger-client.ts index 5c35a9004427..c764daac4fce 100644 --- a/GDJS/Runtime/debugger-client/window-message-debugger-client.ts +++ b/GDJS/Runtime/debugger-client/window-message-debugger-client.ts @@ -8,6 +8,10 @@ namespace gdjs { */ export class WindowMessageDebuggerClient extends gdjs.AbstractDebuggerClient { _opener: Window | null = null; + private _onWindowMessage = (event: MessageEvent) => { + const data = event.data; + this.handleCommand(data); + }; constructor(runtimeGame: RuntimeGame) { super(runtimeGame); @@ -24,10 +28,11 @@ namespace gdjs { return; } - window.addEventListener('message', (event) => { - const data = event.data; - this.handleCommand(data); - }); + window.addEventListener('message', this._onWindowMessage); + } + + dispose() { + window.removeEventListener('message', this._onWindowMessage); } protected _sendMessage(message: string) { diff --git a/GDJS/Runtime/runtimegame.ts b/GDJS/Runtime/runtimegame.ts index be92cd47d24e..df1d29ce772f 100644 --- a/GDJS/Runtime/runtimegame.ts +++ b/GDJS/Runtime/runtimegame.ts @@ -1270,6 +1270,9 @@ namespace gdjs { if (this._inGameEditor) { this._inGameEditor.dispose(); } + if (this._debuggerClient) { + this._debuggerClient.dispose(); + } this._renderer.stopGameLoop(); this._sceneStack.dispose(); this._renderer.dispose(removeCanvas);