mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 17:45:25 -04:00
8e50ddefe4
- This is an advanced, experimental feature which is subject to changes. It's in most cases not useful, unless you have a large game or low end devices for which controlling memory usage is important. It's mostly useful to delay loading of large custom objects. - Objects can be configured so that its resources are not loaded when the scene is loaded. Instead, you can use an action to manually load the resources used by it. When the loading is done (this can be checked using a condition), the object can then be created. Be careful: if an object assets are not loaded, it will be broken when displayed on screen.
195 lines
7.4 KiB
C++
195 lines
7.4 KiB
C++
/*
|
|
* GDevelop Core
|
|
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
|
* reserved. This project is released under the MIT License.
|
|
*/
|
|
#include "ResourceExposer.h"
|
|
|
|
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
|
|
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
|
#include "GDCore/Extensions/Platform.h"
|
|
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
|
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
|
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
|
#include "GDCore/Project/Effect.h"
|
|
#include "GDCore/Project/EventsFunctionsExtension.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "GDCore/Project/Object.h"
|
|
#include "GDCore/String.h"
|
|
|
|
namespace gd {
|
|
|
|
void ResourceExposer::ExposeWholeProjectResources(
|
|
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
|
|
// See also gd::ProjectBrowserHelper::ExposeProjectEvents for a method that
|
|
// traverse the whole project (this time for events) and ExposeProjectEffects
|
|
// (this time for effects).
|
|
|
|
// Expose any project resources as files.
|
|
worker.ExposeResources();
|
|
|
|
project.GetPlatformSpecificAssets().ExposeResources(worker);
|
|
|
|
// Expose event resources
|
|
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
|
gd::ProjectBrowserHelper::ExposeProjectEvents(project, eventWorker);
|
|
|
|
// Expose object configuration resources
|
|
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
|
gd::ProjectBrowserHelper::ExposeProjectObjects(project, objectWorker);
|
|
|
|
// Expose layer effect resources
|
|
for (std::size_t layoutIndex = 0; layoutIndex < project.GetLayoutsCount();
|
|
layoutIndex++) {
|
|
auto &layout = project.GetLayout(layoutIndex);
|
|
|
|
for (std::size_t layerIndex = 0; layerIndex < layout.GetLayersCount();
|
|
layerIndex++) {
|
|
auto &layer = layout.GetLayer(layerIndex);
|
|
|
|
auto &effects = layer.GetEffects();
|
|
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
|
effectIndex++) {
|
|
auto &effect = effects.GetEffect(effectIndex);
|
|
gd::ResourceExposer::ExposeEffectResources(
|
|
project.GetCurrentPlatform(), effect, worker);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Expose loading screen background image if present
|
|
auto &loadingScreen = project.GetLoadingScreen();
|
|
if (loadingScreen.GetBackgroundImageResourceName() != "")
|
|
worker.ExposeImage(loadingScreen.GetBackgroundImageResourceName());
|
|
|
|
// Expose extension source files
|
|
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
|
e++) {
|
|
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
|
ExposeExtensionResources(eventsFunctionsExtension, worker);
|
|
}
|
|
}
|
|
|
|
void ResourceExposer::ExposeProjectResources(
|
|
gd::Project &project, gd::ArbitraryResourceWorker &worker) {
|
|
// Expose global objects configuration resources
|
|
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
|
objectWorker.Launch(project.GetObjects());
|
|
|
|
// Exposed extension event resources
|
|
// Note that using resources in extensions is very unlikely and probably not
|
|
// worth the effort of something smart.
|
|
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
|
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
|
e++) {
|
|
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
|
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
|
|
project, eventsFunctionsExtension, eventWorker);
|
|
}
|
|
}
|
|
|
|
void ResourceExposer::ExposeLayoutResources(
|
|
gd::Project &project, gd::Layout &layout,
|
|
gd::ArbitraryResourceWorker &worker) {
|
|
std::function<bool(const gd::Object &)> shouldCheckObject =
|
|
[](const gd::Object &object) { return true; };
|
|
gd::ResourceExposer::ExposeLayoutResources(project, layout, worker,
|
|
shouldCheckObject);
|
|
}
|
|
|
|
void ResourceExposer::ExposeLayoutResources(
|
|
gd::Project &project, gd::Layout &layout,
|
|
gd::ArbitraryResourceWorker &worker,
|
|
std::function<bool(const gd::Object &)> &shouldCheckObject) {
|
|
// Expose object configuration resources
|
|
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker, shouldCheckObject);
|
|
gd::ProjectBrowserHelper::ExposeLayoutObjects(layout, objectWorker);
|
|
|
|
// Expose layer effect resources
|
|
for (std::size_t layerIndex = 0; layerIndex < layout.GetLayersCount();
|
|
layerIndex++) {
|
|
auto &layer = layout.GetLayer(layerIndex);
|
|
|
|
auto &effects = layer.GetEffects();
|
|
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
|
effectIndex++) {
|
|
auto &effect = effects.GetEffect(effectIndex);
|
|
gd::ResourceExposer::ExposeEffectResources(
|
|
project.GetCurrentPlatform(), effect, worker);
|
|
}
|
|
}
|
|
|
|
// Expose event resources
|
|
auto eventWorker = gd::GetResourceWorkerOnEvents(project, worker);
|
|
gd::ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
|
|
project, layout, eventWorker);
|
|
}
|
|
|
|
void ResourceExposer::ExposeEventsBasedObjectVariantResources(
|
|
gd::Project &project,
|
|
gd::EventsBasedObjectVariant &eventsBasedObjectVariant,
|
|
gd::ArbitraryResourceWorker &worker) {
|
|
// Expose object configuration resources
|
|
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
|
gd::ProjectBrowserHelper::ExposeEventsBasedObjectVariantObjects(
|
|
eventsBasedObjectVariant, objectWorker);
|
|
|
|
// Expose layer effect resources
|
|
auto &layers = eventsBasedObjectVariant.GetLayers();
|
|
for (std::size_t layerIndex = 0; layerIndex < layers.GetLayersCount();
|
|
layerIndex++) {
|
|
auto &layer = layers.GetLayer(layerIndex);
|
|
|
|
auto &effects = layer.GetEffects();
|
|
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount();
|
|
effectIndex++) {
|
|
auto &effect = effects.GetEffect(effectIndex);
|
|
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(),
|
|
effect, worker);
|
|
}
|
|
}
|
|
// We don't check the events because it would cost too much to do it for every
|
|
// variant. Resource usage in events-based object events and their
|
|
// dependencies should be rare.
|
|
}
|
|
|
|
void ResourceExposer::ExposeEffectResources(
|
|
gd::Platform &platform,
|
|
gd::Effect &effect,
|
|
gd::ArbitraryResourceWorker &worker) {
|
|
auto &effectMetadata =
|
|
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
|
|
|
|
for (auto &propertyPair : effectMetadata.GetProperties()) {
|
|
auto &propertyName = propertyPair.first;
|
|
auto &propertyDescriptor = propertyPair.second;
|
|
|
|
if (propertyDescriptor.GetType() == "resource" &&
|
|
propertyDescriptor.GetExtraInfo().size() > 0) {
|
|
auto &resourceType = propertyDescriptor.GetExtraInfo()[0];
|
|
|
|
const gd::String &resourceName = effect.GetStringParameter(propertyName);
|
|
if (!resourceName.empty()) {
|
|
gd::String potentiallyUpdatedResourceName = resourceName;
|
|
worker.ExposeResourceWithType(resourceType,
|
|
potentiallyUpdatedResourceName);
|
|
if (potentiallyUpdatedResourceName != resourceName) {
|
|
effect.SetStringParameter(propertyName,
|
|
potentiallyUpdatedResourceName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ResourceExposer::ExposeExtensionResources(
|
|
gd::EventsFunctionsExtension &extension,
|
|
gd::ArbitraryResourceWorker &worker) {
|
|
for (auto &sourceFile : extension.GetAllSourceFiles()) {
|
|
worker.ExposeJavaScript(sourceFile.GetResourceName());
|
|
}
|
|
}
|
|
|
|
} // namespace gd
|