Skip to content

Commit

Permalink
Fix unused resources clean up to keep resources used in effects (#5560)
Browse files Browse the repository at this point in the history
  • Loading branch information
D8H authored Aug 16, 2023
1 parent 9532a42 commit 6a26e2c
Show file tree
Hide file tree
Showing 21 changed files with 571 additions and 185 deletions.
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

0 comments on commit 6a26e2c

Please sign in to comment.