Skip to content
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

Fix unused resources clean up to keep resources used in effects #5560

Merged
merged 8 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 130 additions & 94 deletions Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/Project/Effect.h"
#include "GDCore/Tools/Log.h"
#include "GDCore/IDE/ResourceExposer.h"

using namespace std;

Expand Down Expand Up @@ -131,29 +133,9 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
std::cout << targetResourceName << std::endl;
gd::Resource& targetResource =
resourcesManager->GetResource(targetResourceName);
const gd::String& targetResourceKind = targetResource.GetKind();

gd::String potentiallyUpdatedTargetResourceName = targetResourceName;

if (targetResourceKind == "audio") {
ExposeAudio(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "bitmapFont") {
ExposeBitmapFont(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "font") {
ExposeFont(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "image") {
ExposeImage(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "json") {
ExposeJson(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "tilemap") {
ExposeTilemap(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "tileset") {
ExposeTileset(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "video") {
ExposeVideo(potentiallyUpdatedTargetResourceName);
} else if (targetResourceKind == "model3D") {
ExposeModel3D(potentiallyUpdatedTargetResourceName);
}
ExposeResourceWithType(targetResource.GetKind(), potentiallyUpdatedTargetResourceName);

if (potentiallyUpdatedTargetResourceName != targetResourceName) {
// The resource name was renamed. Also update the mapping.
Expand All @@ -170,6 +152,48 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
}
}

void ArbitraryResourceWorker::ExposeResourceWithType(
const gd::String &resourceType, gd::String &resourceName) {
if (resourceType == "image") {
ExposeImage(resourceName);
return;
}
if (resourceType == "model3D") {
ExposeModel3D(resourceName);
return;
}
if (resourceType == "audio") {
ExposeAudio(resourceName);
return;
}
if (resourceType == "font") {
ExposeFont(resourceName);
return;
}
if (resourceType == "bitmapFont") {
ExposeBitmapFont(resourceName);
return;
}
if (resourceType == "tilemap") {
ExposeTilemap(resourceName);
return;
}
if (resourceType == "tileset") {
ExposeTileset(resourceName);
return;
}
if (resourceType == "json") {
ExposeJson(resourceName);
return;
}
if (resourceType == "video") {
ExposeVideo(resourceName);
return;
}
gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName);
return;
}

void ArbitraryResourceWorker::ExposeResource(gd::Resource& resource) {
if (!resource.UseFile()) return;

Expand All @@ -180,86 +204,98 @@ void ArbitraryResourceWorker::ExposeResource(gd::Resource& resource) {

ArbitraryResourceWorker::~ArbitraryResourceWorker() {}

/**
* Launch the specified resource worker on every resource referenced in the
* events.
*/
class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
public:
ResourceWorkerInEventsWorker(const gd::Project& project_,
gd::ArbitraryResourceWorker& worker_)
: project(project_), worker(worker_){};
virtual ~ResourceWorkerInEventsWorker(){};

private:
bool DoVisitInstruction(gd::Instruction& instruction, bool isCondition) {
const auto& platform = project.GetCurrentPlatform();
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());

gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterExpression,
size_t parameterIndex,
const gd::String& lastObjectName) {
const String& parameterValue = parameterExpression.GetPlainString();
if (parameterMetadata.GetType() ==
"police" || // Should be renamed fontResource
parameterMetadata.GetType() == "fontResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeFont(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "soundfile" ||
parameterMetadata.GetType() ==
"musicfile") { // Should be renamed audioResource
gd::String updatedParameterValue = parameterValue;
worker.ExposeAudio(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "bitmapFontResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeBitmapFont(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "imageResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeImage(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "jsonResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeJson(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilemapResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeTilemap(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilesetResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeTileset(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "model3DResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeModel3D(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
}
});

return false;
};
bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instruction, bool isCondition) {
const auto& platform = project.GetCurrentPlatform();
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());

gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterExpression,
size_t parameterIndex,
const gd::String& lastObjectName) {
const String& parameterValue = parameterExpression.GetPlainString();
if (parameterMetadata.GetType() ==
"police" || // Should be renamed fontResource
parameterMetadata.GetType() == "fontResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeFont(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "soundfile" ||
parameterMetadata.GetType() ==
"musicfile") { // Should be renamed audioResource
gd::String updatedParameterValue = parameterValue;
worker.ExposeAudio(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "bitmapFontResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeBitmapFont(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "imageResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeImage(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "jsonResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeJson(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilemapResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeTilemap(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "tilesetResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeTileset(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
} else if (parameterMetadata.GetType() == "model3DResource") {
gd::String updatedParameterValue = parameterValue;
worker.ExposeModel3D(updatedParameterValue);
instruction.SetParameter(parameterIndex, updatedParameterValue);
}
});

const gd::Project& project;
gd::ArbitraryResourceWorker& worker;
return false;
};

void LaunchResourceWorkerOnEvents(const gd::Project& project,
gd::EventsList& events,
gd::ArbitraryResourceWorker& worker) {
ResourceWorkerInEventsWorker eventsWorker(project, worker);
gd::ResourceWorkerInEventsWorker eventsWorker(project, worker);
eventsWorker.Launch(events);
}

gd::ResourceWorkerInEventsWorker
GetResourceWorkerOnEvents(const gd::Project &project,
gd::ArbitraryResourceWorker &worker) {
gd::ResourceWorkerInEventsWorker eventsWorker(project, worker);
return eventsWorker;
}

void ResourceWorkerInObjectsWorker::DoVisitObject(gd::Object &object) {
object.GetConfiguration().ExposeResources(worker);
auto& effects = object.GetEffects();
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount(); effectIndex++)
{
auto& effect = effects.GetEffect(effectIndex);
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(), effect, worker);
}
};

void ResourceWorkerInObjectsWorker::DoVisitBehavior(gd::Behavior &behavior){
// TODO Allow behaviors to expose resources
};

gd::ResourceWorkerInObjectsWorker
GetResourceWorkerOnObjects(const gd::Project &project,
gd::ArbitraryResourceWorker &worker) {
gd::ResourceWorkerInObjectsWorker eventsWorker(project, worker);
return eventsWorker;
}

} // namespace gd
#endif
63 changes: 49 additions & 14 deletions Core/GDCore/IDE/Project/ArbitraryResourceWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
* reserved. This project is released under the MIT License.
*/

#ifndef ARBITRARYRESOURCEWORKER_H
#define ARBITRARYRESOURCEWORKER_H
#pragma once

#include <map>
#include <memory>
#include <vector>
#include "GDCore/String.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
namespace gd {
class BaseEvent;
}
Expand Down Expand Up @@ -53,6 +54,11 @@ class GD_CORE_API ArbitraryResourceWorker {
*/
void ExposeResources(gd::ResourcesManager *resourcesManager);

/**
* \brief Expose a resource from a given type.
*/
void ExposeResourceWithType(const gd::String& resourceType, gd::String& resourceName);

/**
* \brief Expose an image, which is always a reference to a "image" resource.
*/
Expand Down Expand Up @@ -132,18 +138,47 @@ class GD_CORE_API ArbitraryResourceWorker {
};

/**
* Tool function iterating over each event and calling
* Expose(Actions/Conditions)Resources for each actions and conditions with the
* ArbitraryResourceWorker passed as argument.
*
* \see gd::ArbitraryResourceWorker
* \ingroup IDE
* Launch the specified resource worker on every resource referenced in the
* events.
*/
void GD_CORE_API
LaunchResourceWorkerOnEvents(const gd::Project &project,
gd::EventsList &events,
gd::ArbitraryResourceWorker &worker);
class ResourceWorkerInEventsWorker : public gd::ArbitraryEventsWorker {
public:
ResourceWorkerInEventsWorker(const gd::Project &project_,
gd::ArbitraryResourceWorker &worker_)
: project(project_), worker(worker_){};
virtual ~ResourceWorkerInEventsWorker(){};

private:
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;

const gd::Project &project;
gd::ArbitraryResourceWorker &worker;
};

} // namespace gd
ResourceWorkerInEventsWorker GD_CORE_API GetResourceWorkerOnEvents(
const gd::Project &project, gd::ArbitraryResourceWorker &worker);

#endif // ARBITRARYRESOURCEWORKER_H
/**
* Launch the specified resource worker on every resource referenced in the
* objects.
*/
class GD_CORE_API ResourceWorkerInObjectsWorker
: public gd::ArbitraryObjectsWorker {
public:
ResourceWorkerInObjectsWorker(const gd::Project &project_, gd::ArbitraryResourceWorker &worker_)
: project(project_), worker(worker_){};
~ResourceWorkerInObjectsWorker() {}

private:
void DoVisitObject(gd::Object &object) override;
void DoVisitBehavior(gd::Behavior &behavior) override;

const gd::Project &project;
gd::ArbitraryResourceWorker &worker;
};

gd::ResourceWorkerInObjectsWorker GD_CORE_API
GetResourceWorkerOnObjects(const gd::Project &project, gd::ArbitraryResourceWorker &worker);

} // namespace gd
3 changes: 2 additions & 1 deletion Core/GDCore/IDE/Project/ProjectResourcesAdder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "GDCore/Project/Project.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h"
#include "GDCore/IDE/ResourceExposer.h"

using namespace std;

Expand All @@ -19,7 +20,7 @@ std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
std::vector<gd::String> unusedResources;
// Search for resources used in the project
gd::ResourcesInUseHelper resourcesInUse;
project.ExposeResources(resourcesInUse);
gd::ResourceExposer::ExposeWholeProjectResources(project, resourcesInUse);
std::set<gd::String>& usedResources = resourcesInUse.GetAll(resourceType);

// Search all resources not used
Expand Down
7 changes: 4 additions & 3 deletions Core/GDCore/IDE/Project/ProjectResourcesCopier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "GDCore/Project/Project.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h"
#include "GDCore/IDE/ResourceExposer.h"

using namespace std;

Expand All @@ -26,7 +27,7 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
bool preserveDirectoryStructure) {
// Check if there are some resources with absolute filenames
gd::ResourcesAbsolutePathChecker absolutePathChecker(fs);
originalProject.ExposeResources(absolutePathChecker);
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, absolutePathChecker);

auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
std::cout << "Copying all resources from " << projectDirectory << " to "
Expand All @@ -41,10 +42,10 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
preserveAbsoluteFilenames);

if (updateOriginalProject) {
originalProject.ExposeResources(resourcesMergingHelper);
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, resourcesMergingHelper);
} else {
std::shared_ptr<gd::Project> project(new gd::Project(originalProject));
project->ExposeResources(resourcesMergingHelper);
gd::ResourceExposer::ExposeWholeProjectResources(*project, resourcesMergingHelper);
}

// Copy resources
Expand Down
Loading