Fix events refactoring when duplicating custom behaviors or custom objects (#7005)

This commit is contained in:
D8H
2024-10-10 19:48:31 +02:00
committed by GitHub
parent 8972e0e3a6
commit e9781133e1
17 changed files with 500 additions and 86 deletions

View File

@@ -29,9 +29,6 @@ void EventBasedBehaviorBrowser::ExposeEvents(
project, eventsFunctionsExtension, eventsBasedBehavior, worker);
}
void EventBasedBehaviorBrowser::ExposeObjects(
gd::Project &project, gd::ArbitraryObjectsWorker &worker) const {}
void EventBasedBehaviorBrowser::ExposeFunctions(
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) const {
worker.Launch(eventsBasedBehavior.GetEventsFunctions());
@@ -43,7 +40,4 @@ void EventBasedBehaviorBrowser::ExposeEventBasedBehaviors(
worker.Launch(eventsBasedBehavior);
}
void EventBasedBehaviorBrowser::ExposeBehaviorSharedDatas(
gd::Project &project, gd::ArbitraryBehaviorSharedDataWorker &worker) const {}
} // namespace gd

View File

@@ -67,7 +67,7 @@ public:
* \brief Do nothing.
*/
void ExposeObjects(gd::Project &project,
gd::ArbitraryObjectsWorker &worker) const override;
gd::ArbitraryObjectsWorker &worker) const override {};
/**
* \brief Call the specified worker on the event-based behavior.
@@ -80,7 +80,7 @@ public:
* \brief Do nothing.
*/
void ExposeBehaviorSharedDatas(gd::Project &project,
gd::ArbitraryBehaviorSharedDataWorker &worker) const override;
gd::ArbitraryBehaviorSharedDataWorker &worker) const override {};
private:
const gd::EventsFunctionsExtension &eventsFunctionsExtension;

View File

@@ -0,0 +1,37 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "EventBasedObjectBrowser.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventBasedBehaviorsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventsFunctionsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/IDE/Project/ArbitraryBehaviorSharedDataWorker.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/Project.h"
#include "GDCore/String.h"
namespace gd {
void EventBasedObjectBrowser::ExposeEvents(
gd::Project &project, gd::ArbitraryEventsWorker &worker) const {
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsBasedObject, worker);
}
void EventBasedObjectBrowser::ExposeEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) const {
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject, worker);
}
void EventBasedObjectBrowser::ExposeFunctions(
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) const {
worker.Launch(eventsBasedObject.GetEventsFunctions());
}
} // namespace gd

View File

@@ -0,0 +1,90 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/IDE/ProjectBrowser.h"
namespace gd {
class Project;
class String;
class EventsFunctionsExtension;
class EventsFunction;
class EventsBasedBehavior;
class EventsBasedObject;
class ArbitraryEventsWorker;
class ArbitraryEventsWorkerWithContext;
class ArbitraryEventsFunctionsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventBasedBehaviorsWorker;
class ArbitraryBehaviorSharedDataWorker;
} // namespace gd
namespace gd {
/**
* \brief Expose event-based object contents to workers.
*/
class GD_CORE_API EventBasedObjectBrowser : public ProjectBrowser {
public:
EventBasedObjectBrowser(
const gd::EventsFunctionsExtension &eventsFunctionsExtension_,
gd::EventsBasedObject &eventsBasedObject_)
: eventsFunctionsExtension(eventsFunctionsExtension_),
eventsBasedObject(eventsBasedObject_) {}
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an event-based object.
*/
void ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorker &worker) const override;
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an event-based object.
*/
void
ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorkerWithContext &worker) const override;
/**
* \brief Call the specified worker on all functions of the event-based object
*
* This should be the preferred way to traverse all the function signatures
* of an event-based object.
*/
void ExposeFunctions(gd::Project &project,
gd::ArbitraryEventsFunctionsWorker &worker) const override;
/**
* \brief Do nothing.
*/
void ExposeObjects(gd::Project &project,
gd::ArbitraryObjectsWorker &worker) const override {};
/**
* @brief Do nothing.
*/
void ExposeEventBasedBehaviors(
gd::Project &project,
gd::ArbitraryEventBasedBehaviorsWorker &worker) const override {};
/**
* \brief Do nothing.
*/
void ExposeBehaviorSharedDatas(gd::Project &project,
gd::ArbitraryBehaviorSharedDataWorker &worker) const override {};
private:
const gd::EventsFunctionsExtension &eventsFunctionsExtension;
gd::EventsBasedObject &eventsBasedObject;
};
} // namespace gd

View File

