Compare commits
187 Commits
v5.0.0-bet
...
v5.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
![]() |
98d0d5102e | ||
![]() |
47818846e7 | ||
![]() |
8276eda243 | ||
![]() |
ca2e00bd91 | ||
![]() |
6177b0197e | ||
![]() |
fb65b56cb7 | ||
![]() |
6f780f79e9 | ||
![]() |
d31f0793d5 | ||
![]() |
88c88ad1eb | ||
![]() |
4202e2672d | ||
![]() |
f29cc503bf | ||
![]() |
1aa81949ce | ||
![]() |
4593f09131 | ||
![]() |
782ea0e0af | ||
![]() |
8e893e660b | ||
![]() |
384346c54e | ||
![]() |
df3920cce3 | ||
![]() |
6e9ff4b682 | ||
![]() |
df161c48fd | ||
![]() |
ee6a337e71 | ||
![]() |
d5146a0c65 | ||
![]() |
eae4683c4f | ||
![]() |
dec96a2f3a | ||
![]() |
9610eeb6e5 | ||
![]() |
213cd0a8c7 | ||
![]() |
8a117c1813 | ||
![]() |
73ff10bb1f | ||
![]() |
300efbbd5c | ||
![]() |
2e240643a2 | ||
![]() |
aa16e90aac | ||
![]() |
137ffc2b84 | ||
![]() |
34b460e968 | ||
![]() |
30cb0bcfb3 | ||
![]() |
1b7a667c79 | ||
![]() |
9a4655eefc | ||
![]() |
ca9a0d3d37 | ||
![]() |
10d8d6c4a8 | ||
![]() |
a7f4da8e40 | ||
![]() |
40b3c688d1 | ||
![]() |
fc340b9477 | ||
![]() |
cc810b3e9f | ||
![]() |
7d165660a5 | ||
![]() |
8d35bbbfdf | ||
![]() |
8ebff3c15e | ||
![]() |
a00fff9376 | ||
![]() |
32f56f3366 | ||
![]() |
09eab9eb46 | ||
![]() |
9fe379d073 | ||
![]() |
f21fbd9871 | ||
![]() |
f38dfd1211 | ||
![]() |
eefc656d49 | ||
![]() |
1490b34650 | ||
![]() |
ff496c65a5 | ||
![]() |
e9a3e801f7 | ||
![]() |
4f8401ab1a | ||
![]() |
871b01124f | ||
![]() |
45d2844d8b | ||
![]() |
566517320d | ||
![]() |
15773bca85 | ||
![]() |
a48d7017ea | ||
![]() |
7d1f52ded4 | ||
![]() |
569adc1500 | ||
![]() |
e6eb193e8e | ||
![]() |
b8c63dade1 | ||
![]() |
82f92d36f1 | ||
![]() |
6b17c1febd | ||
![]() |
95882d1289 | ||
![]() |
70340bba7f | ||
![]() |
c809be9a07 | ||
![]() |
cc7b0f524e | ||
![]() |
a61784bb6c | ||
![]() |
3f92fc2ee5 | ||
![]() |
a4c08305c7 | ||
![]() |
067798ff2c | ||
![]() |
7a838fc8f9 | ||
![]() |
e669190ca2 | ||
![]() |
b84bb8630a | ||
![]() |
fb849be246 | ||
![]() |
382aa0f086 | ||
![]() |
303873974c | ||
![]() |
9f0ec46064 | ||
![]() |
9b2fa5d080 | ||
![]() |
93611d8642 | ||
![]() |
a0f15817ca | ||
![]() |
6323aefb6b | ||
![]() |
6bdc0f3961 | ||
![]() |
905a459ea2 | ||
![]() |
eb67604ca6 | ||
![]() |
63077c7cef | ||
![]() |
2fed5b9a8b | ||
![]() |
88b4b3860b | ||
![]() |
e295efac7f | ||
![]() |
c5554d05fd | ||
![]() |
6a163a59ca | ||
![]() |
9f5b63bad9 | ||
![]() |
35aa78ea35 | ||
![]() |
82442fe618 | ||
![]() |
9dabcbd1f1 | ||
![]() |
7f0fce5f6d | ||
![]() |
90baf3cdb5 | ||
![]() |
cccbb0e61b | ||
![]() |
702f1b529f | ||
![]() |
fcc9740a77 | ||
![]() |
094bdb60f6 | ||
![]() |
215044cafe | ||
![]() |
4d0185de9d | ||
![]() |
557f1da2c1 | ||
![]() |
becddeab9f | ||
![]() |
ec6628baba | ||
![]() |
3289285a37 | ||
![]() |
c4047702ed | ||
![]() |
3c21e33928 | ||
![]() |
25f5550666 | ||
![]() |
2b7caf5fac | ||
![]() |
29f7525290 | ||
![]() |
80aa1ebec8 | ||
![]() |
af7f13c0b8 | ||
![]() |
4e71030103 | ||
![]() |
b3b7f181fa | ||
![]() |
4138f5f4aa | ||
![]() |
f302989b9d | ||
![]() |
0f7c2c43cf | ||
![]() |
04b37bebf7 | ||
![]() |
a12d999e7b | ||
![]() |
cad23ed67c | ||
![]() |
f059728fdb | ||
![]() |
545676b1f2 | ||
![]() |
48d99457e5 | ||
![]() |
c2c961f1d4 | ||
![]() |
04131e1795 | ||
![]() |
53a5dc1742 | ||
![]() |
a790be3c37 | ||
![]() |
6772fecc2e | ||
![]() |
3244cbd8ad | ||
![]() |
066f2b0fea | ||
![]() |
f370b8b78b | ||
![]() |
e24daa4dc3 | ||
![]() |
f889c9fc0a | ||
![]() |
cdc374df9c | ||
![]() |
d60efd2394 | ||
![]() |
d448ffb8f2 | ||
![]() |
eb31be67ed | ||
![]() |
23b4e2c026 | ||
![]() |
1381ead3b4 | ||
![]() |
5377708093 | ||
![]() |
e7afebf722 | ||
![]() |
7915d3ba59 | ||
![]() |
c11cc80488 | ||
![]() |
a33b421de4 | ||
![]() |
852d91b745 | ||
![]() |
df78d5e096 | ||
![]() |
7718132510 | ||
![]() |
af00760d3e | ||
![]() |
c88c05f737 | ||
![]() |
e3b446cee0 | ||
![]() |
721c31adc9 | ||
![]() |
e5c4580483 | ||
![]() |
4c0d46ae2c | ||
![]() |
d05f2b9674 | ||
![]() |
566540133d | ||
![]() |
45533cf163 | ||
![]() |
ad83d7d08f | ||
![]() |
d755e10368 | ||
![]() |
6543544dc1 | ||
![]() |
6cd9e4b4d9 | ||
![]() |
b5b90cc838 | ||
![]() |
c4be6f6522 | ||
![]() |
fd3698f590 | ||
![]() |
0fdbe19641 | ||
![]() |
48e1d04fb6 | ||
![]() |
677478b4a2 | ||
![]() |
fc3826d472 | ||
![]() |
d135447e00 | ||
![]() |
856d7cdb46 | ||
![]() |
c2151149d4 | ||
![]() |
9de604bd50 | ||
![]() |
a4899cf030 | ||
![]() |
483090dd32 | ||
![]() |
0e4304f3d7 | ||
![]() |
9050bfbc6f | ||
![]() |
32869c0588 | ||
![]() |
f7f08f762d | ||
![]() |
b19ffb93e0 | ||
![]() |
63a06a4bad | ||
![]() |
12efa6641c | ||
![]() |
edfe915ae5 | ||
![]() |
2e1509a16b |
4
.github/ISSUE_TEMPLATE/--feature-request.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: "\U0001F4A1Feature request"
|
||||
about: Suggest an idea for this project AFTER discussing about it on the Discord or
|
||||
Forum first.
|
||||
Forum first. We'll create a card for it on the roadmap.
|
||||
|
||||
---
|
||||
|
||||
@@ -10,6 +10,8 @@ BEFORE opening a new feature request, please make sure that you:
|
||||
* There is not already a suggestion about it in the issues or in the roadmap: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
|
||||
* Consider commenting on the roadmap if something is important for you
|
||||
|
||||
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in the roadmap if it's relevant and does not exist yet :)
|
||||
|
||||
## Description
|
||||
Is your feature request **related to a problem**? Please describe.
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
BIN
Binaries/Output/Release_Windows/res/actions/wordWrap.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Binaries/Output/Release_Windows/res/actions/wordWrap24.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
Binaries/Output/Release_Windows/res/conditions/wordWrap.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Binaries/Output/Release_Windows/res/conditions/wordWrap24.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 951 B |
BIN
Binaries/Output/Release_Windows/res/function16.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
Binaries/Output/Release_Windows/res/function32.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
@@ -370,8 +370,8 @@
|
||||
<Unit filename="GDCore/IDE/Events/ExpressionsCorrectnessTesting.h" />
|
||||
<Unit filename="GDCore/IDE/ExtensionsLoader.cpp" />
|
||||
<Unit filename="GDCore/IDE/ExtensionsLoader.h" />
|
||||
<Unit filename="GDCore/IDE/Project/ImagesUsedInventorizer.cpp" />
|
||||
<Unit filename="GDCore/IDE/Project/ImagesUsedInventorizer.h" />
|
||||
<Unit filename="GDCore/IDE/Project/ResourcesInUseHelper.cpp" />
|
||||
<Unit filename="GDCore/IDE/Project/ResourcesInUseHelper.h" />
|
||||
<Unit filename="GDCore/Extensions/Metadata/MetadataProvider.cpp" />
|
||||
<Unit filename="GDCore/Extensions/Metadata/MetadataProvider.h" />
|
||||
<Unit filename="GDCore/IDE/PlatformLoader.cpp" />
|
||||
|
@@ -643,6 +643,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
} else if (metadata.type == "trueorfalse") {
|
||||
// This is duplicated in AdvancedExtension.cpp for GDJS
|
||||
argOutput += (parameter == "True" || parameter == "Vrai") ? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
}
|
||||
|
@@ -15,38 +15,18 @@
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
}
|
||||
namespace gd {
|
||||
class MainFrameWrapper;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class EventsCodeGenerator;
|
||||
}
|
||||
namespace gd {
|
||||
class EventsCodeGenerationContext;
|
||||
}
|
||||
namespace gd {
|
||||
class Platform;
|
||||
}
|
||||
class wxWindow;
|
||||
namespace gd {
|
||||
class EventsEditorItemsAreas;
|
||||
}
|
||||
namespace gd {
|
||||
class EventsEditorSelection;
|
||||
}
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
}
|
||||
class wxWindow;
|
||||
class wxDC;
|
||||
|
||||
namespace gd {
|
||||
|
@@ -450,9 +450,7 @@ bool ExpressionParser::ParseMathExpression(const gd::Platform& platform,
|
||||
parameters[i],
|
||||
instructionInfos.parameters[i],
|
||||
functionNameEnd))
|
||||
return false; // TODO : Boarf, param<61>tres optionels sont rajout<75>s
|
||||
// et <20>valu<6C>s : Probl<62>me avec les calques par
|
||||
// exemple ( Au minimum, il faut "" )
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
firstErrorPos = functionNameEnd;
|
||||
|
@@ -32,6 +32,62 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/conditions/toujours.png")
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetReturnNumber",
|
||||
_("Set number return value"),
|
||||
_("Set the return value of the events function to the specified "
|
||||
"number (to be used with \"Expression\" functions)."),
|
||||
_("Set return value to number _PARAM0_"),
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("expression", "The number to be returned")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetReturnString",
|
||||
_("Set text return value"),
|
||||
_("Set the return value of the events function to the specified text "
|
||||
"(to be used with \"String Expression\" functions)."),
|
||||
_("Set return value to text _PARAM0_"),
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("expression", "The text to be returned")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("SetReturnBoolean",
|
||||
_("Set condition return value"),
|
||||
_("Set the return value of the Condition events function to "
|
||||
"either true (condition will pass) or false."),
|
||||
_("Set return value of the condition to _PARAM0_"),
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("trueorfalse", "Should the condition be true or false?")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"GetArgumentAsNumber",
|
||||
_("Get function parameter value"),
|
||||
_("Get function parameter (also called \"argument\") value"),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name");
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
"GetArgumentAsString",
|
||||
_("Get function parameter text"),
|
||||
_("Get function parameter (also called \"argument\") text "),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -257,7 +257,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
.AddAction("PlaySound",
|
||||
_("Play a sound"),
|
||||
_("Play a sound."),
|
||||
_("Play the sound _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_)"),
|
||||
_("Play the sound _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
|
||||
_("Audio"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
@@ -276,7 +276,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
.AddAction("PlayMusic",
|
||||
_("Play a music file"),
|
||||
_("Play a music file."),
|
||||
_("Play the music _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_)"),
|
||||
_("Play the music _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
|
||||
_("Audio"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
|
@@ -180,7 +180,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Add a force"),
|
||||
_("Add a force to an object. The object will move according to "
|
||||
"all of the forces it has."),
|
||||
_("Add to _PARAM0_ a force of _PARAM1_ p/s on X axis and "
|
||||
_("Add to _PARAM0_ _PARAM3_ force of _PARAM1_ p/s on X axis and "
|
||||
"_PARAM2_ p/s on Y axis"),
|
||||
_("Movement"),
|
||||
"res/actions/force24.png",
|
||||
@@ -189,14 +189,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Speed on X axis (in pixels per second)"))
|
||||
.AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"));
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"));
|
||||
|
||||
obj.AddAction("AddForceAL",
|
||||
_("Add a force (angle)"),
|
||||
_("Add a force to an object. The object will move according to "
|
||||
"all of the forces it has. This action creates the force "
|
||||
"using the specified angle and length."),
|
||||
_("Add to _PARAM0_ a force, angle: _PARAM1_ degrees and "
|
||||
_("Add to _PARAM0_ _PARAM3_ force, angle: _PARAM1_ degrees and "
|
||||
"length: _PARAM2_ pixels"),
|
||||
_("Movement"),
|
||||
"res/actions/force24.png",
|
||||
@@ -205,14 +205,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Angle"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
"AddForceVersPos",
|
||||
_("Add a force to move toward a position"),
|
||||
_("Add a force to an object to make it move toward a position."),
|
||||
_("Move _PARAM0_ to _PARAM1_;_PARAM2_ with a force of _PARAM3_ "
|
||||
_("Move _PARAM0_ to _PARAM1_;_PARAM2_ with _PARAM4_ force of _PARAM3_ "
|
||||
"pixels"),
|
||||
_("Movement"),
|
||||
"res/actions/force24.png",
|
||||
@@ -222,7 +222,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -243,13 +243,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("Y position of the center"))
|
||||
.AddParameter("expression", _("Speed (in Degrees per seconds)"))
|
||||
.AddParameter("expression", _("Distance (in pixels)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.SetHidden();
|
||||
|
||||
obj.AddAction("Arreter",
|
||||
_("Stop the object"),
|
||||
_("Stop the object by deleting all of its forces."),
|
||||
_("Stop the object _PARAM0_"),
|
||||
_("Stop object _PARAM0_"),
|
||||
_("Movement"),
|
||||
"res/actions/arreter24.png",
|
||||
"res/actions/arreter.png")
|
||||
@@ -272,7 +272,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddAction("ChangePlan",
|
||||
_("Z order"),
|
||||
_("Modify the Z-order of an object"),
|
||||
_("Do _PARAM1__PARAM2_ to z-Order of _PARAM0_"),
|
||||
_("Do _PARAM1__PARAM2_ to Z-order of _PARAM0_"),
|
||||
_("Z order"),
|
||||
"res/actions/planicon24.png",
|
||||
"res/actions/planicon.png")
|
||||
@@ -554,7 +554,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddAction("AddForceVers",
|
||||
_("Add a force to move toward an object"),
|
||||
_("Add a force to an object to make it move toward another."),
|
||||
_("Move _PARAM0_ to _PARAM1_ with a force of _PARAM2_ pixels"),
|
||||
_("Move _PARAM0_ to _PARAM1_ with _PARAM3_ force of _PARAM2_ pixels"),
|
||||
_("Movement"),
|
||||
"res/actions/forceVers24.png",
|
||||
"res/actions/forceVers.png")
|
||||
@@ -562,7 +562,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Target Object"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -582,7 +582,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectPtr", _("Rotate around this object"))
|
||||
.AddParameter("expression", _("Speed (in degrees per second)"))
|
||||
.AddParameter("expression", _("Distance (in pixels)"))
|
||||
.AddParameter("expression", _("Damping (Default: 0)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction("MettreAutour",
|
||||
@@ -878,7 +878,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectListWithoutPicking", _("Object to create"))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
@@ -896,7 +896,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter(
|
||||
"objectListWithoutPicking",
|
||||
_("Groups containing objects that can be created by the action"))
|
||||
@@ -916,7 +916,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/add24.png",
|
||||
"res/actions/add.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
|
@@ -174,6 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
"res/actions/launchFile24.png",
|
||||
"res/actions/launchFile.png")
|
||||
.AddParameter("string", _("URL (or filename)"))
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
|
@@ -18,7 +18,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("Built-in extension that enables the use of a mouse"),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/events/mouse-touch");
|
||||
.SetExtensionHelpPath("/all-features/mouse-touch");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
|
@@ -89,7 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
.AddAction("Scene",
|
||||
_("Change the scene"),
|
||||
_("Stop this scene and start the specified one instead."),
|
||||
_("Change for scene _PARAM1_"),
|
||||
_("Change to scene _PARAM1_"),
|
||||
_("Scene"),
|
||||
"res/actions/replaceScene24.png",
|
||||
"res/actions/replaceScene.png")
|
||||
|
@@ -15,7 +15,7 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
Direction::Direction() : loop(false), timeBetweenFrame(1) {}
|
||||
Direction::Direction() : loop(false), timeBetweenFrame(0.08) {}
|
||||
|
||||
Direction::~Direction(){};
|
||||
|
||||
@@ -75,6 +75,11 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
SetTimeBetweenFrames(
|
||||
element.GetDoubleAttribute("timeBetweenFrames", 1, "tempsEntre"));
|
||||
SetLoop(element.GetBoolAttribute("looping", false, "boucle"));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetMetadata(element.HasAttribute("metadata") || element.HasChild("metadata")
|
||||
? element.GetStringAttribute("metadata")
|
||||
: "");
|
||||
#endif
|
||||
|
||||
const gd::SerializerElement& spritesElement =
|
||||
element.GetChild("sprites", 0, "Sprites");
|
||||
@@ -182,6 +187,7 @@ void SaveSpritesDirection(const vector<Sprite>& sprites,
|
||||
void Direction::SerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("looping", IsLooping());
|
||||
element.SetAttribute("timeBetweenFrames", GetTimeBetweenFrames());
|
||||
if (!GetMetadata().empty()) element.SetAttribute("metadata", GetMetadata());
|
||||
SaveSpritesDirection(sprites, element.AddChild("sprites"));
|
||||
}
|
||||
#endif
|
||||
|
@@ -6,17 +6,16 @@
|
||||
#ifndef GDCORE_DIRECTION_H
|
||||
#define GDCORE_DIRECTION_H
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Sprite;
|
||||
}
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Class defining a direction of an Animation.
|
||||
* \brief Class defining a direction (set of frames) of an Animation.
|
||||
*
|
||||
* \see SpriteObject
|
||||
* \see Animation
|
||||
@@ -32,78 +31,101 @@ class GD_CORE_API Direction {
|
||||
virtual ~Direction();
|
||||
|
||||
/**
|
||||
* Return true if sprites looping is activated
|
||||
* \brief Return true if sprites looping is activated
|
||||
*/
|
||||
inline bool IsLooping() const { return loop; }
|
||||
|
||||
/**
|
||||
* Set if the sprites must be looping or not.
|
||||
* \brief Set if the sprites must be looping or not.
|
||||
*/
|
||||
void SetLoop(bool loop_);
|
||||
|
||||
/**
|
||||
* Get the time between each sprite
|
||||
* \brief Get the time between each sprite
|
||||
*/
|
||||
inline float GetTimeBetweenFrames() const { return timeBetweenFrame; }
|
||||
|
||||
/**
|
||||
* Set the time between each sprite
|
||||
* \brief Set the time between each sprite
|
||||
*
|
||||
* \param time Time between each sprite, in seconds.
|
||||
*/
|
||||
void SetTimeBetweenFrames(float time);
|
||||
|
||||
/**
|
||||
* Return a reference to a sprite of the direction.
|
||||
* \brief Return a reference to a sprite of the direction.
|
||||
*
|
||||
* \param nb The index of the sprite to be accessed. Bound checking is not
|
||||
* made. \return A reference to the sprite.
|
||||
* made.
|
||||
*
|
||||
* \return A reference to the sprite.
|
||||
*/
|
||||
const Sprite& GetSprite(std::size_t nb) const;
|
||||
|
||||
/**
|
||||
* Return a reference to a sprite of the direction.
|
||||
* \brief Return a reference to a sprite of the direction.
|
||||
*
|
||||
* \param nb The index of the sprite to be accessed. Bound checking is not
|
||||
* made. \return A reference to the sprite.
|
||||
* made.
|
||||
*
|
||||
* \return A reference to the sprite.
|
||||
*/
|
||||
Sprite& GetSprite(std::size_t nb);
|
||||
|
||||
/**
|
||||
* Check if the direction contains sprites.
|
||||
* \brief Check if the direction contains sprites.
|
||||
*
|
||||
* \return true if the direction does not have any sprite.
|
||||
*/
|
||||
bool HasNoSprites() const;
|
||||
|
||||
/**
|
||||
* Return the number of sprite used in the direction
|
||||
* \brief Return the number of sprite used in the direction
|
||||
*
|
||||
* \return The number of sprite used in the direction
|
||||
*/
|
||||
std::size_t GetSpritesCount() const;
|
||||
|
||||
/**
|
||||
* Remove the sprite at the specified position.
|
||||
* \brief Remove the sprite at the specified position.
|
||||
*
|
||||
* Bound-checking is made.
|
||||
*/
|
||||
void RemoveSprite(std::size_t index);
|
||||
|
||||
/**
|
||||
* Clear the direction from all of its sprites
|
||||
* \brief Clear the direction from all of its sprites
|
||||
*/
|
||||
void RemoveAllSprites();
|
||||
|
||||
/**
|
||||
* Add a new sprite at the end of the list.
|
||||
* \brief Add a new sprite at the end of the list.
|
||||
*/
|
||||
void AddSprite(const Sprite& sprite);
|
||||
|
||||
/**
|
||||
* Swap the position of two sprites
|
||||
* \brief Swap the position of two sprites
|
||||
*/
|
||||
void SwapSprites(std::size_t firstSpriteIndex, std::size_t secondSpriteIndex);
|
||||
|
||||
/**
|
||||
* Change the position of the specified sprite.
|
||||
* \brief Change the position of the specified sprite.
|
||||
*/
|
||||
void MoveSprite(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Set the metadata (any string) associated to the Direction.
|
||||
* \note Can be used by external editors to store extra information.
|
||||
*/
|
||||
virtual void SetMetadata(const gd::String& metadata_) { metadata = metadata_; }
|
||||
|
||||
/**
|
||||
* \brief Return the (optional) metadata associated to the Direction.
|
||||
*/
|
||||
virtual const gd::String& GetMetadata() const { return metadata; }
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const gd::SerializerElement& element);
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
@@ -113,6 +135,9 @@ class GD_CORE_API Direction {
|
||||
bool loop; ///< true if the animation must loop.
|
||||
float timeBetweenFrame; ///< The time between each sprite of the animation.
|
||||
std::vector<Sprite> sprites; ///< The sprites of the direction.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String metadata;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -17,7 +17,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
extension
|
||||
.SetExtensionInformation("Sprite",
|
||||
_("Sprite"),
|
||||
_("Sprite are animated object which can be used for most elements of a game."),
|
||||
_("Sprite are animated object which can be used "
|
||||
"for most elements of a game."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects/sprite");
|
||||
@@ -30,8 +31,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddAction("Opacity",
|
||||
_("Change object's opacity"),
|
||||
_("Change the opacity of an object."),
|
||||
_("Change Sprite opacity"),
|
||||
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
|
||||
"is opaque (default)."),
|
||||
_("Do _PARAM1__PARAM2_ to the opacity of _PARAM0_"),
|
||||
_("Visibility"),
|
||||
"res/actions/opacity24.png",
|
||||
@@ -39,7 +41,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.AddParameter("expression", _("Value (between 0 and 255)"))
|
||||
.MarkAsSimple()
|
||||
.SetManipulatedType("number");
|
||||
|
||||
@@ -198,6 +200,34 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.MarkAsAdvanced()
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ChangeWidth",
|
||||
_("Width"),
|
||||
_("Change the width of a Sprite object."),
|
||||
_("Do _PARAM1__PARAM2_ to the width of _PARAM0_"),
|
||||
_("Size"),
|
||||
"res/actions/scale24.png",
|
||||
"res/actions/scale.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.MarkAsAdvanced()
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddAction("ChangeHeight",
|
||||
_("Height"),
|
||||
_("Change the height of a Sprite object."),
|
||||
_("Do _PARAM1__PARAM2_ to the height of _PARAM0_"),
|
||||
_("Size"),
|
||||
"res/actions/scale24.png",
|
||||
"res/actions/scale.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.MarkAsAdvanced()
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition(
|
||||
"Animation",
|
||||
_("Current animation"),
|
||||
@@ -309,8 +339,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
obj.AddCondition("Opacity",
|
||||
_("Opacity"),
|
||||
_("Compare the opacity of an object, between 0 (fully "
|
||||
"transparent) to 255 (opaque)"),
|
||||
_("Compare the opacity of a Sprite, between 0 (fully "
|
||||
"transparent) to 255 (opaque)."),
|
||||
_("The opacity of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Visibility"),
|
||||
"res/conditions/opacity24.png",
|
||||
|
@@ -23,9 +23,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("VarScene",
|
||||
_("Value of a variable"),
|
||||
_("Value of a scene variable"),
|
||||
_("Compare the value of a scene variable."),
|
||||
_("Variable _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Scene variable _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
@@ -36,9 +36,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddCondition("VarSceneTxt",
|
||||
_("Text of a variable"),
|
||||
_("Text of a scene variable"),
|
||||
_("Compare the text of a scene variable."),
|
||||
_("The text of variable _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("The text of scene variable _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
@@ -51,8 +51,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddCondition(
|
||||
"VariableChildExists",
|
||||
_("Child existence"),
|
||||
_("Return true if the specified child of the variable exists."),
|
||||
_("Child _PARAM1_ of variable _PARAM0_ exists"),
|
||||
_("Return true if the specified child of the scene variable exists."),
|
||||
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
|
||||
_("Variables/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
@@ -76,8 +76,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
extension
|
||||
.AddCondition("VarSceneDef",
|
||||
_("Test if a scene variable is defined"),
|
||||
_("Test if the scene variable exist."),
|
||||
_("Variable _PARAM0_ is defined"),
|
||||
_("Test if the scene variable exists."),
|
||||
_("Scene variable _PARAM0_ is defined"),
|
||||
_("Variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
@@ -129,9 +129,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ModVarScene",
|
||||
_("Value of a variable"),
|
||||
_("Value of a scene variable"),
|
||||
_("Modify the value of a scene variable."),
|
||||
_("Do _PARAM1__PARAM2_ to variable _PARAM0_"),
|
||||
_("Do _PARAM1__PARAM2_ to scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
@@ -142,9 +142,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ModVarSceneTxt",
|
||||
_("String of a variable"),
|
||||
_("String of a scene variable"),
|
||||
_("Modify the text of a scene variable."),
|
||||
_("Do _PARAM1__PARAM2_ to the text of variable _PARAM0_"),
|
||||
_("Do _PARAM1__PARAM2_ to the text of scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
@@ -185,8 +185,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
extension
|
||||
.AddAction("VariableRemoveChild",
|
||||
_("Remove a child"),
|
||||
_("Remove a child from a variable."),
|
||||
_("Remove child _PARAM1_ from variable _PARAM0_"),
|
||||
_("Remove a child from a scene variable."),
|
||||
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
|
||||
_("Variables/Structure"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
@@ -208,9 +208,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddAction("VariableClearChildren",
|
||||
_("Clear variable"),
|
||||
_("Remove all the children from the variable."),
|
||||
_("Clear children from variable _PARAM0_"),
|
||||
_("Clear scene variable"),
|
||||
_("Remove all the children from the scene variable."),
|
||||
_("Clear children from scene variable _PARAM0_"),
|
||||
_("Variables/Structure"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
@@ -230,7 +230,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddExpression("GlobalVariableChildCount",
|
||||
_("Global variable number of children"),
|
||||
_("Number of children of a global variable"),
|
||||
_("Get the number of children of a global variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
@@ -238,7 +238,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddExpression("VariableChildCount",
|
||||
_("Scene variable number of children"),
|
||||
_("Number of children of a scene variable"),
|
||||
_("Get the number of children of a scene variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
@@ -246,15 +246,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddExpression("Variable",
|
||||
_("Scene variables"),
|
||||
_("Scene variables"),
|
||||
_("Value of a scene variable"),
|
||||
_("Value of a scene variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
|
||||
extension
|
||||
.AddStrExpression("VariableString",
|
||||
_("Scene variables"),
|
||||
_("Text of a scene variable"),
|
||||
_("Text of a scene variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
@@ -262,15 +262,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
|
||||
extension
|
||||
.AddExpression("GlobalVariable",
|
||||
_("Global variables"),
|
||||
_("Global variable"),
|
||||
_("Value of a global variable"),
|
||||
_("Value of a global variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Name of the global variable"));
|
||||
|
||||
extension
|
||||
.AddStrExpression("GlobalVariableString",
|
||||
_("Global variables"),
|
||||
_("Text of a global variable"),
|
||||
_("Text of a global variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <algorithm>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "InstructionMetadata.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -81,4 +82,23 @@ InstructionMetadata& InstructionMetadata::AddCodeOnlyParameter(
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ParameterMetadata::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("type", type);
|
||||
element.SetAttribute("supplementaryInformation", supplementaryInformation);
|
||||
element.SetAttribute("optional", optional);
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("codeOnly", codeOnly);
|
||||
element.SetAttribute("defaultValue", defaultValue);
|
||||
element.SetAttribute("name", name);
|
||||
}
|
||||
|
||||
void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
|
||||
type = element.GetStringAttribute("type");
|
||||
supplementaryInformation = element.GetStringAttribute("supplementaryInformation");
|
||||
optional = element.GetBoolAttribute("optional");
|
||||
description = element.GetStringAttribute("description");
|
||||
codeOnly = element.GetBoolAttribute("codeOnly");
|
||||
defaultValue = element.GetStringAttribute("defaultValue");
|
||||
name = element.GetStringAttribute("name");
|
||||
}
|
||||
} // namespace gd
|
||||
|
@@ -22,6 +22,7 @@ class Project;
|
||||
class Layout;
|
||||
class EventsCodeGenerator;
|
||||
class EventsCodeGenerationContext;
|
||||
class SerializerElement;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -53,17 +54,19 @@ class GD_CORE_API ParameterMetadata {
|
||||
|
||||
/**
|
||||
* \brief Return the name of the parameter.
|
||||
*
|
||||
*
|
||||
* Name is optional, and won't be filled for most parameters of extensions.
|
||||
* It is useful when generating a function from events, where parameters must be named.
|
||||
* It is useful when generating a function from events, where parameters must
|
||||
* be named.
|
||||
*/
|
||||
const gd::String &GetName() const { return name; }
|
||||
|
||||
/**
|
||||
* \brief Set the name of the parameter.
|
||||
*
|
||||
*
|
||||
* Name is optional, and won't be filled for most parameters of extensions.
|
||||
* It is useful when generating a function from events, where parameters must be named.
|
||||
* It is useful when generating a function from events, where parameters must
|
||||
* be named.
|
||||
*/
|
||||
ParameterMetadata &SetName(const gd::String &name_) {
|
||||
name = name_;
|
||||
@@ -158,7 +161,8 @@ class GD_CORE_API ParameterMetadata {
|
||||
static bool IsExpression(const gd::String &type,
|
||||
const gd::String ¶meterType) {
|
||||
if (type == "number") {
|
||||
return parameterType == "expression" || parameterType == "camera";
|
||||
return parameterType == "expression" || parameterType == "camera" ||
|
||||
parameterType == "forceMultiplier";
|
||||
} else if (type == "string") {
|
||||
return parameterType == "string" || parameterType == "layer" ||
|
||||
parameterType == "color" || parameterType == "file" ||
|
||||
@@ -167,6 +171,20 @@ class GD_CORE_API ParameterMetadata {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the ParameterMetadata to the specified element
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement &element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the ParameterMetadata from the specified element
|
||||
*/
|
||||
void UnserializeFrom(const gd::SerializerElement &element);
|
||||
///@}
|
||||
|
||||
// TODO: Deprecated public fields. Any direct using should be moved to
|
||||
// getter/setter.
|
||||
gd::String type; ///< Parameter type
|
||||
@@ -178,8 +196,9 @@ class GD_CORE_API ParameterMetadata {
|
||||
///< i.e. must not be shown in editor
|
||||
gd::String defaultValue; ///< Used as a default value in editor or if an
|
||||
///< optional parameter is empty.
|
||||
private:
|
||||
gd::String name; ///< The name of the parameter to be used in code generation. Optional.
|
||||
private:
|
||||
gd::String name; ///< The name of the parameter to be used in code
|
||||
///< generation. Optional.
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -204,6 +223,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
const gd::String &GetDescription() const { return description; }
|
||||
const gd::String &GetSentence() const { return sentence; }
|
||||
const gd::String &GetGroup() const { return group; }
|
||||
ParameterMetadata &GetParameter(size_t i) { return parameters[i]; }
|
||||
const ParameterMetadata &GetParameter(size_t i) const {
|
||||
return parameters[i];
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer) {
|
||||
outputObjectsContainer.GetObjects().clear();
|
||||
for (std::size_t i = 0; i < parameters.size(); ++i) {
|
||||
const auto& parameter = parameters[i];
|
||||
if (parameter.GetName().empty()) continue;
|
||||
|
@@ -25,16 +25,16 @@ Platform::Platform() {}
|
||||
Platform::~Platform() {}
|
||||
|
||||
bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
|
||||
std::cout << extension->GetName();
|
||||
bool loaded = false;
|
||||
for (std::size_t i = 0; i < extensionsLoaded.size(); ++i) {
|
||||
if (extensionsLoaded[i]->GetName() == extension->GetName()) {
|
||||
std::cout << "(replacing existing extension)" << std::endl;
|
||||
extensionsLoaded[i] = extension;
|
||||
loaded = true;
|
||||
}
|
||||
if (!extension) return false;
|
||||
|
||||
std::cout << "Loading " << extension->GetName() << "...";
|
||||
if (IsExtensionLoaded(extension->GetName())) {
|
||||
std::cout << " (replacing existing extension)";
|
||||
RemoveExtension(extension->GetName());
|
||||
}
|
||||
if (!loaded) extensionsLoaded.push_back(extension);
|
||||
std::cout << std::endl;
|
||||
|
||||
extensionsLoaded.push_back(extension);
|
||||
|
||||
// Load all creation/destruction functions for objects provided by the
|
||||
// extension
|
||||
@@ -44,10 +44,30 @@ bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
|
||||
extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
|
||||
}
|
||||
|
||||
std::cout << ", ";
|
||||
return true;
|
||||
}
|
||||
|
||||
void Platform::RemoveExtension(const gd::String& name) {
|
||||
// Unload all creation/destruction functions for objects provided by the
|
||||
// extension
|
||||
for (std::size_t i = 0; i < extensionsLoaded.size(); ++i) {
|
||||
auto& extension = extensionsLoaded[i];
|
||||
if (extension->GetName() == name) {
|
||||
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
|
||||
for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
|
||||
creationFunctionTable.erase(objectsTypes[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extensionsLoaded.erase(remove_if(extensionsLoaded.begin(),
|
||||
extensionsLoaded.end(),
|
||||
[&name](std::shared_ptr<PlatformExtension> extension) {
|
||||
return extension->GetName() == name;
|
||||
}),
|
||||
extensionsLoaded.end());
|
||||
}
|
||||
|
||||
bool Platform::IsExtensionLoaded(const gd::String& name) const {
|
||||
for (std::size_t i = 0; i < extensionsLoaded.size(); ++i) {
|
||||
if (extensionsLoaded[i]->GetName() == name) return true;
|
||||
|
@@ -27,7 +27,8 @@ class LayoutEditorCanvas;
|
||||
class ProjectExporter;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)> CreateFunPtr;
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
CreateFunPtr;
|
||||
|
||||
#undef CreateEvent
|
||||
|
||||
@@ -85,7 +86,7 @@ class GD_CORE_API Platform {
|
||||
virtual gd::String GetExtensionCreateFunctionName() { return ""; }
|
||||
|
||||
/**
|
||||
* \brief Add an extension to the manager.
|
||||
* \brief Add an extension to the platform.
|
||||
* \note This method is virtual and can be redefined by platforms if they want
|
||||
* to do special work when an extension is loaded. \see gd::ExtensionsLoader
|
||||
*/
|
||||
@@ -111,6 +112,13 @@ class GD_CORE_API Platform {
|
||||
return extensionsLoaded;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Remove an extension from the platform.
|
||||
*
|
||||
* Events, objects, behaviors provided by the extension won't be available
|
||||
* anymore.
|
||||
*/
|
||||
virtual void RemoveExtension(const gd::String& name);
|
||||
///@}
|
||||
|
||||
/** \name Factory method
|
||||
|
@@ -388,7 +388,7 @@ void PlatformExtension::SetNameSpace(gd::String nameSpace_) {
|
||||
return;
|
||||
}
|
||||
|
||||
nameSpace = nameSpace_ + "::";
|
||||
nameSpace = nameSpace_ + GetNamespaceSeparator();
|
||||
}
|
||||
|
||||
std::vector<gd::String> PlatformExtension::GetBuiltinExtensionsNames() {
|
||||
|
@@ -432,6 +432,12 @@ class GD_CORE_API PlatformExtension {
|
||||
*/
|
||||
static std::vector<gd::String> GetBuiltinExtensionsNames();
|
||||
|
||||
/**
|
||||
* \brief Get the string used to separate the name of the
|
||||
* instruction/expression and the extension.
|
||||
*/
|
||||
static gd::String GetNamespaceSeparator() { return "::"; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Set the namespace ( the String each actions/conditions/expressions start
|
||||
|
@@ -1505,7 +1505,8 @@ void EditExpressionDialog::OnAddPropBtClick(wxCommandEvent& event) {
|
||||
.parameters[i]
|
||||
.supplementaryInformation);
|
||||
if (dialog.DeduceBehavior() || dialog.ShowModal() == 1)
|
||||
behaviorStr = dialog.GetChosenBehavior() + "::";
|
||||
behaviorStr = dialog.GetChosenBehavior() +
|
||||
gd::PlatformExtension::GetNamespaceSeparator();
|
||||
} else {
|
||||
if (!parametersStr.empty()) parametersStr += ",";
|
||||
parametersStr += ShowParameterDialog(
|
||||
|
@@ -782,7 +782,8 @@ void EditStrExpressionDialog::OnAddPropBtClick(wxCommandEvent& event) {
|
||||
.parameters[i]
|
||||
.supplementaryInformation);
|
||||
if (dialog.DeduceBehavior() || dialog.ShowModal() == 1)
|
||||
behaviorStr = dialog.GetChosenBehavior() + "::";
|
||||
behaviorStr = dialog.GetChosenBehavior() +
|
||||
gd::PlatformExtension::GetNamespaceSeparator();
|
||||
} else {
|
||||
if (!parametersStr.empty()) parametersStr += ",";
|
||||
parametersStr += ShowParameterDialog(
|
||||
|
@@ -7,6 +7,8 @@
|
||||
#include "EventStoreDialog.h"
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/IDE/Events/EventsRefactorer.h"
|
||||
#include "GDCore/IDE/wxTools/SafeYield.h"
|
||||
|
@@ -41,7 +41,7 @@
|
||||
#include "GDCore/IDE/Dialogs/DndResourcesEditor.h"
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#include "GDCore/IDE/Dialogs/ResourceLibraryDialog.h"
|
||||
#include "GDCore/IDE/Project/ImagesUsedInventorizer.h"
|
||||
#include "GDCore/IDE/Project/ResourcesInUseHelper.h"
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/IDE/wxTools/FileProperty.h"
|
||||
#include "GDCore/IDE/wxTools/SkinHelper.h"
|
||||
@@ -1332,7 +1332,7 @@ void ResourcesEditor::Refresh() {
|
||||
|
||||
void ResourcesEditor::OnDeleteUnusedFiles(wxCommandEvent& event) {
|
||||
std::vector<gd::String> unusedImages =
|
||||
gd::ProjectResourcesAdder::GetAllUselessImages(project);
|
||||
gd::ProjectResourcesAdder::GetAllUseless(project, "image");
|
||||
|
||||
// Construct corresponding wxArrayString with unused images
|
||||
wxArrayString imagesNotUsed;
|
||||
|
@@ -12,8 +12,8 @@
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -103,6 +103,8 @@ class CallbacksForRenamingObject : public gd::ParserCallbacks {
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression) {
|
||||
// TODO: Add support for renaming in sub expressions. This is not working
|
||||
// as the parser does not handle change made to the expression.
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForRenamingObject callbacks(newExpression, oldName, newName);
|
||||
@@ -111,7 +113,7 @@ class CallbacksForRenamingObject : public gd::ParserCallbacks {
|
||||
if (!parser.ParseMathExpression(platform, project, layout, callbacks))
|
||||
return false;
|
||||
|
||||
expression = gd::Expression(newExpression);
|
||||
expression = gd::Expression(newExpression); // This change won't be picked up by the parser
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -119,6 +121,8 @@ class CallbacksForRenamingObject : public gd::ParserCallbacks {
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression) {
|
||||
// TODO: Add support for renaming in sub expressions. This is not working
|
||||
// as the parser does not handle change made to the expression.
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForRenamingObject callbacks(newExpression, oldName, newName);
|
||||
@@ -127,7 +131,7 @@ class CallbacksForRenamingObject : public gd::ParserCallbacks {
|
||||
if (!parser.ParseStringExpression(platform, project, layout, callbacks))
|
||||
return false;
|
||||
|
||||
expression = gd::Expression(newExpression);
|
||||
expression = gd::Expression(newExpression); // This change won't be picked up by the parser
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -201,8 +205,8 @@ class CallbacksForRemovingObject : public gd::ParserCallbacks {
|
||||
};
|
||||
|
||||
bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String oldName,
|
||||
gd::String newName) {
|
||||
@@ -265,8 +269,8 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
|
||||
bool EventsRefactorer::RenameObjectInConditions(
|
||||
const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String oldName,
|
||||
gd::String newName) {
|
||||
@@ -325,8 +329,8 @@ bool EventsRefactorer::RenameObjectInConditions(
|
||||
}
|
||||
|
||||
void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String oldName,
|
||||
gd::String newName) {
|
||||
@@ -362,8 +366,8 @@ void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
|
||||
}
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -426,8 +430,8 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInConditions(
|
||||
const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -489,8 +493,8 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
}
|
||||
|
||||
void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String name) {
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
@@ -520,8 +524,8 @@ void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
|
||||
}
|
||||
}
|
||||
|
||||
void EventsRefactorer::ReplaceStringInEvents(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
void EventsRefactorer::ReplaceStringInEvents(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
@@ -590,8 +594,8 @@ gd::String ReplaceAllOccurencesCaseUnsensitive(gd::String context,
|
||||
return context;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::ReplaceStringInActions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
bool EventsRefactorer::ReplaceStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
@@ -632,8 +636,8 @@ bool EventsRefactorer::ReplaceStringInActions(gd::Project& project,
|
||||
}
|
||||
|
||||
bool EventsRefactorer::ReplaceStringInConditions(
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
@@ -675,8 +679,8 @@ bool EventsRefactorer::ReplaceStringInConditions(
|
||||
}
|
||||
|
||||
vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
@@ -734,8 +738,8 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
return results;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInActions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
bool EventsRefactorer::SearchStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
@@ -766,8 +770,8 @@ bool EventsRefactorer::SearchStringInActions(gd::Project& project,
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInConditions(
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
|
@@ -11,9 +11,8 @@
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
class Platform;
|
||||
class Project;
|
||||
class ExternalEvents;
|
||||
class BaseEvent;
|
||||
class Instruction;
|
||||
@@ -77,8 +76,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* events ).
|
||||
*/
|
||||
static void RenameObjectInEvents(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -87,8 +86,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* Remove all actions or conditions using an object
|
||||
*/
|
||||
static void RemoveObjectInEvents(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String name);
|
||||
|
||||
@@ -98,8 +97,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return A vector containing EventsSearchResult objects filled with events
|
||||
* containing the string
|
||||
*/
|
||||
static std::vector<EventsSearchResult> SearchInEvents(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static std::vector<EventsSearchResult> SearchInEvents(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
@@ -109,8 +108,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
/**
|
||||
* Replace all occurrences of a gd::String in events
|
||||
*/
|
||||
static void ReplaceStringInEvents(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static void ReplaceStringInEvents(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::EventsList& events,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
@@ -128,8 +127,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RenameObjectInActions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& instructions,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -141,8 +140,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RenameObjectInConditions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& instructions,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -153,8 +152,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RemoveObjectInConditions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name);
|
||||
|
||||
@@ -164,8 +163,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RemoveObjectInActions(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name);
|
||||
|
||||
@@ -174,8 +173,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
*
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool ReplaceStringInConditions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static bool ReplaceStringInConditions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
@@ -186,20 +185,20 @@ class GD_CORE_API EventsRefactorer {
|
||||
*
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool ReplaceStringInActions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static bool ReplaceStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String toReplace,
|
||||
gd::String newString,
|
||||
bool matchCase);
|
||||
|
||||
static bool SearchStringInActions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static bool SearchStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
static bool SearchStringInConditions(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
static bool SearchStringInConditions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/IDE/Events/EventsTypesLister.h"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#ifndef EventsTypesLister_H
|
||||
#define EventsTypesLister_H
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
51
Core/GDCore/IDE/Events/ExpressionsRenamer.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool ExpressionsRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
auto& metadata = isCondition ? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.size() &&
|
||||
pNb < instruction.GetParametersCount();
|
||||
++pNb) {
|
||||
// Replace object's name in parameters
|
||||
if (gd::ParameterMetadata::IsExpression("number",
|
||||
metadata.parameters[pNb].type) ||
|
||||
gd::ParameterMetadata::IsExpression("string",
|
||||
metadata.parameters[pNb].type)) {
|
||||
// This raw replacement is theorically too broad and a ExpressionParser
|
||||
// should be used instead with callbacks to rename only the function. But
|
||||
// as ExpressionsRenamer is only used for renaming EventsFunction, which
|
||||
// have namespaces (i.e: Extension::MyFunction), it's safe enough to do
|
||||
// this raw search/replace.
|
||||
instruction.SetParameter(
|
||||
pNb,
|
||||
instruction.GetParameter(pNb).GetPlainString().FindAndReplace(
|
||||
oldType, newType));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ExpressionsRenamer::~ExpressionsRenamer() {}
|
||||
|
||||
} // namespace gd
|
52
Core/GDCore/IDE/Events/ExpressionsRenamer.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef ExpressionsRenamer_H
|
||||
#define ExpressionsRenamer_H
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Platform;
|
||||
class EventsList;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Replace in expressions, in parameters of actions or conditions, calls
|
||||
* to a function by another function.
|
||||
*
|
||||
* \note The replacement is done by making a raw search/replace in parameters
|
||||
* that are expecting expressions or string expressions. Consequently, to avoid
|
||||
* unwanted renaming, be sure to only use ExpressionsRenamer for expression
|
||||
* calls that have an obvious name (in particular, make sure they have a
|
||||
* namespace: Extension::Expression).
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ExpressionsRenamer : public ArbitraryEventsWorker {
|
||||
public:
|
||||
ExpressionsRenamer(const gd::Platform& platform_,
|
||||
const gd::String& oldType_,
|
||||
const gd::String& newType_)
|
||||
: platform(platform_), oldType(oldType_), newType(newType_){};
|
||||
virtual ~ExpressionsRenamer();
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Platform& platform;
|
||||
gd::String oldType;
|
||||
gd::String newType;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // ExpressionsRenamer_H
|
29
Core/GDCore/IDE/Events/InstructionsTypeRenamer.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool InstructionsTypeRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
if (instruction.GetType() == oldType) {
|
||||
instruction.SetType(newType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
InstructionsTypeRenamer::~InstructionsTypeRenamer() {}
|
||||
|
||||
} // namespace gd
|
46
Core/GDCore/IDE/Events/InstructionsTypeRenamer.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef InstructionsTypeRenamer_H
|
||||
#define InstructionsTypeRenamer_H
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Project;
|
||||
class EventsList;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Replace in events all instructions of the specified type
|
||||
* by another type.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API InstructionsTypeRenamer : public ArbitraryEventsWorker {
|
||||
public:
|
||||
InstructionsTypeRenamer(const gd::Project& project_,
|
||||
const gd::String& oldType_,
|
||||
const gd::String& newType_)
|
||||
: project(project_), oldType(oldType_), newType(newType_){};
|
||||
virtual ~InstructionsTypeRenamer();
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Project& project;
|
||||
gd::String oldType;
|
||||
gd::String newType;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // InstructionsTypeRenamer_H
|
@@ -21,7 +21,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void ArbitraryResourceWorker::ExposeImage(gd::String& imageName){
|
||||
// Nothing to do, the image is a referece to a resource that
|
||||
// Nothing to do, the image is a reference to a resource that
|
||||
// is already exposed.
|
||||
};
|
||||
|
||||
@@ -40,6 +40,21 @@ void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
|
||||
ExposeFile(audioName);
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
|
||||
for (auto resources : GetResources()) {
|
||||
if (!resources) continue;
|
||||
|
||||
if (resources->HasResource(fontName) &&
|
||||
resources->GetResource(fontName).GetKind() == "font") {
|
||||
// Nothing to do, the font is a reference to a resource that
|
||||
// is already exposed.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ExposeFile(fontName);
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeResources(
|
||||
gd::ResourcesManager* resourcesManager) {
|
||||
if (!resourcesManager) return;
|
||||
|
@@ -34,7 +34,7 @@ namespace gd {
|
||||
* sometimes update them.
|
||||
*
|
||||
* \see ResourcesMergingHelper
|
||||
* \see gd::ImagesUsedInventorizer
|
||||
* \see gd::ResourcesInUseHelper
|
||||
*
|
||||
* \see gd::LaunchResourceWorkerOnEvents
|
||||
*
|
||||
@@ -64,6 +64,12 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
*/
|
||||
virtual void ExposeAudio(gd::String &audioName);
|
||||
|
||||
/**
|
||||
* \brief Expose a font, which is either a reference to a "font" resource,
|
||||
* or a filename if no resource with this name exists.
|
||||
*/
|
||||
virtual void ExposeFont(gd::String &fontName);
|
||||
|
||||
/**
|
||||
* \brief Expose a shader.
|
||||
* \warn Currently unsupported.
|
||||
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef IMAGESUSEDINVENTORIZER_H
|
||||
#define IMAGESUSEDINVENTORIZER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Class used to track all images used in a game.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
gd::ImagesUsedInventorizer inventorizer;
|
||||
project.ExposeResources(inventorizer);
|
||||
|
||||
//Get a set with the name of all images in the project:
|
||||
std::set<gd::String> & usedImages = inventorizer.GetAllUsedImages();
|
||||
\endcode
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class ImagesUsedInventorizer : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
ImagesUsedInventorizer() : gd::ArbitraryResourceWorker(){};
|
||||
virtual ~ImagesUsedInventorizer(){};
|
||||
|
||||
std::set<gd::String>& GetAllUsedImages() { return allUsedImages; };
|
||||
|
||||
virtual void ExposeFile(gd::String& resource){
|
||||
/*Don't care, we just list images*/};
|
||||
virtual void ExposeImage(gd::String& imageName) {
|
||||
allUsedImages.insert(imageName);
|
||||
};
|
||||
|
||||
protected:
|
||||
std::set<gd::String> allUsedImages;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // IMAGESUSEDINVENTORIZER_H
|
||||
#endif
|
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
#include "ProjectResourcesAdder.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/IDE/Project/ImagesUsedInventorizer.h"
|
||||
#include "GDCore/IDE/Project/ResourcesInUseHelper.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -14,51 +14,52 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool ProjectResourcesAdder::AddAllMissingImages(gd::Project& project) {
|
||||
gd::ImagesUsedInventorizer inventorizer;
|
||||
project.ExposeResources(inventorizer);
|
||||
std::set<gd::String>& allImages = inventorizer.GetAllUsedImages();
|
||||
bool ProjectResourcesAdder::AddAllMissing(gd::Project& project,
|
||||
const gd::String& resourceType) {
|
||||
// Search for resources used in the project
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
|
||||
ResourcesManager& resourcesManager = project.GetResourcesManager();
|
||||
for (std::set<gd::String>::const_iterator it = allImages.begin();
|
||||
it != allImages.end();
|
||||
++it) {
|
||||
if (!resourcesManager.HasResource(*it)) {
|
||||
std::cout << "Adding missing resource \"" << *it << "\"to the project.";
|
||||
resourcesManager.AddResource(*it, /*filename=*/*it, "image");
|
||||
for (auto& resourceName : resourcesInUse.GetAll(resourceType)) {
|
||||
if (!resourcesManager.HasResource(resourceName)) {
|
||||
std::cout << "Adding missing resource \"" << resourceName
|
||||
<< "\"to the project." << std::endl;
|
||||
resourcesManager.AddResource(
|
||||
resourceName, /*filename=*/resourceName, resourceType);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ProjectResourcesAdder::GetAllUselessImages(
|
||||
gd::Project& project) {
|
||||
std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
|
||||
gd::Project& project, const gd::String& resourceType) {
|
||||
std::vector<gd::String> unusedResources;
|
||||
// Search for resources used in the project
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
std::set<gd::String>& usedResources = resourcesInUse.GetAll(resourceType);
|
||||
|
||||
// Search for used images
|
||||
gd::ImagesUsedInventorizer inventorizer;
|
||||
|
||||
project.ExposeResources(inventorizer);
|
||||
std::set<gd::String>& usedImages = inventorizer.GetAllUsedImages();
|
||||
|
||||
// Search all images resources not used
|
||||
// Search all resources not used
|
||||
std::vector<gd::String> resources =
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
for (std::size_t i = 0; i < resources.size(); i++) {
|
||||
if (project.GetResourcesManager().GetResource(resources[i]).GetKind() !=
|
||||
"image")
|
||||
resourceType)
|
||||
continue;
|
||||
|
||||
if (usedImages.find(resources[i]) == usedImages.end())
|
||||
if (usedResources.find(resources[i]) == usedResources.end())
|
||||
unusedResources.push_back(resources[i]);
|
||||
}
|
||||
|
||||
return unusedResources;
|
||||
}
|
||||
|
||||
void ProjectResourcesAdder::RemoveAllUselessImages(gd::Project& project) {
|
||||
std::vector<gd::String> unusedResources = GetAllUselessImages(project);
|
||||
void ProjectResourcesAdder::RemoveAllUseless(gd::Project& project,
|
||||
const gd::String& resourceType) {
|
||||
std::vector<gd::String> unusedResources =
|
||||
GetAllUseless(project, resourceType);
|
||||
|
||||
for (std::size_t i = 0; i < unusedResources.size(); ++i) {
|
||||
project.GetResourcesManager().RemoveResource(unusedResources[i]);
|
||||
|
@@ -21,38 +21,35 @@ namespace gd {
|
||||
class GD_CORE_API ProjectResourcesAdder {
|
||||
public:
|
||||
/**
|
||||
* \brief Update the project so that all missing images are added, with an
|
||||
* \brief Update the project so that all missing resources are added, with an
|
||||
* filename that is equal to the missing resource name.
|
||||
*
|
||||
* \param project The project to be updated.
|
||||
* \param resourceType The type of the resource the be searched
|
||||
*
|
||||
* \return true if no error happened
|
||||
*/
|
||||
static bool AddAllMissingImages(gd::Project& project);
|
||||
static bool AddAllMissing(gd::Project& project, const gd::String & resourceType);
|
||||
|
||||
/**
|
||||
* \brief Find all resources that are
|
||||
* not used in the project.
|
||||
*
|
||||
* \note For now, only images resources can be tracked and marked
|
||||
* as not used.
|
||||
* \brief Find all resources of the specified kind that are
|
||||
* not used by the project.
|
||||
*
|
||||
* \param project The project to be crawled.
|
||||
* \param resourceType The type of the resource the be searched
|
||||
*
|
||||
* \return A vector containing the name of all unused resources
|
||||
*/
|
||||
static std::vector<gd::String> GetAllUselessImages(gd::Project& project);
|
||||
static std::vector<gd::String> GetAllUseless(gd::Project& project, const gd::String & resourceType);
|
||||
|
||||
/**
|
||||
* \brief Remove all resources that are not used
|
||||
* in the project.
|
||||
*
|
||||
* \note For now, only images resources can be tracked and marked
|
||||
* as not used.
|
||||
* \brief Remove all resources of the specified kind that are not used
|
||||
* by the project.
|
||||
*
|
||||
* \param project The project to be crawled.
|
||||
* \param resourceType The type of the resource the be searched
|
||||
*/
|
||||
static void RemoveAllUselessImages(gd::Project& project);
|
||||
static void RemoveAllUseless(gd::Project& project, const gd::String & resourceType);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
72
Core/GDCore/IDE/Project/ResourcesInUseHelper.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef IMAGESUSEDINVENTORIZER_H
|
||||
#define IMAGESUSEDINVENTORIZER_H
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Class used to track all resources used by a game,
|
||||
* or a part of it (like a gd::Object).
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
|
||||
//Get a set with the name of all images in the project:
|
||||
std::set<gd::String> & usedImages = resourcesInUse.GetAllImages();
|
||||
\endcode
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
ResourcesInUseHelper() : gd::ArbitraryResourceWorker(){};
|
||||
virtual ~ResourcesInUseHelper(){};
|
||||
|
||||
std::set<gd::String>& GetAllImages() { return GetAll("image"); };
|
||||
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
|
||||
std::set<gd::String>& GetAllAudios() { return GetAll("audio"); };
|
||||
std::set<gd::String>& GetAll(const gd::String& resourceType) {
|
||||
return resourceType == "image"
|
||||
? allImages
|
||||
: (resourceType == "audio"
|
||||
? allAudios
|
||||
: (resourceType == "font") ? allFonts : emptyResources);
|
||||
};
|
||||
|
||||
virtual void ExposeFile(gd::String& resource) override{
|
||||
/*Don't care, we just list resource names*/
|
||||
};
|
||||
virtual void ExposeImage(gd::String& imageResourceName) override {
|
||||
allImages.insert(imageResourceName);
|
||||
};
|
||||
virtual void ExposeAudio(gd::String& audioResourceName) override {
|
||||
allAudios.insert(audioResourceName);
|
||||
};
|
||||
virtual void ExposeFont(gd::String& fontResourceName) override {
|
||||
allFonts.insert(fontResourceName);
|
||||
};
|
||||
|
||||
protected:
|
||||
std::set<gd::String> allImages;
|
||||
std::set<gd::String> allAudios;
|
||||
std::set<gd::String> allFonts;
|
||||
std::set<gd::String> emptyResources;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // IMAGESUSEDINVENTORIZER_H
|
||||
#endif
|
@@ -49,11 +49,25 @@ void ResourcesMergingHelper::SetNewFilename(gd::String oldFilename,
|
||||
gd::String newFilename) {
|
||||
if (oldFilenames.find(oldFilename) != oldFilenames.end()) return;
|
||||
|
||||
// Make sure that the new filename is not already used.
|
||||
gd::String finalFilename = gd::NewNameGenerator::Generate(
|
||||
newFilename, [this](const gd::String& name) {
|
||||
return newFilenames.find(name) != newFilenames.end();
|
||||
});
|
||||
// Extract baseName and extension from the new filename
|
||||
size_t extensionPos = newFilename.find_last_of(".");
|
||||
gd::String extension =
|
||||
extensionPos != gd::String::npos
|
||||
? newFilename.substr(extensionPos, newFilename.length())
|
||||
: "";
|
||||
gd::String baseName = newFilename.substr(0, extensionPos);
|
||||
|
||||
// Make sure that the new filename is not already used. Generate a
|
||||
// new filename while there is a collision.
|
||||
// Preserving extension is important.
|
||||
gd::String finalFilename =
|
||||
gd::NewNameGenerator::Generate(
|
||||
baseName,
|
||||
[this, extension](const gd::String& newBaseName) {
|
||||
return newFilenames.find(newBaseName + extension) !=
|
||||
newFilenames.end();
|
||||
}) +
|
||||
extension;
|
||||
|
||||
oldFilenames[oldFilename] = finalFilename;
|
||||
newFilenames[finalFilename] = oldFilename;
|
||||
|
@@ -18,8 +18,10 @@ class AbstractFileSystem;
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief ResourcesMergingHelper is used (mainly during compilation) so
|
||||
* as to inventory resources and change their filenames
|
||||
* \brief ResourcesMergingHelper is used (mainly during export)
|
||||
* to list resources and generate new filenames, to allow them to be all copied
|
||||
* in a single directory (potentially changing the filename to avoid conflicts,
|
||||
* but preserving extensions).
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*
|
||||
@@ -82,9 +84,9 @@ class GD_CORE_API ResourcesMergingHelper : public ArbitraryResourceWorker {
|
||||
///< baseDirectory, will be preserved in
|
||||
///< filenames.
|
||||
bool preserveAbsoluteFilenames; ///< If set to true, the filenames which are
|
||||
///< absolute ( C:\MyFile.png ) will not be
|
||||
///< transformed into their filenames (
|
||||
///< MyFile.png ).
|
||||
///< absolute (C:\MyFile.png will not be
|
||||
///< transformed into a relative filename
|
||||
///< (MyFile.png).
|
||||
gd::AbstractFileSystem&
|
||||
fs; ///< The gd::AbstractFileSystem used to manipulate files.
|
||||
};
|
||||
|
@@ -4,8 +4,13 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "WholeProjectRefactorer.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/DependenciesAnalyzer.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Events/EventsRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
|
||||
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
@@ -16,6 +21,105 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
void WholeProjectRefactorer::ExposeProjectEvents(
|
||||
gd::Project& project, gd::ArbitraryEventsWorker& worker) {
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources).
|
||||
|
||||
// Add layouts resources
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
worker.Launch(project.GetLayout(s).GetEvents());
|
||||
}
|
||||
// Add external events resources
|
||||
for (std::size_t s = 0; s < project.GetExternalEventsCount(); s++) {
|
||||
worker.Launch(project.GetExternalEvents(s).GetEvents());
|
||||
}
|
||||
// Add events functions extensions resources
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto& eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
for (auto&& eventsFunction : eventsFunctionsExtension.GetEventsFunctions()) {
|
||||
worker.Launch(eventsFunction->GetEvents());
|
||||
}
|
||||
}
|
||||
}
|
||||
void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName) {
|
||||
auto renameEventsFunction =
|
||||
[&project, &oldName, &newName](const gd::EventsFunction& eventsFunction) {
|
||||
auto separator = gd::PlatformExtension::GetNamespaceSeparator();
|
||||
gd::String oldType = oldName + separator + eventsFunction.GetName();
|
||||
gd::String newType = newName + separator + eventsFunction.GetName();
|
||||
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsTypeRenamer renamer =
|
||||
gd::InstructionsTypeRenamer(project, oldType, newType);
|
||||
ExposeProjectEvents(project, renamer);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
gd::ExpressionsRenamer renamer = gd::ExpressionsRenamer(
|
||||
project.GetCurrentPlatform(), oldType, newType);
|
||||
ExposeProjectEvents(project, renamer);
|
||||
}
|
||||
};
|
||||
|
||||
// Order is important: we first rename the expressions then the instructions,
|
||||
// to avoid being unable to fetch the metadata (the types of parameters) of
|
||||
// instructions after they are renamed.
|
||||
for (auto&& eventsFunction : eventsFunctionsExtension.GetEventsFunctions()) {
|
||||
if (eventsFunction->GetFunctionType() == gd::EventsFunction::Expression ||
|
||||
eventsFunction->GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
renameEventsFunction(*eventsFunction);
|
||||
}
|
||||
}
|
||||
for (auto&& eventsFunction : eventsFunctionsExtension.GetEventsFunctions()) {
|
||||
if (eventsFunction->GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction->GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
renameEventsFunction(*eventsFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an events function is renamed
|
||||
*/
|
||||
void WholeProjectRefactorer::RenameEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldFunctionName,
|
||||
const gd::String& newFunctionName) {
|
||||
if (!eventsFunctionsExtension.HasEventsFunctionNamed(oldFunctionName)) return;
|
||||
|
||||
const gd::EventsFunction& eventsFunction =
|
||||
eventsFunctionsExtension.GetEventsFunction(oldFunctionName);
|
||||
auto separator = gd::PlatformExtension::GetNamespaceSeparator();
|
||||
gd::String oldType =
|
||||
eventsFunctionsExtension.GetName() + separator + oldFunctionName;
|
||||
gd::String newType =
|
||||
eventsFunctionsExtension.GetName() + separator + newFunctionName;
|
||||
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsTypeRenamer renamer =
|
||||
gd::InstructionsTypeRenamer(project, oldType, newType);
|
||||
ExposeProjectEvents(project, renamer);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
gd::ExpressionsRenamer renamer =
|
||||
gd::ExpressionsRenamer(project.GetCurrentPlatform(), oldType, newType);
|
||||
ExposeProjectEvents(project, renamer);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInLayout(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
const gd::String& objectName,
|
||||
|
@@ -8,22 +8,51 @@
|
||||
#include <vector>
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class String;
|
||||
}
|
||||
class EventsFunctionsExtension;
|
||||
class ArbitraryEventsWorker;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Tool functions to do refactoring on the whole project after
|
||||
* changes like deletion or renaming of an object.
|
||||
*/
|
||||
*
|
||||
* \TODO Ideally ObjectRenamedInLayout, ObjectRemovedInLayout,
|
||||
* GlobalObjectRenamed, GlobalObjectRemoved would be implemented using
|
||||
* ExposeProjectEvents.
|
||||
**/
|
||||
class GD_CORE_API WholeProjectRefactorer {
|
||||
public:
|
||||
/**
|
||||
* \brief Call the specified worker on all events of the project (layout,
|
||||
* external events, events functions...)
|
||||
*
|
||||
* This should be the preferred way to traverse all the events of a project.
|
||||
*/
|
||||
static void ExposeProjectEvents(gd::Project& project,
|
||||
gd::ArbitraryEventsWorker& worker);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an events function extension is renamed
|
||||
*/
|
||||
static void RenameEventsFunctionsExtension(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an events function is renamed
|
||||
*/
|
||||
static void RenameEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldFunctionName,
|
||||
const gd::String& newFunctionName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is renamed in a layout
|
||||
*
|
||||
|
69
Core/GDCore/Project/EventsFunction.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "EventsFunction.h"
|
||||
#include <vector>
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
EventsFunction::EventsFunction() : functionType(Action) {}
|
||||
|
||||
void EventsFunction::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("sentence", sentence);
|
||||
events.SerializeTo(element.AddChild("events"));
|
||||
|
||||
gd::String functionTypeStr = "Action";
|
||||
if (functionType == Condition)
|
||||
functionTypeStr = "Condition";
|
||||
else if (functionType == Expression)
|
||||
functionTypeStr = "Expression";
|
||||
else if (functionType == StringExpression)
|
||||
functionTypeStr = "StringExpression";
|
||||
element.SetAttribute("functionType", functionTypeStr);
|
||||
|
||||
gd::SerializerElement& parametersElement = element.AddChild("parameters");
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (const auto& parameter : parameters) {
|
||||
parameter.SerializeTo(parametersElement.AddChild("parameter"));
|
||||
}
|
||||
}
|
||||
|
||||
void EventsFunction::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
description = element.GetStringAttribute("description");
|
||||
sentence = element.GetStringAttribute("sentence");
|
||||
events.UnserializeFrom(project, element.GetChild("events"));
|
||||
|
||||
gd::String functionTypeStr = element.GetStringAttribute("functionType");
|
||||
if (functionTypeStr == "Condition")
|
||||
functionType = Condition;
|
||||
else if (functionTypeStr == "Expression")
|
||||
functionType = Expression;
|
||||
else if (functionTypeStr == "StringExpression")
|
||||
functionType = StringExpression;
|
||||
else
|
||||
functionType = Action;
|
||||
|
||||
const gd::SerializerElement& parametersElement =
|
||||
element.GetChild("parameters");
|
||||
parameters.clear();
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i) {
|
||||
ParameterMetadata parameter;
|
||||
parameter.UnserializeFrom(parametersElement.GetChild(i));
|
||||
parameters.push_back(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
172
Core/GDCore/Project/EventsFunction.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EVENTSFUNCTION_H
|
||||
#define GDCORE_EVENTSFUNCTION_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/String.h"
|
||||
// TODO: In theory (for separation of concerns between Project and
|
||||
// extensions/events), this include should be removed and gd::ParameterMetadata
|
||||
// replaced by a new gd::EventsFunctionParameter class.
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Events that can be generated as a stand-alone function, and used
|
||||
* as a condition, action or expression.
|
||||
*
|
||||
* \note The code generation can be done using gd::EventsCodeGenerator
|
||||
*
|
||||
* \note The conversion to an extension is not in GDCore and should be done
|
||||
* by the IDE (see EventsFunctionsExtensionsLoader)
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API EventsFunction {
|
||||
public:
|
||||
EventsFunction();
|
||||
virtual ~EventsFunction(){};
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new EventsFunction constructed from
|
||||
* this one.
|
||||
*/
|
||||
EventsFunction* Clone() const { return new EventsFunction(*this); };
|
||||
|
||||
/**
|
||||
* \brief Get the description of the function, that is displayed in the
|
||||
* editor.
|
||||
*/
|
||||
const gd::String& GetDescription() const { return description; };
|
||||
|
||||
/**
|
||||
* \brief Set the description of the function, to be displayed in the editor.
|
||||
*/
|
||||
EventsFunction& SetDescription(const gd::String& description_) {
|
||||
description = description_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the function, to be used for the
|
||||
* action/condition/expression name.
|
||||
*/
|
||||
const gd::String& GetName() const { return name; };
|
||||
|
||||
/**
|
||||
* \brief Set the name of the function, to be used for the
|
||||
* action/condition/expression name.
|
||||
*/
|
||||
EventsFunction& SetName(const gd::String& name_) {
|
||||
name = name_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the function, that is displayed in the editor.
|
||||
*/
|
||||
const gd::String& GetFullName() const { return fullName; };
|
||||
|
||||
/**
|
||||
* \brief Set the name of the function, to be displayed in the editor.
|
||||
*/
|
||||
EventsFunction& SetFullName(const gd::String& fullName_) {
|
||||
fullName = fullName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the sentence of the function, that is used for the
|
||||
* condition/action in the Events Editor.
|
||||
*/
|
||||
const gd::String& GetSentence() const { return sentence; };
|
||||
|
||||
/**
|
||||
* \brief Set the sentence of the function, to be used for the
|
||||
* condition/action in the Events Editor.
|
||||
*/
|
||||
EventsFunction& SetSentence(const gd::String& sentence_) {
|
||||
sentence = sentence_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
enum FunctionType { Action, Condition, Expression, StringExpression };
|
||||
|
||||
/**
|
||||
* \brief Set the type of the function
|
||||
*/
|
||||
EventsFunction& SetFunctionType(FunctionType type) {
|
||||
functionType = type;
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the type of the function
|
||||
*/
|
||||
FunctionType GetFunctionType() const { return functionType; };
|
||||
|
||||
/**
|
||||
* \brief Return the events.
|
||||
*/
|
||||
const gd::EventsList& GetEvents() const { return events; };
|
||||
|
||||
/**
|
||||
* \brief Return the events.
|
||||
*/
|
||||
gd::EventsList& GetEvents() { return events; };
|
||||
|
||||
/**
|
||||
* \brief Return the parameters of the function.
|
||||
*
|
||||
* \note During code/extension generation, new parameters are added
|
||||
* to the generated function, like "runtimeScene" and "eventsFunctionContext".
|
||||
* This should be transparent to the user.
|
||||
*/
|
||||
const std::vector<gd::ParameterMetadata>& GetParameters() const {
|
||||
return parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the parameters.
|
||||
*/
|
||||
std::vector<gd::ParameterMetadata>& GetParameters() { return parameters; };
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the EventsFunction to the specified element
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the EventsFunction from the specified element
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
gd::String description;
|
||||
gd::String sentence;
|
||||
gd::EventsList events;
|
||||
FunctionType functionType;
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSFUNCTION_H
|
||||
#endif
|
161
Core/GDCore/Project/EventsFunctionsExtension.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "EventsFunctionsExtension.h"
|
||||
#include "EventsFunction.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GDCore/Tools/PolymorphicClone.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
EventsFunctionsExtension::EventsFunctionsExtension() {}
|
||||
|
||||
EventsFunctionsExtension::EventsFunctionsExtension(
|
||||
const EventsFunctionsExtension& other) {
|
||||
Init(other);
|
||||
}
|
||||
|
||||
EventsFunctionsExtension& EventsFunctionsExtension::operator=(
|
||||
const EventsFunctionsExtension& other) {
|
||||
if (this != &other) Init(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
|
||||
version = other.version;
|
||||
extensionNamespace = other.extensionNamespace;
|
||||
description = other.description;
|
||||
name = other.name;
|
||||
fullName = other.fullName;
|
||||
eventsFunctions = gd::Clone(other.eventsFunctions);
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("version", version);
|
||||
element.SetAttribute("extensionNamespace", extensionNamespace);
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
|
||||
gd::SerializerElement& eventsFunctionsElement =
|
||||
element.AddChild("eventsFunctions");
|
||||
eventsFunctionsElement.ConsiderAsArrayOf("eventsFunction");
|
||||
for (const auto& eventsFunction : eventsFunctions) {
|
||||
eventsFunction->SerializeTo(
|
||||
eventsFunctionsElement.AddChild("eventsFunction"));
|
||||
}
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::UnserializeFrom(
|
||||
gd::Project& project, const SerializerElement& element) {
|
||||
version = element.GetStringAttribute("version");
|
||||
extensionNamespace = element.GetStringAttribute("extensionNamespace");
|
||||
description = element.GetStringAttribute("description");
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
|
||||
const gd::SerializerElement& eventsFunctionsElement =
|
||||
element.GetChild("eventsFunctions");
|
||||
eventsFunctions.clear();
|
||||
eventsFunctionsElement.ConsiderAsArrayOf("eventsFunction");
|
||||
for (std::size_t i = 0; i < eventsFunctionsElement.GetChildrenCount(); ++i) {
|
||||
gd::EventsFunction& newEventsFunction =
|
||||
InsertNewEventsFunction("", GetEventsFunctionsCount());
|
||||
|
||||
newEventsFunction.UnserializeFrom(project,
|
||||
eventsFunctionsElement.GetChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
bool EventsFunctionsExtension::HasEventsFunctionNamed(
|
||||
const gd::String& name) const {
|
||||
return find_if(eventsFunctions.begin(),
|
||||
eventsFunctions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunction>& function) {
|
||||
return function->GetName() == name;
|
||||
}) != eventsFunctions.end();
|
||||
}
|
||||
|
||||
std::size_t EventsFunctionsExtension::GetEventsFunctionsCount() const {
|
||||
return eventsFunctions.size();
|
||||
}
|
||||
|
||||
gd::EventsFunction& EventsFunctionsExtension::InsertNewEventsFunction(
|
||||
const gd::String& name, std::size_t position) {
|
||||
gd::EventsFunction& newEventsFunction = *(*(eventsFunctions.insert(
|
||||
position < eventsFunctions.size() ? eventsFunctions.begin() + position
|
||||
: eventsFunctions.end(),
|
||||
std::unique_ptr<gd::EventsFunction>(new EventsFunction()))));
|
||||
|
||||
newEventsFunction.SetName(name);
|
||||
return newEventsFunction;
|
||||
}
|
||||
|
||||
gd::EventsFunction& EventsFunctionsExtension::InsertEventsFunction(
|
||||
const gd::EventsFunction& object, std::size_t position) {
|
||||
gd::EventsFunction& newEventsFunction = *(*(eventsFunctions.insert(
|
||||
position < eventsFunctions.size() ? eventsFunctions.begin() + position
|
||||
: eventsFunctions.end(),
|
||||
std::unique_ptr<gd::EventsFunction>(new EventsFunction(object)))));
|
||||
|
||||
return newEventsFunction;
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::MoveEventsFunction(std::size_t oldIndex,
|
||||
std::size_t newIndex) {
|
||||
if (oldIndex >= eventsFunctions.size() || newIndex >= eventsFunctions.size())
|
||||
return;
|
||||
|
||||
std::unique_ptr<gd::EventsFunction> object =
|
||||
std::move(eventsFunctions[oldIndex]);
|
||||
eventsFunctions.erase(eventsFunctions.begin() + oldIndex);
|
||||
eventsFunctions.insert(eventsFunctions.begin() + newIndex, std::move(object));
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::RemoveEventsFunction(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::EventsFunction> >::iterator object =
|
||||
find_if(eventsFunctions.begin(),
|
||||
eventsFunctions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunction>& function) {
|
||||
return function->GetName() == name;
|
||||
});
|
||||
if (object == eventsFunctions.end()) return;
|
||||
|
||||
eventsFunctions.erase(object);
|
||||
}
|
||||
|
||||
gd::EventsFunction& EventsFunctionsExtension::GetEventsFunction(
|
||||
const gd::String& name) {
|
||||
return *(
|
||||
*find_if(eventsFunctions.begin(),
|
||||
eventsFunctions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunction>& function) {
|
||||
return function->GetName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
const gd::EventsFunction& EventsFunctionsExtension::GetEventsFunction(
|
||||
const gd::String& name) const {
|
||||
return *(
|
||||
*find_if(eventsFunctions.begin(),
|
||||
eventsFunctions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunction>& function) {
|
||||
return function->GetName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
gd::EventsFunction& EventsFunctionsExtension::GetEventsFunction(std::size_t index) {
|
||||
return *eventsFunctions[index];
|
||||
}
|
||||
const gd::EventsFunction& EventsFunctionsExtension::GetEventsFunction(std::size_t index) const {
|
||||
return *eventsFunctions[index];
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
172
Core/GDCore/Project/EventsFunctionsExtension.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
#define GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/EventsFunction.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Hold a list of Events Functions (gd::EventsFunction).
|
||||
*
|
||||
* Events functions can be generated as stand-alone functions, and
|
||||
* converted to actions/conditions/expressions.
|
||||
* Similarly, a gd::EventsFunctionsExtension can be converted to
|
||||
* an extension.
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API EventsFunctionsExtension {
|
||||
public:
|
||||
EventsFunctionsExtension();
|
||||
EventsFunctionsExtension(const EventsFunctionsExtension&);
|
||||
EventsFunctionsExtension& operator=(const EventsFunctionsExtension& rhs);
|
||||
virtual ~EventsFunctionsExtension(){};
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new EventsFunctionsExtension constructed from
|
||||
* this one.
|
||||
*/
|
||||
EventsFunctionsExtension* Clone() const {
|
||||
return new EventsFunctionsExtension(*this);
|
||||
};
|
||||
|
||||
const gd::String& GetVersion() const { return version; };
|
||||
EventsFunctionsExtension& SetVersion(const gd::String& version_) {
|
||||
version = version_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetNamespace() const { return extensionNamespace; };
|
||||
EventsFunctionsExtension& SetNamespace(const gd::String& namespace_) {
|
||||
extensionNamespace = namespace_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetDescription() const { return description; };
|
||||
EventsFunctionsExtension& SetDescription(const gd::String& description_) {
|
||||
description = description_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetName() const { return name; };
|
||||
EventsFunctionsExtension& SetName(const gd::String& name_) {
|
||||
name = name_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetFullName() const { return fullName; };
|
||||
EventsFunctionsExtension& SetFullName(const gd::String& fullName_) {
|
||||
fullName = fullName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the function with the specified name exists.
|
||||
*/
|
||||
bool HasEventsFunctionNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Get the function with the specified name.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
gd::EventsFunction& GetEventsFunction(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Get the function with the specified name.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
const gd::EventsFunction& GetEventsFunction(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Get the function at the specified index in the list.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
gd::EventsFunction& GetEventsFunction(std::size_t index);
|
||||
|
||||
/**
|
||||
* \brief Get the function at the specified index in the list.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
const gd::EventsFunction& GetEventsFunction(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* \brief Return the number of functions.
|
||||
*/
|
||||
std::size_t GetEventsFunctionsCount() const;
|
||||
|
||||
gd::EventsFunction& InsertNewEventsFunction(const gd::String& name,
|
||||
std::size_t position);
|
||||
gd::EventsFunction& InsertEventsFunction(const gd::EventsFunction& object,
|
||||
std::size_t position);
|
||||
void RemoveEventsFunction(const gd::String& name);
|
||||
void MoveEventsFunction(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Provide a raw access to the vector containing the functions.
|
||||
*/
|
||||
const std::vector<std::unique_ptr<gd::EventsFunction>>& GetEventsFunctions()
|
||||
const {
|
||||
return eventsFunctions;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Provide a raw access to the vector containing the functions.
|
||||
*/
|
||||
std::vector<std::unique_ptr<gd::EventsFunction>>& GetEventsFunctions() {
|
||||
return eventsFunctions;
|
||||
};
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the EventsFunctionsExtension to the specified element
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the EventsFunctionsExtension from the specified element
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Initialize object using another object. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::EventsFunctionsExtension& other);
|
||||
|
||||
gd::String version;
|
||||
gd::String extensionNamespace;
|
||||
gd::String description;
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
std::vector<std::unique_ptr<gd::EventsFunction>> eventsFunctions;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
#endif
|
@@ -16,28 +16,16 @@
|
||||
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class MainFrameWrapper;
|
||||
}
|
||||
namespace gd {
|
||||
class ArbitraryResourceWorker;
|
||||
}
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
}
|
||||
class SerializerElement;
|
||||
} // namespace gd
|
||||
namespace sf {
|
||||
class RenderTarget;
|
||||
}
|
||||
namespace sf {
|
||||
class SerializerElement;
|
||||
}
|
||||
class wxWindow;
|
||||
class wxBitmap;
|
||||
|
||||
@@ -77,7 +65,10 @@ class GD_CORE_API Object {
|
||||
/**
|
||||
* Must return a pointer to a copy of the object. A such method is needed to
|
||||
* do polymorphic copies. Just redefine this method in your derived object
|
||||
* class like this: \code return new MyObject(*this); \endcode
|
||||
* class like this:
|
||||
* \code
|
||||
* return gd::make_unique<MyObject>(*this);
|
||||
* \endcode
|
||||
*/
|
||||
virtual std::unique_ptr<gd::Object> Clone() const {
|
||||
return gd::make_unique<gd::Object>(*this);
|
||||
|
@@ -10,8 +10,6 @@
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
namespace gd {
|
||||
class ArbitraryResourceWorker;
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "GDCore/IDE/PlatformManager.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/wxTools/SafeYield.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ChangesNotifier.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
@@ -64,6 +65,7 @@ Project::Project()
|
||||
version("1.0.0"),
|
||||
packageName("com.example.gamename"),
|
||||
orientation("landscape"),
|
||||
adMobAppId(""),
|
||||
folderProject(false),
|
||||
#endif
|
||||
windowWidth(800),
|
||||
@@ -434,6 +436,104 @@ void Project::RemoveExternalLayout(const gd::String& name) {
|
||||
externalLayouts.erase(externalLayout);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void Project::SwapEventsFunctionsExtensions(std::size_t first,
|
||||
std::size_t second) {
|
||||
if (first >= eventsFunctionsExtensions.size() ||
|
||||
second >= eventsFunctionsExtensions.size())
|
||||
return;
|
||||
|
||||
std::iter_swap(eventsFunctionsExtensions.begin() + first,
|
||||
eventsFunctionsExtensions.begin() + second);
|
||||
}
|
||||
bool Project::HasEventsFunctionsExtensionNamed(const gd::String& name) const {
|
||||
return (
|
||||
find_if(
|
||||
eventsFunctionsExtensions.begin(),
|
||||
eventsFunctionsExtensions.end(),
|
||||
[&name](
|
||||
const std::unique_ptr<gd::EventsFunctionsExtension>& extension) {
|
||||
return extension->GetName() == name;
|
||||
}) != eventsFunctionsExtensions.end());
|
||||
}
|
||||
gd::EventsFunctionsExtension& Project::GetEventsFunctionsExtension(
|
||||
const gd::String& name) {
|
||||
return *(*find_if(
|
||||
eventsFunctionsExtensions.begin(),
|
||||
eventsFunctionsExtensions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunctionsExtension>& extension) {
|
||||
return extension->GetName() == name;
|
||||
}));
|
||||
}
|
||||
const gd::EventsFunctionsExtension& Project::GetEventsFunctionsExtension(
|
||||
const gd::String& name) const {
|
||||
return *(*find_if(
|
||||
eventsFunctionsExtensions.begin(),
|
||||
eventsFunctionsExtensions.end(),
|
||||
[&name](const std::unique_ptr<gd::EventsFunctionsExtension>& extension) {
|
||||
return extension->GetName() == name;
|
||||
}));
|
||||
}
|
||||
gd::EventsFunctionsExtension& Project::GetEventsFunctionsExtension(
|
||||
std::size_t index) {
|
||||
return *eventsFunctionsExtensions[index];
|
||||
}
|
||||
const gd::EventsFunctionsExtension& Project::GetEventsFunctionsExtension(
|
||||
std::size_t index) const {
|
||||
return *eventsFunctionsExtensions[index];
|
||||
}
|
||||
std::size_t Project::GetEventsFunctionsExtensionPosition(
|
||||
const gd::String& name) const {
|
||||
for (std::size_t i = 0; i < eventsFunctionsExtensions.size(); ++i) {
|
||||
if (eventsFunctionsExtensions[i]->GetName() == name) return i;
|
||||
}
|
||||
return gd::String::npos;
|
||||
}
|
||||
|
||||
std::size_t Project::GetEventsFunctionsExtensionsCount() const {
|
||||
return eventsFunctionsExtensions.size();
|
||||
}
|
||||
|
||||
gd::EventsFunctionsExtension& Project::InsertNewEventsFunctionsExtension(
|
||||
const gd::String& name, std::size_t position) {
|
||||
gd::EventsFunctionsExtension& newlyInsertedEventsFunctionsExtension =
|
||||
*(*(eventsFunctionsExtensions.emplace(
|
||||
position < eventsFunctionsExtensions.size()
|
||||
? eventsFunctionsExtensions.begin() + position
|
||||
: eventsFunctionsExtensions.end(),
|
||||
new gd::EventsFunctionsExtension())));
|
||||
|
||||
newlyInsertedEventsFunctionsExtension.SetName(name);
|
||||
return newlyInsertedEventsFunctionsExtension;
|
||||
}
|
||||
|
||||
gd::EventsFunctionsExtension& Project::InsertEventsFunctionsExtension(
|
||||
const gd::EventsFunctionsExtension& extension, std::size_t position) {
|
||||
gd::EventsFunctionsExtension& newlyInsertedEventsFunctionsExtension =
|
||||
*(*(eventsFunctionsExtensions.emplace(
|
||||
position < eventsFunctionsExtensions.size()
|
||||
? eventsFunctionsExtensions.begin() + position
|
||||
: eventsFunctionsExtensions.end(),
|
||||
new gd::EventsFunctionsExtension(extension))));
|
||||
|
||||
return newlyInsertedEventsFunctionsExtension;
|
||||
}
|
||||
|
||||
void Project::RemoveEventsFunctionsExtension(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::EventsFunctionsExtension> >::iterator
|
||||
eventsFunctionExtension = find_if(
|
||||
eventsFunctionsExtensions.begin(),
|
||||
eventsFunctionsExtensions.end(),
|
||||
[&name](
|
||||
const std::unique_ptr<gd::EventsFunctionsExtension>& extension) {
|
||||
return extension->GetName() == name;
|
||||
});
|
||||
if (eventsFunctionExtension == eventsFunctionsExtensions.end()) return;
|
||||
|
||||
eventsFunctionsExtensions.erase(eventsFunctionExtension);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI)
|
||||
// Compatibility with GD2.x
|
||||
class SpriteObjectsPositionUpdater : public gd::InitialInstanceFunctor {
|
||||
@@ -541,6 +641,7 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
SetAdMobAppId(propElement.GetStringAttribute("adMobAppId", ""));
|
||||
SetFolderProject(propElement.GetBoolAttribute("folderProject"));
|
||||
SetProjectFile(propElement.GetStringAttribute("projectFile"));
|
||||
SetLastCompilationDirectory(propElement
|
||||
@@ -732,6 +833,24 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
GetExternalEventsCount());
|
||||
externalEvents.UnserializeFrom(*this, externalEventElement);
|
||||
}
|
||||
|
||||
eventsFunctionsExtensions.clear();
|
||||
const SerializerElement& eventsFunctionsExtensionsElement =
|
||||
element.GetChild("eventsFunctionsExtensions");
|
||||
eventsFunctionsExtensionsElement.ConsiderAsArrayOf(
|
||||
"eventsFunctionsExtension");
|
||||
for (std::size_t i = 0;
|
||||
i < eventsFunctionsExtensionsElement.GetChildrenCount();
|
||||
++i) {
|
||||
const SerializerElement& eventsFunctionsExtensionElement =
|
||||
eventsFunctionsExtensionsElement.GetChild(i);
|
||||
|
||||
gd::EventsFunctionsExtension& newEventsFunctionsExtension =
|
||||
InsertNewEventsFunctionsExtension("",
|
||||
GetEventsFunctionsExtensionsCount());
|
||||
newEventsFunctionsExtension.UnserializeFrom(
|
||||
*this, eventsFunctionsExtensionElement);
|
||||
}
|
||||
#endif
|
||||
|
||||
externalLayouts.clear();
|
||||
@@ -799,6 +918,7 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
propElement.SetAttribute("folderProject", folderProject);
|
||||
propElement.SetAttribute("packageName", packageName);
|
||||
propElement.SetAttribute("orientation", orientation);
|
||||
propElement.SetAttribute("adMobAppId", adMobAppId);
|
||||
platformSpecificAssets.SerializeTo(
|
||||
propElement.AddChild("platformSpecificAssets"));
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
@@ -848,6 +968,14 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
GetExternalEvents(i).SerializeTo(
|
||||
externalEventsElement.AddChild("externalEvents"));
|
||||
|
||||
SerializerElement& eventsFunctionsExtensionsElement =
|
||||
element.AddChild("eventsFunctionsExtensions");
|
||||
eventsFunctionsExtensionsElement.ConsiderAsArrayOf(
|
||||
"eventsFunctionsExtension");
|
||||
for (std::size_t i = 0; i < eventsFunctionsExtensions.size(); ++i)
|
||||
eventsFunctionsExtensions[i]->SerializeTo(
|
||||
eventsFunctionsExtensionsElement.AddChild("eventsFunctionsExtension"));
|
||||
|
||||
SerializerElement& externalLayoutsElement =
|
||||
element.AddChild("externalLayouts");
|
||||
externalLayoutsElement.ConsiderAsArrayOf("externalLayout");
|
||||
@@ -878,6 +1006,10 @@ gd::String Project::GetBadObjectNameWarning() {
|
||||
}
|
||||
|
||||
void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
// See also gd::WholeProjectRefactorer::ExposeProjectEvents for a method that traverse the whole
|
||||
// project (this time for events).
|
||||
// Ideally, this method could be moved outside of gd::Project.
|
||||
|
||||
// Add project resources
|
||||
worker.ExposeResources(&GetResourcesManager());
|
||||
platformSpecificAssets.ExposeResources(worker);
|
||||
@@ -898,6 +1030,13 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
LaunchResourceWorkerOnEvents(
|
||||
*this, GetExternalEvents(s).GetEvents(), worker);
|
||||
}
|
||||
// Add events functions extensions resources
|
||||
for (std::size_t e = 0; e < GetEventsFunctionsExtensionsCount(); e++) {
|
||||
auto& eventsFunctionsExtension = GetEventsFunctionsExtension(e);
|
||||
for (auto&& eventsFunction : eventsFunctionsExtension.GetEventsFunctions()) {
|
||||
LaunchResourceWorkerOnEvents(*this, eventsFunction->GetEvents(), worker);
|
||||
}
|
||||
}
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
gd::SafeYield::Do();
|
||||
#endif
|
||||
@@ -1115,6 +1254,7 @@ void Project::Init(const gd::Project& game) {
|
||||
author = game.author;
|
||||
packageName = game.packageName;
|
||||
orientation = game.orientation;
|
||||
adMobAppId = game.adMobAppId;
|
||||
folderProject = game.folderProject;
|
||||
latestCompilationDirectory = game.latestCompilationDirectory;
|
||||
platformSpecificAssets = game.platformSpecificAssets;
|
||||
@@ -1143,8 +1283,9 @@ void Project::Init(const gd::Project& game) {
|
||||
#endif
|
||||
|
||||
externalLayouts = gd::Clone(game.externalLayouts);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
eventsFunctionsExtensions = gd::Clone(game.eventsFunctionsExtensions);
|
||||
|
||||
useExternalSourceFiles = game.useExternalSourceFiles;
|
||||
|
||||
externalSourceFiles = gd::Clone(game.externalSourceFiles);
|
||||
|
@@ -13,9 +13,9 @@ class wxPropertyGrid;
|
||||
class wxPropertyGridEvent;
|
||||
class TiXmlElement;
|
||||
#include "GDCore/Project/ChangesNotifier.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/LoadingScreen.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/PlatformSpecificAssets.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
@@ -25,6 +25,7 @@ class Layout;
|
||||
class ExternalEvents;
|
||||
class ResourcesManager;
|
||||
class ExternalLayout;
|
||||
class EventsFunctionsExtension;
|
||||
class Object;
|
||||
class VariablesContainer;
|
||||
class ArbitraryResourceWorker;
|
||||
@@ -34,7 +35,7 @@ class Behavior;
|
||||
class BehaviorsSharedData;
|
||||
class BaseEvent;
|
||||
class SerializerElement;
|
||||
}
|
||||
} // namespace gd
|
||||
#undef GetObject // Disable an annoying macro
|
||||
#undef CreateEvent
|
||||
|
||||
@@ -68,7 +69,8 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
/**
|
||||
* \brief Change the version of the project.
|
||||
* This can be freely set, but should follow "X.Y.Z" format for compatibility with some exporters.
|
||||
* This can be freely set, but should follow "X.Y.Z" format for compatibility
|
||||
* with some exporters.
|
||||
*/
|
||||
void SetVersion(const gd::String& version_) { version = version_; };
|
||||
|
||||
@@ -114,6 +116,20 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
const gd::String& GetOrientation() const { return orientation; }
|
||||
|
||||
/**
|
||||
* \brief Change the project AdMob application ID (needed
|
||||
* to use the AdMob extension). This has no effect on desktop
|
||||
* and web browsers.
|
||||
*/
|
||||
void SetAdMobAppId(const gd::String& adMobAppId_) {
|
||||
adMobAppId = adMobAppId_;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the project AdMob application ID.
|
||||
*/
|
||||
const gd::String& GetAdMobAppId() const { return adMobAppId; }
|
||||
|
||||
/**
|
||||
* Called when project file has changed.
|
||||
*/
|
||||
@@ -456,13 +472,13 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
std::size_t GetLayoutsCount() const;
|
||||
|
||||
/**
|
||||
* \brief Must add a new empty layout called "name" at the specified position
|
||||
* in the layout list.
|
||||
* \brief \brief Adds a new empty layout called "name" at the specified
|
||||
* position in the layout list.
|
||||
*/
|
||||
gd::Layout& InsertNewLayout(const gd::String& name, std::size_t position);
|
||||
|
||||
/**
|
||||
* \brief Must add a new layout constructed from the layout passed as
|
||||
* \brief \brief Adds a new layout constructed from the layout passed as
|
||||
* parameter. \note No pointer or reference must be kept on the layout passed
|
||||
* as parameter. \param layout The layout that must be copied and inserted
|
||||
* into the project \param position Insertion position. Even if the position
|
||||
@@ -565,15 +581,15 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
std::size_t GetExternalEventsCount() const;
|
||||
|
||||
/**
|
||||
* Must add a new empty external events sheet called "name" at the specified
|
||||
* position in the layout list.
|
||||
* \brief Adds a new empty external events sheet called "name" at the
|
||||
* specified position in the layout list.
|
||||
*/
|
||||
ExternalEvents& InsertNewExternalEvents(const gd::String& name,
|
||||
std::size_t position);
|
||||
|
||||
/**
|
||||
* Must add a new external events sheet constructed from the layout passed as
|
||||
* parameter. \note No pointer or reference must be kept on the external
|
||||
* \brief Adds a new external events sheet constructed from the layout passed
|
||||
* as parameter. \note No pointer or reference must be kept on the external
|
||||
* events passed as parameter. \param externalEvents The external events that
|
||||
* must be copied and inserted into the project \param position Insertion
|
||||
* position. Even if the position is invalid, the external events must be
|
||||
@@ -642,19 +658,23 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
std::size_t GetExternalLayoutsCount() const;
|
||||
|
||||
/**
|
||||
* Must add a new empty external layout called "name" at the specified
|
||||
* \brief Adds a new empty external layout called "name" at the specified
|
||||
* position in the layout list.
|
||||
*/
|
||||
gd::ExternalLayout& InsertNewExternalLayout(const gd::String& name,
|
||||
std::size_t position);
|
||||
|
||||
/**
|
||||
* Must add a new external layout constructed from the layout passed as
|
||||
* parameter. \note No pointer or reference must be kept on the external
|
||||
* layout passed as parameter. \param externalLayout The external layout that
|
||||
* must be copied and inserted into the project \param position Insertion
|
||||
* position. Even if the position is invalid, the external layout must be
|
||||
* inserted at the end of the external layout list.
|
||||
* \brief Adds a new external layout constructed from the layout passed as
|
||||
* parameter.
|
||||
*
|
||||
* \note No pointer or reference must be kept on the external
|
||||
* layout passed as parameter.
|
||||
*
|
||||
* \param externalLayout The external layout that
|
||||
* must be copied and inserted into the projects
|
||||
* \param position Insertion position. Even if the position is invalid, the
|
||||
* external layout must be inserted at the end of the external layout list.
|
||||
*/
|
||||
gd::ExternalLayout& InsertExternalLayout(const ExternalLayout& externalLayout,
|
||||
std::size_t position);
|
||||
@@ -674,6 +694,81 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
const gd::String& GetFirstLayout() { return firstLayout; }
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Events functions extensions management
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Return true if events functions extension called "name" exists.
|
||||
*/
|
||||
bool HasEventsFunctionsExtensionNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Return a reference to the events functions extension called "name".
|
||||
*/
|
||||
EventsFunctionsExtension& GetEventsFunctionsExtension(const gd::String& name);
|
||||
|
||||
/**
|
||||
* Return a reference to the events functions extension called "name".
|
||||
*/
|
||||
const EventsFunctionsExtension& GetEventsFunctionsExtension(
|
||||
const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Return a reference to the events functions extension at position "index" in
|
||||
* the list
|
||||
*/
|
||||
EventsFunctionsExtension& GetEventsFunctionsExtension(std::size_t index);
|
||||
|
||||
/**
|
||||
* Return a reference to the events functions extension at position "index" in
|
||||
* the list
|
||||
*/
|
||||
const EventsFunctionsExtension& GetEventsFunctionsExtension(
|
||||
std::size_t index) const;
|
||||
|
||||
/**
|
||||
* Return the position of the events functions extension called "name" in the
|
||||
* list
|
||||
*/
|
||||
std::size_t GetEventsFunctionsExtensionPosition(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Swap the specified events functions extensions.
|
||||
*
|
||||
* Do nothing if indexes are not correct.
|
||||
*/
|
||||
void SwapEventsFunctionsExtensions(std::size_t first, std::size_t second);
|
||||
|
||||
/**
|
||||
* Return the number of events functions extension.
|
||||
*/
|
||||
std::size_t GetEventsFunctionsExtensionsCount() const;
|
||||
|
||||
/**
|
||||
* \brief Adds a new empty events functions extension called "name" at the
|
||||
* specified position in the list.
|
||||
*/
|
||||
gd::EventsFunctionsExtension& InsertNewEventsFunctionsExtension(
|
||||
const gd::String& name, std::size_t position);
|
||||
|
||||
/**
|
||||
* \brief Adds a new events functions extension constructed from the layout
|
||||
* passed as parameter.
|
||||
*
|
||||
* \note No pointer or reference must be kept on the extension passed as
|
||||
* parameter.
|
||||
*/
|
||||
gd::EventsFunctionsExtension& InsertEventsFunctionsExtension(
|
||||
const EventsFunctionsExtension& externalLayout, std::size_t position);
|
||||
|
||||
/**
|
||||
* Must delete the events functions extension named "name".
|
||||
*/
|
||||
void RemoveEventsFunctionsExtension(const gd::String& name);
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
@@ -718,8 +813,11 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources and sometimes update their filename.
|
||||
* resources, sometimes update their filename or any other work or resources.
|
||||
*
|
||||
* See WholeProjectRefactorer for the same thing for events.
|
||||
*
|
||||
* \see WholeProjectRefactorer
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker);
|
||||
@@ -857,6 +955,10 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
gd::VariablesContainer variables; ///< Initial global variables
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >
|
||||
externalLayouts; ///< List of all externals layouts
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<std::unique_ptr<gd::EventsFunctionsExtension> >
|
||||
eventsFunctionsExtensions;
|
||||
#endif
|
||||
gd::ResourcesManager
|
||||
resourcesManager; ///< Contains all resources used by the project
|
||||
std::shared_ptr<gd::ImageManager>
|
||||
@@ -870,10 +972,11 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
bool useExternalSourceFiles; ///< True if game used external source files.
|
||||
std::vector<std::unique_ptr<gd::SourceFile> >
|
||||
externalSourceFiles; ///< List of external source files used.
|
||||
gd::String author; ///< Game author name
|
||||
gd::String packageName; ///< Game package name
|
||||
gd::String orientation; ///< Lock game orientation (on mobile devices).
|
||||
///< "default", "landscape" or "portrait".
|
||||
gd::String author; ///< Game author name
|
||||
gd::String packageName; ///< Game package name
|
||||
gd::String orientation; ///< Lock game orientation (on mobile devices).
|
||||
///< "default", "landscape" or "portrait".
|
||||
gd::String adMobAppId; ///< AdMob application ID.
|
||||
bool
|
||||
folderProject; ///< True if folder project, false if single file project.
|
||||
gd::String gameFile; ///< File of the game
|
||||
|
@@ -79,6 +79,8 @@ std::shared_ptr<Resource> ResourcesManager::CreateResource(
|
||||
return std::make_shared<ImageResource>();
|
||||
else if (kind == "audio")
|
||||
return std::make_shared<AudioResource>();
|
||||
else if (kind == "font")
|
||||
return std::make_shared<FontResource>();
|
||||
|
||||
std::cout << "Bad resource created (type: " << kind << ")" << std::endl;
|
||||
return std::make_shared<Resource>();
|
||||
@@ -92,7 +94,7 @@ bool ResourcesManager::HasResource(const gd::String& name) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourceNames() {
|
||||
std::vector<gd::String> ResourcesManager::GetAllResourceNames() const {
|
||||
std::vector<gd::String> allResources;
|
||||
for (std::size_t i = 0; i < resources.size(); ++i)
|
||||
allResources.push_back(resources[i]->GetName());
|
||||
@@ -134,19 +136,11 @@ bool ImageResource::UpdateProperty(const gd::String& name,
|
||||
bool ResourcesManager::AddResource(const gd::Resource& resource) {
|
||||
if (HasResource(resource.GetName())) return false;
|
||||
|
||||
try {
|
||||
const Resource& castedResource = dynamic_cast<const Resource&>(resource);
|
||||
std::shared_ptr<Resource> newResource =
|
||||
std::shared_ptr<Resource>(castedResource.Clone());
|
||||
if (newResource == std::shared_ptr<Resource>()) return false;
|
||||
|
||||
resources.push_back(newResource);
|
||||
} catch (...) {
|
||||
std::cout << "WARNING: Tried to add a resource which is not a GD C++ "
|
||||
"Platform Resource to a GD C++ Platform project";
|
||||
std::cout << char(7);
|
||||
}
|
||||
std::shared_ptr<Resource> newResource =
|
||||
std::shared_ptr<Resource>(resource.Clone());
|
||||
if (newResource == std::shared_ptr<Resource>()) return false;
|
||||
|
||||
resources.push_back(newResource);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -408,16 +402,8 @@ bool ResourceFolder::HasResource(const gd::String& name) const {
|
||||
|
||||
void ResourceFolder::AddResource(const gd::String& name,
|
||||
gd::ResourcesManager& parentManager) {
|
||||
try {
|
||||
ResourcesManager& manager = dynamic_cast<ResourcesManager&>(parentManager);
|
||||
std::shared_ptr<Resource> resource =
|
||||
std::dynamic_pointer_cast<Resource>(manager.GetResourceSPtr(name));
|
||||
if (resource != std::shared_ptr<Resource>()) resources.push_back(resource);
|
||||
} catch (...) {
|
||||
std::cout << "Warning: A resources manager which is not part of GD C++ "
|
||||
"Platform was used during call to AddResource"
|
||||
<< std::endl;
|
||||
}
|
||||
std::shared_ptr<Resource> resource = parentManager.GetResourceSPtr(name);
|
||||
if (resource != std::shared_ptr<Resource>()) resources.push_back(resource);
|
||||
}
|
||||
|
||||
void ResourcesManager::RenameResource(const gd::String& oldName,
|
||||
@@ -487,9 +473,11 @@ void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
const SerializerElement& resourceElement = resourcesElement.GetChild(i);
|
||||
gd::String kind = resourceElement.GetStringAttribute("kind");
|
||||
gd::String name = resourceElement.GetStringAttribute("name");
|
||||
gd::String metadata = resourceElement.GetStringAttribute("metadata", "");
|
||||
|
||||
std::shared_ptr<Resource> resource = CreateResource(kind);
|
||||
resource->SetName(name);
|
||||
resource->SetMetadata(metadata);
|
||||
resource->UnserializeFrom(resourceElement);
|
||||
|
||||
resources.push_back(resource);
|
||||
@@ -519,6 +507,7 @@ void ResourcesManager::SerializeTo(SerializerElement& element) const {
|
||||
SerializerElement& resourceElement = resourcesElement.AddChild("resource");
|
||||
resourceElement.SetAttribute("kind", resources[i]->GetKind());
|
||||
resourceElement.SetAttribute("name", resources[i]->GetName());
|
||||
resourceElement.SetAttribute("metadata", resources[i]->GetMetadata());
|
||||
|
||||
resources[i]->SerializeTo(resourceElement);
|
||||
}
|
||||
@@ -577,7 +566,31 @@ void AudioResource::SerializeTo(SerializerElement& element) const {
|
||||
"file", GetFile()); // Keep the resource path in the current locale (but
|
||||
// save it in UTF8 for compatibility on other OSes)
|
||||
}
|
||||
#endif
|
||||
|
||||
void FontResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
|
||||
// Convert all backslash to slashs.
|
||||
while (file.find('\\') != gd::String::npos)
|
||||
file.replace(file.find('\\'), 1, "/");
|
||||
}
|
||||
|
||||
void FontResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetUserAdded(element.GetBoolAttribute("userAdded"));
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void FontResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute(
|
||||
"file", GetFile()); // Keep the resource path in the current locale (but
|
||||
// save it in UTF8 for compatibility on other OSes)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
ResourceFolder::ResourceFolder(const ResourceFolder& other) { Init(other); }
|
||||
|
||||
ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) {
|
||||
|
@@ -10,14 +10,8 @@
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class ResourceFolder;
|
||||
}
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
}
|
||||
class wxPaintDC;
|
||||
@@ -48,7 +42,7 @@ class GD_CORE_API Resource {
|
||||
*/
|
||||
virtual void SetKind(const gd::String& newKind) { kind = newKind; }
|
||||
|
||||
/** \brief Return the name of the object.
|
||||
/** \brief Return the kind of the resource.
|
||||
*/
|
||||
virtual const gd::String& GetKind() const { return kind; }
|
||||
|
||||
@@ -91,6 +85,18 @@ class GD_CORE_API Resource {
|
||||
*/
|
||||
gd::String GetAbsoluteFile(const gd::Project& game) const;
|
||||
|
||||
/**
|
||||
* \brief Set the metadata (any string) associated to the resource.
|
||||
* \note Can be used by external editors to store extra information, for
|
||||
* example the configuration used to produce a sound.
|
||||
*/
|
||||
virtual void SetMetadata(const gd::String& metadata_) { metadata = metadata_; }
|
||||
|
||||
/**
|
||||
* \brief Return the (optional) metadata associated to the resource
|
||||
*/
|
||||
virtual const gd::String& GetMetadata() const { return metadata; }
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
/**
|
||||
* \brief Called when the resource must be rendered in a preview panel.
|
||||
@@ -150,6 +156,7 @@ class GD_CORE_API Resource {
|
||||
private:
|
||||
gd::String kind;
|
||||
gd::String name;
|
||||
gd::String metadata;
|
||||
bool userAdded; ///< True if the resource was added by the user, and not
|
||||
///< automatically by GDevelop.
|
||||
|
||||
@@ -255,6 +262,34 @@ class GD_CORE_API AudioResource : public Resource {
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describe a font file used by a project.
|
||||
*
|
||||
* \see Resource
|
||||
* \ingroup ResourcesManagement
|
||||
*/
|
||||
class GD_CORE_API FontResource : public Resource {
|
||||
public:
|
||||
FontResource() : Resource() { SetKind("font"); };
|
||||
virtual ~FontResource(){};
|
||||
virtual FontResource* Clone() const override {
|
||||
return new FontResource(*this);
|
||||
}
|
||||
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
gd::String file;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Inventory all resources used by a project
|
||||
*
|
||||
@@ -291,7 +326,7 @@ class GD_CORE_API ResourcesManager {
|
||||
/**
|
||||
* \brief Get a list containing the names of all resources.
|
||||
*/
|
||||
std::vector<gd::String> GetAllResourceNames();
|
||||
std::vector<gd::String> GetAllResourceNames() const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
|
@@ -121,7 +121,7 @@ double SerializerElement::GetDoubleAttribute(const gd::String& name,
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
bool SerializerElement::HasAttribute(const gd::String& name) {
|
||||
bool SerializerElement::HasAttribute(const gd::String& name) const {
|
||||
return attributes.find(name) != attributes.end();
|
||||
}
|
||||
|
||||
|
@@ -164,7 +164,8 @@ class GD_CORE_API SerializerElement {
|
||||
* \brief Return true if the specified attribute exists.
|
||||
* \param name The name of the attribute to find.
|
||||
*/
|
||||
bool HasAttribute(const gd::String &name);
|
||||
bool HasAttribute(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Return all the children of the element.
|
||||
*/
|
||||
|
@@ -87,11 +87,11 @@ TEST_CASE("Resources", "[common][resources]") {
|
||||
|
||||
SECTION("ProjectResourcesAdder") {
|
||||
std::vector<gd::String> uselessResources =
|
||||
gd::ProjectResourcesAdder::GetAllUselessImages(project);
|
||||
gd::ProjectResourcesAdder::GetAllUseless(project, "image");
|
||||
|
||||
REQUIRE(uselessResources.size() == 2);
|
||||
|
||||
gd::ProjectResourcesAdder::RemoveAllUselessImages(project);
|
||||
gd::ProjectResourcesAdder::RemoveAllUseless(project, "image");
|
||||
std::vector<gd::String> remainingResources =
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
REQUIRE(remainingResources.size() == 2);
|
||||
|
361
Extensions/AdMob/JsExtension.js
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* This is a declaration of an extension for GDevelop 5.
|
||||
*
|
||||
* ℹ️ Run `node import-GDJS-Runtime.js` (in newIDE/app/scripts) if you make any change
|
||||
* to this extension file or to any other *.js file that you reference inside.
|
||||
*
|
||||
* The file must be named "JsExtension.js", otherwise GDevelop won't load it.
|
||||
* ⚠️ If you make a change and the extension is not loaded, open the developer console
|
||||
* and search for any errors.
|
||||
*
|
||||
* More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md
|
||||
*/
|
||||
module.exports = {
|
||||
createExtension: function(t, gd) {
|
||||
const extension = new gd.PlatformExtension();
|
||||
extension.setExtensionInformation(
|
||||
'AdMob',
|
||||
t('AdMob'),
|
||||
t(
|
||||
'Allow the game to display AdMob banner, interstitial and reward video ads'
|
||||
),
|
||||
'Franco Maciel',
|
||||
'MIT'
|
||||
);
|
||||
|
||||
// Banner
|
||||
extension
|
||||
.addCondition(
|
||||
'BannerLoading',
|
||||
t('Banner loading'),
|
||||
t('Check if a banner is currently loading.'),
|
||||
t('Banner is loading'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isBannerLoading');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'BannerReady',
|
||||
t('Banner ready'),
|
||||
t('Check if a banner is ready to be displayed.'),
|
||||
t('Banner is ready'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isBannerReady');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'BannerShowing',
|
||||
t('Banner showing'),
|
||||
t('Check if there is a banner being displayed.'),
|
||||
t('Banner is showing'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isBannerShowing');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'BannerExists',
|
||||
t('Banner exists'),
|
||||
t('Check if there is a banner in memory (visible or hidden).'),
|
||||
t('Banner exists'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.existBanner');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadBanner',
|
||||
t('Load banner'),
|
||||
t(
|
||||
'Start loading a banner, you can display it automatically when finish loading.\nIf test mode is set to true a test banner will be displayed.'
|
||||
),
|
||||
t(
|
||||
'Load banner (at top: _PARAM2_, overlap: _PARAM3_, show on load: _PARAM4_, test mode: _PARAM5_)'
|
||||
),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.addParameter('string', t('Android banner ID'), '', false)
|
||||
.addParameter('string', t('iOS banner ID'), '', false)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
t('Display at top? (bottom otherwise)'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setDefaultValue('false')
|
||||
.addParameter('yesorno', t('Overlap webview?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('yesorno', t('Display on load complete?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('yesorno', t('Test mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.loadBanner');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ShowBanner',
|
||||
t('Show banner'),
|
||||
t('Show the banner, will work only when the banner is fully loaded.'),
|
||||
t('Show banner'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.showBanner');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'HideBanner',
|
||||
t('Hide banner'),
|
||||
t(
|
||||
'Hide the banner. You can show it again with the corresponding action.'
|
||||
),
|
||||
t('Hide banner'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.hideBanner');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'RemoveBanner',
|
||||
t('Remove banner'),
|
||||
t(
|
||||
'Remove the banner. You have to load another banner to show it again.'
|
||||
),
|
||||
t('Remove banner'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.removeBanner');
|
||||
|
||||
// Interstitial
|
||||
extension
|
||||
.addCondition(
|
||||
'InterstitialLoading',
|
||||
t('Interstitial loading'),
|
||||
t('Check if an interstitial is currently loading.'),
|
||||
t('Interstitial is loading'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isInterstitialLoading');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'InterstitialReady',
|
||||
t('Interstitial ready'),
|
||||
t('Check if an interstitial is ready to be displayed.'),
|
||||
t('Interstitial is ready'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isInterstitialReady');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'InterstitialShowing',
|
||||
t('Interstitial showing'),
|
||||
t('Check if there is an interstitial being displayed.'),
|
||||
t('Interstitial is showing'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isInterstitialShowing');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadInterstitial',
|
||||
t('Load interstitial'),
|
||||
t(
|
||||
'Start loading an interstitial, you can display it automatically when finish loading.\nIf test mode is set to true a test interstitial will be displayed.'
|
||||
),
|
||||
t('Load interstitial (show on load: _PARAM2_, test mode: _PARAM3_)'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.addParameter('string', t('Android interstitial ID'), '', false)
|
||||
.addParameter('string', t('iOS interstitial ID'), '', false)
|
||||
.addParameter('yesorno', t('Display on load complete?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('yesorno', t('Test mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.loadInterstitial');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ShowInterstitial',
|
||||
t('Show interstitial'),
|
||||
t(
|
||||
'Show the interstitial, will work only when the interstitial is fully loaded.'
|
||||
),
|
||||
t('Show interstitial'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.showInterstitial');
|
||||
|
||||
// Reward video
|
||||
extension
|
||||
.addCondition(
|
||||
'VideoLoading',
|
||||
t('Video loading'),
|
||||
t('Check if a reward video is currently loading.'),
|
||||
t('Reward video is loading'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isVideoLoading');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'VideoReady',
|
||||
t('Video ready'),
|
||||
t('Check if a reward video is ready to be displayed.'),
|
||||
t('Reward video is ready'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isVideoReady');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'VideoShowing',
|
||||
t('Video showing'),
|
||||
t('Check if there is a reward video being displayed.'),
|
||||
t('Reward video is showing'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.isVideoShowing');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'VideoReward',
|
||||
t('Video reward'),
|
||||
t(
|
||||
'Check if there is a video reward.\nYou can mark it as non-claimed yet, so you can check this reward in other events.'
|
||||
),
|
||||
t('Video reward given'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.addParameter('yesorno', t('Mark as claimed'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.existVideoReward');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'LoadVideo',
|
||||
t('Load video'),
|
||||
t(
|
||||
'Start loading a reward video, you can display it automatically when finish loading.\nIf test mode is set to true a test video will be displayed.'
|
||||
),
|
||||
t('Load reward video (show on load: _PARAM2_, test mode: _PARAM3_)'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.addParameter('string', t('Android reward video ID'), '', false)
|
||||
.addParameter('string', t('iOS reward video ID'), '', false)
|
||||
.addParameter('yesorno', t('Display on load complete?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.addParameter('yesorno', t('Test mode?'), '', false)
|
||||
.setDefaultValue('true')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.loadVideo');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ShowVideo',
|
||||
t('Show video'),
|
||||
t(
|
||||
'Show the reward video, will work only when the video is fully loaded.'
|
||||
),
|
||||
t('Show reward video'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.showVideo');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ClaimReward',
|
||||
t('Claim reward'),
|
||||
t('Mark the video reward as claimed.'),
|
||||
t('Claim video reward'),
|
||||
t('AdMob'),
|
||||
'JsPlatform/Extensions/admobicon24.png',
|
||||
'JsPlatform/Extensions/admobicon16.png'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/AdMob/admobtools.js')
|
||||
.setFunctionName('gdjs.adMob.claimVideoReward');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function(gd, extension) {
|
||||
return [];
|
||||
},
|
||||
};
|
352
Extensions/AdMob/admobtools.js
Normal file
@@ -0,0 +1,352 @@
|
||||
/**
|
||||
* @memberof gdjs
|
||||
* @class adMob
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
gdjs.adMob = {
|
||||
// Banner
|
||||
bannerLoading: false,
|
||||
bannerReady: false,
|
||||
bannerShowing: false,
|
||||
bannerExists: false,
|
||||
bannerAutoshow: false, // Needed because the banner event listeners bug
|
||||
// Interstitial
|
||||
interstitialLoading: false,
|
||||
interstitialReady: false,
|
||||
interstitialShowing: false,
|
||||
// Reward video
|
||||
videoLoading: false,
|
||||
videoReady: false,
|
||||
videoShowing: false,
|
||||
videoReward: false,
|
||||
};
|
||||
|
||||
gdjs.adMob._getPlatformName = function() {
|
||||
if (/(android)/i.test(navigator.userAgent)) {
|
||||
return 'android';
|
||||
} else if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
|
||||
return 'ios';
|
||||
} else {
|
||||
return 'windowsPhone';
|
||||
}
|
||||
};
|
||||
|
||||
// Banner
|
||||
gdjs.adMob.isBannerLoading = function() {
|
||||
return gdjs.adMob.bannerLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isBannerReady = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isBannerShowing = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.existBanner = function() {
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerAutoshow && gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
return gdjs.adMob.bannerExists;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadBanner = function(
|
||||
androidID,
|
||||
iosID,
|
||||
atTop,
|
||||
overlap,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.bannerLoading ||
|
||||
gdjs.adMob.bannerReady ||
|
||||
gdjs.adMob.bannerExists
|
||||
)
|
||||
return;
|
||||
|
||||
admob.banner.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
bannerAtTop: atTop,
|
||||
overlap: overlap,
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.banner.prepare();
|
||||
|
||||
gdjs.adMob.bannerLoading = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerAutoshow = displayOnLoading;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
gdjs.adMob.bannerExists = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
// This block is needed because the banner event listeners bug
|
||||
if (gdjs.adMob.bannerReady) {
|
||||
gdjs.adMob.bannerReady = false;
|
||||
gdjs.adMob.bannerExists = true;
|
||||
}
|
||||
|
||||
if (gdjs.adMob.bannerExists) gdjs.adMob.bannerShowing = true;
|
||||
|
||||
admob.banner.show();
|
||||
};
|
||||
|
||||
gdjs.adMob.hideBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (gdjs.adMob.bannerExists) gdjs.adMob.bannerShowing = false;
|
||||
|
||||
admob.banner.hide();
|
||||
};
|
||||
|
||||
gdjs.adMob.removeBanner = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
// These lines are needed because the banner event listeners bug
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
|
||||
admob.banner.remove();
|
||||
};
|
||||
|
||||
// Interstitial
|
||||
gdjs.adMob.isInterstitialLoading = function() {
|
||||
return gdjs.adMob.interstitialLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isInterstitialReady = function() {
|
||||
return gdjs.adMob.interstitialReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isInterstitialShowing = function() {
|
||||
return gdjs.adMob.interstitialShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadInterstitial = function(
|
||||
androidID,
|
||||
iosID,
|
||||
displayOnLoading,
|
||||
testMode
|
||||
) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.interstitialLoading ||
|
||||
gdjs.adMob.interstitialReady ||
|
||||
gdjs.adMob.interstitialShowing
|
||||
)
|
||||
return;
|
||||
|
||||
admob.interstitial.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.interstitial.prepare();
|
||||
|
||||
gdjs.adMob.interstitialLoading = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showInterstitial = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
admob.interstitial.show();
|
||||
};
|
||||
|
||||
// Reward video
|
||||
gdjs.adMob.isVideoLoading = function() {
|
||||
return gdjs.adMob.videoLoading;
|
||||
};
|
||||
|
||||
gdjs.adMob.isVideoReady = function() {
|
||||
return gdjs.adMob.videoReady;
|
||||
};
|
||||
|
||||
gdjs.adMob.isVideoShowing = function() {
|
||||
return gdjs.adMob.videoShowing;
|
||||
};
|
||||
|
||||
gdjs.adMob.existVideoReward = function(markAsClaimed) {
|
||||
var reward = gdjs.adMob.videoReward;
|
||||
if (markAsClaimed) gdjs.adMob.videoReward = false;
|
||||
|
||||
return reward;
|
||||
};
|
||||
|
||||
gdjs.adMob.loadVideo = function(androidID, iosID, displayOnLoading, testMode) {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
if (
|
||||
gdjs.adMob.videoLoading ||
|
||||
gdjs.adMob.videoReady ||
|
||||
gdjs.adMob.videoShowing
|
||||
)
|
||||
return;
|
||||
|
||||
admob.rewardvideo.config({
|
||||
id: gdjs.adMob._getPlatformName() === 'android' ? androidID : iosID, // Support Android & iOS
|
||||
autoShow: displayOnLoading,
|
||||
isTesting: testMode,
|
||||
});
|
||||
admob.rewardvideo.prepare();
|
||||
|
||||
gdjs.adMob.videoLoading = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
};
|
||||
|
||||
gdjs.adMob.showVideo = function() {
|
||||
if (typeof admob === 'undefined') return;
|
||||
|
||||
admob.rewardvideo.show();
|
||||
};
|
||||
|
||||
gdjs.adMob.claimVideoReward = function() {
|
||||
gdjs.adMob.videoReward = false;
|
||||
};
|
||||
|
||||
// Banner event listeners
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.bannerReady = true;
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.banner.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.bannerLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// BUG: These two never get called
|
||||
/*
|
||||
document.addEventListener(
|
||||
"admob.banner.events.OPEN",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = true;
|
||||
gdjs.adMob.bannerShowing = true;
|
||||
gdjs.adMob.bannerReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
"admob.banner.events.CLOSE",
|
||||
function() {
|
||||
gdjs.adMob.bannerExists = false;
|
||||
gdjs.adMob.bannerShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
*/
|
||||
|
||||
// Interstitial event listeners
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.interstitialReady = true;
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.interstitialLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.OPEN',
|
||||
function() {
|
||||
gdjs.adMob.interstitialShowing = true;
|
||||
gdjs.adMob.interstitialReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.interstitial.events.CLOSE',
|
||||
function() {
|
||||
gdjs.adMob.interstitialShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Reward video event listeners
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD',
|
||||
function() {
|
||||
gdjs.adMob.videoReady = true;
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.LOAD_FAIL',
|
||||
function() {
|
||||
gdjs.adMob.videoLoading = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.OPEN',
|
||||
function() {
|
||||
gdjs.adMob.videoShowing = true;
|
||||
gdjs.adMob.videoReady = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.CLOSE',
|
||||
function() {
|
||||
gdjs.adMob.videoShowing = false;
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
document.addEventListener(
|
||||
'admob.rewardvideo.events.REWARD',
|
||||
function() {
|
||||
gdjs.adMob.videoReward = true;
|
||||
},
|
||||
false
|
||||
);
|
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
|
||||
GDevelop - AdMob Object Extension
|
||||
Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "AdMobObject.h"
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "GDCore/IDE/Dialogs/PropertyDescriptor.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCpp/Runtime/CommonTools.h"
|
||||
#include "GDCpp/Runtime/ImageManager.h"
|
||||
#include "GDCpp/Runtime/Project/InitialInstance.h"
|
||||
#include "GDCpp/Runtime/Project/Object.h"
|
||||
#include "GDCpp/Runtime/Serialization/SerializerElement.h"
|
||||
|
||||
#if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI)
|
||||
#include <wx/bitmap.h>
|
||||
|
||||
sf::Texture AdMobObject::edittimeIconImage;
|
||||
sf::Sprite AdMobObject::edittimeIcon;
|
||||
#endif
|
||||
|
||||
AdMobObject::AdMobObject(gd::String name_)
|
||||
: Object(name_), isTesting(true), overlap(true), showOnStartup(true) {}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> AdMobObject::GetProperties(
|
||||
gd::Project& project) const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Banner ID (Android)")].SetValue(androidBannerId);
|
||||
properties[_("Interstitial ID (Android)")].SetValue(androidInterstitialId);
|
||||
properties[_("Banner ID (iOS)")].SetValue(iosBannerId);
|
||||
properties[_("Interstitial ID (iOS)")].SetValue(iosInterstitialId);
|
||||
properties[_("Testing mode")]
|
||||
.SetValue(isTesting ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
properties[_("Overlap game")]
|
||||
.SetValue(overlap ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
properties[_("Show banner on startup")]
|
||||
.SetValue(showOnStartup ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
properties[_("Banner position")]
|
||||
.SetValue(position == "Bottom" ? _("Bottom of the screen")
|
||||
: _("Top of the screen"))
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("Top of the screen"))
|
||||
.AddExtraInfo(_("Bottom of the screen"));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool AdMobObject::UpdateProperty(const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project) {
|
||||
if (name == _("Banner ID (Android)")) androidBannerId = value;
|
||||
if (name == _("Interstitial ID (Android)")) androidInterstitialId = value;
|
||||
if (name == _("Banner ID (iOS)")) iosBannerId = value;
|
||||
if (name == _("Interstitial ID (iOS)")) iosInterstitialId = value;
|
||||
if (name == _("Testing mode")) isTesting = value == "1";
|
||||
if (name == _("Overlap game")) overlap = value == "1";
|
||||
if (name == _("Show banner on startup")) showOnStartup = value == "1";
|
||||
if (name == _("Banner position"))
|
||||
position = value == _("Top of the screen") ? "Top" : "Bottom";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdMobObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
androidBannerId = element.GetStringAttribute("androidBannerId");
|
||||
androidInterstitialId = element.GetStringAttribute("androidInterstitialId");
|
||||
iosBannerId = element.GetStringAttribute("iosBannerId");
|
||||
iosInterstitialId = element.GetStringAttribute("iosInterstitialId");
|
||||
position = element.GetStringAttribute("position");
|
||||
isTesting = element.GetBoolAttribute("isTesting");
|
||||
overlap = element.GetBoolAttribute("overlap");
|
||||
showOnStartup = element.GetBoolAttribute("showOnStartup");
|
||||
}
|
||||
|
||||
void AdMobObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("androidBannerId", androidBannerId);
|
||||
element.SetAttribute("androidInterstitialId", androidInterstitialId);
|
||||
element.SetAttribute("iosBannerId", iosBannerId);
|
||||
element.SetAttribute("iosInterstitialId", iosInterstitialId);
|
||||
element.SetAttribute("position", position);
|
||||
element.SetAttribute("isTesting", isTesting);
|
||||
element.SetAttribute("overlap", overlap);
|
||||
element.SetAttribute("showOnStartup", showOnStartup);
|
||||
}
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void AdMobObject::DrawInitialInstance(gd::InitialInstance& instance,
|
||||
sf::RenderTarget& renderTarget,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
edittimeIcon.setPosition(instance.GetX(), instance.GetY());
|
||||
renderTarget.draw(edittimeIcon);
|
||||
}
|
||||
|
||||
void AdMobObject::LoadEdittimeIcon() {
|
||||
edittimeIconImage.loadFromFile("JsPlatform/Extensions/admobicon.png");
|
||||
edittimeIcon.setTexture(edittimeIconImage);
|
||||
}
|
||||
|
||||
bool AdMobObject::GenerateThumbnail(const gd::Project& project,
|
||||
wxBitmap& thumbnail) const {
|
||||
thumbnail =
|
||||
wxBitmap("JsPlatform/Extensions/admobicon24.png", wxBITMAP_TYPE_ANY);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
gd::Object* CreateAdMobObject(gd::String name) { return new AdMobObject(name); }
|
@@ -1,73 +0,0 @@
|
||||
/**
|
||||
|
||||
GDevelop - AdMob Object Extension
|
||||
Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ADMOBOBJECT_H
|
||||
#define ADMOBOBJECT_H
|
||||
|
||||
#include "GDCpp/Runtime/Project/Object.h"
|
||||
#include "GDCpp/Runtime/String.h"
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace sf {
|
||||
class Texture;
|
||||
}
|
||||
namespace sf {
|
||||
class Sprite;
|
||||
}
|
||||
class wxBitmap;
|
||||
|
||||
class GD_EXTENSION_API AdMobObject : public gd::Object {
|
||||
public:
|
||||
AdMobObject(gd::String name_);
|
||||
virtual ~AdMobObject(){};
|
||||
virtual std::unique_ptr<gd::Object> Clone() const override {
|
||||
return gd::make_unique<AdMobObject>(*this);
|
||||
}
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
void DrawInitialInstance(gd::InitialInstance& instance,
|
||||
sf::RenderTarget& renderTarget,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) override;
|
||||
bool GenerateThumbnail(const gd::Project& project,
|
||||
wxBitmap& thumbnail) const override;
|
||||
static void LoadEdittimeIcon();
|
||||
#endif
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties(
|
||||
gd::Project& project) const override;
|
||||
bool UpdateProperty(const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project) override;
|
||||
|
||||
private:
|
||||
void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) override;
|
||||
void DoSerializeTo(gd::SerializerElement& element) const override;
|
||||
|
||||
gd::String androidBannerId;
|
||||
gd::String androidInterstitialId;
|
||||
gd::String iosBannerId;
|
||||
gd::String iosInterstitialId;
|
||||
gd::String position; //"Top" or "Bottom"
|
||||
bool isTesting;
|
||||
bool overlap;
|
||||
bool showOnStartup;
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
static sf::Texture edittimeIconImage;
|
||||
static sf::Sprite edittimeIcon;
|
||||
#endif
|
||||
};
|
||||
|
||||
gd::Object* CreateAdMobObject(gd::String name);
|
||||
|
||||
#endif // ADMOBOBJECT_H
|
@@ -1,21 +0,0 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
|
||||
project(AdMobObject)
|
||||
gd_add_extension_includes()
|
||||
|
||||
#Defines
|
||||
###
|
||||
gd_add_extension_definitions(AdMobObject)
|
||||
|
||||
#The targets
|
||||
###
|
||||
include_directories(.)
|
||||
file(GLOB source_files *.cpp *.h)
|
||||
gd_add_clang_utils(AdMobObject "${source_files}")
|
||||
|
||||
gd_add_extension_target(AdMobObject "${source_files}" "JsPlatform")
|
||||
|
||||
#Linker files for the IDE extension
|
||||
###
|
||||
gd_extension_link_libraries(AdMobObject)
|
@@ -1,94 +0,0 @@
|
||||
/**
|
||||
|
||||
GDevelop - AdMob Object Extension
|
||||
Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
#include "AdMobObject.h"
|
||||
|
||||
void DeclareAdMobObjectExtension(gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"AdMobObject",
|
||||
_("AdMob banners and interstitial screens"),
|
||||
_("Display an ads banner and interstitial screens powered by AdMob."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects/admob");
|
||||
|
||||
gd::ObjectMetadata& obj = extension.AddObject<AdMobObject>(
|
||||
"AdMob",
|
||||
_("AdMob banner"),
|
||||
_("Display an ad banner or interstitial screen using AdMob"),
|
||||
"JsPlatform/Extensions/admobicon.png");
|
||||
|
||||
obj.SetHelpUrl("/gdevelop/documentation/manual/built_admob");
|
||||
|
||||
#if !defined(GD_NO_WX_GUI)
|
||||
AdMobObject::LoadEdittimeIcon();
|
||||
#endif
|
||||
|
||||
obj.AddAction("ShowBanner",
|
||||
_("Show banner ad"),
|
||||
_("Show the banner ad"),
|
||||
_("Show the banner ad of _PARAM0_"),
|
||||
_("Banner"),
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
|
||||
obj.AddAction("HideBanner",
|
||||
_("Hide banner ad"),
|
||||
_("Hide the banner ad"),
|
||||
_("Hide the banner ad of _PARAM0_"),
|
||||
_("Banner"),
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
|
||||
obj.AddCondition(
|
||||
"BannerDisplayed",
|
||||
_("Banner is displayed"),
|
||||
_("Return true if the object is currently displaying a banner"),
|
||||
_("_PARAM0_ is displaying a banner"),
|
||||
"",
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
|
||||
obj.AddAction("PreloadInterstitial",
|
||||
_("Preload interstitial screen"),
|
||||
_("Preload the interstitial screen in memory, so that it can "
|
||||
"be shown later.\nYou can use this action at the beginning "
|
||||
"of a level for example."),
|
||||
_("Preload an interstitial screen for _PARAM0_"),
|
||||
_("Interstitial screen"),
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
|
||||
obj.AddAction(
|
||||
"ShowInterstitial",
|
||||
_("Show interstitial screen"),
|
||||
_("Show the interstitial screen.\nIf the interstitial screen has not "
|
||||
"been preloaded, it will be loaded and displayed when ready."),
|
||||
_("Show the interstitial screen of _PARAM0_"),
|
||||
_("Interstitial screen"),
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
|
||||
obj.AddCondition("InterstitialReady",
|
||||
_("Interstitial screen is ready"),
|
||||
_("Return true if the interstitial screen was loaded and is "
|
||||
"ready to be shown."),
|
||||
_("Interstitial screen of _PARAM0_ is ready"),
|
||||
"",
|
||||
"JsPlatform/Extensions/admobicon24.png",
|
||||
"JsPlatform/Extensions/admobicon16.png")
|
||||
.AddParameter("object", _("Object"), "AdMob");
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
/**
|
||||
|
||||
GDevelop - AdMob Object Extension
|
||||
Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
#include "AdMobObject.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
void DeclareAdMobObjectExtension(gd::PlatformExtension& extension);
|
||||
|
||||
/**
|
||||
* \brief This class declares information about the JS extension.
|
||||
*/
|
||||
class AdMobObjectJsExtension : public gd::PlatformExtension {
|
||||
public:
|
||||
/**
|
||||
* Constructor of an extension declares everything the extension contains:
|
||||
* objects, actions, conditions and expressions.
|
||||
*/
|
||||
AdMobObjectJsExtension() {
|
||||
DeclareAdMobObjectExtension(*this);
|
||||
|
||||
GetObjectMetadata("AdMobObject::AdMob")
|
||||
.SetIncludeFile("Extensions/AdMobObject/admobruntimeobject.js");
|
||||
|
||||
GetAllActionsForObject("AdMobObject::AdMob")["AdMobObject::ShowBanner"]
|
||||
.SetFunctionName("showBanner");
|
||||
GetAllActionsForObject("AdMobObject::AdMob")["AdMobObject::HideBanner"]
|
||||
.SetFunctionName("hideBanner");
|
||||
GetAllConditionsForObject(
|
||||
"AdMobObject::AdMob")["AdMobObject::BannerDisplayed"]
|
||||
.SetFunctionName("isBannerDisplayed");
|
||||
GetAllActionsForObject(
|
||||
"AdMobObject::AdMob")["AdMobObject::PreloadInterstitial"]
|
||||
.SetFunctionName("prepareInterstitial");
|
||||
GetAllActionsForObject(
|
||||
"AdMobObject::AdMob")["AdMobObject::ShowInterstitial"]
|
||||
.SetFunctionName("showInterstitial");
|
||||
GetAllConditionsForObject(
|
||||
"AdMobObject::AdMob")["AdMobObject::InterstitialReady"]
|
||||
.SetFunctionName("isInterstitialReady");
|
||||
|
||||
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
|
||||
};
|
||||
};
|
||||
|
||||
#if defined(EMSCRIPTEN)
|
||||
extern "C" gd::PlatformExtension* CreateGDJSAdMobObjectExtension() {
|
||||
return new AdMobObjectJsExtension;
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* Used by GDevelop to create the extension class
|
||||
* -- Do not need to be modified. --
|
||||
*/
|
||||
extern "C" gd::PlatformExtension* GD_EXTENSION_API CreateGDJSExtension() {
|
||||
return new AdMobObjectJsExtension;
|
||||
}
|
||||
#endif
|
||||
#endif
|
@@ -1,160 +0,0 @@
|
||||
/**
|
||||
|
||||
GDevelop - AdMob Object Extension
|
||||
Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
if (typeof AdMob !== "undefined")
|
||||
console.warn("AdMob plugin for Cordova is not installed - no ads will be displayed. Ensure you have installed com.google.cordova.admob or cordova-plugin-admobpro.");
|
||||
|
||||
/**
|
||||
* The AdMobRuntimeObject displays an AdMob ad banner on screen.
|
||||
* This works with Cordova compatible platforms with `cordova-plugin-admobpro` plugin installed.
|
||||
*
|
||||
* @memberof gdjs
|
||||
* @class AdMobRuntimeObject
|
||||
* @extends RuntimeObject
|
||||
* @memberof gdjs
|
||||
*/
|
||||
gdjs.AdMobRuntimeObject = function(runtimeScene, objectData)
|
||||
{
|
||||
gdjs.RuntimeObject.call(this, runtimeScene, objectData);
|
||||
|
||||
this._androidBannerId = objectData.androidBannerId;
|
||||
this._androidInterstitialId = objectData.androidInterstitialId;
|
||||
this._iosBannerId = objectData.iosBannerId;
|
||||
this._iosInterstitialId = objectData.iosInterstitialId;
|
||||
this._isTesting = objectData.isTesting;
|
||||
this._position = objectData.position;
|
||||
this._overlap = objectData.overlap;
|
||||
this._showOnStartup = objectData.showOnStartup;
|
||||
|
||||
this._bannerDisplayed = false;
|
||||
this._interstitialReady = false;
|
||||
|
||||
if (this._showOnStartup)
|
||||
this.createBanner();
|
||||
|
||||
document.addEventListener('onAdPresent', this._onAdPresent.bind(this), false);
|
||||
document.addEventListener('onAdDismiss', this._onAdDismiss.bind(this), false);
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.AdMobRuntimeObject.thisIsARuntimeObjectConstructor = "AdMobObject::AdMob";
|
||||
|
||||
gdjs.AdMobRuntimeObject.getPlatformName = function() {
|
||||
if( /(android)/i.test(navigator.userAgent) ) {
|
||||
return "android";
|
||||
} else if(/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
|
||||
return "ios";
|
||||
} else {
|
||||
return "windowsPhone";
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype._onAdPresent = function(data) {
|
||||
if (data.adType == 'interstitial')
|
||||
this._interstitialReady = false;
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype._onAdDismiss = function(data) {
|
||||
if (data.adType == 'interstitial')
|
||||
this._interstitialReady = false;
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.createBanner = function() {
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
var adName = "_" + gdjs.AdMobRuntimeObject.getPlatformName() + "BannerId";
|
||||
if (!this.hasOwnProperty(adName)) return;
|
||||
var adId = this[adName];
|
||||
|
||||
var position = AdMob.AD_POSITION.TOP_CENTER;
|
||||
if (this._position === "Bottom")
|
||||
position = AdMob.AD_POSITION.BOTTOM_CENTER;
|
||||
|
||||
var that = this;
|
||||
AdMob.createBanner({
|
||||
adId: adId || 'not-specified-xxx', //Avoid a crash by never letting the id empty.
|
||||
position: position,
|
||||
autoShow: true,
|
||||
overlap: this._overlap,
|
||||
isTesting: this._isTesting
|
||||
}, function() {
|
||||
that._bannerDisplayed = true;
|
||||
}, function() {
|
||||
that._bannerDisplayed = false;
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.showBanner = function() {
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
if (!this._bannerDisplayed)
|
||||
this.createBanner();
|
||||
}
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.hideBanner = function() {
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
this._bannerDisplayed = false;
|
||||
AdMob.removeBanner();
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.isBannerDisplayed = function() {
|
||||
return this._bannerDisplayed;
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.showInterstitial = function(runtimeScene) {
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
if (!this._interstitialReady) {
|
||||
this.prepareInterstitial(function() {
|
||||
AdMob.showInterstitial();
|
||||
})
|
||||
} else {
|
||||
AdMob.showInterstitial();
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.prepareInterstitial = function(cb) {
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
var adName = "_" + gdjs.AdMobRuntimeObject.getPlatformName() + "InterstitialId";
|
||||
if (!this.hasOwnProperty(adName)) return;
|
||||
var adId = this[adName];
|
||||
|
||||
var that = this;
|
||||
AdMob.prepareInterstitial({
|
||||
adId: adId || 'not-specified-xxx', //Avoid a crash by never letting the id empty.
|
||||
autoShow: false
|
||||
}, function() {
|
||||
that._interstitialReady = true;
|
||||
cb();
|
||||
}, function() {
|
||||
that._interstitialReady = false;
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.isInterstitialReady = function() {
|
||||
return this._interstitialReady;
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.onDeletedFromScene = function(runtimeScene) {
|
||||
gdjs.RuntimeObject.prototype.onDeletedFromScene.call(this, runtimeScene);
|
||||
if (typeof AdMob === "undefined") return;
|
||||
|
||||
document.removeEventListener('onAdPresent', this._onAdPresent, false);
|
||||
document.removeEventListener('onAdDismiss', this._onAdDismiss, false);
|
||||
if (this._bannerDisplayed) this.hideBanner();
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.setLayer = function(layer) {
|
||||
// No renderable object
|
||||
};
|
||||
|
||||
gdjs.AdMobRuntimeObject.prototype.setZOrder = function(z) {
|
||||
// No renderable object
|
||||
};
|
@@ -45,9 +45,6 @@ gdjs.AnchorRuntimeBehavior.prototype.onActivate = function() {
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene) {
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
var game = runtimeScene.getGame();
|
||||
var rendererWidth = game.getRenderer().getCurrentWidth();
|
||||
var rendererHeight = game.getRenderer().getCurrentHeight();
|
||||
@@ -160,3 +157,6 @@ gdjs.AnchorRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
this.owner.setY(topLeftCoord[1] + this.owner.getY() - this.owner.getDrawableY());
|
||||
}
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
};
|
||||
|
@@ -8,7 +8,6 @@ project(GD-Extensions)
|
||||
include(CMakeUtils.txt) #Functions to factor common tasks done in CMakeLists.txt of extensions
|
||||
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(AdMobObject)
|
||||
ADD_SUBDIRECTORY(AnchorBehavior)
|
||||
IF (NOT EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(AdvancedXML)
|
||||
|
@@ -38,10 +38,18 @@ gdjs.DestroyOutsideRuntimeBehavior.prototype.doStepPostEvents = function(runtime
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set an additional border to the camera viewport as a buffer before the object gets destroyed.
|
||||
* @param {number} val Border in pixels.
|
||||
*/
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.setExtraBorder = function(val) {
|
||||
this._extraBorder = val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the additional border of the camera viewport buffer which triggers the destruction of an object.
|
||||
* @return {number} The additional border around the camera viewport in pixels
|
||||
*/
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.getExtraBorder = function() {
|
||||
return this._extraBorder;
|
||||
};
|
||||
|
@@ -29,6 +29,10 @@ gdjs.DraggableRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
this._endDrag();
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.ownerRemovedFromScene = function() {
|
||||
this.onDeActivate();
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype._endDrag = function() {
|
||||
if ( this._dragged && this._mouse ) gdjs.DraggableRuntimeBehavior.mouseDraggingSomething = false;
|
||||
if ( this._dragged && this._touchId !== null ) gdjs.DraggableRuntimeBehavior.touchDraggingSomething[this._touchId] = false;
|
||||
|
@@ -183,6 +183,154 @@ module.exports = {
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.getPlayerEntry");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
"AreAdsSupported",
|
||||
t("Check if ads are supported"),
|
||||
t("Check if showind ads is supported on this device (only mobile phones can show ads)"),
|
||||
t("Ads can be shown on this device"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.areAdsSupported");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
"IsInterstitialAdReady",
|
||||
t("Is the interstitial ad ready"),
|
||||
t("Check if the interstitial ad requested from Facebook is loaded and ready to be shown."),
|
||||
t("The interstitial ad is loaded and ready to be shown"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.isInterstitialAdReady");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
"LoadInterstitialAd",
|
||||
t("Load and prepare an interstitial ad"),
|
||||
t("Request and load an interstitial ad from Facebook, so that it is ready to be shown."),
|
||||
t("Request and load an interstitial ad from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.addParameter(
|
||||
"string",
|
||||
t("The Ad Placement id (can be found while setting up the ad on Facebook)"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
"scenevar",
|
||||
t("Variable where to error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.loadInterstitialAd");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
"ShowInterstitialAd",
|
||||
t("Show the loaded interstitial ad"),
|
||||
t("Show the interstitial ad previously loaded in memory. This won't work if you did not load the interstitial before."),
|
||||
t("Show the interstitial ad previously loaded in memory (if any error, store it in _PARAM0_)"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.addParameter(
|
||||
"scenevar",
|
||||
t("Variable where to error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.showInterstitialAd");
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
"IsRewardedVideoReady",
|
||||
t("Is the rewarded video ready"),
|
||||
t("Check if the rewarded video requested from Facebook is loaded and ready to be shown."),
|
||||
t("The rewarded video is loaded and ready to be shown"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.isRewardedVideoReady");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
"LoadRewardedVideo",
|
||||
t("Load and prepare a rewarded video"),
|
||||
t("Request and load a rewarded video from Facebook, so that it is ready to be shown."),
|
||||
t("Request and load a rewarded video from Facebook (ad placement id: _PARAM0_, error in _PARAM1_)"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.addParameter(
|
||||
"string",
|
||||
t("The Ad Placement id (can be found while setting up the ad on Facebook)"),
|
||||
"",
|
||||
false
|
||||
)
|
||||
.addParameter(
|
||||
"scenevar",
|
||||
t("Variable where to error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.loadRewardedVideo");
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
"ShowRewardedVideo",
|
||||
t("Show the loaded rewarded video"),
|
||||
t("Show the rewarded video previously loaded in memory. This won't work if you did not load the video before."),
|
||||
t("Show the rewarded video previously loaded in memory (if any error, store it in _PARAM0_)"),
|
||||
t("Facebook Instant Games/Ads"),
|
||||
"JsPlatform/Extensions/facebookicon24.png",
|
||||
"JsPlatform/Extensions/facebookicon16.png"
|
||||
)
|
||||
.addParameter(
|
||||
"scenevar",
|
||||
t("Variable where to error message (optional, if an error occurs)"),
|
||||
"",
|
||||
true
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
"Extensions/FacebookInstantGames/facebookinstantgamestools.js"
|
||||
)
|
||||
.setFunctionName("gdjs.evtTools.facebookInstantGames.showRewardedVideo");
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
"PlayerId",
|
||||
|
@@ -4,7 +4,24 @@
|
||||
* @static
|
||||
* @private
|
||||
*/
|
||||
gdjs.evtTools.facebookInstantGames = {};
|
||||
gdjs.evtTools.facebookInstantGames = {
|
||||
_preloadedInterstitial: null,
|
||||
_preloadedInterstitialLoading: false,
|
||||
_preloadedInterstitialLoaded: false,
|
||||
_preloadedRewardedVideo: null,
|
||||
_preloadedRewardedVideoLoading: false,
|
||||
_preloadedRewardedVideoLoaded: false
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.areAdsSupported = function() {
|
||||
if (typeof FBInstant === "undefined") return false;
|
||||
|
||||
var supportedAPIs = FBInstant.getSupportedAPIs();
|
||||
return (
|
||||
supportedAPIs.indexOf("getInterstitialAdAsync") !== -1 &&
|
||||
supportedAPIs.indexOf("getRewardedVideoAsync") !== -1
|
||||
);
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.getPlayerId = function() {
|
||||
if (typeof FBInstant === "undefined") return "";
|
||||
@@ -102,7 +119,9 @@ gdjs.evtTools.facebookInstantGames.getPlayerEntry = function(
|
||||
})
|
||||
.then(function(entry) {
|
||||
rankVariable.setNumber(entry.getRank() === null ? -1 : entry.getRank());
|
||||
scoreVariable.setNumber(entry.getScore() === null ? -1 : entry.getScore());
|
||||
scoreVariable.setNumber(
|
||||
entry.getScore() === null ? -1 : entry.getScore()
|
||||
);
|
||||
gdjs.evtTools.network.jsonToVariableStructure(
|
||||
entry.getExtraData(),
|
||||
extraDataVariable
|
||||
@@ -113,9 +132,123 @@ gdjs.evtTools.facebookInstantGames.getPlayerEntry = function(
|
||||
});
|
||||
};
|
||||
|
||||
if (typeof FBInstant === "undefined" && typeof window !== "undefined") {
|
||||
console.log("Creating a mocked version of Facebook Instant Games");
|
||||
gdjs.evtTools.facebookInstantGames.loadInterstitialAd = function(
|
||||
adPlacementId,
|
||||
errorVariable
|
||||
) {
|
||||
if (typeof FBInstant === "undefined") return;
|
||||
|
||||
if (
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading ||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded
|
||||
)
|
||||
return;
|
||||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = true;
|
||||
FBInstant.getInterstitialAdAsync(adPlacementId)
|
||||
.then(function(interstitial) {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitial = interstitial;
|
||||
return interstitial.loadAsync();
|
||||
})
|
||||
.then(function() {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = false;
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = true;
|
||||
console.info("Facebook Instant Games interstitial preloaded.");
|
||||
})
|
||||
.catch(function(err) {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = false;
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
|
||||
console.error("Interstitial failed to preload: " + err.message);
|
||||
errorVariable.setString(error.message || "Unknown error");
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.showInterstitialAd = function(
|
||||
errorVariable
|
||||
) {
|
||||
if (typeof FBInstant === "undefined") return;
|
||||
|
||||
if (!gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded) return;
|
||||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitial
|
||||
.showAsync()
|
||||
.then(function() {
|
||||
console.info("Facebook Instant Games interstitial shown.");
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Interstitial failed to show: " + err.message);
|
||||
errorVariable.setString(error.message || "Unknown error");
|
||||
})
|
||||
.then(function() {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.isInterstitialAdReady = function() {
|
||||
return gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded;
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.loadRewardedVideo = function(
|
||||
adPlacementId,
|
||||
errorVariable
|
||||
) {
|
||||
if (typeof FBInstant === "undefined") return;
|
||||
|
||||
if (
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading ||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded
|
||||
)
|
||||
return;
|
||||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = true;
|
||||
FBInstant.getRewardedVideoAsync(adPlacementId)
|
||||
.then(function(rewardedVideo) {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideo = rewardedVideo;
|
||||
return rewardedVideo.loadAsync();
|
||||
})
|
||||
.then(function() {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = false;
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = true;
|
||||
console.info("Facebook Instant Games rewarded video preloaded.");
|
||||
})
|
||||
.catch(function(err) {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = false;
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
|
||||
console.error("Rewarded video failed to preload: " + err.message);
|
||||
errorVariable.setString(error.message || "Unknown error");
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.showRewardedVideo = function(errorVariable) {
|
||||
if (typeof FBInstant === "undefined") return;
|
||||
|
||||
if (!gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded) return;
|
||||
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideo
|
||||
.showAsync()
|
||||
.then(function() {
|
||||
console.info("Facebook Instant Games rewarded video shown.");
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.error("Rewarded video failed to show: " + err.message);
|
||||
errorVariable.setString(error.message || "Unknown error");
|
||||
})
|
||||
.then(function() {
|
||||
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
|
||||
});
|
||||
};
|
||||
|
||||
gdjs.evtTools.facebookInstantGames.isRewardedVideoReady = function() {
|
||||
return gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded;
|
||||
};
|
||||
|
||||
if (typeof FBInstant === "undefined" && typeof window !== "undefined") {
|
||||
console.log("Creating a mocked version of Facebook Instant Games.");
|
||||
|
||||
/**
|
||||
* A mocked Leaderboard, part of the mock of FBInstant.
|
||||
* @class MockedLeaderboard
|
||||
*/
|
||||
function MockedLeaderboard() {
|
||||
this._playerScore = null;
|
||||
this._playerRank = null;
|
||||
@@ -147,6 +280,49 @@ if (typeof FBInstant === "undefined" && typeof window !== "undefined") {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* A mocked RewardedVideo, part of the mock of FBInstant.
|
||||
* @class RewardedVideo
|
||||
*/
|
||||
function MockedRewardedVideo() {
|
||||
this._isLoaded = false;
|
||||
}
|
||||
MockedRewardedVideo.prototype.loadAsync = function() {
|
||||
this._isLoaded = true;
|
||||
return Promise.resolve();
|
||||
};
|
||||
MockedRewardedVideo.prototype.showAsync = function() {
|
||||
if (this._isLoaded) {
|
||||
console.info(
|
||||
"In a real Instant Game, a video reward should have been shown to the user."
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("Rewarded video is not loaded."));
|
||||
};
|
||||
|
||||
/**
|
||||
* A mocked MockedInterstitial, part of the mock of FBInstant.
|
||||
* @class MockedInterstitial
|
||||
*/
|
||||
function MockedInterstitial() {
|
||||
this._isLoaded = false;
|
||||
}
|
||||
MockedInterstitial.prototype.loadAsync = function() {
|
||||
this._isLoaded = true;
|
||||
return Promise.resolve();
|
||||
};
|
||||
MockedInterstitial.prototype.showAsync = function() {
|
||||
if (this._isLoaded) {
|
||||
console.info(
|
||||
"In a real Instant Game, an interstitial should have been shown to the user."
|
||||
);
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error("Interstitial is not loaded."));
|
||||
};
|
||||
|
||||
var supportedAPIs = [];
|
||||
var FBInstantMock = {
|
||||
_mockedPlayerData: {},
|
||||
_mockedLeaderboards: {},
|
||||
@@ -176,8 +352,30 @@ if (typeof FBInstant === "undefined" && typeof window !== "undefined") {
|
||||
new MockedLeaderboard();
|
||||
resolve(FBInstantMock._mockedLeaderboards[leaderboardName]);
|
||||
});
|
||||
},
|
||||
getInterstitialAdAsync: function() {
|
||||
return Promise.resolve(new MockedInterstitial());
|
||||
},
|
||||
getRewardedVideoAsync: function() {
|
||||
return Promise.resolve(new MockedRewardedVideo());
|
||||
},
|
||||
getSupportedAPIs: function() {
|
||||
return supportedAPIs;
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve the name of the supported APIs in our mock.
|
||||
for (var property in FBInstantMock) {
|
||||
if (typeof FBInstantMock[property] == "object") {
|
||||
for (var subProperty in FBInstantMock[property]) {
|
||||
if (typeof FBInstantMock[property][subProperty] == "function") {
|
||||
supportedAPIs.push(property + "." + subProperty);
|
||||
}
|
||||
}
|
||||
} else if (typeof FBInstantMock[property] == "function") {
|
||||
supportedAPIs.push(property);
|
||||
}
|
||||
}
|
||||
|
||||
window.FBInstant = FBInstantMock;
|
||||
}
|
||||
|
@@ -59,38 +59,71 @@ gdjs.PanelSpriteRuntimeObject.prototype.extraInitializationFromInitialInstance =
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the x position of the panel sprite.
|
||||
* @param {number} x The new x position in pixels.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setX = function(x) {
|
||||
gdjs.RuntimeObject.prototype.setX.call(this, x);
|
||||
this._renderer.updatePosition();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the y position of the panel sprite.
|
||||
* @param {number} y The new y position in pixels.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setY = function(y) {
|
||||
gdjs.RuntimeObject.prototype.setY.call(this, y);
|
||||
this._renderer.updatePosition();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the texture of the panel sprite.
|
||||
* @param {string} textureName The name of the texture.
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The scene the object lives in.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setTexture = function(textureName, runtimeScene) {
|
||||
this._renderer.setTexture(textureName, runtimeScene);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the angle of the panel sprite.
|
||||
* @param {number} angle The new angle in degrees.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setAngle = function(angle) {
|
||||
gdjs.RuntimeObject.prototype.setAngle.call(this, angle);
|
||||
this._renderer.updateAngle();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the width of the panel sprite in pixels
|
||||
* @return {number} The width in pixels
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.getWidth = function() {
|
||||
return this._width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the height of the panel sprite in pixels
|
||||
* @return {number} The height in pixels
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.getHeight = function() {
|
||||
return this._height;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the width of the panel sprite.
|
||||
* @param {number} width The new width in pixels.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setWidth = function(width) {
|
||||
this._width = width;
|
||||
this._renderer.updateWidth();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the height of the panel sprite.
|
||||
* @param {number} height The new height in pixels.
|
||||
*/
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.setHeight = function(height) {
|
||||
this._height = height;
|
||||
this._renderer.updateHeight();
|
||||
|
@@ -27,12 +27,13 @@ gdjs.ParticleEmitterObjectCocosRenderer = function(runtimeScene, runtimeObject,
|
||||
}
|
||||
else{
|
||||
if(objectData.textureParticleName){
|
||||
// Read the comment at gdjs.ParticleEmitterObjectCocosRenderer.prototype.setTexture
|
||||
var imageManager = runtimeScene.getGame().getImageManager();
|
||||
var sprite = new cc.Sprite(imageManager.getTexture(objectData.textureParticleName));
|
||||
this.originalSize = Math.max(sprite.width, sprite.height);
|
||||
sprite.setPosition( this.originalSize/2.0, this.originalSize/2.0);
|
||||
sprite.setPosition(this.originalSize/2.0, this.originalSize/2.0);
|
||||
drawer.addChild(sprite);
|
||||
renderTexture = new cc.RenderTexture( this.originalSize, this.originalSize);
|
||||
renderTexture = new cc.RenderTexture(this.originalSize, this.originalSize);
|
||||
}
|
||||
else{
|
||||
drawer.drawRect(cc.p((this.originalSize - objectData.rendererParam1)/2.0,
|
||||
@@ -163,17 +164,13 @@ gdjs.ParticleEmitterObjectCocosRenderer = function(runtimeScene, runtimeObject,
|
||||
plist.finishParticleSizeVariance = plist.startParticleSizeVariance;
|
||||
}
|
||||
|
||||
if(objectData.angleParam === "Mutable"){
|
||||
plist.rotationStart = objectData.particleAngle1 + (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationEnd = objectData.particleAngle2 + (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationStartVariance = Math.abs(objectData.particleAngleRandomness2 - objectData.particleAngleRandomness1)/2.0;
|
||||
plist.rotationEndVariance = plist.rotationStartVariance;
|
||||
}
|
||||
else{
|
||||
plist.rotationStart = plist.rotationEnd = (objectData.particleAngleRandomness1 + objectData.particleAngleRandomness2)/2.0;
|
||||
plist.rotationStartVariance = Math.abs(objectData.particleAngleRandomness2 - objectData.particleAngleRandomness1)/2.0;
|
||||
plist.rotationEndVariance = plist.rotationStartVariance;
|
||||
}
|
||||
var mediumLifetime = (objectData.particleLifeTimeMin + objectData.particleLifeTimeMax)/2.0;
|
||||
plist.rotationStart = 0.0;
|
||||
plist.rotationStartVariance = 0.0;
|
||||
plist.rotationEnd = (objectData.particleAngle1 + objectData.particleAngle2)/2.0 * mediumLifetime;
|
||||
plist.rotationEndVariance = (Math.max(objectData.particleAngle1, objectData.particleAngle2) -
|
||||
Math.min(objectData.particleAngle1, objectData.particleAngle2)) *
|
||||
mediumLifetime / 2.0;
|
||||
|
||||
this.renderer = new cc.ParticleSystem(plist);
|
||||
this.renderer.setTexture(texture);
|
||||
@@ -273,7 +270,23 @@ gdjs.ParticleEmitterObjectCocosRenderer.prototype.isTextureValid = function(text
|
||||
gdjs.ParticleEmitterObjectCocosRenderer.prototype.setTexture = function(texture, runtimeScene){
|
||||
var texture = runtimeScene.getGame().getImageManager().getTexture(texture);
|
||||
if(texture._textureLoaded){
|
||||
this.renderer.setTexture(texture);
|
||||
if(texture.width === texture.height){
|
||||
this.originalSize = texture.width;
|
||||
this.renderer.setTexture(texture);
|
||||
}
|
||||
// Cocos particles are always square, so if the new texture is not squared we have to
|
||||
// render it over a squared renderTexture object, this way we keep the original
|
||||
// texture's aspect ratio
|
||||
else{
|
||||
var sprite = new cc.Sprite(texture);
|
||||
this.originalSize = Math.max(sprite.width, sprite.height);
|
||||
sprite.setPosition(this.originalSize/2.0, this.originalSize/2.0);
|
||||
var renderTexture = new cc.RenderTexture(this.originalSize, this.originalSize);
|
||||
renderTexture.begin();
|
||||
sprite.visit();
|
||||
renderTexture.end();
|
||||
this.renderer.setTexture(renderTexture.getSprite().getTexture());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -132,16 +132,9 @@ gdjs.ParticleEmitterObjectPixiRenderer = function(runtimeScene, runtimeObject, o
|
||||
max: objectData.emitterAngleB };
|
||||
}
|
||||
|
||||
if(objectData.angleParam === "Mutable"){
|
||||
var mediumLifetime = (objectData.particleLifeTimeMin + objectData.particleLifeTimeMax)/2;
|
||||
config.rotationSpeed = { min: objectData.particleAngle1/mediumLifetime,
|
||||
max: objectData.particleAngle2/mediumLifetime };
|
||||
}
|
||||
else{
|
||||
config.startRotation = { min: objectData.particleAngle1,
|
||||
max: objectData.particleAngle2 };
|
||||
config.rotationSpeed = { min: 0, max: 0 };
|
||||
}
|
||||
var mediumLifetime = (objectData.particleLifeTimeMin + objectData.particleLifeTimeMax)/2.0;
|
||||
config.rotationSpeed = { min: objectData.particleAngle1/mediumLifetime,
|
||||
max: objectData.particleAngle2/mediumLifetime };
|
||||
|
||||
config.blendMode = objectData.additive ? "ADD" : "NORMAL";
|
||||
|
||||
|
@@ -152,10 +152,6 @@ gdjs.PlatformRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene)
|
||||
gdjs.PlatformRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
};
|
||||
|
||||
gdjs.PlatformRuntimeBehavior.prototype.getAABB = function(){
|
||||
return this.owner.getAABB();
|
||||
};
|
||||
|
||||
gdjs.PlatformRuntimeBehavior.prototype.onActivate = function() {
|
||||
if (this._registeredInManager) return;
|
||||
|
||||
|
@@ -41,6 +41,10 @@ gdjs.ShapePainterRuntimeObject.prototype.stepBehaviorsPreEvents = function(runti
|
||||
gdjs.RuntimeObject.prototype.stepBehaviorsPreEvents.call(this, runtimeScene);
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype.getVisibilityAABB = function() {
|
||||
return this._absoluteCoordinates ? null : this.getAABB();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype.drawRectangle = function(x1, y1, x2, y2) {
|
||||
this._renderer.drawRectangle(x1, y1, x2, y2);
|
||||
};
|
||||
@@ -95,12 +99,16 @@ gdjs.ShapePainterRuntimeObject.prototype.getOutlineOpacity = function() {
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype.setX = function(x) {
|
||||
this.x = x;
|
||||
if ( x === this.x ) return;
|
||||
|
||||
gdjs.RuntimeObject.prototype.setX.call(this, x);
|
||||
this._renderer.updateXPosition();
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype.setY = function(y) {
|
||||
this.y = y;
|
||||
if ( y === this.y ) return;
|
||||
|
||||
gdjs.RuntimeObject.prototype.setY.call(this, y);
|
||||
this._renderer.updateYPosition();
|
||||
};
|
||||
|
||||
|
@@ -35,7 +35,7 @@ TextObjectEditor::TextObjectEditor(wxWindow* parent,
|
||||
|
||||
// Update from the text object
|
||||
m_textCtrl->SetValue(object.GetString());
|
||||
m_fontTextCtrl->SetValue(object.GetFontFilename());
|
||||
m_fontTextCtrl->SetValue(object.GetFontName());
|
||||
m_sizeCombobox->SetValue(gd::String::From<float>(object.GetCharacterSize()));
|
||||
textColor =
|
||||
wxColour(object.GetColorR(), object.GetColorG(), object.GetColorB());
|
||||
@@ -56,7 +56,7 @@ TextObjectEditor::~TextObjectEditor() {}
|
||||
void TextObjectEditor::OnOkBtClicked(wxCommandEvent& event) {
|
||||
// Update the text object
|
||||
object.SetString(m_textCtrl->GetValue());
|
||||
object.SetFontFilename(m_fontTextCtrl->GetValue());
|
||||
object.SetFontName(m_fontTextCtrl->GetValue());
|
||||
object.SetCharacterSize(gd::String(m_sizeCombobox->GetValue()).To<float>());
|
||||
object.SetColor(textColor.Red(), textColor.Green(), textColor.Blue());
|
||||
object.SetBold(m_toolbar->GetToolToggled(BOLD_TOOL_ID));
|
||||
|
@@ -15,12 +15,13 @@ This project is released under the MIT License.
|
||||
#include "TextObject.h"
|
||||
|
||||
void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
extension.SetExtensionInformation(
|
||||
"TextObject",
|
||||
_("Text object"),
|
||||
_("This Extension enables the use of an object that displays text."),
|
||||
"Florian Rival and Victor Levasseur",
|
||||
"Open source (MIT License)")
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"TextObject",
|
||||
_("Text object"),
|
||||
_("This Extension enables the use of an object that displays text."),
|
||||
"Florian Rival and Victor Levasseur",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects/text");
|
||||
|
||||
gd::ObjectMetadata& obj =
|
||||
@@ -65,7 +66,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction("Font",
|
||||
_("Font"),
|
||||
_("Modify the font of the text."),
|
||||
_("Change the font of the text."),
|
||||
_("Change font of _PARAM0_ to _PARAM1_"),
|
||||
_("Font"),
|
||||
"res/actions/font24.png",
|
||||
@@ -78,7 +79,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddAction("Size",
|
||||
_("Size"),
|
||||
_("Modify the size of the text."),
|
||||
_("Change the size of the text."),
|
||||
_("Do _PARAM1__PARAM2_ to the size of the text of _PARAM0_"),
|
||||
_(""),
|
||||
"res/actions/characterSize24.png",
|
||||
@@ -94,7 +95,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("Size",
|
||||
_("Size"),
|
||||
_("Test the size of the text"),
|
||||
_("Compare the size of the text"),
|
||||
_("The size of the text of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_(""),
|
||||
"res/conditions/characterSize24.png",
|
||||
@@ -122,8 +123,9 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.SetIncludeFile("TextObject/TextObject.h");
|
||||
|
||||
obj.AddAction("Opacity",
|
||||
_("Opacity"),
|
||||
_("Modify the opacity of a Text object."),
|
||||
_("Change Text Opacity"),
|
||||
_("Change the opacity of a Text. 0 is fully transparent, 255 "
|
||||
"is opaque (default)."),
|
||||
_("Do _PARAM1__PARAM2_ to the opacity of _PARAM0_"),
|
||||
_(""),
|
||||
"res/actions/opacity24.png",
|
||||
@@ -139,7 +141,8 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("Opacity",
|
||||
_("Opacity"),
|
||||
_("Test the value of the opacity of a Text object."),
|
||||
_("Compare the opacity of a Text object, between 0 (fully "
|
||||
"transparent) to 255 (opaque)."),
|
||||
_("The opacity of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_(""),
|
||||
"res/conditions/opacity24.png",
|
||||
@@ -167,7 +170,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("Smoothed",
|
||||
_("Smoothing"),
|
||||
_("Test if an object is smoothed"),
|
||||
_("Check if an object is smoothed"),
|
||||
_("_PARAM0_ is smoothed"),
|
||||
_("Style"),
|
||||
"res/conditions/opacity24.png",
|
||||
@@ -192,7 +195,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("IsBold",
|
||||
_("Bold"),
|
||||
_("Test if the bold style is activated"),
|
||||
_("Check if the bold style is activated"),
|
||||
_("_PARAM0_ bold style is set"),
|
||||
_("Style"),
|
||||
"res/conditions/bold.png",
|
||||
@@ -217,7 +220,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("IsItalic",
|
||||
_("Italic"),
|
||||
_("Test if the italic style is activated"),
|
||||
_("Check if the italic style is activated"),
|
||||
_("_PARAM0_ italic style is set"),
|
||||
_("Style"),
|
||||
"res/conditions/italic.png",
|
||||
@@ -242,7 +245,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("IsUnderlined",
|
||||
_("Underlined"),
|
||||
_("Test if the underlined style of an object is set."),
|
||||
_("Check if the underlined style of an object is set."),
|
||||
_("_PARAM0_ underlined style is activated"),
|
||||
_("Style"),
|
||||
"res/conditions/underline.png",
|
||||
@@ -270,7 +273,7 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
|
||||
obj.AddCondition("Angle",
|
||||
_("Angle"),
|
||||
_("Test the value of the angle of a Text object."),
|
||||
_("Compare the value of the angle of a Text object."),
|
||||
_("The angle of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Rotation"),
|
||||
"res/conditions/rotate24.png",
|
||||
@@ -283,9 +286,58 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
|
||||
.SetManipulatedType("number")
|
||||
.SetIncludeFile("TextObject/TextObject.h");
|
||||
|
||||
obj.AddAction(
|
||||
"SetWrapping",
|
||||
_("Wrapping"),
|
||||
_("De/activate word wrapping. Note that word wrapping is a graphical "
|
||||
"option,\nyou can't get the number of lines displayed"),
|
||||
_("Set word wrapping style of _PARAM0_: _PARAM1_"),
|
||||
_("Style"),
|
||||
"res/actions/wordWrap24.png",
|
||||
"res/actions/wordWrap.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("yesorno", _("Wrapping"));
|
||||
|
||||
obj.AddCondition("IsWrapping",
|
||||
_("Wrapping"),
|
||||
_("Test if the word wrapping style of an object is set."),
|
||||
_("_PARAM0_ word wrapping style is activated"),
|
||||
_("Style"),
|
||||
"res/conditions/wordWrap24.png",
|
||||
"res/conditions/wordWrap.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Text");
|
||||
|
||||
obj.AddAction("WrappingWidth",
|
||||
_("Wrapping width"),
|
||||
_("Modify the word wrapping width of a Text object."),
|
||||
_("Do _PARAM1__PARAM2_ to the wrapping width of _PARAM0_"),
|
||||
_("Style"),
|
||||
"res/actions/wordWrap24.png",
|
||||
"res/actions/wordWrap.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("expression", _("Value"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("WrappingWidth",
|
||||
_("Wrapping width"),
|
||||
_("Test the word wrapping width of a Text object."),
|
||||
_("The wrapping width of _PARAM0_ is _PARAM1__PARAM2_"),
|
||||
_("Style"),
|
||||
"res/conditions/wordWrap24.png",
|
||||
"res/conditions/wordWrap.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("expression", _("Value to test"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddExpression("Opacity",
|
||||
_("Opacity"),
|
||||
_("Opacity"),
|
||||
_("Opacity of a Text object"),
|
||||
_("Opacity of a Text object"),
|
||||
_("Opacity"),
|
||||
"res/actions/opacity.png")
|
||||
.AddParameter("object", _("Object"), "Text")
|
||||
|
@@ -76,6 +76,21 @@ class TextObjectJsExtension : public gd::PlatformExtension {
|
||||
.SetFunctionName("isItalic")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::SetWrapping"]
|
||||
.SetFunctionName("setWrapping")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::IsWrapping"]
|
||||
.SetFunctionName("isWrapping")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
|
||||
GetAllActionsForObject("TextObject::Text")["TextObject::WrappingWidth"]
|
||||
.SetFunctionName("setWrappingWidth")
|
||||
.SetGetter("getWrappingWidth")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
GetAllConditionsForObject("TextObject::Text")["TextObject::WrappingWidth"]
|
||||
.SetFunctionName("getWrappingWidth")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
|
||||
GetAllExpressionsForObject("TextObject::Text")["Opacity"]
|
||||
.SetFunctionName("getOpacity")
|
||||
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js");
|
||||
|
@@ -54,7 +54,7 @@ TextObject::~TextObject(){};
|
||||
void TextObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
SetString(element.GetChild("string", 0, "String").GetValue().GetString());
|
||||
SetFontFilename(element.GetChild("font", 0, "Font").GetValue().GetString());
|
||||
SetFontName(element.GetChild("font", 0, "Font").GetValue().GetString());
|
||||
SetCharacterSize(element.GetChild("characterSize", 0, "CharacterSize")
|
||||
.GetValue()
|
||||
.GetInt());
|
||||
@@ -119,7 +119,7 @@ void TextObject::LoadResources(gd::Project& project, gd::Layout& layout) {
|
||||
|
||||
void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.AddChild("string").SetValue(GetString());
|
||||
element.AddChild("font").SetValue(GetFontFilename());
|
||||
element.AddChild("font").SetValue(GetFontName());
|
||||
element.AddChild("characterSize").SetValue(GetCharacterSize());
|
||||
element.AddChild("color")
|
||||
.SetAttribute("r", (int)GetColorR())
|
||||
@@ -133,7 +133,7 @@ void TextObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
}
|
||||
|
||||
void TextObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
worker.ExposeFile(fontName);
|
||||
worker.ExposeFont(fontName);
|
||||
}
|
||||
|
||||
bool TextObject::GenerateThumbnail(const gd::Project& project,
|
||||
@@ -157,19 +157,12 @@ void TextObject::EditObject(wxWindow* parent,
|
||||
}
|
||||
#endif
|
||||
|
||||
void TextObject::SetFontFilename(const gd::String& fontFilename) {
|
||||
fontName = fontFilename;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
fontName = gd::AbstractFileSystem::NormalizeSeparator(fontName);
|
||||
#endif
|
||||
};
|
||||
|
||||
/* RuntimeTextObject : */
|
||||
|
||||
RuntimeTextObject::RuntimeTextObject(RuntimeScene& scene,
|
||||
const TextObject& textObject)
|
||||
: RuntimeObject(scene, textObject), opacity(255), angle(0) {
|
||||
ChangeFont(textObject.GetFontFilename());
|
||||
ChangeFont(textObject.GetFontName());
|
||||
SetSmooth(textObject.IsSmoothed());
|
||||
SetColor(
|
||||
textObject.GetColorR(), textObject.GetColorG(), textObject.GetColorB());
|
||||
@@ -332,7 +325,7 @@ void RuntimeTextObject::GetPropertyForDebugger(std::size_t propertyNb,
|
||||
value = GetString();
|
||||
} else if (propertyNb == 1) {
|
||||
name = _("Font");
|
||||
value = GetFontFilename();
|
||||
value = GetFontName();
|
||||
} else if (propertyNb == 2) {
|
||||
name = _("Font Size");
|
||||
value = gd::String::From(GetCharacterSize());
|
||||
|
@@ -15,26 +15,17 @@ This project is released under the MIT License.
|
||||
class ImageManager;
|
||||
class RuntimeScene;
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
}
|
||||
namespace gd {
|
||||
class ImageManager;
|
||||
}
|
||||
namespace gd {
|
||||
class InitialInstance;
|
||||
}
|
||||
#if defined(GD_IDE_ONLY)
|
||||
class wxBitmap;
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
class wxWindow;
|
||||
namespace gd {
|
||||
class MainFrameWrapper;
|
||||
}
|
||||
namespace gd {
|
||||
class ResourcesMergingHelper;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -82,13 +73,13 @@ class GD_EXTENSION_API TextObject : public gd::Object {
|
||||
*/
|
||||
inline float GetCharacterSize() const { return characterSize; };
|
||||
|
||||
/** \brief Return the font filename.
|
||||
/** \brief Return the name of the font resource used for the text.
|
||||
*/
|
||||
inline const gd::String& GetFontFilename() const { return fontName; };
|
||||
inline const gd::String& GetFontName() const { return fontName; };
|
||||
|
||||
/** \brief Change the font filename.
|
||||
/** \brief Change the font resource used for the text.
|
||||
*/
|
||||
void SetFontFilename(const gd::String& fontFilename);
|
||||
void SetFontName(const gd::String& resourceName) { fontName = resourceName; };
|
||||
|
||||
bool IsBold() const { return bold; };
|
||||
void SetBold(bool enable) { bold = enable; };
|
||||
@@ -170,9 +161,9 @@ class GD_EXTENSION_API RuntimeTextObject : public RuntimeObject {
|
||||
*/
|
||||
void ChangeFont(const gd::String& fontFilename);
|
||||
|
||||
/** \brief Return the font file name.
|
||||
/** \brief Return the font resource name.
|
||||
*/
|
||||
inline gd::String GetFontFilename() const { return fontName; };
|
||||
inline gd::String GetFontName() const { return fontName; };
|
||||
|
||||
void SetFontStyle(int style);
|
||||
int GetFontStyle();
|
||||
|
@@ -1,6 +1,7 @@
|
||||
gdjs.TextRuntimeObjectCocosRenderer = function(runtimeObject, runtimeScene)
|
||||
{
|
||||
this._object = runtimeObject;
|
||||
this._fontManager = runtimeScene.getGame().getFontManager();
|
||||
|
||||
this._text = new cc.LabelTTF(" ", "Arial", 38);
|
||||
this._text.disableStroke();
|
||||
@@ -27,13 +28,14 @@ gdjs.TextRuntimeObjectCocosRenderer.prototype.updateStyle = function() {
|
||||
this._text.setFontSize(this._object._characterSize);
|
||||
this._text.setFontFillColor(cc.color(this._object._color[0],
|
||||
this._object._color[1], this._object._color[2]));
|
||||
this._text._setBoundingWidth(this._object._wrapping ? this._object._wrappingWidth : 0);
|
||||
|
||||
var fontName = !this._object._fontName ?
|
||||
'Arial' :
|
||||
(
|
||||
gdjs.CocosTools.isHTML5() ?
|
||||
'gdjs_font_' + this._object._fontName :
|
||||
'res/' + this._object._fontName
|
||||
this._fontManager.getFontFamily(this._object._fontName) :
|
||||
'res/' + this._fontManager.getFontFile(this._object._fontName)
|
||||
);
|
||||
this._text.setFontName(fontName);
|
||||
};
|
||||
|
@@ -1,6 +1,7 @@
|
||||
gdjs.TextRuntimeObjectPixiRenderer = function(runtimeObject, runtimeScene)
|
||||
{
|
||||
this._object = runtimeObject;
|
||||
this._fontManager = runtimeScene.getGame().getFontManager();
|
||||
|
||||
if ( this._text === undefined ) this._text = new PIXI.Text(" ", {align:"left"});
|
||||
this._text.anchor.x = 0.5;
|
||||
@@ -28,7 +29,7 @@ gdjs.TextRuntimeObjectPixiRenderer.prototype.ensureUpToDate = function() {
|
||||
};
|
||||
|
||||
gdjs.TextRuntimeObjectPixiRenderer.prototype.updateStyle = function() {
|
||||
var fontName = this._object._fontName ? "\"gdjs_font_" + this._object._fontName + "\"" : 'Arial';
|
||||
var fontName = "\"" + this._fontManager.getFontFamily(this._object._fontName) + "\"";
|
||||
|
||||
var style = this._text.style;
|
||||
style.fontStyle = this._object._italic ? 'italic' : 'normal';
|
||||
@@ -40,6 +41,10 @@ gdjs.TextRuntimeObjectPixiRenderer.prototype.updateStyle = function() {
|
||||
this._object._color[1],
|
||||
this._object._color[2]
|
||||
);
|
||||
style.wordWrap = this._object._wrapping;
|
||||
style.wordWrapWidth = this._object._wrappingWidth;
|
||||
style.breakWords = true;
|
||||
this.updatePosition();
|
||||
|
||||
// Manually ask the PIXI object to re-render as we changed a style property
|
||||
// see http://www.html5gamedevs.com/topic/16924-change-text-style-post-render/
|
||||
|
@@ -20,6 +20,8 @@ gdjs.TextRuntimeObject = function(runtimeScene, objectData)
|
||||
this._italic = objectData.italic;
|
||||
this._underlined = objectData.underlined;
|
||||
this._color = [objectData.color.r, objectData.color.g, objectData.color.b];
|
||||
this._wrapping = false;
|
||||
this._wrappingWidth = 1;
|
||||
|
||||
this._str = objectData.string;
|
||||
|
||||
@@ -40,6 +42,17 @@ gdjs.TextRuntimeObject.prototype.update = function() {
|
||||
this._renderer.ensureUpToDate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the extra parameters that could be set for an instance.
|
||||
* @private
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
|
||||
if ( initialInstanceData.customSize ) {
|
||||
this.setWrapping(true);
|
||||
this.setWrappingWidth(initialInstanceData.width);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the position object's.
|
||||
* @private
|
||||
@@ -187,3 +200,37 @@ gdjs.TextRuntimeObject.prototype.setColor = function(str) {
|
||||
this._color[2] = parseInt(color[2], 10);
|
||||
this._renderer.updateStyle();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return true if word wrapping is enabled for your text.
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.isWrapping = function() {
|
||||
return this._wrapping;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set word wrapping for your object text.
|
||||
* @param enable {Boolean} Set it to true to enable word wrapping, false to disable it.
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.setWrapping = function(enable) {
|
||||
this._wrapping = enable;
|
||||
this._renderer.updateStyle();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the word wrapping width for your text object.
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.getWrappingWidth = function() {
|
||||
return this._wrappingWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the word wrapping width for your text object.
|
||||
* @param {number} width The new width to set.
|
||||
*/
|
||||
gdjs.TextRuntimeObject.prototype.setWrappingWidth = function(width) {
|
||||
if (width <= 1) width = 1;
|
||||
this._wrappingWidth = width;
|
||||
this._renderer.updateStyle();
|
||||
};
|
||||
|
@@ -351,7 +351,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
gd::String argOutput;
|
||||
|
||||
// Code only parameter type
|
||||
if (metadata.type == "currentScene") {
|
||||
if (metadata.type == "currentScene" || metadata.type == "objectsContext") {
|
||||
argOutput += "*runtimeContext->scene";
|
||||
}
|
||||
// Code only parameter type
|
||||
|
@@ -126,7 +126,6 @@ CppPlatform::CppPlatform() : gd::Platform() {
|
||||
std::cout.flush();
|
||||
AddExtension(std::make_shared<ExternalLayoutsExtension>());
|
||||
std::cout.flush();
|
||||
std::cout << "done." << std::endl;
|
||||
}
|
||||
|
||||
bool CppPlatform::AddExtension(
|
||||
|
@@ -47,8 +47,8 @@ class JsCodeEvent : public gd::BaseEvent {
|
||||
const gd::String& GetInlineCode() const { return inlineCode; };
|
||||
void SetInlineCode(const gd::String& code) { inlineCode = code; };
|
||||
|
||||
gd::String GetParameterObjects() const { return parameterObjects; };
|
||||
void SetParameterObjects(gd::String objectName) {
|
||||
const gd::String& GetParameterObjects() const { return parameterObjects; };
|
||||
void SetParameterObjects(const gd::String& objectName) {
|
||||
parameterObjects = objectName;
|
||||
};
|
||||
|
||||
|
@@ -15,10 +15,11 @@
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/IDE/SceneNameMangler.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/EventsFunction.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDJS/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDJS/Events/CodeGeneration/VariableParserCallbacks.h"
|
||||
@@ -88,15 +89,16 @@ gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateEventsFunctionCode(
|
||||
gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
const gd::EventsList& events,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
const gd::String& codeNamespace,
|
||||
std::set<gd::String>& includeFiles,
|
||||
bool compilationForRuntime) {
|
||||
gd::ObjectsContainer objectsAndGroups;
|
||||
gd::ObjectsContainer
|
||||
emptyObjectsAndGroups; // As opposed to layout events, we don't have
|
||||
// objects in the "outer" scope.
|
||||
gd::ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
project, parameters, objectsAndGroups);
|
||||
project, eventsFunction.GetParameters(), objectsAndGroups);
|
||||
|
||||
// Prepare the global context
|
||||
unsigned int maxDepthLevelReached = 0;
|
||||
@@ -106,8 +108,9 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionCode(
|
||||
// Generate whole events code
|
||||
// Preprocessing then code generation can make changes to the events, so we
|
||||
// need to do the work on a copy of the events.
|
||||
gd::EventsList generatedEvents = events;
|
||||
gd::EventsList generatedEvents = eventsFunction.GetEvents();
|
||||
codeGenerator.SetGenerateCodeForRuntime(compilationForRuntime);
|
||||
codeGenerator.SetCodeNamespace(codeNamespace);
|
||||
codeGenerator.PreprocessEventList(generatedEvents);
|
||||
gd::String wholeEventsCode =
|
||||
codeGenerator.GenerateEventsListCode(generatedEvents, context);
|
||||
@@ -136,23 +139,26 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionCode(
|
||||
codeGenerator.GetCustomCodeOutsideMain() + "\n\n" +
|
||||
codeGenerator.GetCodeNamespaceAccessor() + "func = function(" +
|
||||
codeGenerator.GenerateEventsFunctionParameterDeclarationsList(
|
||||
parameters) +
|
||||
") {\n" + codeGenerator.GenerateEventsFunctionContext(parameters) + "\n" +
|
||||
globalObjectListsReset + "\n" + codeGenerator.GetCustomCodeInMain() +
|
||||
wholeEventsCode + "\n" + "return;\n" + "}\n";
|
||||
eventsFunction.GetParameters()) +
|
||||
") {\n" +
|
||||
codeGenerator.GenerateEventsFunctionContext(
|
||||
eventsFunction.GetParameters()) +
|
||||
"\n" + globalObjectListsReset + "\n" +
|
||||
codeGenerator.GetCustomCodeInMain() + wholeEventsCode + "\n" +
|
||||
codeGenerator.GenerateEventsFunctionReturn(eventsFunction) + "\n" + "}\n";
|
||||
|
||||
// includeFiles.insert(codeGenerator.GetIncludeFiles().begin(),
|
||||
// codeGenerator.GetIncludeFiles().end());
|
||||
includeFiles.insert(codeGenerator.GetIncludeFiles().begin(),
|
||||
codeGenerator.GetIncludeFiles().end());
|
||||
return output;
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateEventsFunctionParameterDeclarationsList(
|
||||
const vector<gd::ParameterMetadata>& parameters) {
|
||||
gd::String declaration = "";
|
||||
gd::String declaration = "runtimeScene";
|
||||
for (const auto& parameter : parameters) {
|
||||
if (!declaration.empty()) declaration += ", ";
|
||||
declaration += parameter.GetName().empty() ? "_" : parameter.GetName();
|
||||
declaration += ", " + (parameter.GetName().empty() ? "_" : parameter.GetName());
|
||||
}
|
||||
declaration += ", parentEventsFunctionContext";
|
||||
|
||||
return declaration;
|
||||
}
|
||||
@@ -160,14 +166,32 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionParameterDeclarationsList(
|
||||
gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
const vector<gd::ParameterMetadata>& parameters) {
|
||||
gd::String objectsGetters;
|
||||
gd::String objectsCreators;
|
||||
gd::String argumentsGetters;
|
||||
for (const auto& parameter : parameters) {
|
||||
if (parameter.GetName().empty()) continue;
|
||||
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
|
||||
// Generate getter that will be used to get the lists of objects passed
|
||||
// as parameters
|
||||
objectsGetters +=
|
||||
"if (objectName === " + ConvertToStringExplicit(parameter.GetName()) +
|
||||
") return gdjs.objectsListsToArray(" + parameter.GetName() + ");\n";
|
||||
"&& !!" + parameter.GetName() + ") return gdjs.objectsListsToArray(" +
|
||||
parameter.GetName() + ");\n";
|
||||
|
||||
// Generate creator functions that will be used to create new objects. We
|
||||
// need to check if the function was given the context of the calling
|
||||
// function (parentEventsFunctionContext). If this is the case, use it to
|
||||
// create the new object as the object names used in the function are not
|
||||
// the same as the objects available in the scene.
|
||||
gd::String objectNameCode = parameter.GetName() + ".firstKey()";
|
||||
objectsCreators +=
|
||||
"if (objectName === " + ConvertToStringExplicit(parameter.GetName()) +
|
||||
"&& !!" + parameter.GetName() +
|
||||
") return parentEventsFunctionContext ? "
|
||||
"parentEventsFunctionContext.createObject(" +
|
||||
objectNameCode + ") : runtimeScene.createObject(" + objectNameCode +
|
||||
");\n";
|
||||
} else {
|
||||
argumentsGetters +=
|
||||
"if (argName === " + ConvertToStringExplicit(parameter.GetName()) +
|
||||
@@ -179,8 +203,26 @@ gd::String EventsCodeGenerator::GenerateEventsFunctionContext(
|
||||
" getObjects: function(objectName) {\n" + objectsGetters +
|
||||
" return [];"
|
||||
" },\n" +
|
||||
" getArgument: function(argName) {\n" + argumentsGetters +
|
||||
" return \"\";" + " }\n" + "};\n";
|
||||
" createObject: function(objectName) {\n" + objectsCreators +
|
||||
" return null;\n" +
|
||||
" },\n"
|
||||
" getArgument: function(argName) {\n" +
|
||||
argumentsGetters + " return \"\";\n" + " }\n" + "};\n";
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateEventsFunctionReturn(
|
||||
const gd::EventsFunction& eventsFunction) {
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
return "return !!eventsFunctionContext.returnValue;";
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression) {
|
||||
return "return Number(eventsFunctionContext.returnValue) || 0;";
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
return "return \"\" + eventsFunctionContext.returnValue;";
|
||||
}
|
||||
|
||||
return "return;";
|
||||
}
|
||||
|
||||
std::pair<gd::String, gd::String>
|
||||
@@ -725,6 +767,18 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
argOutput = "runtimeScene";
|
||||
}
|
||||
// Code only parameter type
|
||||
else if (metadata.type == "objectsContext") {
|
||||
argOutput =
|
||||
"(typeof eventsFunctionContext !== 'undefined' ? eventsFunctionContext "
|
||||
": runtimeScene)";
|
||||
}
|
||||
// Code only parameter type
|
||||
else if (metadata.type == "eventsFunctionContext") {
|
||||
argOutput =
|
||||
"(typeof eventsFunctionContext !== 'undefined' ? eventsFunctionContext "
|
||||
": undefined)";
|
||||
}
|
||||
// Code only parameter type
|
||||
else if (metadata.type == "objectList") {
|
||||
std::vector<gd::String> realObjects = ExpandObjectsName(parameter, context);
|
||||
for (auto& objectName : realObjects) context.ObjectsListNeeded(objectName);
|
||||
@@ -847,8 +901,10 @@ gd::String EventsCodeGenerator::GetCodeNamespace() {
|
||||
return "gdjs." +
|
||||
gd::SceneNameMangler::GetMangledSceneName(GetLayout().GetName()) +
|
||||
"Code";
|
||||
} else if (!codeNamespace.empty()) {
|
||||
return codeNamespace;
|
||||
} else {
|
||||
return "gdjs.events" + gd::String::From(&objectsAndGroups) + "Code";
|
||||
return "gdjs.unspecifiednamespacethisisprobablyanerrorincodegeneratorsetup";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
namespace gd {
|
||||
class ObjectsContainer;
|
||||
class EventsFunction;
|
||||
class ObjectMetadata;
|
||||
class BehaviorMetadata;
|
||||
class InstructionMetadata;
|
||||
@@ -54,17 +55,17 @@ class EventsCodeGenerator : public gd::EventsCodeGenerator {
|
||||
* Generate JavaScript for executing events in a function
|
||||
*
|
||||
* \param project Project used
|
||||
* \param parameters The parameters of the function (objects will be deduced from these).
|
||||
* \param events events of the scene
|
||||
* \param compilationForRuntime Set this to true if the code is generated for
|
||||
* runtime.
|
||||
* \param parameters The parameters of the function (objects will be deduced
|
||||
* from these). \param events events of the scene \param compilationForRuntime
|
||||
* Set this to true if the code is generated for runtime.
|
||||
*
|
||||
* \return JavaScript code
|
||||
*/
|
||||
static gd::String GenerateEventsFunctionCode(
|
||||
gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata> & parameters,
|
||||
const gd::EventsList& events,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
const gd::String& codeNamespace,
|
||||
std::set<gd::String>& includeFiles,
|
||||
bool compilationForRuntime = false);
|
||||
|
||||
/**
|
||||
@@ -134,6 +135,16 @@ class EventsCodeGenerator : public gd::EventsCodeGenerator {
|
||||
*/
|
||||
virtual gd::String GetCodeNamespace();
|
||||
|
||||
/**
|
||||
* \brief Specify the code namespace to use, useful for functions as it is not
|
||||
* autogenerated.
|
||||
*
|
||||
* Example: "gdjs.something"
|
||||
*/
|
||||
void SetCodeNamespace(const gd::String& codeNamespace_) {
|
||||
codeNamespace = codeNamespace_;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual gd::String GenerateParameterCodes(
|
||||
const gd::String& parameter,
|
||||
@@ -243,8 +254,25 @@ class EventsCodeGenerator : public gd::EventsCodeGenerator {
|
||||
*/
|
||||
void AddAllObjectsIncludeFiles();
|
||||
|
||||
gd::String GenerateEventsFunctionParameterDeclarationsList(const std::vector<gd::ParameterMetadata> & parameters);
|
||||
gd::String GenerateEventsFunctionContext(const std::vector<gd::ParameterMetadata> & parameters);
|
||||
/**
|
||||
* \brief Generate the list of parameters of a function.
|
||||
*
|
||||
* \note runtimeScene is always added as the first parameter, and
|
||||
* parentEventsFunctionContext as the last parameter.
|
||||
*/
|
||||
gd::String GenerateEventsFunctionParameterDeclarationsList(
|
||||
const std::vector<gd::ParameterMetadata>& parameters);
|
||||
|
||||
/**
|
||||
* \brief Generate the "eventsFunctionContext" object that allow a function
|
||||
* to provides access objects, object creation and access to arguments from
|
||||
* the rest of the events.
|
||||
*/
|
||||
gd::String GenerateEventsFunctionContext(
|
||||
const std::vector<gd::ParameterMetadata>& parameters);
|
||||
|
||||
gd::String GenerateEventsFunctionReturn(
|
||||
const gd::EventsFunction & eventFunction);
|
||||
|
||||
/**
|
||||
* \brief Construct a code generator for the specified project and layout.
|
||||
@@ -257,6 +285,9 @@ class EventsCodeGenerator : public gd::EventsCodeGenerator {
|
||||
EventsCodeGenerator(gd::ObjectsContainer& globalObjectsAndGroups,
|
||||
const gd::ObjectsContainer& objectsAndGroups);
|
||||
virtual ~EventsCodeGenerator();
|
||||
|
||||
gd::String codeNamespace; ///< Optional namespace for the generated code,
|
||||
///< used when generating events function.
|
||||
};
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -5,7 +5,9 @@
|
||||
*/
|
||||
#include "AdvancedExtension.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
@@ -16,6 +18,121 @@ AdvancedExtension::AdvancedExtension() {
|
||||
|
||||
GetAllConditions()["Toujours"].SetFunctionName(
|
||||
"gdjs.evtTools.common.logicalNegation");
|
||||
|
||||
GetAllActions()["SetReturnNumber"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([](gd::Instruction& instruction,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String expressionCode;
|
||||
{
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
expressionCode, codeGenerator, context);
|
||||
gd::ExpressionParser parser(
|
||||
instruction.GetParameter(0).GetPlainString());
|
||||
if (!parser.ParseMathExpression(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
expressionCode.empty())
|
||||
expressionCode = "0";
|
||||
}
|
||||
|
||||
return "if (typeof eventsFunctionContext !== 'undefined') { "
|
||||
"eventsFunctionContext.returnValue = " +
|
||||
expressionCode + "; }";
|
||||
});
|
||||
|
||||
GetAllActions()["SetReturnString"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([](gd::Instruction& instruction,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String expressionCode;
|
||||
{
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
expressionCode, codeGenerator, context);
|
||||
gd::ExpressionParser parser(
|
||||
instruction.GetParameter(0).GetPlainString());
|
||||
if (!parser.ParseStringExpression(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
expressionCode.empty())
|
||||
expressionCode = "\"\"";
|
||||
}
|
||||
|
||||
return "if (typeof eventsFunctionContext !== 'undefined') { "
|
||||
"eventsFunctionContext.returnValue = " +
|
||||
expressionCode + "; }";
|
||||
});
|
||||
|
||||
GetAllActions()["SetReturnBoolean"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([](gd::Instruction& instruction,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
// This is duplicated from EventsCodeGenerator::GenerateParameterCodes
|
||||
gd::String parameter = instruction.GetParameter(0).GetPlainString();
|
||||
gd::String booleanCode =
|
||||
(parameter == "True" || parameter == "Vrai") ? "true" : "false";
|
||||
|
||||
return "if (typeof eventsFunctionContext !== 'undefined') { "
|
||||
"eventsFunctionContext.returnValue = " +
|
||||
booleanCode + "; }";
|
||||
});
|
||||
|
||||
auto generateParameterNameCode =
|
||||
[](const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String parameterNameCode;
|
||||
{
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
parameterNameCode, codeGenerator, context);
|
||||
gd::ExpressionParser parser(
|
||||
!parameters.empty() ? parameters[0].GetPlainString() : "");
|
||||
if (!parser.ParseStringExpression(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
parameterNameCode.empty())
|
||||
parameterNameCode = "\"\"";
|
||||
}
|
||||
|
||||
return parameterNameCode;
|
||||
};
|
||||
|
||||
GetAllExpressions()["GetArgumentAsNumber"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([&generateParameterNameCode](
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String parameterNameCode =
|
||||
generateParameterNameCode(parameters, codeGenerator, context);
|
||||
|
||||
return "(typeof eventsFunctionContext !== 'undefined' ? "
|
||||
"Number(eventsFunctionContext.getArgument(" +
|
||||
parameterNameCode + ")) || 0 : 0)";
|
||||
});
|
||||
|
||||
GetAllStrExpressions()["GetArgumentAsString"]
|
||||
.GetCodeExtraInformation()
|
||||
.SetCustomCodeGenerator([&generateParameterNameCode](
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
gd::String parameterNameCode =
|
||||
generateParameterNameCode(parameters, codeGenerator, context);
|
||||
|
||||
return "(typeof eventsFunctionContext !== 'undefined' ? \"\" + "
|
||||
"eventsFunctionContext.getArgument(" +
|
||||
parameterNameCode + ") : \"\")";
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace gdjs
|
||||
|
@@ -67,6 +67,12 @@ SpriteExtension::SpriteExtension() {
|
||||
.SetGetter("getScale");
|
||||
spriteConditions["ScaleWidth"].SetFunctionName("getScaleX");
|
||||
spriteConditions["ScaleHeight"].SetFunctionName("getScaleY");
|
||||
spriteActions["ChangeWidth"]
|
||||
.SetFunctionName("setWidth")
|
||||
.SetGetter("getWidth");
|
||||
spriteActions["ChangeHeight"]
|
||||
.SetFunctionName("setHeight")
|
||||
.SetGetter("getHeight");
|
||||
spriteActions["TourneVersPos"].SetFunctionName("rotateTowardPosition");
|
||||
spriteActions["TourneVers"].SetFunctionName("turnTowardObject");
|
||||
spriteActions["ChangeColor"].SetFunctionName("setColor");
|
||||
|