-
Notifications
You must be signed in to change notification settings - Fork 970
Unload scene specific resources on demand #7381
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
base: master
Are you sure you want to change the base?
Unload scene specific resources on demand #7381
Conversation
…ne-specific-resources-on-demand
…ne-specific-resources-on-demand
…ne-specific-resources-on-demand
…ne-specific-resources-on-demand
GDJS/Runtime/scenestack.ts
Outdated
const currentSceneName = currentScene.getName(); | ||
const newSceneName = currentScene.getRequestedScene(); | ||
|
||
if (this._sceneWasUnloadedResources.has(newSceneName)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a loading screen that is shown if a scene is not yet ready. We could probably rely on this instead of adding a special case? I.e: calling replace should call push that will display a loading screen if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored
Hi @ViktorVovk! (we could imagine an action to change this at runtime, but in most cases it could be something that never changes). The unloading algorithm could unload resources that are neither from a living scene (including the next one) nor a scene with the "unload" property disabled. Let's discuss what this would imply and how this would impact the algorithm that unloads resources :) |
…ne-specific-resources-on-demand
…ne-specific-resources-on-demand
Hi @4ian. I would really appreciate it if you could take another look at this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's going in the right direction, thanks! I've added a few more comments.
Core/GDCore/Project/Layout.h
Outdated
@@ -381,6 +393,7 @@ class GD_CORE_API Layout { | |||
behaviorsSharedData; ///< Initial shared datas of behaviors | |||
bool stopSoundsOnStartup = true; ///< True to make the scene stop all sounds at | |||
///< startup. | |||
bool unloadSceneAssets = false; ///< True to unload scene assets after exit scene |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool UnloadSceneAssets()
sounds as a method that actually unloads the assets.
What do you think about shouldUnloadAssetsWhenUnloaded
?
bool unloadSceneAssets = false; ///< True to unload scene assets after exit scene | |
bool shouldUnloadAssetsWhenUnloaded = false; ///< True to unload scene assets after exit scene | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. Thanks for you review. I totally agree with you on that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed!
async loadSceneAssetsBySceneName( | ||
sceneName: string, | ||
progressCallback?: (progress: float) => void | ||
): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is similar to gdjs.RuntimeGame.loadSceneAssets
.
Did you face any issue using loadSceneAssets
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I tried to understand and use the existing API, specifically RuntimeGame.loadSceneAssets
. However, when I used it and then returned to a previously unloaded scene, the resources for that scene were not loaded again. Although the methods RuntimeGame.loadSceneAssets
and RuntimeGame.loadSceneAssetsBySceneName
seem quite similar, I assumed they perform different tasks, as they invoke different methods in the ResourceLoader
.
RuntimeGame.loadSceneAssets
calls this._resourcesLoader.loadAndProcessSceneResources
, which in turn calls ResourceLoader.loadSceneResources
. From my understanding, this method does not actually load the resources but rather is intended for scenarios when switching to a scene whose resources are not yet loaded, but already queued for loading.
In contrast, RuntimeGame.loadSceneAssetsBySceneName
invokes this._resourcesLoader.loadSceneResourcesBySceneName
, which explicitly loads resources of a previously unloaded scene.
As an external developer, and not fully immersed in the entire context of the project, I tried to alter or modify the existing codebase as minimally as possible, just to avoid breaking any existing functionality that I might not be aware of. I would greatly appreciate your help in understanding why I couldn’t successfully use RuntimeGame.loadSceneAssets
. Perhaps there is something I overlooked.
…ne-specific-resources-on-demand
…ne-specific-resources-on-demand
This is an implementation of functionality for unloading all resources from the scene we are leaving. For example, we have several scenes (Preloader, postPreloader) that contain a significant number of resources such as images, audio, spine animations, atlases, JSON files, and so on. After these scenes have been loaded, once we transition to the so-called main scene, we want to remove (unload) all resources from the scenes that we do not expect to return to during the game’s runtime.
Plan for implementing the unloading of scene-specific resources on the GDevelop side:
An additional boolean parameter needs to be added to the "change scene" action. Enabling this parameter will indicate that all resources specific to the scene being exited should be unloaded. It is assumed that we will not return to this scene during the game’s runtime.
During the execution of the "change scene" action, the
_destroy
method is eventually called on the scene object (inruntimescene.ts
). At that point, the resource cleanup methoddisposeScene
—implemented in theResourceLoader
class—is invoked.The
disposeScene
method accepts the scene name as a parameter and creates aMap
where the keys are resource types (ResourceKind
) and the values are arrays ofResourceData
.In the
ResourceLoader
class, there is a field_resourceManagersMap
where the keys are resource types (ResourceKind
) and the values are resource managers. This makes it easy to correlate this map with the map of resources grouped by type since they share the same keys.In each resource manager class, a method
disposeByResourcesList
has been implemented, which takes an array of resources that need to be cleared. This method performs the cleanup of the resources in the provided list.