mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
180 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c6c586459c | ||
![]() |
a930011d8d | ||
![]() |
51d723bd3d | ||
![]() |
b63f968011 | ||
![]() |
3387c553d8 | ||
![]() |
441cd20846 | ||
![]() |
f9871bd63d | ||
![]() |
bac11b3818 | ||
![]() |
3e32cb8cea | ||
![]() |
db74a59730 | ||
![]() |
e7d09531b7 | ||
![]() |
97cf19180b | ||
![]() |
5cc999c0a3 | ||
![]() |
5eb0aa9e14 | ||
![]() |
7f528649d7 | ||
![]() |
c4f44daa8c | ||
![]() |
7d00e78628 | ||
![]() |
887ced270a | ||
![]() |
b8e9bc801a | ||
![]() |
7f023e1a58 | ||
![]() |
6606ddb260 | ||
![]() |
a682c1baa8 | ||
![]() |
d581af20e1 | ||
![]() |
2abf636283 | ||
![]() |
7d09853c12 | ||
![]() |
bb88f3ae4d | ||
![]() |
44b06039e1 | ||
![]() |
9c7f2e4293 | ||
![]() |
facbbe614d | ||
![]() |
d5cadadf82 | ||
![]() |
aed4b76a3f | ||
![]() |
b1e03f4555 | ||
![]() |
93be3153b5 | ||
![]() |
d0c9ff6754 | ||
![]() |
a5cf0896bc | ||
![]() |
7f6ce26c43 | ||
![]() |
eda9db6b40 | ||
![]() |
b9405f5e7d | ||
![]() |
ca591f60d6 | ||
![]() |
214e012ec4 | ||
![]() |
9cc0172a60 | ||
![]() |
6e01228ae6 | ||
![]() |
e22611625e | ||
![]() |
28ccb55a06 | ||
![]() |
7893b892a3 | ||
![]() |
10b3c50a42 | ||
![]() |
8c5fbc6e34 | ||
![]() |
a40382333b | ||
![]() |
fb95f26fbb | ||
![]() |
48a90ae86d | ||
![]() |
6303a50a9d | ||
![]() |
a47ec5199e | ||
![]() |
a6921c2de3 | ||
![]() |
b21b6f0dfb | ||
![]() |
c0d4480099 | ||
![]() |
56277ff5d3 | ||
![]() |
4fa1fbd5e2 | ||
![]() |
f61ef1be2e | ||
![]() |
bf387631ec | ||
![]() |
981752af26 | ||
![]() |
58e5933c75 | ||
![]() |
237ad8ce39 | ||
![]() |
02225cb0ec | ||
![]() |
b34426e084 | ||
![]() |
23c09f3472 | ||
![]() |
59a7690748 | ||
![]() |
3e97d4b878 | ||
![]() |
d710dd0335 | ||
![]() |
78695b6b17 | ||
![]() |
4e3dec4356 | ||
![]() |
f373e3b8d1 | ||
![]() |
3e71c3a63f | ||
![]() |
86cad044d4 | ||
![]() |
21b525ab98 | ||
![]() |
fb328fd0f5 | ||
![]() |
afdb934a8a | ||
![]() |
530f756e47 | ||
![]() |
b1fb207a08 | ||
![]() |
5f87213ccd | ||
![]() |
9065454bfe | ||
![]() |
801fbb4b10 | ||
![]() |
cfa538ec3d | ||
![]() |
504443dea4 | ||
![]() |
bdbc665d2e | ||
![]() |
1d77f2da23 | ||
![]() |
7b6aa78aeb | ||
![]() |
e9aaed9d41 | ||
![]() |
982c9e38c1 | ||
![]() |
c86388018c | ||
![]() |
6ae1b62df7 | ||
![]() |
ea745a49d7 | ||
![]() |
48fc2f640b | ||
![]() |
a86ee8c338 | ||
![]() |
1787b3c5c8 | ||
![]() |
3e246e3cf0 | ||
![]() |
5035d16bd4 | ||
![]() |
2f6109a21c | ||
![]() |
0792fdadc7 | ||
![]() |
0ca596e287 | ||
![]() |
899a252ddd | ||
![]() |
d92bf23e58 | ||
![]() |
37ae451178 | ||
![]() |
9c47a92ea6 | ||
![]() |
1afd4b94be | ||
![]() |
4d5a3f499f | ||
![]() |
13da1c56fd | ||
![]() |
8131ffcdb5 | ||
![]() |
77f948bfbf | ||
![]() |
c6abfc5433 | ||
![]() |
2777e458ae | ||
![]() |
1d0695d722 | ||
![]() |
1820575f52 | ||
![]() |
f62236788d | ||
![]() |
247e2f39e0 | ||
![]() |
30898058a4 | ||
![]() |
4e5d268f63 | ||
![]() |
fc4072b055 | ||
![]() |
9adec3ac72 | ||
![]() |
95c2efbe07 | ||
![]() |
5a71b3a05f | ||
![]() |
fe87150cd4 | ||
![]() |
ddd3dc095a | ||
![]() |
43bd02f99f | ||
![]() |
7ebf3c559b | ||
![]() |
a5dca5fcb7 | ||
![]() |
179a130d30 | ||
![]() |
9953d33764 | ||
![]() |
5cb8603b56 | ||
![]() |
5278628480 | ||
![]() |
99b615c573 | ||
![]() |
0ffc88a470 | ||
![]() |
b389b3cc90 | ||
![]() |
41a70ec1e7 | ||
![]() |
1844d826f9 | ||
![]() |
e7e45e9c9b | ||
![]() |
7f7dc0e07f | ||
![]() |
7af0153ceb | ||
![]() |
9aaabbcc1d | ||
![]() |
55cc75e990 | ||
![]() |
d3d6c50790 | ||
![]() |
c7f2e4312c | ||
![]() |
38cff7bbce | ||
![]() |
761de213ac | ||
![]() |
f871b64011 | ||
![]() |
9441d3a2d2 | ||
![]() |
e86348727e | ||
![]() |
754845e5cd | ||
![]() |
1b86c23b92 | ||
![]() |
3c44602486 | ||
![]() |
b0f1e962a4 | ||
![]() |
c48c86a51f | ||
![]() |
2b83ec9871 | ||
![]() |
c340f8ad06 | ||
![]() |
07341f1e00 | ||
![]() |
7402d4f29f | ||
![]() |
8599a1cfa7 | ||
![]() |
98bfc7a4e0 | ||
![]() |
cef352276d | ||
![]() |
49ea27fd54 | ||
![]() |
23b5b16bdf | ||
![]() |
2124133b4a | ||
![]() |
905344f396 | ||
![]() |
84b78dfe0f | ||
![]() |
1d8086b2f4 | ||
![]() |
22d5d46601 | ||
![]() |
a5d56c37c9 | ||
![]() |
5025ad9fb9 | ||
![]() |
daae78e802 | ||
![]() |
9ee4b704da | ||
![]() |
a8991b7c9b | ||
![]() |
cf061638b8 | ||
![]() |
0686e02e27 | ||
![]() |
e65b576e4b | ||
![]() |
aacfed02a1 | ||
![]() |
6a25a9ad77 | ||
![]() |
e1140609d0 | ||
![]() |
81ef11163d | ||
![]() |
fcc19a6dcf | ||
![]() |
bcad2d5667 | ||
![]() |
3c83e5d24a |
@@ -68,7 +68,7 @@ jobs:
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
|
||||
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app" && rm -rf "newIDE/electron-app/dist/mac-arm64/GDevelop 5.app"
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
@@ -143,11 +143,11 @@ jobs:
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux AppImage zip deb --publish=never
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/linux-arm64-unpacked
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
|
@@ -468,6 +468,14 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action, *this, context);
|
||||
}
|
||||
|
||||
// Get the correct function name depending on whether it should be async or
|
||||
// not.
|
||||
const gd::String& functionCallName =
|
||||
instrInfos.IsAsync() &&
|
||||
(!instrInfos.IsOptionallyAsync() || action.IsAwaited())
|
||||
? instrInfos.codeExtraInformation.asyncFunctionCallName
|
||||
: instrInfos.codeExtraInformation.functionCallName;
|
||||
|
||||
// Be sure there is no lack of parameter.
|
||||
while (action.GetParameters().size() < instrInfos.parameters.size()) {
|
||||
vector<gd::Expression> parameters = action.GetParameters();
|
||||
@@ -522,6 +530,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode += GenerateObjectAction(realObjects[i],
|
||||
objInfo,
|
||||
functionCallName,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
@@ -556,6 +565,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
GenerateBehaviorAction(realObjects[i],
|
||||
action.GetParameter(1).GetPlainString(),
|
||||
autoInfo,
|
||||
functionCallName,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
@@ -567,8 +577,11 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
} else {
|
||||
vector<gd::String> arguments = GenerateParametersCodes(
|
||||
action.GetParameters(), instrInfos.parameters, context);
|
||||
actionCode +=
|
||||
GenerateFreeAction(arguments, instrInfos, context, optionalAsyncCallbackName);
|
||||
actionCode += GenerateFreeAction(functionCallName,
|
||||
arguments,
|
||||
instrInfos,
|
||||
context,
|
||||
optionalAsyncCallbackName);
|
||||
}
|
||||
|
||||
return actionCode;
|
||||
@@ -678,7 +691,8 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
} else if (ParameterMetadata::IsObject(metadata.type)) {
|
||||
// It would be possible to run a gd::ExpressionCodeGenerator if later
|
||||
// objects can have nested objects, or function returning objects.
|
||||
argOutput = GenerateObject(parameter.GetPlainString(), metadata.type, context);
|
||||
argOutput =
|
||||
GenerateObject(parameter.GetPlainString(), metadata.type, context);
|
||||
} else if (metadata.type == "relationalOperator") {
|
||||
auto parameterString = parameter.GetPlainString();
|
||||
argOutput += parameterString == "=" ? "==" : parameterString;
|
||||
@@ -716,13 +730,15 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
|
||||
} else if (metadata.type == "yesorno") {
|
||||
auto parameterString = parameter.GetPlainString();
|
||||
argOutput += (parameterString == "yes" || parameterString == "oui") ? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
argOutput += (parameterString == "yes" || parameterString == "oui")
|
||||
? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
} else if (metadata.type == "trueorfalse") {
|
||||
auto parameterString = parameter.GetPlainString();
|
||||
// This is duplicated in AdvancedExtension.cpp for GDJS
|
||||
argOutput += (parameterString == "True" || parameterString == "Vrai") ? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
argOutput += (parameterString == "True" || parameterString == "Vrai")
|
||||
? GenerateTrue()
|
||||
: GenerateFalse();
|
||||
}
|
||||
// Code only parameter type
|
||||
else if (metadata.type == "inlineCode") {
|
||||
@@ -1082,6 +1098,7 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -1095,21 +1112,21 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
call = GenerateOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName,
|
||||
functionCallName,
|
||||
instrInfos.codeExtraInformation.optionalAssociatedInstruction);
|
||||
else if (instrInfos.codeExtraInformation.accessType ==
|
||||
gd::InstructionMetadata::ExtraInformation::Mutators)
|
||||
call =
|
||||
GenerateMutatorCall(instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName);
|
||||
functionCallName);
|
||||
else
|
||||
call = GenerateCompoundOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName);
|
||||
functionCallName);
|
||||
} else {
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
call = functionCallName + "(" +
|
||||
GenerateArgumentsList(arguments) + ")";
|
||||
}
|
||||
|
||||
@@ -1123,6 +1140,7 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
const gd::String& objectName,
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -1136,27 +1154,25 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
|
||||
call = GenerateOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName,
|
||||
functionCallName,
|
||||
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
|
||||
2);
|
||||
else
|
||||
call = GenerateCompoundOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName,
|
||||
2);
|
||||
instrInfos, arguments, functionCallName, 2);
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call +
|
||||
".\n";
|
||||
} else {
|
||||
gd::String argumentsStr = GenerateArgumentsList(arguments, 1);
|
||||
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
argumentsStr + ")";
|
||||
call = functionCallName + "(" + argumentsStr + ")";
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call + "(" +
|
||||
argumentsStr + ")" +
|
||||
(optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
|
||||
(optionalAsyncCallbackName.empty()
|
||||
? ""
|
||||
: (", then call" + optionalAsyncCallbackName)) +
|
||||
".\n";
|
||||
}
|
||||
}
|
||||
@@ -1165,6 +1181,7 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
const gd::String& objectName,
|
||||
const gd::String& behaviorName,
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -1178,26 +1195,28 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
|
||||
call = GenerateOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName,
|
||||
functionCallName,
|
||||
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
|
||||
2);
|
||||
else
|
||||
call = GenerateCompoundOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName,
|
||||
functionCallName,
|
||||
2);
|
||||
return "For each picked object \"" + objectName + "\", call " + call +
|
||||
" for behavior \"" + behaviorName + "\".\n";
|
||||
} else {
|
||||
gd::String argumentsStr = GenerateArgumentsList(arguments, 2);
|
||||
|
||||
call = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
call = functionCallName + "(" +
|
||||
argumentsStr + ")";
|
||||
|
||||
return "For each picked object \"" + objectName + "\", call " + call + "(" +
|
||||
argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" +
|
||||
(optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
|
||||
(optionalAsyncCallbackName.empty()
|
||||
? ""
|
||||
: (", then call" + optionalAsyncCallbackName)) +
|
||||
".\n";
|
||||
}
|
||||
}
|
||||
|
@@ -154,9 +154,10 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \param context Context used for generation
|
||||
* \return Code
|
||||
*/
|
||||
gd::String GenerateActionCode(gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
gd::String GenerateActionCode(
|
||||
gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
struct CallbackDescriptor {
|
||||
CallbackDescriptor(const gd::String functionName_,
|
||||
@@ -174,7 +175,8 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
const gd::String argumentsList;
|
||||
/**
|
||||
* A set of all objects that need to be backed up to be passed to the callback code.
|
||||
* A set of all objects that need to be backed up to be passed to the
|
||||
* callback code.
|
||||
*/
|
||||
const std::set<gd::String> requiredObjects;
|
||||
};
|
||||
@@ -507,10 +509,10 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* - currentScene: Reference to the current runtime scene.
|
||||
* - objectList : a map containing lists of objects which are specified by the
|
||||
object name in another parameter.
|
||||
* - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick object if
|
||||
they are not already picked.
|
||||
* - objectPtr: Return a reference to the object specified by the object name in
|
||||
another parameter. Example:
|
||||
* - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick
|
||||
object if they are not already picked.
|
||||
* - objectPtr: Return a reference to the object specified by the object name
|
||||
in another parameter. Example:
|
||||
* \code
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Target object"))
|
||||
@@ -700,6 +702,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateFreeAction(
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -708,6 +711,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
virtual gd::String GenerateObjectAction(
|
||||
const gd::String& objectName,
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -717,6 +721,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const gd::String& objectName,
|
||||
const gd::String& behaviorName,
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
@@ -775,8 +780,8 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
|
||||
bool hasProjectAndLayout; ///< true only if project and layout are valid
|
||||
///< references. If false, they should not be used.
|
||||
const gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
const gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
|
||||
bool errorOccurred; ///< Must be set to true if an error occured.
|
||||
bool compilationForRuntime; ///< Is set to true if the code generation is
|
||||
|
@@ -75,7 +75,8 @@ void BaseEvent::PreprocessAsyncActions(const gd::Platform& platform) {
|
||||
const auto& action = actionsList->at(aId);
|
||||
const gd::InstructionMetadata& actionMetadata =
|
||||
gd::MetadataProvider::GetActionMetadata(platform, action.GetType());
|
||||
if (actionMetadata.IsAsync()) {
|
||||
if (actionMetadata.IsAsync() &&
|
||||
(!actionMetadata.IsOptionallyAsync() || action.IsAwaited())) {
|
||||
gd::InstructionsList remainingActions;
|
||||
remainingActions.InsertInstructions(
|
||||
*actionsList, aId + 1, actionsList->size() - 1);
|
||||
|
@@ -72,6 +72,22 @@ class GD_CORE_API Instruction {
|
||||
*/
|
||||
void SetInverted(bool inverted_) { inverted = inverted_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the async instruction should be awaited.
|
||||
* This is not relevant if the instruction is not optionally asynchronous.
|
||||
*
|
||||
* \return true if the instruction is to be awaited
|
||||
*/
|
||||
bool IsAwaited() const { return awaitAsync; }
|
||||
|
||||
/**
|
||||
* \brief Set if the async instruction is to be awaited or not.
|
||||
* This is not relevant if the instruction is not optionally asynchronous.
|
||||
*
|
||||
* \param inverted true if the instruction must be awaited
|
||||
*/
|
||||
void SetAwaited(bool awaited) { awaitAsync = awaited; }
|
||||
|
||||
/**
|
||||
* \brief Return the number of parameters of the instruction.
|
||||
*/
|
||||
@@ -139,7 +155,9 @@ class GD_CORE_API Instruction {
|
||||
* Useful to get reference to the original instruction in memory during code
|
||||
* generation, to ensure stable unique identifiers.
|
||||
*/
|
||||
std::weak_ptr<Instruction> GetOriginalInstruction() { return originalInstruction; };
|
||||
std::weak_ptr<Instruction> GetOriginalInstruction() {
|
||||
return originalInstruction;
|
||||
};
|
||||
|
||||
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
|
||||
std::shared_ptr<Instruction> instruction);
|
||||
@@ -148,6 +166,9 @@ class GD_CORE_API Instruction {
|
||||
gd::String type; ///< Instruction type
|
||||
bool inverted; ///< True if the instruction if inverted. Only applicable for
|
||||
///< instruction used as conditions by events
|
||||
bool awaitAsync =
|
||||
false; ///< Tells the code generator whether the optionally asynchronous
|
||||
///< instruction should be generated as asynchronous (awaited) or not.
|
||||
mutable std::vector<gd::Expression>
|
||||
parameters; ///< Vector containing the parameters
|
||||
gd::InstructionsList subInstructions; ///< Sub instructions, if applicable.
|
||||
|
@@ -269,6 +269,9 @@ void gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
instrElement.GetChild("type", 0, "Type")
|
||||
.GetBoolAttribute("inverted", false, "Contraire"));
|
||||
|
||||
instruction.SetAwaited(
|
||||
instrElement.GetChild("type", 0, "Type").GetBoolAttribute("await"));
|
||||
|
||||
// Read parameters
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
@@ -346,6 +349,8 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
|
||||
if (list[k].IsInverted())
|
||||
instruction.GetChild("type").SetAttribute("inverted", true);
|
||||
if (list[k].IsAwaited())
|
||||
instruction.GetChild("type").SetAttribute("await", true);
|
||||
|
||||
// Parameters
|
||||
SerializerElement& parameters = instruction.AddChild("parameters");
|
||||
|
@@ -14,14 +14,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinAudio",
|
||||
_("Sounds and musics"),
|
||||
_("Sounds and music"),
|
||||
_("GDevelop provides several conditions and actions to play audio "
|
||||
"files. They can be either long musics or short sound effects."),
|
||||
"files. They can be either long music or short sound effects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/audio")
|
||||
.SetCategory("Audio");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and musics"))
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and music"))
|
||||
.SetIcon("res/actions/music24.png");
|
||||
|
||||
extension
|
||||
@@ -73,9 +73,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
|
||||
extension
|
||||
.AddAction("RePlaySoundCanal",
|
||||
_("Play the sound of a channel"),
|
||||
_("Play the sound of the channel."),
|
||||
_("Play the sound of channel _PARAM1_"),
|
||||
_("Resume playing a sound on a channel"),
|
||||
_("Resume playing a sound on a channel that was paused."),
|
||||
_("Resume the sound of channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
@@ -132,9 +132,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
|
||||
extension
|
||||
.AddAction("RePlayMusicCanal",
|
||||
_("Play the music of a channel"),
|
||||
_("Play the music of the channel."),
|
||||
_("Play the music of channel _PARAM1_"),
|
||||
_("Resume playing a music on a channel"),
|
||||
_("Resume playing a music on a channel that was paused."),
|
||||
_("Resume the music of channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
|
@@ -28,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Movement using forces"))
|
||||
.SetIcon("res/actions/force24.png");
|
||||
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::Object>(
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
|
||||
"", _("Base object"), _("Base object"), "res/objeticon24.png");
|
||||
|
||||
obj.AddCondition("PosX",
|
||||
@@ -219,7 +219,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
|
||||
obj.AddAction("SetAngle",
|
||||
_("Angle"),
|
||||
_("Change the angle of rotation of an object."),
|
||||
_("Change the angle of rotation of an object (in degrees)."),
|
||||
_("the angle"),
|
||||
_("Angle"),
|
||||
"res/actions/direction24.png",
|
||||
@@ -289,7 +289,8 @@ 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("forceMultiplier", _("Force multiplier"));
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
obj.AddAction("AddForceAL",
|
||||
_("Add a force (angle)"),
|
||||
@@ -305,7 +306,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Angle"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -323,7 +325,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -390,7 +393,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/layer.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("layer", _("Move it to this layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Move it to this layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -756,7 +759,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Target Object"))
|
||||
.AddParameter("expression", _("Speed (in pixels per second)"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -776,7 +780,8 @@ 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("forceMultiplier", _("Force multiplier"))
|
||||
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction("MettreAutour",
|
||||
@@ -993,7 +998,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
|
||||
obj.AddExpression("ForceAngle",
|
||||
_("Angle of the sum of forces"),
|
||||
_("Angle of the sum of forces"),
|
||||
_("Angle of the sum of forces (in degrees)"),
|
||||
_("Movement using forces"),
|
||||
"res/actions/force.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
@@ -1093,7 +1098,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
obj.AddExpression("Variable",
|
||||
_("Object variable"),
|
||||
_("Value of an object variable"),
|
||||
_("Value of an object variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
@@ -1109,7 +1114,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectvar", _("Variable"));
|
||||
|
||||
obj.AddStrExpression("VariableString",
|
||||
_("Object variable"),
|
||||
_("Text of an object variable"),
|
||||
_("Text of an object variable"),
|
||||
_("Variables"),
|
||||
"res/actions/var.png")
|
||||
@@ -1126,8 +1131,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
|
||||
obj.AddExpression("AngleToObject",
|
||||
_("Angle between two objects"),
|
||||
_("Compute the angle between two objects. If you need the "
|
||||
"angle to an arbitrary position, use AngleToPosition."),
|
||||
_("Compute the angle between two objects (in degrees). "
|
||||
"If you need the angle to an arbitrary position, "
|
||||
"use AngleToPosition."),
|
||||
_("Angle"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
@@ -1160,8 +1166,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddExpression("AngleToPosition",
|
||||
_("Angle between an object and a position"),
|
||||
_("Compute the angle between the object center and a "
|
||||
"\"target\" position. If you need the angle between two "
|
||||
"objects, use AngleToObject."),
|
||||
"\"target\" position (in degrees). If you need the angle "
|
||||
"between two objects, use AngleToObject."),
|
||||
_("Angle"),
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
@@ -1523,7 +1529,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"object will become the only one taken into account.\nIf "
|
||||
"the condition is inverted, the object to be intersected "
|
||||
"will be the farthest one within the ray radius."),
|
||||
_("Cast a ray from from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
|
||||
_("Cast a ray from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
|
||||
"against _PARAM0_, and save the "
|
||||
"result in _PARAM5_, _PARAM6_"),
|
||||
"",
|
||||
|
@@ -195,7 +195,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"number",
|
||||
"CameraAngle",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("the angle of rotation of a camera"),
|
||||
_("the angle of rotation of a camera (in degrees)"),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
@@ -221,7 +221,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Width"), "", true)
|
||||
.AddParameter("expression", _("Height"), "", true)
|
||||
@@ -256,7 +256,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.MarkAsComplex();
|
||||
@@ -272,7 +272,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.AddParameter("expression", _("Width"))
|
||||
@@ -290,7 +290,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.AddParameter(
|
||||
@@ -309,7 +309,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ZoomCamera",
|
||||
_("Change camera zoom"),
|
||||
_("Camera zoom"),
|
||||
_("Change camera zoom."),
|
||||
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
|
||||
"_PARAM3_)"),
|
||||
@@ -413,7 +413,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -426,7 +426,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -439,7 +439,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -576,7 +576,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetLayerDefaultZOrder",
|
||||
_("Change layer default Z order"),
|
||||
_("Layer default Z order"),
|
||||
_("Change the default Z order set to objects when they are "
|
||||
"created on a layer."),
|
||||
_("Set the default Z order of objects created on _PARAM1_ to "
|
||||
|
@@ -96,13 +96,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
_("Difference between two angles"),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First angle"))
|
||||
.AddParameter("expression", _("Second angle"));
|
||||
.AddParameter("expression", _("First angle, in degrees"))
|
||||
.AddParameter("expression", _("Second angle, in degrees"));
|
||||
|
||||
extension
|
||||
.AddExpression("AngleBetweenPositions",
|
||||
_("Angle between two positions"),
|
||||
_("Compute the angle between two positions."),
|
||||
_("Compute the angle between two positions (in degrees)."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("First point X position"))
|
||||
@@ -159,7 +159,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("acos",
|
||||
_("Arccosine"),
|
||||
_("Arccosine"),
|
||||
_("Arccosine, return an angle (in radian). "
|
||||
"`ToDeg` allows to convert it to degrees."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
@@ -175,7 +176,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("asin",
|
||||
_("Arcsine"),
|
||||
_("Arcsine"),
|
||||
_("Arcsine, return an angle (in radian). "
|
||||
"`ToDeg` allows to convert it to degrees."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
@@ -191,7 +193,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("atan",
|
||||
_("Arctangent"),
|
||||
_("Arctangent"),
|
||||
_("Arctangent, return an angle (in radian). "
|
||||
"`ToDeg` allows to convert it to degrees."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
@@ -258,7 +261,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("cos",
|
||||
_("Cosine"),
|
||||
_("Cosine of a number"),
|
||||
_("Cosine of an angle (in radian). "
|
||||
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
@@ -400,7 +404,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("sin",
|
||||
_("Sine"),
|
||||
_("Sine of a number"),
|
||||
_("Sine of an angle (in radian). "
|
||||
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
@@ -424,7 +429,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
extension
|
||||
.AddExpression("tan",
|
||||
_("Tangent"),
|
||||
_("Tangent of a number"),
|
||||
_("Tangent of an angle (in radian). "
|
||||
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
|
||||
"",
|
||||
"res/mathfunction.png")
|
||||
.AddParameter("expression", _("Expression"));
|
||||
|
@@ -112,7 +112,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SceneBackground",
|
||||
_("Change background color"),
|
||||
_("Background color"),
|
||||
_("Change the background color of the scene."),
|
||||
_("Set background color to _PARAM1_"),
|
||||
"",
|
||||
|
@@ -33,7 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.SetCategoryFullName(_("General"));
|
||||
|
||||
obj.AddAction("Opacity",
|
||||
_("Change sprite opacity"),
|
||||
_("Sprite opacity"),
|
||||
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
|
||||
"is opaque (default)."),
|
||||
_("the opacity"),
|
||||
|
@@ -25,8 +25,7 @@ namespace gd {
|
||||
|
||||
Animation SpriteObject::badAnimation;
|
||||
|
||||
SpriteObject::SpriteObject(gd::String name_)
|
||||
: Object(name_), updateIfNotVisible(false) {}
|
||||
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
|
||||
|
||||
SpriteObject::~SpriteObject(){};
|
||||
|
||||
|
@@ -36,11 +36,11 @@ namespace gd {
|
||||
* \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension
|
||||
* \ingroup SpriteObjectExtension
|
||||
*/
|
||||
class GD_CORE_API SpriteObject : public gd::Object {
|
||||
class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
public:
|
||||
SpriteObject(gd::String name_);
|
||||
SpriteObject();
|
||||
virtual ~SpriteObject();
|
||||
std::unique_ptr<gd::Object> Clone() const override {
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override {
|
||||
return gd::make_unique<SpriteObject>(*this);
|
||||
}
|
||||
|
||||
|
@@ -21,9 +21,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/timers-and-time");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(
|
||||
_("Timers and time")
|
||||
)
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Timers and time"))
|
||||
.SetIcon("res/conditions/timer24.png");
|
||||
|
||||
// Deprecated and replaced by CompareTimer
|
||||
@@ -138,7 +136,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ChangeTimeScale",
|
||||
_("Change time scale"),
|
||||
_("Time scale"),
|
||||
_("Change the time scale of the scene."),
|
||||
_("Set the time scale of the scene to _PARAM1_"),
|
||||
"",
|
||||
@@ -158,8 +156,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"res/timer.svg",
|
||||
"res/timer.svg")
|
||||
.AddParameter("expression", "Time to wait in seconds")
|
||||
.SetHelpPath("/all-features/timers-and-time/wait-action")
|
||||
.SetAsync();
|
||||
.SetHelpPath("/all-features/timers-and-time/wait-action");
|
||||
|
||||
extension
|
||||
.AddExpression("TimeDelta",
|
||||
|
@@ -55,7 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetWindowMargins",
|
||||
_("Change the window's margins"),
|
||||
_("Window's margins"),
|
||||
_("This action changes the margins, in pixels, between the "
|
||||
"game frame and the window borders."),
|
||||
_("Set margins of game window to "
|
||||
@@ -71,7 +71,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetGameResolutionSize",
|
||||
_("Change the resolution of the game"),
|
||||
_("Game resolution"),
|
||||
_("Changes the resolution of the game, effectively changing "
|
||||
"the game area size. This won't change the size of the "
|
||||
"window in which the game is running."),
|
||||
@@ -117,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetGameResolutionResizeMode",
|
||||
_("Change the game resolution resize mode"),
|
||||
_("Game resolution resize mode"),
|
||||
_("Set if the width or the height of the game resolution "
|
||||
"should be changed to fit the game window - or if the game "
|
||||
"resolution should not be updated automatically."),
|
||||
@@ -153,7 +153,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetWindowIcon",
|
||||
_("Change the window's icon"),
|
||||
_("Window's icon"),
|
||||
_("This action changes the icon of the game's window."),
|
||||
_("Use _PARAM1_ as the icon for the game's window."),
|
||||
"",
|
||||
@@ -164,7 +164,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
|
||||
extension
|
||||
.AddAction("SetWindowTitle",
|
||||
_("Change the window's title"),
|
||||
_("Window's title"),
|
||||
_("This action changes the title of the game's window."),
|
||||
_("Change window title to _PARAM1_"),
|
||||
"",
|
||||
|
@@ -14,6 +14,8 @@
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -29,21 +31,50 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
std::shared_ptr<gd::Behavior> instance_,
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance_)
|
||||
: extensionNamespace(extensionNamespace_),
|
||||
className(className_),
|
||||
iconFilename(icon24x24),
|
||||
instance(instance_),
|
||||
sharedDatasInstance(sharedDatasInstance_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
sharedDatasInstance(sharedDatasInstance_),
|
||||
isEventBased(false) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
SetDefaultName(gd::String(defaultName_));
|
||||
SetGroup(group_);
|
||||
className = className_;
|
||||
iconFilename = icon24x24;
|
||||
#endif
|
||||
|
||||
if (!instance) {
|
||||
gd::LogFatalError(
|
||||
"Trying to create a BehaviorMetadata that has no "
|
||||
"behavior. This will crash - please double check that the "
|
||||
"BehaviorMetadata is valid for: " + name_);
|
||||
}
|
||||
|
||||
if (instance) instance->SetTypeName(name_);
|
||||
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(name_);
|
||||
}
|
||||
|
||||
BehaviorMetadata::BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon24x24_): BehaviorMetadata(
|
||||
extensionNamespace,
|
||||
name_,
|
||||
fullname_,
|
||||
// Default name is the name
|
||||
name_,
|
||||
description_,
|
||||
group_,
|
||||
icon24x24_,
|
||||
// Class name is the name, actually unused
|
||||
name_,
|
||||
// It is only used to get the name for GetName.
|
||||
gd::make_unique<gd::Behavior>("", name_),
|
||||
nullptr){
|
||||
isEventBased = true;
|
||||
};
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
@@ -52,7 +83,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
const gd::String& group,
|
||||
const gd::String& icon,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String nameWithNamespace =
|
||||
extensionNamespace.empty() ? name : extensionNamespace + name;
|
||||
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
|
||||
@@ -66,7 +96,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
.SetHelpPath(GetHelpPath())
|
||||
.SetIsBehaviorInstruction();
|
||||
return conditionsInfos[nameWithNamespace];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddAction(
|
||||
@@ -77,7 +106,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
|
||||
const gd::String& group,
|
||||
const gd::String& icon,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String nameWithNamespace =
|
||||
extensionNamespace.empty() ? name : extensionNamespace + name;
|
||||
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
|
||||
@@ -91,7 +119,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
|
||||
.SetHelpPath(GetHelpPath())
|
||||
.SetIsBehaviorInstruction();
|
||||
return actionsInfos[nameWithNamespace];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
|
||||
@@ -102,7 +129,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
|
||||
const gd::String& group,
|
||||
const gd::String& icon,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String nameWithNamespace =
|
||||
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
|
||||
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
|
||||
@@ -116,7 +142,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
|
||||
.SetHelpPath(GetHelpPath())
|
||||
.SetIsBehaviorInstruction();
|
||||
return conditionsInfos[nameWithNamespace];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
|
||||
@@ -127,7 +152,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
|
||||
const gd::String& group,
|
||||
const gd::String& icon,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String nameWithNamespace =
|
||||
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
|
||||
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
|
||||
@@ -141,7 +165,6 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
|
||||
.SetHelpPath(GetHelpPath())
|
||||
.SetIsBehaviorInstruction();
|
||||
return actionsInfos[nameWithNamespace];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
|
||||
@@ -150,7 +173,6 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
|
||||
const gd::String& description,
|
||||
const gd::String& group,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
// Be careful, behaviors expression do not have namespace (not necessary as
|
||||
// we refer to the behavior name in the expression).
|
||||
expressionsInfos[name] = ExpressionMetadata("number",
|
||||
@@ -162,7 +184,6 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
|
||||
smallicon)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return expressionsInfos[name];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
|
||||
@@ -171,7 +192,6 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
|
||||
const gd::String& description,
|
||||
const gd::String& group,
|
||||
const gd::String& smallicon) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
// Be careful, behaviors expression do not have namespace (not necessary as
|
||||
// we refer to the behavior name in the expression).
|
||||
strExpressionsInfos[name] = ExpressionMetadata("string",
|
||||
@@ -183,7 +203,6 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
|
||||
smallicon)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return strExpressionsInfos[name];
|
||||
#endif
|
||||
}
|
||||
|
||||
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
|
||||
@@ -288,7 +307,6 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
|
||||
expression, condition, action);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newActionName;
|
||||
@@ -356,49 +374,44 @@ gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
|
||||
|
||||
return strExpressionsInfos[newNameWithNamespace];
|
||||
}
|
||||
#endif
|
||||
|
||||
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
fullname = fullname_;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
BehaviorMetadata& BehaviorMetadata::SetDefaultName(
|
||||
const gd::String& defaultName_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
defaultName = defaultName_;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
BehaviorMetadata& BehaviorMetadata::SetDescription(
|
||||
const gd::String& description_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
description = description_;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
BehaviorMetadata& BehaviorMetadata::SetGroup(const gd::String& group_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
group = group_;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
BehaviorMetadata& BehaviorMetadata::SetIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
BehaviorMetadata& BehaviorMetadata::AddIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
|
||||
includeFiles.end())
|
||||
includeFiles.push_back(includeFile);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
BehaviorMetadata& BehaviorMetadata::AddRequiredFile(
|
||||
const gd::String& requiredFile) {
|
||||
if (std::find(requiredFiles.begin(), requiredFiles.end(), requiredFile) ==
|
||||
requiredFiles.end())
|
||||
requiredFiles.push_back(requiredFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -407,13 +420,25 @@ const gd::String& BehaviorMetadata::GetName() const {
|
||||
}
|
||||
|
||||
gd::Behavior& BehaviorMetadata::Get() const {
|
||||
if (!instance)
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
if (!instance) {
|
||||
gd::LogFatalError(
|
||||
"Trying to get a behavior from a BehaviorMetadata that has no "
|
||||
"behavior. This will crash - please double check that the "
|
||||
"BehaviorMetadata is valid.");
|
||||
|
||||
"BehaviorMetadata is valid for: " + className);
|
||||
}
|
||||
return *instance;
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -38,6 +38,20 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& className_,
|
||||
std::shared_ptr<gd::Behavior> instance,
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
|
||||
|
||||
/**
|
||||
* \brief Construct a behavior metadata, without "blueprint" behavior.
|
||||
*
|
||||
* \note This is used by events based behaviors.
|
||||
*/
|
||||
BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon24x24_);
|
||||
|
||||
BehaviorMetadata(){};
|
||||
virtual ~BehaviorMetadata(){};
|
||||
|
||||
@@ -195,6 +209,13 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing required files.
|
||||
* \note These files are required for the behavior to work,
|
||||
* but they are not executable.
|
||||
*/
|
||||
BehaviorMetadata& AddRequiredFile(const gd::String& requiredFile);
|
||||
|
||||
/**
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
@@ -239,16 +260,20 @@ class GD_CORE_API BehaviorMetadata {
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::Behavior, handling behavior contents.
|
||||
*
|
||||
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior
|
||||
* are using EventBasedBehavior.
|
||||
*/
|
||||
gd::Behavior& Get() const;
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
|
||||
* shared data, if any (nullptr if none).
|
||||
*
|
||||
* \note Returns nullptr for events based behaviors as they don't declare
|
||||
* shared data yet.
|
||||
*/
|
||||
gd::BehaviorsSharedData* GetSharedDataInstance() const {
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
gd::BehaviorsSharedData* GetSharedDataInstance() const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
@@ -271,30 +296,29 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
|
||||
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
|
||||
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
|
||||
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
|
||||
|
||||
std::vector<gd::String> includeFiles;
|
||||
std::vector<gd::String> requiredFiles;
|
||||
gd::String className;
|
||||
#endif
|
||||
|
||||
private:
|
||||
gd::String extensionNamespace;
|
||||
gd::String helpPath;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String fullname;
|
||||
gd::String defaultName;
|
||||
gd::String description;
|
||||
gd::String group;
|
||||
gd::String iconFilename;
|
||||
gd::String objectType;
|
||||
#endif
|
||||
|
||||
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
|
||||
std::shared_ptr<gd::Behavior> instance;
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
|
||||
bool isEventBased;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -22,7 +22,6 @@ InstructionMetadata::InstructionMetadata()
|
||||
canHaveSubInstructions(false),
|
||||
hidden(true),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
@@ -46,7 +45,6 @@ InstructionMetadata::InstructionMetadata(const gd::String& extensionNamespace_,
|
||||
extensionNamespace(extensionNamespace_),
|
||||
hidden(false),
|
||||
usageComplexity(5),
|
||||
isAsync(false),
|
||||
isPrivate(false),
|
||||
isObjectInstruction(false),
|
||||
isBehaviorInstruction(false) {}
|
||||
|
@@ -6,10 +6,10 @@
|
||||
|
||||
#ifndef INSTRUCTIONMETADATA_H
|
||||
#define INSTRUCTIONMETADATA_H
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -104,16 +104,16 @@ class GD_CORE_API InstructionMetadata {
|
||||
* background, executing the instructions following it before the frame after
|
||||
* it resolved.
|
||||
*/
|
||||
bool IsAsync() const { return isAsync; }
|
||||
bool IsAsync() const {
|
||||
return !codeExtraInformation.asyncFunctionCallName.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction is asynchronous - it will be running in the
|
||||
* background, executing the instructions following it before the frame after
|
||||
* it resolved.
|
||||
* Check if the instruction asynchronicity is optional. If it is, it can either
|
||||
* be used synchronously or asynchronously, with one function for each.
|
||||
*/
|
||||
InstructionMetadata &SetAsync() {
|
||||
isAsync = true;
|
||||
return *this;
|
||||
bool IsOptionallyAsync() const {
|
||||
return IsAsync() && !codeExtraInformation.functionCallName.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,14 +319,26 @@ class GD_CORE_API InstructionMetadata {
|
||||
virtual ~ExtraInformation(){};
|
||||
|
||||
/**
|
||||
* Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName_) {
|
||||
functionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be called in
|
||||
* the generated code. This function should return an asynchronous task
|
||||
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to call.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName_) {
|
||||
asyncFunctionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare if the instruction being declared is somewhat manipulating in a
|
||||
* standard way.
|
||||
@@ -354,7 +366,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString").SetIncludeFile("MyExtension/TextObject.h");
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
|
||||
*
|
||||
* DECLARE_END_OBJECT_ACTION()
|
||||
* \endcode
|
||||
@@ -422,6 +434,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
|
||||
|
||||
gd::String functionCallName;
|
||||
gd::String asyncFunctionCallName;
|
||||
gd::String type;
|
||||
AccessType accessType;
|
||||
gd::String optionalAssociatedInstruction;
|
||||
@@ -454,15 +467,26 @@ class GD_CORE_API InstructionMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the function that should be called when generating the source
|
||||
* code from events.
|
||||
* \param functionName the name of the function to call
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetFunctionName(functionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be called in
|
||||
* the generated code. This function should return an asynchronous task
|
||||
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to call.
|
||||
* \note Shortcut for `codeExtraInformation.SetAsyncFunctionName`.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetAsyncFunctionName(functionName);
|
||||
}
|
||||
|
||||
std::vector<ParameterMetadata> parameters;
|
||||
|
||||
private:
|
||||
@@ -479,7 +503,6 @@ class GD_CORE_API InstructionMetadata {
|
||||
int usageComplexity; ///< Evaluate the instruction from 0 (simple&easy to
|
||||
///< use) to 10 (complex to understand)
|
||||
bool isPrivate;
|
||||
bool isAsync;
|
||||
bool isObjectInstruction;
|
||||
bool isBehaviorInstruction;
|
||||
gd::String requiredBaseObjectCapability;
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -22,45 +23,53 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24,
|
||||
std::shared_ptr<gd::Object> blueprintObject_)
|
||||
: extensionNamespace(extensionNamespace_),
|
||||
blueprintObject(blueprintObject_) {
|
||||
name = name_;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
iconFilename = icon24x24;
|
||||
#endif
|
||||
createFunPtr =
|
||||
[blueprintObject_](gd::String name) -> std::unique_ptr<gd::Object> {
|
||||
if (blueprintObject_ == std::shared_ptr<gd::Object>()) {
|
||||
std::cout
|
||||
<< "Error: Unable to create object. Have you declared an extension "
|
||||
"(or ObjectMetadata) without specifying an object as blueprint?"
|
||||
<< std::endl;
|
||||
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_)
|
||||
: ObjectMetadata(extensionNamespace_,
|
||||
name_,
|
||||
fullname_,
|
||||
description_,
|
||||
icon24x24,
|
||||
[blueprintObject_]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
if (blueprintObject_ == std::shared_ptr<gd::ObjectConfiguration>()) {
|
||||
gd::LogFatalError(
|
||||
"Error: Unable to create object. Have you declared an extension "
|
||||
"(or ObjectMetadata) without specifying an object as blueprint?");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::Object> newObject = blueprintObject_->Clone();
|
||||
newObject->SetName(name);
|
||||
return newObject;
|
||||
};
|
||||
return blueprintObject_->Clone();
|
||||
}) {
|
||||
blueprintObject = blueprintObject_;
|
||||
}
|
||||
|
||||
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24)
|
||||
: ObjectMetadata(extensionNamespace_,
|
||||
name_,
|
||||
fullname_,
|
||||
description_,
|
||||
icon24x24,
|
||||
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
gd::LogFatalError(
|
||||
"Error: Event-based objects don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
return nullptr;
|
||||
}) {}
|
||||
|
||||
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24,
|
||||
CreateFunPtr createFunPtrP)
|
||||
: extensionNamespace(extensionNamespace_) {
|
||||
name = name_;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
: name(name_),
|
||||
iconFilename(icon24x24),
|
||||
createFunPtr(createFunPtrP),
|
||||
extensionNamespace(extensionNamespace_) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
iconFilename = icon24x24;
|
||||
#endif
|
||||
createFunPtr = createFunPtrP;
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& ObjectMetadata::AddCondition(
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class InstructionMetadata;
|
||||
@@ -20,7 +21,7 @@ class MultipleInstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
namespace gd {
|
||||
@@ -42,7 +43,17 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24_,
|
||||
std::shared_ptr<gd::Object> blueprintObject_);
|
||||
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
|
||||
/**
|
||||
* \brief Construct an object metadata, without "blueprint" object
|
||||
*
|
||||
* \note This is used by events based objects.
|
||||
*/
|
||||
ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon24x24_);
|
||||
|
||||
/**
|
||||
* \brief Construct an object metadata, with a function that will be called
|
||||
@@ -304,10 +315,12 @@ class GD_CORE_API ObjectMetadata {
|
||||
gd::String categoryFullName;
|
||||
std::set<gd::String> unsupportedBaseObjectCapabilities;
|
||||
|
||||
std::shared_ptr<gd::Object>
|
||||
std::shared_ptr<gd::ObjectConfiguration>
|
||||
blueprintObject; ///< The "blueprint" object to be copied when a new
|
||||
///< object is asked. Can be null in case a creation
|
||||
///< function is passed.
|
||||
///< function is passed or for events based objects
|
||||
///< (CustomObject are using EventBasedObject, they
|
||||
///< don't need blueprints).
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -7,7 +7,9 @@
|
||||
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -91,24 +93,22 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
|
||||
return std::shared_ptr<gd::PlatformExtension>();
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::Object> Platform::CreateObject(
|
||||
gd::String type, const gd::String& name) const {
|
||||
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
|
||||
gd::String type) const {
|
||||
if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
|
||||
std::cout << "Tried to create an object with an unknown type: " << type
|
||||
<< " for platform " << GetName() << "!" << std::endl;
|
||||
gd::LogWarning("Tried to create an object with an unknown type: " + type
|
||||
+ " for platform " + GetName() + "!");
|
||||
type = "";
|
||||
if (creationFunctionTable.find("") == creationFunctionTable.end()) {
|
||||
std::cout << "Unable to create a Base object!" << std::endl;
|
||||
gd::LogError("Unable to create a Base object!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new object with the type we want.
|
||||
std::unique_ptr<gd::Object> object =
|
||||
(creationFunctionTable.find(type)->second)(name);
|
||||
object->SetType(type);
|
||||
|
||||
return std::unique_ptr<gd::Object>(std::move(object));
|
||||
auto objectConfiguration = (creationFunctionTable.find(type)->second)();
|
||||
objectConfiguration->SetType(type);
|
||||
return objectConfiguration;
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
@@ -16,6 +16,7 @@ namespace gd {
|
||||
class InstructionsMetadataHolder;
|
||||
class Project;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
class Behavior;
|
||||
class BehaviorMetadata;
|
||||
class ObjectMetadata;
|
||||
@@ -26,7 +27,7 @@ class LayoutEditorCanvas;
|
||||
class ProjectExporter;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
#undef CreateEvent
|
||||
@@ -146,8 +147,8 @@ class GD_CORE_API Platform {
|
||||
/**
|
||||
* \brief Create an object of given type with the specified name.
|
||||
*/
|
||||
std::unique_ptr<gd::Object> CreateObject(gd::String type,
|
||||
const gd::String& name) const;
|
||||
std::unique_ptr<gd::ObjectConfiguration> CreateObjectConfiguration(
|
||||
gd::String type) const;
|
||||
|
||||
/**
|
||||
* \brief Create an event of given type
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/PlatformManager.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
@@ -231,7 +232,7 @@ gd::ObjectMetadata& PlatformExtension::AddObject(
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& icon24x24,
|
||||
std::shared_ptr<gd::Object> instance) {
|
||||
std::shared_ptr<gd::ObjectConfiguration> instance) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
@@ -244,6 +245,21 @@ gd::ObjectMetadata& PlatformExtension::AddObject(
|
||||
return objectsInfos[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::ObjectMetadata& PlatformExtension::AddEventsBasedObject(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& icon24x24) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
fullname,
|
||||
description,
|
||||
icon24x24)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return objectsInfos[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::BehaviorMetadata& PlatformExtension::AddBehavior(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
@@ -269,6 +285,23 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::BehaviorMetadata& PlatformExtension::AddEventsBasedBehavior(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& group,
|
||||
const gd::String& icon24x24) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
behaviorsInfo[nameWithNamespace] = BehaviorMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
fullname,
|
||||
description,
|
||||
group,
|
||||
icon24x24)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::EffectMetadata& PlatformExtension::AddEffect(const gd::String& name) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
effectsMetadata[nameWithNamespace] = EffectMetadata(nameWithNamespace);
|
||||
|
@@ -37,9 +37,10 @@ class ArbitraryResourceWorker;
|
||||
class BehaviorsSharedData;
|
||||
class Behavior;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
} // namespace gd
|
||||
|
||||
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
|
||||
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
|
||||
CreateFunPtr;
|
||||
|
||||
namespace gd {
|
||||
@@ -242,7 +243,21 @@ class GD_CORE_API PlatformExtension {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon_,
|
||||
std::shared_ptr<gd::Object> instance);
|
||||
std::shared_ptr<gd::ObjectConfiguration> instance);
|
||||
|
||||
/**
|
||||
* \brief Declare a new events based object as being part of the extension.
|
||||
*
|
||||
* \param name The name of the object
|
||||
* \param fullname The user friendly name of the object
|
||||
* \param description The user friendly description of the object
|
||||
* \param icon The icon of the object.
|
||||
*/
|
||||
gd::ObjectMetadata& AddEventsBasedObject(
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& icon_);
|
||||
|
||||
/**
|
||||
* \brief Declare a new behavior as being part of the extension.
|
||||
@@ -267,6 +282,21 @@ class GD_CORE_API PlatformExtension {
|
||||
std::shared_ptr<gd::Behavior> instance,
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
|
||||
|
||||
/**
|
||||
* \brief Declare a new events based behavior as being part of the extension.
|
||||
*
|
||||
* \param name The name of the behavior
|
||||
* \param fullname The user friendly name of the behavior
|
||||
* \param description The user friendly description of the behavior
|
||||
* \param icon The icon of the behavior.
|
||||
*/
|
||||
gd::BehaviorMetadata& AddEventsBasedBehavior(
|
||||
const gd::String& name_,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_);
|
||||
|
||||
/**
|
||||
* \brief Declare a new effect as being part of the extension.
|
||||
* \param name The internal name of the effect (also called effect type).
|
||||
|
@@ -25,8 +25,8 @@ gd::ObjectMetadata& PlatformExtension::AddObject(const gd::String& name,
|
||||
fullname,
|
||||
description,
|
||||
icon24x24,
|
||||
[](gd::String name) -> std::unique_ptr<gd::Object> {
|
||||
return gd::make_unique<T>(name);
|
||||
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
|
||||
return gd::make_unique<T>();
|
||||
})
|
||||
.SetHelpPath(GetHelpPath());
|
||||
|
||||
|
25
Core/GDCore/IDE/Events/BehaviorTypeRenamer.cpp
Normal file
25
Core/GDCore/IDE/Events/BehaviorTypeRenamer.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "BehaviorTypeRenamer.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void BehaviorTypeRenamer::DoVisitObject(gd::Object& object) {
|
||||
};
|
||||
|
||||
void BehaviorTypeRenamer::DoVisitBehavior(gd::Behavior& behavior) {
|
||||
if (behavior.GetTypeName() == oldType) {
|
||||
behavior.SetTypeName(newType);
|
||||
}
|
||||
};
|
||||
|
||||
BehaviorTypeRenamer::~BehaviorTypeRenamer() {}
|
||||
|
||||
} // namespace gd
|
43
Core/GDCore/IDE/Events/BehaviorTypeRenamer.h
Normal file
43
Core/GDCore/IDE/Events/BehaviorTypeRenamer.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_BEHAVIORTYPERENAMER_H
|
||||
#define GDCORE_BEHAVIORTYPERENAMER_H
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
class GD_CORE_API BehaviorTypeRenamer : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
BehaviorTypeRenamer(const gd::Project& project_,
|
||||
const gd::String& oldType_,
|
||||
const gd::String& newType_)
|
||||
: project(project_), oldType(oldType_), newType(newType_){};
|
||||
virtual ~BehaviorTypeRenamer();
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
void DoVisitBehavior(gd::Behavior& behavior) override;
|
||||
|
||||
const gd::Project& project;
|
||||
gd::String oldType;
|
||||
gd::String newType;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
||||
|
||||
#endif // GDCORE_BEHAVIORTYPERENAMER_H
|
24
Core/GDCore/IDE/Events/CustomObjectTypeRenamer.cpp
Normal file
24
Core/GDCore/IDE/Events/CustomObjectTypeRenamer.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "CustomObjectTypeRenamer.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void CustomObjectTypeRenamer::DoVisitObject(gd::Object& object) {
|
||||
if (object.GetType() == oldType) {
|
||||
object.SetType(newType);
|
||||
}
|
||||
};
|
||||
|
||||
void CustomObjectTypeRenamer::DoVisitBehavior(gd::Behavior& behavior) {};
|
||||
|
||||
CustomObjectTypeRenamer::~CustomObjectTypeRenamer() {}
|
||||
|
||||
} // namespace gd
|
43
Core/GDCore/IDE/Events/CustomObjectTypeRenamer.h
Normal file
43
Core/GDCore/IDE/Events/CustomObjectTypeRenamer.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_CUSTOMOBJECTTYPERENAMER_H
|
||||
#define GDCORE_CUSTOMOBJECTTYPERENAMER_H
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
class GD_CORE_API CustomObjectTypeRenamer : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
CustomObjectTypeRenamer(const gd::Project& project_,
|
||||
const gd::String& oldType_,
|
||||
const gd::String& newType_)
|
||||
: project(project_), oldType(oldType_), newType(newType_){};
|
||||
virtual ~CustomObjectTypeRenamer();
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
void DoVisitBehavior(gd::Behavior& behavior) override;
|
||||
|
||||
const gd::Project& project;
|
||||
gd::String oldType;
|
||||
gd::String newType;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
||||
|
||||
#endif // GDCORE_CUSTOMOBJECTTYPERENAMER_H
|
41
Core/GDCore/IDE/Events/EventsLeaderboardsLister.cpp
Normal file
41
Core/GDCore/IDE/Events/EventsLeaderboardsLister.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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/EventsLeaderboardsLister.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool EventsLeaderboardsLister::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
const gd::InstructionMetadata& instrInfo =
|
||||
isCondition ? MetadataProvider::GetConditionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType());
|
||||
|
||||
for (int i = 0; i < instruction.GetParametersCount() &&
|
||||
i < instrInfo.GetParametersCount();
|
||||
++i)
|
||||
if (instrInfo.GetParameter(i).type == "leaderboardId") {
|
||||
leaderboardIds.insert(instruction.GetParameter(i).GetPlainString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsLeaderboardsLister::~EventsLeaderboardsLister() {}
|
||||
|
||||
} // namespace gd
|
48
Core/GDCore/IDE/Events/EventsLeaderboardsLister.h
Normal file
48
Core/GDCore/IDE/Events/EventsLeaderboardsLister.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EventsLeaderboardsLister_H
|
||||
#define EventsLeaderboardsLister_H
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Project;
|
||||
class EventsList;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief List the leaderboard ids in the instructions.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API EventsLeaderboardsLister : public ArbitraryEventsWorker {
|
||||
public:
|
||||
EventsLeaderboardsLister(gd::Project& project_) : project(project_){};
|
||||
virtual ~EventsLeaderboardsLister();
|
||||
|
||||
/**
|
||||
* Return the values of all leaderboardIds found in the events.
|
||||
*/
|
||||
const std::set<gd::String>& GetLeaderboardIds() { return leaderboardIds; }
|
||||
|
||||
private:
|
||||
virtual bool DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition);
|
||||
|
||||
std::set<gd::String> leaderboardIds;
|
||||
gd::Project& project;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // EventsLeaderboardsLister_H
|
49
Core/GDCore/IDE/Events/EventsLeaderboardsRenamer.cpp
Normal file
49
Core/GDCore/IDE/Events/EventsLeaderboardsRenamer.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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/EventsLeaderboardsRenamer.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool EventsLeaderboardsRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
const gd::InstructionMetadata& instrInfo =
|
||||
isCondition ? MetadataProvider::GetConditionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
project.GetCurrentPlatform(), instruction.GetType());
|
||||
|
||||
for (int i = 0; i < instruction.GetParametersCount() &&
|
||||
i < instrInfo.GetParametersCount();
|
||||
++i) {
|
||||
const gd::ParameterMetadata parameter = instrInfo.GetParameter(i);
|
||||
|
||||
if (parameter.type == "leaderboardId") {
|
||||
const gd::String leaderboardId =
|
||||
instruction.GetParameter(i).GetPlainString();
|
||||
|
||||
if (leaderboardIdMap.find(leaderboardId) != leaderboardIdMap.end()) {
|
||||
instruction.SetParameter(i, leaderboardIdMap[leaderboardId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsLeaderboardsRenamer::~EventsLeaderboardsRenamer() {}
|
||||
|
||||
} // namespace gd
|
46
Core/GDCore/IDE/Events/EventsLeaderboardsRenamer.h
Normal file
46
Core/GDCore/IDE/Events/EventsLeaderboardsRenamer.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 EventsLeaderboardsRenamer_H
|
||||
#define EventsLeaderboardsRenamer_H
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Project;
|
||||
class EventsList;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Replace the leaderboard ids in the instructions.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API EventsLeaderboardsRenamer : public ArbitraryEventsWorker {
|
||||
public:
|
||||
EventsLeaderboardsRenamer(
|
||||
gd::Project& project_,
|
||||
const std::map<gd::String, gd::String>& leaderboardIdMap_)
|
||||
: project(project_), leaderboardIdMap(leaderboardIdMap_){};
|
||||
virtual ~EventsLeaderboardsRenamer();
|
||||
|
||||
private:
|
||||
virtual bool DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition);
|
||||
|
||||
std::map<gd::String, gd::String> leaderboardIdMap;
|
||||
gd::Project& project;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // EventsLeaderboardsRenamer_H
|
@@ -19,6 +19,7 @@
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/IDE/Events/InstructionSentenceFormatter.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -121,7 +122,7 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
|
||||
bool hasDoneRenaming;
|
||||
const gd::String& objectName;
|
||||
const gd::String& objectNewName;
|
||||
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::ObjectsContainer &globalObjectsContainer;
|
||||
const gd::ObjectsContainer &objectsContainer;
|
||||
@@ -216,7 +217,7 @@ class GD_CORE_API ExpressionObjectFinder : public ExpressionParser2NodeWorker {
|
||||
private:
|
||||
bool hasObject;
|
||||
const gd::String& objectName;
|
||||
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::ObjectsContainer &globalObjectsContainer;
|
||||
const gd::ObjectsContainer &objectsContainer;
|
||||
@@ -411,8 +412,8 @@ void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
|
||||
}
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -434,7 +435,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
"number", instrInfos.parameters[pNb].type)) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, project, layout, "number", *node, name)) {
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, globalObjectsContainer, objectsContainer, "number", *node, name)) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
@@ -444,7 +445,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
"string", instrInfos.parameters[pNb].type)) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, project, layout, "string", *node, name)) {
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, globalObjectsContainer, objectsContainer, "string", *node, name)) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
@@ -458,8 +459,8 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
} else if (!actions[aId].GetSubInstructions().empty())
|
||||
somethingModified =
|
||||
RemoveObjectInActions(platform,
|
||||
project,
|
||||
layout,
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
actions[aId].GetSubInstructions(),
|
||||
name) ||
|
||||
somethingModified;
|
||||
@@ -470,8 +471,8 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInConditions(
|
||||
const gd::Platform& platform,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -494,7 +495,7 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
"number", instrInfos.parameters[pNb].type)) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, project, layout, "number", *node, name)) {
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, globalObjectsContainer, objectsContainer, "number", *node, name)) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
@@ -504,7 +505,7 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
"string", instrInfos.parameters[pNb].type)) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, project, layout, "string", *node, name)) {
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, globalObjectsContainer, objectsContainer, "string", *node, name)) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
@@ -518,8 +519,8 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
} else if (!conditions[cId].GetSubInstructions().empty())
|
||||
somethingModified =
|
||||
RemoveObjectInConditions(platform,
|
||||
project,
|
||||
layout,
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
conditions[cId].GetSubInstructions(),
|
||||
name) ||
|
||||
somethingModified;
|
||||
@@ -529,8 +530,8 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
}
|
||||
|
||||
void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
gd::EventsList& events,
|
||||
gd::String name) {
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
@@ -538,19 +539,19 @@ void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
|
||||
events[i].GetAllConditionsVectors();
|
||||
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
|
||||
bool conditionsModified = RemoveObjectInConditions(
|
||||
platform, project, layout, *conditionsVectors[j], name);
|
||||
platform, globalObjectsContainer, objectsContainer, *conditionsVectors[j], name);
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList*> actionsVectors =
|
||||
events[i].GetAllActionsVectors();
|
||||
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
|
||||
bool actionsModified = RemoveObjectInActions(
|
||||
platform, project, layout, *actionsVectors[j], name);
|
||||
platform, globalObjectsContainer, objectsContainer, *actionsVectors[j], name);
|
||||
}
|
||||
|
||||
if (events[i].CanHaveSubEvents())
|
||||
RemoveObjectInEvents(
|
||||
platform, project, layout, events[i].GetSubEvents(), name);
|
||||
platform, globalObjectsContainer, objectsContainer, events[i].GetSubEvents(), name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,6 +566,8 @@ std::vector<EventsSearchResult> EventsRefactorer::ReplaceStringInEvents(
|
||||
bool inActions,
|
||||
bool inEventStrings) {
|
||||
vector<EventsSearchResult> modifiedEvents;
|
||||
if (toReplace.empty()) return modifiedEvents;
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
bool eventModified = false;
|
||||
if (inConditions) {
|
||||
|
@@ -78,13 +78,16 @@ class GD_CORE_API ExpressionParameterMover
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
|
||||
void OnVisitFunctionCallNode(FunctionCallNode& node) override {
|
||||
auto moveParameter =
|
||||
[this](std::vector<std::unique_ptr<gd::ExpressionNode>>& parameters) {
|
||||
if (oldIndex >= parameters.size() || newIndex >= parameters.size())
|
||||
[this](std::vector<std::unique_ptr<gd::ExpressionNode>>& parameters, int firstWrittenParameterIndex) {
|
||||
size_t newExpressionIndex = newIndex - firstWrittenParameterIndex;
|
||||
size_t oldExpressionIndex = oldIndex - firstWrittenParameterIndex;
|
||||
|
||||
if (oldExpressionIndex >= parameters.size() || newExpressionIndex >= parameters.size())
|
||||
return;
|
||||
|
||||
auto movedParameterNode = std::move(parameters[oldIndex]);
|
||||
parameters.erase(parameters.begin() + oldIndex);
|
||||
parameters.insert(parameters.begin() + newIndex,
|
||||
auto movedParameterNode = std::move(parameters[oldExpressionIndex]);
|
||||
parameters.erase(parameters.begin() + oldExpressionIndex);
|
||||
parameters.insert(parameters.begin() + newExpressionIndex,
|
||||
std::move(movedParameterNode));
|
||||
};
|
||||
|
||||
@@ -92,10 +95,13 @@ class GD_CORE_API ExpressionParameterMover
|
||||
if (behaviorType.empty() && !objectType.empty() &&
|
||||
!node.objectName.empty()) {
|
||||
// Move parameter of an object function
|
||||
// This refactor only applies on events object functions
|
||||
// and events object functions doesn't exist yet.
|
||||
// This is a dead code.
|
||||
const gd::String& thisObjectType = gd::GetTypeOfObject(
|
||||
globalObjectsContainer, objectsContainer, node.objectName);
|
||||
if (thisObjectType == objectType) {
|
||||
moveParameter(node.parameters);
|
||||
moveParameter(node.parameters, 1);
|
||||
hasDoneMoving = true;
|
||||
}
|
||||
} else if (!behaviorType.empty() && !node.behaviorName.empty()) {
|
||||
@@ -103,12 +109,12 @@ class GD_CORE_API ExpressionParameterMover
|
||||
const gd::String& thisBehaviorType = gd::GetTypeOfBehavior(
|
||||
globalObjectsContainer, objectsContainer, node.behaviorName);
|
||||
if (thisBehaviorType == behaviorType) {
|
||||
moveParameter(node.parameters);
|
||||
moveParameter(node.parameters, 2);
|
||||
hasDoneMoving = true;
|
||||
}
|
||||
} else if (behaviorType.empty() && objectType.empty()) {
|
||||
// Move parameter of a free function
|
||||
moveParameter(node.parameters);
|
||||
moveParameter(node.parameters, 1);
|
||||
hasDoneMoving = true;
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
@@ -29,7 +29,7 @@ void UsedExtensionsFinder::DoVisitObject(gd::Object& object) {
|
||||
|
||||
// Behaviors scanner
|
||||
|
||||
void UsedExtensionsFinder::DoVisitBehavior(gd::BehaviorContent& behavior) {
|
||||
void UsedExtensionsFinder::DoVisitBehavior(gd::Behavior& behavior) {
|
||||
usedExtensions.insert(
|
||||
gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
|
||||
project.GetCurrentPlatform(), behavior.GetTypeName())
|
||||
|
@@ -16,7 +16,7 @@
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
class BehaviorContent;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -38,7 +38,7 @@ class GD_CORE_API UsedExtensionsFinder
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
|
||||
// Behavior Visitor
|
||||
void DoVisitBehavior(gd::BehaviorContent& behavior) override;
|
||||
void DoVisitBehavior(gd::Behavior& behavior) override;
|
||||
|
||||
// Instructions Visitor
|
||||
bool DoVisitInstruction(gd::Instruction& instruction,
|
||||
|
@@ -8,9 +8,10 @@
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
//#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/EventsFunction.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -72,4 +73,39 @@ void EventsFunctionTools::BehaviorEventsFunctionToObjectsContainer(
|
||||
}
|
||||
}
|
||||
|
||||
void EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& outputGlobalObjectsContainer,
|
||||
gd::ObjectsContainer& outputObjectsContainer) {
|
||||
// The context is build the same way as free function...
|
||||
FreeEventsFunctionToObjectsContainer(project,
|
||||
eventsFunction,
|
||||
outputGlobalObjectsContainer,
|
||||
outputObjectsContainer);
|
||||
|
||||
// TODO EBO Use a constant instead a hard coded value "Object".
|
||||
// ...and has an "Object" by convention...
|
||||
if (!outputObjectsContainer.HasObjectNamed("Object")) {
|
||||
gd::LogWarning("No \"Object\" in a function of an events based object: " +
|
||||
eventsFunction.GetName() +
|
||||
". This means this function is likely misconfigured (check "
|
||||
"its parameters).");
|
||||
return;
|
||||
}
|
||||
if (eventsBasedObject.HasObjectNamed("Object")) {
|
||||
gd::LogWarning("Child-objects can't be named Object because it's reserved"
|
||||
"for the parent. ");
|
||||
return;
|
||||
}
|
||||
|
||||
// ...and its children.
|
||||
auto &children = eventsBasedObject.GetObjects();
|
||||
for (auto &childObject : children) {
|
||||
auto child = childObject.get();
|
||||
outputObjectsContainer.InsertObject(*child, children.size());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -14,6 +14,7 @@ class ObjectsContainer;
|
||||
class ParameterMetadata;
|
||||
class EventsFunction;
|
||||
class EventsBasedBehavior;
|
||||
class EventsBasedObject;
|
||||
class Expression;
|
||||
} // namespace gd
|
||||
|
||||
@@ -51,6 +52,21 @@ class GD_CORE_API EventsFunctionTools {
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& outputGlobalObjectsContainer,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
/**
|
||||
* \brief Given a parent-object events function, initialize the given objects container
|
||||
* with objects described in the events function parameters, in
|
||||
* the events function groups and in the parent-object properties for
|
||||
* child-objects.
|
||||
*
|
||||
* This is useful to create the "context" of a function, before code
|
||||
* generation for example.
|
||||
*/
|
||||
static void ObjectEventsFunctionToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& outputGlobalObjectsContainer,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -36,7 +36,7 @@ void ArbitraryObjectsWorker::VisitObject(gd::Object& object) {
|
||||
VisitBehavior(object.GetBehavior(behaviorName));
|
||||
}
|
||||
|
||||
void ArbitraryObjectsWorker::VisitBehavior(gd::BehaviorContent& behavior) {
|
||||
void ArbitraryObjectsWorker::VisitBehavior(gd::Behavior& behavior) {
|
||||
DoVisitBehavior(behavior);
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
namespace gd {
|
||||
class Object;
|
||||
class ObjectsContainer;
|
||||
class BehaviorContent;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -40,7 +40,7 @@ class GD_CORE_API ArbitraryObjectsWorker {
|
||||
private:
|
||||
void VisitObjectContainer(gd::ObjectsContainer& objects);
|
||||
void VisitObject(gd::Object& object);
|
||||
void VisitBehavior(gd::BehaviorContent& instruction);
|
||||
void VisitBehavior(gd::Behavior& behavior);
|
||||
|
||||
/**
|
||||
* Called to do some work on an object container.
|
||||
@@ -55,7 +55,7 @@ class GD_CORE_API ArbitraryObjectsWorker {
|
||||
/**
|
||||
* Called to do some work on a behavior.
|
||||
*/
|
||||
virtual void DoVisitBehavior(gd::BehaviorContent& instruction){};
|
||||
virtual void DoVisitBehavior(gd::Behavior& behavior){};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -111,7 +111,7 @@ class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
|
||||
ResourceWorkerInEventsWorker(const gd::Project& project_,
|
||||
gd::ArbitraryResourceWorker& worker_)
|
||||
: project(project_), worker(worker_){};
|
||||
virtual ~ResourceWorkerInEventsWorker() {};
|
||||
virtual ~ResourceWorkerInEventsWorker(){};
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction& instruction, bool isCondition) {
|
||||
@@ -131,7 +131,8 @@ class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police") { // Should be renamed fontResource
|
||||
"police" || // Should be renamed fontResource
|
||||
parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
@@ -149,6 +150,10 @@ class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeImage(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "jsonResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeJson(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Object;
|
||||
class BehaviorContent;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -24,12 +24,12 @@ class GD_CORE_API UnfilledRequiredBehaviorPropertyProblem {
|
||||
UnfilledRequiredBehaviorPropertyProblem(
|
||||
const gd::Project& sourceProject_,
|
||||
gd::Object& sourceObject_,
|
||||
gd::BehaviorContent& sourceBehaviorContent_,
|
||||
gd::Behavior& sourceBehavior_,
|
||||
const gd::String& sourcePropertyName_,
|
||||
const gd::String& expectedBehaviorTypeName_)
|
||||
: sourceProject(sourceProject_),
|
||||
sourceObject(sourceObject_),
|
||||
sourceBehaviorContent(sourceBehaviorContent_),
|
||||
sourceBehavior(sourceBehavior_),
|
||||
sourcePropertyName(sourcePropertyName_),
|
||||
expectedBehaviorTypeName(expectedBehaviorTypeName_){};
|
||||
virtual ~UnfilledRequiredBehaviorPropertyProblem();
|
||||
@@ -47,8 +47,8 @@ class GD_CORE_API UnfilledRequiredBehaviorPropertyProblem {
|
||||
/**
|
||||
* \brief Return the behavior where the problem appears.
|
||||
*/
|
||||
virtual gd::BehaviorContent& GetSourceBehaviorContent() const {
|
||||
return sourceBehaviorContent;
|
||||
virtual gd::Behavior& GetSourceBehaviorContent() const {
|
||||
return sourceBehavior;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ class GD_CORE_API UnfilledRequiredBehaviorPropertyProblem {
|
||||
private:
|
||||
const gd::Project& sourceProject;
|
||||
gd::Object& sourceObject;
|
||||
gd::BehaviorContent& sourceBehaviorContent;
|
||||
gd::Behavior& sourceBehavior;
|
||||
const gd::String sourcePropertyName;
|
||||
|
||||
const gd::String expectedBehaviorTypeName;
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include "GDCore/IDE/DependenciesAnalyzer.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Events/EventsBehaviorRenamer.h"
|
||||
#include "GDCore/IDE/Events/CustomObjectTypeRenamer.h"
|
||||
#include "GDCore/IDE/Events/BehaviorTypeRenamer.h"
|
||||
#include "GDCore/IDE/Events/EventsRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionsParameterMover.h"
|
||||
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
|
||||
@@ -20,8 +22,9 @@
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/IDE/UnfilledRequiredBehaviorPropertyProblem.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
#include "GDCore/Project/BehaviorConfigurationContainer.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
@@ -53,6 +56,17 @@ gd::String GetBehaviorFullType(const gd::String& extensionName,
|
||||
const auto& separator = gd::PlatformExtension::GetNamespaceSeparator();
|
||||
return extensionName + separator + behaviorName;
|
||||
}
|
||||
gd::String GetObjectEventsFunctionFullType(const gd::String& extensionName,
|
||||
const gd::String& objectName,
|
||||
const gd::String& functionName) {
|
||||
const auto& separator = gd::PlatformExtension::GetNamespaceSeparator();
|
||||
return extensionName + separator + objectName + separator + functionName;
|
||||
}
|
||||
gd::String GetObjectFullType(const gd::String& extensionName,
|
||||
const gd::String& objectName) {
|
||||
const auto& separator = gd::PlatformExtension::GetNamespaceSeparator();
|
||||
return extensionName + separator + objectName;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace gd {
|
||||
@@ -60,6 +74,9 @@ namespace gd {
|
||||
// By convention, the first parameter of an events based behavior method is
|
||||
// always called "Object".
|
||||
const gd::String WholeProjectRefactorer::behaviorObjectParameterName = "Object";
|
||||
// By convention, the first parameter of an events based object method is
|
||||
// always called "Object".
|
||||
const gd::String WholeProjectRefactorer::parentObjectParameterName = "Object";
|
||||
|
||||
void WholeProjectRefactorer::ExposeProjectEvents(
|
||||
gd::Project& project, gd::ArbitraryEventsWorker& worker) {
|
||||
@@ -93,6 +110,17 @@ void WholeProjectRefactorer::ExposeProjectEvents(
|
||||
worker.Launch(eventsFunction->GetEvents());
|
||||
}
|
||||
}
|
||||
|
||||
// Add (object) events functions
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto& objectEventsFunctions = eventsBasedObject->GetEventsFunctions();
|
||||
for (auto&& eventsFunction :
|
||||
objectEventsFunctions.GetInternalVector()) {
|
||||
worker.Launch(eventsFunction->GetEvents());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +167,13 @@ void WholeProjectRefactorer::ExposeProjectEvents(
|
||||
.GetInternalVector()) {
|
||||
ExposeEventsBasedBehaviorEvents(project, *eventsBasedBehavior, worker);
|
||||
}
|
||||
|
||||
// Add (object) events functions
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
ExposeEventsBasedObjectEvents(project, *eventsBasedObject, worker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,11 +197,49 @@ void WholeProjectRefactorer::ExposeEventsBasedBehaviorEvents(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ExposeEventsBasedObjectEvents(
|
||||
gd::Project& project,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ArbitraryEventsWorkerWithContext& worker) {
|
||||
auto& objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
for (auto&& eventsFunction : objectEventsFunctions.GetInternalVector()) {
|
||||
gd::ObjectsContainer globalObjectsAndGroups;
|
||||
gd::ObjectsContainer objectsAndGroups;
|
||||
gd::EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
|
||||
project,
|
||||
eventsBasedObject,
|
||||
*eventsFunction,
|
||||
globalObjectsAndGroups,
|
||||
objectsAndGroups);
|
||||
|
||||
worker.Launch(
|
||||
eventsFunction->GetEvents(), globalObjectsAndGroups, objectsAndGroups);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ExposeProjectObjects(
|
||||
gd::Project& project, gd::ArbitraryObjectsWorker& worker) {
|
||||
|
||||
// Global objects
|
||||
worker.Launch(project);
|
||||
for (size_t i = 0; i < project.GetLayoutsCount(); i++)
|
||||
|
||||
// Layers objects
|
||||
for (size_t i = 0; i < project.GetLayoutsCount(); i++) {
|
||||
worker.Launch(project.GetLayout(i));
|
||||
}
|
||||
|
||||
// Event based objects children
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto& eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
|
||||
for (auto&& eventsBasedObjectUniquePtr :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto eventsBasedObject = eventsBasedObjectUniquePtr.get();
|
||||
worker.Launch(*eventsBasedObject);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::set<gd::String>
|
||||
@@ -181,8 +254,8 @@ WholeProjectRefactorer::GetAllObjectTypesUsingEventsBasedBehavior(
|
||||
auto addTypesOfObjectsIn =
|
||||
[&allTypes, &behaviorType](const gd::ObjectsContainer& objectsContainer) {
|
||||
for (auto& object : objectsContainer.GetObjects()) {
|
||||
for (auto& behaviorContent : object->GetAllBehaviorContents()) {
|
||||
if (behaviorContent.second->GetTypeName() == behaviorType) {
|
||||
for (auto& behavior : object->GetAllBehaviorContents()) {
|
||||
if (behavior.second->GetTypeName() == behaviorType) {
|
||||
allTypes.insert(object->GetType());
|
||||
}
|
||||
}
|
||||
@@ -223,6 +296,26 @@ void WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject) {
|
||||
for (auto& eventsFunction :
|
||||
eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto& parameters = eventsFunction->GetParameters();
|
||||
while (parameters.size() < 1) {
|
||||
gd::ParameterMetadata newParameter;
|
||||
parameters.push_back(newParameter);
|
||||
}
|
||||
|
||||
parameters[0]
|
||||
.SetType("object")
|
||||
.SetName(parentObjectParameterName)
|
||||
.SetDescription("Object")
|
||||
.SetExtraInfo(GetObjectFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName()));
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
@@ -297,6 +390,66 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
// extension name
|
||||
};
|
||||
|
||||
auto renameObjectEventsFunction =
|
||||
[&project, &oldName, &newName](
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::EventsFunction& eventsFunction) {
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsTypeRenamer renamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(oldName,
|
||||
eventsBasedObject.GetName(),
|
||||
eventsFunction.GetName()),
|
||||
GetObjectEventsFunctionFullType(newName,
|
||||
eventsBasedObject.GetName(),
|
||||
eventsFunction.GetName()));
|
||||
ExposeProjectEvents(project, renamer);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
// Nothing to do, expressions are not including the extension name
|
||||
}
|
||||
};
|
||||
|
||||
auto renameObjectPropertyFunctions =
|
||||
[&project, &oldName, &newName](
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::NamedPropertyDescriptor& property) {
|
||||
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
oldName,
|
||||
eventsBasedObject.GetName(),
|
||||
gd::EventsBasedObject::GetPropertyActionName(
|
||||
property.GetName())),
|
||||
GetObjectEventsFunctionFullType(
|
||||
newName,
|
||||
eventsBasedObject.GetName(),
|
||||
gd::EventsBasedObject::GetPropertyActionName(
|
||||
property.GetName())));
|
||||
ExposeProjectEvents(project, actionRenamer);
|
||||
|
||||
gd::InstructionsTypeRenamer conditionRenamer =
|
||||
gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
oldName,
|
||||
eventsBasedObject.GetName(),
|
||||
gd::EventsBasedObject::GetPropertyConditionName(
|
||||
property.GetName())),
|
||||
GetObjectEventsFunctionFullType(
|
||||
newName,
|
||||
eventsBasedObject.GetName(),
|
||||
gd::EventsBasedObject::GetPropertyConditionName(
|
||||
property.GetName())));
|
||||
ExposeProjectEvents(project, conditionRenamer);
|
||||
|
||||
// Nothing to do for expressions, expressions are not including the
|
||||
// extension name
|
||||
};
|
||||
|
||||
// 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.
|
||||
@@ -352,6 +505,28 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
}
|
||||
}
|
||||
|
||||
// Object instructions
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
|
||||
auto& objectEventsFunctions = eventsBasedObject->GetEventsFunctions();
|
||||
for (auto&& eventsFunction : objectEventsFunctions.GetInternalVector()) {
|
||||
if (eventsFunction->GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction->GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
renameObjectEventsFunction(*eventsBasedObject, *eventsFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Object properties
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
|
||||
auto& objectProperties = eventsBasedObject->GetPropertyDescriptors();
|
||||
for (auto&& propertyDescriptor : objectProperties.GetInternalVector()) {
|
||||
renameObjectPropertyFunctions(*eventsBasedObject,
|
||||
*propertyDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, rename behaviors used in objects
|
||||
for (auto&& eventsBasedBehavior :
|
||||
eventsFunctionsExtension.GetEventsBasedBehaviors().GetInternalVector()) {
|
||||
@@ -360,6 +535,15 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
GetBehaviorFullType(oldName, eventsBasedBehavior->GetName()),
|
||||
GetBehaviorFullType(newName, eventsBasedBehavior->GetName()));
|
||||
}
|
||||
|
||||
// Finally, rename custom objects type
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
|
||||
DoRenameObject(
|
||||
project,
|
||||
GetObjectFullType(oldName, eventsBasedObject->GetName()),
|
||||
GetObjectFullType(newName, eventsBasedObject->GetName()));
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameEventsFunction(
|
||||
@@ -419,6 +603,44 @@ void WholeProjectRefactorer::RenameBehaviorEventsFunction(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldFunctionName,
|
||||
const gd::String& newFunctionName) {
|
||||
auto& eventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
if (!eventsFunctions.HasEventsFunctionNamed(oldFunctionName)) return;
|
||||
|
||||
const gd::EventsFunction& eventsFunction =
|
||||
eventsFunctions.GetEventsFunction(oldFunctionName);
|
||||
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsTypeRenamer renamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
oldFunctionName),
|
||||
GetObjectEventsFunctionFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
newFunctionName));
|
||||
ExposeProjectEvents(project, renamer);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
gd::ExpressionsRenamer renamer =
|
||||
gd::ExpressionsRenamer(project.GetCurrentPlatform());
|
||||
renamer.SetReplacedObjectExpression(
|
||||
GetObjectFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName()),
|
||||
oldFunctionName,
|
||||
newFunctionName);
|
||||
ExposeProjectEvents(project, renamer);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::MoveEventsFunctionParameter(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
@@ -489,6 +711,45 @@ void WholeProjectRefactorer::MoveBehaviorEventsFunctionParameter(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::MoveObjectEventsFunctionParameter(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& functionName,
|
||||
std::size_t oldIndex,
|
||||
std::size_t newIndex) {
|
||||
auto& eventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
if (!eventsFunctions.HasEventsFunctionNamed(functionName)) return;
|
||||
|
||||
const gd::EventsFunction& eventsFunction =
|
||||
eventsFunctions.GetEventsFunction(functionName);
|
||||
|
||||
const gd::String& eventsFunctionType =
|
||||
GetObjectEventsFunctionFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
functionName);
|
||||
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsParameterMover mover = gd::InstructionsParameterMover(
|
||||
project, eventsFunctionType, oldIndex, newIndex);
|
||||
ExposeProjectEvents(project, mover);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
gd::ExpressionsParameterMover mover =
|
||||
gd::ExpressionsParameterMover(project.GetCurrentPlatform());
|
||||
mover.SetObjectExpressionMovedParameter(
|
||||
GetObjectFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName()),
|
||||
functionName,
|
||||
oldIndex,
|
||||
newIndex);
|
||||
ExposeProjectEvents(project, mover);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
@@ -555,6 +816,55 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameEventsBasedObjectProperty(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldPropertyName,
|
||||
const gd::String& newPropertyName) {
|
||||
auto& properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
if (!properties.Has(oldPropertyName)) return;
|
||||
|
||||
// Properties that represent primitive values will be used through
|
||||
// their related actions/conditions/expressions. Rename these.
|
||||
|
||||
// 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.
|
||||
gd::ExpressionsRenamer expressionRenamer =
|
||||
gd::ExpressionsRenamer(project.GetCurrentPlatform());
|
||||
expressionRenamer.SetReplacedObjectExpression(
|
||||
GetObjectFullType(eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName()),
|
||||
EventsBasedObject::GetPropertyExpressionName(oldPropertyName),
|
||||
EventsBasedObject::GetPropertyExpressionName(newPropertyName));
|
||||
ExposeProjectEvents(project, expressionRenamer);
|
||||
|
||||
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
EventsBasedObject::GetPropertyActionName(oldPropertyName)),
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
EventsBasedObject::GetPropertyActionName(newPropertyName)));
|
||||
ExposeProjectEvents(project, actionRenamer);
|
||||
|
||||
gd::InstructionsTypeRenamer conditionRenamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
EventsBasedObject::GetPropertyConditionName(oldPropertyName)),
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
EventsBasedObject::GetPropertyConditionName(newPropertyName)));
|
||||
ExposeProjectEvents(project, conditionRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
|
||||
gd::Project& project,
|
||||
gd::Object& object,
|
||||
@@ -575,10 +885,8 @@ void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
|
||||
return;
|
||||
}
|
||||
|
||||
gd::Behavior& behavior = behaviorMetadata.Get();
|
||||
gd::BehaviorContent& behaviorContent = object.GetBehavior(behaviorName);
|
||||
for (auto const& keyValue :
|
||||
behavior.GetProperties(behaviorContent.GetContent())) {
|
||||
gd::Behavior& behavior = object.GetBehavior(behaviorName);
|
||||
for (auto const& keyValue : behavior.GetProperties()) {
|
||||
const gd::String& propertyName = keyValue.first;
|
||||
const gd::PropertyDescriptor& property = keyValue.second;
|
||||
if (property.GetType().LowerCase() == "behavior") {
|
||||
@@ -588,11 +896,11 @@ void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
|
||||
continue;
|
||||
}
|
||||
const gd::String& requiredBehaviorType = extraInfo.at(0);
|
||||
const auto behaviorContents =
|
||||
const auto behaviorNames =
|
||||
WholeProjectRefactorer::GetBehaviorsWithType(object,
|
||||
requiredBehaviorType);
|
||||
const gd::String* defaultBehaviorName = nullptr;
|
||||
if (behaviorContents.size() == 0) {
|
||||
if (behaviorNames.size() == 0) {
|
||||
const gd::BehaviorMetadata& requiredBehaviorMetadata =
|
||||
MetadataProvider::GetBehaviorMetadata(platform,
|
||||
requiredBehaviorType);
|
||||
@@ -602,10 +910,9 @@ void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
|
||||
project, object, requiredBehaviorType, requiredBehaviorName);
|
||||
defaultBehaviorName = &requiredBehaviorName;
|
||||
} else {
|
||||
defaultBehaviorName = &behaviorContents.at(0);
|
||||
defaultBehaviorName = &behaviorNames.at(0);
|
||||
}
|
||||
behavior.UpdateProperty(
|
||||
behaviorContent.GetContent(), propertyName, *defaultBehaviorName);
|
||||
behavior.UpdateProperty(propertyName, *defaultBehaviorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -614,9 +921,8 @@ std::vector<gd::String> WholeProjectRefactorer::GetBehaviorsWithType(
|
||||
const gd::Object& object, const gd::String& type) {
|
||||
std::vector<gd::String> behaviors;
|
||||
for (auto& behaviorName : object.GetAllBehaviorNames()) {
|
||||
const gd::BehaviorContent& behaviorContent =
|
||||
object.GetBehavior(behaviorName);
|
||||
if (behaviorContent.GetTypeName() == type) {
|
||||
const gd::Behavior& behavior = object.GetBehavior(behaviorName);
|
||||
if (behavior.GetTypeName() == type) {
|
||||
behaviors.push_back(behaviorName);
|
||||
}
|
||||
}
|
||||
@@ -644,18 +950,15 @@ void WholeProjectRefactorer::FindDependentBehaviorNames(
|
||||
std::unordered_set<gd::String>& dependentBehaviorNames) {
|
||||
const gd::Platform& platform = project.GetCurrentPlatform();
|
||||
for (auto const& objectBehaviorName : object.GetAllBehaviorNames()) {
|
||||
const gd::BehaviorContent& behaviorContent =
|
||||
object.GetBehavior(objectBehaviorName);
|
||||
const gd::Behavior& behavior = object.GetBehavior(objectBehaviorName);
|
||||
const auto& behaviorMetadata = MetadataProvider::GetBehaviorMetadata(
|
||||
platform, behaviorContent.GetTypeName());
|
||||
platform, behavior.GetTypeName());
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
// Ignore this behavior as it's unknown.
|
||||
continue;
|
||||
}
|
||||
|
||||
gd::Behavior& behavior = behaviorMetadata.Get();
|
||||
for (auto const& keyValue :
|
||||
behavior.GetProperties(behaviorContent.GetContent())) {
|
||||
for (auto const& keyValue : behavior.GetProperties()) {
|
||||
const gd::String& propertyName = keyValue.first;
|
||||
const gd::PropertyDescriptor& property = keyValue.second;
|
||||
if (property.GetType().LowerCase() == "behavior" &&
|
||||
@@ -679,25 +982,11 @@ WholeProjectRefactorer::FindInvalidRequiredBehaviorProperties(
|
||||
[&project, &invalidRequiredBehaviorProperties](
|
||||
const std::vector<std::unique_ptr<gd::Object> >& objectsList) {
|
||||
for (auto& object : objectsList) {
|
||||
for (auto& behaviorContentKeyValuePair :
|
||||
for (auto& behaviorKeyValuePair :
|
||||
object->GetAllBehaviorContents()) {
|
||||
gd::BehaviorContent& behaviorContent =
|
||||
*behaviorContentKeyValuePair.second;
|
||||
gd::Behavior& behavior = *behaviorKeyValuePair.second;
|
||||
|
||||
const auto& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(
|
||||
project.GetCurrentPlatform(),
|
||||
behaviorContent.GetTypeName());
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
std::cout << "Could not find metadata for behavior with type \""
|
||||
<< behaviorContent.GetTypeName() << "\"" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& behavior = behaviorMetadata.Get();
|
||||
|
||||
for (auto const& keyValue :
|
||||
behavior.GetProperties(behaviorContent.GetContent())) {
|
||||
for (auto const& keyValue : behavior.GetProperties()) {
|
||||
const gd::String& propertyName = keyValue.first;
|
||||
const gd::PropertyDescriptor& property = keyValue.second;
|
||||
if (property.GetType().LowerCase() != "behavior") {
|
||||
@@ -719,7 +1008,7 @@ WholeProjectRefactorer::FindInvalidRequiredBehaviorProperties(
|
||||
auto problem = UnfilledRequiredBehaviorPropertyProblem(
|
||||
project,
|
||||
*object,
|
||||
behaviorContent,
|
||||
behavior,
|
||||
propertyName,
|
||||
requiredBehaviorType);
|
||||
invalidRequiredBehaviorProperties.push_back(problem);
|
||||
@@ -748,21 +1037,15 @@ bool WholeProjectRefactorer::FixInvalidRequiredBehaviorProperties(
|
||||
auto& object = problem.GetSourceObject();
|
||||
auto suggestedBehaviorNames =
|
||||
GetBehaviorsWithType(object, problem.GetExpectedBehaviorTypeName());
|
||||
auto& behaviorContent = problem.GetSourceBehaviorContent();
|
||||
auto& behaviorMetadata = MetadataProvider::GetBehaviorMetadata(
|
||||
project.GetCurrentPlatform(), behaviorContent.GetTypeName());
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
continue;
|
||||
}
|
||||
auto& behavior = problem.GetSourceBehaviorContent();
|
||||
|
||||
auto& behavior = behaviorMetadata.Get();
|
||||
if (suggestedBehaviorNames.empty()) {
|
||||
// No matching behavior on the object.
|
||||
// Add required behaviors on the object.
|
||||
|
||||
auto& expectedBehaviorMetadata = MetadataProvider::GetBehaviorMetadata(
|
||||
project.GetCurrentPlatform(), problem.GetExpectedBehaviorTypeName());
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
if (MetadataProvider::IsBadBehaviorMetadata(expectedBehaviorMetadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -772,13 +1055,11 @@ bool WholeProjectRefactorer::FixInvalidRequiredBehaviorProperties(
|
||||
object,
|
||||
problem.GetExpectedBehaviorTypeName(),
|
||||
newBehaviorName);
|
||||
behavior.UpdateProperty(behaviorContent.GetContent(),
|
||||
problem.GetSourcePropertyName(),
|
||||
behavior.UpdateProperty(problem.GetSourcePropertyName(),
|
||||
newBehaviorName);
|
||||
} else {
|
||||
// There is a matching behavior on the object use it by default.
|
||||
behavior.UpdateProperty(
|
||||
behaviorContent.GetContent(),
|
||||
problem.GetSourcePropertyName(),
|
||||
// It's unlikely the object has 2 behaviors of the same type.
|
||||
suggestedBehaviorNames[0]);
|
||||
@@ -897,6 +1178,115 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
|
||||
GetBehaviorFullType(eventsFunctionsExtension.GetName(), newBehaviorName));
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameEventsBasedObject(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldObjectName,
|
||||
const gd::String& newObjectName) {
|
||||
auto& eventsBasedObjects =
|
||||
eventsFunctionsExtension.GetEventsBasedObjects();
|
||||
if (!eventsBasedObjects.Has(oldObjectName)) {
|
||||
gd::LogWarning("Warning, " + oldObjectName +
|
||||
" was not found when calling RenameEventsBasedObject.");
|
||||
return;
|
||||
}
|
||||
auto& eventsBasedObject = eventsBasedObjects.Get(oldObjectName);
|
||||
|
||||
auto renameObjectEventsFunction =
|
||||
[&project,
|
||||
&eventsFunctionsExtension,
|
||||
&oldObjectName,
|
||||
&newObjectName](const gd::EventsFunction& eventsFunction) {
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction.GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
gd::InstructionsTypeRenamer renamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
oldObjectName,
|
||||
eventsFunction.GetName()),
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
newObjectName,
|
||||
eventsFunction.GetName()));
|
||||
ExposeProjectEvents(project, renamer);
|
||||
} else if (eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::Expression ||
|
||||
eventsFunction.GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
// Nothing to do, expressions are not including the name of the
|
||||
// object
|
||||
}
|
||||
};
|
||||
|
||||
auto renameObjectProperty = [&project,
|
||||
&eventsFunctionsExtension,
|
||||
&oldObjectName,
|
||||
&newObjectName](
|
||||
const gd::NamedPropertyDescriptor&
|
||||
property) {
|
||||
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
oldObjectName,
|
||||
EventsBasedObject::GetPropertyActionName(property.GetName())),
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
newObjectName,
|
||||
EventsBasedObject::GetPropertyActionName(property.GetName())));
|
||||
ExposeProjectEvents(project, actionRenamer);
|
||||
|
||||
gd::InstructionsTypeRenamer conditionRenamer = gd::InstructionsTypeRenamer(
|
||||
project,
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
oldObjectName,
|
||||
EventsBasedObject::GetPropertyConditionName(property.GetName())),
|
||||
GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
newObjectName,
|
||||
EventsBasedObject::GetPropertyConditionName(property.GetName())));
|
||||
ExposeProjectEvents(project, conditionRenamer);
|
||||
|
||||
// Nothing to do for expression, expressions are not including the name of
|
||||
// the object
|
||||
};
|
||||
|
||||
// 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.
|
||||
auto& objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
|
||||
// Object expressions
|
||||
for (auto&& eventsFunction : objectEventsFunctions.GetInternalVector()) {
|
||||
if (eventsFunction->GetFunctionType() == gd::EventsFunction::Expression ||
|
||||
eventsFunction->GetFunctionType() ==
|
||||
gd::EventsFunction::StringExpression) {
|
||||
renameObjectEventsFunction(*eventsFunction);
|
||||
}
|
||||
}
|
||||
|
||||
// Object instructions
|
||||
for (auto&& eventsFunction : objectEventsFunctions.GetInternalVector()) {
|
||||
if (eventsFunction->GetFunctionType() == gd::EventsFunction::Action ||
|
||||
eventsFunction->GetFunctionType() == gd::EventsFunction::Condition) {
|
||||
renameObjectEventsFunction(*eventsFunction);
|
||||
}
|
||||
}
|
||||
|
||||
// Object properties
|
||||
auto& properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
for (auto&& property : properties.GetInternalVector()) {
|
||||
renameObjectProperty(*property);
|
||||
}
|
||||
|
||||
DoRenameObject(
|
||||
project,
|
||||
GetObjectFullType(eventsFunctionsExtension.GetName(), oldObjectName),
|
||||
GetObjectFullType(eventsFunctionsExtension.GetName(), newObjectName));
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::DoRenameEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
@@ -924,18 +1314,9 @@ void WholeProjectRefactorer::DoRenameBehavior(
|
||||
const gd::String& newBehaviorType) {
|
||||
auto renameBehaviorTypeInBehaviorContent =
|
||||
[&oldBehaviorType,
|
||||
&newBehaviorType](gd::BehaviorContent& behaviorContent) {
|
||||
if (behaviorContent.GetTypeName() == oldBehaviorType) {
|
||||
behaviorContent.SetTypeName(newBehaviorType);
|
||||
}
|
||||
};
|
||||
auto renameBehaviorTypeInObjects =
|
||||
[&renameBehaviorTypeInBehaviorContent](
|
||||
std::vector<std::unique_ptr<gd::Object> >& objectsList) {
|
||||
for (auto& object : objectsList) {
|
||||
for (auto& behaviorContent : object->GetAllBehaviorContents()) {
|
||||
renameBehaviorTypeInBehaviorContent(*behaviorContent.second);
|
||||
}
|
||||
&newBehaviorType](gd::BehaviorConfigurationContainer& behavior) {
|
||||
if (behavior.GetTypeName() == oldBehaviorType) {
|
||||
behavior.SetTypeName(newBehaviorType);
|
||||
}
|
||||
};
|
||||
auto renameBehaviorTypeInParameters =
|
||||
@@ -972,15 +1353,18 @@ void WholeProjectRefactorer::DoRenameBehavior(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rename behavior in objects lists.
|
||||
auto behaviorTypeRenamer = gd::BehaviorTypeRenamer(
|
||||
project,
|
||||
oldBehaviorType,
|
||||
newBehaviorType);
|
||||
ExposeProjectObjects(project, behaviorTypeRenamer);
|
||||
|
||||
// Rename behavior in global objects
|
||||
renameBehaviorTypeInObjects(project.GetObjects());
|
||||
|
||||
// Rename behavior in layout objects and layout behavior shared data.
|
||||
// Rename behavior in layout behavior shared data.
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
gd::Layout& layout = project.GetLayout(i);
|
||||
|
||||
renameBehaviorTypeInObjects(layout.GetObjects());
|
||||
for (auto& behaviorSharedDataContent : layout.GetAllBehaviorSharedData()) {
|
||||
renameBehaviorTypeInBehaviorContent(*behaviorSharedDataContent.second);
|
||||
}
|
||||
@@ -1003,6 +1387,76 @@ void WholeProjectRefactorer::DoRenameBehavior(
|
||||
renameBehaviorTypeInParameters(*eventsFunction);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto& behaviorEventsFunctions = eventsBasedObject->GetEventsFunctions();
|
||||
for (auto&& eventsFunction :
|
||||
behaviorEventsFunctions.GetInternalVector()) {
|
||||
renameBehaviorTypeInParameters(*eventsFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::DoRenameObject(
|
||||
gd::Project& project,
|
||||
const gd::String& oldObjectType,
|
||||
const gd::String& newObjectType) {
|
||||
|
||||
auto customObjectTypeRenamer = gd::CustomObjectTypeRenamer(
|
||||
project,
|
||||
oldObjectType,
|
||||
newObjectType);
|
||||
ExposeProjectObjects(project, customObjectTypeRenamer);
|
||||
|
||||
auto renameObjectTypeInParameters =
|
||||
[&oldObjectType, &newObjectType](gd::EventsFunction& eventsFunction) {
|
||||
for (auto& parameter : eventsFunction.GetParameters()) {
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType()) &&
|
||||
parameter.GetExtraInfo() == oldObjectType) {
|
||||
parameter.SetExtraInfo(newObjectType);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Rename in parameters of (free/behavior) events function
|
||||
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
|
||||
e++) {
|
||||
auto& eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
|
||||
|
||||
// Behavior object types
|
||||
for (auto&& eventsBasedBehavior :
|
||||
eventsFunctionsExtension.GetEventsBasedBehaviors().GetInternalVector()) {
|
||||
if (eventsBasedBehavior->GetObjectType() == oldObjectType) {
|
||||
eventsBasedBehavior->SetObjectType(newObjectType);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
|
||||
renameObjectTypeInParameters(*eventsFunction);
|
||||
}
|
||||
|
||||
for (auto&& eventsBasedBehavior :
|
||||
eventsFunctionsExtension.GetEventsBasedBehaviors()
|
||||
.GetInternalVector()) {
|
||||
auto& behaviorEventsFunctions = eventsBasedBehavior->GetEventsFunctions();
|
||||
for (auto&& eventsFunction :
|
||||
behaviorEventsFunctions.GetInternalVector()) {
|
||||
renameObjectTypeInParameters(*eventsFunction);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& eventsBasedObject :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects()
|
||||
.GetInternalVector()) {
|
||||
auto& behaviorEventsFunctions = eventsBasedObject->GetEventsFunctions();
|
||||
for (auto&& eventsFunction :
|
||||
behaviorEventsFunctions.GetInternalVector()) {
|
||||
renameObjectTypeInParameters(*eventsFunction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,6 +1577,28 @@ void WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
const gd::String& objectName,
|
||||
bool isObjectGroup,
|
||||
bool removeEventsAndGroups) {
|
||||
for (auto &functionUniquePtr : eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto function = functionUniquePtr.get();
|
||||
WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction(
|
||||
project,
|
||||
*function,
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
objectName,
|
||||
isObjectGroup,
|
||||
isObjectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction(
|
||||
gd::Project& project,
|
||||
gd::EventsFunction& eventsFunction,
|
||||
@@ -1150,6 +1626,26 @@ void WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup) {
|
||||
for (auto &functionUniquePtr : eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto *function = functionUniquePtr.get();
|
||||
WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
|
||||
project,
|
||||
*function,
|
||||
globalObjectsContainer,
|
||||
eventsBasedObject,
|
||||
oldName,
|
||||
newName,
|
||||
isObjectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
|
||||
gd::Project& project,
|
||||
gd::EventsFunction& eventsFunction,
|
||||
|
@@ -18,11 +18,11 @@ class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
class ObjectsContainer;
|
||||
class EventsBasedBehavior;
|
||||
class EventsBasedObject;
|
||||
class ArbitraryEventsWorker;
|
||||
class ArbitraryObjectsWorker;
|
||||
class ArbitraryEventsWorkerWithContext;
|
||||
class Behavior;
|
||||
class BehaviorContent;
|
||||
class BehaviorMetadata;
|
||||
class UnfilledRequiredBehaviorPropertyProblem;
|
||||
} // namespace gd
|
||||
@@ -61,13 +61,24 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
* \brief Call the specified worker on all events of the events based behavior
|
||||
*
|
||||
* This should be the preferred way to traverse all the events of an events
|
||||
* based behavior
|
||||
* based behavior.
|
||||
*/
|
||||
static void ExposeEventsBasedBehaviorEvents(
|
||||
gd::Project& project,
|
||||
const gd::EventsBasedBehavior& eventsBasedBehavior,
|
||||
gd::ArbitraryEventsWorkerWithContext& worker);
|
||||
|
||||
/**
|
||||
* \brief Call the specified worker on all events of the events based object
|
||||
*
|
||||
* This should be the preferred way to traverse all the events of an events
|
||||
* based object.
|
||||
*/
|
||||
static void ExposeEventsBasedObjectEvents(
|
||||
gd::Project& project,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ArbitraryEventsWorkerWithContext& worker);
|
||||
|
||||
/**
|
||||
* \brief Call the specified worker on all ObjectContainers of the project
|
||||
* (global, layouts...)
|
||||
@@ -119,6 +130,21 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::String& oldFunctionName,
|
||||
const gd::String& newFunctionName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** an events function of an object is
|
||||
* renamed.
|
||||
*
|
||||
* \warning Do the renaming of the specified function after calling this.
|
||||
* This is because the function is expected to have its old name for the
|
||||
* refactoring.
|
||||
*/
|
||||
static void RenameObjectEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldFunctionName,
|
||||
const gd::String& newFunctionName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** an events function parameter
|
||||
* is moved.
|
||||
@@ -150,6 +176,22 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
std::size_t oldIndex,
|
||||
std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** the parameter of an events function
|
||||
* of an object is moved.
|
||||
*
|
||||
* \warning Do the move of the specified function parameters after calling
|
||||
* this. This is because the function is expected to be in its old state for
|
||||
* the refactoring.
|
||||
*/
|
||||
static void MoveObjectEventsFunctionParameter(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& functionName,
|
||||
std::size_t oldIndex,
|
||||
std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** a property of a behavior is
|
||||
* renamed.
|
||||
@@ -165,6 +207,21 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::String& oldPropertyName,
|
||||
const gd::String& newPropertyName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** a property of an object is
|
||||
* renamed.
|
||||
*
|
||||
* \warning Do the renaming of the specified property after calling this.
|
||||
* This is because the property is expected to have its old name for the
|
||||
* refactoring.
|
||||
*/
|
||||
static void RenameEventsBasedObjectProperty(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldPropertyName,
|
||||
const gd::String& newPropertyName);
|
||||
|
||||
/**
|
||||
* \brief Add a behavior to an object and add required behaviors if necessary
|
||||
* to fill every behavior properties of the added behaviors.
|
||||
@@ -217,6 +274,19 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::String& oldBehaviorName,
|
||||
const gd::String& newBehaviorName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** an object is renamed.
|
||||
*
|
||||
* \warning Do the renaming of the specified object after calling this.
|
||||
* This is because the object is expected to have its old name for the
|
||||
* refactoring.
|
||||
*/
|
||||
static void RenameEventsBasedObject(
|
||||
gd::Project& project,
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::String& oldObjectName,
|
||||
const gd::String& newObjectName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is renamed in a layout
|
||||
*
|
||||
@@ -241,6 +311,34 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
bool isObjectGroup,
|
||||
bool removeEventsAndGroups = true);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is removed in an events-based
|
||||
* object.
|
||||
*
|
||||
* This will update the events of the function and groups.
|
||||
*/
|
||||
static void ObjectOrGroupRemovedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
const gd::String& objectName,
|
||||
bool isObjectGroup,
|
||||
bool removeEventsAndGroups);
|
||||
|
||||
/**
|
||||
* \brief Refactor the events function after an object or group is renamed
|
||||
*
|
||||
* This will update the events of the function and groups.
|
||||
*/
|
||||
static void ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup);
|
||||
|
||||
/**
|
||||
* \brief Refactor the events function after an object or group is renamed
|
||||
*
|
||||
@@ -309,6 +407,14 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedBehavior& eventsBasedBehavior);
|
||||
|
||||
/**
|
||||
* \brief Ensure (adding if necessary) that the functions of the given
|
||||
* object have the proper mandatory parameters (the "Object").
|
||||
*/
|
||||
static void EnsureObjectEventsFunctionsProperParameters(
|
||||
const gd::EventsFunctionsExtension& eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject& eventsBasedObject);
|
||||
|
||||
virtual ~WholeProjectRefactorer(){};
|
||||
|
||||
private:
|
||||
@@ -324,6 +430,10 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::String& oldBehaviorType,
|
||||
const gd::String& newBehaviorType);
|
||||
|
||||
static void DoRenameObject(gd::Project& project,
|
||||
const gd::String& oldObjectType,
|
||||
const gd::String& newObjectType);
|
||||
|
||||
static void FindDependentBehaviorNames(
|
||||
const gd::Project& project,
|
||||
const gd::Object& object,
|
||||
@@ -331,6 +441,7 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
std::unordered_set<gd::String>& dependentBehaviorNames);
|
||||
|
||||
static const gd::String behaviorObjectParameterName;
|
||||
static const gd::String parentObjectParameterName;
|
||||
|
||||
WholeProjectRefactorer(){};
|
||||
};
|
||||
|
42
Core/GDCore/Project/AbstractEventsBasedEntity.cpp
Normal file
42
Core/GDCore/Project/AbstractEventsBasedEntity.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "AbstractEventsBasedEntity.h"
|
||||
#include "EventsFunctionsContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
AbstractEventsBasedEntity::AbstractEventsBasedEntity(const gd::String& _name)
|
||||
: name(_name), fullName("") {}
|
||||
|
||||
void AbstractEventsBasedEntity::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
|
||||
gd::SerializerElement& eventsFunctionsElement =
|
||||
element.AddChild("eventsFunctions");
|
||||
eventsFunctionsContainer.SerializeEventsFunctionsTo(eventsFunctionsElement);
|
||||
propertyDescriptors.SerializeElementsTo(
|
||||
"propertyDescriptor", element.AddChild("propertyDescriptors"));
|
||||
}
|
||||
|
||||
void AbstractEventsBasedEntity::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
description = element.GetStringAttribute("description");
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
|
||||
const gd::SerializerElement& eventsFunctionsElement =
|
||||
element.GetChild("eventsFunctions");
|
||||
eventsFunctionsContainer.UnserializeEventsFunctionsFrom(
|
||||
project, eventsFunctionsElement);
|
||||
propertyDescriptors.UnserializeElementsFrom(
|
||||
"propertyDescriptor", element.GetChild("propertyDescriptors"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
151
Core/GDCore/Project/AbstractEventsBasedEntity.h
Normal file
151
Core/GDCore/Project/AbstractEventsBasedEntity.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
||||
#define GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/NamedPropertyDescriptor.h"
|
||||
#include "GDCore/Tools/SerializableWithNameList.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Represents a behavior or an object that is implemented with events.
|
||||
*
|
||||
* It's the responsibility of the IDE to run the logic to transform this into a
|
||||
* real behavior or object, by declaring an extension and running code generation.
|
||||
* See `EventsFunctionsExtensionsLoader`.
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API AbstractEventsBasedEntity {
|
||||
public:
|
||||
AbstractEventsBasedEntity(const gd::String& _name);
|
||||
virtual ~AbstractEventsBasedEntity(){};
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new AbstractEventsBasedEntity constructed from
|
||||
* this one.
|
||||
*/
|
||||
AbstractEventsBasedEntity* Clone() const { return new AbstractEventsBasedEntity(*this); };
|
||||
|
||||
/**
|
||||
* \brief Get the description of the behavior or object, that is displayed in the
|
||||
* editor.
|
||||
*/
|
||||
const gd::String& GetDescription() const { return description; };
|
||||
|
||||
/**
|
||||
* \brief Set the description of the behavior or object, to be displayed in the editor.
|
||||
*/
|
||||
virtual AbstractEventsBasedEntity& SetDescription(const gd::String& description_) {
|
||||
description = description_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the internal name of the behavior or object.
|
||||
*/
|
||||
const gd::String& GetName() const { return name; };
|
||||
|
||||
/**
|
||||
* \brief Set the internal name of the behavior or object.
|
||||
*/
|
||||
AbstractEventsBasedEntity& SetName(const gd::String& name_) {
|
||||
name = name_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the behavior or object, that is displayed in the editor.
|
||||
*/
|
||||
const gd::String& GetFullName() const { return fullName; };
|
||||
|
||||
/**
|
||||
* \brief Set the name of the behavior or object, to be displayed in the editor.
|
||||
*/
|
||||
AbstractEventsBasedEntity& SetFullName(const gd::String& fullName_) {
|
||||
fullName = fullName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the functions of the events based behavior or object.
|
||||
*/
|
||||
EventsFunctionsContainer& GetEventsFunctions() {
|
||||
return eventsFunctionsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the functions of the events based
|
||||
* behavior or object.
|
||||
*/
|
||||
const EventsFunctionsContainer& GetEventsFunctions() const {
|
||||
return eventsFunctionsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of the properties.
|
||||
*/
|
||||
SerializableWithNameList<NamedPropertyDescriptor>& GetPropertyDescriptors() {
|
||||
return propertyDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the list of the properties.
|
||||
*/
|
||||
const SerializableWithNameList<NamedPropertyDescriptor>& GetPropertyDescriptors()
|
||||
const {
|
||||
return propertyDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the action to change a property.
|
||||
*/
|
||||
static gd::String GetPropertyActionName(const gd::String& propertyName) { return "SetProperty" + propertyName; };
|
||||
|
||||
/**
|
||||
* \brief Get the name of the condition to compare a property.
|
||||
*/
|
||||
static gd::String GetPropertyConditionName(const gd::String& propertyName) { return "Property" + propertyName; };
|
||||
|
||||
/**
|
||||
* \brief Get the name of the expression to get a property.
|
||||
*/
|
||||
static gd::String GetPropertyExpressionName(const gd::String& propertyName) { return "Property" + propertyName; };
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the AbstractEventsBasedEntity to the specified element
|
||||
*/
|
||||
virtual void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the AbstractEventsBasedEntity from the specified element
|
||||
*/
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
gd::String description;
|
||||
gd::EventsFunctionsContainer eventsFunctionsContainer;
|
||||
SerializableWithNameList<NamedPropertyDescriptor> propertyDescriptors;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_ABSTRACTEVENTSBASEDENTITY_H
|
@@ -5,20 +5,10 @@
|
||||
*/
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include <iostream>
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
Behavior::~Behavior(){};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> Behavior::GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -5,86 +5,28 @@
|
||||
*/
|
||||
#ifndef GDCORE_BEHAVIOR_H
|
||||
#define GDCORE_BEHAVIOR_H
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
}
|
||||
#endif
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
#include "GDCore/Project/BehaviorConfigurationContainer.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class used to represents a behavior that can be applied to an
|
||||
* object
|
||||
* object. It stores the content (i.e: the properties) of a behavior of an object.
|
||||
*
|
||||
* \see gd::BehaviorContent
|
||||
* \see gd::BehaviorsSharedData
|
||||
* \see gd::Object
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API Behavior {
|
||||
class GD_CORE_API Behavior: public BehaviorConfigurationContainer {
|
||||
public:
|
||||
Behavior(){};
|
||||
|
||||
Behavior(): BehaviorConfigurationContainer() {};
|
||||
Behavior(const gd::String& name_, const gd::String& type_)
|
||||
: BehaviorConfigurationContainer(name_, type_) {};
|
||||
virtual ~Behavior();
|
||||
virtual Behavior* Clone() const { return new Behavior(*this); }
|
||||
|
||||
/**
|
||||
* \brief Return the type of the behavior
|
||||
*/
|
||||
const gd::String& GetTypeName() const { return type; }
|
||||
|
||||
/**
|
||||
* \brief Set the type of the behavior.
|
||||
*/
|
||||
void SetTypeName(const gd::String& type_) { type = type_; };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
* behavior.
|
||||
*
|
||||
* Implementation example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the
|
||||
* behavior
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
const gd::String& name,
|
||||
const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Called to initialize the content with the default properties
|
||||
* for the behavior.
|
||||
*/
|
||||
virtual void InitializeContent(gd::SerializerElement& behaviorContent){};
|
||||
|
||||
private:
|
||||
gd::String type;
|
||||
virtual Behavior* Clone() const override { return new Behavior(*this); }
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
25
Core/GDCore/Project/BehaviorConfigurationContainer.cpp
Normal file
25
Core/GDCore/Project/BehaviorConfigurationContainer.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/BehaviorConfigurationContainer.h"
|
||||
#include <iostream>
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
BehaviorConfigurationContainer::~BehaviorConfigurationContainer(){};
|
||||
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorConfigurationContainer::GetProperties() const {
|
||||
return GetProperties(content);
|
||||
};
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorConfigurationContainer::GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
} // namespace gd
|
155
Core/GDCore/Project/BehaviorConfigurationContainer.h
Normal file
155
Core/GDCore/Project/BehaviorConfigurationContainer.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H
|
||||
#define GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class for containers of behavior configuration.
|
||||
* They can be attached to objects (Behavior) or layouts (BehaviorsSharedData).
|
||||
* It stores the content (i.e: the properties) of a behavior of an object.
|
||||
*
|
||||
* \see gd::Behavior
|
||||
* \see gd::BehaviorsSharedData
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API BehaviorConfigurationContainer {
|
||||
public:
|
||||
|
||||
BehaviorConfigurationContainer(){};
|
||||
BehaviorConfigurationContainer(const gd::String& name_, const gd::String& type_)
|
||||
: name(name_), type(type_){};
|
||||
virtual ~BehaviorConfigurationContainer();
|
||||
virtual BehaviorConfigurationContainer* Clone() const { return new BehaviorConfigurationContainer(*this); }
|
||||
|
||||
/**
|
||||
* \brief Return the name identifying the behavior
|
||||
*/
|
||||
const gd::String& GetName() const { return name; }
|
||||
|
||||
/**
|
||||
* \brief Change the name identifying the behavior
|
||||
*/
|
||||
void SetName(const gd::String& name_) { name = name_; }
|
||||
|
||||
/**
|
||||
* \brief Return the type of the behavior
|
||||
*/
|
||||
const gd::String& GetTypeName() const { return type; }
|
||||
|
||||
/**
|
||||
* \brief Set the type of the behavior.
|
||||
*/
|
||||
void SetTypeName(const gd::String& type_) { type = type_; };
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
* behavior.
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the
|
||||
* behavior
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return UpdateProperty(content, name, value);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Called to initialize the content with the default properties
|
||||
* for the behavior.
|
||||
*/
|
||||
virtual void InitializeContent() {
|
||||
InitializeContent(content);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Serialize the behavior content.
|
||||
*/
|
||||
virtual void SerializeTo(gd::SerializerElement& element) const {
|
||||
element = content;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Unserialize the behavior content.
|
||||
*/
|
||||
virtual void UnserializeFrom(const gd::SerializerElement& element) {
|
||||
content = element;
|
||||
};
|
||||
|
||||
const gd::SerializerElement& GetContent() const { return content; };
|
||||
gd::SerializerElement& GetContent() { return content; };
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
* behavior.
|
||||
*
|
||||
* Implementation example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
|
||||
const gd::SerializerElement& behaviorContent) const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the
|
||||
* behavior
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
const gd::String& name,
|
||||
const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Called to initialize the content with the default properties
|
||||
* for the behavior.
|
||||
*/
|
||||
virtual void InitializeContent(gd::SerializerElement& behaviorContent){};
|
||||
|
||||
private:
|
||||
gd::String name; ///< Name of the behavior
|
||||
gd::String type; ///< The type of the behavior that is represented. Usually
|
||||
///< in the form "ExtensionName::BehaviorTypeName"
|
||||
|
||||
gd::SerializerElement content; // Storage for the behavior properties
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_BEHAVIORCONFIGURATIONCONTAINER_H
|
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
BehaviorContent::~BehaviorContent(){};
|
||||
|
||||
} // namespace gd
|
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_BEHAVIORCONTENT_H
|
||||
#define GDCORE_BEHAVIORCONTENT_H
|
||||
#include <map>
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/String.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
}
|
||||
#endif
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Store the content (i.e: the properties) of a behavior of an object.
|
||||
*
|
||||
* \see gd::Behavior
|
||||
* \see gd::BehaviorsSharedData
|
||||
* \see gd::Object
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API BehaviorContent {
|
||||
public:
|
||||
BehaviorContent(const gd::String& name_, const gd::String& type_)
|
||||
: name(name_), type(type_){};
|
||||
virtual ~BehaviorContent();
|
||||
virtual BehaviorContent* Clone() const { return new BehaviorContent(*this); }
|
||||
|
||||
/**
|
||||
* \brief Return the name identifying the behavior
|
||||
*/
|
||||
virtual const gd::String& GetName() const { return name; }
|
||||
|
||||
/**
|
||||
* \brief Change the name identifying the behavior
|
||||
*/
|
||||
virtual void SetName(const gd::String& name_) { name = name_; }
|
||||
|
||||
/**
|
||||
* \brief Get the type of the behavior.
|
||||
*/
|
||||
virtual const gd::String& GetTypeName() const { return type; }
|
||||
|
||||
/**
|
||||
* \brief Change the type of the behavior
|
||||
*/
|
||||
virtual void SetTypeName(const gd::String& type_) { type = type_; }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Serialize the behavior content.
|
||||
*/
|
||||
virtual void SerializeTo(gd::SerializerElement& element) const {
|
||||
element = content;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the behavior content.
|
||||
*/
|
||||
virtual void UnserializeFrom(const gd::SerializerElement& element) {
|
||||
content = element;
|
||||
};
|
||||
|
||||
const gd::SerializerElement& GetContent() const { return content; };
|
||||
gd::SerializerElement& GetContent() { return content; };
|
||||
|
||||
protected:
|
||||
gd::String name; ///< Name of the behavior
|
||||
gd::String type; ///< The type of the behavior that is represented. Usually
|
||||
///< in the form "ExtensionName::BehaviorTypeName"
|
||||
|
||||
gd::SerializerElement content; // Storage for the behavior properties
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_BEHAVIORCONTENT_H
|
@@ -5,21 +5,11 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <map>
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
BehaviorsSharedData::~BehaviorsSharedData(){};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor> BehaviorsSharedData::GetProperties(
|
||||
const gd::SerializerElement& behaviorSharedDataContent) const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,19 +4,11 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef BEHAVIORSSHAREDDATA_H
|
||||
#define BEHAVIORSSHAREDDATA_H
|
||||
#ifndef GDCORE_BEHAVIORSSHAREDDATA_H
|
||||
#define GDCORE_BEHAVIORSSHAREDDATA_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/String.h"
|
||||
class BehaviorsRuntimeSharedData;
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
#include "GDCore/Project/BehaviorConfigurationContainer.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -29,63 +21,15 @@ namespace gd {
|
||||
*
|
||||
* \ingroup GameEngine
|
||||
*/
|
||||
class GD_CORE_API BehaviorsSharedData {
|
||||
class GD_CORE_API BehaviorsSharedData: public BehaviorConfigurationContainer {
|
||||
public:
|
||||
BehaviorsSharedData(){};
|
||||
BehaviorsSharedData(): BehaviorConfigurationContainer() {};
|
||||
BehaviorsSharedData(const gd::String& name_, const gd::String& type_)
|
||||
: BehaviorConfigurationContainer(name_, type_) {};
|
||||
virtual ~BehaviorsSharedData();
|
||||
virtual gd::BehaviorsSharedData* Clone() const {
|
||||
return new BehaviorsSharedData(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the name identifying the type of the behavior
|
||||
*/
|
||||
gd::String GetTypeName() { return type; }
|
||||
|
||||
/**
|
||||
* \brief Change name identifying the type of the behavior.
|
||||
*/
|
||||
void SetTypeName(const gd::String& type_) { type = type_; };
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the properties of the shared
|
||||
data.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Initial speed")].SetValue(gd::String::From(initialSpeed));
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
|
||||
const gd::SerializerElement& behaviorSharedDataContent) const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a property of the shared data
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateProperty(gd::SerializerElement& behaviorSharedDataContent,
|
||||
const gd::String& name,
|
||||
const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
#endif
|
||||
|
||||
virtual void InitializeContent(
|
||||
gd::SerializerElement& behaviorSharedDataContent){};
|
||||
|
||||
private:
|
||||
gd::String type; ///< The type indicate of which type is the behavior.
|
||||
virtual BehaviorsSharedData* Clone() const override { return new BehaviorsSharedData(*this); }
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // BEHAVIORSSHAREDDATA_H
|
||||
#endif // GDCORE_BEHAVIORSSHAREDDATA_H
|
||||
|
119
Core/GDCore/Project/CustomBehavior.cpp
Normal file
119
Core/GDCore/Project/CustomBehavior.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "CustomBehavior.h"
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
using namespace gd;
|
||||
|
||||
CustomBehavior *CustomBehavior::Clone() const {
|
||||
CustomBehavior *clone = new CustomBehavior(*this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomBehavior::GetProperties(
|
||||
const gd::SerializerElement &behaviorContent) const {
|
||||
auto behaviorProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
if (!project.HasEventsBasedBehavior(GetTypeName())) {
|
||||
return behaviorProperties;
|
||||
}
|
||||
const auto &eventsBasedBehavior = project.GetEventsBasedBehavior(GetTypeName());
|
||||
const auto &properties = eventsBasedBehavior.GetPropertyDescriptors();
|
||||
|
||||
for (auto &property : properties.GetInternalVector()) {
|
||||
const auto &propertyName = property->GetName();
|
||||
const auto &propertyType = property->GetType();
|
||||
|
||||
// TODO Move this into a PropertyDescriptor copy method.
|
||||
auto &newProperty = behaviorProperties[propertyName]
|
||||
.SetType(property->GetType())
|
||||
.SetDescription(property->GetDescription())
|
||||
.SetGroup(property->GetGroup())
|
||||
.SetLabel(property->GetLabel())
|
||||
.SetValue(property->GetValue())
|
||||
.SetHidden(property->IsHidden());
|
||||
|
||||
for (auto &extraInfo : property->GetExtraInfo()) {
|
||||
newProperty.AddExtraInfo(extraInfo);
|
||||
}
|
||||
|
||||
if (behaviorContent.HasChild(propertyName)) {
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior") {
|
||||
newProperty.SetValue(
|
||||
behaviorContent.GetChild(propertyName).GetStringValue());
|
||||
} else if (propertyType == "Number") {
|
||||
newProperty.SetValue(gd::String::From(
|
||||
behaviorContent.GetChild(propertyName).GetDoubleValue()));
|
||||
} else if (propertyType == "Boolean") {
|
||||
newProperty.SetValue(
|
||||
behaviorContent.GetChild(propertyName).GetBoolValue() ? "true"
|
||||
: "false");
|
||||
}
|
||||
} else {
|
||||
// No value was serialized for this property. `newProperty`
|
||||
// will have the default value coming from `enumeratedProperty`.
|
||||
}
|
||||
}
|
||||
|
||||
return behaviorProperties;
|
||||
}
|
||||
|
||||
bool CustomBehavior::UpdateProperty(gd::SerializerElement &behaviorContent,
|
||||
const gd::String &propertyName,
|
||||
const gd::String &newValue) {
|
||||
if (!project.HasEventsBasedBehavior(GetTypeName())) {
|
||||
return false;
|
||||
}
|
||||
const auto &eventsBasedBehavior = project.GetEventsBasedBehavior(GetTypeName());
|
||||
const auto &properties = eventsBasedBehavior.GetPropertyDescriptors();
|
||||
if (!properties.Has(propertyName)) {
|
||||
return false;
|
||||
}
|
||||
const auto &property = properties.Get(propertyName);
|
||||
|
||||
auto &element = behaviorContent.AddChild(propertyName);
|
||||
const gd::String &propertyType = property.GetType();
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior") {
|
||||
element.SetStringValue(newValue);
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(newValue.To<double>());
|
||||
} else if (propertyType == "Boolean") {
|
||||
element.SetBoolValue(newValue == "1");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CustomBehavior::InitializeContent(gd::SerializerElement &behaviorContent) {
|
||||
if (!project.HasEventsBasedBehavior(GetTypeName())) {
|
||||
return;
|
||||
}
|
||||
const auto &eventsBasedBehavior = project.GetEventsBasedBehavior(GetTypeName());
|
||||
const auto &properties = eventsBasedBehavior.GetPropertyDescriptors();
|
||||
for (auto &&property : properties.GetInternalVector()) {
|
||||
auto &element = behaviorContent.AddChild(property->GetName());
|
||||
auto propertyType = property->GetType();
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior") {
|
||||
element.SetStringValue(property->GetValue());
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(property->GetValue().To<double>());
|
||||
} else if (propertyType == "Boolean") {
|
||||
element.SetBoolValue(property->GetValue() == "true");
|
||||
}
|
||||
}
|
||||
}
|
51
Core/GDCore/Project/CustomBehavior.h
Normal file
51
Core/GDCore/Project/CustomBehavior.h
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.
|
||||
*/
|
||||
#ifndef GDCORE_CUSTOMBEHAVIOR_H
|
||||
#define GDCORE_CUSTOMBEHAVIOR_H
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief A gd::Behavior that stores its content in JSON and forward the
|
||||
* properties related functions to Javascript with Emscripten.
|
||||
*/
|
||||
class CustomBehavior : public gd::Behavior {
|
||||
public:
|
||||
CustomBehavior(const gd::String &name,
|
||||
const Project &project_,
|
||||
const gd::String &fullType)
|
||||
: Behavior(name, fullType),
|
||||
project(project_) {}
|
||||
CustomBehavior *Clone() const override;
|
||||
|
||||
using Behavior::GetProperties;
|
||||
using Behavior::InitializeContent;
|
||||
using Behavior::UpdateProperty;
|
||||
|
||||
protected:
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetProperties(const gd::SerializerElement &behaviorContent) const override;
|
||||
virtual bool UpdateProperty(gd::SerializerElement &behaviorContent,
|
||||
const gd::String &name,
|
||||
const gd::String &value) override;
|
||||
virtual void
|
||||
InitializeContent(gd::SerializerElement &behaviorContent) override;
|
||||
|
||||
private:
|
||||
const Project &project; ///< The project is used to get the
|
||||
///< EventBasedBehavior from the fullType.
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_CUSTOMBEHAVIOR_H
|
230
Core/GDCore/Project/CustomObjectConfiguration.cpp
Normal file
230
Core/GDCore/Project/CustomObjectConfiguration.cpp
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "CustomObjectConfiguration.h"
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
void CustomObjectConfiguration::Init(const gd::CustomObjectConfiguration& objectConfiguration) {
|
||||
project = objectConfiguration.project;
|
||||
objectContent = objectConfiguration.objectContent;
|
||||
|
||||
// There is no default copy for a map of unique_ptr like childObjectConfigurations.
|
||||
childObjectConfigurations.clear();
|
||||
for (auto& it : objectConfiguration.childObjectConfigurations) {
|
||||
childObjectConfigurations[it.first] =
|
||||
gd::make_unique<gd::ObjectConfiguration>(*it.second);
|
||||
}
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration CustomObjectConfiguration::badObjectConfiguration;
|
||||
|
||||
std::unique_ptr<gd::ObjectConfiguration> CustomObjectConfiguration::Clone() const {
|
||||
CustomObjectConfiguration* clone = new CustomObjectConfiguration(*this);
|
||||
return std::unique_ptr<gd::ObjectConfiguration>(clone);
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(const gd::String &objectName) {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
if (!eventsBasedObject.HasObjectNamed(objectName)) {
|
||||
gd::LogError("Tried to get the configuration of a child-object:" + objectName
|
||||
+ " that doesn't exist in the event-based object: " + GetType());
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
|
||||
auto &childObject = eventsBasedObject.GetObject(objectName);
|
||||
auto configurationPosition = childObjectConfigurations.find(objectName);
|
||||
if (configurationPosition == childObjectConfigurations.end()) {
|
||||
childObjectConfigurations.insert(std::make_pair(
|
||||
objectName,
|
||||
project->CreateObjectConfiguration(childObject.GetType())));
|
||||
return *(childObjectConfigurations[objectName]);
|
||||
}
|
||||
else {
|
||||
auto &pair = *configurationPosition;
|
||||
auto &configuration = pair.second;
|
||||
return *configuration;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomObjectConfiguration::GetProperties() const {
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return objectProperties;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
const auto &properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
|
||||
for (auto &property : properties.GetInternalVector()) {
|
||||
const auto &propertyName = property->GetName();
|
||||
const auto &propertyType = property->GetType();
|
||||
|
||||
// TODO Move this into a PropertyDescriptor copy method.
|
||||
auto &newProperty = objectProperties[propertyName]
|
||||
.SetType(property->GetType())
|
||||
.SetDescription(property->GetDescription())
|
||||
.SetGroup(property->GetGroup())
|
||||
.SetLabel(property->GetLabel())
|
||||
.SetValue(property->GetValue())
|
||||
.SetHidden(property->IsHidden());
|
||||
|
||||
for (auto &extraInfo : property->GetExtraInfo()) {
|
||||
newProperty.AddExtraInfo(extraInfo);
|
||||
}
|
||||
|
||||
if (objectContent.HasChild(propertyName)) {
|
||||
if (
|
||||
propertyType == "String" ||
|
||||
propertyType == "Choice" ||
|
||||
propertyType == "Color"
|
||||
) {
|
||||
newProperty.SetValue(
|
||||
objectContent.GetChild(propertyName).GetStringValue()
|
||||
);
|
||||
} else if (propertyType == "Number") {
|
||||
newProperty.SetValue(
|
||||
gd::String::From(objectContent.GetChild(propertyName).GetDoubleValue())
|
||||
);
|
||||
} else if (propertyType == "Boolean") {
|
||||
newProperty.SetValue(
|
||||
objectContent.GetChild(propertyName).GetBoolValue()
|
||||
? "true"
|
||||
: "false"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// No value was serialized for this property. `newProperty`
|
||||
// will have the default value coming from `enumeratedProperty`.
|
||||
}
|
||||
}
|
||||
|
||||
return objectProperties;
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::UpdateProperty(const gd::String& propertyName,
|
||||
const gd::String& newValue) {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return false;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
const auto &properties = eventsBasedObject.GetPropertyDescriptors();
|
||||
if (!properties.Has(propertyName)) {
|
||||
return false;
|
||||
}
|
||||
const auto &property = properties.Get(propertyName);
|
||||
|
||||
auto &element = objectContent.AddChild(propertyName);
|
||||
const gd::String &propertyType = property.GetType();
|
||||
|
||||
if (
|
||||
propertyType == "String" ||
|
||||
propertyType == "Choice" ||
|
||||
propertyType == "Color"
|
||||
) {
|
||||
element.SetStringValue(newValue);
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(newValue.To<double>());
|
||||
} else if (propertyType == "Boolean") {
|
||||
element.SetBoolValue(newValue == "1");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
CustomObjectConfiguration::GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
return std::map<gd::String, gd::PropertyDescriptor>();
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::UpdateInitialInstanceProperty(
|
||||
gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CustomObjectConfiguration::DoSerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("content") = objectContent;
|
||||
auto &childrenContentElement = element.AddChild("childrenContent");
|
||||
for (auto &pair : childObjectConfigurations) {
|
||||
auto &childName = pair.first;
|
||||
auto &childConfiguration = pair.second;
|
||||
auto &childElement = childrenContentElement.AddChild(childName);
|
||||
childConfiguration->SerializeTo(childElement);
|
||||
}
|
||||
}
|
||||
void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
const SerializerElement& element) {
|
||||
objectContent = element.GetChild("content");
|
||||
auto &childrenContentElement = element.GetChild("childrenContent");
|
||||
for (auto &pair : childrenContentElement.GetAllChildren()) {
|
||||
auto &childName = pair.first;
|
||||
auto &childElement = pair.second;
|
||||
auto &childConfiguration = GetChildObjectConfiguration(childName);
|
||||
childConfiguration.UnserializeFrom(project, *childElement);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomObjectConfiguration::ExposeResources(
|
||||
gd::ArbitraryResourceWorker& worker) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties = GetProperties();
|
||||
|
||||
for (auto& property : properties) {
|
||||
const String& propertyName = property.first;
|
||||
const gd::PropertyDescriptor& propertyDescriptor = property.second;
|
||||
if (propertyDescriptor.GetType() == "resource") {
|
||||
auto& extraInfo = propertyDescriptor.GetExtraInfo();
|
||||
const gd::String& resourceType = extraInfo.empty() ? "" : extraInfo[0];
|
||||
const gd::String& oldPropertyValue = propertyDescriptor.GetValue();
|
||||
|
||||
gd::String newPropertyValue = oldPropertyValue;
|
||||
if (resourceType == "image") {
|
||||
worker.ExposeImage(newPropertyValue);
|
||||
} else if (resourceType == "audio") {
|
||||
worker.ExposeAudio(newPropertyValue);
|
||||
} else if (resourceType == "font") {
|
||||
worker.ExposeFont(newPropertyValue);
|
||||
} else if (resourceType == "video") {
|
||||
worker.ExposeVideo(newPropertyValue);
|
||||
} else if (resourceType == "json") {
|
||||
worker.ExposeJson(newPropertyValue);
|
||||
} else if (resourceType == "bitmapFont") {
|
||||
worker.ExposeBitmapFont(newPropertyValue);
|
||||
}
|
||||
|
||||
if (newPropertyValue != oldPropertyValue) {
|
||||
UpdateProperty(propertyName, newPropertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
for (auto& childObject : eventsBasedObject.GetObjects()) {
|
||||
auto &configuration = GetChildObjectConfiguration(childObject->GetName());
|
||||
configuration.ExposeResources(worker);
|
||||
}
|
||||
}
|
100
Core/GDCore/Project/CustomObjectConfiguration.h
Normal file
100
Core/GDCore/Project/CustomObjectConfiguration.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
||||
#define GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
||||
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief A gd::ObjectConfiguration that stores its content in JSON and is
|
||||
* composed of other configuration according to it's object children.
|
||||
*
|
||||
* It also implements "ExposeResources" to expose the properties of type
|
||||
* "resource".
|
||||
*/
|
||||
class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
public:
|
||||
CustomObjectConfiguration(const Project& project_, const String& type_)
|
||||
: project(&project_) {
|
||||
SetType(type_);
|
||||
}
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override;
|
||||
|
||||
/**
|
||||
* Copy constructor. Calls Init().
|
||||
*/
|
||||
CustomObjectConfiguration(const gd::CustomObjectConfiguration& object)
|
||||
: ObjectConfiguration(object) {
|
||||
Init(object);
|
||||
};
|
||||
|
||||
/**
|
||||
* Assignment operator. Calls Init().
|
||||
*/
|
||||
CustomObjectConfiguration& operator=(const gd::CustomObjectConfiguration& object){
|
||||
if ((this) != &object) {
|
||||
ObjectConfiguration::operator=(object);
|
||||
Init(object);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
gd::ObjectConfiguration &GetChildObjectConfiguration(const gd::String& objectName);
|
||||
|
||||
protected:
|
||||
void DoSerializeTo(SerializerElement& element) const override;
|
||||
void DoUnserializeFrom(Project& project, const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
const Project* project; ///< The project is used to get the
|
||||
///< EventBasedObject from the fullType.
|
||||
gd::SerializerElement objectContent;
|
||||
std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
|
||||
static gd::ObjectConfiguration badObjectConfiguration;
|
||||
|
||||
/**
|
||||
* Initialize configuration using another configuration. Used by copy-ctor
|
||||
* and assign-op.
|
||||
*
|
||||
* Don't forget to update me if members were changed!
|
||||
*
|
||||
* It's needed because there is no default copy for childObjectConfigurations
|
||||
* and it must be a deep copy.
|
||||
*/
|
||||
void Init(const gd::CustomObjectConfiguration& object);
|
||||
};
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_CUSTOMOBJECTCONFIGURATION_H
|
@@ -3,7 +3,6 @@
|
||||
* 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 "EventsBasedBehavior.h"
|
||||
#include "EventsFunctionsContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -12,36 +11,17 @@
|
||||
namespace gd {
|
||||
|
||||
EventsBasedBehavior::EventsBasedBehavior()
|
||||
: name("MyBehavior"), fullName("") {}
|
||||
: AbstractEventsBasedEntity("MyBehavior") {}
|
||||
|
||||
void EventsBasedBehavior::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
element.SetAttribute("objectType", objectType);
|
||||
|
||||
gd::SerializerElement& eventsFunctionsElement =
|
||||
element.AddChild("eventsFunctions");
|
||||
eventsFunctionsContainer.SerializeEventsFunctionsTo(eventsFunctionsElement);
|
||||
propertyDescriptors.SerializeElementsTo(
|
||||
"propertyDescriptor", element.AddChild("propertyDescriptors"));
|
||||
}
|
||||
|
||||
void EventsBasedBehavior::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
description = element.GetStringAttribute("description");
|
||||
name = element.GetStringAttribute("name");
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
AbstractEventsBasedEntity::UnserializeFrom(project, element);
|
||||
objectType = element.GetStringAttribute("objectType");
|
||||
|
||||
const gd::SerializerElement& eventsFunctionsElement =
|
||||
element.GetChild("eventsFunctions");
|
||||
eventsFunctionsContainer.UnserializeEventsFunctionsFrom(
|
||||
project, eventsFunctionsElement);
|
||||
propertyDescriptors.UnserializeElementsFrom(
|
||||
"propertyDescriptor", element.GetChild("propertyDescriptors"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
|
@@ -3,11 +3,11 @@
|
||||
* 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_EVENTSBASEDBEHAVIOR_H
|
||||
#define GDCORE_EVENTSBASEDBEHAVIOR_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/AbstractEventsBasedEntity.h"
|
||||
#include "GDCore/Project/NamedPropertyDescriptor.h"
|
||||
#include "GDCore/Tools/SerializableWithNameList.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
@@ -28,7 +28,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API EventsBasedBehavior {
|
||||
class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
public:
|
||||
EventsBasedBehavior();
|
||||
virtual ~EventsBasedBehavior(){};
|
||||
@@ -39,43 +39,24 @@ class GD_CORE_API EventsBasedBehavior {
|
||||
*/
|
||||
EventsBasedBehavior* Clone() const { return new EventsBasedBehavior(*this); };
|
||||
|
||||
/**
|
||||
* \brief Get the description of the behavior, that is displayed in the
|
||||
* editor.
|
||||
*/
|
||||
const gd::String& GetDescription() const { return description; };
|
||||
|
||||
/**
|
||||
* \brief Set the description of the behavior, to be displayed in the editor.
|
||||
*/
|
||||
EventsBasedBehavior& SetDescription(const gd::String& description_) {
|
||||
description = description_;
|
||||
EventsBasedBehavior& SetDescription(const gd::String& description_) override {
|
||||
AbstractEventsBasedEntity::SetDescription(description_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the internal name of the behavior.
|
||||
*/
|
||||
const gd::String& GetName() const { return name; };
|
||||
|
||||
/**
|
||||
* \brief Set the internal name of the behavior.
|
||||
*/
|
||||
EventsBasedBehavior& SetName(const gd::String& name_) {
|
||||
name = name_;
|
||||
AbstractEventsBasedEntity::SetName(name_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the behavior, that is displayed in the editor.
|
||||
*/
|
||||
const gd::String& GetFullName() const { return fullName; };
|
||||
|
||||
/**
|
||||
* \brief Set the name of the behavior, to be displayed in the editor.
|
||||
*/
|
||||
EventsBasedBehavior& SetFullName(const gd::String& fullName_) {
|
||||
fullName = fullName_;
|
||||
AbstractEventsBasedEntity::SetFullName(fullName_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -92,76 +73,15 @@ class GD_CORE_API EventsBasedBehavior {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the functions of the events based behavior.
|
||||
*/
|
||||
EventsFunctionsContainer& GetEventsFunctions() {
|
||||
return eventsFunctionsContainer;
|
||||
}
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the functions of the events based
|
||||
* behavior.
|
||||
*/
|
||||
const EventsFunctionsContainer& GetEventsFunctions() const {
|
||||
return eventsFunctionsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of the properties.
|
||||
*/
|
||||
SerializableWithNameList<NamedPropertyDescriptor>& GetPropertyDescriptors() {
|
||||
return propertyDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the list of the properties.
|
||||
*/
|
||||
const SerializableWithNameList<NamedPropertyDescriptor>& GetPropertyDescriptors()
|
||||
const {
|
||||
return propertyDescriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the name of the action to change a property.
|
||||
*/
|
||||
static gd::String GetPropertyActionName(const gd::String& propertyName) { return "SetProperty" + propertyName; };
|
||||
|
||||
/**
|
||||
* \brief Get the name of the condition to compare a property.
|
||||
*/
|
||||
static gd::String GetPropertyConditionName(const gd::String& propertyName) { return "Property" + propertyName; };
|
||||
|
||||
/**
|
||||
* \brief Get the name of the expression to get a property.
|
||||
*/
|
||||
static gd::String GetPropertyExpressionName(const gd::String& propertyName) { return "Property" + propertyName; };
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the EventsBasedBehavior to the specified element
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the EventsBasedBehavior from the specified element
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
gd::String description;
|
||||
gd::String objectType;
|
||||
gd::EventsFunctionsContainer eventsFunctionsContainer;
|
||||
SerializableWithNameList<NamedPropertyDescriptor> propertyDescriptors;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSBASEDBEHAVIOR_H
|
||||
#endif
|
||||
|
36
Core/GDCore/Project/EventsBasedObject.cpp
Normal file
36
Core/GDCore/Project/EventsBasedObject.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EventsBasedObject.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
EventsBasedObject::EventsBasedObject()
|
||||
: AbstractEventsBasedEntity("MyObject"), ObjectsContainer() {
|
||||
}
|
||||
|
||||
EventsBasedObject::~EventsBasedObject() {}
|
||||
|
||||
EventsBasedObject::EventsBasedObject(const gd::EventsBasedObject &_eventBasedObject)
|
||||
: AbstractEventsBasedEntity(_eventBasedObject) {
|
||||
// TODO Add a copy constructor in ObjectsContainer.
|
||||
initialObjects = gd::Clone(_eventBasedObject.initialObjects);
|
||||
objectGroups = _eventBasedObject.objectGroups;
|
||||
}
|
||||
|
||||
void EventsBasedObject::SerializeTo(SerializerElement& element) const {
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
SerializeObjectsTo(element.AddChild("objects"));
|
||||
}
|
||||
|
||||
void EventsBasedObject::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
AbstractEventsBasedEntity::UnserializeFrom(project, element);
|
||||
UnserializeObjectsFrom(project, element.GetChild("objects"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
72
Core/GDCore/Project/EventsBasedObject.h
Normal file
72
Core/GDCore/Project/EventsBasedObject.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.
|
||||
*/
|
||||
#ifndef GDCORE_EVENTSBASEDOBJECT_H
|
||||
#define GDCORE_EVENTSBASEDOBJECT_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/AbstractEventsBasedEntity.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
// TODO EBO Add a way to mark some parts of children configuration as readonly.
|
||||
/**
|
||||
* \brief Represents an object that is implemented with events.
|
||||
*
|
||||
* It's the responsibility of the IDE to run the logic to transform this into a
|
||||
* real object, by declaring an extension and running code generation.
|
||||
* See `EventsFunctionsExtensionsLoader`.
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public ObjectsContainer {
|
||||
public:
|
||||
EventsBasedObject();
|
||||
virtual ~EventsBasedObject();
|
||||
EventsBasedObject(const gd::EventsBasedObject &_eventBasedObject);
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new EventsBasedObject constructed from
|
||||
* this one.
|
||||
*/
|
||||
EventsBasedObject* Clone() const { return new EventsBasedObject(*this); };
|
||||
|
||||
EventsBasedObject& SetDescription(const gd::String& description_) override {
|
||||
AbstractEventsBasedEntity::SetDescription(description_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the internal name of the object.
|
||||
*/
|
||||
EventsBasedObject& SetName(const gd::String& name_) {
|
||||
AbstractEventsBasedEntity::SetName(name_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the name of the object, to be displayed in the editor.
|
||||
*/
|
||||
EventsBasedObject& SetFullName(const gd::String& fullName_) {
|
||||
AbstractEventsBasedEntity::SetFullName(fullName_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSBASEDOBJECT_H
|
@@ -6,6 +6,7 @@
|
||||
#include "EventsFunctionsExtension.h"
|
||||
|
||||
#include "EventsBasedBehavior.h"
|
||||
#include "EventsBasedObject.h"
|
||||
#include "EventsFunction.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
@@ -42,6 +43,7 @@ void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
|
||||
helpPath = other.helpPath;
|
||||
EventsFunctionsContainer::Init(other);
|
||||
eventsBasedBehaviors = other.eventsBasedBehaviors;
|
||||
eventsBasedObjects = other.eventsBasedObjects;
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
@@ -79,9 +81,17 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
SerializeEventsFunctionsTo(element.AddChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.SerializeElementsTo(
|
||||
"eventsBasedBehavior", element.AddChild("eventsBasedBehaviors"));
|
||||
eventsBasedObjects.SerializeElementsTo(
|
||||
"eventsBasedObject", element.AddChild("eventsBasedObjects"));
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::UnserializeFrom(
|
||||
gd::Project& project, const SerializerElement& element) {
|
||||
UnserializeExtensionDeclarationFrom(project, element);
|
||||
UnserializeExtensionImplementationFrom(project, element);
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::UnserializeExtensionDeclarationFrom(
|
||||
gd::Project& project, const SerializerElement& element) {
|
||||
version = element.GetStringAttribute("version");
|
||||
extensionNamespace = element.GetStringAttribute("extensionNamespace");
|
||||
@@ -134,9 +144,48 @@ void EventsFunctionsExtension::UnserializeFrom(
|
||||
dependencies.push_back(
|
||||
UnserializeDependencyFrom(dependenciesElement.GetChild(i)));
|
||||
|
||||
// Only unserialize behaviors and objects names.
|
||||
// As event based objects can contains objects using CustomBehavior and/or
|
||||
// CustomObject, this allows them to reference EventBasedBehavior and
|
||||
// EventBasedObject respectively.
|
||||
auto &behaviorsElement = element.GetChild("eventsBasedBehaviors");
|
||||
behaviorsElement.ConsiderAsArrayOf("eventsBasedBehavior");
|
||||
for (std::size_t i = 0; i < behaviorsElement.GetChildrenCount(); ++i) {
|
||||
const gd::String &behaviorName =
|
||||
behaviorsElement.GetChild(i).GetStringAttribute("name");
|
||||
eventsBasedBehaviors.InsertNew(behaviorName, eventsBasedBehaviors.GetCount());
|
||||
}
|
||||
auto &objectsElement = element.GetChild("eventsBasedObjects");
|
||||
objectsElement.ConsiderAsArrayOf("eventsBasedObject");
|
||||
for (std::size_t i = 0; i < objectsElement.GetChildrenCount(); ++i) {
|
||||
const gd::String &objectName =
|
||||
objectsElement.GetChild(i).GetStringAttribute("name");
|
||||
eventsBasedObjects.InsertNew(objectName, eventsBasedObjects.GetCount());
|
||||
}
|
||||
}
|
||||
|
||||
void EventsFunctionsExtension::UnserializeExtensionImplementationFrom(
|
||||
gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
UnserializeEventsFunctionsFrom(project, element.GetChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.UnserializeElementsFrom(
|
||||
"eventsBasedBehavior", project, element.GetChild("eventsBasedBehaviors"));
|
||||
auto &behaviorsElement = element.GetChild("eventsBasedBehaviors");
|
||||
behaviorsElement.ConsiderAsArrayOf("eventsBasedBehavior");
|
||||
for (std::size_t i = 0; i < behaviorsElement.GetChildrenCount(); ++i) {
|
||||
const gd::String &behaviorName =
|
||||
behaviorsElement.GetChild(i).GetStringAttribute("name");
|
||||
if (eventsBasedBehaviors.Has(behaviorName)) {
|
||||
eventsBasedBehaviors.Get(behaviorName).UnserializeFrom(project, behaviorsElement.GetChild(i));
|
||||
}
|
||||
}
|
||||
auto &objectsElement = element.GetChild("eventsBasedObjects");
|
||||
objectsElement.ConsiderAsArrayOf("eventsBasedObject");
|
||||
for (std::size_t i = 0; i < objectsElement.GetChildrenCount(); ++i) {
|
||||
const gd::String &objectName =
|
||||
objectsElement.GetChild(i).GetStringAttribute("name");
|
||||
if (eventsBasedObjects.Has(objectName)) {
|
||||
eventsBasedObjects.Get(objectName).UnserializeFrom(project, objectsElement.GetChild(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EventsFunctionsExtension::IsExtensionLifecycleEventsFunction(
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/SerializableWithNameList.h"
|
||||
@@ -145,6 +146,21 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
return eventsBasedBehaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of the events based objects.
|
||||
*/
|
||||
gd::SerializableWithNameList<EventsBasedObject>& GetEventsBasedObjects() {
|
||||
return eventsBasedObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the list of the events based objects.
|
||||
*/
|
||||
const gd::SerializableWithNameList<EventsBasedObject>&
|
||||
GetEventsBasedObjects() const {
|
||||
return eventsBasedObjects;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets an extension origin. This method is not present since the
|
||||
* beginning so the projects created before that will have extensions
|
||||
@@ -200,10 +216,26 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the EventsFunctionsExtension from the specified element
|
||||
* \brief Load the EventsFunctionsExtension from the specified element.
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
|
||||
/**
|
||||
* \brief Load the extension without free functions, behaviors and objects
|
||||
* implementation.
|
||||
*/
|
||||
void UnserializeExtensionDeclarationFrom(
|
||||
gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
|
||||
/**
|
||||
* \brief Load free functions, behaviors and objects implementation
|
||||
* (in opposition to load just their "declaration" by reading their name).
|
||||
*/
|
||||
void UnserializeExtensionImplementationFrom(
|
||||
gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
|
||||
/** \name Lifecycle event functions
|
||||
@@ -255,6 +287,7 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation (or an absolute URL).
|
||||
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
gd::SerializableWithNameList<EventsBasedObject> eventsBasedObjects;
|
||||
std::vector<gd::DependencyMetadata> dependencies;
|
||||
};
|
||||
|
||||
|
@@ -11,9 +11,7 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -30,6 +28,7 @@ InitialInstance::InitialInstance()
|
||||
width(0),
|
||||
height(0),
|
||||
locked(false),
|
||||
sealed(false),
|
||||
persistentUuid(UUID::MakeUuid4()) {}
|
||||
|
||||
void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
@@ -44,6 +43,7 @@ void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
SetZOrder(element.GetIntAttribute("zOrder", 0, "plan"));
|
||||
SetLayer(element.GetStringAttribute("layer"));
|
||||
SetLocked(element.GetBoolAttribute("locked", false));
|
||||
SetSealed(element.GetBoolAttribute("sealed", false));
|
||||
|
||||
persistentUuid = element.GetStringAttribute("persistentUuid");
|
||||
if (persistentUuid.empty()) ResetPersistentUuid();
|
||||
@@ -83,7 +83,8 @@ void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("customSize", HasCustomSize());
|
||||
element.SetAttribute("width", GetCustomWidth());
|
||||
element.SetAttribute("height", GetCustomHeight());
|
||||
element.SetAttribute("locked", IsLocked());
|
||||
if (IsLocked()) element.SetAttribute("locked", IsLocked());
|
||||
if (IsSealed()) element.SetAttribute("sealed", IsSealed());
|
||||
|
||||
if (persistentUuid.empty()) persistentUuid = UUID::MakeUuid4();
|
||||
element.SetStringAttribute("persistentUuid", persistentUuid);
|
||||
@@ -112,15 +113,14 @@ InitialInstance& InitialInstance::ResetPersistentUuid() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
InitialInstance::GetCustomProperties(gd::Project& project, gd::Layout& layout) {
|
||||
// Find an object
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
return layout.GetObject(GetObjectName()).GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
return project.GetObject(GetObjectName()).GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
@@ -132,15 +132,14 @@ bool InitialInstance::UpdateCustomProperty(const gd::String& name,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
return layout.GetObject(GetObjectName()).GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
return project.GetObject(GetObjectName()).GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
double InitialInstance::GetRawDoubleProperty(const gd::String& name) const {
|
||||
const auto& it = numberProperties.find(name);
|
||||
|
@@ -127,19 +127,31 @@ class GD_CORE_API InitialInstance {
|
||||
void SetCustomHeight(double height_) { height = height_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance is locked and cannot be selected by
|
||||
* clicking on it in the IDE.
|
||||
* \brief Return true if the instance is locked and cannot be moved in the IDE.
|
||||
*/
|
||||
bool IsLocked() const { return locked; };
|
||||
|
||||
/**
|
||||
* \brief (Un)lock the initial instance.
|
||||
*
|
||||
* An instance which is locked cannot be selected by clicking on it in a
|
||||
* layout editor canvas.
|
||||
* An instance which is locked cannot be moved with actions in the IDE.
|
||||
*/
|
||||
void SetLocked(bool enable = true) { locked = enable; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance cannot be selected by clicking on it
|
||||
* in the IDE (only applies if instance is also locked).
|
||||
*/
|
||||
bool IsSealed() const { return sealed; };
|
||||
|
||||
/**
|
||||
* \brief (Un)seal the initial instance.
|
||||
*
|
||||
* An instance which is sealed cannot be selected by clicking on it in a
|
||||
* layout editor canvas.
|
||||
*/
|
||||
void SetSealed(bool enable = true) { sealed = enable; }
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Variable management
|
||||
@@ -270,6 +282,7 @@ class GD_CORE_API InitialInstance {
|
||||
double height; ///< Object custom height
|
||||
gd::VariablesContainer initialVariables; ///< Instance specific variables
|
||||
bool locked; ///< True if the instance is locked
|
||||
bool sealed; ///< True if the instance is sealed
|
||||
mutable gd::String persistentUuid; ///< A persistent random version 4 UUID, useful for hot reloading.
|
||||
|
||||
static gd::String*
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/SceneNameMangler.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/InitialInstance.h"
|
||||
#include "GDCore/Project/Layer.h"
|
||||
@@ -33,7 +32,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
gd::Layer Layout::badLayer;
|
||||
gd::BehaviorContent Layout::badBehaviorContent("", "");
|
||||
gd::BehaviorsSharedData Layout::badBehaviorSharedData("", "");
|
||||
|
||||
Layout::Layout(const Layout& other) { Init(other); }
|
||||
|
||||
@@ -51,9 +50,6 @@ Layout::Layout()
|
||||
backgroundColorB(209),
|
||||
stopSoundsOnStartup(true),
|
||||
standardSortMethod(true),
|
||||
oglFOV(90.0f),
|
||||
oglZNear(1.0f),
|
||||
oglZFar(500.0f),
|
||||
disableInputWhenNotFocused(true),
|
||||
profiler(NULL)
|
||||
{
|
||||
@@ -79,23 +75,23 @@ std::vector<gd::String> Layout::GetAllBehaviorSharedDataNames() const {
|
||||
return allNames;
|
||||
}
|
||||
|
||||
const gd::BehaviorContent& Layout::GetBehaviorSharedData(
|
||||
const gd::BehaviorsSharedData& Layout::GetBehaviorSharedData(
|
||||
const gd::String& behaviorName) const {
|
||||
auto it = behaviorsSharedData.find(behaviorName);
|
||||
if (it != behaviorsSharedData.end()) return *it->second;
|
||||
|
||||
return badBehaviorContent;
|
||||
return badBehaviorSharedData;
|
||||
}
|
||||
|
||||
gd::BehaviorContent& Layout::GetBehaviorSharedData(
|
||||
gd::BehaviorsSharedData& Layout::GetBehaviorSharedData(
|
||||
const gd::String& behaviorName) {
|
||||
auto it = behaviorsSharedData.find(behaviorName);
|
||||
if (it != behaviorsSharedData.end()) return *it->second;
|
||||
|
||||
return badBehaviorContent;
|
||||
return badBehaviorSharedData;
|
||||
}
|
||||
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorContent> >&
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorsSharedData> >&
|
||||
Layout::GetAllBehaviorSharedData() const {
|
||||
return behaviorsSharedData;
|
||||
}
|
||||
@@ -197,20 +193,20 @@ void Layout::UpdateBehaviorsSharedData(gd::Project& project) {
|
||||
std::vector<gd::String> objectBehaviors =
|
||||
initialObjects[i]->GetAllBehaviorNames();
|
||||
for (unsigned int j = 0; j < objectBehaviors.size(); ++j) {
|
||||
auto& behaviorContent =
|
||||
auto& behavior =
|
||||
initialObjects[i]->GetBehavior(objectBehaviors[j]);
|
||||
allBehaviorsTypes.push_back(behaviorContent.GetTypeName());
|
||||
allBehaviorsNames.push_back(behaviorContent.GetName());
|
||||
allBehaviorsTypes.push_back(behavior.GetTypeName());
|
||||
allBehaviorsNames.push_back(behavior.GetName());
|
||||
}
|
||||
}
|
||||
for (std::size_t i = 0; i < project.GetObjectsCount(); ++i) {
|
||||
std::vector<gd::String> objectBehaviors =
|
||||
project.GetObject(i).GetAllBehaviorNames();
|
||||
for (std::size_t j = 0; j < objectBehaviors.size(); ++j) {
|
||||
auto& behaviorContent =
|
||||
auto& behavior =
|
||||
project.GetObject(i).GetBehavior(objectBehaviors[j]);
|
||||
allBehaviorsTypes.push_back(behaviorContent.GetTypeName());
|
||||
allBehaviorsNames.push_back(behaviorContent.GetName());
|
||||
allBehaviorsTypes.push_back(behavior.GetTypeName());
|
||||
allBehaviorsNames.push_back(behavior.GetName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,19 +218,34 @@ void Layout::UpdateBehaviorsSharedData(gd::Project& project) {
|
||||
|
||||
if (behaviorsSharedData.find(name) != behaviorsSharedData.end()) continue;
|
||||
|
||||
const gd::BehaviorMetadata& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
|
||||
allBehaviorsTypes[i]);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) continue;
|
||||
if (project.HasEventsBasedBehavior(allBehaviorsTypes[i])) {
|
||||
// Events based behaviors don't have shared data yet.
|
||||
auto sharedData =
|
||||
gd::make_unique<gd::BehaviorsSharedData>(name, allBehaviorsTypes[i]);
|
||||
sharedData->InitializeContent();
|
||||
behaviorsSharedData[name] = std::move(sharedData);
|
||||
}
|
||||
else {
|
||||
const gd::BehaviorMetadata& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(
|
||||
project.GetCurrentPlatform(),
|
||||
allBehaviorsTypes[i]);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* behaviorSharedData =
|
||||
behaviorMetadata.GetSharedDataInstance();
|
||||
if (!behaviorSharedData) continue;
|
||||
gd::BehaviorsSharedData* behaviorsSharedDataBluePrint =
|
||||
behaviorMetadata.GetSharedDataInstance();
|
||||
if (!behaviorsSharedDataBluePrint) continue;
|
||||
|
||||
auto behaviorContent =
|
||||
gd::make_unique<gd::BehaviorContent>(name, allBehaviorsTypes[i]);
|
||||
behaviorSharedData->InitializeContent(behaviorContent->GetContent());
|
||||
behaviorsSharedData[name] = std::move(behaviorContent);
|
||||
auto sharedData =
|
||||
gd::make_unique<gd::BehaviorsSharedData>(
|
||||
*behaviorsSharedDataBluePrint);
|
||||
sharedData->SetName(name);
|
||||
sharedData->SetTypeName(allBehaviorsTypes[i]);
|
||||
sharedData->InitializeContent();
|
||||
behaviorsSharedData[name] = std::move(sharedData);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove useless shared data:
|
||||
@@ -260,17 +271,12 @@ void Layout::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("v", (int)GetBackgroundColorGreen());
|
||||
element.SetAttribute("b", (int)GetBackgroundColorBlue());
|
||||
element.SetAttribute("title", GetWindowDefaultTitle());
|
||||
element.SetAttribute("oglFOV", oglFOV);
|
||||
element.SetAttribute("oglZNear", oglZNear);
|
||||
element.SetAttribute("oglZFar", oglZFar);
|
||||
element.SetAttribute("standardSortMethod", standardSortMethod);
|
||||
element.SetAttribute("stopSoundsOnStartup", stopSoundsOnStartup);
|
||||
element.SetAttribute("disableInputWhenNotFocused",
|
||||
disableInputWhenNotFocused);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
editorSettings.SerializeTo(element.AddChild("uiSettings"));
|
||||
#endif
|
||||
|
||||
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
GetVariables().SerializeTo(element.AddChild("variables"));
|
||||
@@ -321,9 +327,6 @@ void Layout::UnserializeFrom(gd::Project& project,
|
||||
element.GetIntAttribute("b"));
|
||||
SetWindowDefaultTitle(
|
||||
element.GetStringAttribute("title", "(No title)", "titre"));
|
||||
oglFOV = element.GetDoubleAttribute("oglFOV");
|
||||
oglZNear = element.GetDoubleAttribute("oglZNear");
|
||||
oglZFar = element.GetDoubleAttribute("oglZFar");
|
||||
standardSortMethod = element.GetBoolAttribute("standardSortMethod");
|
||||
stopSoundsOnStartup = element.GetBoolAttribute("stopSoundsOnStartup");
|
||||
disableInputWhenNotFocused =
|
||||
@@ -364,20 +367,20 @@ void Layout::UnserializeFrom(gd::Project& project,
|
||||
"Behavior"); // Compatibility with GD <= 4
|
||||
gd::String name = sharedDataElement.GetStringAttribute("name", "", "Name");
|
||||
|
||||
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
|
||||
auto behavior = gd::make_unique<gd::BehaviorsSharedData>(name, type);
|
||||
// Compatibility with GD <= 4.0.98
|
||||
// If there is only one child called "content" (in addition to "type" and
|
||||
// "name"), it's the content of a JavaScript behavior. Move the content
|
||||
// out of the "content" object (to put it directly at the root of the
|
||||
// behavior shared data element).
|
||||
if (sharedDataElement.HasChild("content")) {
|
||||
behaviorContent->UnserializeFrom(sharedDataElement.GetChild("content"));
|
||||
behavior->UnserializeFrom(sharedDataElement.GetChild("content"));
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
behaviorContent->UnserializeFrom(sharedDataElement);
|
||||
behavior->UnserializeFrom(sharedDataElement);
|
||||
}
|
||||
behaviorsSharedData[name] = std::move(behaviorContent);
|
||||
behaviorsSharedData[name] = std::move(behavior);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,9 +391,6 @@ void Layout::Init(const Layout& other) {
|
||||
backgroundColorB = other.backgroundColorB;
|
||||
standardSortMethod = other.standardSortMethod;
|
||||
title = other.title;
|
||||
oglFOV = other.oglFOV;
|
||||
oglZNear = other.oglZNear;
|
||||
oglZFar = other.oglZFar;
|
||||
stopSoundsOnStartup = other.stopSoundsOnStartup;
|
||||
disableInputWhenNotFocused = other.disableInputWhenNotFocused;
|
||||
initialInstances = other.initialInstances;
|
||||
@@ -402,7 +402,7 @@ void Layout::Init(const Layout& other) {
|
||||
behaviorsSharedData.clear();
|
||||
for (const auto& it : other.behaviorsSharedData) {
|
||||
behaviorsSharedData[it.first] =
|
||||
std::unique_ptr<gd::BehaviorContent>(it.second->Clone());
|
||||
gd::make_unique<gd::BehaviorsSharedData>(*(it.second->Clone()));
|
||||
}
|
||||
|
||||
events = other.events;
|
||||
|
@@ -17,14 +17,12 @@
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Object;
|
||||
class Project;
|
||||
class BehaviorContent;
|
||||
class InitialInstancesContainer;
|
||||
} // namespace gd
|
||||
class TiXmlElement;
|
||||
@@ -131,7 +129,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
*/
|
||||
///@{
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Get the events of the layout
|
||||
*/
|
||||
@@ -141,7 +138,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* Get the events of the layout
|
||||
*/
|
||||
gd::EventsList& GetEvents() { return events; }
|
||||
#endif
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Variable management
|
||||
@@ -238,12 +235,10 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
*/
|
||||
void MoveLayer(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Serialize the layers.
|
||||
*/
|
||||
void SerializeLayersTo(SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the layers.
|
||||
@@ -274,21 +269,21 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
/**
|
||||
* \brief Get the shared data stored for a behavior
|
||||
*/
|
||||
const gd::BehaviorContent& GetBehaviorSharedData(
|
||||
const gd::BehaviorsSharedData& GetBehaviorSharedData(
|
||||
const gd::String& behaviorName) const;
|
||||
|
||||
/**
|
||||
* \brief Get the shared data stored for a behavior
|
||||
*/
|
||||
gd::BehaviorContent& GetBehaviorSharedData(const gd::String& behaviorName);
|
||||
gd::BehaviorsSharedData& GetBehaviorSharedData(const gd::String& behaviorName);
|
||||
|
||||
/**
|
||||
* \brief Get a map of all shared data stored for behaviors
|
||||
*/
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorContent>>&
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorsSharedData>>&
|
||||
GetAllBehaviorSharedData() const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
/**
|
||||
* Return the settings associated to the layout.
|
||||
* \see gd::EditorSettings
|
||||
@@ -304,7 +299,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() {
|
||||
return editorSettings;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \name Other properties
|
||||
*/
|
||||
@@ -345,48 +339,16 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* launched
|
||||
*/
|
||||
bool StopSoundsOnStartup() const { return stopSoundsOnStartup; }
|
||||
|
||||
/**
|
||||
* Set OpenGL default field of view
|
||||
*/
|
||||
void SetOpenGLFOV(float oglFOV_) { oglFOV = oglFOV_; }
|
||||
|
||||
/**
|
||||
* Get OpenGL default field of view
|
||||
*/
|
||||
float GetOpenGLFOV() const { return oglFOV; }
|
||||
|
||||
/**
|
||||
* Set OpenGL near clipping plan
|
||||
*/
|
||||
void SetOpenGLZNear(float oglZNear_) { oglZNear = oglZNear_; }
|
||||
|
||||
/**
|
||||
* Get OpenGL near clipping plan
|
||||
*/
|
||||
float GetOpenGLZNear() const { return oglZNear; }
|
||||
|
||||
/**
|
||||
* Set OpenGL far clipping plan
|
||||
*/
|
||||
void SetOpenGLZFar(float oglZFar_) { oglZFar = oglZFar_; }
|
||||
|
||||
/**
|
||||
* Get OpenGL far clipping plan
|
||||
*/
|
||||
float GetOpenGLZFar() const { return oglZFar; }
|
||||
///@}
|
||||
|
||||
/** \name Saving and loading
|
||||
* Members functions related to saving and loading the object.
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Serialize the layout.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the layout.
|
||||
@@ -395,7 +357,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
///@}
|
||||
|
||||
// TODO: GD C++ Platform specific code below
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Get the profiler associated with the scene. Can be NULL.
|
||||
*/
|
||||
@@ -405,7 +366,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* Set the profiler associated with the scene. Can be NULL.
|
||||
*/
|
||||
void SetProfiler(BaseProfiler* profiler_) { profiler = profiler_; };
|
||||
#endif
|
||||
|
||||
private:
|
||||
gd::String name; ///< Scene name
|
||||
@@ -417,32 +377,27 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
gd::VariablesContainer variables; ///< Variables list
|
||||
gd::InitialInstancesContainer initialInstances; ///< Initial instances
|
||||
std::vector<gd::Layer> initialLayers; ///< Initial layers
|
||||
std::map<gd::String, std::unique_ptr<gd::BehaviorContent>>
|
||||
std::map<gd::String, std::unique_ptr<gd::BehaviorsSharedData>>
|
||||
behaviorsSharedData; ///< Initial shared datas of behaviors
|
||||
bool stopSoundsOnStartup; ///< True to make the scene stop all sounds at
|
||||
///< startup.
|
||||
bool standardSortMethod; ///< True to sort objects using standard sort.
|
||||
float oglFOV; ///< OpenGL Field Of View value
|
||||
float oglZNear; ///< OpenGL Near Z position
|
||||
float oglZFar; ///< OpenGL Far Z position
|
||||
bool disableInputWhenNotFocused; /// If set to true, the input must be
|
||||
/// disabled when the window do not have the
|
||||
/// focus.
|
||||
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not
|
||||
///< find an appropriate layer.
|
||||
static gd::BehaviorContent
|
||||
badBehaviorContent; ///< Null object, returned when
|
||||
static gd::BehaviorsSharedData
|
||||
badBehaviorSharedData; ///< Null object, returned when
|
||||
///< GetBehaviorSharedData can not find the
|
||||
///< specified behavior shared data.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
EventsList events; ///< Scene events
|
||||
gd::EditorSettings editorSettings;
|
||||
#endif
|
||||
|
||||
// TODO: GD C++ Platform specific code below
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
BaseProfiler* profiler; ///< Pointer to the profiler. Can be NULL.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize from another layout. Used by copy-ctor and assign-op.
|
||||
|
@@ -9,29 +9,52 @@
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
Object::~Object() {}
|
||||
|
||||
Object::Object(const gd::String& name_) : name(name_) {}
|
||||
Object::Object(const gd::String& name_,
|
||||
const gd::String& type_,
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration_)
|
||||
: name(name_), configuration(std::move(configuration_)) {
|
||||
SetType(type_);
|
||||
}
|
||||
|
||||
Object::Object(const gd::String& name_,
|
||||
const gd::String& type_,
|
||||
gd::ObjectConfiguration* configuration_)
|
||||
: name(name_), configuration(configuration_) {
|
||||
SetType(type_);
|
||||
}
|
||||
|
||||
void Object::Init(const gd::Object& object) {
|
||||
name = object.name;
|
||||
assetStoreId = object.assetStoreId;
|
||||
type = object.type;
|
||||
objectVariables = object.objectVariables;
|
||||
tags = object.tags;
|
||||
effectsContainer = object.effectsContainer;
|
||||
|
||||
behaviors.clear();
|
||||
for (auto& it : object.behaviors) {
|
||||
behaviors[it.first] = gd::make_unique<gd::BehaviorContent>(*it.second);
|
||||
behaviors[it.first] = gd::make_unique<gd::Behavior>(*it.second);
|
||||
}
|
||||
|
||||
configuration = object.configuration->Clone();
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration& Object::GetConfiguration() {
|
||||
return *configuration;
|
||||
}
|
||||
|
||||
const gd::ObjectConfiguration& Object::GetConfiguration() const {
|
||||
return *configuration;
|
||||
}
|
||||
|
||||
std::vector<gd::String> Object::GetAllBehaviorNames() const {
|
||||
@@ -49,7 +72,7 @@ bool Object::RenameBehavior(const gd::String& name, const gd::String& newName) {
|
||||
behaviors.find(newName) != behaviors.end())
|
||||
return false;
|
||||
|
||||
std::unique_ptr<BehaviorContent> aut =
|
||||
std::unique_ptr<Behavior> aut =
|
||||
std::move(behaviors.find(name)->second);
|
||||
behaviors.erase(name);
|
||||
behaviors[newName] = std::move(aut);
|
||||
@@ -58,11 +81,11 @@ bool Object::RenameBehavior(const gd::String& name, const gd::String& newName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
gd::BehaviorContent& Object::GetBehavior(const gd::String& name) {
|
||||
gd::Behavior& Object::GetBehavior(const gd::String& name) {
|
||||
return *behaviors.find(name)->second;
|
||||
}
|
||||
|
||||
const gd::BehaviorContent& Object::GetBehavior(const gd::String& name) const {
|
||||
const gd::Behavior& Object::GetBehavior(const gd::String& name) const {
|
||||
return *behaviors.find(name)->second;
|
||||
}
|
||||
|
||||
@@ -70,47 +93,41 @@ bool Object::HasBehaviorNamed(const gd::String& name) const {
|
||||
return behaviors.find(name) != behaviors.end();
|
||||
}
|
||||
|
||||
gd::BehaviorContent& Object::AddBehavior(
|
||||
const gd::BehaviorContent& behaviorContent) {
|
||||
const gd::String& behaviorName = behaviorContent.GetName();
|
||||
auto newBehaviorContent =
|
||||
gd::make_unique<gd::BehaviorContent>(behaviorContent);
|
||||
behaviors[behaviorName] = std::move(newBehaviorContent);
|
||||
return *behaviors[behaviorName];
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> Object::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
gd::BehaviorContent* Object::AddNewBehavior(const gd::Project& project,
|
||||
gd::Behavior* Object::AddNewBehavior(const gd::Project& project,
|
||||
const gd::String& type,
|
||||
const gd::String& name) {
|
||||
const gd::BehaviorMetadata& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
|
||||
type);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
return nullptr;
|
||||
auto initializeAndAdd =
|
||||
[this, &name](std::unique_ptr<gd::Behavior> behavior) {
|
||||
behavior->InitializeContent();
|
||||
this->behaviors[name] = std::move(behavior);
|
||||
return this->behaviors[name].get();
|
||||
};
|
||||
|
||||
if (project.HasEventsBasedBehavior(type)) {
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
}
|
||||
else {
|
||||
const gd::BehaviorMetadata& behaviorMetadata =
|
||||
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
|
||||
type);
|
||||
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
|
||||
gd::LogWarning("Tried to create a behavior with an unknown type: " + type
|
||||
+ " on object " + GetName() + "!");
|
||||
// It's probably an events-based object that was removed.
|
||||
// Create a custom behavior to preserve the properties values.
|
||||
return initializeAndAdd(
|
||||
gd::make_unique<CustomBehavior>(name, project, type));
|
||||
}
|
||||
std::unique_ptr<gd::Behavior> behavior(behaviorMetadata.Get().Clone());
|
||||
behavior->SetName(name);
|
||||
return initializeAndAdd(std::move(behavior));
|
||||
}
|
||||
|
||||
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
|
||||
behaviorMetadata.Get().InitializeContent(behaviorContent->GetContent());
|
||||
behaviors[name] = std::move(behaviorContent);
|
||||
return behaviors[name].get();
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
Object::GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
void Object::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
type = element.GetStringAttribute("type");
|
||||
SetType(element.GetStringAttribute("type"));
|
||||
assetStoreId = element.GetStringAttribute("assetStoreId");
|
||||
name = element.GetStringAttribute("name", name, "nom");
|
||||
tags = element.GetStringAttribute("tags");
|
||||
@@ -133,9 +150,8 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
.FindAndReplace("Automatism", "Behavior");
|
||||
gd::String name = behaviorElement.GetStringAttribute("name", "", "Name");
|
||||
|
||||
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
|
||||
behaviorContent->UnserializeFrom(behaviorElement);
|
||||
behaviors[name] = std::move(behaviorContent);
|
||||
auto behavior = gd::Object::AddNewBehavior(project, type, name);
|
||||
behavior->UnserializeFrom(behaviorElement);
|
||||
}
|
||||
}
|
||||
// End of compatibility code
|
||||
@@ -151,7 +167,7 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
"Automatism", "Behavior"); // Compatibility with GD <= 4
|
||||
gd::String name = behaviorElement.GetStringAttribute("name");
|
||||
|
||||
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
|
||||
auto behavior = gd::Object::AddNewBehavior(project, type, name);
|
||||
// Compatibility with GD <= 4.0.98
|
||||
// If there is only one child called "content" (in addition to "type" and
|
||||
// "name"), it's the content of a JavaScript behavior. Move the content
|
||||
@@ -169,17 +185,16 @@ void Object::UnserializeFrom(gd::Project& project,
|
||||
contentElement.RemoveChild("type");
|
||||
}
|
||||
|
||||
behaviorContent->UnserializeFrom(contentElement);
|
||||
behavior->UnserializeFrom(contentElement);
|
||||
}
|
||||
// end of compatibility code
|
||||
else {
|
||||
behaviorContent->UnserializeFrom(behaviorElement);
|
||||
behavior->UnserializeFrom(behaviorElement);
|
||||
}
|
||||
behaviors[name] = std::move(behaviorContent);
|
||||
}
|
||||
}
|
||||
|
||||
DoUnserializeFrom(project, element);
|
||||
configuration->UnserializeFrom(project, element);
|
||||
}
|
||||
|
||||
void Object::SerializeTo(SerializerElement& element) const {
|
||||
@@ -194,18 +209,18 @@ void Object::SerializeTo(SerializerElement& element) const {
|
||||
behaviorsElement.ConsiderAsArrayOf("behavior");
|
||||
std::vector<gd::String> allBehaviors = GetAllBehaviorNames();
|
||||
for (std::size_t i = 0; i < allBehaviors.size(); ++i) {
|
||||
const gd::BehaviorContent& behaviorContent = GetBehavior(allBehaviors[i]);
|
||||
const gd::Behavior& behavior = GetBehavior(allBehaviors[i]);
|
||||
SerializerElement& behaviorElement = behaviorsElement.AddChild("behavior");
|
||||
|
||||
behaviorContent.SerializeTo(behaviorElement);
|
||||
behavior.SerializeTo(behaviorElement);
|
||||
behaviorElement.RemoveChild("type"); // The content can contain type or
|
||||
// name properties, remove them.
|
||||
behaviorElement.RemoveChild("name");
|
||||
behaviorElement.SetAttribute("type", behaviorContent.GetTypeName());
|
||||
behaviorElement.SetAttribute("name", behaviorContent.GetName());
|
||||
behaviorElement.SetAttribute("type", behavior.GetTypeName());
|
||||
behaviorElement.SetAttribute("name", behavior.GetName());
|
||||
}
|
||||
|
||||
DoSerializeTo(element);
|
||||
configuration->SerializeTo(element);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -10,11 +10,13 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/BehaviorContent.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
@@ -28,7 +30,7 @@ class EffectsContainer;
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class used to represent an object of a platform
|
||||
* \brief Represent an object of a platform
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
@@ -36,9 +38,19 @@ class GD_CORE_API Object {
|
||||
public:
|
||||
/**
|
||||
* Create a new object with the name passed as argument.
|
||||
* \param name Object's name
|
||||
*/
|
||||
Object(const gd::String& name);
|
||||
Object(const gd::String& name,
|
||||
const gd::String& type,
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration);
|
||||
|
||||
/**
|
||||
* Create a new object with the name passed as argument.
|
||||
*
|
||||
* Object takes the ownership of the configuration.
|
||||
*/
|
||||
Object(const gd::String& name,
|
||||
const gd::String& type,
|
||||
gd::ObjectConfiguration* configuration);
|
||||
|
||||
/**
|
||||
* Copy constructor. Calls Init().
|
||||
@@ -70,6 +82,13 @@ class GD_CORE_API Object {
|
||||
return gd::make_unique<gd::Object>(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the object configuration.
|
||||
*/
|
||||
gd::ObjectConfiguration& GetConfiguration();
|
||||
|
||||
const gd::ObjectConfiguration& GetConfiguration() const;
|
||||
|
||||
/** \name Common properties
|
||||
* Members functions related to common properties
|
||||
*/
|
||||
@@ -93,11 +112,15 @@ class GD_CORE_API Object {
|
||||
|
||||
/** \brief Change the type of the object.
|
||||
*/
|
||||
void SetType(const gd::String& type_) { type = type_; }
|
||||
void SetType(const gd::String& type_) {
|
||||
configuration->SetType(type_);
|
||||
}
|
||||
|
||||
/** \brief Return the type of the object.
|
||||
*/
|
||||
const gd::String& GetType() const { return type; }
|
||||
const gd::String& GetType() const {
|
||||
return configuration->GetType();
|
||||
}
|
||||
|
||||
/** \brief Change the tags of the object.
|
||||
*/
|
||||
@@ -108,92 +131,6 @@ class GD_CORE_API Object {
|
||||
const gd::String& GetTags() const { return tags; }
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
* Members functions related to managing resources used by the object
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources and sometimes update their filename. Implementation example:
|
||||
* \code
|
||||
* worker.ExposeImage(myImage);
|
||||
* worker.ExposeFile(myResourceFile);
|
||||
* \endcode
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
virtual void ExposeResources(gd::ArbitraryResourceWorker& worker) { return; };
|
||||
|
||||
/**
|
||||
* Redefine this function to return true if your object can use shaders.
|
||||
*/
|
||||
virtual bool SupportShaders() { return false; }
|
||||
///@}
|
||||
|
||||
/** \name Object properties
|
||||
* Reading and updating object properties
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
object.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Text"))].SetValue("Hello world!");
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the object
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Drawing and editing initial instances
|
||||
* Members functions related to drawing and editing initial instances of this
|
||||
* object
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of an
|
||||
* initial instance of this object.
|
||||
*
|
||||
* \return a std::map with properties names as key and values.
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of an initial
|
||||
* instance of this object.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Behaviors management
|
||||
* Members functions related to behaviors management.
|
||||
*/
|
||||
@@ -208,12 +145,12 @@ class GD_CORE_API Object {
|
||||
/**
|
||||
* \brief Return a reference to the content of the behavior called \a name.
|
||||
*/
|
||||
BehaviorContent& GetBehavior(const gd::String& name);
|
||||
Behavior& GetBehavior(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the content of the behavior called \a name.
|
||||
*/
|
||||
const BehaviorContent& GetBehavior(const gd::String& name) const;
|
||||
const Behavior& GetBehavior(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return true if object has a behavior called \a name.
|
||||
@@ -231,13 +168,6 @@ class GD_CORE_API Object {
|
||||
*/
|
||||
bool RenameBehavior(const gd::String& name, const gd::String& newName);
|
||||
|
||||
/**
|
||||
* \brief Add the specified behavior content to the object
|
||||
*
|
||||
* \return A reference to the newly added behavior content.
|
||||
*/
|
||||
gd::BehaviorContent& AddBehavior(const gd::BehaviorContent& behavior);
|
||||
|
||||
/**
|
||||
* \brief Add the behavior of the specified \a type with the specified \a
|
||||
* name.
|
||||
@@ -247,15 +177,15 @@ class GD_CORE_API Object {
|
||||
* \return A pointer to the newly added behavior content. NULL if the creation
|
||||
* failed.
|
||||
*/
|
||||
gd::BehaviorContent* AddNewBehavior(const gd::Project& project,
|
||||
const gd::String& type,
|
||||
const gd::String& name);
|
||||
gd::Behavior* AddNewBehavior(const gd::Project& project,
|
||||
const gd::String& type,
|
||||
const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Get a read-only access to the map containing the behaviors with
|
||||
* their properties.
|
||||
*/
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorContent>>&
|
||||
const std::map<gd::String, std::unique_ptr<gd::Behavior>>&
|
||||
GetAllBehaviorContents() const {
|
||||
return behaviors;
|
||||
};
|
||||
@@ -316,9 +246,8 @@ class GD_CORE_API Object {
|
||||
protected:
|
||||
gd::String name; ///< The full name of the object
|
||||
gd::String assetStoreId; ///< The ID of the asset if the object comes from the store.
|
||||
gd::String type; ///< Which type is the object. ( To test if we can do
|
||||
///< something reserved to some objects with it )
|
||||
std::map<gd::String, std::unique_ptr<gd::BehaviorContent>>
|
||||
std::unique_ptr<gd::ObjectConfiguration> configuration;
|
||||
std::map<gd::String, std::unique_ptr<gd::Behavior>>
|
||||
behaviors; ///< Contains all behaviors and their properties for the
|
||||
///< object. Behavior contents are the ownership of the
|
||||
///< object.
|
||||
@@ -328,20 +257,12 @@ class GD_CORE_API Object {
|
||||
gd::EffectsContainer
|
||||
effectsContainer; ///< The effects container for the object.
|
||||
|
||||
/**
|
||||
* \brief Derived objects can redefine this method to load custom attributes.
|
||||
*/
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
/**
|
||||
* \brief Derived objects can redefine this method to save custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
|
||||
/**
|
||||
* Initialize object using another object. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed!
|
||||
*
|
||||
* It's needed because there is no default copy for a map of unique_ptr like
|
||||
* behaviors and it must be a deep copy.
|
||||
*/
|
||||
void Init(const gd::Object& object);
|
||||
};
|
||||
|
47
Core/GDCore/Project/ObjectConfiguration.cpp
Normal file
47
Core/GDCore/Project/ObjectConfiguration.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/CustomBehavior.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
ObjectConfiguration::ObjectConfiguration() {}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> ObjectConfiguration::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
ObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
void ObjectConfiguration::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
DoUnserializeFrom(project, element);
|
||||
}
|
||||
|
||||
void ObjectConfiguration::SerializeTo(SerializerElement& element) const {
|
||||
DoSerializeTo(element);
|
||||
}
|
||||
|
||||
} // namespace gd
|
194
Core/GDCore/Project/ObjectConfiguration.h
Normal file
194
Core/GDCore/Project/ObjectConfiguration.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_OBJECTCONFIGURATION_H
|
||||
#define GDCORE_OBJECTCONFIGURATION_H
|
||||
#include "GDCore/Vector2.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ArbitraryResourceWorker;
|
||||
class InitialInstance;
|
||||
class SerializerElement;
|
||||
class EffectsContainer;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Base class used to represent an object configuration.
|
||||
* For example, this can be the animations in a sprite, the text, its font,
|
||||
* its color in a Text object, etc...
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API ObjectConfiguration {
|
||||
public:
|
||||
/**
|
||||
* Create a new object configuration.
|
||||
*/
|
||||
ObjectConfiguration();
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~ObjectConfiguration();
|
||||
|
||||
/**
|
||||
* Must return a pointer to a copy of the configuration. This method is
|
||||
* needed to do polymorphic copies. Just redefine this method in your derived
|
||||
* object class like this:
|
||||
* \code
|
||||
* return gd::make_unique<MyObjectConfiguration>(*this);
|
||||
* \endcode
|
||||
*/
|
||||
virtual std::unique_ptr<gd::ObjectConfiguration> Clone() const {
|
||||
return gd::make_unique<gd::ObjectConfiguration>(*this);
|
||||
}
|
||||
|
||||
/** \brief Change the type of the object.
|
||||
*/
|
||||
void SetType(const gd::String& type_) { type = type_; }
|
||||
|
||||
/** \brief Return the type of the object.
|
||||
*/
|
||||
const gd::String& GetType() const { return type; }
|
||||
|
||||
/** \name Object properties
|
||||
* Reading and updating object configuration properties
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of the
|
||||
object configuration.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[ToString(_("Text"))].SetValue("Hello world!");
|
||||
|
||||
return properties;
|
||||
\endcode
|
||||
*
|
||||
* \return a std::map with properties names as key.
|
||||
* \see gd::PropertyDescriptor
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of the object
|
||||
* configuration.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
*/
|
||||
virtual bool UpdateProperty(const gd::String& name, const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Drawing and editing initial instances
|
||||
* Members functions related to drawing and editing initial instances of this
|
||||
* object configuration
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Called when the IDE wants to know about the custom properties of an
|
||||
* initial instance of this object configuration.
|
||||
*
|
||||
* \return a std::map with properties names as key and values.
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of an initial
|
||||
* instance of this object configuration.
|
||||
*
|
||||
* \return false if the new value cannot be set
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
* Members functions related to managing resources used by the object configuration
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Called ( e.g. during compilation ) so as to inventory internal
|
||||
* resources and sometimes update their filename. Implementation example:
|
||||
* \code
|
||||
* worker.ExposeImage(myImage);
|
||||
* worker.ExposeFile(myResourceFile);
|
||||
* \endcode
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
virtual void ExposeResources(gd::ArbitraryResourceWorker& worker) { return; };
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
* Members functions related to serialization of the object configuration
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the object configuration.
|
||||
* \see DoSerializeTo
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the object configuration.
|
||||
* \see DoUnserializeFrom
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
|
||||
/**
|
||||
* \brief Derived object configuration can redefine this method to load
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoUnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
/**
|
||||
* \brief Derived object configuration can redefine this method to save
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
/**
|
||||
* Object configurations are usually managed thanks to (smart) pointers.
|
||||
*/
|
||||
using ObjConfSPtr = std::unique_ptr<gd::ObjectConfiguration>;
|
||||
|
||||
#endif // GDCORE_OBJECT_H
|
@@ -83,7 +83,7 @@ gd::Object& ObjectsContainer::InsertNewObject(const gd::Project& project,
|
||||
gd::Object& newlyCreatedObject = *(*(initialObjects.insert(
|
||||
position < initialObjects.size() ? initialObjects.begin() + position
|
||||
: initialObjects.end(),
|
||||
project.GetCurrentPlatform().CreateObject(objectType, name))));
|
||||
project.CreateObject(objectType, name))));
|
||||
|
||||
return newlyCreatedObject;
|
||||
}
|
||||
|
@@ -23,10 +23,12 @@
|
||||
#include "GDCore/IDE/PlatformManager.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/CustomObjectConfiguration.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/SourceFile.h"
|
||||
@@ -79,22 +81,84 @@ Project::~Project() {}
|
||||
void Project::ResetProjectUuid() { projectUuid = UUID::MakeUuid4(); }
|
||||
|
||||
std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
const gd::String& type,
|
||||
const gd::String& name,
|
||||
const gd::String& platformName) {
|
||||
for (std::size_t i = 0; i < platforms.size(); ++i) {
|
||||
if (!platformName.empty() && platforms[i]->GetName() != platformName)
|
||||
continue;
|
||||
const gd::String& type,
|
||||
const gd::String& name) const {
|
||||
return gd::make_unique<Object>(name, type, CreateObjectConfiguration(type));
|
||||
}
|
||||
|
||||
std::unique_ptr<gd::Object> object = platforms[i]->CreateObject(
|
||||
type, name); // Create a base object if the type can't be found in the
|
||||
// platform
|
||||
if (object && object->GetType() == type)
|
||||
return object; // If the object is valid and has the good type (not a
|
||||
// base object), return it
|
||||
std::unique_ptr<gd::ObjectConfiguration> Project::CreateObjectConfiguration(
|
||||
const gd::String& type) const {
|
||||
if (Project::HasEventsBasedObject(type)) {
|
||||
return gd::make_unique<CustomObjectConfiguration>(*this, type);
|
||||
}
|
||||
else {
|
||||
// Create a base object if the type can't be found in the platform.
|
||||
return currentPlatform->CreateObjectConfiguration(type);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
bool Project::HasEventsBasedObject(const gd::String& type) const {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
if (separatorIndex == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
if (!Project::HasEventsFunctionsExtensionNamed(extensionName)) {
|
||||
return false;
|
||||
}
|
||||
auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
gd::String objectTypeName = type.substr(separatorIndex + 2);
|
||||
return extension.GetEventsBasedObjects().Has(objectTypeName);
|
||||
}
|
||||
|
||||
gd::EventsBasedObject& Project::GetEventsBasedObject(const gd::String& type) {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
gd::String objectTypeName = type.substr(separatorIndex + 2);
|
||||
|
||||
auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
return extension.GetEventsBasedObjects().Get(objectTypeName);
|
||||
}
|
||||
|
||||
const gd::EventsBasedObject& Project::GetEventsBasedObject(const gd::String& type) const {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
gd::String objectTypeName = type.substr(separatorIndex + 2);
|
||||
|
||||
const auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
return extension.GetEventsBasedObjects().Get(objectTypeName);
|
||||
}
|
||||
|
||||
bool Project::HasEventsBasedBehavior(const gd::String& type) const {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
if (separatorIndex == std::string::npos) {
|
||||
return false;
|
||||
}
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
if (!Project::HasEventsFunctionsExtensionNamed(extensionName)) {
|
||||
return false;
|
||||
}
|
||||
auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
gd::String behaviorTypeName = type.substr(separatorIndex + 2);
|
||||
return extension.GetEventsBasedBehaviors().Has(behaviorTypeName);
|
||||
}
|
||||
|
||||
gd::EventsBasedBehavior& Project::GetEventsBasedBehavior(const gd::String& type) {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
gd::String behaviorTypeName = type.substr(separatorIndex + 2);
|
||||
|
||||
auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
return extension.GetEventsBasedBehaviors().Get(behaviorTypeName);
|
||||
}
|
||||
|
||||
const gd::EventsBasedBehavior& Project::GetEventsBasedBehavior(const gd::String& type) const {
|
||||
const auto separatorIndex = type.find(PlatformExtension::GetNamespaceSeparator());
|
||||
gd::String extensionName = type.substr(0, separatorIndex);
|
||||
gd::String behaviorTypeName = type.substr(separatorIndex + 2);
|
||||
|
||||
auto &extension = Project::GetEventsFunctionsExtension(extensionName);
|
||||
return extension.GetEventsBasedBehaviors().Get(behaviorTypeName);
|
||||
}
|
||||
|
||||
std::shared_ptr<gd::BaseEvent> Project::CreateEvent(
|
||||
@@ -642,6 +706,38 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
if (currentPlatform == NULL && !platforms.empty())
|
||||
currentPlatform = platforms.back();
|
||||
|
||||
eventsFunctionsExtensions.clear();
|
||||
const SerializerElement& eventsFunctionsExtensionsElement =
|
||||
element.GetChild("eventsFunctionsExtensions");
|
||||
eventsFunctionsExtensionsElement.ConsiderAsArrayOf(
|
||||
"eventsFunctionsExtension");
|
||||
// First, only unserialize behaviors and objects names.
|
||||
// As event based objects can contains CustomObject and Custom Object,
|
||||
// this allows them to reference EventBasedBehavior and EventBasedObject
|
||||
// respectively.
|
||||
for (std::size_t i = 0;
|
||||
i < eventsFunctionsExtensionsElement.GetChildrenCount();
|
||||
++i) {
|
||||
const SerializerElement& eventsFunctionsExtensionElement =
|
||||
eventsFunctionsExtensionsElement.GetChild(i);
|
||||
|
||||
gd::EventsFunctionsExtension& newEventsFunctionsExtension =
|
||||
InsertNewEventsFunctionsExtension("",
|
||||
GetEventsFunctionsExtensionsCount());
|
||||
newEventsFunctionsExtension.UnserializeExtensionDeclarationFrom(
|
||||
*this, eventsFunctionsExtensionElement);
|
||||
}
|
||||
// Then unserialize functions, behaviors and objects content.
|
||||
for (std::size_t i = 0;
|
||||
i < eventsFunctionsExtensionsElement.GetChildrenCount();
|
||||
++i) {
|
||||
const SerializerElement& eventsFunctionsExtensionElement =
|
||||
eventsFunctionsExtensionsElement.GetChild(i);
|
||||
|
||||
eventsFunctionsExtensions.at(i)->UnserializeExtensionImplementationFrom(
|
||||
*this, eventsFunctionsExtensionElement);
|
||||
}
|
||||
|
||||
GetObjectGroups().UnserializeFrom(
|
||||
element.GetChild("objectsGroups", 0, "ObjectGroups"));
|
||||
resourcesManager.UnserializeFrom(
|
||||
@@ -676,24 +772,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
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);
|
||||
}
|
||||
|
||||
externalLayouts.clear();
|
||||
const SerializerElement& externalLayoutsElement =
|
||||
element.GetChild("externalLayouts", 0, "ExternalLayouts");
|
||||
@@ -868,8 +946,9 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
// Add layouts resources
|
||||
for (std::size_t s = 0; s < GetLayoutsCount(); s++) {
|
||||
for (std::size_t j = 0; j < GetLayout(s).GetObjectsCount();
|
||||
++j) // Add objects resources
|
||||
GetLayout(s).GetObject(j).ExposeResources(worker);
|
||||
++j) { // Add objects resources
|
||||
GetLayout(s).GetObject(j).GetConfiguration().ExposeResources(worker);
|
||||
}
|
||||
|
||||
LaunchResourceWorkerOnEvents(*this, GetLayout(s).GetEvents(), worker);
|
||||
}
|
||||
@@ -888,7 +967,7 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
|
||||
// Add global objects resources
|
||||
for (std::size_t j = 0; j < GetObjectsCount(); ++j) {
|
||||
GetObject(j).ExposeResources(worker);
|
||||
GetObject(j).GetConfiguration().ExposeResources(worker);
|
||||
}
|
||||
|
||||
// Add loading screen background image if present
|
||||
|
@@ -24,7 +24,10 @@ class ExternalEvents;
|
||||
class ResourcesManager;
|
||||
class ExternalLayout;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsBasedObject;
|
||||
class EventsBasedBehavior;
|
||||
class Object;
|
||||
class ObjectConfiguration;
|
||||
class VariablesContainer;
|
||||
class ArbitraryResourceWorker;
|
||||
class SourceFile;
|
||||
@@ -455,20 +458,20 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
/**
|
||||
* Create an object of the given type with the specified name.
|
||||
*
|
||||
* \note A project can use more than one platform. In this case, the first
|
||||
* platform supporting the object is used, unless \a platformName argument is
|
||||
* not empty.<br> It is assumed that each platform provides an equivalent
|
||||
* object.
|
||||
*
|
||||
*
|
||||
* \param type The type of the object
|
||||
* \param name The name of the object
|
||||
* \param platformName The name of the platform to be used. If empty, the
|
||||
* first platform supporting the object is used.
|
||||
*/
|
||||
std::unique_ptr<gd::Object> CreateObject(const gd::String& type,
|
||||
const gd::String& name,
|
||||
const gd::String& platformName = "");
|
||||
const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Create an object configuration of the given type.
|
||||
*
|
||||
* \param type The type of the object
|
||||
*/
|
||||
std::unique_ptr<gd::ObjectConfiguration> CreateObjectConfiguration(
|
||||
const gd::String& type) const;
|
||||
|
||||
/**
|
||||
* Create an event of the given type.
|
||||
@@ -827,6 +830,37 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* \brief Remove all the events functions extensions.
|
||||
*/
|
||||
void ClearEventsFunctionsExtensions();
|
||||
|
||||
/**
|
||||
* \brief Check if events based object with a given type exists.
|
||||
*/
|
||||
bool HasEventsBasedObject(const gd::String& type) const;
|
||||
|
||||
/**
|
||||
* \brief Return the events based object with a given type.
|
||||
*/
|
||||
gd::EventsBasedObject& GetEventsBasedObject(const gd::String& type);
|
||||
|
||||
/**
|
||||
* \brief Return the events based object with a given type.
|
||||
*/
|
||||
const gd::EventsBasedObject& GetEventsBasedObject(const gd::String& type) const;
|
||||
|
||||
/**
|
||||
* \brief Check if events based behavior with a given type exists.
|
||||
*/
|
||||
bool HasEventsBasedBehavior(const gd::String& type) const;
|
||||
|
||||
/**
|
||||
* \brief Return the events based behavior with a given type.
|
||||
*/
|
||||
gd::EventsBasedBehavior& GetEventsBasedBehavior(const gd::String& type);
|
||||
|
||||
/**
|
||||
* \brief Return the events based behavior with a given type.
|
||||
*/
|
||||
const gd::EventsBasedBehavior& GetEventsBasedBehavior(const gd::String& type) const;
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
|
@@ -184,11 +184,17 @@ std::map<gd::String, gd::PropertyDescriptor> AudioResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Preload as sound")]
|
||||
.SetDescription(_("Loads the fully decoded file into cache, so it can be played right away as Sound with no further delays."))
|
||||
.SetValue(preloadAsSound ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
properties[_("Preload as music")]
|
||||
.SetDescription(_("Prepares the file for immediate streaming as Music (does not wait for complete download)."))
|
||||
.SetValue(preloadAsMusic ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
properties[_("Preload in cache")]
|
||||
.SetDescription(_("Loads the complete file into cache, but does not decode it into memory until requested."))
|
||||
.SetValue(preloadInCache ? "true" : "false")
|
||||
.SetType("Boolean");
|
||||
|
||||
return properties;
|
||||
}
|
||||
@@ -199,6 +205,8 @@ bool AudioResource::UpdateProperty(const gd::String& name,
|
||||
preloadAsSound = value == "1";
|
||||
else if (name == _("Preload as music"))
|
||||
preloadAsMusic = value == "1";
|
||||
else if (name == _("Preload in cache"))
|
||||
preloadInCache = value == "1";
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -569,6 +577,7 @@ void AudioResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
SetPreloadAsMusic(element.GetBoolAttribute("preloadAsMusic"));
|
||||
SetPreloadAsSound(element.GetBoolAttribute("preloadAsSound"));
|
||||
SetPreloadInCache(element.GetBoolAttribute("preloadInCache"));
|
||||
}
|
||||
|
||||
void AudioResource::SerializeTo(SerializerElement& element) const {
|
||||
@@ -576,6 +585,7 @@ void AudioResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("file", GetFile());
|
||||
element.SetAttribute("preloadAsMusic", PreloadAsMusic());
|
||||
element.SetAttribute("preloadAsSound", PreloadAsSound());
|
||||
element.SetAttribute("preloadInCache", PreloadInCache());
|
||||
}
|
||||
|
||||
void FontResource::SetFile(const gd::String& newFile) {
|
||||
|
@@ -223,7 +223,7 @@ class GD_CORE_API ImageResource : public Resource {
|
||||
*/
|
||||
class GD_CORE_API AudioResource : public Resource {
|
||||
public:
|
||||
AudioResource() : Resource(), preloadAsMusic(false), preloadAsSound(false) {
|
||||
AudioResource() : Resource(), preloadAsMusic(false), preloadAsSound(false), preloadInCache(false) {
|
||||
SetKind("audio");
|
||||
};
|
||||
virtual ~AudioResource(){};
|
||||
@@ -263,10 +263,21 @@ class GD_CORE_API AudioResource : public Resource {
|
||||
*/
|
||||
void SetPreloadAsSound(bool enable = true) { preloadAsSound = enable; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the audio resource should be preloaded in cache (without decoding into memory).
|
||||
*/
|
||||
bool PreloadInCache() const { return preloadInCache; }
|
||||
|
||||
/**
|
||||
* \brief Set if the audio resource should be preloaded in cache (without decoding into memory).
|
||||
*/
|
||||
void SetPreloadInCache(bool enable = true) { preloadInCache = enable; }
|
||||
|
||||
private:
|
||||
gd::String file;
|
||||
bool preloadAsSound;
|
||||
bool preloadAsMusic;
|
||||
bool preloadInCache;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -22,7 +22,7 @@ namespace gd {
|
||||
* properties).
|
||||
*
|
||||
* It is used for serialization (to JSON or XML), or as a generic
|
||||
* container for properties of objects (see for example gd::BehaviorContent).
|
||||
* container for properties of objects (see for example gd::Behavior).
|
||||
*
|
||||
* It also has specialized methods in GDevelop.js (see postjs.js) to be
|
||||
* converted to a JavaScript object.
|
||||
|
@@ -13,12 +13,14 @@
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
class ArbitraryResourceWorkerTest : public gd::ArbitraryResourceWorker {
|
||||
@@ -63,14 +65,15 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
|
||||
"path/to/file4.png") != worker.files.end());
|
||||
|
||||
SECTION("Object using a resource") {
|
||||
gd::SpriteObject obj("myObject");
|
||||
|
||||
gd::SpriteObject spriteConfiguration;
|
||||
gd::Animation anim;
|
||||
gd::Sprite sprite;
|
||||
sprite.SetImageName("res1");
|
||||
anim.SetDirectionsCount(1);
|
||||
anim.GetDirection(0).AddSprite(sprite);
|
||||
obj.AddAnimation(anim);
|
||||
spriteConfiguration.AddAnimation(anim);
|
||||
|
||||
gd::Object obj("myObject", "", spriteConfiguration.Clone());
|
||||
project.InsertObject(obj, 0);
|
||||
|
||||
worker.files.clear();
|
||||
|
209
Core/tests/BehaviorSerialization.cpp
Normal file
209
Core/tests/BehaviorSerialization.cpp
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering serialization to JSON.
|
||||
*/
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace {
|
||||
|
||||
void AddEventsBasedExtension(gd::Project &project) {
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
|
||||
auto &eventsBasedBehavior =
|
||||
eventsExtension.GetEventsBasedBehaviors().InsertNew(
|
||||
"MyEventsBasedBehavior", 0);
|
||||
eventsBasedBehavior.SetFullName("My events based behavior");
|
||||
eventsBasedBehavior.SetDescription("An events based behavior for test");
|
||||
eventsBasedBehavior.SetObjectType("");
|
||||
eventsBasedBehavior.GetPropertyDescriptors()
|
||||
.InsertNew("MyProperty", 0)
|
||||
.SetType("Number");
|
||||
};
|
||||
|
||||
void AddAnotherEventsBasedExtensionWithDependency(gd::Project &project) {
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyOtherEventsExtension", 0);
|
||||
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
eventsBasedObject.SetFullName("My events based object");
|
||||
eventsBasedObject.SetDescription("An events based object for test");
|
||||
|
||||
gd::Object &object = eventsBasedObject.InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
gd::Behavior *behavior =
|
||||
object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior",
|
||||
"MyEventsBasedBehavior");
|
||||
behavior->UpdateProperty("MyProperty", "481516");
|
||||
};
|
||||
|
||||
void SetupProject(gd::Project &project, gd::Platform &platform) {
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
AddEventsBasedExtension(project);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object =
|
||||
layout.InsertNewObject(project, "MyExtension::Sprite", "MyObject", 0);
|
||||
gd::Behavior *behavior =
|
||||
object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior",
|
||||
"MyEventsBasedBehavior");
|
||||
behavior->UpdateProperty("MyProperty", "481516");
|
||||
};
|
||||
|
||||
void CheckBehaviorPropertyInObjectContainerElement(
|
||||
SerializerElement &objectContainerElement) {
|
||||
REQUIRE(objectContainerElement.HasChild("objects"));
|
||||
|
||||
auto &objectsElement = objectContainerElement.GetChild("objects");
|
||||
objectsElement.ConsiderAsArrayOf("object");
|
||||
REQUIRE(objectsElement.GetChildrenCount() == 1);
|
||||
auto &objectElement = objectsElement.GetChild(0);
|
||||
|
||||
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
|
||||
REQUIRE(objectElement.GetStringAttribute("type") == "MyExtension::Sprite");
|
||||
REQUIRE(objectElement.HasChild("behaviors"));
|
||||
|
||||
auto &behaviorsElement = objectElement.GetChild("behaviors");
|
||||
behaviorsElement.ConsiderAsArrayOf("behavior");
|
||||
REQUIRE(behaviorsElement.GetChildrenCount() == 1);
|
||||
auto &behaviorElement = behaviorsElement.GetChild(0);
|
||||
|
||||
REQUIRE(behaviorElement.GetStringAttribute("name") ==
|
||||
"MyEventsBasedBehavior");
|
||||
REQUIRE(behaviorElement.GetStringAttribute("type") ==
|
||||
"MyEventsExtension::MyEventsBasedBehavior");
|
||||
REQUIRE(behaviorElement.GetStringAttribute("MyProperty") == "481516");
|
||||
};
|
||||
|
||||
void CheckBehaviorPropertyInElement(SerializerElement &projectElement) {
|
||||
auto &layoutsElement = projectElement.GetChild("layouts");
|
||||
layoutsElement.ConsiderAsArrayOf("layout");
|
||||
REQUIRE(layoutsElement.GetChildrenCount() == 1);
|
||||
auto &layoutElement = layoutsElement.GetChild(0);
|
||||
|
||||
REQUIRE(layoutElement.GetStringAttribute("name") == "Scene");
|
||||
CheckBehaviorPropertyInObjectContainerElement(layoutElement);
|
||||
};
|
||||
|
||||
void CheckBehaviorProperty(ObjectsContainer &container) {
|
||||
auto &object = container.GetObject("MyObject");
|
||||
REQUIRE(object.GetType() == "MyExtension::Sprite");
|
||||
REQUIRE(object.HasBehaviorNamed("MyEventsBasedBehavior"));
|
||||
|
||||
auto &behavior = object.GetBehavior("MyEventsBasedBehavior");
|
||||
REQUIRE(behavior.GetTypeName() == "MyEventsExtension::MyEventsBasedBehavior");
|
||||
REQUIRE(behavior.GetProperties().size() == 1);
|
||||
REQUIRE(behavior.GetProperties().at("MyProperty").GetValue() == "481516");
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// TODO EBO Add similar test cases for events-based objects.
|
||||
TEST_CASE("BehaviorSerialization", "[common]") {
|
||||
|
||||
SECTION("Save and load a project with a custom behavior property value") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
CheckBehaviorProperty(writtenProject.GetLayout("Scene"));
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
||||
CheckBehaviorPropertyInElement(projectElement);
|
||||
|
||||
gd::Project readProject;
|
||||
readProject.AddPlatform(platform);
|
||||
readProject.UnserializeFrom(projectElement);
|
||||
CheckBehaviorProperty(readProject.GetLayout("Scene"));
|
||||
}
|
||||
|
||||
SECTION("Load a project with a property value on a custom behavior that no longer exists") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
|
||||
// Remove the events-based behavior
|
||||
writtenProject.RemoveEventsFunctionsExtension("MyEventsExtension");
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
||||
CheckBehaviorPropertyInElement(projectElement);
|
||||
|
||||
gd::Project readProject;
|
||||
readProject.AddPlatform(platform);
|
||||
readProject.UnserializeFrom(projectElement);
|
||||
|
||||
// Add the events-based behavior back
|
||||
AddEventsBasedExtension(readProject);
|
||||
|
||||
CheckBehaviorProperty(readProject.GetLayout("Scene"));
|
||||
}
|
||||
|
||||
SECTION("Save and load a project with an event based extension dependency") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
AddAnotherEventsBasedExtensionWithDependency(writtenProject);
|
||||
|
||||
// It's important that the extension with the dependency is the first one.
|
||||
REQUIRE(writtenProject.GetEventsFunctionsExtension(0).GetName() ==
|
||||
"MyOtherEventsExtension");
|
||||
REQUIRE(writtenProject.GetEventsFunctionsExtension(1).GetName() ==
|
||||
"MyEventsExtension");
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
||||
|
||||
auto &extensionsElement =
|
||||
projectElement.GetChild("eventsFunctionsExtensions");
|
||||
extensionsElement.ConsiderAsArrayOf("eventsFunctionsExtension");
|
||||
REQUIRE(extensionsElement.GetChildrenCount() == 2);
|
||||
|
||||
auto &firstExtensionElement = extensionsElement.GetChild(0);
|
||||
REQUIRE(firstExtensionElement.GetStringAttribute("name") ==
|
||||
"MyOtherEventsExtension");
|
||||
auto &eventsBasedObjectsElement =
|
||||
firstExtensionElement.GetChild("eventsBasedObjects");
|
||||
eventsBasedObjectsElement.ConsiderAsArrayOf("eventsBasedObject");
|
||||
auto &eventsBasedObjectElement =
|
||||
eventsBasedObjectsElement.GetChild(0);
|
||||
CheckBehaviorPropertyInObjectContainerElement(eventsBasedObjectElement);
|
||||
|
||||
auto &secondExtensionElement = extensionsElement.GetChild(1);
|
||||
REQUIRE(secondExtensionElement.GetStringAttribute("name") ==
|
||||
"MyEventsExtension");
|
||||
|
||||
gd::Project readProject;
|
||||
readProject.AddPlatform(platform);
|
||||
readProject.UnserializeFrom(projectElement);
|
||||
|
||||
// The custom behavior is unserialized even though it depends on the other
|
||||
// extension.
|
||||
REQUIRE(readProject.HasEventsBasedObject(
|
||||
"MyOtherEventsExtension::MyEventsBasedObject"));
|
||||
CheckBehaviorProperty(readProject.GetEventsBasedObject(
|
||||
"MyOtherEventsExtension::MyEventsBasedObject"));
|
||||
}
|
||||
}
|
@@ -19,6 +19,8 @@
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
// TODO: Add some tests on layouts and behavior shared data.
|
||||
|
||||
TEST_CASE("Project", "[common]") {
|
||||
SECTION("Basics") {
|
||||
gd::Project project;
|
||||
|
@@ -7,14 +7,19 @@
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/ObjectConfiguration.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
// TODO Remove these 2 classes and write the test with events based behaviors.
|
||||
class BehaviorWithRequiredBehaviorProperty : public gd::Behavior {
|
||||
public:
|
||||
BehaviorWithRequiredBehaviorProperty(){};
|
||||
BehaviorWithRequiredBehaviorProperty(
|
||||
const gd::String& name, const gd::String& type)
|
||||
: Behavior(name, type) {};
|
||||
virtual ~BehaviorWithRequiredBehaviorProperty(){};
|
||||
virtual Behavior* Clone() const override {
|
||||
return new BehaviorWithRequiredBehaviorProperty(*this);
|
||||
@@ -49,7 +54,9 @@ class BehaviorWithRequiredBehaviorProperty : public gd::Behavior {
|
||||
class BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior
|
||||
: public gd::Behavior {
|
||||
public:
|
||||
BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior(){};
|
||||
BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior(
|
||||
const gd::String& name, const gd::String& type)
|
||||
: Behavior(name, type) {};
|
||||
virtual ~BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior(){};
|
||||
virtual Behavior* Clone() const override {
|
||||
return new BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior(
|
||||
@@ -93,7 +100,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
// Create the base object. All objects "inherits" from it.
|
||||
baseObjectExtension->SetExtensionInformation(
|
||||
"BuiltinObject", "Base Object dummy extension", "", "", "");
|
||||
auto& baseObject = baseObjectExtension->AddObject<gd::Object>(
|
||||
auto& baseObject = baseObjectExtension->AddObject<gd::ObjectConfiguration>(
|
||||
"", "Dummy Base Object", "Dummy Base Object", "");
|
||||
|
||||
// Add this expression for all objects. But it requires a "capability".
|
||||
@@ -125,6 +132,18 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
.AddParameter("expression", "Parameter 1 (a number)")
|
||||
.SetFunctionName("doSomething");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomethingWithObjects",
|
||||
"Do something",
|
||||
"This does something",
|
||||
"Do something please",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
.AddParameter("object", _("Object 1 parameter"))
|
||||
.AddParameter("object", _("Object 2 parameter"))
|
||||
.SetFunctionName("doSomethingWithObjects");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomethingWithResources",
|
||||
"Do something with resources",
|
||||
@@ -209,7 +228,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
.AddParameter("objectvar", _("Variable for object 2"))
|
||||
.SetFunctionName("getStringWith1ObjectParamAnd2ObjectVarParam");
|
||||
|
||||
auto& object = extension->AddObject<gd::Object>(
|
||||
auto& object = extension->AddObject<gd::SpriteObject>(
|
||||
"Sprite", "Dummy Sprite", "Dummy sprite object", "");
|
||||
object
|
||||
.AddExpression("GetObjectVariableAsNumber",
|
||||
@@ -260,10 +279,11 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"Dummy behavior",
|
||||
"MyBehavior",
|
||||
"A dummy behavior for tests",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
gd::make_unique<gd::Behavior>(),
|
||||
"Group",
|
||||
"Icon.png",
|
||||
"MyBehavior",
|
||||
gd::make_unique<gd::Behavior>(
|
||||
"Behavior", "MyExtension::MyBehavior"),
|
||||
gd::make_unique<gd::BehaviorsSharedData>());
|
||||
behavior
|
||||
.AddAction("BehaviorDoSomething",
|
||||
@@ -304,10 +324,11 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"Another Dummy behavior",
|
||||
"MyOtherBehavior",
|
||||
"Another dummy behavior for tests",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
gd::make_unique<gd::Behavior>(),
|
||||
"Group",
|
||||
"Icon.png",
|
||||
"MyOtherBehavior",
|
||||
gd::make_unique<gd::Behavior>(
|
||||
"Behavior", "MyExtension::MyOtherBehavior"),
|
||||
gd::make_unique<gd::BehaviorsSharedData>());
|
||||
}
|
||||
|
||||
@@ -317,10 +338,11 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"BehaviorWithRequiredBehaviorProperty",
|
||||
"BehaviorWithRequiredBehaviorProperty",
|
||||
"A dummy behavior requiring another behavior (MyBehavior)",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
gd::make_unique<BehaviorWithRequiredBehaviorProperty>(),
|
||||
"Group",
|
||||
"Icon.png",
|
||||
"BehaviorWithRequiredBehaviorProperty",
|
||||
gd::make_unique<BehaviorWithRequiredBehaviorProperty>(
|
||||
"Behavior", "MyExtension::BehaviorWithRequiredBehaviorProperty"),
|
||||
gd::make_unique<gd::BehaviorsSharedData>());
|
||||
}
|
||||
{
|
||||
@@ -331,17 +353,19 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"A dummy behavior requiring another behavior "
|
||||
"(BehaviorWithRequiredBehaviorProperty) that itself requires another "
|
||||
"behavior (MyBehavior)",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Group",
|
||||
"Icon.png",
|
||||
"BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior",
|
||||
gd::make_unique<
|
||||
BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior>(),
|
||||
BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior>(
|
||||
"Behavior",
|
||||
"MyExtension::BehaviorWithRequiredBehaviorPropertyRequiringAnotherBehavior"),
|
||||
gd::make_unique<gd::BehaviorsSharedData>());
|
||||
}
|
||||
|
||||
{
|
||||
auto& object = extension
|
||||
->AddObject<gd::Object>(
|
||||
->AddObject<gd::ObjectConfiguration>(
|
||||
"FakeObjectWithUnsupportedCapability",
|
||||
"FakeObjectWithUnsupportedCapability",
|
||||
"This is FakeObjectWithUnsupportedCapability",
|
||||
|
76
Core/tests/EventsExtension.cpp
Normal file
76
Core/tests/EventsExtension.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering events-based extensions
|
||||
*/
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/UnfilledRequiredBehaviorPropertyProblem.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
gd::EventsFunctionsExtension &
|
||||
SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
|
||||
// Add an events-based behavior
|
||||
{
|
||||
auto &eventsBasedBehavior =
|
||||
eventsExtension.GetEventsBasedBehaviors().InsertNew(
|
||||
"MyEventsBasedBehavior", 0);
|
||||
eventsBasedBehavior.SetFullName("My events based behavior");
|
||||
eventsBasedBehavior.SetDescription("An events based behavior for test");
|
||||
|
||||
// Add a property
|
||||
eventsBasedBehavior.GetPropertyDescriptors()
|
||||
.InsertNew("MyProperty", 0)
|
||||
.SetValue("123")
|
||||
.SetType("Number");
|
||||
}
|
||||
|
||||
return eventsExtension;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("Events-based extension", "[common]") {
|
||||
SECTION("Behavior property default value") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
|
||||
auto &layout1 = project.InsertNewLayout("Layout1", 0);
|
||||
auto &object = layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0);
|
||||
|
||||
// Attach a behavior to an object.
|
||||
auto *behavior = object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior", "MyEventsBasedBehavior");
|
||||
behavior->InitializeContent();
|
||||
|
||||
// The behavior has the default value.
|
||||
REQUIRE(behavior->GetProperties().size() == 1);
|
||||
REQUIRE(behavior->GetProperties().at("MyProperty").GetValue() == "123");
|
||||
}
|
||||
}
|
111
Core/tests/ObjectSerialization.cpp
Normal file
111
Core/tests/ObjectSerialization.cpp
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering serialization to JSON.
|
||||
*/
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
namespace {
|
||||
|
||||
void SetupProject(gd::Project &project, gd::Platform &platform) {
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object =
|
||||
layout.InsertNewObject(project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto &configuration = object.GetConfiguration();
|
||||
auto *spriteConfiguration = dynamic_cast<gd::SpriteObject *>(&configuration);
|
||||
REQUIRE(spriteConfiguration != nullptr);
|
||||
gd::Animation animation;
|
||||
animation.SetName("Idle");
|
||||
spriteConfiguration->AddAnimation(animation);
|
||||
};
|
||||
|
||||
void CheckSpriteConfiguration(
|
||||
SerializerElement &objectContainerElement) {
|
||||
};
|
||||
|
||||
void CheckSpriteConfigurationInElement(SerializerElement &projectElement) {
|
||||
auto &layoutsElement = projectElement.GetChild("layouts");
|
||||
layoutsElement.ConsiderAsArrayOf("layout");
|
||||
REQUIRE(layoutsElement.GetChildrenCount() == 1);
|
||||
auto &layoutElement = layoutsElement.GetChild(0);
|
||||
|
||||
REQUIRE(layoutElement.GetStringAttribute("name") == "Scene");
|
||||
REQUIRE(layoutElement.HasChild("objects"));
|
||||
|
||||
auto &objectsElement = layoutElement.GetChild("objects");
|
||||
objectsElement.ConsiderAsArrayOf("object");
|
||||
REQUIRE(objectsElement.GetChildrenCount() == 1);
|
||||
auto &objectElement = objectsElement.GetChild(0);
|
||||
|
||||
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
|
||||
REQUIRE(objectElement.GetStringAttribute("type") == "MyExtension::Sprite");
|
||||
|
||||
REQUIRE(objectElement.HasChild("animations"));
|
||||
auto &animationsElement = objectElement.GetChild("animations");
|
||||
animationsElement.ConsiderAsArrayOf("animation");
|
||||
REQUIRE(animationsElement.GetChildrenCount() == 1);
|
||||
auto &animationElement = animationsElement.GetChild(0);
|
||||
|
||||
REQUIRE(animationElement.GetStringAttribute("name") ==
|
||||
"Idle");
|
||||
};
|
||||
|
||||
void CheckSpriteConfiguration(gd::Project &project) {
|
||||
auto &layout = project.GetLayout("Scene");
|
||||
auto &object = layout.GetObject("MyObject");
|
||||
REQUIRE(object.GetName() == "MyObject");
|
||||
REQUIRE(object.GetType() == "MyExtension::Sprite");
|
||||
|
||||
auto &configuration = object.GetConfiguration();
|
||||
auto *spriteConfiguration = dynamic_cast<gd::SpriteObject *>(&configuration);
|
||||
REQUIRE(spriteConfiguration);
|
||||
REQUIRE(spriteConfiguration->GetAnimationsCount() == 1);
|
||||
|
||||
auto &animation = spriteConfiguration->GetAnimation(0);
|
||||
REQUIRE(animation.GetName() == "Idle");
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ObjectSerialization", "[common]") {
|
||||
|
||||
SECTION("Save and load a project with a sprite configuration") {
|
||||
gd::Platform platform;
|
||||
gd::Project writtenProject;
|
||||
SetupProject(writtenProject, platform);
|
||||
CheckSpriteConfiguration(writtenProject);
|
||||
|
||||
SerializerElement projectElement;
|
||||
writtenProject.SerializeTo(projectElement);
|
||||
CheckSpriteConfigurationInElement(projectElement);
|
||||
|
||||
gd::Project readProject;
|
||||
readProject.AddPlatform(platform);
|
||||
readProject.UnserializeFrom(projectElement);
|
||||
CheckSpriteConfiguration(readProject);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -58,7 +58,7 @@ module.exports = {
|
||||
.setName('AdMob Cordova plugin')
|
||||
.setDependencyType('cordova')
|
||||
.setExportName('gdevelop-cordova-admob-plus')
|
||||
.setVersion('0.43.0')
|
||||
.setVersion('0.45.0')
|
||||
.setExtraSetting(
|
||||
'APP_ID_ANDROID',
|
||||
new gd.PropertyDescriptor('AdMobAppIdAndroid').setType(
|
||||
|
@@ -454,7 +454,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -463,7 +463,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -507,7 +507,8 @@ module.exports = {
|
||||
* This is called to update the PIXI object on the scene editor
|
||||
*/
|
||||
RenderedBBTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObject.getProperties();
|
||||
const properties = this._associatedObjectConfiguration
|
||||
.getProperties();
|
||||
|
||||
const rawText = properties.get('text').getValue();
|
||||
if (rawText !== this._pixiObject.text) {
|
||||
|
@@ -589,7 +589,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -598,7 +598,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -634,7 +634,8 @@ module.exports = {
|
||||
|
||||
// This is called to update the PIXI object on the scene editor
|
||||
RenderedBitmapTextInstance.prototype.update = function () {
|
||||
const properties = this._associatedObject.getProperties();
|
||||
const properties = this._associatedObjectConfiguration
|
||||
.getProperties();
|
||||
|
||||
// Update the rendered text properties (note: Pixi is only
|
||||
// applying changes if there were changed).
|
||||
|
@@ -34,7 +34,6 @@ void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
std::make_shared<DestroyOutsideBehavior>(),
|
||||
std::shared_ptr<gd::BehaviorsSharedData>());
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
aut.AddCondition("ExtraBorder",
|
||||
_("Additional border"),
|
||||
_("Compare the additional border that the object must cross "
|
||||
@@ -47,8 +46,7 @@ void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("behavior", _("Behavior"), "DestroyOutside")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced()
|
||||
.SetFunctionName("GetExtraBorder")
|
||||
.SetIncludeFile("DestroyOutsideBehavior/DestroyOutsideRuntimeBehavior.h");
|
||||
.SetFunctionName("GetExtraBorder");
|
||||
|
||||
aut.AddAction("ExtraBorder",
|
||||
_("Additional border"),
|
||||
@@ -63,7 +61,5 @@ void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced()
|
||||
.SetFunctionName("SetExtraBorder")
|
||||
.SetGetter("GetExtraBorder")
|
||||
.SetIncludeFile("DestroyOutsideBehavior/DestroyOutsideRuntimeBehavior.h");
|
||||
#endif
|
||||
.SetGetter("GetExtraBorder");
|
||||
}
|
||||
|
@@ -506,7 +506,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -515,7 +515,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
@@ -549,7 +549,7 @@ module.exports = {
|
||||
*/
|
||||
RenderedDummyObjectInstance.prototype.update = function () {
|
||||
// Read a property from the object
|
||||
const property1Value = this._associatedObject
|
||||
const property1Value = this._associatedObjectConfiguration
|
||||
.getProperties()
|
||||
.get('My first property')
|
||||
.getValue();
|
||||
|
@@ -1786,7 +1786,7 @@ module.exports = {
|
||||
'FirestoreHasDocument',
|
||||
_("Check for a document's existence"),
|
||||
_(
|
||||
'Checks for the existence of a document. Sets the result variable to 1 if it exists else to 2.'
|
||||
'Checks for the existence of a document. Sets the result variable to true if it exists else to false.'
|
||||
),
|
||||
_(
|
||||
'Check for existence of _PARAM1_ in collection _PARAM0_ and store result in _PARAM2_ (store result state in _PARAM3_)'
|
||||
|
@@ -24,7 +24,6 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddInstructionOrExpressionGroupMetadata(_("Inventories"))
|
||||
.SetIcon("CppPlatform/Extensions/Inventoryicon.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction("Add",
|
||||
_("Add an item"),
|
||||
@@ -37,8 +36,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::Add")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Add");
|
||||
|
||||
extension
|
||||
.AddAction("Remove",
|
||||
@@ -52,8 +50,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::Remove")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Remove");
|
||||
|
||||
extension
|
||||
.AddCondition("Count",
|
||||
@@ -68,8 +65,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.SetFunctionName("InventoryTools::Count")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Count");
|
||||
|
||||
extension
|
||||
.AddCondition("Has",
|
||||
@@ -84,8 +80,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::Has")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Has");
|
||||
|
||||
extension
|
||||
.AddAction("SetMaximum",
|
||||
@@ -103,8 +98,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.AddParameter("expression", _("Maximum count"))
|
||||
.SetFunctionName("InventoryTools::SetMaximum")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::SetMaximum");
|
||||
|
||||
extension
|
||||
.AddAction("SetUnlimited",
|
||||
@@ -121,8 +115,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.AddParameter("yesorno", _("Allow an unlimited amount?"))
|
||||
.SetFunctionName("InventoryTools::SetUnlimited")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::SetUnlimited");
|
||||
|
||||
extension
|
||||
.AddCondition("IsFull",
|
||||
@@ -137,8 +130,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::Has")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Has");
|
||||
|
||||
extension
|
||||
.AddAction("Equip",
|
||||
@@ -154,8 +146,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.AddParameter("yesorno", _("Equip?"))
|
||||
.SetFunctionName("InventoryTools::Equip")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::Equip");
|
||||
|
||||
extension
|
||||
.AddCondition("IsEquipped",
|
||||
@@ -169,8 +160,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::IsEquipped")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::IsEquipped");
|
||||
|
||||
extension
|
||||
.AddAction("SerializeToVariable",
|
||||
@@ -185,8 +175,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetFunctionName("InventoryTools::SerializeToVariable")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::SerializeToVariable");
|
||||
|
||||
extension
|
||||
.AddAction("UnserializeFromVariable",
|
||||
@@ -200,8 +189,7 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("scenevar", _("Scene variable"))
|
||||
.SetFunctionName("InventoryTools::UnserializeFromVariable")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
.SetFunctionName("InventoryTools::UnserializeFromVariable");
|
||||
|
||||
extension
|
||||
.AddExpression("Count",
|
||||
@@ -212,7 +200,5 @@ void DeclareInventoryExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Inventory name"))
|
||||
.AddParameter("string", _("Item name"))
|
||||
.SetFunctionName("InventoryTools::Count")
|
||||
.SetIncludeFile("Inventory/InventoryTools.h");
|
||||
#endif
|
||||
.SetFunctionName("InventoryTools::Count");
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ module.exports = {
|
||||
_('Save player score'),
|
||||
_("Save the player's score to the given leaderboard."),
|
||||
_(
|
||||
'Send to leaderboard _PARAM1_ the score _PARAM2_ with player name: _PARAM3_.'
|
||||
'Send to leaderboard _PARAM1_ the score _PARAM2_ with player name: _PARAM3_'
|
||||
),
|
||||
_('Save score'),
|
||||
'JsPlatform/Extensions/leaderboard.svg',
|
||||
|
@@ -269,7 +269,7 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
) {
|
||||
@@ -278,19 +278,19 @@ module.exports = {
|
||||
project,
|
||||
layout,
|
||||
instance,
|
||||
associatedObject,
|
||||
associatedObjectConfiguration,
|
||||
pixiContainer,
|
||||
pixiResourcesLoader
|
||||
);
|
||||
this._radius = parseFloat(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('radius')
|
||||
.getValue()
|
||||
);
|
||||
if (this._radius <= 0) this._radius = 1;
|
||||
const colorHex = objectsRenderingService.rgbOrHexToHexNumber(
|
||||
this._associatedObject
|
||||
this._associatedObjectConfiguration
|
||||
.getProperties(this.project)
|
||||
.get('color')
|
||||
.getValue()
|
||||
|
@@ -28,8 +28,6 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Linked objects"))
|
||||
.SetIcon("CppPlatform/Extensions/LinkedObjectsicon24.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
extension
|
||||
.AddAction("LinkObjects",
|
||||
_("Link two objects"),
|
||||
@@ -44,8 +42,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("objectPtr", _("Object 1"))
|
||||
.AddParameter("objectPtr", _("Object 2"))
|
||||
|
||||
.SetFunctionName("GDpriv::LinkedObjects::LinkObjects")
|
||||
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
|
||||
.SetFunctionName("GDpriv::LinkedObjects::LinkObjects");
|
||||
|
||||
extension
|
||||
.AddAction("RemoveLinkBetween",
|
||||
@@ -60,8 +57,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("objectPtr", _("Object 1"))
|
||||
.AddParameter("objectPtr", _("Object 2"))
|
||||
|
||||
.SetFunctionName("GDpriv::LinkedObjects::RemoveLinkBetween")
|
||||
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
|
||||
.SetFunctionName("GDpriv::LinkedObjects::RemoveLinkBetween");
|
||||
|
||||
extension
|
||||
.AddAction("RemoveAllLinksOf",
|
||||
@@ -75,8 +71,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
|
||||
.SetFunctionName("GDpriv::LinkedObjects::RemoveAllLinksOf")
|
||||
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
|
||||
.SetFunctionName("GDpriv::LinkedObjects::RemoveAllLinksOf");
|
||||
|
||||
extension
|
||||
.AddCondition("PickObjectsLinkedTo",
|
||||
@@ -94,8 +89,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("objectPtr", _("...if they are linked to this object"))
|
||||
.AddCodeOnlyParameter("eventsFunctionContext", "")
|
||||
|
||||
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo")
|
||||
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
|
||||
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo");
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -112,8 +106,5 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
|
||||
.AddParameter("objectPtr", _("...if they are linked to this object"))
|
||||
.AddCodeOnlyParameter("eventsFunctionContext", "")
|
||||
|
||||
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo")
|
||||
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
|
||||
|
||||
#endif
|
||||
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo");
|
||||
}
|
||||
|
75
Extensions/P2P/A_peer.js
vendored
75
Extensions/P2P/A_peer.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user