From b06ff9fd4e3f679110363f2bd1e25c3d8081bc2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davy=20H=C3=A9lard?= Date: Thu, 7 Dec 2023 13:11:40 +0100 Subject: [PATCH] WIP: Update resources at hot-reload --- GDJS/Runtime/Model3DManager.ts | 8 ++++++++ GDJS/Runtime/ResourceCache.ts | 4 ++++ GDJS/Runtime/ResourceLoader.ts | 15 +++++++++------ GDJS/Runtime/ResourceManager.ts | 5 +++++ GDJS/Runtime/debugger-client/hot-reloader.ts | 2 ++ .../fontfaceobserver-font-manager.ts | 4 ++++ .../howler-sound-manager.ts | 6 +++++- GDJS/Runtime/jsonmanager.ts | 5 +++++ .../pixi-renderers/pixi-bitmapfont-manager.ts | 4 ++++ .../pixi-renderers/pixi-image-manager.ts | 18 ++++++++++++++++++ 10 files changed, 64 insertions(+), 7 deletions(-) diff --git a/GDJS/Runtime/Model3DManager.ts b/GDJS/Runtime/Model3DManager.ts index 0ea71c560b43..f3e84764bbd9 100644 --- a/GDJS/Runtime/Model3DManager.ts +++ b/GDJS/Runtime/Model3DManager.ts @@ -69,6 +69,11 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + this._loadedThreeModels.clear(); + this._downloadedArrayBuffers.clear(); + } + async processResource(resourceName: string): Promise { const resource = this._resourceLoader.getResource(resourceName); if (!resource) { @@ -114,6 +119,9 @@ namespace gdjs { if (!loader) { return; } + if (this._loadedThreeModels.get(resource)) { + return; + } const url = this._resourceLoader.getFullUrl(resource.file); try { const response = await fetch(url, { diff --git a/GDJS/Runtime/ResourceCache.ts b/GDJS/Runtime/ResourceCache.ts index e6edc8102ae5..1b8ea953f3f2 100644 --- a/GDJS/Runtime/ResourceCache.ts +++ b/GDJS/Runtime/ResourceCache.ts @@ -50,5 +50,9 @@ namespace gdjs { this._nameToContent.clear(); this._fileToContent.clear(); } + + getAllValues(): IterableIterator { + return this._fileToContent.values(); + } } } diff --git a/GDJS/Runtime/ResourceLoader.ts b/GDJS/Runtime/ResourceLoader.ts index 2ca32946ff06..c3c2611f6e1a 100644 --- a/GDJS/Runtime/ResourceLoader.ts +++ b/GDJS/Runtime/ResourceLoader.ts @@ -146,12 +146,6 @@ namespace gdjs { this._resources = new Map(); this._globalResources = globalResources; - // These 3 attributes are filled by `setResources`. - this._sceneResources = new Map>(); - this._sceneNamesToLoad = new Set(); - this._sceneNamesToMakeReady = new Set(); - this.setResources(resourceDataArray, globalResources, layoutDataArray); - this._imageManager = new gdjs.ImageManager(this); this._soundManager = new gdjs.SoundManager(this); this._fontManager = new gdjs.FontManager(this); @@ -176,6 +170,12 @@ namespace gdjs { this._resourceManagersMap.set(resourceKind, resourceManager); } } + + // These 3 attributes are filled by `setResources`. + this._sceneResources = new Map>(); + this._sceneNamesToLoad = new Set(); + this._sceneNamesToMakeReady = new Set(); + this.setResources(resourceDataArray, globalResources, layoutDataArray); } /** @@ -212,6 +212,9 @@ namespace gdjs { for (const resourceData of resourceDataArray) { this._resources.set(resourceData.name, resourceData); } + for (const resourceManager of this._resourceManagersMap.values()) { + resourceManager.clearCache(); + } } async loadAllResources( diff --git a/GDJS/Runtime/ResourceManager.ts b/GDJS/Runtime/ResourceManager.ts index 0de9a9667e3e..ca98f70d123e 100644 --- a/GDJS/Runtime/ResourceManager.ts +++ b/GDJS/Runtime/ResourceManager.ts @@ -29,5 +29,10 @@ namespace gdjs { * Return the kind of resources handled by this manager. */ getResourceKinds(): Array; + + /** + * Clear any resource in cache. + */ + clearCache():void; } } diff --git a/GDJS/Runtime/debugger-client/hot-reloader.ts b/GDJS/Runtime/debugger-client/hot-reloader.ts index ff8e0fafa499..168d9fa99e84 100644 --- a/GDJS/Runtime/debugger-client/hot-reloader.ts +++ b/GDJS/Runtime/debugger-client/hot-reloader.ts @@ -1237,6 +1237,8 @@ namespace gdjs { ): void { let somethingChanged = false; + // TODO Refresh resources here. + // Check if default properties changed if (oldInstance.x !== newInstance.x) { runtimeObject.setX(newInstance.x); diff --git a/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.ts b/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.ts index 9b242b837379..d1cb5c2c56c8 100644 --- a/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.ts +++ b/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.ts @@ -31,6 +31,10 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + // Hot-reload of font is not handled as fonts are unlikely to be edited. + } + /** * Return the font family associated to the specified font resource name. * The font resource must have been loaded before. If that's not the case, diff --git a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts index ec3849199f2a..aed4caef311f 100644 --- a/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts +++ b/GDJS/Runtime/howler-sound-manager/howler-sound-manager.ts @@ -365,7 +365,7 @@ namespace gdjs { * It is basically a container to associate channels to sounds and keep a list * of all sounds being played. */ - export class HowlerSoundManager { + export class HowlerSoundManager implements gdjs.ResourceManager { _loadedMusics = new gdjs.ResourceCache(); _loadedSounds = new gdjs.ResourceCache(); _availableResources: Record = {}; @@ -437,6 +437,10 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + // TODO Handle hot-reload of sounds. + } + /** * Ensure rate is in a range valid for Howler.js * @return The clamped rate diff --git a/GDJS/Runtime/jsonmanager.ts b/GDJS/Runtime/jsonmanager.ts index 8c8151820cff..a215165543f5 100644 --- a/GDJS/Runtime/jsonmanager.ts +++ b/GDJS/Runtime/jsonmanager.ts @@ -39,6 +39,11 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + this._loadedJsons.clear(); + this._callbacks.clear(); + } + /** * Request all the json resources to be preloaded (unless they are marked as not preloaded). * diff --git a/GDJS/Runtime/pixi-renderers/pixi-bitmapfont-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-bitmapfont-manager.ts index a9bd2b07e840..c2ec08591f15 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-bitmapfont-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-bitmapfont-manager.ts @@ -76,6 +76,10 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + this._loadedFontsData.clear(); + } + /** * Get the instance of the default `Pixi.BitmapFont`, always available. */ diff --git a/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts b/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts index 60d2852e7b67..8049be729a69 100644 --- a/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts +++ b/GDJS/Runtime/pixi-renderers/pixi-image-manager.ts @@ -76,6 +76,24 @@ namespace gdjs { return resourceKinds; } + clearCache(): void { + for (const texture of this._loadedTextures.getAllValues()) { + texture.destroy(true); + } + for (const name in this._loadedThreeTextures.items) { + const texture = this._loadedThreeTextures.items[name]; + texture.dispose(); + } + for (const name in this._loadedThreeMaterials.items) { + const texture = this._loadedThreeMaterials.items[name]; + texture.dispose(); + } + this._loadedTextures.clear(); + this._loadedThreeTextures.clear(); + this._loadedThreeMaterials.clear(); + PIXI.Assets.cache.reset(); + } + /** * Return the PIXI texture associated to the specified resource name. * Returns a placeholder texture if not found.