@@ -6,17 +6,9 @@
#include "ResourceExposer.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/EventsFunctionTools.h"
#include "GDCore/IDE/Project/ArbitraryBehaviorSharedDataWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventBasedBehaviorsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventsFunctionsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/Project/EventsBasedBehavior.h"
#include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/ExternalEvents.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/Effect.h"
@@ -24,7 +16,6 @@
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/IDE/Events/UsedExtensionsFinder.h"
namespace gd {

View File

@@ -13,6 +13,7 @@
#include "GDCore/IDE/DependenciesAnalyzer.h"
#include "GDCore/IDE/GroupVariableHelper.h"
#include "GDCore/IDE/EventBasedBehaviorBrowser.h"
#include "GDCore/IDE/EventBasedObjectBrowser.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Events/BehaviorParametersFiller.h"
#include "GDCore/IDE/Events/BehaviorTypeRenamer.h"
@@ -28,11 +29,6 @@
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
#include "GDCore/IDE/Events/LinkEventTargetRenamer.h"
#include "GDCore/IDE/Events/ProjectElementRenamer.h"
#include "GDCore/IDE/EventsFunctionTools.h"
#include "GDCore/IDE/Project/ArbitraryBehaviorSharedDataWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventBasedBehaviorsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventsFunctionsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/IDE/Project/BehaviorObjectTypeRenamer.h"
#include "GDCore/IDE/Project/BehaviorsSharedDataBehaviorTypeRenamer.h"
#include "GDCore/IDE/Project/FunctionParameterBehaviorTypeRenamer.h"
@@ -415,20 +411,32 @@ void WholeProjectRefactorer::UpdateExtensionNameInEventsBasedBehavior(
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceExtensionName) {
const EventBasedBehaviorBrowser eventBasedBehaviorExposer(
const EventBasedBehaviorBrowser eventBasedBehaviorBrowser(
eventsFunctionsExtension, eventsBasedBehavior);
WholeProjectRefactorer::RenameEventsFunctionsExtension(
project, eventsFunctionsExtension, sourceExtensionName,
eventsFunctionsExtension.GetName(), eventBasedBehaviorExposer);
eventsFunctionsExtension.GetName(), eventBasedBehaviorBrowser);
}
void WholeProjectRefactorer::UpdateExtensionNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceExtensionName) {
const EventBasedObjectBrowser eventBasedObjectBrowser(
eventsFunctionsExtension, eventsBasedObject);
WholeProjectRefactorer::RenameEventsFunctionsExtension(
project, eventsFunctionsExtension, sourceExtensionName,
eventsFunctionsExtension.GetName(), eventBasedObjectBrowser);
}
void WholeProjectRefactorer::RenameEventsFunctionsExtension(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::String &oldName, const gd::String &newName) {
const WholeProjectBrowser wholeProjectExposer;
const WholeProjectBrowser wholeProjectBrowser;
RenameEventsFunctionsExtension(project, eventsFunctionsExtension, oldName,
newName, wholeProjectExposer);
newName, wholeProjectBrowser);
}
void WholeProjectRefactorer::RenameEventsFunctionsExtension(
@@ -1312,6 +1320,19 @@ bool WholeProjectRefactorer::FixInvalidRequiredBehaviorProperties(
return !invalidRequiredBehaviorProblems.empty();
}
void WholeProjectRefactorer::UpdateBehaviorNameInEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceBehaviorName) {
const EventBasedBehaviorBrowser eventBasedBehaviorExposer(
eventsFunctionsExtension, eventsBasedBehavior);
WholeProjectRefactorer::RenameEventsBasedBehavior(
project, eventsFunctionsExtension, eventsBasedBehavior,
sourceBehaviorName, eventsBasedBehavior.GetName(),
eventBasedBehaviorExposer);
}
void WholeProjectRefactorer::RenameEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
@@ -1324,10 +1345,22 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
return;
}
auto &eventsBasedBehavior = eventsBasedBehaviors.Get(oldBehaviorName);
const WholeProjectBrowser projectBrowser;
WholeProjectRefactorer::RenameEventsBasedBehavior(
project, eventsFunctionsExtension, eventsBasedBehavior, oldBehaviorName,
newBehaviorName, projectBrowser);
}
void WholeProjectRefactorer::RenameEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &oldBehaviorName,
const gd::String &newBehaviorName,
const gd::ProjectBrowser &projectBrowser) {
auto renameBehaviorEventsFunction =
[&project, &eventsFunctionsExtension, &oldBehaviorName,
&newBehaviorName](const gd::EventsFunction &eventsFunction) {
&newBehaviorName, &projectBrowser](const gd::EventsFunction &eventsFunction) {
if (eventsFunction.IsExpression()) {
// Nothing to do, expressions are not including the name of the
// behavior
@@ -1341,12 +1374,12 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newBehaviorName,
eventsFunction.GetName()));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, renamer);
projectBrowser.ExposeEvents(project, renamer);
}
};
auto renameBehaviorProperty = [&project, &eventsFunctionsExtension,
&oldBehaviorName, &newBehaviorName](
&oldBehaviorName, &newBehaviorName, &projectBrowser](
const gd::NamedPropertyDescriptor
&property) {
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
@@ -1357,7 +1390,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newBehaviorName,
EventsBasedBehavior::GetPropertyActionName(property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, actionRenamer);
projectBrowser.ExposeEvents(project, actionRenamer);
gd::InstructionsTypeRenamer conditionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -1367,7 +1400,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newBehaviorName,
EventsBasedBehavior::GetPropertyConditionName(property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, conditionRenamer);
projectBrowser.ExposeEvents(project, conditionRenamer);
// Nothing to do for expression, expressions are not including the name of
// the behavior
@@ -1375,7 +1408,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
auto renameBehaviorSharedProperty =
[&project, &eventsFunctionsExtension, &oldBehaviorName,
&newBehaviorName](const gd::NamedPropertyDescriptor &property) {
&newBehaviorName, &projectBrowser](const gd::NamedPropertyDescriptor &property) {
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
project,
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
@@ -1386,7 +1419,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
eventsFunctionsExtension.GetName(), newBehaviorName,
EventsBasedBehavior::GetSharedPropertyActionName(
property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, actionRenamer);
projectBrowser.ExposeEvents(project, actionRenamer);
gd::InstructionsTypeRenamer conditionRenamer =
gd::InstructionsTypeRenamer(
@@ -1399,8 +1432,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
eventsFunctionsExtension.GetName(), newBehaviorName,
EventsBasedBehavior::GetSharedPropertyConditionName(
property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
conditionRenamer);
projectBrowser.ExposeEvents(project, conditionRenamer);
// Nothing to do for expression, expressions are not including the name
// of the behavior
@@ -1435,13 +1467,25 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
renameBehaviorSharedProperty(*property);
}
const WholeProjectBrowser wholeProjectExposer;
DoRenameBehavior(project,
gd::PlatformExtension::GetBehaviorFullType(
eventsFunctionsExtension.GetName(), oldBehaviorName),
gd::PlatformExtension::GetBehaviorFullType(
eventsFunctionsExtension.GetName(), newBehaviorName),
wholeProjectExposer);
projectBrowser);
}
void WholeProjectRefactorer::UpdateObjectNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceObjectName) {
const EventBasedObjectBrowser eventBasedObjectBrowser(
eventsFunctionsExtension, eventsBasedObject);
WholeProjectRefactorer::RenameEventsBasedObject(
project, eventsFunctionsExtension, eventsBasedObject,
sourceObjectName, eventsBasedObject.GetName(),
eventBasedObjectBrowser);
}
void WholeProjectRefactorer::RenameEventsBasedObject(
@@ -1455,10 +1499,21 @@ void WholeProjectRefactorer::RenameEventsBasedObject(
return;
}
auto &eventsBasedObject = eventsBasedObjects.Get(oldObjectName);
const WholeProjectBrowser projectBrowser;
WholeProjectRefactorer::RenameEventsBasedObject(
project, eventsFunctionsExtension, eventsBasedObject, oldObjectName,
newObjectName, projectBrowser);
}
void WholeProjectRefactorer::RenameEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &oldObjectName, const gd::String &newObjectName,
const gd::ProjectBrowser &projectBrowser) {
auto renameObjectEventsFunction =
[&project, &eventsFunctionsExtension, &oldObjectName,
&newObjectName](const gd::EventsFunction &eventsFunction) {
[&project, &eventsFunctionsExtension, &oldObjectName, &newObjectName,
&projectBrowser](const gd::EventsFunction &eventsFunction) {
if (eventsFunction.IsExpression()) {
// Nothing to do, expressions are not including the name of the
// object
@@ -1472,12 +1527,12 @@ void WholeProjectRefactorer::RenameEventsBasedObject(
gd::PlatformExtension::GetObjectEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newObjectName,
eventsFunction.GetName()));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, renamer);
projectBrowser.ExposeEvents(project, renamer);
}
};
auto renameObjectProperty = [&project, &eventsFunctionsExtension,
&oldObjectName, &newObjectName](
&oldObjectName, &newObjectName, &projectBrowser](
const gd::NamedPropertyDescriptor &property) {
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -1487,7 +1542,7 @@ void WholeProjectRefactorer::RenameEventsBasedObject(
gd::PlatformExtension::GetObjectEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newObjectName,
EventsBasedObject::GetPropertyActionName(property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, actionRenamer);
projectBrowser.ExposeEvents(project, actionRenamer);
gd::InstructionsTypeRenamer conditionRenamer = gd::InstructionsTypeRenamer(
project,
@@ -1497,7 +1552,7 @@ void WholeProjectRefactorer::RenameEventsBasedObject(
gd::PlatformExtension::GetObjectEventsFunctionFullType(
eventsFunctionsExtension.GetName(), newObjectName,
EventsBasedObject::GetPropertyConditionName(property.GetName())));
gd::ProjectBrowserHelper::ExposeProjectEvents(project, conditionRenamer);
projectBrowser.ExposeEvents(project, conditionRenamer);
// Nothing to do for expression, expressions are not including the name of
// the object
@@ -1528,13 +1583,12 @@ void WholeProjectRefactorer::RenameEventsBasedObject(
renameObjectProperty(*property);
}
const WholeProjectBrowser wholeProjectExposer;
DoRenameObject(project,
gd::PlatformExtension::GetObjectFullType(
eventsFunctionsExtension.GetName(), oldObjectName),
gd::PlatformExtension::GetObjectFullType(
eventsFunctionsExtension.GetName(), newObjectName),
wholeProjectExposer);
projectBrowser);
}
void WholeProjectRefactorer::DoRenameEventsFunction(

View File

@@ -27,14 +27,7 @@ class ObjectsContainer;
class VariablesContainer;
class EventsBasedBehavior;
class EventsBasedObject;
class ArbitraryEventsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventsFunctionsWorker;
class ArbitraryEventsWorkerWithContext;
class ArbitraryEventBasedBehaviorsWorker;
class ArbitraryBehaviorSharedDataWorker;
class Behavior;
class BehaviorMetadata;
class UnfilledRequiredBehaviorPropertyProblem;
class ProjectBrowser;
class SerializerElement;
@@ -121,14 +114,24 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& newName);
/**
* \brief Refactor behavior events after the extension was placed in a new
* \brief Refactor behavior events after the behavior has been placed in a new
* extension.
*/
static void UpdateExtensionNameInEventsBasedBehavior(
gd::Project& project,
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::String& sourceExtensionName);
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceExtensionName);
/**
* \brief Refactor object events after the object has been placed in a new
* extension.
*/
static void UpdateExtensionNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceExtensionName);
/**
* \brief Refactor the project **before** an events function is renamed.
@@ -324,6 +327,16 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& oldBehaviorName,
const gd::String& newBehaviorName);
/**
* \brief Refactor events-based behavior events after the events-based
* behavior has been duplicated.
*/
static void UpdateBehaviorNameInEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &sourceBehaviorName);
/**
* \brief Refactor the project **before** an object is renamed.
*
@@ -337,6 +350,16 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& oldObjectName,
const gd::String& newObjectName);
/**
* \brief Refactor events-based object events after the events-based object
* has been duplicated.
*/
static void UpdateObjectNameInEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::EventsBasedObject &eventsBasedObject,
const gd::String &sourceObjectName);
/**
* \brief Refactor the project after a layout is renamed.
*/
@@ -654,6 +677,35 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& newName,
const gd::ProjectBrowser& projectBrowser);
/**
* \brief Refactor the project **before** a behavior is renamed.
*
* \warning Do the renaming of the specified behavior after calling this.
* This is because the behavior is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedBehavior(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &oldBehaviorName,
const gd::String &newBehaviorName,
const gd::ProjectBrowser &projectBrowser);
/**
* \brief Refactor the project **before** an object is renamed.
*
* \warning Do the renaming of the specified object after calling this.
* This is because the object is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedObject(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &oldObjectName, const gd::String &newObjectName,
const gd::ProjectBrowser &projectBrowser);
static void FindDependentBehaviorNames(
const gd::Project& project,
const gd::Object& object,

View File

@@ -1992,7 +1992,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
// A behavior is copied from one extension to another.
// An events-based behavior is copied from one extension to another.
auto &destinationExtension =
project.InsertNewEventsFunctionsExtension("DestinationExtension", 0);
@@ -2001,21 +2001,19 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// instruction keeps pointing to the old extension.
destinationExtension.InsertNewEventsFunction("MyEventsFunction", 0);
auto &copiedBehavior =
auto &duplicatedBehavior =
destinationExtension.GetEventsBasedBehaviors().InsertNew(
"MyOtherEventsBasedBehavior", 0);
copiedBehavior.SetFullName("My events based behavior");
copiedBehavior.SetDescription("An events based behavior for test");
copiedBehavior.SetObjectType("MyEventsExtension::MyEventsBasedObject");
duplicatedBehavior.SetObjectType("MyEventsExtension::MyEventsBasedObject");
// Add the copied events.
auto &behaviorEventsFunctions = copiedBehavior.GetEventsFunctions();
auto &behaviorAction = behaviorEventsFunctions.InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
auto &eventsFunctions = duplicatedBehavior.GetEventsFunctions();
auto &behaviorAction = eventsFunctions.InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
SetupEvents(behaviorAction.GetEvents());
gd::WholeProjectRefactorer::UpdateExtensionNameInEventsBasedBehavior(
project, destinationExtension, copiedBehavior, "MyEventsExtension");
project, destinationExtension, duplicatedBehavior, "MyEventsExtension");
// Check that events function calls in instructions have been renamed
REQUIRE(GetEventFirstActionType(behaviorAction.GetEvents().GetEvent(
@@ -2023,13 +2021,123 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
for (auto *eventsList : GetEventsLists(project)) {
// Check that events function calls in instructions have NOT been renamed
// outside of the copied behavior.
// outside of the copied events-based behavior.
REQUIRE(
GetEventFirstActionType(eventsList->GetEvent(FreeFunctionAction)) ==
"MyEventsExtension::MyEventsFunction");
}
}
SECTION("Events extension renamed in instructions scoped to one object") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
// An events-based object is copied from one extension to another.
auto &destinationExtension =
project.InsertNewEventsFunctionsExtension("DestinationExtension", 0);
// Add the function used by the instruction that is checked in this test.
// When the function doesn't exist the destination extension, the
// instruction keeps pointing to the old extension.
destinationExtension.InsertNewEventsFunction("MyEventsFunction", 0);
auto &duplicatedObject =
destinationExtension.GetEventsBasedObjects().InsertNew(
"MyDuplicatedEventsBasedObject", 0);
// Add the copied events.
auto &eventsFunctions = duplicatedObject.GetEventsFunctions();
auto &objectAction = eventsFunctions.InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
SetupEvents(objectAction.GetEvents());
gd::WholeProjectRefactorer::UpdateExtensionNameInEventsBasedObject(
project, destinationExtension, duplicatedObject, "MyEventsExtension");
// Check that events function calls in instructions have been renamed
REQUIRE(GetEventFirstActionType(objectAction.GetEvents().GetEvent(
FreeFunctionAction)) == "DestinationExtension::MyEventsFunction");
for (auto *eventsList : GetEventsLists(project)) {
// Check that events function calls in instructions have NOT been renamed
// outside of the copied events-based object.
REQUIRE(
GetEventFirstActionType(eventsList->GetEvent(FreeFunctionAction)) ==
"MyEventsExtension::MyEventsFunction");
}
}
SECTION("Events-based behavior renamed in instructions scoped to one behavior") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
// An events-based behavior is duplicated in the same extension.
auto &duplicatedBehavior =
eventsExtension.GetEventsBasedBehaviors().InsertNew(
"MyDuplicatedEventsBasedBehavior", 0);
duplicatedBehavior.SetObjectType("MyEventsExtension::MyEventsBasedObject");
// Add the copied events.
auto &eventsFunctions = duplicatedBehavior.GetEventsFunctions();
auto &behaviorAction = eventsFunctions.InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
SetupEvents(behaviorAction.GetEvents());
gd::WholeProjectRefactorer::UpdateBehaviorNameInEventsBasedBehavior(
project, eventsExtension, duplicatedBehavior, "MyEventsBasedBehavior");
// Check that events function calls in instructions have been renamed
REQUIRE(GetEventFirstActionType(
behaviorAction.GetEvents().GetEvent(BehaviorAction)) ==
"MyEventsExtension::MyDuplicatedEventsBasedBehavior::MyBehaviorEventsFunction");
for (auto *eventsList : GetEventsLists(project)) {
// Check that events function calls in instructions have NOT been renamed
// outside of the duplicated events-based behavior.
REQUIRE(
GetEventFirstActionType(eventsList->GetEvent(BehaviorAction)) ==
"MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunction");
}
}
SECTION("Events-based object renamed in instructions scoped to one object") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
// An events-based object is duplicated in the same extension.
auto &duplicatedObject =
eventsExtension.GetEventsBasedObjects().InsertNew(
"MyDuplicatedEventsBasedObject", 0);
// Add the copied events.
auto &eventsFunctions = duplicatedObject.GetEventsFunctions();
auto &objectAction = eventsFunctions.InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
SetupEvents(objectAction.GetEvents());
gd::WholeProjectRefactorer::UpdateObjectNameInEventsBasedObject(
project, eventsExtension, duplicatedObject, "MyEventsBasedObject");
// Check that events function calls in instructions have been renamed
REQUIRE(GetEventFirstActionType(
objectAction.GetEvents().GetEvent(ObjectAction)) ==
"MyEventsExtension::MyDuplicatedEventsBasedObject::MyObjectEventsFunction");
for (auto *eventsList : GetEventsLists(project)) {
// Check that events function calls in instructions have NOT been renamed
// outside of the duplicated events-based object.
REQUIRE(
GetEventFirstActionType(eventsList->GetEvent(ObjectAction)) ==
"MyEventsExtension::MyEventsBasedObject::MyObjectEventsFunction");
}
}
SECTION("Events extension renamed in parameters") {
gd::Project project;
gd::Platform platform;

View File

@@ -2451,6 +2451,11 @@ interface WholeProjectRefactorer {
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Ref] EventsBasedBehavior eventsBasedBehavior,
[Const] DOMString sourceExtensionName);
void STATIC_UpdateExtensionNameInEventsBasedObject(
[Ref] Project project,
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Ref] EventsBasedObject eventsBasedObject,
[Const] DOMString sourceExtensionName);
void STATIC_RenameEventsFunction(
[Ref] Project project,
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
@@ -2511,11 +2516,21 @@ interface WholeProjectRefactorer {
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Const] DOMString oldName,
[Const] DOMString newName);
void STATIC_UpdateBehaviorNameInEventsBasedBehavior(
[Ref] Project project,
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Ref] EventsBasedBehavior eventsBasedBehavior,
[Const] DOMString sourceBehaviorName);
void STATIC_RenameEventsBasedObject(
[Ref] Project project,
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Const] DOMString oldName,
[Const] DOMString newName);
void STATIC_UpdateObjectNameInEventsBasedObject(
[Ref] Project project,
[Const, Ref] EventsFunctionsExtension eventsFunctionsExtension,
[Ref] EventsBasedObject eventsBasedObject,
[Const] DOMString sourceObjectName);
void STATIC_RenameLayout(
[Ref] Project project,
[Const] DOMString oldName,

View File

@@ -717,6 +717,8 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
#define STATIC_RenameEventsFunctionsExtension RenameEventsFunctionsExtension
#define STATIC_UpdateExtensionNameInEventsBasedBehavior \
UpdateExtensionNameInEventsBasedBehavior
#define STATIC_UpdateExtensionNameInEventsBasedObject \
UpdateExtensionNameInEventsBasedObject
#define STATIC_RenameEventsFunction RenameEventsFunction
#define STATIC_RenameBehaviorEventsFunction RenameBehaviorEventsFunction
#define STATIC_RenameObjectEventsFunction RenameObjectEventsFunction
@@ -731,7 +733,9 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
RenameEventsBasedBehaviorSharedProperty
#define STATIC_RenameEventsBasedObjectProperty RenameEventsBasedObjectProperty
#define STATIC_RenameEventsBasedBehavior RenameEventsBasedBehavior
#define STATIC_UpdateBehaviorNameInEventsBasedBehavior UpdateBehaviorNameInEventsBasedBehavior
#define STATIC_RenameEventsBasedObject RenameEventsBasedObject
#define STATIC_UpdateObjectNameInEventsBasedObject UpdateObjectNameInEventsBasedObject
#define STATIC_RenameLayout RenameLayout
#define STATIC_RenameExternalLayout RenameExternalLayout
#define STATIC_RenameExternalEvents RenameExternalEvents

View File

@@ -1863,6 +1863,7 @@ export class WholeProjectRefactorer extends EmscriptenObject {
static applyRefactoringForGroupVariablesContainer(project: Project, globalObjectsContainer: ObjectsContainer, objectsContainer: ObjectsContainer, groupVariablesContainer: VariablesContainer, objectGroup: ObjectGroup, changeset: VariablesChangeset, originalSerializedVariables: SerializerElement): void;
static renameEventsFunctionsExtension(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, oldName: string, newName: string): void;
static updateExtensionNameInEventsBasedBehavior(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedBehavior: EventsBasedBehavior, sourceExtensionName: string): void;
static updateExtensionNameInEventsBasedObject(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedObject: EventsBasedObject, sourceExtensionName: string): void;
static renameEventsFunction(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, oldName: string, newName: string): void;
static renameBehaviorEventsFunction(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedBehavior: EventsBasedBehavior, oldName: string, newName: string): void;
static renameObjectEventsFunction(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedObject: EventsBasedObject, oldName: string, newName: string): void;
@@ -1873,7 +1874,9 @@ export class WholeProjectRefactorer extends EmscriptenObject {
static renameEventsBasedBehaviorSharedProperty(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedBehavior: EventsBasedBehavior, oldName: string, newName: string): void;
static renameEventsBasedObjectProperty(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedObject: EventsBasedObject, oldName: string, newName: string): void;
static renameEventsBasedBehavior(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, oldName: string, newName: string): void;
static updateBehaviorNameInEventsBasedBehavior(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedBehavior: EventsBasedBehavior, sourceBehaviorName: string): void;
static renameEventsBasedObject(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, oldName: string, newName: string): void;
static updateObjectNameInEventsBasedObject(project: Project, eventsFunctionsExtension: EventsFunctionsExtension, eventsBasedObject: EventsBasedObject, sourceObjectName: string): void;
static renameLayout(project: Project, oldName: string, newName: string): void;
static renameExternalLayout(project: Project, oldName: string, newName: string): void;
static renameExternalEvents(project: Project, oldName: string, newName: string): void;

View File

@@ -5,6 +5,7 @@ declare class gdWholeProjectRefactorer {
static applyRefactoringForGroupVariablesContainer(project: gdProject, globalObjectsContainer: gdObjectsContainer, objectsContainer: gdObjectsContainer, groupVariablesContainer: gdVariablesContainer, objectGroup: gdObjectGroup, changeset: gdVariablesChangeset, originalSerializedVariables: gdSerializerElement): void;
static renameEventsFunctionsExtension(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, oldName: string, newName: string): void;
static updateExtensionNameInEventsBasedBehavior(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedBehavior: gdEventsBasedBehavior, sourceExtensionName: string): void;
static updateExtensionNameInEventsBasedObject(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedObject: gdEventsBasedObject, sourceExtensionName: string): void;
static renameEventsFunction(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, oldName: string, newName: string): void;
static renameBehaviorEventsFunction(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedBehavior: gdEventsBasedBehavior, oldName: string, newName: string): void;
static renameObjectEventsFunction(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedObject: gdEventsBasedObject, oldName: string, newName: string): void;
@@ -15,7 +16,9 @@ declare class gdWholeProjectRefactorer {
static renameEventsBasedBehaviorSharedProperty(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedBehavior: gdEventsBasedBehavior, oldName: string, newName: string): void;
static renameEventsBasedObjectProperty(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedObject: gdEventsBasedObject, oldName: string, newName: string): void;
static renameEventsBasedBehavior(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, oldName: string, newName: string): void;
static updateBehaviorNameInEventsBasedBehavior(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedBehavior: gdEventsBasedBehavior, sourceBehaviorName: string): void;
static renameEventsBasedObject(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, oldName: string, newName: string): void;
static updateObjectNameInEventsBasedObject(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension, eventsBasedObject: gdEventsBasedObject, sourceObjectName: string): void;
static renameLayout(project: gdProject, oldName: string, newName: string): void;
static renameExternalLayout(project: gdProject, oldName: string, newName: string): void;
static renameExternalEvents(project: gdProject, oldName: string, newName: string): void;

View File

@@ -694,18 +694,50 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
_onEventsBasedBehaviorPasted = (
eventsBasedBehavior: gdEventsBasedBehavior,
sourceExtensionName: string
sourceExtensionName: string,
sourceEventsBasedBehaviorName: string
) => {
const { project, eventsFunctionsExtension } = this.props;
if (eventsFunctionsExtension.getName() === sourceExtensionName) {
return;
if (eventsFunctionsExtension.getName() !== sourceExtensionName) {
gd.WholeProjectRefactorer.updateExtensionNameInEventsBasedBehavior(
project,
eventsFunctionsExtension,
eventsBasedBehavior,
sourceExtensionName
);
}
if (eventsBasedBehavior.getName() !== sourceEventsBasedBehaviorName) {
gd.WholeProjectRefactorer.updateBehaviorNameInEventsBasedBehavior(
project,
eventsFunctionsExtension,
eventsBasedBehavior,
sourceEventsBasedBehaviorName
);
}
};
_onEventsBasedObjectPasted = (
eventsBasedObject: gdEventsBasedObject,
sourceExtensionName: string,
sourceEventsBasedObjectName: string
) => {
const { project, eventsFunctionsExtension } = this.props;
if (eventsFunctionsExtension.getName() !== sourceExtensionName) {
gd.WholeProjectRefactorer.updateExtensionNameInEventsBasedObject(
project,
eventsFunctionsExtension,
eventsBasedObject,
sourceExtensionName
);
}
if (eventsBasedObject.getName() !== sourceEventsBasedObjectName) {
gd.WholeProjectRefactorer.updateObjectNameInEventsBasedObject(
project,
eventsFunctionsExtension,
eventsBasedObject,
sourceEventsBasedObjectName
);
}
gd.WholeProjectRefactorer.updateExtensionNameInEventsBasedBehavior(
project,
eventsFunctionsExtension,
eventsBasedBehavior,
sourceExtensionName
);
};
_onEventsBasedBehaviorRenamed = () => {
@@ -1429,6 +1461,7 @@ export default class EventsFunctionsExtensionEditor extends React.Component<
i18n
)}
onEventsBasedObjectRenamed={this._onEventsBasedObjectRenamed}
onEventsBasedObjectPasted={this._onEventsBasedObjectPasted}
onAddEventsBasedObject={this._onAddEventsBasedObject}
onSelectExtensionProperties={() => this._editOptions(true)}
onSelectExtensionGlobalVariables={() =>

View File

@@ -52,7 +52,8 @@ export type EventsBasedBehaviorCallbacks = {|
) => void,
onEventsBasedBehaviorPasted: (
eventsBasedBehavior: gdEventsBasedBehavior,
sourceExtensionName: string
sourceExtensionName: string,
sourceEventsBasedBehaviorName: string
) => void,
|};
@@ -284,16 +285,19 @@ export class EventsBasedBehaviorTreeViewItemContent
const clipboardContent = Clipboard.get(
EVENTS_BASED_BEHAVIOR_CLIPBOARD_KIND
);
const copiedEventsBasedBehavior = SafeExtractor.extractObjectProperty(
const sourceEventsBasedBehavior = SafeExtractor.extractObjectProperty(
clipboardContent,
'eventsBasedBehavior'
);
const name = SafeExtractor.extractStringProperty(clipboardContent, 'name');
if (!name || !copiedEventsBasedBehavior) return;
const sourceEventsBasedBehaviorName = SafeExtractor.extractStringProperty(
clipboardContent,
'name'
);
if (!sourceEventsBasedBehaviorName || !sourceEventsBasedBehavior) return;
const { project, eventsBasedBehaviorsList } = this.props;
const newName = newNameGenerator(name, name =>
const newName = newNameGenerator(sourceEventsBasedBehaviorName, name =>
eventsBasedBehaviorsList.has(name)
);
@@ -304,7 +308,7 @@ export class EventsBasedBehaviorTreeViewItemContent
unserializeFromJSObject(
newEventsBasedBehavior,
copiedEventsBasedBehavior,
sourceEventsBasedBehavior,
'unserializeFrom',
project
);
@@ -317,7 +321,8 @@ export class EventsBasedBehaviorTreeViewItemContent
if (sourceExtensionName) {
this.props.onEventsBasedBehaviorPasted(
newEventsBasedBehavior,
sourceExtensionName
sourceExtensionName,
sourceEventsBasedBehaviorName
);
}

View File

@@ -38,6 +38,11 @@ export type EventsBasedObjectCallbacks = {|
(parameters: ?EventsBasedObjectCreationParameters) => void
) => void,
onEventsBasedObjectRenamed: (eventsBasedObject: gdEventsBasedObject) => void,
onEventsBasedObjectPasted: (
eventsBasedObject: gdEventsBasedObject,
sourceExtensionName: string,
sourceEventsBasedObjectName: string
) => void,
onOpenCustomObjectEditor: (eventsBasedObject: gdEventsBasedObject) => void,
|};
@@ -239,6 +244,7 @@ export class EventsBasedObjectTreeViewItemContent
Clipboard.set(EVENTS_BASED_OBJECT_CLIPBOARD_KIND, {
eventsBasedObject: serializeToJSObject(this.eventsBasedObject),
name: this.eventsBasedObject.getName(),
extensionName: this.props.eventsFunctionsExtension.getName(),
});
}
@@ -257,12 +263,15 @@ export class EventsBasedObjectTreeViewItemContent
clipboardContent,
'eventsBasedObject'
);
const name = SafeExtractor.extractStringProperty(clipboardContent, 'name');
if (!name || !copiedEventsBasedObject) return;
const sourceEventsBasedObjectName = SafeExtractor.extractStringProperty(
clipboardContent,
'name'
);
if (!sourceEventsBasedObjectName || !copiedEventsBasedObject) return;
const { project, eventsBasedObjectsList } = this.props;
const newName = newNameGenerator(name, name =>
const newName = newNameGenerator(sourceEventsBasedObjectName, name =>
eventsBasedObjectsList.has(name)
);
@@ -279,6 +288,18 @@ export class EventsBasedObjectTreeViewItemContent
);
newEventsBasedObject.setName(newName);
const sourceExtensionName = SafeExtractor.extractStringProperty(
clipboardContent,
'extensionName'
);
if (sourceExtensionName) {
this.props.onEventsBasedObjectPasted(
newEventsBasedObject,
sourceExtensionName,
sourceEventsBasedObjectName
);
}
this._onEventsBasedObjectModified();
this.props.onSelectEventsBasedObject(newEventsBasedObject);
this.props.editName(getObjectTreeViewItemId(newEventsBasedObject));

View File

@@ -539,6 +539,7 @@ const EventsFunctionsList = React.forwardRef<
onDeleteEventsBasedObject,
onRenameEventsBasedObject,
onEventsBasedObjectRenamed,
onEventsBasedObjectPasted,
onAddEventsBasedObject,
selectedEventsFunction,
selectedEventsBasedBehavior,
@@ -997,6 +998,7 @@ const EventsFunctionsList = React.forwardRef<
onDeleteEventsBasedObject,
onRenameEventsBasedObject,
onEventsBasedObjectRenamed,
onEventsBasedObjectPasted,
onAddEventsBasedObject,
addNewEventsFunction,
selectedEventsBasedBehavior,
@@ -1021,6 +1023,7 @@ const EventsFunctionsList = React.forwardRef<
onDeleteEventsBasedObject,
onRenameEventsBasedObject,
onEventsBasedObjectRenamed,
onEventsBasedObjectPasted,
onAddEventsBasedObject,
addNewEventsFunction,
selectedEventsBasedBehavior,

View File

@@ -33,6 +33,7 @@ export const Default = () => (
onDeleteEventsBasedObject={action('object deleted')}
onRenameEventsBasedObject={action('rename object')}
onEventsBasedObjectRenamed={action('object renamed')}
onEventsBasedObjectPasted={action('object pasted')}
onOpenCustomObjectEditor={action('onOpenCustomObjectEditor')}
onAddEventsBasedObject={cb => cb({ isRenderedIn3D: false })}
// Behaviors