Skip to content

Commit

Permalink
Fix event refactoring of behaviors copied to the same extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
D8H committed Oct 2, 2024
1 parent d0a7fbb commit 85617ce
Show file tree
Hide file tree
Showing 9 changed files with 130 additions and 28 deletions.
45 changes: 34 additions & 11 deletions Core/GDCore/IDE/WholeProjectRefactorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,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,
Expand All @@ -1324,10 +1337,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
Expand All @@ -1341,12 +1366,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(
Expand All @@ -1357,7 +1382,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,
Expand All @@ -1367,15 +1392,15 @@ 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
};

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(
Expand All @@ -1386,7 +1411,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(
Expand All @@ -1399,8 +1424,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
Expand Down Expand Up @@ -1435,13 +1459,12 @@ 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::RenameEventsBasedObject(
Expand Down
26 changes: 25 additions & 1 deletion Core/GDCore/IDE/WholeProjectRefactorer.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ 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 was placed in a new
* extension.
*/
static void UpdateExtensionNameInEventsBasedBehavior(
Expand Down Expand Up @@ -324,6 +324,15 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& oldBehaviorName,
const gd::String& newBehaviorName);

/**
* \brief Refactor behavior events after the behavior was 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.
*
Expand Down Expand Up @@ -654,6 +663,21 @@ 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);

static void FindDependentBehaviorNames(
const gd::Project& project,
const gd::Object& object,
Expand Down
37 changes: 37 additions & 0 deletions Core/tests/WholeProjectRefactorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2030,6 +2030,43 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
}
}

SECTION("Events-based behavior renamed in instructions scoped to one behavior") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);

// A behavior is copied to the same extension.
auto &copiedBehavior =
eventsExtension.GetEventsBasedBehaviors().InsertNew(
"MyDuplicatedEventsBasedBehavior", 0);
copiedBehavior.SetFullName("My events based behavior");
copiedBehavior.SetDescription("An events based behavior for test");
copiedBehavior.SetObjectType("MyEventsExtension::MyEventsBasedObject");

// Add the copied events.
auto &behaviorEventsFunctions = copiedBehavior.GetEventsFunctions();
auto &behaviorAction = behaviorEventsFunctions.InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
SetupEvents(behaviorAction.GetEvents());

gd::WholeProjectRefactorer::UpdateBehaviorNameInEventsBasedBehavior(
project, eventsExtension, copiedBehavior, "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 copied behavior.
REQUIRE(
GetEventFirstActionType(eventsList->GetEvent(BehaviorAction)) ==
"MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunction");
}
}

SECTION("Events extension renamed in parameters") {
gd::Project project;
gd::Platform platform;
Expand Down
5 changes: 5 additions & 0 deletions GDevelop.js/Bindings/Bindings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2511,6 +2511,11 @@ 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,
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/Bindings/Wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
RenameEventsBasedBehaviorSharedProperty
#define STATIC_RenameEventsBasedObjectProperty RenameEventsBasedObjectProperty
#define STATIC_RenameEventsBasedBehavior RenameEventsBasedBehavior
#define STATIC_UpdateBehaviorNameInEventsBasedBehavior UpdateBehaviorNameInEventsBasedBehavior
#define STATIC_RenameEventsBasedObject RenameEventsBasedObject
#define STATIC_RenameLayout RenameLayout
#define STATIC_RenameExternalLayout RenameExternalLayout
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,7 @@ 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 renameLayout(project: Project, oldName: string, newName: string): void;
static renameExternalLayout(project: Project, oldName: string, newName: string): void;
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/types/gdwholeprojectrefactorer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 17 additions & 9 deletions newIDE/app/src/EventsFunctionsExtensionEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -694,18 +694,26 @@ 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
);
}
gd.WholeProjectRefactorer.updateExtensionNameInEventsBasedBehavior(
project,
eventsFunctionsExtension,
eventsBasedBehavior,
sourceExtensionName
);
};

_onEventsBasedBehaviorRenamed = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export type EventsBasedBehaviorCallbacks = {|
) => void,
onEventsBasedBehaviorPasted: (
eventsBasedBehavior: gdEventsBasedBehavior,
sourceExtensionName: string
sourceExtensionName: string,
sourceEventsBasedBehaviorName: string
) => void,
|};

Expand Down Expand Up @@ -284,16 +285,16 @@ 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)
);

Expand All @@ -304,7 +305,7 @@ export class EventsBasedBehaviorTreeViewItemContent

unserializeFromJSObject(
newEventsBasedBehavior,
copiedEventsBasedBehavior,
sourceEventsBasedBehavior,
'unserializeFrom',
project
);
Expand All @@ -317,7 +318,8 @@ export class EventsBasedBehaviorTreeViewItemContent
if (sourceExtensionName) {
this.props.onEventsBasedBehaviorPasted(
newEventsBasedBehavior,
sourceExtensionName
sourceExtensionName,
sourceEventsBasedBehaviorName
);
}

Expand Down

0 comments on commit 85617ce

Please sign in to comment.