From 6ff80a185acfd256859787970bc7465c58eb14bf Mon Sep 17 00:00:00 2001 From: Martin Valigursky Date: Mon, 27 Mar 2023 14:45:48 +0100 Subject: [PATCH] Addition of private helper debug only function to help guard against destroyed objects being used. --- rollup.config.mjs | 2 ++ src/core/debug.js | 27 ++++++++++++++++++++++++++ src/platform/graphics/render-target.js | 5 ++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index 94cc71f894b..86c55d75db1 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -254,6 +254,7 @@ const moduleOptions = buildType => ({ const stripFunctions = [ 'Debug.assert', 'Debug.assertDeprecated', + 'Debug.assertDestroyed', 'Debug.call', 'Debug.deprecated', 'Debug.warn', @@ -265,6 +266,7 @@ const stripFunctions = [ 'Debug.trace', 'DebugHelper.setName', 'DebugHelper.setLabel', + `DebugHelper.setDestroyed`, 'DebugGraphics.toString', 'DebugGraphics.clearGpuMarkers', 'DebugGraphics.pushGpuMarker', diff --git a/src/core/debug.js b/src/core/debug.js index 6eaff59302b..eba526610a6 100644 --- a/src/core/debug.js +++ b/src/core/debug.js @@ -51,6 +51,22 @@ class Debug { } } + /** + * Assertion error message that writes an error message to the log if the object has already + * been destroyed. To be used along setDestroyed. + * + * @param {object} object - The object to check. + */ + static assertDestroyed(object) { + if (object?.__alreadyDestroyed) { + const message = `[${object.constructor?.name}] with name [${object.name}] has already been destroyed, and cannot be used.`; + if (!Debug._loggedMessages.has(message)) { + Debug._loggedMessages.add(message); + console.error('ASSERT FAILED: ', message, object); + } + } + } + /** * Executes a function in debug mode only. * @@ -169,6 +185,17 @@ class DebugHelper { object.label = label; } } + + /** + * Marks object as destroyed. Executes only in the debug build. To be used along assertDestroyed. + * + * @param {object} object - The object to mark as destroyed. + */ + static setDestroyed(object) { + if (object) { + object.__alreadyDestroyed = true; + } + } } export { Debug, DebugHelper }; diff --git a/src/platform/graphics/render-target.js b/src/platform/graphics/render-target.js index 58634a4d43a..b7b435ba26e 100644 --- a/src/platform/graphics/render-target.js +++ b/src/platform/graphics/render-target.js @@ -1,4 +1,4 @@ -import { Debug } from '../../core/debug.js'; +import { Debug, DebugHelper } from '../../core/debug.js'; import { TRACEID_RENDER_TARGET_ALLOC } from '../../core/constants.js'; import { PIXELFORMAT_DEPTH, PIXELFORMAT_DEPTHSTENCIL } from './constants.js'; import { DebugGraphics } from './debug-graphics.js'; @@ -167,6 +167,8 @@ class RenderTarget { this.destroyFrameBuffers(); } + + DebugHelper.setDestroyed(this); } /** @@ -206,6 +208,7 @@ class RenderTarget { * @ignore */ init() { + Debug.assertDestroyed(this); this.impl.init(this._device, this); }