Skip to content

Commit dd40a99

Browse files
authored
Add support for setting a custom help URL for extension actions/conditions/expressions (#8103)
Only show in developer changelog
1 parent 12b7ed5 commit dd40a99

File tree

15 files changed

+474
-21
lines changed

15 files changed

+474
-21
lines changed

Core/GDCore/Project/EventsFunction.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ void EventsFunction::SerializeTo(SerializerElement& element) const {
7575
if (isAsync) {
7676
element.SetBoolAttribute("async", isAsync);
7777
}
78+
if (!helpUrl.empty()) {
79+
element.SetAttribute("helpUrl", helpUrl);
80+
}
7881
events.SerializeTo(element.AddChild("events"));
7982

8083
gd::String functionTypeStr = "Action";
@@ -116,6 +119,7 @@ void EventsFunction::UnserializeFrom(gd::Project& project,
116119
getterName = element.GetStringAttribute("getterName");
117120
isPrivate = element.GetBoolAttribute("private");
118121
isAsync = element.GetBoolAttribute("async");
122+
helpUrl = element.GetStringAttribute("helpUrl");
119123
events.UnserializeFrom(project, element.GetChild("events"));
120124

121125
gd::String functionTypeStr = element.GetStringAttribute("functionType");

Core/GDCore/Project/EventsFunction.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,19 @@ class GD_CORE_API EventsFunction {
223223
return *this;
224224
}
225225

226+
/**
227+
* \brief Get the help URL for this function.
228+
*/
229+
const gd::String& GetHelpUrl() const { return helpUrl; }
230+
231+
/**
232+
* \brief Set the help URL for this function.
233+
*/
234+
EventsFunction& SetHelpUrl(const gd::String& helpUrl_) {
235+
helpUrl = helpUrl_;
236+
return *this;
237+
}
238+
226239
/**
227240
* \brief Return the events.
228241
*/
@@ -304,6 +317,7 @@ class GD_CORE_API EventsFunction {
304317
gd::ObjectGroupsContainer objectGroups;
305318
bool isPrivate = false;
306319
bool isAsync = false;
320+
gd::String helpUrl;
307321
};
308322

309323
} // namespace gd

Core/tests/EventsFunction.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* GDevelop Core
3+
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
4+
* reserved. This project is released under the MIT License.
5+
*/
6+
/**
7+
* @file Tests covering EventsFunction
8+
*/
9+
#include "GDCore/Project/EventsFunction.h"
10+
#include "GDCore/Project/Project.h"
11+
#include "GDCore/Serialization/SerializerElement.h"
12+
#include "catch.hpp"
13+
14+
TEST_CASE("EventsFunction", "[common]") {
15+
SECTION("Basic properties") {
16+
gd::EventsFunction eventsFunction;
17+
18+
eventsFunction.SetName("MyFunction");
19+
eventsFunction.SetFullName("My Function");
20+
eventsFunction.SetDescription("A test function");
21+
eventsFunction.SetGroup("Test Group");
22+
eventsFunction.SetSentence("Do something with _PARAM1_");
23+
24+
REQUIRE(eventsFunction.GetName() == "MyFunction");
25+
REQUIRE(eventsFunction.GetFullName() == "My Function");
26+
REQUIRE(eventsFunction.GetDescription() == "A test function");
27+
REQUIRE(eventsFunction.GetGroup() == "Test Group");
28+
REQUIRE(eventsFunction.GetSentence() == "Do something with _PARAM1_");
29+
}
30+
31+
SECTION("Help URL") {
32+
gd::EventsFunction eventsFunction;
33+
34+
// Default should be empty
35+
REQUIRE(eventsFunction.GetHelpUrl() == "");
36+
37+
// Can set a help URL
38+
eventsFunction.SetHelpUrl("https://example.com/help");
39+
REQUIRE(eventsFunction.GetHelpUrl() == "https://example.com/help");
40+
41+
// Can clear the help URL
42+
eventsFunction.SetHelpUrl("");
43+
REQUIRE(eventsFunction.GetHelpUrl() == "");
44+
}
45+
46+
SECTION("Serialization with help URL") {
47+
gd::Project project;
48+
49+
gd::EventsFunction eventsFunction;
50+
eventsFunction.SetName("MyFunction");
51+
eventsFunction.SetFullName("My Function");
52+
eventsFunction.SetDescription("A test function");
53+
eventsFunction.SetHelpUrl("https://example.com/custom-help");
54+
55+
gd::SerializerElement element;
56+
eventsFunction.SerializeTo(element);
57+
58+
gd::EventsFunction eventsFunction2;
59+
eventsFunction2.UnserializeFrom(project, element);
60+
61+
REQUIRE(eventsFunction2.GetName() == "MyFunction");
62+
REQUIRE(eventsFunction2.GetFullName() == "My Function");
63+
REQUIRE(eventsFunction2.GetDescription() == "A test function");
64+
REQUIRE(eventsFunction2.GetHelpUrl() == "https://example.com/custom-help");
65+
}
66+
67+
SECTION("Serialization without help URL") {
68+
gd::Project project;
69+
70+
gd::EventsFunction eventsFunction;
71+
eventsFunction.SetName("MyFunction");
72+
eventsFunction.SetFullName("My Function");
73+
eventsFunction.SetDescription("A test function");
74+
// No help URL set
75+
76+
gd::SerializerElement element;
77+
eventsFunction.SerializeTo(element);
78+
79+
gd::EventsFunction eventsFunction2;
80+
eventsFunction2.UnserializeFrom(project, element);
81+
82+
REQUIRE(eventsFunction2.GetName() == "MyFunction");
83+
REQUIRE(eventsFunction2.GetFullName() == "My Function");
84+
REQUIRE(eventsFunction2.GetDescription() == "A test function");
85+
REQUIRE(eventsFunction2.GetHelpUrl() == "");
86+
}
87+
}
88+

GDJS/GDJS/Events/CodeGeneration/MetadataDeclarationHelper.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,9 @@ MetadataDeclarationHelper::DeclareExpressionMetadata(
535535
expressionAndCondition.AddCodeOnlyParameter("currentScene", "");
536536
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
537537
expressionAndCondition, 0);
538+
if (!eventsFunction.GetHelpUrl().empty()) {
539+
expressionAndCondition.SetHelpPath(eventsFunction.GetHelpUrl());
540+
}
538541
expressionAndConditions.push_back(expressionAndCondition);
539542
return expressionAndConditions.back();
540543
} else {
@@ -556,6 +559,9 @@ MetadataDeclarationHelper::DeclareExpressionMetadata(
556559
expression.AddCodeOnlyParameter("currentScene", "");
557560
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
558561
expression, 0);
562+
if (!eventsFunction.GetHelpUrl().empty()) {
563+
expression.SetHelpPath(eventsFunction.GetHelpUrl());
564+
}
559565
return expression;
560566
}
561567
}
@@ -581,6 +587,9 @@ gd::InstructionMetadata &MetadataDeclarationHelper::DeclareInstructionMetadata(
581587
condition.AddCodeOnlyParameter("currentScene", "");
582588
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
583589
condition, 0);
590+
if (!eventsFunction.GetHelpUrl().empty()) {
591+
condition.SetHelpPath(eventsFunction.GetHelpUrl());
592+
}
584593
return condition;
585594
} else if (functionType == gd::EventsFunction::ActionWithOperator) {
586595
if (freeEventsFunctions.HasEventsFunctionNamed(
@@ -607,6 +616,9 @@ gd::InstructionMetadata &MetadataDeclarationHelper::DeclareInstructionMetadata(
607616
action.AddCodeOnlyParameter("currentScene", "");
608617
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
609618
action, 0);
619+
if (!eventsFunction.GetHelpUrl().empty()) {
620+
action.SetHelpPath(eventsFunction.GetHelpUrl());
621+
}
610622
return action;
611623
} else {
612624

@@ -621,6 +633,9 @@ gd::InstructionMetadata &MetadataDeclarationHelper::DeclareInstructionMetadata(
621633
action.AddCodeOnlyParameter("currentScene", "");
622634
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
623635
action, 0);
636+
if (!eventsFunction.GetHelpUrl().empty()) {
637+
action.SetHelpPath(eventsFunction.GetHelpUrl());
638+
}
624639
return action;
625640
}
626641
} else {
@@ -634,6 +649,9 @@ gd::InstructionMetadata &MetadataDeclarationHelper::DeclareInstructionMetadata(
634649
action.AddCodeOnlyParameter("currentScene", "");
635650
DeclareEventsFunctionParameters(freeEventsFunctions, eventsFunction,
636651
action, 0);
652+
if (!eventsFunction.GetHelpUrl().empty()) {
653+
action.SetHelpPath(eventsFunction.GetHelpUrl());
654+
}
637655
return action;
638656
}
639657
}
@@ -726,6 +744,9 @@ MetadataDeclarationHelper::DeclareBehaviorExpressionMetadata(
726744
GetExtensionIconUrl(extension));
727745
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
728746
eventsFunction, expressionAndCondition, 2);
747+
if (!eventsFunction.GetHelpUrl().empty()) {
748+
expressionAndCondition.SetHelpPath(eventsFunction.GetHelpUrl());
749+
}
729750
expressionAndConditions.push_back(expressionAndCondition);
730751
return expressionAndConditions.back();
731752
} else {
@@ -751,6 +772,9 @@ MetadataDeclarationHelper::DeclareBehaviorExpressionMetadata(
751772
GetExtensionIconUrl(extension));
752773
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
753774
eventsFunction, expression, 2);
775+
if (!eventsFunction.GetHelpUrl().empty()) {
776+
expression.SetHelpPath(eventsFunction.GetHelpUrl());
777+
}
754778
return expression;
755779
}
756780
}
@@ -779,6 +803,9 @@ MetadataDeclarationHelper::DeclareBehaviorInstructionMetadata(
779803
GetExtensionIconUrl(extension), GetExtensionIconUrl(extension));
780804
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
781805
eventsFunction, condition, 2);
806+
if (!eventsFunction.GetHelpUrl().empty()) {
807+
condition.SetHelpPath(eventsFunction.GetHelpUrl());
808+
}
782809
return condition;
783810
} else if (functionType == gd::EventsFunction::ActionWithOperator) {
784811
auto &eventsFunctionsContainer = eventsBasedBehavior.GetEventsFunctions();
@@ -804,6 +831,9 @@ MetadataDeclarationHelper::DeclareBehaviorInstructionMetadata(
804831

805832
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
806833
eventsFunction, action, 2);
834+
if (!eventsFunction.GetHelpUrl().empty()) {
835+
action.SetHelpPath(eventsFunction.GetHelpUrl());
836+
}
807837
return action;
808838
} else {
809839
auto &action = behaviorMetadata.AddScopedAction(
@@ -817,6 +847,9 @@ MetadataDeclarationHelper::DeclareBehaviorInstructionMetadata(
817847

818848
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
819849
eventsFunction, action, 2);
850+
if (!eventsFunction.GetHelpUrl().empty()) {
851+
action.SetHelpPath(eventsFunction.GetHelpUrl());
852+
}
820853
return action;
821854
}
822855
} else {
@@ -834,6 +867,9 @@ MetadataDeclarationHelper::DeclareBehaviorInstructionMetadata(
834867

835868
DeclareEventsFunctionParameters(eventsBasedBehavior.GetEventsFunctions(),
836869
eventsFunction, action, 2);
870+
if (!eventsFunction.GetHelpUrl().empty()) {
871+
action.SetHelpPath(eventsFunction.GetHelpUrl());
872+
}
837873
return action;
838874
}
839875
}
@@ -900,6 +936,9 @@ MetadataDeclarationHelper::DeclareObjectExpressionMetadata(
900936

901937
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
902938
eventsFunction, expressionAndCondition, 1);
939+
if (!eventsFunction.GetHelpUrl().empty()) {
940+
expressionAndCondition.SetHelpPath(eventsFunction.GetHelpUrl());
941+
}
903942
expressionAndConditions.push_back(expressionAndCondition);
904943
return expressionAndConditions.back();
905944
} else {
@@ -926,6 +965,9 @@ MetadataDeclarationHelper::DeclareObjectExpressionMetadata(
926965

927966
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
928967
eventsFunction, expression, 1);
968+
if (!eventsFunction.GetHelpUrl().empty()) {
969+
expression.SetHelpPath(eventsFunction.GetHelpUrl());
970+
}
929971
return expression;
930972
}
931973
}
@@ -955,6 +997,9 @@ MetadataDeclarationHelper::DeclareObjectInstructionMetadata(
955997

956998
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
957999
eventsFunction, condition, 1);
1000+
if (!eventsFunction.GetHelpUrl().empty()) {
1001+
condition.SetHelpPath(eventsFunction.GetHelpUrl());
1002+
}
9581003
return condition;
9591004
} else if (functionType == gd::EventsFunction::ActionWithOperator) {
9601005
auto &eventsFunctionsContainer = eventsBasedObject.GetEventsFunctions();
@@ -979,6 +1024,9 @@ MetadataDeclarationHelper::DeclareObjectInstructionMetadata(
9791024

9801025
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
9811026
eventsFunction, action, 1);
1027+
if (!eventsFunction.GetHelpUrl().empty()) {
1028+
action.SetHelpPath(eventsFunction.GetHelpUrl());
1029+
}
9821030
return action;
9831031
} else {
9841032
auto &action = objectMetadata.AddScopedAction(
@@ -991,6 +1039,9 @@ MetadataDeclarationHelper::DeclareObjectInstructionMetadata(
9911039

9921040
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
9931041
eventsFunction, action, 1);
1042+
if (!eventsFunction.GetHelpUrl().empty()) {
1043+
action.SetHelpPath(eventsFunction.GetHelpUrl());
1044+
}
9941045
return action;
9951046
}
9961047
} else {
@@ -1008,6 +1059,9 @@ MetadataDeclarationHelper::DeclareObjectInstructionMetadata(
10081059

10091060
DeclareEventsFunctionParameters(eventsBasedObject.GetEventsFunctions(),
10101061
eventsFunction, action, 1);
1062+
if (!eventsFunction.GetHelpUrl().empty()) {
1063+
action.SetHelpPath(eventsFunction.GetHelpUrl());
1064+
}
10111065
return action;
10121066
}
10131067
}

