From 9bdcdc20af3858949988fb14a8de63b100db13d0 Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Tue, 28 Jan 2025 13:13:22 -0800 Subject: [PATCH 1/5] Improved Immediate queue management --- .../dev/core/src/Engines/abstractEngine.ts | 7 +++++ packages/dev/core/src/Misc/timingTools.ts | 28 ++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/dev/core/src/Engines/abstractEngine.ts b/packages/dev/core/src/Engines/abstractEngine.ts index e4501ed4dcb..df8f955c111 100644 --- a/packages/dev/core/src/Engines/abstractEngine.ts +++ b/packages/dev/core/src/Engines/abstractEngine.ts @@ -52,6 +52,7 @@ import { Observable } from "../Misc/observable"; import { EngineFunctionContext, _loadFile } from "./abstractEngine.functions"; import type { Material } from "core/Materials/material"; import { _GetCompatibleTextureLoader } from "core/Materials/Textures/Loaders/textureLoaderManager"; +import { _RunImmediateQueue } from "core/Misc/timingTools"; /** * Defines the interface used by objects working like Scene @@ -216,6 +217,9 @@ export abstract class AbstractEngine { protected _activeRequests: IFileRequest[] = []; + /** @internal */ + public _immediateQueue: Array<() => void> = []; + /** @internal */ public _badOS = false; /** @internal */ @@ -880,6 +884,9 @@ export abstract class AbstractEngine { this._frameId++; this.onEndFrameObservable.notifyObservers(this); + + /** It is ok to call it even if several engines run */ + _RunImmediateQueue(); } /** diff --git a/packages/dev/core/src/Misc/timingTools.ts b/packages/dev/core/src/Misc/timingTools.ts index 0c5791e6cde..b04643ab545 100644 --- a/packages/dev/core/src/Misc/timingTools.ts +++ b/packages/dev/core/src/Misc/timingTools.ts @@ -1,4 +1,4 @@ -import { IsWindowObjectExist } from "./domManagement"; +const ImmediateQueue: Array<() => void> = []; /** * Class used to provide helper for timing @@ -9,12 +9,26 @@ export class TimingTools { * @param action defines the action to execute after the current execution block */ public static SetImmediate(action: () => void) { - if (IsWindowObjectExist() && window.setImmediate) { - // Note - deprecated and should not be used directly. Not supported in any browser. - window.setImmediate(action); - } else { - setTimeout(action, 1); - } + ImmediateQueue.push(action); + } +} + +/** + * @internal + */ +export function _RunImmediateQueue() { + if (ImmediateQueue.length) { + // Execute all immediate functions + // Doing a copy even though it should be fine but I do not want to deal with race conditions + // in the future. So, let's be safe. + const functionsToCall = ImmediateQueue.slice(0); + ImmediateQueue.length = 0; + + setTimeout(() => { + for (let i = 0; i < functionsToCall.length; i++) { + functionsToCall[i](); + } + }, 1); } } From 5ab7552987c0ccb2bd7d814d7e1d6c6d4e3ed4fe Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Tue, 28 Jan 2025 13:24:00 -0800 Subject: [PATCH 2/5] address feedback --- packages/dev/core/src/Engines/abstractEngine.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/dev/core/src/Engines/abstractEngine.ts b/packages/dev/core/src/Engines/abstractEngine.ts index df8f955c111..a9c011feaac 100644 --- a/packages/dev/core/src/Engines/abstractEngine.ts +++ b/packages/dev/core/src/Engines/abstractEngine.ts @@ -217,9 +217,6 @@ export abstract class AbstractEngine { protected _activeRequests: IFileRequest[] = []; - /** @internal */ - public _immediateQueue: Array<() => void> = []; - /** @internal */ public _badOS = false; /** @internal */ From e5776fc8785c804ceebca27ce5dfa26433071ab0 Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Tue, 28 Jan 2025 13:31:31 -0800 Subject: [PATCH 3/5] Address feedback --- .../dev/core/src/Engines/abstractEngine.ts | 4 --- packages/dev/core/src/Misc/timingTools.ts | 29 +++++++++---------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/packages/dev/core/src/Engines/abstractEngine.ts b/packages/dev/core/src/Engines/abstractEngine.ts index a9c011feaac..e4501ed4dcb 100644 --- a/packages/dev/core/src/Engines/abstractEngine.ts +++ b/packages/dev/core/src/Engines/abstractEngine.ts @@ -52,7 +52,6 @@ import { Observable } from "../Misc/observable"; import { EngineFunctionContext, _loadFile } from "./abstractEngine.functions"; import type { Material } from "core/Materials/material"; import { _GetCompatibleTextureLoader } from "core/Materials/Textures/Loaders/textureLoaderManager"; -import { _RunImmediateQueue } from "core/Misc/timingTools"; /** * Defines the interface used by objects working like Scene @@ -881,9 +880,6 @@ export abstract class AbstractEngine { this._frameId++; this.onEndFrameObservable.notifyObservers(this); - - /** It is ok to call it even if several engines run */ - _RunImmediateQueue(); } /** diff --git a/packages/dev/core/src/Misc/timingTools.ts b/packages/dev/core/src/Misc/timingTools.ts index b04643ab545..50bca42edaa 100644 --- a/packages/dev/core/src/Misc/timingTools.ts +++ b/packages/dev/core/src/Misc/timingTools.ts @@ -5,10 +5,21 @@ const ImmediateQueue: Array<() => void> = []; */ export class TimingTools { /** - * Polyfill for setImmediate + * Execute a function after the current execution block * @param action defines the action to execute after the current execution block */ public static SetImmediate(action: () => void) { + if (ImmediateQueue.length === 0) { + setTimeout(() => { + // Execute all immediate functions + const functionsToCall = ImmediateQueue.slice(0); + ImmediateQueue.length = 0; + + for (const func of functionsToCall) { + func(); + } + }, 1); + } ImmediateQueue.push(action); } } @@ -16,21 +27,7 @@ export class TimingTools { /** * @internal */ -export function _RunImmediateQueue() { - if (ImmediateQueue.length) { - // Execute all immediate functions - // Doing a copy even though it should be fine but I do not want to deal with race conditions - // in the future. So, let's be safe. - const functionsToCall = ImmediateQueue.slice(0); - ImmediateQueue.length = 0; - - setTimeout(() => { - for (let i = 0; i < functionsToCall.length; i++) { - functionsToCall[i](); - } - }, 1); - } -} +export function _RunImmediateQueue() {} function _runWithCondition(condition: () => boolean, onSuccess: () => void, onError?: (e?: any, isTimeout?: boolean) => void) { try { From 455a3ccfa4bbca7a57660fb817694a349cd50907 Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Tue, 28 Jan 2025 13:33:56 -0800 Subject: [PATCH 4/5] . --- packages/dev/core/src/Misc/timingTools.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/dev/core/src/Misc/timingTools.ts b/packages/dev/core/src/Misc/timingTools.ts index 50bca42edaa..99405c129e9 100644 --- a/packages/dev/core/src/Misc/timingTools.ts +++ b/packages/dev/core/src/Misc/timingTools.ts @@ -24,11 +24,6 @@ export class TimingTools { } } -/** - * @internal - */ -export function _RunImmediateQueue() {} - function _runWithCondition(condition: () => boolean, onSuccess: () => void, onError?: (e?: any, isTimeout?: boolean) => void) { try { if (condition()) { From 2ea2a52d11f62cc417e131e010c4ad8b29cf2c35 Mon Sep 17 00:00:00 2001 From: David Catuhe Date: Tue, 28 Jan 2025 13:40:18 -0800 Subject: [PATCH 5/5] address feedback --- packages/dev/core/src/Misc/timingTools.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/dev/core/src/Misc/timingTools.ts b/packages/dev/core/src/Misc/timingTools.ts index 99405c129e9..724f83d7ceb 100644 --- a/packages/dev/core/src/Misc/timingTools.ts +++ b/packages/dev/core/src/Misc/timingTools.ts @@ -1,4 +1,4 @@ -const ImmediateQueue: Array<() => void> = []; +let _immediateQueue: Array<() => void> = []; /** * Class used to provide helper for timing @@ -9,18 +9,18 @@ export class TimingTools { * @param action defines the action to execute after the current execution block */ public static SetImmediate(action: () => void) { - if (ImmediateQueue.length === 0) { + if (_immediateQueue.length === 0) { setTimeout(() => { // Execute all immediate functions - const functionsToCall = ImmediateQueue.slice(0); - ImmediateQueue.length = 0; + const functionsToCall = _immediateQueue; + _immediateQueue = []; for (const func of functionsToCall) { func(); } }, 1); } - ImmediateQueue.push(action); + _immediateQueue.push(action); } }