From d66ea06a4c2c14a6180d1daf278f6ceed5489f8e Mon Sep 17 00:00:00 2001 From: D8H Date: Fri, 18 Oct 2024 18:45:52 +0200 Subject: [PATCH] Fix resource used in behavior properties not being exported (#7084) Only show in developer changelog --- .../IDE/Project/ArbitraryResourceWorker.cpp | 2 +- .../BehaviorConfigurationContainer.cpp | 45 +++++++++++++++++++ .../Project/BehaviorConfigurationContainer.h | 18 ++++++-- .../Project/CustomObjectConfiguration.cpp | 4 +- Core/tests/ArbitraryResourceWorker.cpp | 31 +++++++++++++ Core/tests/DummyPlatform.cpp | 13 +++++- 6 files changed, 105 insertions(+), 8 deletions(-) diff --git a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp index 198ee881dde1..28102fca83a6 100644 --- a/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp +++ b/Core/GDCore/IDE/Project/ArbitraryResourceWorker.cpp @@ -293,7 +293,7 @@ void ResourceWorkerInObjectsWorker::DoVisitObject(gd::Object &object) { }; void ResourceWorkerInObjectsWorker::DoVisitBehavior(gd::Behavior &behavior){ - // TODO Allow behaviors to expose resources + behavior.ExposeResources(worker); }; gd::ResourceWorkerInObjectsWorker diff --git a/Core/GDCore/Project/BehaviorConfigurationContainer.cpp b/Core/GDCore/Project/BehaviorConfigurationContainer.cpp index 6bb15fb6037f..9dea002cc620 100644 --- a/Core/GDCore/Project/BehaviorConfigurationContainer.cpp +++ b/Core/GDCore/Project/BehaviorConfigurationContainer.cpp @@ -6,6 +6,7 @@ #include "GDCore/Project/BehaviorConfigurationContainer.h" #include #include "GDCore/Project/PropertyDescriptor.h" +#include "GDCore/IDE/Project/ArbitraryResourceWorker.h" namespace gd { @@ -22,4 +23,48 @@ std::map BehaviorConfigurationContainer::Get return nothing; } +void BehaviorConfigurationContainer::ExposeResources(gd::ArbitraryResourceWorker& worker) { + std::map properties = GetProperties(); + + for (auto& property : properties) { + const String& propertyName = property.first; + const gd::PropertyDescriptor& propertyDescriptor = property.second; + + if (propertyDescriptor.GetType().LowerCase() == "resource") { + auto& extraInfo = propertyDescriptor.GetExtraInfo(); + const gd::String& resourceType = extraInfo.empty() ? "" : extraInfo[0]; + const gd::String& oldPropertyValue = propertyDescriptor.GetValue(); + + gd::String newPropertyValue = oldPropertyValue; + if (resourceType == "image") { + worker.ExposeImage(newPropertyValue); + } else if (resourceType == "audio") { + worker.ExposeAudio(newPropertyValue); + } else if (resourceType == "font") { + worker.ExposeFont(newPropertyValue); + } else if (resourceType == "video") { + worker.ExposeVideo(newPropertyValue); + } else if (resourceType == "json") { + worker.ExposeJson(newPropertyValue); + } else if (resourceType == "tilemap") { + worker.ExposeTilemap(newPropertyValue); + } else if (resourceType == "tileset") { + worker.ExposeTileset(newPropertyValue); + } else if (resourceType == "bitmapFont") { + worker.ExposeBitmapFont(newPropertyValue); + } else if (resourceType == "model3D") { + worker.ExposeModel3D(newPropertyValue); + } else if (resourceType == "atlas") { + worker.ExposeAtlas(newPropertyValue); + } else if (resourceType == "spine") { + worker.ExposeSpine(newPropertyValue); + } + + if (newPropertyValue != oldPropertyValue) { + UpdateProperty(propertyName, newPropertyValue); + } + } + } +} + } // namespace gd diff --git a/Core/GDCore/Project/BehaviorConfigurationContainer.h b/Core/GDCore/Project/BehaviorConfigurationContainer.h index 9bdf4311bfa2..7d73ce2f5563 100644 --- a/Core/GDCore/Project/BehaviorConfigurationContainer.h +++ b/Core/GDCore/Project/BehaviorConfigurationContainer.h @@ -3,8 +3,7 @@ * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * reserved. This project is released under the MIT License. */ -#ifndef GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H -#define GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H +#pragma once #include #include @@ -19,6 +18,7 @@ class PropertyDescriptor; class SerializerElement; class Project; class Layout; +class ArbitraryResourceWorker; } // namespace gd namespace gd { @@ -158,6 +158,18 @@ class GD_CORE_API BehaviorConfigurationContainer { return propertiesQuickCustomizationVisibilities; } + /** + * \brief Called ( e.g. during compilation ) so as to inventory internal + * resources and sometimes update their filename. Implementation example: + * \code + * worker.ExposeImage(myImage); + * worker.ExposeFile(myResourceFile); + * \endcode + * + * \see ArbitraryResourceWorker + */ + void ExposeResources(gd::ArbitraryResourceWorker& worker); + protected: /** * \brief Called when the IDE wants to know about the custom properties of the @@ -209,5 +221,3 @@ class GD_CORE_API BehaviorConfigurationContainer { }; } // namespace gd - -#endif // GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H diff --git a/Core/GDCore/Project/CustomObjectConfiguration.cpp b/Core/GDCore/Project/CustomObjectConfiguration.cpp index cbee9b397c1d..e572ef155ac0 100644 --- a/Core/GDCore/Project/CustomObjectConfiguration.cpp +++ b/Core/GDCore/Project/CustomObjectConfiguration.cpp @@ -202,8 +202,8 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor for (auto& property : properties) { const String& propertyName = property.first; - const gd::PropertyDescriptor& propertyDescriptor = property.second; - if (propertyDescriptor.GetType() == "resource") { + const gd::PropertyDescriptor &propertyDescriptor = property.second; + if (propertyDescriptor.GetType().LowerCase() == "resource") { auto& extraInfo = propertyDescriptor.GetExtraInfo(); const gd::String& resourceType = extraInfo.empty() ? "" : extraInfo[0]; const gd::String& oldPropertyValue = propertyDescriptor.GetValue(); diff --git a/Core/tests/ArbitraryResourceWorker.cpp b/Core/tests/ArbitraryResourceWorker.cpp index 37ed982fc643..cf56423f5c01 100644 --- a/Core/tests/ArbitraryResourceWorker.cpp +++ b/Core/tests/ArbitraryResourceWorker.cpp @@ -151,6 +151,37 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") { REQUIRE(worker.images[0] == "res1"); } + SECTION("Can find resource usages in behavior configurations") { + gd::Platform platform; + gd::Project project; + SetupProjectWithDummyPlatform(project, platform); + + project.GetResourcesManager().AddResource( + "res1", "path/to/file1.png", "image"); + project.GetResourcesManager().AddResource( + "res2", "path/to/file2.png", "image"); + project.GetResourcesManager().AddResource( + "res3", "path/to/file3.png", "image"); + project.GetResourcesManager().AddResource( + "res4", "path/to/file4.png", "audio"); + ArbitraryResourceWorkerTest worker(project.GetResourcesManager()); + + auto &layout = project.InsertNewLayout("Scene", 0); + auto &object = layout.GetObjects().InsertNewObject( + project, "MyExtension::Sprite", "MyObject", 0); + auto *behavior = object.AddNewBehavior( + project, "MyExtension::BehaviorWithRequiredBehaviorProperty", + "BehaviorWithResource"); + behavior->UpdateProperty("resourceProperty", "res1"); + + worker.files.clear(); + worker.images.clear(); + gd::ResourceExposer::ExposeWholeProjectResources(project, worker); + REQUIRE(worker.files.size() == 4); + REQUIRE(worker.images.size() == 1); + REQUIRE(worker.images[0] == "res1"); + } + SECTION("Can find resource usages in layout events") { gd::Platform platform; gd::Project project; diff --git a/Core/tests/DummyPlatform.cpp b/Core/tests/DummyPlatform.cpp index 9299d4c47be7..791ff9456785 100644 --- a/Core/tests/DummyPlatform.cpp +++ b/Core/tests/DummyPlatform.cpp @@ -39,20 +39,31 @@ class BehaviorWithRequiredBehaviorProperty : public gd::Behavior { behaviorContent.GetStringAttribute("requiredBehaviorProperty")) .SetType("Behavior") .AddExtraInfo("MyExtension::MyBehavior"); + properties["resourceProperty"] + .SetLabel("A resource") + .SetValue( + behaviorContent.GetStringAttribute("resourceProperty")) + .SetType("Resource") + .AddExtraInfo("image"); return properties; } virtual bool UpdateProperty(gd::SerializerElement& behaviorContent, const gd::String& name, const gd::String& value) override { - if (name == _("requiredBehaviorProperty")) { + if (name == "requiredBehaviorProperty") { behaviorContent.SetAttribute("requiredBehaviorProperty", value); return true; } + if (name == "resourceProperty") { + behaviorContent.SetAttribute("resourceProperty", value); + return true; + } return false; } virtual void InitializeContent( gd::SerializerElement& behaviorContent) override { behaviorContent.SetAttribute("requiredBehaviorProperty", ""); + behaviorContent.SetAttribute("resourceProperty", ""); } };