GDevelop.js/Bindings/Bindings.idl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3206,6 +3206,8 @@ interface EventsFunction {
32063206
boolean IsPrivate();
32073207
[Ref] EventsFunction SetAsync(boolean isAsync);
32083208
boolean IsAsync();
3209+
[Ref] EventsFunction SetHelpUrl([Const] DOMString helpUrl);
3210+
[Const, Ref] DOMString GetHelpUrl();
32093211
boolean IsAction();
32103212
boolean IsExpression();
32113213
boolean IsCondition();

GDevelop.js/__tests__/Core.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,6 +4579,15 @@ describe('libGD.js', function () {
45794579
expect(eventsFunction.getDescription()).toBe('My description');
45804580
eventsFunction.delete();
45814581
});
4582+
it('can have a help URL', function () {
4583+
const eventsFunction = new gd.EventsFunction();
4584+
expect(eventsFunction.getHelpUrl()).toBe('');
4585+
eventsFunction.setHelpUrl('https://example.com/help');
4586+
expect(eventsFunction.getHelpUrl()).toBe('https://example.com/help');
4587+
eventsFunction.setHelpUrl('');
4588+
expect(eventsFunction.getHelpUrl()).toBe('');
4589+
eventsFunction.delete();
4590+
});
45824591
});
45834592

45844593
describe('gd.EventsFunctionsExtension', () => {

0 commit comments

Comments
 (0)