mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
66 Commits
v5.4.210
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5eb5fb3af9 | ||
![]() |
cd80872fca | ||
![]() |
61cb6dde0e | ||
![]() |
29c8de0987 | ||
![]() |
802e9a5128 | ||
![]() |
c82602919b | ||
![]() |
80cbb8f542 | ||
![]() |
a9ceba7bef | ||
![]() |
7d9e72c876 | ||
![]() |
3baf5903d3 | ||
![]() |
6008e1045d | ||
![]() |
9dda9a89c5 | ||
![]() |
814c6aec4f | ||
![]() |
84e4158407 | ||
![]() |
aa6c3bc1c8 | ||
![]() |
41dc6d0966 | ||
![]() |
9c19865dec | ||
![]() |
bbfb7f63f0 | ||
![]() |
2f8304c2dd | ||
![]() |
c1aa88861d | ||
![]() |
254ab0350b | ||
![]() |
b0a3c34803 | ||
![]() |
63a3265310 | ||
![]() |
d19292f43d | ||
![]() |
3646d05b65 | ||
![]() |
25a4d04896 | ||
![]() |
2df6c13ed7 | ||
![]() |
93f84a14cb | ||
![]() |
02e0ebf63b | ||
![]() |
da3abb331a | ||
![]() |
a5a9524ed6 | ||
![]() |
c9cc1f6fdc | ||
![]() |
de140f1190 | ||
![]() |
9a82fda7fe | ||
![]() |
eac92704fa | ||
![]() |
dc607d85c3 | ||
![]() |
e96269d899 | ||
![]() |
05d622c5c0 | ||
![]() |
0758397196 | ||
![]() |
65293ddd99 | ||
![]() |
225a3a67c6 | ||
![]() |
a96171aacd | ||
![]() |
1a21a0bfb3 | ||
![]() |
cc23301875 | ||
![]() |
aa513c04e6 | ||
![]() |
a4e8e8c00b | ||
![]() |
0d34680fcd | ||
![]() |
4abdb9dca6 | ||
![]() |
db05a07023 | ||
![]() |
78ebe58713 | ||
![]() |
420c7a4429 | ||
![]() |
1442a2772e | ||
![]() |
ce18bdd5a7 | ||
![]() |
2f2cc1bbe3 | ||
![]() |
097ad4fff5 | ||
![]() |
2112ed789a | ||
![]() |
a41a1c14a0 | ||
![]() |
771d3264bb | ||
![]() |
9fa1e552e0 | ||
![]() |
503a0873d9 | ||
![]() |
715480bdef | ||
![]() |
869fd7eb08 | ||
![]() |
e0cb8e4953 | ||
![]() |
0ef4953241 | ||
![]() |
d154384164 | ||
![]() |
504df2e0a3 |
2
.vscode/GDevelopExtensions.code-snippets
vendored
2
.vscode/GDevelopExtensions.code-snippets
vendored
@@ -107,7 +107,7 @@
|
||||
"description": "Define a parameter in a GDevelop extension definition.",
|
||||
"prefix": "gdparam",
|
||||
"body": [
|
||||
".addParameter('${1|string,expression,object,behavior,yesorno,stringWithSelector,scenevar,globalvar,objectvar,objectList,objectListWithoutPicking,color,key,sceneName,file,layer,relationalOperator,operator,trueorfalse,musicfile,soundfile,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})"
|
||||
".addParameter('${1|string,expression,object,behavior,yesorno,stringWithSelector,scenevar,globalvar,objectvar,objectList,objectListWithoutPicking,color,key,sceneName,file,layer,relationalOperator,operator,trueorfalse,musicfile,soundfile,police,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})"
|
||||
]
|
||||
},
|
||||
"Add code only parameter": {
|
||||
|
@@ -11,11 +11,6 @@ set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE)
|
||||
set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
|
||||
# Create VersionPriv.h - only useful for testing.
|
||||
if (NOT EMSCRIPTEN)
|
||||
file(WRITE "${GD_base_dir}/Core/GDCore/Tools/VersionPriv.h" "#define GD_VERSION_STRING \"0.0.0-0\"")
|
||||
endif()
|
||||
|
||||
# Dependencies on external libraries:
|
||||
#
|
||||
|
||||
|
@@ -42,15 +42,14 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t relationalOperatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
std::size_t relationalOperatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
++i) {
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "relationalOperator") {
|
||||
if (instrInfos.parameters[i].GetType() == "relationalOperator")
|
||||
relationalOperatorIndex = i;
|
||||
}
|
||||
}
|
||||
// Ensure that there is at least one parameter after the relational operator
|
||||
if (relationalOperatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
if (relationalOperatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -77,11 +76,11 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
|
||||
|
||||
/**
|
||||
* @brief Generate a relational operation
|
||||
*
|
||||
*
|
||||
* @param relationalOperator the operator
|
||||
* @param lhs the left hand operand
|
||||
* @param rhs the right hand operand
|
||||
* @return gd::String
|
||||
* @return gd::String
|
||||
*/
|
||||
gd::String EventsCodeGenerator::GenerateRelationalOperation(
|
||||
const gd::String& relationalOperator,
|
||||
@@ -123,16 +122,14 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
|
||||
const gd::String& callStartString,
|
||||
const gd::String& getterStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
++i) {
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -194,16 +191,14 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
++i) {
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -247,16 +242,14 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
++i) {
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -323,7 +316,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
}
|
||||
|
||||
// Insert code only parameters and be sure there is no lack of parameter.
|
||||
while (condition.GetParameters().size() < instrInfos.parameters.GetParametersCount()) {
|
||||
while (condition.GetParameters().size() < instrInfos.parameters.size()) {
|
||||
vector<gd::Expression> parameters = condition.GetParameters();
|
||||
parameters.push_back(gd::Expression(""));
|
||||
condition.SetParameters(parameters);
|
||||
@@ -331,13 +324,13 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter =
|
||||
condition.GetParameter(pNb).GetPlainString();
|
||||
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
@@ -360,7 +353,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
gd::String objectName = condition.GetParameter(0).GetPlainString();
|
||||
if (!objectName.empty() && instrInfos.parameters.GetParametersCount() > 0) {
|
||||
if (!objectName.empty() && !instrInfos.parameters.empty()) {
|
||||
std::vector<gd::String> realObjects =
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
@@ -388,7 +381,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
if (instrInfos.parameters.GetParametersCount() >= 2) {
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
const gd::String &objectName = condition.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName =
|
||||
condition.GetParameter(1).GetPlainString();
|
||||
@@ -546,7 +539,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
: instrInfos.codeExtraInformation.functionCallName;
|
||||
|
||||
// Be sure there is no lack of parameter.
|
||||
while (action.GetParameters().size() < instrInfos.parameters.GetParametersCount()) {
|
||||
while (action.GetParameters().size() < instrInfos.parameters.size()) {
|
||||
vector<gd::Expression> parameters = action.GetParameters();
|
||||
parameters.push_back(gd::Expression(""));
|
||||
action.SetParameters(parameters);
|
||||
@@ -554,12 +547,12 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
|
||||
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
|
||||
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
@@ -584,7 +577,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
gd::String objectName = action.GetParameter(0).GetPlainString();
|
||||
|
||||
if (instrInfos.parameters.GetParametersCount() > 0) {
|
||||
if (!instrInfos.parameters.empty()) {
|
||||
std::vector<gd::String> realObjects =
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
@@ -612,7 +605,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
if (instrInfos.parameters.GetParametersCount() >= 2) {
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
const gd::String &objectName = action.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName = action.GetParameter(1).GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
@@ -828,7 +821,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "spineResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
metadata.GetType() == "soundfile") {
|
||||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
|
||||
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
|
||||
} else if (metadata.GetType() == "mouse") {
|
||||
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
|
||||
@@ -870,7 +863,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
|
||||
vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
|
||||
const vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersInfo,
|
||||
const vector<gd::ParameterMetadata>& parametersInfo,
|
||||
EventsCodeGenerationContext& context,
|
||||
std::vector<std::pair<gd::String, gd::String> >*
|
||||
supplementaryParametersTypes) {
|
||||
@@ -1007,7 +1000,7 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
|
||||
output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" +
|
||||
eventCoreCode + "\n" + scopeEnd + "\n";
|
||||
|
||||
|
||||
if (event.HasVariables()) {
|
||||
GetProjectScopedContainers().GetVariablesContainersList().Pop();
|
||||
}
|
||||
@@ -1107,10 +1100,10 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
|
||||
// Add logical not if needed
|
||||
bool conditionAlreadyTakeCareOfInversion = false;
|
||||
for (std::size_t i = 0; i < instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = 0; i < instrInfos.parameters.size();
|
||||
++i) // Some conditions already have a "conditionInverted" parameter
|
||||
{
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "conditionInverted")
|
||||
if (instrInfos.parameters[i].GetType() == "conditionInverted")
|
||||
conditionAlreadyTakeCareOfInversion = true;
|
||||
}
|
||||
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
|
||||
@@ -1131,7 +1124,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
// Prepare call
|
||||
// Add a static_cast if necessary
|
||||
gd::String objectFunctionCallNamePart =
|
||||
(!instrInfos.parameters.GetParameter(0).GetExtraInfo().empty())
|
||||
(!instrInfos.parameters[0].GetExtraInfo().empty())
|
||||
? "static_cast<" + objInfo.className + "*>(" +
|
||||
GetObjectListName(objectName, context) + "[i])->" +
|
||||
instrInfos.codeExtraInformation.functionCallName
|
||||
@@ -1186,13 +1179,8 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
// Generate call
|
||||
gd::String call;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string" ||
|
||||
// Boolean actions declared with addExpressionAndConditionAndAction uses
|
||||
// MutatorAndOrAccessor even though they don't declare an operator parameter.
|
||||
// Boolean operators are only used with SetMutators or SetCustomCodeGenerator.
|
||||
(instrInfos.codeExtraInformation.type == "boolean" &&
|
||||
instrInfos.codeExtraInformation.accessType ==
|
||||
gd::InstructionMetadata::ExtraInformation::AccessType::Mutators)) {
|
||||
instrInfos.codeExtraInformation.type == "string" ||
|
||||
instrInfos.codeExtraInformation.type == "boolean") {
|
||||
if (instrInfos.codeExtraInformation.accessType ==
|
||||
gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor)
|
||||
call = GenerateOperatorCall(
|
||||
|
@@ -128,7 +128,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
std::vector<gd::String> GenerateParametersCodes(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersInfo,
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfo,
|
||||
EventsCodeGenerationContext& context,
|
||||
std::vector<std::pair<gd::String, gd::String> >*
|
||||
supplementaryParametersTypes = 0);
|
||||
@@ -528,7 +528,7 @@ protected:
|
||||
parameter -> string
|
||||
* - operator : Used to update a value using a setter and a getter -> string
|
||||
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
|
||||
soundfile -> string
|
||||
soundfile, police -> string
|
||||
* - trueorfalse, yesorno -> boolean ( See GenerateTrue/GenerateFalse ).
|
||||
*
|
||||
* <br><br>
|
||||
@@ -849,7 +849,7 @@ protected:
|
||||
instructionUniqueIds; ///< The unique ids generated for instructions.
|
||||
size_t eventsListNextUniqueId; ///< The next identifier to use for an events
|
||||
///< list function name.
|
||||
|
||||
|
||||
gd::DiagnosticReport* diagnosticReport;
|
||||
};
|
||||
|
||||
|
@@ -430,11 +430,11 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
|
||||
size_t nonCodeOnlyParameterIndex = 0;
|
||||
gd::String parametersCode;
|
||||
for (std::size_t i = initialParameterIndex;
|
||||
i < expressionMetadata.GetParameters().GetParametersCount();
|
||||
i < expressionMetadata.parameters.size();
|
||||
++i) {
|
||||
if (i != initialParameterIndex) parametersCode += ", ";
|
||||
|
||||
auto& parameterMetadata = expressionMetadata.GetParameters().GetParameter(i);
|
||||
auto& parameterMetadata = expressionMetadata.parameters[i];
|
||||
if (!parameterMetadata.IsCodeOnly()) {
|
||||
if (nonCodeOnlyParameterIndex < parameters.size()) {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
|
@@ -182,10 +182,10 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
|
||||
// Common updates for some parameters
|
||||
const std::vector<gd::Expression>& parameters = instr.GetParameters();
|
||||
for (std::size_t j = 0;
|
||||
j < parameters.size() && j < metadata.parameters.GetParametersCount();
|
||||
j < parameters.size() && j < metadata.parameters.size();
|
||||
++j) {
|
||||
if (metadata.parameters.GetParameter(j).GetType() == "relationalOperator" ||
|
||||
metadata.parameters.GetParameter(j).GetType() == "operator") {
|
||||
if (metadata.parameters[j].GetType() == "relationalOperator" ||
|
||||
metadata.parameters[j].GetType() == "operator") {
|
||||
if (j == parameters.size() - 1) {
|
||||
std::cout << "ERROR: No more parameters after a [relational]operator "
|
||||
"when trying to update an instruction from GD2.x";
|
||||
|
@@ -116,13 +116,6 @@ void SpriteAnimationList::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SpriteAnimationList::HasAnimationNamed(const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Animation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
||||
|
@@ -51,11 +51,6 @@ class GD_CORE_API SpriteAnimationList {
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if an animation exists for a given name.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String &name) const;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
|
@@ -24,23 +24,18 @@
|
||||
namespace gd {
|
||||
|
||||
SpriteObject::SpriteObject()
|
||||
: updateIfNotVisible(false),
|
||||
preScale(1) {}
|
||||
: updateIfNotVisible(false) {}
|
||||
|
||||
SpriteObject::~SpriteObject(){};
|
||||
|
||||
void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
|
||||
preScale = element.GetDoubleAttribute("preScale", 1);
|
||||
animations.UnserializeFrom(element);
|
||||
}
|
||||
|
||||
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
|
||||
if (preScale != 1) {
|
||||
element.SetAttribute("preScale", preScale);
|
||||
}
|
||||
animations.SerializeTo(element);
|
||||
}
|
||||
|
||||
@@ -92,19 +87,6 @@ bool SpriteObject::UpdateInitialInstanceProperty(
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SpriteObject::GetAnimationsCount() const {
|
||||
return animations.GetAnimationsCount();
|
||||
}
|
||||
|
||||
const gd::String &SpriteObject::GetAnimationName(size_t index) const {
|
||||
return animations.GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool SpriteObject::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return animations.HasAnimationNamed(name);
|
||||
}
|
||||
|
||||
const SpriteAnimationList& SpriteObject::GetAnimations() const {
|
||||
return animations;
|
||||
}
|
||||
|
@@ -52,12 +52,6 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
const gd::String& name,
|
||||
const gd::String& value) override;
|
||||
|
||||
size_t GetAnimationsCount() const override;
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation configuration.
|
||||
*/
|
||||
@@ -82,23 +76,6 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
*/
|
||||
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
|
||||
|
||||
/**
|
||||
* \brief Return the scale applied to object to evaluate the default dimensions.
|
||||
*/
|
||||
double GetPreScale() { return preScale; }
|
||||
|
||||
/**
|
||||
* \brief Set the scale applied to object to evaluate the default dimensions.
|
||||
*
|
||||
* Its value must be strictly positive.
|
||||
*/
|
||||
void SetPreScale(double preScale_) {
|
||||
if (preScale_ <= 0) {
|
||||
return;
|
||||
}
|
||||
preScale = preScale_;
|
||||
}
|
||||
|
||||
private:
|
||||
void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) override;
|
||||
@@ -109,7 +86,6 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
|
||||
///< object animation even if hidden or far from
|
||||
///< the screen.
|
||||
double preScale;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -37,8 +37,7 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
className(className_),
|
||||
iconFilename(icon24x24),
|
||||
instance(instance_),
|
||||
sharedDatasInstance(sharedDatasInstance_),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {
|
||||
sharedDatasInstance(sharedDatasInstance_) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
SetDefaultName(gd::String(defaultName_));
|
||||
@@ -425,7 +424,7 @@ std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() c
|
||||
return instance->GetProperties();
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,6 @@
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
namespace gd {
|
||||
class Behavior;
|
||||
class BehaviorsSharedData;
|
||||
@@ -42,10 +41,10 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
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(
|
||||
@@ -298,18 +297,9 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
return *this;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
|
||||
return quickCustomizationVisibility;
|
||||
}
|
||||
|
||||
BehaviorMetadata &SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::Behavior, handling behavior contents.
|
||||
*
|
||||
*
|
||||
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior
|
||||
* are using EventBasedBehavior.
|
||||
*/
|
||||
@@ -327,7 +317,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
@@ -384,7 +374,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
|
||||
mutable std::vector<gd::String> requiredBehaviors;
|
||||
bool isPrivate = false;
|
||||
bool isHidden = false;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
|
||||
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
|
||||
std::shared_ptr<gd::Behavior> instance;
|
||||
|
@@ -38,12 +38,12 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
|
||||
const gd::String& description,
|
||||
const gd::String& supplementaryInformation,
|
||||
bool parameterIsOptional) {
|
||||
parameters.AddNewParameter("")
|
||||
.SetType(type)
|
||||
.SetDescription(description)
|
||||
.SetCodeOnly(false)
|
||||
.SetOptional(parameterIsOptional)
|
||||
.SetExtraInfo(
|
||||
gd::ParameterMetadata info;
|
||||
info.SetType(type);
|
||||
info.description = description;
|
||||
info.codeOnly = false;
|
||||
info.SetOptional(parameterIsOptional);
|
||||
info.SetExtraInfo(
|
||||
// For objects/behavior, the supplementary information
|
||||
// parameter is an object/behavior type...
|
||||
((gd::ParameterMetadata::IsObject(type) ||
|
||||
@@ -59,16 +59,22 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
||||
parameters.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
gd::ExpressionMetadata &ExpressionMetadata::AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation) {
|
||||
parameters.AddNewParameter("").SetType(type).SetCodeOnly().SetExtraInfo(
|
||||
supplementaryInformation);
|
||||
gd::ExpressionMetadata& ExpressionMetadata::AddCodeOnlyParameter(
|
||||
const gd::String& type, const gd::String& supplementaryInformation) {
|
||||
gd::ParameterMetadata info;
|
||||
info.SetType(type);
|
||||
info.codeOnly = true;
|
||||
info.SetExtraInfo(supplementaryInformation);
|
||||
|
||||
parameters.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
|
||||
const gd::String& capability) {
|
||||
requiredBaseObjectCapability = capability;
|
||||
|
@@ -193,9 +193,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue);
|
||||
}
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetDefaultValue(defaultValue);
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -207,9 +206,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
ExpressionMetadata &
|
||||
SetParameterLongDescription(const gd::String &longDescription) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
|
||||
}
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -222,9 +220,7 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
ExpressionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &extraInfo) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
|
||||
}
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -252,16 +248,19 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
const gd::String& GetGroup() const { return group; }
|
||||
const gd::String& GetSmallIconFilename() const { return smallIconFilename; }
|
||||
const gd::ParameterMetadata& GetParameter(std::size_t id) const {
|
||||
return parameters.GetParameter(id);
|
||||
return parameters[id];
|
||||
};
|
||||
gd::ParameterMetadata& GetParameter(std::size_t id) {
|
||||
return parameters.GetParameter(id);
|
||||
return parameters[id];
|
||||
};
|
||||
std::size_t GetParametersCount() const { return parameters.GetParametersCount(); };
|
||||
const gd::ParameterMetadataContainer& GetParameters() const {
|
||||
std::size_t GetParametersCount() const { return parameters.size(); };
|
||||
const std::vector<gd::ParameterMetadata>& GetParameters() const {
|
||||
return parameters;
|
||||
};
|
||||
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
@@ -369,8 +368,6 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
bool isPrivate;
|
||||
gd::String requiredBaseObjectCapability;
|
||||
gd::String relevantContext;
|
||||
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/ParameterMetadataContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -78,7 +77,7 @@ InstructionMetadata& InstructionMetadata::AddParameter(
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
||||
parameters.AddParameter(info);
|
||||
parameters.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ InstructionMetadata& InstructionMetadata::AddCodeOnlyParameter(
|
||||
info.codeOnly = true;
|
||||
info.SetExtraInfo(supplementaryInformation);
|
||||
|
||||
parameters.AddParameter(info);
|
||||
parameters.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -103,7 +102,7 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
|
||||
AddParameter(
|
||||
"yesorno",
|
||||
options.description.empty() ? _("New value") : options.description);
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("Set _PARAM0_ as <subject>: <value>");
|
||||
@@ -128,8 +127,8 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
|
||||
options.description.empty() ? _("Value") : options.description,
|
||||
options.typeExtraInfo);
|
||||
|
||||
size_t operatorParamIndex = parameters.GetParametersCount() - 2;
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("Change <subject> of _PARAM0_: <operator> <value>");
|
||||
@@ -182,8 +181,8 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
|
||||
AddParameter(type,
|
||||
options.description.empty() ? _("Value to compare") : options.description,
|
||||
options.typeExtraInfo);
|
||||
size_t operatorParamIndex = parameters.GetParametersCount() - 2;
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
|
||||
|
@@ -14,7 +14,6 @@
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/ParameterMetadataContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "ParameterMetadata.h"
|
||||
#include "ParameterOptions.h"
|
||||
@@ -62,12 +61,12 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
const gd::String &GetDescription() const { return description; }
|
||||
const gd::String &GetSentence() const { return sentence; }
|
||||
const gd::String &GetGroup() const { return group; }
|
||||
ParameterMetadata &GetParameter(size_t i) { return parameters.GetParameter(i); }
|
||||
ParameterMetadata &GetParameter(size_t i) { return parameters[i]; }
|
||||
const ParameterMetadata &GetParameter(size_t i) const {
|
||||
return parameters.GetParameter(i);
|
||||
return parameters[i];
|
||||
}
|
||||
size_t GetParametersCount() const { return parameters.GetParametersCount(); }
|
||||
const ParameterMetadataContainer &GetParameters() const {
|
||||
size_t GetParametersCount() const { return parameters.size(); }
|
||||
const std::vector<ParameterMetadata> &GetParameters() const {
|
||||
return parameters;
|
||||
}
|
||||
const gd::String &GetIconFilename() const { return iconFilename; }
|
||||
@@ -257,9 +256,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue_);
|
||||
}
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -271,9 +268,8 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
InstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
|
||||
}
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -285,9 +281,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
|
||||
}
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -566,7 +560,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
InstructionMetadata &GetCodeExtraInformation() { return *this; }
|
||||
|
||||
ParameterMetadataContainer parameters;
|
||||
std::vector<ParameterMetadata> parameters;
|
||||
|
||||
private:
|
||||
gd::String fullname;
|
||||
|
@@ -454,12 +454,11 @@ const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
// TODO use a badMetadata instead of a nullptr?
|
||||
const gd::ParameterMetadata* parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex <
|
||||
metadata.GetParameters().GetParametersCount()) {
|
||||
if (!metadata.GetParameters().GetParameter(metadataParameterIndex)
|
||||
metadata.parameters.size()) {
|
||||
if (!metadata.parameters[metadataParameterIndex]
|
||||
.IsCodeOnly()) {
|
||||
if (visibleParameterIndex == parameterIndex) {
|
||||
parameterMetadata =
|
||||
&metadata.GetParameters().GetParameter(metadataParameterIndex);
|
||||
parameterMetadata = &metadata.parameters[metadataParameterIndex];
|
||||
}
|
||||
visibleParameterIndex++;
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef PARAMETER_METADATA_H
|
||||
#define PARAMETER_METADATA_H
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
@@ -29,12 +29,6 @@ class GD_CORE_API ParameterMetadata {
|
||||
ParameterMetadata();
|
||||
virtual ~ParameterMetadata(){};
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new ParameterMetadata constructed from
|
||||
* this one.
|
||||
*/
|
||||
ParameterMetadata* Clone() const { return new ParameterMetadata(*this); };
|
||||
|
||||
/**
|
||||
* \brief Return the metadata of the parameter type.
|
||||
*/
|
||||
@@ -254,3 +248,5 @@ class GD_CORE_API ParameterMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // PARAMETER_METADATA_H
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/ParameterMetadataContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "InstructionMetadata.h"
|
||||
@@ -21,13 +20,13 @@ const ParameterMetadata ParameterMetadataTools::badParameterMetadata;
|
||||
|
||||
void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const ParameterMetadataContainer& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer) {
|
||||
outputObjectsContainer.GetObjects().clear();
|
||||
|
||||
gd::String lastObjectName;
|
||||
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) {
|
||||
const auto& parameter = parameters.GetParameter(i);
|
||||
for (std::size_t i = 0; i < parameters.size(); ++i) {
|
||||
const auto& parameter = parameters[i];
|
||||
if (parameter.GetName().empty()) continue;
|
||||
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
|
||||
@@ -62,34 +61,31 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::ForEachParameterMatchingSearch(
|
||||
const std::vector<const ParameterMetadataContainer*>&
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto ¶meterMetadata :
|
||||
parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName().FindCaseInsensitive(search) !=
|
||||
gd::String::npos)
|
||||
cb(*parameterMetadata);
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName().FindCaseInsensitive(search) != gd::String::npos) cb(parameterMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ParameterMetadataTools::Has(
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName() == parameterName) return true;
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,18 +93,16 @@ bool ParameterMetadataTools::Has(
|
||||
}
|
||||
|
||||
const gd::ParameterMetadata& ParameterMetadataTools::Get(
|
||||
const std::vector<const ParameterMetadataContainer*>&
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
|
||||
for (const auto ¶meterMetadata :
|
||||
parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName() == parameterName)
|
||||
return *parameterMetadata;
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return parameterMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +111,7 @@ const gd::ParameterMetadata& ParameterMetadataTools::Get(
|
||||
|
||||
void ParameterMetadataTools::IterateOverParameters(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
const gd::String& lastObjectName)> fn) {
|
||||
@@ -134,17 +128,15 @@ void ParameterMetadataTools::IterateOverParameters(
|
||||
|
||||
void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName)> fn) {
|
||||
gd::String lastObjectName = "";
|
||||
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::ParameterMetadata ¶meterMetadata =
|
||||
parametersMetadata.GetParameter(pNb);
|
||||
const gd::Expression ¶meterValue =
|
||||
for (std::size_t pNb = 0; pNb < parametersMetadata.size(); ++pNb) {
|
||||
const gd::ParameterMetadata& parameterMetadata = parametersMetadata[pNb];
|
||||
const gd::Expression& parameterValue =
|
||||
pNb < parameters.size() ? parameters[pNb].GetPlainString() : "";
|
||||
const gd::Expression& parameterValueOrDefault =
|
||||
parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional()
|
||||
@@ -187,10 +179,10 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
metadataIndex < metadata.parameters.size() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto ¶meterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
auto ¶meterMetadata = metadata.parameters[metadataIndex];
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -212,17 +204,16 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
}
|
||||
|
||||
size_t ParameterMetadataTools::GetObjectParameterIndexFor(
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
size_t parameterIndex) {
|
||||
// By convention, parameters that require
|
||||
// an object (mainly, "objectvar" and "behavior") should be placed after
|
||||
// the object in the list of parameters (if possible, just after).
|
||||
// Search "lastObjectName" in the codebase for other place where this
|
||||
// convention is enforced.
|
||||
for (std::size_t pNb = parameterIndex;
|
||||
pNb < parametersMetadata.GetParametersCount(); pNb--) {
|
||||
if (gd::ParameterMetadata::IsObject(
|
||||
parametersMetadata.GetParameter(pNb).GetType())) {
|
||||
for (std::size_t pNb = parameterIndex; pNb < parametersMetadata.size();
|
||||
pNb--) {
|
||||
if (gd::ParameterMetadata::IsObject(parametersMetadata[pNb].GetType())) {
|
||||
return pNb;
|
||||
}
|
||||
}
|
||||
|
@@ -15,7 +15,6 @@ class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ParameterMetadata;
|
||||
class Expression;
|
||||
class ParameterMetadataContainer;
|
||||
struct FunctionCallNode;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
@@ -25,20 +24,20 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
public:
|
||||
static void ParametersToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const ParameterMetadataContainer& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
|
||||
static void ForEachParameterMatchingSearch(
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb);
|
||||
|
||||
static bool Has(
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
static const gd::ParameterMetadata& Get(
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
/**
|
||||
@@ -48,7 +47,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
*/
|
||||
static void IterateOverParameters(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
const gd::String& lastObjectName)> fn);
|
||||
@@ -60,7 +59,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
*/
|
||||
static void IterateOverParametersWithIndex(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
@@ -85,7 +84,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
* it's linked to.
|
||||
*/
|
||||
static size_t GetObjectParameterIndexFor(
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
size_t parameterIndex);
|
||||
|
||||
private:
|
||||
|
@@ -210,8 +210,8 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "scenevar";
|
||||
} else if (type == "resource") {
|
||||
return parameterType == "fontResource" ||
|
||||
parameterType == "audioResource" ||
|
||||
parameterType == "videoResource" ||
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile" ||
|
||||
parameterType == "bitmapFontResource" ||
|
||||
parameterType == "imageResource" ||
|
||||
parameterType == "jsonResource" ||
|
||||
@@ -219,10 +219,7 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "tilesetResource" ||
|
||||
parameterType == "model3DResource" ||
|
||||
parameterType == "atlasResource" ||
|
||||
parameterType == "spineResource" ||
|
||||
// Deprecated, old parameter types:
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile";
|
||||
parameterType == "spineResource";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -72,12 +72,12 @@ public:
|
||||
gd::String lastObjectParameter = "";
|
||||
const gd::InstructionMetadata &instrInfos =
|
||||
MetadataProvider::GetActionMetadata(platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
|
||||
if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
node->Visit(*this);
|
||||
}
|
||||
|
@@ -86,11 +86,9 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
|
||||
&& parameterIndex < node.parameters.size(); ++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.parameters[metadataIndex];
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -146,10 +144,10 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
platform, instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// The parameter has the searched type...
|
||||
if (instrInfos.parameters.GetParameter(pNb).GetType() == "identifier"
|
||||
&& instrInfos.parameters.GetParameter(pNb).GetExtraInfo() == identifierType) {
|
||||
if (instrInfos.parameters[pNb].GetType() == "identifier"
|
||||
&& instrInfos.parameters[pNb].GetExtraInfo() == identifierType) {
|
||||
//...remember the value of the parameter.
|
||||
if (objectName.empty() || lastObjectParameter == objectName) {
|
||||
results.insert(instruction.GetParameter(pNb).GetPlainString());
|
||||
@@ -157,9 +155,9 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
}
|
||||
// Search in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
|
||||
IdentifierFinderExpressionNodeWorker searcher(
|
||||
@@ -172,7 +170,7 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
}
|
||||
// Remember the value of the last "object" parameter.
|
||||
else if (gd::ParameterMetadata::IsObject(
|
||||
instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
instrInfos.parameters[pNb].GetType())) {
|
||||
lastObjectParameter =
|
||||
instruction.GetParameter(pNb).GetPlainString();
|
||||
}
|
||||
|
@@ -305,14 +305,14 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
|
||||
const gd::InstructionMetadata& instrInfos =
|
||||
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// Replace object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
actions[aId].GetParameter(pNb).GetPlainString() == oldName)
|
||||
actions[aId].SetParameter(pNb, gd::Expression(newName));
|
||||
// Replace object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "number", *node, oldName, newName)) {
|
||||
@@ -322,7 +322,7 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
}
|
||||
// Replace object's name in text expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
|
||||
@@ -357,14 +357,14 @@ bool EventsRefactorer::RenameObjectInConditions(
|
||||
const gd::InstructionMetadata& instrInfos =
|
||||
MetadataProvider::GetConditionMetadata(platform,
|
||||
conditions[cId].GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// Replace object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
conditions[cId].GetParameter(pNb).GetPlainString() == oldName)
|
||||
conditions[cId].SetParameter(pNb, gd::Expression(newName));
|
||||
// Replace object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "number", *node, oldName, newName)) {
|
||||
@@ -374,7 +374,7 @@ bool EventsRefactorer::RenameObjectInConditions(
|
||||
}
|
||||
// Replace object's name in text expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
|
||||
@@ -485,16 +485,16 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
|
||||
const gd::InstructionMetadata& instrInfos =
|
||||
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// Find object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
actions[aId].GetParameter(pNb).GetPlainString() == name) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
// Find object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) {
|
||||
@@ -504,7 +504,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
}
|
||||
// Find object's name in text expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
|
||||
@@ -543,16 +543,16 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
const gd::InstructionMetadata& instrInfos =
|
||||
MetadataProvider::GetConditionMetadata(platform,
|
||||
conditions[cId].GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// Find object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
conditions[cId].GetParameter(pNb).GetPlainString() == name) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
// Find object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) {
|
||||
@@ -562,7 +562,7 @@ bool EventsRefactorer::RemoveObjectInConditions(
|
||||
}
|
||||
// Find object's name in text expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
|
||||
|
@@ -31,8 +31,6 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariablesContainer EventsVariableInstructionTypeSwitcher::nullVariablesContainer;
|
||||
|
||||
bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
const auto& metadata = isCondition
|
||||
@@ -84,8 +82,7 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
|
||||
// Every occurrence of the variable or its children are checked.
|
||||
// Ensuring that a child is actually the one with a type change would
|
||||
// take more time.
|
||||
if (variablesContainer == &targetVariablesContainer ||
|
||||
lastObjectName == groupName) {
|
||||
if (variablesContainer == &targetVariablesContainer) {
|
||||
if (typeChangedVariableNames.find(variableName) !=
|
||||
typeChangedVariableNames.end()) {
|
||||
gd::VariableInstructionSwitcher::
|
||||
|
@@ -17,7 +17,7 @@
|
||||
namespace gd {
|
||||
class VariablesContainer;
|
||||
class Platform;
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
@@ -33,36 +33,21 @@ class GD_CORE_API EventsVariableInstructionTypeSwitcher
|
||||
public:
|
||||
EventsVariableInstructionTypeSwitcher(
|
||||
const gd::Platform &platform_,
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_)
|
||||
const gd::VariablesContainer &targetVariablesContainer_,
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames_)
|
||||
: platform(platform_),
|
||||
typeChangedVariableNames(typeChangedVariableNames_),
|
||||
targetVariablesContainer(targetVariablesContainer_), groupName(""){};
|
||||
EventsVariableInstructionTypeSwitcher(
|
||||
const gd::Platform &platform_,
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames_,
|
||||
const gd::String &groupName_)
|
||||
: platform(platform_),
|
||||
typeChangedVariableNames(typeChangedVariableNames_),
|
||||
targetVariablesContainer(nullVariablesContainer),
|
||||
groupName(groupName_){};
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
typeChangedVariableNames(typeChangedVariableNames_){};
|
||||
virtual ~EventsVariableInstructionTypeSwitcher();
|
||||
|
||||
private:
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::VariablesContainer &targetVariablesContainer;
|
||||
/**
|
||||
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be
|
||||
* pointing to `nullVariablesContainer` and the group name is use instead to
|
||||
* check which instruction to modify.
|
||||
*/
|
||||
const gd::String groupName;
|
||||
gd::String objectName;
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames;
|
||||
|
||||
static VariablesContainer nullVariablesContainer;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -32,8 +32,6 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariablesContainer EventsVariableReplacer::nullVariablesContainer;
|
||||
|
||||
/**
|
||||
* \brief Go through the nodes and rename variables,
|
||||
* or signal if the instruction must be renamed if a removed variable is used.
|
||||
@@ -46,26 +44,22 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
ExpressionVariableReplacer(
|
||||
const gd::Platform& platform_,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_,
|
||||
const VariablesRenamingChangesetNode& variablesRenamingChangesetRoot_,
|
||||
const std::unordered_set<gd::String>& removedVariableNames_,
|
||||
const gd::VariablesContainer& targetVariablesContainer_,
|
||||
const gd::String &groupName_,
|
||||
const gd::String &forcedInitialObjectName)
|
||||
const VariablesRenamingChangesetNode& variablesRenamingChangesetRoot_,
|
||||
const std::unordered_set<gd::String>& removedVariableNames_)
|
||||
: hasDoneRenaming(false),
|
||||
removedVariableUsed(false),
|
||||
platform(platform_),
|
||||
projectScopedContainers(projectScopedContainers_),
|
||||
forcedVariablesContainer(nullptr),
|
||||
forcedObjectName(forcedInitialObjectName),
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_),
|
||||
forcedInitialVariablesContainer(nullptr),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
targetGroupName(groupName_){};
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_){};
|
||||
virtual ~ExpressionVariableReplacer(){};
|
||||
|
||||
void SetForcedInitialVariablesContainer(
|
||||
const gd::VariablesContainer* forcedInitialVariablesContainer_) {
|
||||
forcedVariablesContainer = forcedInitialVariablesContainer_;
|
||||
forcedInitialVariablesContainer = forcedInitialVariablesContainer_;
|
||||
}
|
||||
|
||||
bool HasDoneRenaming() const { return hasDoneRenaming; }
|
||||
@@ -88,13 +82,12 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// The node represents a variable or an object name on which a variable
|
||||
// will be accessed.
|
||||
|
||||
if (forcedVariablesContainer) {
|
||||
if (forcedInitialVariablesContainer) {
|
||||
const gd::String oldVariableName = node.name;
|
||||
PushVariablesRenamingChangesetRoot();
|
||||
// A scope was forced. Honor it: it means this node represents a variable
|
||||
// of the forced variables container.
|
||||
if (forcedVariablesContainer == &targetVariablesContainer ||
|
||||
IsTargetingObjectGroup(forcedObjectName)) {
|
||||
if (forcedInitialVariablesContainer == &targetVariablesContainer) {
|
||||
RenameOrRemoveVariableOfTargetVariableContainer(node.name);
|
||||
}
|
||||
|
||||
@@ -157,8 +150,7 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// This is always true because MatchIdentifierWithName is used to get
|
||||
// objectNameToUseForVariableAccessor.
|
||||
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
|
||||
objectNameToUseForVariableAccessor, targetVariablesContainer) ||
|
||||
IsTargetingObjectGroup(objectNameToUseForVariableAccessor)) {
|
||||
objectNameToUseForVariableAccessor, targetVariablesContainer)) {
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
// The node represents an object variable, and this object variables are
|
||||
// the target. Do the replacement or removals:
|
||||
@@ -205,11 +197,10 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// (and if it's a variable reference or a value does not have any importance
|
||||
// here).
|
||||
|
||||
if (forcedVariablesContainer) {
|
||||
if (forcedInitialVariablesContainer) {
|
||||
// A scope was forced. Honor it: it means this node represents a variable
|
||||
// of the forced variables container.
|
||||
if (forcedVariablesContainer == &targetVariablesContainer ||
|
||||
IsTargetingObjectGroup(forcedObjectName)) {
|
||||
if (forcedInitialVariablesContainer == &targetVariablesContainer) {
|
||||
renameVariableAndChild();
|
||||
}
|
||||
return;
|
||||
@@ -222,8 +213,7 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
[&]() {
|
||||
// This represents an object.
|
||||
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
|
||||
node.identifierName, targetVariablesContainer) ||
|
||||
IsTargetingObjectGroup(node.identifierName)) {
|
||||
node.identifierName, targetVariablesContainer)) {
|
||||
// The node represents an object variable, and this object variables
|
||||
// are the target. Do the replacement or removals:
|
||||
PushVariablesRenamingChangesetRoot();
|
||||
@@ -271,33 +261,31 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// force the "scope" at which starts the evalution of variables.
|
||||
if (parameterMetadata && parameterMetadata->GetValueTypeMetadata()
|
||||
.IsLegacyPreScopedVariable()) {
|
||||
const gd::VariablesContainer *oldForcedVariablesContainer =
|
||||
forcedVariablesContainer;
|
||||
const gd::String &oldForcedObjectName = forcedObjectName;
|
||||
const gd::VariablesContainer* oldForcedInitialVariablesContainer =
|
||||
forcedInitialVariablesContainer;
|
||||
|
||||
forcedVariablesContainer = nullptr;
|
||||
forcedObjectName = "";
|
||||
forcedInitialVariablesContainer = nullptr;
|
||||
if (parameterMetadata->GetType() == "globalvar") {
|
||||
forcedVariablesContainer =
|
||||
forcedInitialVariablesContainer =
|
||||
projectScopedContainers.GetVariablesContainersList()
|
||||
.GetTopMostVariablesContainer();
|
||||
} else if (parameterMetadata->GetType() == "scenevar") {
|
||||
forcedVariablesContainer =
|
||||
forcedInitialVariablesContainer =
|
||||
projectScopedContainers.GetVariablesContainersList()
|
||||
.GetBottomMostVariablesContainer();
|
||||
} else if (parameterMetadata->GetType() == "objectvar") {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
|
||||
platform, projectScopedContainers.GetObjectsContainersList(),
|
||||
node.objectName, *node.parameters[parameterIndex].get());
|
||||
forcedVariablesContainer =
|
||||
platform,
|
||||
projectScopedContainers.GetObjectsContainersList(),
|
||||
node.objectName,
|
||||
*node.parameters[parameterIndex].get());
|
||||
forcedInitialVariablesContainer =
|
||||
projectScopedContainers.GetObjectsContainersList()
|
||||
.GetObjectOrGroupVariablesContainer(objectName);
|
||||
forcedObjectName = objectName;
|
||||
}
|
||||
|
||||
node.parameters[parameterIndex]->Visit(*this);
|
||||
forcedVariablesContainer = oldForcedVariablesContainer;
|
||||
forcedObjectName = oldForcedObjectName;
|
||||
forcedInitialVariablesContainer = oldForcedInitialVariablesContainer;
|
||||
} else {
|
||||
// For any other parameter, there is no special treatment being needed.
|
||||
node.parameters[parameterIndex]->Visit(*this);
|
||||
@@ -310,10 +298,6 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
bool hasDoneRenaming;
|
||||
bool removedVariableUsed;
|
||||
|
||||
bool IsTargetingObjectGroup(const gd::String &objectGroupName) {
|
||||
return !targetGroupName.empty() && objectGroupName == targetGroupName;
|
||||
}
|
||||
|
||||
bool RenameOrRemoveVariableOfTargetVariableContainer(
|
||||
gd::String& variableName) {
|
||||
const auto *currentVariablesRenamingChangesetNode =
|
||||
@@ -398,17 +382,10 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// Scope:
|
||||
const gd::Platform& platform;
|
||||
const gd::ProjectScopedContainers& projectScopedContainers;
|
||||
const gd::VariablesContainer* forcedVariablesContainer;
|
||||
gd::String forcedObjectName;
|
||||
const gd::VariablesContainer* forcedInitialVariablesContainer;
|
||||
|
||||
// Renaming or removing to do:
|
||||
const gd::VariablesContainer& targetVariablesContainer;
|
||||
/**
|
||||
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be
|
||||
* pointing to `nullVariablesContainer` and the group name is use instead to
|
||||
* check which variable accesses to modify in expressions.
|
||||
*/
|
||||
const gd::String& targetGroupName;
|
||||
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot;
|
||||
const std::unordered_set<gd::String>& removedVariableNames;
|
||||
|
||||
@@ -420,7 +397,7 @@ const gd::VariablesContainer*
|
||||
EventsVariableReplacer::FindForcedVariablesContainerIfAny(
|
||||
const gd::String& type, const gd::String& lastObjectName) {
|
||||
// Handle legacy pre-scoped variable parameters: in this case, we
|
||||
// force the "scope" at which starts the evaluation of variables.
|
||||
// force the "scope" at which starts the evalution of variables.
|
||||
if (type == "objectvar") {
|
||||
return GetProjectScopedContainers()
|
||||
.GetObjectsContainersList()
|
||||
@@ -465,11 +442,9 @@ bool EventsVariableReplacer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
if (node) {
|
||||
ExpressionVariableReplacer renamer(platform,
|
||||
GetProjectScopedContainers(),
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames,
|
||||
targetVariablesContainer,
|
||||
targetGroupName,
|
||||
type == "objectvar" ? lastObjectName : "");
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames);
|
||||
renamer.SetForcedInitialVariablesContainer(
|
||||
FindForcedVariablesContainerIfAny(type, lastObjectName));
|
||||
node->Visit(renamer);
|
||||
@@ -499,11 +474,9 @@ bool EventsVariableReplacer::DoVisitEventExpression(
|
||||
if (node) {
|
||||
ExpressionVariableReplacer renamer(platform,
|
||||
GetProjectScopedContainers(),
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames,
|
||||
targetVariablesContainer,
|
||||
targetGroupName,
|
||||
"");
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames);
|
||||
renamer.SetForcedInitialVariablesContainer(
|
||||
FindForcedVariablesContainerIfAny(type, ""));
|
||||
node->Visit(renamer);
|
||||
|
@@ -35,24 +35,13 @@ class GD_CORE_API EventsVariableReplacer
|
||||
public:
|
||||
EventsVariableReplacer(
|
||||
const gd::Platform &platform_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_,
|
||||
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot_,
|
||||
const std::unordered_set<gd::String> &removedVariableNames_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_)
|
||||
const std::unordered_set<gd::String> &removedVariableNames_)
|
||||
: platform(platform_),
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
targetGroupName("") {};
|
||||
EventsVariableReplacer(
|
||||
const gd::Platform &platform_,
|
||||
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot_,
|
||||
const std::unordered_set<gd::String> &removedVariableNames_,
|
||||
const gd::String &targetGroupName_)
|
||||
: platform(platform_),
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_),
|
||||
targetVariablesContainer(nullVariablesContainer),
|
||||
targetGroupName(targetGroupName_) {};
|
||||
removedVariableNames(removedVariableNames_) {};
|
||||
virtual ~EventsVariableReplacer();
|
||||
|
||||
private:
|
||||
@@ -66,16 +55,9 @@ class GD_CORE_API EventsVariableReplacer
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::VariablesContainer &targetVariablesContainer;
|
||||
/**
|
||||
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be
|
||||
* pointing to `nullVariablesContainer` and the group name is use instead to
|
||||
* check which variable accesses to modify in expressions.
|
||||
*/
|
||||
const gd::String targetGroupName;
|
||||
gd::String objectName;
|
||||
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot;
|
||||
const std::unordered_set<gd::String> &removedVariableNames;
|
||||
|
||||
static VariablesContainer nullVariablesContainer;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -93,11 +93,9 @@ class GD_CORE_API VariableFinderExpressionNodeWorker
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
|
||||
&& parameterIndex < node.parameters.size(); ++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.parameters[metadataIndex];
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -152,18 +150,18 @@ class GD_CORE_API VariableFinderEventWorker
|
||||
platform, instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
// The parameter has the searched type...
|
||||
if (instrInfos.parameters.GetParameter(pNb).GetType() == parameterType) {
|
||||
if (instrInfos.parameters[pNb].GetType() == parameterType) {
|
||||
//...remember the value of the parameter.
|
||||
if (objectName.empty() || lastObjectParameter == objectName)
|
||||
results.insert(instruction.GetParameter(pNb).GetPlainString());
|
||||
}
|
||||
// Search in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
|
||||
VariableFinderExpressionNodeWorker searcher(
|
||||
@@ -176,7 +174,7 @@ class GD_CORE_API VariableFinderEventWorker
|
||||
}
|
||||
// Remember the value of the last "object" parameter.
|
||||
else if (gd::ParameterMetadata::IsObject(
|
||||
instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
instrInfos.parameters[pNb].GetType())) {
|
||||
lastObjectParameter =
|
||||
instruction.GetParameter(pNb).GetPlainString();
|
||||
}
|
||||
|
@@ -463,15 +463,11 @@ class GD_CORE_API ExpressionCompletionFinder
|
||||
MetadataProvider::GetFunctionCallMetadata(
|
||||
platform, objectsContainersList, *functionCall);
|
||||
|
||||
const gd::ParameterMetadata *parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex <
|
||||
metadata.GetParameters().GetParametersCount()) {
|
||||
if (!metadata.GetParameters()
|
||||
.GetParameter(metadataParameterIndex)
|
||||
.IsCodeOnly()) {
|
||||
const gd::ParameterMetadata* parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex < metadata.parameters.size()) {
|
||||
if (!metadata.parameters[metadataParameterIndex].IsCodeOnly()) {
|
||||
if (visibleParameterIndex == parameterIndex) {
|
||||
parameterMetadata =
|
||||
&metadata.GetParameters().GetParameter(metadataParameterIndex);
|
||||
parameterMetadata = &metadata.parameters[metadataParameterIndex];
|
||||
}
|
||||
visibleParameterIndex++;
|
||||
}
|
||||
|
@@ -36,15 +36,13 @@ namespace {
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMinimumParametersNumber(
|
||||
const gd::ParameterMetadataContainer& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex;
|
||||
i < parameters.GetParametersCount(); ++i) {
|
||||
if (!parameters.GetParameter(i).IsOptional() &&
|
||||
!parameters.GetParameter(i).IsCodeOnly())
|
||||
nb++;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].IsOptional() && !parameters[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
@@ -53,14 +51,13 @@ size_t GetMinimumParametersNumber(
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMaximumParametersNumber(
|
||||
const gd::ParameterMetadataContainer& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex;
|
||||
i < parameters.GetParametersCount(); ++i) {
|
||||
if (!parameters.GetParameter(i).IsCodeOnly())
|
||||
nb++;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
@@ -325,11 +322,11 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(
|
||||
|
||||
// Validate parameters count
|
||||
size_t minParametersCount = GetMinimumParametersNumber(
|
||||
metadata.GetParameters(),
|
||||
metadata.parameters,
|
||||
ExpressionParser2::WrittenParametersFirstIndex(function.objectName,
|
||||
function.behaviorName));
|
||||
size_t maxParametersCount = GetMaximumParametersNumber(
|
||||
metadata.GetParameters(),
|
||||
metadata.parameters,
|
||||
ExpressionParser2::WrittenParametersFirstIndex(function.objectName,
|
||||
function.behaviorName));
|
||||
if (function.parameters.size() < minParametersCount ||
|
||||
@@ -369,11 +366,11 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(
|
||||
for (int parameterIndex = 0; parameterIndex < function.parameters.size();
|
||||
parameterIndex++) {
|
||||
auto& parameter = function.parameters[parameterIndex];
|
||||
while (metadata.GetParameters().GetParameter(metadataIndex).IsCodeOnly()) {
|
||||
while (metadata.GetParameters()[metadataIndex].IsCodeOnly()) {
|
||||
// The sizes are already checked above.
|
||||
metadataIndex++;
|
||||
}
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
auto& parameterMetadata = metadata.GetParameters()[metadataIndex];
|
||||
|
||||
if (!parameterMetadata.IsOptional() ||
|
||||
dynamic_cast<EmptyNode*>(parameter.get()) == nullptr) {
|
||||
|
@@ -144,10 +144,10 @@ bool ExpressionsParameterMover::DoVisitInstruction(gd::Instruction& instruction,
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.GetParametersCount() &&
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.size() &&
|
||||
pNb < instruction.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::String& type = metadata.parameters.GetParameter(pNb).GetType();
|
||||
const gd::String& type = metadata.parameters[pNb].GetType();
|
||||
const gd::Expression& expression = instruction.GetParameter(pNb);
|
||||
|
||||
auto node = expression.GetRootNode();
|
||||
|
@@ -151,7 +151,7 @@ bool ExpressionsRenamer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.GetParametersCount() &&
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.size() &&
|
||||
pNb < instruction.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::Expression& expression = instruction.GetParameter(pNb);
|
||||
|
@@ -43,7 +43,7 @@ InstructionSentenceFormatter::GetAsFormattedText(
|
||||
parse = false;
|
||||
size_t firstParamPosition = gd::String::npos;
|
||||
size_t firstParamIndex = gd::String::npos;
|
||||
for (std::size_t i = 0; i < metadata.parameters.GetParametersCount(); ++i) {
|
||||
for (std::size_t i = 0; i < metadata.parameters.size(); ++i) {
|
||||
size_t paramPosition =
|
||||
sentence.find("_PARAM" + gd::String::From(i) + "_");
|
||||
if (paramPosition < firstParamPosition) {
|
||||
|
@@ -1,196 +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 "GroupVariableHelper.h"
|
||||
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectGroup.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void GroupVariableHelper::FillAnyVariableBetweenObjects(
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::ObjectGroup &objectGroup) {
|
||||
const auto &objectNames = objectGroup.GetAllObjectsNames();
|
||||
for (const gd::String &sourceObjectName : objectNames) {
|
||||
const bool hasObject = objectsContainer.HasObjectNamed(sourceObjectName);
|
||||
if (!hasObject &&
|
||||
!globalObjectsContainer.HasObjectNamed(sourceObjectName)) {
|
||||
continue;
|
||||
}
|
||||
const auto &sourceObject =
|
||||
hasObject ? objectsContainer.GetObject(sourceObjectName)
|
||||
: globalObjectsContainer.GetObject(sourceObjectName);
|
||||
const auto &sourceVariablesContainer = sourceObject.GetVariables();
|
||||
|
||||
for (const gd::String &destinationObjectName : objectNames) {
|
||||
if (sourceObjectName == destinationObjectName) {
|
||||
continue;
|
||||
}
|
||||
const bool hasObject =
|
||||
objectsContainer.HasObjectNamed(destinationObjectName);
|
||||
if (!hasObject &&
|
||||
!globalObjectsContainer.HasObjectNamed(destinationObjectName)) {
|
||||
continue;
|
||||
}
|
||||
auto &destinationObject =
|
||||
hasObject ? objectsContainer.GetObject(destinationObjectName)
|
||||
: globalObjectsContainer.GetObject(destinationObjectName);
|
||||
auto &destinationVariablesContainer = destinationObject.GetVariables();
|
||||
|
||||
for (std::size_t sourceVariableIndex = 0;
|
||||
sourceVariableIndex < sourceVariablesContainer.Count();
|
||||
++sourceVariableIndex) {
|
||||
auto &sourceVariable =
|
||||
sourceVariablesContainer.Get(sourceVariableIndex);
|
||||
const auto &variableName =
|
||||
sourceVariablesContainer.GetNameAt(sourceVariableIndex);
|
||||
|
||||
if (!destinationVariablesContainer.Has(variableName)) {
|
||||
destinationVariablesContainer.Insert(
|
||||
variableName, sourceVariable,
|
||||
destinationVariablesContainer.Count());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gd::VariablesContainer GroupVariableHelper::MergeVariableContainers(
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
const gd::ObjectGroup &objectGroup) {
|
||||
gd::VariablesContainer mergedVariablesContainer;
|
||||
|
||||
const auto &objectNames = objectGroup.GetAllObjectsNames();
|
||||
std::size_t objectIndex = 0;
|
||||
bool isFirstObjectFound = false;
|
||||
for (; objectIndex < objectNames.size() && !isFirstObjectFound;
|
||||
objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!objectsContainersList.HasObjectOrGroupNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
isFirstObjectFound = true;
|
||||
mergedVariablesContainer =
|
||||
*objectsContainersList.GetObjectOrGroupVariablesContainer(objectName);
|
||||
}
|
||||
for (; objectIndex < objectNames.size(); objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!objectsContainersList.HasObjectOrGroupNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
const auto &variablesContainer =
|
||||
*objectsContainersList.GetObjectOrGroupVariablesContainer(objectName);
|
||||
|
||||
for (std::size_t variableIndex = 0;
|
||||
variableIndex < mergedVariablesContainer.Count(); ++variableIndex) {
|
||||
auto &mergedVariable = mergedVariablesContainer.Get(variableIndex);
|
||||
const auto &variableName =
|
||||
mergedVariablesContainer.GetNameAt(variableIndex);
|
||||
|
||||
if (variablesContainer.Has(variableName)) {
|
||||
auto &variable = variablesContainer.Get(variableName);
|
||||
if (mergedVariable.GetType() != variable.GetType()) {
|
||||
mergedVariable.CastTo(gd::Variable::Type::MixedTypes);
|
||||
} else if (mergedVariable != variable) {
|
||||
mergedVariable.MarkAsMixedValues();
|
||||
}
|
||||
} else {
|
||||
mergedVariablesContainer.Remove(variableName);
|
||||
variableIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mergedVariablesContainer;
|
||||
}
|
||||
|
||||
void GroupVariableHelper::FillMissingGroupVariablesToObjects(
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer, const gd::ObjectGroup &objectGroup,
|
||||
const gd::SerializerElement &originalSerializedVariables) {
|
||||
gd::VariablesContainer groupVariablesContainer;
|
||||
groupVariablesContainer.UnserializeFrom(originalSerializedVariables);
|
||||
// Add missing variables to objects added in the group.
|
||||
for (const gd::String &objectName : objectGroup.GetAllObjectsNames()) {
|
||||
const bool hasObject = objectsContainer.HasObjectNamed(objectName);
|
||||
if (!hasObject && !globalObjectsContainer.HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
auto &object = hasObject ? objectsContainer.GetObject(objectName)
|
||||
: globalObjectsContainer.GetObject(objectName);
|
||||
auto &variablesContainer = object.GetVariables();
|
||||
for (std::size_t variableIndex = 0;
|
||||
variableIndex < groupVariablesContainer.Count(); ++variableIndex) {
|
||||
auto &groupVariable = groupVariablesContainer.Get(variableIndex);
|
||||
const auto &variableName =
|
||||
groupVariablesContainer.GetNameAt(variableIndex);
|
||||
|
||||
if (!variablesContainer.Has(variableName)) {
|
||||
variablesContainer.Insert(variableName, groupVariable,
|
||||
variablesContainer.Count());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO Handle position changes for group variables.
|
||||
// We could try to change the order of object variables in a way that the next
|
||||
// call to MergeVariableContainers rebuild them in the same order.
|
||||
void GroupVariableHelper::ApplyChangesToObjects(
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::VariablesContainer &groupVariablesContainer,
|
||||
const gd::ObjectGroup &objectGroup,
|
||||
const gd::VariablesChangeset &changeset) {
|
||||
for (const gd::String &objectName : objectGroup.GetAllObjectsNames()) {
|
||||
const bool hasObject = objectsContainer.HasObjectNamed(objectName);
|
||||
if (!hasObject && !globalObjectsContainer.HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
auto &object = hasObject ? objectsContainer.GetObject(objectName)
|
||||
: globalObjectsContainer.GetObject(objectName);
|
||||
auto &variablesContainer = object.GetVariables();
|
||||
for (const gd::String &variableName : changeset.removedVariableNames) {
|
||||
variablesContainer.Remove(variableName);
|
||||
}
|
||||
for (const gd::String &variableName : changeset.addedVariableNames) {
|
||||
if (variablesContainer.Has(variableName)) {
|
||||
// It can happens if an object already had the variable but it was not
|
||||
// shared by other object of the group.
|
||||
continue;
|
||||
}
|
||||
variablesContainer.Insert(variableName,
|
||||
groupVariablesContainer.Get(variableName),
|
||||
variablesContainer.Count());
|
||||
}
|
||||
for (const auto &pair : changeset.oldToNewVariableNames) {
|
||||
const gd::String &oldVariableName = pair.first;
|
||||
const gd::String &newVariableName = pair.second;
|
||||
if (variablesContainer.Has(newVariableName)) {
|
||||
// It can happens if an object already had the variable but it was not
|
||||
// shared by other object of the group.
|
||||
variablesContainer.Remove(oldVariableName);
|
||||
} else {
|
||||
variablesContainer.Rename(oldVariableName, newVariableName);
|
||||
}
|
||||
}
|
||||
// Apply type and value changes
|
||||
for (const gd::String &variableName : changeset.valueChangedVariableNames) {
|
||||
size_t index = variablesContainer.GetPosition(variableName);
|
||||
variablesContainer.Remove(variableName);
|
||||
variablesContainer.Insert(
|
||||
variableName, groupVariablesContainer.Get(variableName), index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
|
||||
namespace gd {
|
||||
class ObjectsContainersList;
|
||||
class ObjectsContainer;
|
||||
class ObjectGroup;
|
||||
class VariablesContainer;
|
||||
struct VariablesChangeset;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Help handling variables of group objects as a whole.
|
||||
*
|
||||
* This is used by the object group variable editor.
|
||||
*/
|
||||
class GD_CORE_API GroupVariableHelper {
|
||||
public:
|
||||
/**
|
||||
* Copy every variable from every object of the group to the other objects
|
||||
* if they don't have it already.
|
||||
*
|
||||
* In the editor, when an object group is created, users can choose between:
|
||||
* - doing no change and only see variables that are already shared by any
|
||||
* objects of the group
|
||||
* - applying this function and see every variable
|
||||
*/
|
||||
static void
|
||||
FillAnyVariableBetweenObjects(gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::ObjectGroup &objectGroup);
|
||||
|
||||
/**
|
||||
* Build a variable container with the intersection of variables from the
|
||||
* every objects of the given group.
|
||||
*/
|
||||
static gd::VariablesContainer MergeVariableContainers(
|
||||
const gd::ObjectsContainersList &objectsContainersList,
|
||||
const gd::ObjectGroup &objectGroup);
|
||||
|
||||
/**
|
||||
* @brief Copy the variables of the group to all objects.
|
||||
*
|
||||
* Objects can be added during the group edition and may not necessarily have
|
||||
* all the variables initially shared by the group.
|
||||
*
|
||||
* \see gd::GroupVariableHelper::MergeVariableContainers
|
||||
*/
|
||||
static void FillMissingGroupVariablesToObjects(
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::ObjectGroup &objectGroup,
|
||||
const gd::SerializerElement &originalSerializedVariables);
|
||||
|
||||
/**
|
||||
* @brief Apply the changes done with the variables editor to the objects of
|
||||
* the group.
|
||||
*/
|
||||
static void
|
||||
ApplyChangesToObjects(gd::ObjectsContainer &globalObjectsContainers,
|
||||
gd::ObjectsContainer &objectsContainers,
|
||||
const gd::VariablesContainer &groupVariablesContainer,
|
||||
const gd::ObjectGroup &objectGroup,
|
||||
const gd::VariablesChangeset &changeset);
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -225,7 +225,9 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() == "fontResource") {
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police" || // Should be renamed fontResource
|
||||
parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
|
@@ -15,10 +15,10 @@ namespace gd {
|
||||
|
||||
void FunctionParameterBehaviorTypeRenamer::DoVisitEventsFunction(
|
||||
gd::EventsFunction &eventsFunction) {
|
||||
for (auto &¶meter : eventsFunction.GetParameters().GetInternalVector()) {
|
||||
if (gd::ParameterMetadata::IsBehavior(parameter->GetType()) &&
|
||||
parameter->GetExtraInfo() == oldBehaviorType) {
|
||||
parameter->SetExtraInfo(newBehaviorType);
|
||||
for (auto &¶meter : eventsFunction.GetParameters()) {
|
||||
if (gd::ParameterMetadata::IsBehavior(parameter.GetType()) &&
|
||||
parameter.GetExtraInfo() == oldBehaviorType) {
|
||||
parameter.SetExtraInfo(newBehaviorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,10 +15,10 @@ namespace gd {
|
||||
|
||||
void FunctionParameterObjectTypeRenamer::DoVisitEventsFunction(
|
||||
gd::EventsFunction &eventsFunction) {
|
||||
for (auto &¶meter : eventsFunction.GetParameters().GetInternalVector()) {
|
||||
if (gd::ParameterMetadata::IsObject(parameter->GetType()) &&
|
||||
parameter->GetExtraInfo() == oldObjectType) {
|
||||
parameter->SetExtraInfo(newObjectType);
|
||||
for (auto &¶meter : eventsFunction.GetParameters()) {
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType()) &&
|
||||
parameter.GetExtraInfo() == oldObjectType) {
|
||||
parameter.SetExtraInfo(newObjectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -153,7 +153,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
extension.GetName(), eventsBasedEntity.GetName());
|
||||
objectParameter.SetExtraInfo(objectFullType);
|
||||
}
|
||||
setter.GetParameters().AddParameter(objectParameter);
|
||||
setter.GetParameters().push_back(objectParameter);
|
||||
if (isBehavior) {
|
||||
gd::ParameterMetadata behaviorParameter;
|
||||
gd::String behaviorFullType =
|
||||
@@ -163,7 +163,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
.SetName("Behavior")
|
||||
.SetDescription("Behavior")
|
||||
.SetExtraInfo(behaviorFullType);
|
||||
setter.GetParameters().AddParameter(behaviorParameter);
|
||||
setter.GetParameters().push_back(behaviorParameter);
|
||||
}
|
||||
gd::ParameterMetadata valueParameter;
|
||||
valueParameter.SetType("yesorno")
|
||||
@@ -171,7 +171,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
.SetDescription(capitalizedName)
|
||||
.SetOptional(true)
|
||||
.SetDefaultValue("yes");
|
||||
setter.GetParameters().AddParameter(valueParameter);
|
||||
setter.GetParameters().push_back(valueParameter);
|
||||
} else {
|
||||
setter.SetFunctionType(gd::EventsFunction::ActionWithOperator);
|
||||
setter.SetGetterName(getterName);
|
||||
|
@@ -11,23 +11,22 @@
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/DependenciesAnalyzer.h"
|
||||
#include "GDCore/IDE/GroupVariableHelper.h"
|
||||
#include "GDCore/IDE/EventBasedBehaviorBrowser.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Events/BehaviorParametersFiller.h"
|
||||
#include "GDCore/IDE/Events/BehaviorTypeRenamer.h"
|
||||
#include "GDCore/IDE/Events/CustomObjectTypeRenamer.h"
|
||||
#include "GDCore/IDE/Events/EventsBehaviorRenamer.h"
|
||||
#include "GDCore/IDE/Events/EventsPropertyReplacer.h"
|
||||
#include "GDCore/IDE/Events/EventsRefactorer.h"
|
||||
#include "GDCore/IDE/Events/EventsVariableInstructionTypeSwitcher.h"
|
||||
#include "GDCore/IDE/Events/EventsVariableReplacer.h"
|
||||
#include "GDCore/IDE/Events/EventsVariableInstructionTypeSwitcher.h"
|
||||
#include "GDCore/IDE/Events/ExpressionsParameterMover.h"
|
||||
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
|
||||
#include "GDCore/IDE/Events/InstructionsParameterMover.h"
|
||||
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
|
||||
#include "GDCore/IDE/Events/LinkEventTargetRenamer.h"
|
||||
#include "GDCore/IDE/Events/ProjectElementRenamer.h"
|
||||
#include "GDCore/IDE/Events/BehaviorParametersFiller.h"
|
||||
#include "GDCore/IDE/EventsFunctionTools.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryBehaviorSharedDataWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryEventBasedBehaviorsWorker.h"
|
||||
@@ -102,17 +101,17 @@ void WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
|
||||
for (auto &eventsFunction :
|
||||
eventsBasedBehavior.GetEventsFunctions().GetInternalVector()) {
|
||||
auto ¶meters = eventsFunction->GetParameters();
|
||||
while (parameters.GetParametersCount() < 2) {
|
||||
while (parameters.size() < 2) {
|
||||
gd::ParameterMetadata newParameter;
|
||||
parameters.AddParameter(newParameter);
|
||||
parameters.push_back(newParameter);
|
||||
}
|
||||
|
||||
parameters.GetParameter(0)
|
||||
parameters[0]
|
||||
.SetType("object")
|
||||
.SetName(behaviorObjectParameterName)
|
||||
.SetDescription("Object")
|
||||
.SetExtraInfo(eventsBasedBehavior.GetObjectType());
|
||||
parameters.GetParameter(1)
|
||||
parameters[1]
|
||||
.SetType("behavior")
|
||||
.SetName("Behavior")
|
||||
.SetDescription("Behavior")
|
||||
@@ -127,12 +126,12 @@ void WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
for (auto &eventsFunction :
|
||||
eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto ¶meters = eventsFunction->GetParameters();
|
||||
while (parameters.GetParametersCount() < 1) {
|
||||
while (parameters.size() < 1) {
|
||||
gd::ParameterMetadata newParameter;
|
||||
parameters.AddParameter(newParameter);
|
||||
parameters.push_back(newParameter);
|
||||
}
|
||||
|
||||
parameters.GetParameter(0)
|
||||
parameters[0]
|
||||
.SetType("object")
|
||||
.SetName(parentObjectParameterName)
|
||||
.SetDescription("Object")
|
||||
@@ -174,7 +173,6 @@ WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
|
||||
removedUuidAndNames.find(variable.GetPersistentUuid());
|
||||
if (existingOldVariableUuidAndName == removedUuidAndNames.end()) {
|
||||
// This is a new variable.
|
||||
changeset.addedVariableNames.insert(variableName);
|
||||
} else {
|
||||
const gd::String &oldName = existingOldVariableUuidAndName->second;
|
||||
|
||||
@@ -184,15 +182,9 @@ WholeProjectRefactorer::ComputeChangesetForVariablesContainer(
|
||||
}
|
||||
|
||||
const auto &oldVariable = oldVariablesContainer.Get(oldName);
|
||||
if (gd::WholeProjectRefactorer::HasAnyVariableTypeChanged(oldVariable,
|
||||
variable)) {
|
||||
if (gd::WholeProjectRefactorer::HasAnyVariableTypeChanged(oldVariable, variable)) {
|
||||
changeset.typeChangedVariableNames.insert(variableName);
|
||||
}
|
||||
if (oldVariable != variable
|
||||
// Mixed values are never equals, but they must not override anything.
|
||||
&& !variable.HasMixedValues()) {
|
||||
changeset.valueChangedVariableNames.insert(variableName);
|
||||
}
|
||||
|
||||
const auto &variablesRenamingChangesetNode =
|
||||
gd::WholeProjectRefactorer::ComputeChangesetForVariable(oldVariable,
|
||||
@@ -318,8 +310,8 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
|
||||
|
||||
// Rename and remove variables
|
||||
gd::EventsVariableReplacer eventsVariableReplacer(
|
||||
project.GetCurrentPlatform(), changeset, changeset.removedVariableNames,
|
||||
variablesContainer);
|
||||
project.GetCurrentPlatform(), variablesContainer,
|
||||
changeset, changeset.removedVariableNames);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
|
||||
eventsVariableReplacer);
|
||||
|
||||
@@ -329,83 +321,8 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
|
||||
// Switch types of instructions
|
||||
gd::EventsVariableInstructionTypeSwitcher
|
||||
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
|
||||
changeset.typeChangedVariableNames,
|
||||
variablesContainer);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(
|
||||
project, eventsVariableInstructionTypeSwitcher);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ApplyRefactoringForGroupVariablesContainer(
|
||||
gd::Project &project, gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::VariablesContainer &groupVariablesContainer,
|
||||
const gd::ObjectGroup &objectGroup,
|
||||
const gd::VariablesChangeset &changeset,
|
||||
const gd::SerializerElement &originalSerializedVariables) {
|
||||
|
||||
// While we support refactoring that would remove all references (actions, conditions...)
|
||||
// it's both a bit dangerous for the user and we would need to show the user what
|
||||
// will be removed before doing so. For now, just clear the removed variables so they don't
|
||||
// trigger any refactoring.
|
||||
std::unordered_set<gd::String> removedVariableNames;
|
||||
|
||||
// Rename variables in events for the objects of the group.
|
||||
for (const gd::String &objectName : objectGroup.GetAllObjectsNames()) {
|
||||
const bool hasObject = objectsContainer.HasObjectNamed(objectName);
|
||||
if (!hasObject && !globalObjectsContainer.HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
auto &object = hasObject ? objectsContainer.GetObject(objectName)
|
||||
: globalObjectsContainer.GetObject(objectName);
|
||||
auto &variablesContainer = object.GetVariables();
|
||||
|
||||
gd::EventsVariableReplacer eventsVariableReplacer(
|
||||
project.GetCurrentPlatform(), changeset,
|
||||
removedVariableNames, variablesContainer);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
|
||||
eventsVariableReplacer);
|
||||
}
|
||||
|
||||
// Rename variables in events for the group.
|
||||
gd::EventsVariableReplacer eventsVariableReplacer(
|
||||
project.GetCurrentPlatform(), changeset, removedVariableNames,
|
||||
objectGroup.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
|
||||
eventsVariableReplacer);
|
||||
|
||||
// Apply changes to objects.
|
||||
gd::GroupVariableHelper::FillMissingGroupVariablesToObjects(
|
||||
globalObjectsContainer,
|
||||
objectsContainer,
|
||||
objectGroup,
|
||||
originalSerializedVariables);
|
||||
gd::GroupVariableHelper::ApplyChangesToObjects(
|
||||
globalObjectsContainer, objectsContainer, groupVariablesContainer,
|
||||
objectGroup, changeset);
|
||||
|
||||
// Switch types of instructions for the group objects.
|
||||
for (const gd::String &objectName : objectGroup.GetAllObjectsNames()) {
|
||||
const bool hasObject = objectsContainer.HasObjectNamed(objectName);
|
||||
if (!hasObject && !globalObjectsContainer.HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
auto &object = hasObject ? objectsContainer.GetObject(objectName)
|
||||
: globalObjectsContainer.GetObject(objectName);
|
||||
auto &variablesContainer = object.GetVariables();
|
||||
|
||||
gd::EventsVariableInstructionTypeSwitcher
|
||||
eventsVariableInstructionTypeSwitcher(
|
||||
project.GetCurrentPlatform(), changeset.typeChangedVariableNames,
|
||||
variablesContainer);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(
|
||||
project, eventsVariableInstructionTypeSwitcher);
|
||||
}
|
||||
|
||||
// Switch types of instructions for the group.
|
||||
gd::EventsVariableInstructionTypeSwitcher
|
||||
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
|
||||
changeset.typeChangedVariableNames,
|
||||
objectGroup.GetName());
|
||||
variablesContainer,
|
||||
changeset.typeChangedVariableNames);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(
|
||||
project, eventsVariableInstructionTypeSwitcher);
|
||||
}
|
||||
@@ -932,8 +849,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
|
||||
oldPropertyName, newPropertyName);
|
||||
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedBehavior,
|
||||
behaviorRenamer);
|
||||
project, eventsFunctionsExtension, eventsBasedBehavior, behaviorRenamer);
|
||||
} else {
|
||||
// Properties that represent primitive values will be used through
|
||||
// their related actions/conditions/expressions. Rename these.
|
||||
@@ -1003,8 +919,7 @@ void WholeProjectRefactorer::RenameEventsBasedBehaviorSharedProperty(
|
||||
oldPropertyName, newPropertyName);
|
||||
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedBehavior,
|
||||
behaviorRenamer);
|
||||
project, eventsFunctionsExtension, eventsBasedBehavior, behaviorRenamer);
|
||||
} else {
|
||||
// Properties that represent primitive values will be used through
|
||||
// their related actions/conditions/expressions. Rename these.
|
||||
@@ -1603,7 +1518,7 @@ void WholeProjectRefactorer::DoRenameObject(
|
||||
projectBrowser.ExposeFunctions(project, objectParameterRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInScene(
|
||||
void WholeProjectRefactorer::ObjectRemovedInLayout(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &objectName) {
|
||||
auto projectScopedContainers = gd::ProjectScopedContainers::
|
||||
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
|
||||
@@ -1625,7 +1540,7 @@ void WholeProjectRefactorer::ObjectRemovedInScene(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::BehaviorsAddedToObjectInScene(
|
||||
void WholeProjectRefactorer::BehaviorsAddedToObjectInLayout(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &objectName) {
|
||||
auto projectScopedContainers = gd::ProjectScopedContainers::
|
||||
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
|
||||
@@ -1635,7 +1550,7 @@ void WholeProjectRefactorer::BehaviorsAddedToObjectInScene(
|
||||
project, layout, behaviorParameterFiller);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &oldName,
|
||||
const gd::String &newName, bool isObjectGroup) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
@@ -1726,150 +1641,81 @@ void WholeProjectRefactorer::RenameExternalEvents(gd::Project &project,
|
||||
linkEventTargetRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayerInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameLayer(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
|
||||
gd::ProjectElementRenamer projectElementRenamer(project.GetCurrentPlatform(),
|
||||
"layer", oldName, newName);
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, scene, projectElementRenamer);
|
||||
scene.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
project, layout, projectElementRenamer);
|
||||
layout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
|
||||
std::vector<gd::String> externalLayoutsNames =
|
||||
GetAssociatedExternalLayouts(project, scene);
|
||||
GetAssociatedExternalLayouts(project, layout);
|
||||
for (gd::String name : externalLayoutsNames) {
|
||||
auto &externalLayout = project.GetExternalLayout(name);
|
||||
externalLayout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayerInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
|
||||
gd::ProjectElementRenamer projectElementRenamer(project.GetCurrentPlatform(),
|
||||
"layer", oldName, newName);
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedObject,
|
||||
projectElementRenamer);
|
||||
eventsBasedObject.GetInitialInstances().MoveInstancesToLayer(oldName,
|
||||
newName);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayerEffectInScene(
|
||||
gd::Project &project, gd::Layout &scene, gd::Layer &layer,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameLayerEffect(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Layer &layer,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "layerEffectName", oldName, newName);
|
||||
projectElementRenamer.SetLayerConstraint(layer.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, scene, projectElementRenamer);
|
||||
project, layout, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayerEffectInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Layer &layer,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "layerEffectName", oldName, newName);
|
||||
projectElementRenamer.SetLayerConstraint(layer.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedObject,
|
||||
projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectAnimationInScene(
|
||||
gd::Project &project, gd::Layout &scene, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameObjectAnimation(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectAnimationName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, scene, projectElementRenamer);
|
||||
project, layout, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectAnimationInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectAnimationName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedObject,
|
||||
projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectPointInScene(
|
||||
gd::Project &project, gd::Layout &scene, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameObjectPoint(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectPointName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, scene, projectElementRenamer);
|
||||
project, layout, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectPointInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectPointName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedObject,
|
||||
projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectEffectInScene(
|
||||
gd::Project &project, gd::Layout &scene, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameObjectEffect(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectEffectName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, scene, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectEffectInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectEffectName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
|
||||
project, eventsFunctionsExtension, eventsBasedObject,
|
||||
projectElementRenamer);
|
||||
project, layout, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInEventsBasedObject(
|
||||
@@ -1947,9 +1793,10 @@ void WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
bool isObjectGroup) {
|
||||
// Object groups can't be in other groups
|
||||
if (!isObjectGroup) {
|
||||
for (std::size_t g = 0; g < project.GetObjects().GetObjectGroups().size();
|
||||
++g) {
|
||||
project.GetObjects().GetObjectGroups()[g].RenameObject(oldName, newName);
|
||||
for (std::size_t g = 0;
|
||||
g < project.GetObjects().GetObjectGroups().size(); ++g) {
|
||||
project.GetObjects().GetObjectGroups()[g].RenameObject(oldName,
|
||||
newName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1958,13 +1805,13 @@ void WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
if (layout.GetObjects().HasObjectNamed(oldName))
|
||||
continue;
|
||||
|
||||
ObjectOrGroupRenamedInScene(project, layout, oldName, newName,
|
||||
ObjectOrGroupRenamedInLayout(project, layout, oldName, newName,
|
||||
isObjectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::GlobalObjectRemoved(gd::Project &project,
|
||||
const gd::String &objectName) {
|
||||
void WholeProjectRefactorer::GlobalObjectRemoved(
|
||||
gd::Project &project, const gd::String &objectName) {
|
||||
auto &globalGroups = project.GetObjects().GetObjectGroups();
|
||||
for (std::size_t g = 0; g < globalGroups.size(); ++g) {
|
||||
globalGroups[g].RemoveObject(objectName);
|
||||
@@ -1975,7 +1822,7 @@ void WholeProjectRefactorer::GlobalObjectRemoved(gd::Project &project,
|
||||
if (layout.GetObjects().HasObjectNamed(objectName))
|
||||
continue;
|
||||
|
||||
ObjectRemovedInScene(project, layout, objectName);
|
||||
ObjectRemovedInLayout(project, layout, objectName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1986,13 +1833,13 @@ void WholeProjectRefactorer::BehaviorsAddedToGlobalObject(
|
||||
if (layout.GetObjects().HasObjectNamed(objectName))
|
||||
continue;
|
||||
|
||||
BehaviorsAddedToObjectInScene(project, layout, objectName);
|
||||
BehaviorsAddedToObjectInLayout(project, layout, objectName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RemoveLayerInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &layerName) {
|
||||
gd::Layout &scene,
|
||||
const gd::String &layerName) {
|
||||
if (layerName.empty())
|
||||
return;
|
||||
|
||||
@@ -2006,14 +1853,15 @@ void WholeProjectRefactorer::RemoveLayerInScene(gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::MergeLayersInScene(
|
||||
gd::Project &project, gd::Layout &scene, const gd::String &originLayerName,
|
||||
const gd::String &targetLayerName) {
|
||||
void WholeProjectRefactorer::MergeLayersInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &originLayerName,
|
||||
const gd::String &targetLayerName) {
|
||||
if (originLayerName == targetLayerName || originLayerName.empty())
|
||||
return;
|
||||
|
||||
scene.GetInitialInstances().MoveInstancesToLayer(originLayerName,
|
||||
targetLayerName);
|
||||
targetLayerName);
|
||||
|
||||
std::vector<gd::String> externalLayoutsNames =
|
||||
GetAssociatedExternalLayouts(project, scene);
|
||||
|
@@ -19,7 +19,6 @@ class Project;
|
||||
class Layout;
|
||||
class Layer;
|
||||
class Object;
|
||||
class ObjectGroup;
|
||||
class String;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
@@ -59,8 +58,6 @@ struct VariablesChangeset : VariablesRenamingChangesetNode {
|
||||
* would take more time than checking the instruction type is rightly set.
|
||||
*/
|
||||
std::unordered_set<gd::String> typeChangedVariableNames;
|
||||
std::unordered_set<gd::String> valueChangedVariableNames;
|
||||
std::unordered_set<gd::String> addedVariableNames;
|
||||
|
||||
bool HasRemovedVariables() { return !removedVariableNames.empty(); }
|
||||
|
||||
@@ -71,7 +68,7 @@ struct VariablesChangeset : VariablesRenamingChangesetNode {
|
||||
* \brief Tool functions to do refactoring on the whole project after
|
||||
* changes like deletion or renaming of an object.
|
||||
*
|
||||
* \TODO Ideally ObjectOrGroupRenamedInScene, ObjectRemovedInScene,
|
||||
* \TODO Ideally ObjectOrGroupRenamedInLayout, ObjectRemovedInLayout,
|
||||
* GlobalObjectOrGroupRenamed, GlobalObjectRemoved would be implemented
|
||||
* using ExposeProjectEvents.
|
||||
*/
|
||||
@@ -94,18 +91,6 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
const gd::VariablesChangeset &changeset,
|
||||
const gd::SerializerElement &originalSerializedVariables);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project according to the changes (renaming or deletion)
|
||||
* made to variables of a group.
|
||||
*/
|
||||
static void ApplyRefactoringForGroupVariablesContainer(
|
||||
gd::Project &project, gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer,
|
||||
const gd::VariablesContainer &groupVariablesContainer,
|
||||
const gd::ObjectGroup &objectGroup,
|
||||
const gd::VariablesChangeset &changeset,
|
||||
const gd::SerializerElement &originalSerializedVariables);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project **before** an events function extension is
|
||||
* renamed.
|
||||
@@ -354,103 +339,52 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
static void RenameExternalEvents(gd::Project &project,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after a layer is renamed.
|
||||
*/
|
||||
static void RenameLayerInScene(gd::Project &project, gd::Layout &scene,
|
||||
const gd::String &oldName,
|
||||
static void RenameLayer(gd::Project &project, gd::Layout &layout,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after a layer effect is renamed.
|
||||
*/
|
||||
static void RenameLayerEffect(gd::Project &project, gd::Layout &layout,
|
||||
gd::Layer &layer, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object animation is renamed.
|
||||
*/
|
||||
static void RenameObjectAnimation(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object point is renamed.
|
||||
*/
|
||||
static void RenameObjectPoint(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object effect is renamed.
|
||||
*/
|
||||
static void RenameObjectEffect(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after a layer is renamed.
|
||||
*/
|
||||
static void RenameLayerInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after a layer effect is renamed.
|
||||
*/
|
||||
static void RenameLayerEffectInScene(gd::Project &project, gd::Layout &scene,
|
||||
gd::Layer &layer,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after a layer effect is renamed.
|
||||
*/
|
||||
static void RenameLayerEffectInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Layer &layer,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object animation is renamed.
|
||||
*/
|
||||
static void RenameObjectAnimationInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object animation is renamed.
|
||||
*/
|
||||
static void RenameObjectAnimationInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object point is renamed.
|
||||
*/
|
||||
static void RenameObjectPointInScene(gd::Project &project, gd::Layout &scene,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object point is renamed.
|
||||
*/
|
||||
static void RenameObjectPointInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object effect is renamed.
|
||||
*/
|
||||
static void RenameObjectEffectInScene(gd::Project &project, gd::Layout &scene,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object effect is renamed.
|
||||
*/
|
||||
static void RenameObjectEffectInEventsBasedObject(
|
||||
gd::Project &project,
|
||||
gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
gd::EventsBasedObject &eventsBasedObject, gd::Object &object,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is renamed in a layout
|
||||
*
|
||||
* This will update the layout, all external layouts associated with it
|
||||
* and all external events associated with it.
|
||||
*/
|
||||
static void ObjectOrGroupRenamedInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName,
|
||||
bool isObjectGroup);
|
||||
static void ObjectOrGroupRenamedInLayout(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is removed in a layout
|
||||
@@ -458,8 +392,9 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
* This will update the layout, all external layouts associated with it
|
||||
* and all external events associated with it.
|
||||
*/
|
||||
static void ObjectRemovedInScene(gd::Project &project, gd::Layout &scene,
|
||||
const gd::String &objectName);
|
||||
static void ObjectRemovedInLayout(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after behaviors are added to an object in a
|
||||
@@ -469,9 +404,9 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
* The refactor is actually applied to all objects because it allow to handle
|
||||
* groups.
|
||||
*/
|
||||
static void BehaviorsAddedToObjectInScene(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &objectName);
|
||||
static void BehaviorsAddedToObjectInLayout(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &objectName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is removed in an events-based
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -32,10 +31,10 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API BehaviorConfigurationContainer {
|
||||
public:
|
||||
BehaviorConfigurationContainer() : folded(false), quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
BehaviorConfigurationContainer() : folded(false){};
|
||||
BehaviorConfigurationContainer(const gd::String& name_,
|
||||
const gd::String& type_)
|
||||
: name(name_), type(type_), folded(false), quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
: name(name_), type(type_), folded(false){};
|
||||
virtual ~BehaviorConfigurationContainer();
|
||||
virtual BehaviorConfigurationContainer* Clone() const { return new BehaviorConfigurationContainer(*this); }
|
||||
|
||||
@@ -115,13 +114,6 @@ class GD_CORE_API BehaviorConfigurationContainer {
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
void SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
|
||||
return quickCustomizationVisibility;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -168,7 +160,6 @@ protected:
|
||||
|
||||
gd::SerializerElement content; // Storage for the behavior properties
|
||||
bool folded;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -26,7 +26,7 @@ void CustomConfigurationHelper::InitializeContent(
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior" ||
|
||||
propertyType == "Resource") {
|
||||
propertyType == "resource") {
|
||||
element.SetStringValue(property->GetValue());
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(property->GetValue().To<double>());
|
||||
@@ -39,21 +39,21 @@ void CustomConfigurationHelper::InitializeContent(
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomConfigurationHelper::GetProperties(
|
||||
const gd::PropertiesContainer &properties,
|
||||
const gd::SerializerElement &configurationContent) {
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
auto behaviorProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
|
||||
for (auto &property : properties.GetInternalVector()) {
|
||||
const auto &propertyName = property->GetName();
|
||||
const auto &propertyType = property->GetType();
|
||||
|
||||
// Copy the property
|
||||
objectProperties[propertyName] = *property;
|
||||
behaviorProperties[propertyName] = *property;
|
||||
|
||||
auto &newProperty = objectProperties[propertyName];
|
||||
auto &newProperty = behaviorProperties[propertyName];
|
||||
|
||||
if (configurationContent.HasChild(propertyName)) {
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior" ||
|
||||
propertyType == "Resource") {
|
||||
propertyType == "resource") {
|
||||
newProperty.SetValue(
|
||||
configurationContent.GetChild(propertyName).GetStringValue());
|
||||
} else if (propertyType == "Number") {
|
||||
@@ -71,7 +71,7 @@ std::map<gd::String, gd::PropertyDescriptor> CustomConfigurationHelper::GetPrope
|
||||
}
|
||||
}
|
||||
|
||||
return objectProperties;
|
||||
return behaviorProperties;
|
||||
}
|
||||
|
||||
bool CustomConfigurationHelper::UpdateProperty(
|
||||
@@ -89,7 +89,7 @@ bool CustomConfigurationHelper::UpdateProperty(
|
||||
|
||||
if (propertyType == "String" || propertyType == "Choice" ||
|
||||
propertyType == "Color" || propertyType == "Behavior" ||
|
||||
propertyType == "Resource") {
|
||||
propertyType == "resource") {
|
||||
element.SetStringValue(newValue);
|
||||
} else if (propertyType == "Number") {
|
||||
element.SetDoubleValue(newValue.To<double>());
|
||||
|
@@ -21,9 +21,6 @@ void CustomObjectConfiguration::Init(const gd::CustomObjectConfiguration& object
|
||||
project = objectConfiguration.project;
|
||||
objectContent = objectConfiguration.objectContent;
|
||||
animations = objectConfiguration.animations;
|
||||
isMarkedAsOverridingEventsBasedObjectChildrenConfiguration =
|
||||
objectConfiguration
|
||||
.isMarkedAsOverridingEventsBasedObjectChildrenConfiguration;
|
||||
|
||||
// There is no default copy for a map of unique_ptr like childObjectConfigurations.
|
||||
childObjectConfigurations.clear();
|
||||
@@ -45,26 +42,6 @@ const gd::EventsBasedObject* CustomObjectConfiguration::GetEventsBasedObject() c
|
||||
return &project->GetEventsBasedObject(GetType());
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::
|
||||
IsForcedToOverrideEventsBasedObjectChildrenConfiguration() const {
|
||||
const auto *eventsBasedObject = GetEventsBasedObject();
|
||||
if (!eventsBasedObject) {
|
||||
// True is safer because nothing will be lost when serializing.
|
||||
return true;
|
||||
}
|
||||
return eventsBasedObject->GetInitialInstances().GetInstancesCount() == 0;
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::
|
||||
IsOverridingEventsBasedObjectChildrenConfiguration() const {
|
||||
return isMarkedAsOverridingEventsBasedObjectChildrenConfiguration ||
|
||||
IsForcedToOverrideEventsBasedObjectChildrenConfiguration();
|
||||
}
|
||||
|
||||
void CustomObjectConfiguration::ClearChildrenConfiguration() {
|
||||
childObjectConfigurations.clear();
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(const gd::String &objectName) {
|
||||
const auto *eventsBasedObject = GetEventsBasedObject();
|
||||
if (!eventsBasedObject) {
|
||||
@@ -78,18 +55,6 @@ gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(
|
||||
}
|
||||
|
||||
auto &childObject = eventsBasedObject->GetObjects().GetObject(objectName);
|
||||
|
||||
if (!IsOverridingEventsBasedObjectChildrenConfiguration()) {
|
||||
// It should be fine because the editor doesn't allow to edit values when
|
||||
// the default values from the events-based object is used.
|
||||
//
|
||||
// Resource refactor operations may modify it but they will do the same
|
||||
// thing on the custom object as on the event-based object children so it
|
||||
// shouldn't have any side effect.
|
||||
return const_cast<gd::ObjectConfiguration &>(
|
||||
childObject.GetConfiguration());
|
||||
}
|
||||
|
||||
auto configurationPosition = childObjectConfigurations.find(objectName);
|
||||
if (configurationPosition == childObjectConfigurations.end()) {
|
||||
childObjectConfigurations.insert(std::make_pair(
|
||||
@@ -102,7 +67,7 @@ gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(
|
||||
auto &configuration = pair.second;
|
||||
return *configuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> CustomObjectConfiguration::GetProperties() const {
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
@@ -163,14 +128,26 @@ void CustomObjectConfiguration::DoSerializeTo(SerializerElement& element) const
|
||||
animations.SerializeTo(animatableElement);
|
||||
}
|
||||
|
||||
if (IsOverridingEventsBasedObjectChildrenConfiguration()) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
const auto *eventsBasedObject = GetEventsBasedObject();
|
||||
if (eventsBasedObject) {
|
||||
eventsBasedObject->GetInitialInstances().SerializeTo(
|
||||
element.AddChild("instances"));
|
||||
eventsBasedObject->GetLayers().SerializeLayersTo(
|
||||
element.AddChild("layers"));
|
||||
element.SetIntAttribute("areaMinX", eventsBasedObject->GetAreaMinX());
|
||||
element.SetIntAttribute("areaMinY", eventsBasedObject->GetAreaMinY());
|
||||
element.SetIntAttribute("areaMinZ", eventsBasedObject->GetAreaMinZ());
|
||||
element.SetIntAttribute("areaMaxX", eventsBasedObject->GetAreaMaxX());
|
||||
element.SetIntAttribute("areaMaxY", eventsBasedObject->GetAreaMaxY());
|
||||
element.SetIntAttribute("areaMaxZ", eventsBasedObject->GetAreaMaxZ());
|
||||
}
|
||||
}
|
||||
void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
@@ -182,16 +159,12 @@ void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
animations.UnserializeFrom(animatableElement);
|
||||
}
|
||||
|
||||
isMarkedAsOverridingEventsBasedObjectChildrenConfiguration =
|
||||
element.HasChild("childrenContent");
|
||||
if (isMarkedAsOverridingEventsBasedObjectChildrenConfiguration) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,20 +224,6 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t CustomObjectConfiguration::GetAnimationsCount() const {
|
||||
return animations.GetAnimationsCount();
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
CustomObjectConfiguration::GetAnimationName(size_t index) const {
|
||||
return animations.GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool CustomObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return animations.HasAnimationNamed(name);
|
||||
}
|
||||
|
||||
const SpriteAnimationList& CustomObjectConfiguration::GetAnimations() const {
|
||||
return animations;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ namespace gd {
|
||||
class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
public:
|
||||
CustomObjectConfiguration(const Project& project_, const String& type_)
|
||||
: project(&project_), isMarkedAsOverridingEventsBasedObjectChildrenConfiguration(false) {
|
||||
: project(&project_) {
|
||||
SetType(type_);
|
||||
}
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override;
|
||||
@@ -65,28 +65,7 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
bool IsForcedToOverrideEventsBasedObjectChildrenConfiguration() const;
|
||||
|
||||
bool IsMarkedAsOverridingEventsBasedObjectChildrenConfiguration() const {
|
||||
return isMarkedAsOverridingEventsBasedObjectChildrenConfiguration;
|
||||
}
|
||||
|
||||
void SetMarkedAsOverridingEventsBasedObjectChildrenConfiguration(
|
||||
bool isOverridingEventsBasedObjectChildrenConfiguration_) {
|
||||
isMarkedAsOverridingEventsBasedObjectChildrenConfiguration =
|
||||
isOverridingEventsBasedObjectChildrenConfiguration_;
|
||||
}
|
||||
|
||||
void ClearChildrenConfiguration();
|
||||
|
||||
gd::ObjectConfiguration &
|
||||
GetChildObjectConfiguration(const gd::String &objectName);
|
||||
|
||||
std::size_t GetAnimationsCount() const override;
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
gd::ObjectConfiguration &GetChildObjectConfiguration(const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* \brief Return the animation configuration for Animatable custom objects.
|
||||
@@ -105,14 +84,10 @@ protected:
|
||||
private:
|
||||
const gd::EventsBasedObject* GetEventsBasedObject() const;
|
||||
|
||||
bool IsOverridingEventsBasedObjectChildrenConfiguration() const;
|
||||
|
||||
const Project* project; ///< The project is used to get the
|
||||
///< EventBasedObject from the fullType.
|
||||
gd::SerializerElement objectContent;
|
||||
|
||||
bool isMarkedAsOverridingEventsBasedObjectChildrenConfiguration;
|
||||
mutable std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
|
||||
static gd::ObjectConfiguration badObjectConfiguration;
|
||||
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EventsBasedBehavior.h"
|
||||
|
||||
#include "EventsFunctionsContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
@@ -13,10 +12,9 @@ namespace gd {
|
||||
|
||||
EventsBasedBehavior::EventsBasedBehavior()
|
||||
: AbstractEventsBasedEntity(
|
||||
"MyBehavior", gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
sharedPropertyDescriptors(
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
"MyBehavior",
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
sharedPropertyDescriptors(gd::EventsFunctionsContainer::FunctionOwner::Behavior) {}
|
||||
|
||||
void EventsBasedBehavior::SerializeTo(SerializerElement& element) const {
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
@@ -26,13 +24,6 @@ void EventsBasedBehavior::SerializeTo(SerializerElement& element) const {
|
||||
}
|
||||
sharedPropertyDescriptors.SerializeElementsTo(
|
||||
"propertyDescriptor", element.AddChild("sharedPropertyDescriptors"));
|
||||
if (quickCustomizationVisibility != QuickCustomization::Visibility::Default) {
|
||||
element.SetStringAttribute(
|
||||
"quickCustomizationVisibility",
|
||||
quickCustomizationVisibility == QuickCustomization::Visibility::Visible
|
||||
? "visible"
|
||||
: "hidden");
|
||||
}
|
||||
}
|
||||
|
||||
void EventsBasedBehavior::UnserializeFrom(gd::Project& project,
|
||||
@@ -42,14 +33,6 @@ void EventsBasedBehavior::UnserializeFrom(gd::Project& project,
|
||||
isPrivate = element.GetBoolAttribute("private");
|
||||
sharedPropertyDescriptors.UnserializeElementsFrom(
|
||||
"propertyDescriptor", element.GetChild("sharedPropertyDescriptors"));
|
||||
if (element.HasChild("quickCustomizationVisibility")) {
|
||||
quickCustomizationVisibility =
|
||||
element.GetStringAttribute("quickCustomizationVisibility") == "visible"
|
||||
? QuickCustomization::Visibility::Visible
|
||||
: QuickCustomization::Visibility::Hidden;
|
||||
} else {
|
||||
quickCustomizationVisibility = QuickCustomization::Visibility::Default;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include "GDCore/Project/NamedPropertyDescriptor.h"
|
||||
#include "GDCore/Project/PropertiesContainer.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
@@ -89,15 +88,6 @@ class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
return *this;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
|
||||
return quickCustomizationVisibility;
|
||||
}
|
||||
|
||||
EventsBasedBehavior& SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the list of shared properties.
|
||||
*/
|
||||
@@ -151,7 +141,6 @@ class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
gd::String objectType;
|
||||
bool isPrivate = false;
|
||||
gd::PropertiesContainer sharedPropertyDescriptors;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -16,7 +16,6 @@ EventsBasedObject::EventsBasedObject()
|
||||
isRenderedIn3D(false),
|
||||
isAnimatable(false),
|
||||
isTextContainer(false),
|
||||
isInnerAreaFollowingParentSize(false),
|
||||
areaMinX(0),
|
||||
areaMinY(0),
|
||||
areaMinZ(0),
|
||||
@@ -38,9 +37,6 @@ void EventsBasedObject::SerializeTo(SerializerElement& element) const {
|
||||
if (isTextContainer) {
|
||||
element.SetBoolAttribute("isTextContainer", true);
|
||||
}
|
||||
if (isInnerAreaFollowingParentSize) {
|
||||
element.SetBoolAttribute("isInnerAreaFollowingParentSize", true);
|
||||
}
|
||||
element.SetIntAttribute("areaMinX", areaMinX);
|
||||
element.SetIntAttribute("areaMinY", areaMinY);
|
||||
element.SetIntAttribute("areaMinZ", areaMinZ);
|
||||
@@ -63,8 +59,6 @@ void EventsBasedObject::UnserializeFrom(gd::Project& project,
|
||||
isRenderedIn3D = element.GetBoolAttribute("is3D", false);
|
||||
isAnimatable = element.GetBoolAttribute("isAnimatable", false);
|
||||
isTextContainer = element.GetBoolAttribute("isTextContainer", false);
|
||||
isInnerAreaFollowingParentSize =
|
||||
element.GetBoolAttribute("isInnerAreaFollowingParentSize", false);
|
||||
areaMinX = element.GetIntAttribute("areaMinX", 0);
|
||||
areaMinY = element.GetIntAttribute("areaMinY", 0);
|
||||
areaMinZ = element.GetIntAttribute("areaMinZ", 0);
|
||||
|
@@ -101,35 +101,11 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity {
|
||||
/**
|
||||
* \brief Declare a TextContainer capability.
|
||||
*/
|
||||
EventsBasedObject &MarkAsTextContainer(bool isTextContainer_) {
|
||||
EventsBasedObject& MarkAsTextContainer(bool isTextContainer_) {
|
||||
isTextContainer = isTextContainer_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Declare that the parent scale will always be 1 and children will
|
||||
* adapt there size. This is removing the ScalableCapability.
|
||||
*/
|
||||
EventsBasedObject &
|
||||
MarkAsInnerAreaExpandingWithParent(bool isInnerAreaExpandingWithParent_) {
|
||||
isInnerAreaFollowingParentSize = isInnerAreaExpandingWithParent_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if objects handle size changes on their own and
|
||||
* don't have the ScalableCapability.
|
||||
*
|
||||
* When the parent dimensions change:
|
||||
* - if `false`, the object is stretch proportionally while children local
|
||||
* positions stay the same.
|
||||
* - if `true`, the children local positions need to be adapted by events
|
||||
* to follow their parent size.
|
||||
*/
|
||||
bool IsInnerAreaFollowingParentSize() const {
|
||||
return isInnerAreaFollowingParentSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the object needs a TextContainer capability.
|
||||
*/
|
||||
@@ -303,7 +279,6 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity {
|
||||
bool isRenderedIn3D;
|
||||
bool isAnimatable;
|
||||
bool isTextContainer;
|
||||
bool isInnerAreaFollowingParentSize;
|
||||
gd::InitialInstancesContainer initialInstances;
|
||||
gd::LayersContainer layers;
|
||||
gd::ObjectsContainer objectsContainer;
|
||||
|
@@ -16,41 +16,41 @@ EventsFunction::EventsFunction() : functionType(Action) {
|
||||
expressionType.SetName("expression");
|
||||
}
|
||||
|
||||
const gd::ParameterMetadataContainer &EventsFunction::GetParametersForEvents(
|
||||
const gd::EventsFunctionsContainer &functionsContainer) const {
|
||||
const std::vector<gd::ParameterMetadata>& EventsFunction::GetParametersForEvents(
|
||||
const gd::EventsFunctionsContainer& functionsContainer) const {
|
||||
if (functionType != FunctionType::ActionWithOperator) {
|
||||
// For most function types, the parameters are specified in the function.
|
||||
return parameters;
|
||||
}
|
||||
// For ActionWithOperator, the parameters are auto generated.
|
||||
actionWithOperationParameters.ClearParameters();
|
||||
actionWithOperationParameters.clear();
|
||||
if (!functionsContainer.HasEventsFunctionNamed(getterName)) {
|
||||
return actionWithOperationParameters;
|
||||
}
|
||||
const auto &expression = functionsContainer.GetEventsFunction(getterName);
|
||||
const auto &expressionParameters = expression.parameters;
|
||||
const auto& expression = functionsContainer.GetEventsFunction(getterName);
|
||||
const auto& expressionParameters = expression.parameters;
|
||||
const auto functionsSource = functionsContainer.GetOwner();
|
||||
const int expressionValueParameterIndex =
|
||||
functionsSource == gd::EventsFunctionsContainer::FunctionOwner::Behavior
|
||||
? 2
|
||||
: functionsSource == gd::EventsFunctionsContainer::FunctionOwner::Object
|
||||
? 1
|
||||
: 0;
|
||||
|
||||
for (size_t i = 0; i < expressionValueParameterIndex &&
|
||||
i < expressionParameters.GetParametersCount();
|
||||
i++) {
|
||||
actionWithOperationParameters.AddParameter(
|
||||
expressionParameters.GetParameter(i));
|
||||
functionsSource == gd::EventsFunctionsContainer::FunctionOwner::Behavior ?
|
||||
2 :
|
||||
functionsSource == gd::EventsFunctionsContainer::FunctionOwner::Object ?
|
||||
1 :
|
||||
0;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < expressionValueParameterIndex && i < expressionParameters.size();
|
||||
i++)
|
||||
{
|
||||
actionWithOperationParameters.push_back(expressionParameters[i]);
|
||||
}
|
||||
gd::ParameterMetadata parameterMetadata;
|
||||
parameterMetadata.SetName("Value").SetValueTypeMetadata(
|
||||
expression.expressionType);
|
||||
actionWithOperationParameters.AddParameter(parameterMetadata);
|
||||
parameterMetadata.SetName("Value").SetValueTypeMetadata(expression.expressionType);
|
||||
actionWithOperationParameters.push_back(parameterMetadata);
|
||||
for (size_t i = expressionValueParameterIndex;
|
||||
i < expressionParameters.GetParametersCount(); i++) {
|
||||
actionWithOperationParameters.AddParameter(
|
||||
expressionParameters.GetParameter(i));
|
||||
i < expressionParameters.size();
|
||||
i++)
|
||||
{
|
||||
actionWithOperationParameters.push_back(expressionParameters[i]);
|
||||
}
|
||||
|
||||
return actionWithOperationParameters;
|
||||
@@ -101,7 +101,10 @@ void EventsFunction::SerializeTo(SerializerElement& element) const {
|
||||
expressionType.SerializeTo(element.AddChild("expressionType"));
|
||||
}
|
||||
gd::SerializerElement& parametersElement = element.AddChild("parameters");
|
||||
parameters.SerializeParametersTo(parametersElement);
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (const auto& parameter : parameters) {
|
||||
parameter.SerializeTo(parametersElement.AddChild("parameter"));
|
||||
}
|
||||
|
||||
objectGroups.SerializeTo(element.AddChild("objectGroups"));
|
||||
}
|
||||
@@ -143,9 +146,15 @@ void EventsFunction::UnserializeFrom(gd::Project& project,
|
||||
else
|
||||
functionType = Action;
|
||||
|
||||
const gd::SerializerElement ¶metersElement =
|
||||
const gd::SerializerElement& parametersElement =
|
||||
element.GetChild("parameters");
|
||||
parameters.UnserializeParametersFrom(parametersElement);
|
||||
parameters.clear();
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i) {
|
||||
ParameterMetadata parameter;
|
||||
parameter.UnserializeFrom(parametersElement.GetChild(i));
|
||||
parameters.push_back(parameter);
|
||||
}
|
||||
|
||||
objectGroups.UnserializeFrom(element.GetChild("objectGroups"));
|
||||
}
|
||||
|
@@ -3,13 +3,14 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EVENTSFUNCTION_H
|
||||
#define GDCORE_EVENTSFUNCTION_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ParameterMetadataContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Extensions/Metadata/ValueTypeMetadata.h"
|
||||
// TODO: In theory (for separation of concerns between Project and
|
||||
@@ -240,7 +241,7 @@ class GD_CORE_API EventsFunction {
|
||||
* to the generated function, like "runtimeScene" and "eventsFunctionContext".
|
||||
* This should be transparent to the user.
|
||||
*/
|
||||
const gd::ParameterMetadataContainer& GetParametersForEvents(
|
||||
const std::vector<gd::ParameterMetadata>& GetParametersForEvents(
|
||||
const gd::EventsFunctionsContainer& functionsContainer) const;
|
||||
|
||||
/**
|
||||
@@ -253,14 +254,14 @@ class GD_CORE_API EventsFunction {
|
||||
* to the generated function, like "runtimeScene" and "eventsFunctionContext".
|
||||
* This should be transparent to the user.
|
||||
*/
|
||||
const ParameterMetadataContainer& GetParameters() const {
|
||||
const std::vector<gd::ParameterMetadata>& GetParameters() const {
|
||||
return parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the parameters.
|
||||
*/
|
||||
ParameterMetadataContainer& GetParameters() { return parameters; };
|
||||
std::vector<gd::ParameterMetadata>& GetParameters() { return parameters; };
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the object groups that can be used in the
|
||||
@@ -299,11 +300,14 @@ class GD_CORE_API EventsFunction {
|
||||
gd::ValueTypeMetadata expressionType;
|
||||
gd::EventsList events;
|
||||
FunctionType functionType;
|
||||
ParameterMetadataContainer parameters;
|
||||
mutable gd::ParameterMetadataContainer actionWithOperationParameters;
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
mutable std::vector<gd::ParameterMetadata> actionWithOperationParameters;
|
||||
gd::ObjectGroupsContainer objectGroups;
|
||||
bool isPrivate = false;
|
||||
bool isAsync = false;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSFUNCTION_H
|
||||
#endif
|
||||
|
@@ -14,7 +14,6 @@
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
gd::String ObjectConfiguration::badAnimationName;
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
|
@@ -165,36 +165,7 @@ class GD_CORE_API ObjectConfiguration {
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
/** \name Animations
|
||||
* Members functions related to object animations
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Return the number of animations declared in this object
|
||||
* configuration.
|
||||
*/
|
||||
virtual size_t GetAnimationsCount() const {
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the name of an animation declared in this object
|
||||
* configuration.
|
||||
*/
|
||||
virtual const gd::String &GetAnimationName(size_t index) const {
|
||||
return badAnimationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if an animation is declared in this object
|
||||
* configuration for a given name.
|
||||
*/
|
||||
virtual bool HasAnimationNamed(const gd::String &animationName) const {
|
||||
return false;
|
||||
}
|
||||
///@}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
|
||||
@@ -210,9 +181,6 @@ protected:
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
|
||||
private:
|
||||
static gd::String badAnimationName;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -19,20 +19,13 @@ namespace gd {
|
||||
ObjectFolderOrObject ObjectFolderOrObject::badObjectFolderOrObject;
|
||||
|
||||
ObjectFolderOrObject::ObjectFolderOrObject()
|
||||
: folderName("__NULL"),
|
||||
object(nullptr),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
: folderName("__NULL"), object(nullptr) {}
|
||||
ObjectFolderOrObject::ObjectFolderOrObject(gd::String folderName_,
|
||||
ObjectFolderOrObject* parent_)
|
||||
: folderName(folderName_),
|
||||
parent(parent_),
|
||||
object(nullptr),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
: folderName(folderName_), parent(parent_), object(nullptr) {}
|
||||
ObjectFolderOrObject::ObjectFolderOrObject(gd::Object* object_,
|
||||
ObjectFolderOrObject* parent_)
|
||||
: object(object_),
|
||||
parent(parent_),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
: object(object_), parent(parent_) {}
|
||||
ObjectFolderOrObject::~ObjectFolderOrObject() {}
|
||||
|
||||
bool ObjectFolderOrObject::HasObjectNamed(const gd::String& name) {
|
||||
@@ -73,8 +66,7 @@ ObjectFolderOrObject& ObjectFolderOrObject::GetChildAt(std::size_t index) {
|
||||
if (index >= children.size()) return badObjectFolderOrObject;
|
||||
return *children[index];
|
||||
}
|
||||
const ObjectFolderOrObject& ObjectFolderOrObject::GetChildAt(
|
||||
std::size_t index) const {
|
||||
const ObjectFolderOrObject& ObjectFolderOrObject::GetChildAt(std::size_t index) const {
|
||||
if (index >= children.size()) return badObjectFolderOrObject;
|
||||
return *children[index];
|
||||
}
|
||||
@@ -214,14 +206,6 @@ void ObjectFolderOrObject::SerializeTo(SerializerElement& element) const {
|
||||
} else {
|
||||
element.SetAttribute("objectName", GetObject().GetName());
|
||||
}
|
||||
|
||||
if (quickCustomizationVisibility != QuickCustomization::Visibility::Default) {
|
||||
element.SetStringAttribute(
|
||||
"quickCustomizationVisibility",
|
||||
quickCustomizationVisibility == QuickCustomization::Visibility::Visible
|
||||
? "visible"
|
||||
: "hidden");
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFolderOrObject::UnserializeFrom(
|
||||
@@ -259,15 +243,6 @@ void ObjectFolderOrObject::UnserializeFrom(
|
||||
object = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (element.HasChild("quickCustomizationVisibility")) {
|
||||
quickCustomizationVisibility =
|
||||
element.GetStringAttribute("quickCustomizationVisibility") == "visible"
|
||||
? QuickCustomization::Visibility::Visible
|
||||
: QuickCustomization::Visibility::Hidden;
|
||||
} else {
|
||||
quickCustomizationVisibility = QuickCustomization::Visibility::Default;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
@@ -167,11 +166,6 @@ class GD_CORE_API ObjectFolderOrObject {
|
||||
gd::ObjectFolderOrObject& newParentFolder,
|
||||
std::size_t newPosition);
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const { return quickCustomizationVisibility; }
|
||||
void SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
}
|
||||
|
||||
/** \name Saving and loading
|
||||
* Members functions related to saving and loading the objects of the class.
|
||||
*/
|
||||
@@ -194,7 +188,6 @@ class GD_CORE_API ObjectFolderOrObject {
|
||||
|
||||
gd::ObjectFolderOrObject*
|
||||
parent; // nullptr if root folder, points to the parent folder otherwise.
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
|
||||
// Representing an object:
|
||||
gd::Object* object; // nullptr if folderName is set.
|
||||
|
@@ -73,15 +73,6 @@ bool ObjectsContainersList::HasObjectNamed(const gd::String& name) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gd::Object* ObjectsContainersList::GetObject(const gd::String& name) const {
|
||||
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
|
||||
++it) {
|
||||
if ((*it)->HasObjectNamed(name)) return &(*it)->GetObject(name);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ObjectsContainersList::VariableExistence
|
||||
ObjectsContainersList::HasObjectOrGroupWithVariableNamed(
|
||||
const gd::String& objectOrGroupName, const gd::String& variableName) const {
|
||||
@@ -377,7 +368,7 @@ std::vector<gd::String> ObjectsContainersList::ExpandObjectName(
|
||||
}
|
||||
|
||||
// Ensure that all returned objects actually exists (i.e: if some groups have
|
||||
// names referring to non existing objects, don't return them).
|
||||
// names refering to non existing objects, don't return them).
|
||||
for (std::size_t i = 0; i < realObjects.size();) {
|
||||
if (!HasObjectNamed(realObjects[i]))
|
||||
realObjects.erase(realObjects.begin() + i);
|
||||
@@ -530,72 +521,4 @@ std::vector<gd::String> ObjectsContainersList::GetBehaviorsOfObject(
|
||||
*objectsContainers[0], *objectsContainers[1], objectName, searchInGroups);
|
||||
}
|
||||
|
||||
std::vector<gd::String> ObjectsContainersList::GetAnimationNamesOfObject(
|
||||
const gd::String &objectOrGroupName) const {
|
||||
std::vector<gd::String> animationNames;
|
||||
|
||||
for (auto it = objectsContainers.rbegin(); it != objectsContainers.rend();
|
||||
++it) {
|
||||
if ((*it)->HasObjectNamed(objectOrGroupName)) {
|
||||
const auto &objectConfiguration =
|
||||
(*it)->GetObject(objectOrGroupName).GetConfiguration();
|
||||
|
||||
for (size_t index = 0; index < objectConfiguration.GetAnimationsCount();
|
||||
index++) {
|
||||
animationNames.push_back(objectConfiguration.GetAnimationName(index));
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
if ((*it)->GetObjectGroups().Has(objectOrGroupName)) {
|
||||
const auto &objectGroup = (*it)->GetObjectGroups().Get(objectOrGroupName);
|
||||
const auto &objectNames = objectGroup.GetAllObjectsNames();
|
||||
|
||||
std::size_t objectIndex = 0;
|
||||
bool isFirstObjectFound = false;
|
||||
for (; objectIndex < objectNames.size() && !isFirstObjectFound;
|
||||
objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
isFirstObjectFound = true;
|
||||
const auto &objectConfiguration =
|
||||
GetObject(objectName)->GetConfiguration();
|
||||
for (size_t index = 0; index < objectConfiguration.GetAnimationsCount();
|
||||
index++) {
|
||||
animationNames.push_back(objectConfiguration.GetAnimationName(index));
|
||||
}
|
||||
}
|
||||
for (; objectIndex < objectNames.size(); objectIndex++) {
|
||||
const gd::String &objectName = objectNames[objectIndex];
|
||||
if (!HasObjectNamed(objectName)) {
|
||||
continue;
|
||||
}
|
||||
const auto &objectConfiguration =
|
||||
GetObject(objectName)->GetConfiguration();
|
||||
|
||||
for (size_t animationIndex = 0; animationIndex < animationNames.size();
|
||||
animationIndex++) {
|
||||
if (!objectConfiguration.HasAnimationNamed(
|
||||
animationNames[animationIndex])) {
|
||||
animationNames.erase(animationNames.begin() + animationIndex);
|
||||
animationIndex--;
|
||||
}
|
||||
}
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
}
|
||||
return animationNames;
|
||||
}
|
||||
|
||||
const gd::ObjectsContainer &
|
||||
ObjectsContainersList::GetObjectsContainer(std::size_t index) const {
|
||||
return *objectsContainers[index];
|
||||
}
|
||||
|
||||
std::size_t ObjectsContainersList::GetObjectsContainersCount() const {
|
||||
return objectsContainers.size();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -129,17 +129,7 @@ class GD_CORE_API ObjectsContainersList {
|
||||
const gd::String& objectName, bool searchInGroups = true) const;
|
||||
|
||||
/**
|
||||
* \brief Get the animation names of an object/group.
|
||||
* \note The animation names of a group are the animation names common to
|
||||
* every object of the group.
|
||||
*
|
||||
* @return The names of animations
|
||||
*/
|
||||
std::vector<gd::String>
|
||||
GetAnimationNamesOfObject(const gd::String &objectOrGroupName) const;
|
||||
|
||||
/**
|
||||
* \brief Return a list containing all objects referred to by the group.
|
||||
* \brief Return a list containing all objects refered to by the group.
|
||||
* If an object name is passed, then only this object name is returned.
|
||||
*
|
||||
* If \a onlyObjectToSelectIfPresent is set and present in the group(s),
|
||||
@@ -173,16 +163,6 @@ class GD_CORE_API ObjectsContainersList {
|
||||
std::function<void(const gd::String& variableName,
|
||||
const gd::Variable& variable)> fn) const;
|
||||
|
||||
/**
|
||||
* \brief Return a the objects container at position \a index.
|
||||
*/
|
||||
const gd::ObjectsContainer &GetObjectsContainer(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* \brief Return the number of objects containers.
|
||||
*/
|
||||
std::size_t GetObjectsContainersCount() const;
|
||||
|
||||
/** Do not use - should be private but accessible to let Emscripten create a
|
||||
* temporary. */
|
||||
ObjectsContainersList(){};
|
||||
@@ -190,8 +170,6 @@ class GD_CORE_API ObjectsContainersList {
|
||||
private:
|
||||
bool HasObjectNamed(const gd::String& name) const;
|
||||
|
||||
const gd::Object* GetObject(const gd::String& name) const;
|
||||
|
||||
bool HasObjectWithVariableNamed(const gd::String& objectName,
|
||||
const gd::String& variableName) const;
|
||||
|
||||
|
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/SerializableWithNameList.h"
|
||||
#include <vector>
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Used as a base class for classes that will own events-backed
|
||||
* functions.
|
||||
*
|
||||
* \see gd::ParameterMetadata
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API ParameterMetadataContainer
|
||||
: private SerializableWithNameList<gd::ParameterMetadata> {
|
||||
public:
|
||||
ParameterMetadataContainer() {}
|
||||
|
||||
/** \name Events Functions management
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Check if the function with the specified name exists.
|
||||
*/
|
||||
bool HasParameterNamed(const gd::String &name) const { return Has(name); }
|
||||
|
||||
/**
|
||||
* \brief Get the function with the specified name.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
gd::ParameterMetadata &GetParameter(const gd::String &name) {
|
||||
return Get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the function with the specified name.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
const gd::ParameterMetadata &GetParameter(const gd::String &name) const {
|
||||
return Get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the function at the specified index in the list.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
gd::ParameterMetadata &GetParameter(std::size_t index) { return Get(index); }
|
||||
|
||||
/**
|
||||
* \brief Get the function at the specified index in the list.
|
||||
*
|
||||
* \warning Trying to access to a not existing function will result in
|
||||
* undefined behavior.
|
||||
*/
|
||||
const gd::ParameterMetadata &GetParameter(std::size_t index) const {
|
||||
return Get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the number of functions.
|
||||
*/
|
||||
std::size_t GetParametersCount() const { return GetCount(); }
|
||||
|
||||
gd::ParameterMetadata &InsertNewParameter(const gd::String &name,
|
||||
std::size_t position) {
|
||||
return InsertNew(name, position);
|
||||
}
|
||||
gd::ParameterMetadata &InsertParameter(const gd::ParameterMetadata &object,
|
||||
std::size_t position) {
|
||||
return Insert(object, position);
|
||||
}
|
||||
gd::ParameterMetadata &AddNewParameter(const gd::String &name) {
|
||||
return InsertNew(name, GetCount());
|
||||
}
|
||||
gd::ParameterMetadata &AddParameter(const gd::ParameterMetadata &object) {
|
||||
return Insert(object, GetCount());
|
||||
}
|
||||
void RemoveParameter(const gd::String &name) { return Remove(name); }
|
||||
void ClearParameters() { return Clear(); }
|
||||
void MoveParameter(std::size_t oldIndex, std::size_t newIndex) {
|
||||
return Move(oldIndex, newIndex);
|
||||
};
|
||||
std::size_t
|
||||
GetParameterPosition(const gd::ParameterMetadata ¶meterMetadata) {
|
||||
return GetPosition(parameterMetadata);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Provide a raw access to the vector containing the functions.
|
||||
*/
|
||||
const std::vector<std::unique_ptr<gd::ParameterMetadata>> &
|
||||
GetInternalVector() const {
|
||||
return elements;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Provide a raw access to the vector containing the functions.
|
||||
*/
|
||||
std::vector<std::unique_ptr<gd::ParameterMetadata>> &GetInternalVector() {
|
||||
return elements;
|
||||
};
|
||||
///@}
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize events functions.
|
||||
*/
|
||||
void SerializeParametersTo(SerializerElement &element) const {
|
||||
return SerializeElementsTo("parameters", element);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Unserialize the events functions.
|
||||
*/
|
||||
void UnserializeParametersFrom(const SerializerElement &element) {
|
||||
return UnserializeElementsFrom("parameters", element);
|
||||
};
|
||||
///@}
|
||||
protected:
|
||||
/**
|
||||
* Initialize object using another object. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const gd::ParameterMetadataContainer &other) {
|
||||
return SerializableWithNameList<gd::ParameterMetadata>::Init(other);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -13,7 +13,6 @@ class ObjectsContainersList;
|
||||
class VariablesContainersList;
|
||||
class PropertiesContainersList;
|
||||
class NamedPropertyDescriptor;
|
||||
class ParameterMetadataContainer;
|
||||
class BaseEvent;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
@@ -132,7 +131,7 @@ class ProjectScopedContainers {
|
||||
}
|
||||
|
||||
ProjectScopedContainers &AddParameters(
|
||||
const ParameterMetadataContainer ¶meters) {
|
||||
const std::vector<gd::ParameterMetadata> ¶meters) {
|
||||
parametersVectorsList.push_back(¶meters);
|
||||
|
||||
return *this;
|
||||
@@ -225,7 +224,7 @@ class ProjectScopedContainers {
|
||||
return propertiesContainersList;
|
||||
};
|
||||
|
||||
const std::vector<const ParameterMetadataContainer *> &GetParametersVectorsList() const {
|
||||
const std::vector<const std::vector<gd::ParameterMetadata> *> &GetParametersVectorsList() const {
|
||||
return parametersVectorsList;
|
||||
};
|
||||
|
||||
@@ -237,7 +236,7 @@ class ProjectScopedContainers {
|
||||
gd::ObjectsContainersList objectsContainersList;
|
||||
gd::VariablesContainersList variablesContainersList;
|
||||
gd::PropertiesContainersList propertiesContainersList;
|
||||
std::vector<const ParameterMetadataContainer *> parametersVectorsList;
|
||||
std::vector<const std::vector<gd::ParameterMetadata> *> parametersVectorsList;
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -38,13 +38,6 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
|
||||
if (advanced) {
|
||||
element.AddChild("advanced").SetBoolValue(advanced);
|
||||
}
|
||||
if (quickCustomizationVisibility != QuickCustomization::Visibility::Default) {
|
||||
element.AddChild("quickCustomizationVisibility")
|
||||
.SetStringValue(quickCustomizationVisibility ==
|
||||
QuickCustomization::Visibility::Visible
|
||||
? "visible"
|
||||
: "hidden");
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
@@ -74,21 +67,11 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
? element.GetChild("hidden").GetBoolValue()
|
||||
: false;
|
||||
deprecated = element.HasChild("deprecated")
|
||||
? element.GetChild("deprecated").GetBoolValue()
|
||||
: false;
|
||||
? element.GetChild("deprecated").GetBoolValue()
|
||||
: false;
|
||||
advanced = element.HasChild("advanced")
|
||||
? element.GetChild("advanced").GetBoolValue()
|
||||
: false;
|
||||
|
||||
if (element.HasChild("quickCustomizationVisibility")) {
|
||||
quickCustomizationVisibility =
|
||||
element.GetChild("quickCustomizationVisibility").GetStringValue() ==
|
||||
"visible"
|
||||
? QuickCustomization::Visibility::Visible
|
||||
: QuickCustomization::Visibility::Hidden;
|
||||
} else {
|
||||
quickCustomizationVisibility = QuickCustomization::Visibility::Default;
|
||||
}
|
||||
? element.GetChild("advanced").GetBoolValue()
|
||||
: false;
|
||||
}
|
||||
|
||||
void PropertyDescriptor::SerializeValuesTo(SerializerElement& element) const {
|
||||
|
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/MeasurementUnit.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
@@ -33,16 +32,14 @@ class GD_CORE_API PropertyDescriptor {
|
||||
PropertyDescriptor(gd::String propertyValue)
|
||||
: currentValue(propertyValue), type("string"), label(""), hidden(false),
|
||||
deprecated(false), advanced(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()) {}
|
||||
|
||||
/**
|
||||
* \brief Empty constructor creating an empty property to be displayed.
|
||||
*/
|
||||
PropertyDescriptor()
|
||||
: hidden(false), deprecated(false), advanced(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()){};
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
@@ -112,7 +109,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
extraInformation.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Change the unit of measurement of the property value.
|
||||
*/
|
||||
@@ -131,7 +128,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
const std::vector<gd::String>& GetExtraInfo() const {
|
||||
return extraInformation;
|
||||
}
|
||||
|
||||
|
||||
std::vector<gd::String>& GetExtraInfo() {
|
||||
return extraInformation;
|
||||
}
|
||||
@@ -175,13 +172,6 @@ class GD_CORE_API PropertyDescriptor {
|
||||
*/
|
||||
bool IsAdvanced() const { return advanced; }
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const { return quickCustomizationVisibility; }
|
||||
|
||||
PropertyDescriptor& SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
@@ -222,7 +212,6 @@ class GD_CORE_API PropertyDescriptor {
|
||||
bool deprecated;
|
||||
bool advanced;
|
||||
gd::MeasurementUnit measurementUnit; //< The unit of measurement of the property vale.
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -1,16 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace gd {
|
||||
class QuickCustomization {
|
||||
public:
|
||||
enum Visibility {
|
||||
/** Visibility based on the parent or editor heuristics (probably visible). */
|
||||
Default,
|
||||
/** Visible in the quick customization editor. */
|
||||
Visible,
|
||||
/** Not visible in the quick customization editor. */
|
||||
Hidden
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -30,8 +30,6 @@ gd::String Variable::TypeAsString(Type t) {
|
||||
return "structure";
|
||||
case Type::Array:
|
||||
return "array";
|
||||
case Type::MixedTypes:
|
||||
return "mixed";
|
||||
default:
|
||||
return "error-type";
|
||||
}
|
||||
@@ -48,8 +46,6 @@ Variable::Type Variable::StringAsType(const gd::String& str) {
|
||||
return Type::Structure;
|
||||
else if (str == "array")
|
||||
return Type::Array;
|
||||
else if (str == "mixed")
|
||||
return Type::MixedTypes;
|
||||
|
||||
// Default to number
|
||||
return Type::Number;
|
||||
@@ -60,7 +56,6 @@ bool Variable::IsPrimitive(const Type type) {
|
||||
}
|
||||
|
||||
void Variable::CastTo(const Type newType) {
|
||||
hasMixedValues = false;
|
||||
if (newType == Type::Number)
|
||||
SetValue(GetValue());
|
||||
else if (newType == Type::String)
|
||||
@@ -90,9 +85,6 @@ void Variable::CastTo(const Type newType) {
|
||||
type = Type::Array;
|
||||
// Free now unused memory
|
||||
children.clear();
|
||||
} else if (newType == Type::MixedTypes) {
|
||||
type = Type::MixedTypes;
|
||||
hasMixedValues = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +142,6 @@ Variable& Variable::GetChild(const gd::String& name) {
|
||||
if (it != children.end()) return *it->second;
|
||||
|
||||
type = Type::Structure;
|
||||
hasMixedValues = false;
|
||||
children[name] = std::make_shared<gd::Variable>();
|
||||
return *children[name];
|
||||
}
|
||||
@@ -211,7 +202,6 @@ Variable& Variable::PushNew() {
|
||||
const size_t count = GetChildrenCount();
|
||||
auto& variable = GetAtIndex(count);
|
||||
if (type == Type::Array && count > 0) {
|
||||
hasMixedValues = false;
|
||||
const auto childType = GetAtIndex(count - 1).type;
|
||||
variable.type = childType;
|
||||
if (childType == Type::Number) {
|
||||
@@ -234,7 +224,6 @@ void Variable::RemoveAtIndex(const size_t index) {
|
||||
|
||||
bool Variable::InsertAtIndex(const gd::Variable& variable, const size_t index) {
|
||||
if (type != Type::Array) return false;
|
||||
hasMixedValues = false;
|
||||
auto newVariable = std::make_shared<gd::Variable>(variable);
|
||||
if (index < childrenArray.size()) {
|
||||
childrenArray.insert(childrenArray.begin() + index, newVariable);
|
||||
@@ -249,7 +238,6 @@ bool Variable::InsertChild(const gd::String& name,
|
||||
if (type != Type::Structure || HasChild(name)) {
|
||||
return false;
|
||||
}
|
||||
hasMixedValues = false;
|
||||
children[name] = std::make_shared<gd::Variable>(variable);
|
||||
return true;
|
||||
};
|
||||
@@ -282,9 +270,6 @@ void Variable::SerializeTo(SerializerElement& element) const {
|
||||
child->SerializeTo(childrenElement.AddChild("variable"));
|
||||
}
|
||||
}
|
||||
if (hasMixedValues) {
|
||||
element.SetBoolAttribute("hasMixedValues", true);
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
@@ -328,9 +313,6 @@ void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
PushNew().UnserializeFrom(childElement);
|
||||
}
|
||||
}
|
||||
if (element.GetBoolAttribute("hasMixedValues", false)) {
|
||||
MarkAsMixedValues();
|
||||
}
|
||||
}
|
||||
|
||||
Variable& Variable::ResetPersistentUuid() {
|
||||
@@ -402,8 +384,7 @@ Variable::Variable(const Variable& other)
|
||||
folded(other.folded),
|
||||
boolVal(other.boolVal),
|
||||
type(other.type),
|
||||
persistentUuid(other.persistentUuid),
|
||||
hasMixedValues(other.hasMixedValues) {
|
||||
persistentUuid(other.persistentUuid) {
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
@@ -415,7 +396,6 @@ Variable& Variable::operator=(const Variable& other) {
|
||||
boolVal = other.boolVal;
|
||||
type = other.type;
|
||||
persistentUuid = other.persistentUuid;
|
||||
hasMixedValues = other.hasMixedValues;
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
@@ -431,61 +411,4 @@ void Variable::CopyChildren(const gd::Variable& other) {
|
||||
childrenArray.push_back(std::make_shared<gd::Variable>(*child.get()));
|
||||
}
|
||||
}
|
||||
|
||||
bool Variable::operator==(const gd::Variable &variable) const {
|
||||
if (type != variable.type || hasMixedValues || variable.hasMixedValues) {
|
||||
return false;
|
||||
}
|
||||
if (type == Variable::Type::Number) {
|
||||
return value == variable.value;
|
||||
}
|
||||
if (type == Variable::Type::String) {
|
||||
return str == variable.str;
|
||||
}
|
||||
if (type == Variable::Type::Boolean) {
|
||||
return boolVal == variable.boolVal;
|
||||
}
|
||||
if (type == Variable::Type::Structure) {
|
||||
if (children.size() != variable.children.size()) {
|
||||
return false;
|
||||
}
|
||||
for (auto &pair : children) {
|
||||
const gd::String &name = pair.first;
|
||||
const auto &child = pair.second;
|
||||
|
||||
auto it = variable.children.find(name);
|
||||
if (it == variable.children.end()) {
|
||||
return false;
|
||||
}
|
||||
auto &otherChild = it->second;
|
||||
if (*child != *otherChild) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (type == Variable::Type::Array) {
|
||||
if (childrenArray.size() != variable.childrenArray.size()) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < childrenArray.size(); ++i) {
|
||||
if (*childrenArray[i] != *variable.childrenArray[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// MixedTypes variables can't equal another variable.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Variable::operator!=(const gd::Variable &variable) const {
|
||||
return !(*this == variable);
|
||||
}
|
||||
|
||||
void Variable::MarkAsMixedValues() {
|
||||
hasMixedValues = true;
|
||||
ClearChildren();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef GDCORE_VARIABLE_H
|
||||
#define GDCORE_VARIABLE_H
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -31,8 +31,6 @@ class GD_CORE_API Variable {
|
||||
static gd::Variable badVariable;
|
||||
enum Type {
|
||||
Unknown,
|
||||
/** Used when objects of a group have different types for a variable. */
|
||||
MixedTypes,
|
||||
|
||||
// Primitive types
|
||||
String,
|
||||
@@ -52,7 +50,7 @@ class GD_CORE_API Variable {
|
||||
/**
|
||||
* \brief Default constructor creating a variable with 0 as value.
|
||||
*/
|
||||
Variable() : value(0), type(Type::Number), hasMixedValues(false) {};
|
||||
Variable() : value(0), type(Type::Number){};
|
||||
Variable(const Variable&);
|
||||
virtual ~Variable(){};
|
||||
|
||||
@@ -89,7 +87,6 @@ class GD_CORE_API Variable {
|
||||
void SetString(const gd::String& newStr) {
|
||||
str = newStr;
|
||||
type = Type::String;
|
||||
hasMixedValues = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,7 +102,6 @@ class GD_CORE_API Variable {
|
||||
// NaN values are not supported by GDevelop nor the serializer.
|
||||
if (std::isnan(value)) value = 0.0;
|
||||
type = Type::Number;
|
||||
hasMixedValues = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,23 +115,8 @@ class GD_CORE_API Variable {
|
||||
void SetBool(bool val) {
|
||||
boolVal = val;
|
||||
type = Type::Boolean;
|
||||
hasMixedValues = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true when objects of a group have different values for a
|
||||
* variable.
|
||||
*/
|
||||
bool HasMixedValues() const {
|
||||
return hasMixedValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true when objects of a group have different values for a
|
||||
* variable.
|
||||
*/
|
||||
void MarkAsMixedValues();
|
||||
|
||||
// Operators are overloaded to allow accessing to variable using a simple
|
||||
// int-like semantic.
|
||||
void operator=(double val) { SetValue(val); };
|
||||
@@ -187,9 +168,6 @@ class GD_CORE_API Variable {
|
||||
bool operator==(const bool val) const { return GetBool() == val; };
|
||||
bool operator!=(const bool val) const { return GetBool() != val; };
|
||||
|
||||
bool operator==(const gd::Variable& variable) const;
|
||||
bool operator!=(const gd::Variable& variable) const;
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Collection types
|
||||
@@ -398,7 +376,6 @@ class GD_CORE_API Variable {
|
||||
mutable gd::String str;
|
||||
mutable double value;
|
||||
mutable bool boolVal;
|
||||
mutable bool hasMixedValues;
|
||||
mutable std::map<gd::String, std::shared_ptr<Variable>>
|
||||
children; ///< Children, when the variable is considered as a structure.
|
||||
mutable std::vector<std::shared_ptr<Variable>>
|
||||
@@ -415,3 +392,5 @@ class GD_CORE_API Variable {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_VARIABLE_H
|
||||
|
@@ -323,7 +323,6 @@ class GD_CORE_API SerializerElement {
|
||||
gd::String deprecatedName = "") const;
|
||||
|
||||
/**
|
||||
* \deprecated Use HasChild instead. This should be removed from the codebase.
|
||||
* \brief Return true if the specified attribute exists.
|
||||
* \param name The name of the attribute to find.
|
||||
*/
|
||||
|
1
Core/GDCore/Tools/.gitignore
vendored
1
Core/GDCore/Tools/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
VersionPriv.h
|
8
Core/GDCore/Tools/VersionPriv.h
Normal file
8
Core/GDCore/Tools/VersionPriv.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// Deprecated version number that was used for GDevelop 4, but still
|
||||
// used to version the project files.
|
||||
// Might be a good idea to refactor this at some point to make it
|
||||
// clearer this is used for the versioning of the project files.
|
||||
#define GD_VERSION_STRING "4.0.99-0-release"
|
||||
#define GD_VERSION_RC 4,0,99,0-0-release
|
||||
#define GD_VERSION_RC_STRING "4, 0, 99, 0-0-release\0"
|
||||
#define GD_DATE_STRING __DATE__
|
@@ -24,6 +24,15 @@ int VersionWrapper::Revision() {
|
||||
: 0;
|
||||
}
|
||||
gd::String VersionWrapper::FullString() { return GD_VERSION_STRING; }
|
||||
gd::String VersionWrapper::Date() {
|
||||
return gd::String(GD_DATE_STRING).substr(4, 2);
|
||||
}
|
||||
gd::String VersionWrapper::Month() {
|
||||
return gd::String(GD_DATE_STRING).substr(0, 3);
|
||||
}
|
||||
gd::String VersionWrapper::Year() {
|
||||
return gd::String(GD_DATE_STRING).substr(7, 4);
|
||||
}
|
||||
gd::String VersionWrapper::Status() {
|
||||
return Revision() == 0 ? "Release" : "Dev";
|
||||
}
|
||||
|
@@ -46,6 +46,21 @@ class GD_CORE_API VersionWrapper {
|
||||
*/
|
||||
static gd::String Status();
|
||||
|
||||
/**
|
||||
* \brief Get Year of the release
|
||||
*/
|
||||
static gd::String Year();
|
||||
|
||||
/**
|
||||
* \brief Get Month of the release
|
||||
*/
|
||||
static gd::String Month();
|
||||
|
||||
/**
|
||||
* \brief Get Day of the release
|
||||
*/
|
||||
static gd::String Date();
|
||||
|
||||
/**
|
||||
* \brief Return true if the first version is older
|
||||
* than the second version.
|
||||
|
@@ -527,9 +527,15 @@ TEST_CASE("ExpressionCodeGenerator", "[common][events]") {
|
||||
}
|
||||
}
|
||||
SECTION("Parameters (1 level)") {
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("string");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("string");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -562,10 +568,19 @@ TEST_CASE("ExpressionCodeGenerator", "[common][events]") {
|
||||
}
|
||||
}
|
||||
SECTION("Parameters (1 level, number|string)") {
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyNumberParameter", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyStringParameter", 1).SetType("string");
|
||||
parameters.InsertNewParameter("MyBooleanParameter", 2).SetType("yesorno");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyNumberParameter");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyStringParameter");
|
||||
param2.SetType("string");
|
||||
gd::ParameterMetadata param3;
|
||||
param3.SetName("MyBooleanParameter");
|
||||
param3.SetType("yesorno");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
parameters.push_back(param3);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
|
@@ -55,8 +55,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object or expression completions when type is string") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("string", "My", 0, 2).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -67,8 +67,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object or expression completions when type is number") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, number, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, number, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("number", "My", 0, 2).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -79,8 +79,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object or expression completions when type is number|string") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, number|string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, number|string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("number|string", "My", 0, 2).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -94,8 +94,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object or expression completions in a variable name") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("string", "My", 0, 2).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -115,8 +115,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object or expression completions in a variable index") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, number, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, number, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("number", "My", 0, 2).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -136,7 +136,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object when type is an object") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, object, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 0, object, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
};
|
||||
// clang-format on
|
||||
REQUIRE(getCompletionsFor("object", "My", 0) == expectedCompletions);
|
||||
@@ -149,7 +149,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
// result in different code generation):
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, objectPtr, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 0, objectPtr, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
};
|
||||
// clang-format on
|
||||
REQUIRE(getCompletionsFor("objectPtr", "My", 0) == expectedCompletions);
|
||||
@@ -204,8 +204,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 0, unknown, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 0, unknown, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
gd::ExpressionCompletionDescription::ForExpressionWithPrefix("unknown", "My", 9, 10).ToString()
|
||||
};
|
||||
// clang-format on
|
||||
@@ -215,7 +215,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Function with a Variable as argument") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 3, no type, 3, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
};
|
||||
// clang-format on
|
||||
REQUIRE(getCompletionsFor("number",
|
||||
@@ -225,7 +225,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Object function with a Variable as argument") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedCompletions{
|
||||
"{ 3, no type, 3, no prefix, myObjectVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
"{ 3, no type, 2, no prefix, myObjectVariable, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, no object configuration }",
|
||||
};
|
||||
// clang-format on
|
||||
REQUIRE(getCompletionsFor("number",
|
||||
@@ -254,7 +254,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test with string type") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorOrFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("Func", 9, 13, "MyObject").ToString(),
|
||||
@@ -277,7 +277,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test with 'number|string' type") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, number|string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, number|string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorOrFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("Func", 9, 13, "MyObject").ToString(),
|
||||
@@ -303,7 +303,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test 1") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorOrFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("Func", 9, 13, "MyObject").ToString(),
|
||||
@@ -336,7 +336,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test 1") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("MyBehavior", 9, 19, "MyObject").ToString()};
|
||||
@@ -366,7 +366,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test 2") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("MyBehavior", 9, 19, "MyObject").ToString()
|
||||
@@ -396,7 +396,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
SECTION("Test 1") {
|
||||
// clang-format off
|
||||
std::vector<gd::String> expectedObjectCompletions{
|
||||
"{ 0, string, 3, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
"{ 0, string, 2, no prefix, MyObject, no object name, no behavior name, non-exact, not last parameter, no parameter metadata, with object configuration }"
|
||||
};
|
||||
std::vector<gd::String> expectedBehaviorCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehaviorWithPrefix("MyBehavior", 9, 19, "MyObject").ToString()
|
||||
|
@@ -1031,10 +1031,25 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
SECTION("Numbers and texts mismatches ('number|string' type, with a parameter first)") {
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyNumberParameter", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyStringParameter", 1).SetType("string");
|
||||
parameters.InsertNewParameter("MyBooleanParameter", 2).SetType("yesorno");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyNumberParameter");
|
||||
param.SetType("number");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyStringParameter");
|
||||
param.SetType("string");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyBooleanParameter");
|
||||
param.SetType("yesorno");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -2002,10 +2017,19 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
|
||||
SECTION("Valid parameter") {
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("string");
|
||||
parameters.InsertNewParameter("MyParameter3", 2).SetType("yesorno");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("string");
|
||||
gd::ParameterMetadata param3;
|
||||
param3.SetName("MyParameter3");
|
||||
param3.SetType("yesorno");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
parameters.push_back(param3);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -2074,9 +2098,15 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
|
||||
SECTION("Invalid parameter (wrong type)") {
|
||||
{
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("audioResource");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("audioResource");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -2093,9 +2123,15 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
|
||||
SECTION("Invalid parameter (non existing name)") {
|
||||
{
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("string");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("string");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -2112,9 +2148,15 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
|
||||
SECTION("Invalid parameter (unsupported child syntax, 1 level)") {
|
||||
{
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("string");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("string");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -2130,9 +2172,15 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
SECTION("Invalid parameter (unsupported child syntax, 2 levels)") {
|
||||
{
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyParameter2", 1).SetType("string");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
gd::ParameterMetadata param1;
|
||||
param1.SetName("MyParameter1");
|
||||
param1.SetType("number");
|
||||
gd::ParameterMetadata param2;
|
||||
param2.SetName("MyParameter2");
|
||||
param2.SetType("string");
|
||||
parameters.push_back(param1);
|
||||
parameters.push_back(param2);
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
@@ -3056,10 +3104,25 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
}
|
||||
}
|
||||
SECTION("Valid type inferred from expressions with type 'number|string', with a parameter first") {
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
parameters.InsertNewParameter("MyNumberParameter", 0).SetType("number");
|
||||
parameters.InsertNewParameter("MyStringParameter", 1).SetType("string");
|
||||
parameters.InsertNewParameter("MyBooleanParameter", 2).SetType("yesorno");
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyNumberParameter");
|
||||
param.SetType("number");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyStringParameter");
|
||||
param.SetType("string");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
{
|
||||
gd::ParameterMetadata param;
|
||||
param.SetName("MyBooleanParameter");
|
||||
param.SetType("yesorno");
|
||||
parameters.push_back(param);
|
||||
}
|
||||
|
||||
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
|
||||
projectScopedContainersWithParameters.AddParameters(parameters);
|
||||
|
136
Core/tests/Layout.cpp
Normal file
136
Core/tests/Layout.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering layout content helper methods.
|
||||
*/
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace gd;
|
||||
|
||||
TEST_CASE("Layout", "[common]") {
|
||||
|
||||
SECTION("Find the type of a behavior in a object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyObject", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an object that doesn't have the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyObject", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Find the type of a behavior in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Give an empty type for a group with an object missing the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
// object2 doesn't have the behavior.
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for a group with behaviors of same name but "
|
||||
"different types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyBehavior");
|
||||
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group =
|
||||
layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
REQUIRE(GetTypeOfBehaviorInObjectOrGroup(
|
||||
project.GetObjects(), layout.GetObjects(),
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
}
|
@@ -1,488 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering layout content helper methods.
|
||||
*/
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace gd;
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasObjectOrGroupNamed)", "[common]") {
|
||||
|
||||
SECTION("Can check an object exists") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupNamed("MyObject"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupNamed("MyWrongObject"));
|
||||
}
|
||||
|
||||
SECTION("Can check a group exists") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupNamed("MyGroup"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasObjectOrGroupWithVariableNamed)", "[common]") {
|
||||
|
||||
SECTION("Can check a variable exists in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.GetVariables().InsertNew("MyVariable", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupWithVariableNamed("MyObject", "MyVariable"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupWithVariableNamed("MyObject", "MyWrongVariable"));
|
||||
}
|
||||
|
||||
SECTION("Can check a variable exists in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.GetVariables().InsertNew("MyVariable", 0);
|
||||
// This variable is only in one of the 2 objects.
|
||||
object1.GetVariables().InsertNew("MyOtherVariable", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object1.GetVariables().InsertNew("MyVariable", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasObjectOrGroupWithVariableNamed("MyGroup", "MyVariable"));
|
||||
REQUIRE(!objectsContainersList.HasObjectOrGroupWithVariableNamed("MyGroup", "MyWrongVariable"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetTypeOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the type of an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyObject") == "MyExtension::Sprite");
|
||||
}
|
||||
|
||||
SECTION("Find the object type of a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyGroup") == "MyExtension::Sprite");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for groups with mixed object types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "FakeObjectWithDefaultBehavior", "MyObject2", 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject("MyGroup") == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfObject(
|
||||
"MyGroup") == "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetTypeOfBehaviorInObjectOrGroup)",
|
||||
"[common]") {
|
||||
|
||||
SECTION("Find the type of a behavior in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyObject", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an object that doesn't have the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyObject", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Find the type of a behavior in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "MyExtension::MyBehavior");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Give an empty type for a group with an object missing the behavior") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
// object2 doesn't have the behavior.
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for a group with behaviors of same name but different types") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
|
||||
SECTION("Give an empty type for an empty group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.GetTypeOfBehaviorInObjectOrGroup(
|
||||
"MyGroup", "MyBehavior", true) == "");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (HasBehaviorInObjectOrGroup)", "[common]") {
|
||||
|
||||
SECTION("Can check a behavior exists in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasBehaviorInObjectOrGroup("MyObject", "MyBehavior"));
|
||||
REQUIRE(!objectsContainersList.HasBehaviorInObjectOrGroup("MyObject", "MyWrongBehavior"));
|
||||
}
|
||||
|
||||
SECTION("Can check a behavior exists in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
// This behavior is only in one of the 2 objects.
|
||||
object1.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyOtherBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
REQUIRE(objectsContainersList.HasBehaviorInObjectOrGroup("MyGroup", "MyBehavior"));
|
||||
REQUIRE(!objectsContainersList.HasBehaviorInObjectOrGroup("MyGroup", "MyOtherBehavior"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetBehaviorsOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the behaviors in an object") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject", 0);
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto behaviors =
|
||||
objectsContainersList.GetBehaviorsOfObject("MyObject", true);
|
||||
REQUIRE(behaviors.size() == 1);
|
||||
REQUIRE(behaviors[0] == "MyBehavior");
|
||||
}
|
||||
|
||||
SECTION("Find the behaviors in a group") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object &object1 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject1", 0);
|
||||
object1.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
// This behavior is only in one of the 2 objects.
|
||||
object1.AddNewBehavior(project, "MyExtension::MyOtherBehavior",
|
||||
"MyOtherBehavior");
|
||||
gd::Object &object2 = layout.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MyObject2", 0);
|
||||
object2.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto behaviors =
|
||||
objectsContainersList.GetBehaviorsOfObject("MyGroup", true);
|
||||
REQUIRE(behaviors.size() == 1);
|
||||
REQUIRE(behaviors[0] == "MyBehavior");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
gd::SpriteObject BuildSpriteWithAnimations(gd::String animationName1 = "!",
|
||||
gd::String animationName2 = "!",
|
||||
gd::String animationName3 = "!") {
|
||||
gd::SpriteObject configuration;
|
||||
gd::SpriteAnimationList &animations = configuration.GetAnimations();
|
||||
if (animationName1 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName1);
|
||||
animations.AddAnimation(animation);
|
||||
if (animationName2 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName2);
|
||||
animations.AddAnimation(animation);
|
||||
}
|
||||
if (animationName3 != "!") {
|
||||
gd::Animation animation;
|
||||
animation.SetName(animationName3);
|
||||
animations.AddAnimation(animation);
|
||||
}
|
||||
}
|
||||
return configuration;
|
||||
}
|
||||
|
||||
bool Contains(const std::vector<gd::String> &vector, const gd::String &value) {
|
||||
return std::find(vector.begin(), vector.end(), value) !=
|
||||
vector.end();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("ObjectContainersList (GetAnimationNamesOfObject)", "[common]") {
|
||||
|
||||
SECTION("Find the animation names in a sprite") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object object("MyObject", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Idle", "Run")));
|
||||
layout.GetObjects().InsertObject(object, 0);
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto animationNames =
|
||||
objectsContainersList.GetAnimationNamesOfObject("MyObject");
|
||||
REQUIRE(Contains(animationNames, "Idle"));
|
||||
REQUIRE(Contains(animationNames, "Run"));
|
||||
REQUIRE(animationNames.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("Find the animation names in a group of sprite") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
||||
gd::Object object1("MyObject1", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Idle", "Jump", "Run")));
|
||||
layout.GetObjects().InsertObject(object1, 0);
|
||||
gd::Object object2("MyObject2", "Sprite",
|
||||
gd::make_unique<gd::SpriteObject>(
|
||||
BuildSpriteWithAnimations("Run", "Idle", "Climb")));
|
||||
layout.GetObjects().InsertObject(object2, 0);
|
||||
|
||||
auto &group = layout.GetObjects().GetObjectGroups().InsertNew("MyGroup", 0);
|
||||
group.AddObject(object1.GetName());
|
||||
group.AddObject(object2.GetName());
|
||||
|
||||
auto objectsContainersList = gd::ObjectsContainersList::
|
||||
MakeNewObjectsContainersListForProjectAndLayout(project, layout);
|
||||
|
||||
const auto animationNames =
|
||||
objectsContainersList.GetAnimationNamesOfObject("MyGroup");
|
||||
REQUIRE(Contains(animationNames, "Idle"));
|
||||
REQUIRE(Contains(animationNames, "Run"));
|
||||
REQUIRE(animationNames.size() == 2);
|
||||
}
|
||||
}
|
@@ -79,7 +79,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
"angle of the trajectory direction.");
|
||||
REQUIRE(getter.GetSentence() == "the movement angle");
|
||||
// Object and behavior parameters are added automatically.
|
||||
REQUIRE(getter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(getter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(getter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(getter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -106,7 +106,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
REQUIRE(setter.GetDescription() == "");
|
||||
REQUIRE(setter.GetSentence() == "");
|
||||
// Object and behavior parameters are added automatically.
|
||||
REQUIRE(setter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(setter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(setter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(setter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -195,7 +195,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
"this behavior only.");
|
||||
REQUIRE(getter.GetSentence() == "_PARAM0_ rotate object");
|
||||
// Object and behavior parameters are added automatically.
|
||||
REQUIRE(getter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(getter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(getter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(getter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -232,16 +232,16 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
REQUIRE(setter.GetSentence() == "_PARAM0_ rotate object: _PARAM2_");
|
||||
// To generate the value parameter, object and behavior parameters has to
|
||||
// be declared too.
|
||||
REQUIRE(setter.GetParameters().GetParametersCount() == 3);
|
||||
auto &objectParameter = setter.GetParameters().GetParameter(0);
|
||||
REQUIRE(setter.GetParameters().size() == 3);
|
||||
auto &objectParameter = setter.GetParameters().at(0);
|
||||
REQUIRE(objectParameter.GetName() == "Object");
|
||||
REQUIRE(objectParameter.GetType() == "object");
|
||||
auto &behaviorParameter = setter.GetParameters().GetParameter(1);
|
||||
auto &behaviorParameter = setter.GetParameters().at(1);
|
||||
REQUIRE(behaviorParameter.GetName() == "Behavior");
|
||||
REQUIRE(behaviorParameter.GetType() == "behavior");
|
||||
REQUIRE(behaviorParameter.GetExtraInfo() ==
|
||||
"MyEventsExtension::MyEventsBasedBehavior");
|
||||
auto &valueParameter = setter.GetParameters().GetParameter(2);
|
||||
auto &valueParameter = setter.GetParameters().at(2);
|
||||
REQUIRE(valueParameter.GetName() == "Value");
|
||||
REQUIRE(valueParameter.GetType() == "yesorno");
|
||||
|
||||
@@ -329,7 +329,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
"angle of the trajectory direction.");
|
||||
REQUIRE(getter.GetSentence() == "the movement angle");
|
||||
// Object parameter is added automatically.
|
||||
REQUIRE(getter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(getter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(getter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(getter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -356,7 +356,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
REQUIRE(setter.GetDescription() == "");
|
||||
REQUIRE(setter.GetSentence() == "");
|
||||
// Object parameter is added automatically.
|
||||
REQUIRE(setter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(setter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(setter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(setter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -443,7 +443,7 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
"this object.");
|
||||
REQUIRE(getter.GetSentence() == "_PARAM0_ rotate object");
|
||||
// The Object parameter is added automatically.
|
||||
REQUIRE(getter.GetParameters().GetParametersCount() == 0);
|
||||
REQUIRE(getter.GetParameters().size() == 0);
|
||||
|
||||
REQUIRE(getter.GetEvents().GetEventsCount() == 1);
|
||||
REQUIRE(getter.GetEvents().GetEvent(0).GetType() ==
|
||||
@@ -478,13 +478,13 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
|
||||
REQUIRE(setter.GetSentence() == "_PARAM0_ rotate object: _PARAM1_");
|
||||
// To generate the value parameter, the object parameter has to
|
||||
// be declared too.
|
||||
REQUIRE(setter.GetParameters().GetParametersCount() == 2);
|
||||
auto &objectParameter = setter.GetParameters().GetParameter(0);
|
||||
REQUIRE(setter.GetParameters().size() == 2);
|
||||
auto &objectParameter = setter.GetParameters().at(0);
|
||||
REQUIRE(objectParameter.GetName() == "Object");
|
||||
REQUIRE(objectParameter.GetType() == "object");
|
||||
REQUIRE(objectParameter.GetExtraInfo() ==
|
||||
"MyEventsExtension::MyEventsBasedObject");
|
||||
auto &valueParameter = setter.GetParameters().GetParameter(1);
|
||||
auto &valueParameter = setter.GetParameters().at(1);
|
||||
REQUIRE(valueParameter.GetName() == "Value");
|
||||
REQUIRE(valueParameter.GetType() == "yesorno");
|
||||
|
||||
|
@@ -91,49 +91,4 @@ TEST_CASE("Variable", "[common][variables]") {
|
||||
"Hello second copied World");
|
||||
REQUIRE(variable3.GetChild("Child2").GetValue() == 44);
|
||||
}
|
||||
SECTION("Can find identical number variables") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(123);
|
||||
|
||||
gd::Variable otherVariable;
|
||||
otherVariable.SetValue(123);
|
||||
|
||||
REQUIRE(variable == otherVariable);
|
||||
}
|
||||
SECTION("Can find different number variables") {
|
||||
gd::Variable variable;
|
||||
variable.SetValue(123);
|
||||
|
||||
gd::Variable otherVariable;
|
||||
otherVariable.SetValue(456);
|
||||
|
||||
REQUIRE(variable != otherVariable);
|
||||
}
|
||||
SECTION("Can find identical structure variables") {
|
||||
gd::Variable variable;
|
||||
variable.GetChild("MyChild").SetValue(123);
|
||||
|
||||
gd::Variable otherVariable;
|
||||
otherVariable.GetChild("MyChild").SetValue(123);
|
||||
|
||||
REQUIRE(variable == otherVariable);
|
||||
}
|
||||
SECTION("Can find structure with different child value") {
|
||||
gd::Variable variable;
|
||||
variable.GetChild("MyChild").SetValue(123);
|
||||
|
||||
gd::Variable otherVariable;
|
||||
otherVariable.GetChild("MyChild").SetValue(456);
|
||||
|
||||
REQUIRE(variable != otherVariable);
|
||||
}
|
||||
SECTION("Can find structure with different child name") {
|
||||
gd::Variable variable;
|
||||
variable.GetChild("MyChild").SetValue(123);
|
||||
|
||||
gd::Variable otherVariable;
|
||||
otherVariable.GetChild("MyOtherChild").SetValue(123);
|
||||
|
||||
REQUIRE(variable != otherVariable);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -867,22 +867,26 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &behaviorEventsFunctions = eventsBasedBehavior.GetEventsFunctions();
|
||||
auto &behaviorAction = behaviorEventsFunctions.InsertNewEventsFunction(
|
||||
"MyBehaviorEventsFunction", 0);
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("Behavior", 1)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("ObjectWithMyBehavior", 2)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("OtherBehavior", 3)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Behavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("ObjectWithMyBehavior")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("OtherBehavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
auto &group = behaviorAction.GetObjectGroups().InsertNew("GroupWithMyBehavior");
|
||||
group.AddObject("ObjectWithMyBehavior");
|
||||
|
||||
@@ -890,32 +894,36 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
behaviorEventsFunctions
|
||||
.InsertNewEventsFunction("MyBehaviorEventsFunctionExpression", 1)
|
||||
.SetFunctionType(gd::EventsFunction::Expression);
|
||||
behaviorExpression.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
behaviorExpression.GetParameters()
|
||||
.InsertNewParameter("Behavior", 1)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
behaviorExpression.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
behaviorExpression.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Behavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
|
||||
auto &behaviorExpressionAndCondition =
|
||||
behaviorEventsFunctions
|
||||
.InsertNewEventsFunction("MyBehaviorEventsFunctionExpressionAndCondition", 2)
|
||||
.SetFunctionType(gd::EventsFunction::ExpressionAndCondition);
|
||||
behaviorExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object");
|
||||
behaviorExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Behavior", 1)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyExtension::MyEventsBasedBehavior");
|
||||
behaviorExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Value1", 2)
|
||||
.SetType("expression");
|
||||
behaviorExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Value2", 3)
|
||||
.SetType("expression");
|
||||
behaviorExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata().SetName("Object").SetType("object"));
|
||||
behaviorExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Behavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyExtension::MyEventsBasedBehavior"));
|
||||
behaviorExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value1")
|
||||
.SetType("expression"));
|
||||
behaviorExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value2")
|
||||
.SetType("expression"));
|
||||
|
||||
behaviorEventsFunctions
|
||||
.InsertNewEventsFunction("MyBehaviorEventsFunctionActionWithOperator", 2)
|
||||
@@ -948,41 +956,46 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
auto &objectAction = objectEventsFunctions.InsertNewEventsFunction(
|
||||
"MyObjectEventsFunction", 0);
|
||||
objectAction.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
objectAction.GetParameters()
|
||||
.InsertNewParameter("OtherObject", 1)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
objectAction.GetParameters()
|
||||
.InsertNewParameter("OtherBehavior", 2)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
objectAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
objectAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("OtherObject")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
objectAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("OtherBehavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
|
||||
auto &objectExpression =
|
||||
objectEventsFunctions
|
||||
.InsertNewEventsFunction("MyObjectEventsFunctionExpression", 1)
|
||||
.SetFunctionType(gd::EventsFunction::Expression);
|
||||
objectExpression.GetParameters().InsertNewParameter("Object", 0)
|
||||
objectExpression.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
|
||||
auto &objectExpressionAndCondition =
|
||||
objectEventsFunctions
|
||||
.InsertNewEventsFunction(
|
||||
"MyObjectEventsFunctionExpressionAndCondition", 2)
|
||||
.InsertNewEventsFunction("MyObjectEventsFunctionExpressionAndCondition", 2)
|
||||
.SetFunctionType(gd::EventsFunction::ExpressionAndCondition);
|
||||
objectExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object");
|
||||
objectExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Value1", 1)
|
||||
.SetType("expression");
|
||||
objectExpressionAndCondition.GetParameters()
|
||||
.InsertNewParameter("Value2", 2)
|
||||
.SetType("expression");
|
||||
objectExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata().SetName("Object").SetType("object"));
|
||||
objectExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value1")
|
||||
.SetType("expression"));
|
||||
objectExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value2")
|
||||
.SetType("expression"));
|
||||
|
||||
objectEventsFunctions
|
||||
.InsertNewEventsFunction("MyObjectEventsFunctionActionWithOperator", 2)
|
||||
@@ -1009,27 +1022,32 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &behaviorEventsFunctions = eventsBasedBehavior.GetEventsFunctions();
|
||||
auto &behaviorAction = behaviorEventsFunctions.InsertNewEventsFunction(
|
||||
"MyBehaviorEventsFunction", 0);
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("Behavior", 1)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Behavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
// Define the same objects as in the layout to be consistent with events.
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("ObjectWithMyBehavior", 2)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyExtension::Sprite");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("MyBehavior", 3)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
behaviorAction.GetParameters()
|
||||
.InsertNewParameter("MyCustomObject", 4)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("ObjectWithMyBehavior")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyExtension::Sprite"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("MyBehavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
behaviorAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("MyCustomObject")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
}
|
||||
|
||||
// Add an other events based object that uses previously defined events based
|
||||
@@ -1044,10 +1062,11 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
|
||||
auto &objectAction = objectEventsFunctions.InsertNewEventsFunction(
|
||||
"MyObjectEventsFunction", 0);
|
||||
objectAction.GetParameters()
|
||||
.InsertNewParameter("Object", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyOtherEventsBasedObject");
|
||||
objectAction.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyOtherEventsBasedObject"));
|
||||
|
||||
// Add a child-object with the same names the one from the scene
|
||||
// to be able to use the same events list.
|
||||
@@ -1072,33 +1091,39 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
{
|
||||
auto &action =
|
||||
eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0);
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("currentScene", 0)
|
||||
.SetType("")
|
||||
.SetCodeOnly(true);
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("Object", 1)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("Behavior", 2)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
action.GetParameters().push_back(gd::ParameterMetadata()
|
||||
.SetName("currentScene")
|
||||
.SetType("")
|
||||
.SetCodeOnly(true));
|
||||
action.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Object")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
action.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Behavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
|
||||
auto &expression =
|
||||
eventsExtension.InsertNewEventsFunction("MyEventsFunctionExpression", 1)
|
||||
.SetFunctionType(gd::EventsFunction::Expression);
|
||||
expression.GetParameters()
|
||||
.InsertNewParameter("currentScene", 0)
|
||||
.SetType("")
|
||||
.SetCodeOnly(true);
|
||||
expression.GetParameters().push_back(gd::ParameterMetadata()
|
||||
.SetName("currentScene")
|
||||
.SetType("")
|
||||
.SetCodeOnly(true));
|
||||
|
||||
auto &freeExpressionAndCondition = eventsExtension.InsertNewEventsFunction("MyEventsFunctionExpressionAndCondition", 2)
|
||||
.SetFunctionType(gd::EventsFunction::ExpressionAndCondition);
|
||||
freeExpressionAndCondition.GetParameters().InsertNewParameter("Value1", 0)
|
||||
.SetType("expression");
|
||||
freeExpressionAndCondition.GetParameters().InsertNewParameter("Value2", 1)
|
||||
.SetType("expression");
|
||||
freeExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value1")
|
||||
.SetType("expression"));
|
||||
freeExpressionAndCondition.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("Value2")
|
||||
.SetType("expression"));
|
||||
|
||||
eventsExtension.InsertNewEventsFunction("MyEventsFunctionActionWithOperator", 2)
|
||||
.SetFunctionType(gd::EventsFunction::ActionWithOperator)
|
||||
@@ -1112,18 +1137,21 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
|
||||
auto &action =
|
||||
eventsExtension.InsertNewEventsFunction("MyOtherEventsFunction", 0);
|
||||
// Define the same objects as in the layout to be consistent with events.
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("ObjectWithMyBehavior", 0)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyExtension::Sprite");
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("MyBehavior", 1)
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
|
||||
action.GetParameters()
|
||||
.InsertNewParameter("MyCustomObject", 2)
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject");
|
||||
action.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("ObjectWithMyBehavior")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyExtension::Sprite"));
|
||||
action.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("MyBehavior")
|
||||
.SetType("behavior")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior"));
|
||||
action.GetParameters().push_back(
|
||||
gd::ParameterMetadata()
|
||||
.SetName("MyCustomObject")
|
||||
.SetType("object")
|
||||
.SetExtraInfo("MyEventsExtension::MyEventsBasedObject"));
|
||||
auto &group = action.GetObjectGroups().InsertNew("GroupWithMyBehavior");
|
||||
group.AddObject("ObjectWithMyBehavior");
|
||||
}
|
||||
@@ -1200,7 +1228,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
layout1.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "Object2", 0);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInScene(project, layout1,
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInLayout(project, layout1,
|
||||
"Object1");
|
||||
gd::WholeProjectRefactorer::GlobalObjectRemoved(project, "GlobalObject1");
|
||||
REQUIRE(layout1.GetObjects().GetObjectGroups()[0].Find(
|
||||
@@ -1234,7 +1262,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
layout1.GetInitialInstances().InsertInitialInstance(instance2);
|
||||
layout1.GetInitialInstances().InsertInitialInstance(instance3);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInLayout(
|
||||
project, layout1, "Object1");
|
||||
gd::WholeProjectRefactorer::GlobalObjectRemoved(
|
||||
project, "GlobalObject1");
|
||||
@@ -1278,7 +1306,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
externalLayout2.GetInitialInstances().InsertInitialInstance(instance2);
|
||||
externalLayout2.GetInitialInstances().InsertInitialInstance(instance3);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectRemovedInLayout(
|
||||
project, layout1, "Object1");
|
||||
gd::WholeProjectRefactorer::GlobalObjectRemoved(
|
||||
project, "GlobalObject1");
|
||||
@@ -1316,7 +1344,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
layout1.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "Object2", 0);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout1, "Object1", "Object3", /* isObjectGroup =*/false);
|
||||
gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false);
|
||||
@@ -1353,7 +1381,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
layout1.GetInitialInstances().InsertInitialInstance(instance2);
|
||||
layout1.GetInitialInstances().InsertInitialInstance(instance3);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout1, "Object1", "Object3", /* isObjectGroup =*/false);
|
||||
gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false);
|
||||
@@ -1399,7 +1427,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
externalLayout2.GetInitialInstances().InsertInitialInstance(instance2);
|
||||
externalLayout2.GetInitialInstances().InsertInitialInstance(instance3);
|
||||
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout1, "Object1", "Object3", /* isObjectGroup =*/false);
|
||||
gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false);
|
||||
@@ -1434,7 +1462,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
auto &layout = project.GetLayout("Scene");
|
||||
|
||||
// Trigger the refactoring after the renaming of an object
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout, "ObjectWithMyBehavior",
|
||||
"RenamedObjectWithMyBehavior",
|
||||
/* isObjectGroup=*/false);
|
||||
@@ -1462,7 +1490,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
auto &layout = project.GetLayout("Scene");
|
||||
|
||||
// Trigger the refactoring after the renaming of a group
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project, layout, "GroupWithMyBehavior", "RenamedGroupWithMyBehavior",
|
||||
/* isObjectGroup=*/true);
|
||||
|
||||
@@ -1506,7 +1534,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
|
||||
// Attach the behavior to the object.
|
||||
object.AddNewBehavior(project, "MyExtension::MyBehavior", "MyBehavior");
|
||||
gd::WholeProjectRefactorer::BehaviorsAddedToObjectInScene(project, scene,
|
||||
gd::WholeProjectRefactorer::BehaviorsAddedToObjectInLayout(project, scene,
|
||||
"Object");
|
||||
|
||||
// The behavior parameter is now filled.
|
||||
@@ -2043,9 +2071,9 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
auto &myEventsFunction =
|
||||
project.GetEventsFunctionsExtension("MyEventsExtension")
|
||||
.GetEventsFunction("MyEventsFunction");
|
||||
REQUIRE(myEventsFunction.GetParameters().GetParameter(1).GetExtraInfo() ==
|
||||
REQUIRE(myEventsFunction.GetParameters().at(1).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedObject");
|
||||
REQUIRE(myEventsFunction.GetParameters().GetParameter(2).GetExtraInfo() ==
|
||||
REQUIRE(myEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedBehavior");
|
||||
|
||||
// Behavior function
|
||||
@@ -2056,12 +2084,9 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedBehavior")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyBehaviorEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(2)
|
||||
.GetExtraInfo() == "MyRenamedExtension::MyEventsBasedObject");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(3)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedObject");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(3).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedBehavior");
|
||||
}
|
||||
|
||||
@@ -2073,12 +2098,9 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedObject")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyObjectEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(1)
|
||||
.GetExtraInfo() == "MyRenamedExtension::MyEventsBasedObject");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(2)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(1).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedObject");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyRenamedExtension::MyEventsBasedBehavior");
|
||||
}
|
||||
}
|
||||
@@ -2321,7 +2343,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
auto &myEventsFunction =
|
||||
project.GetEventsFunctionsExtension("MyEventsExtension")
|
||||
.GetEventsFunction("MyEventsFunction");
|
||||
REQUIRE(myEventsFunction.GetParameters().GetParameter(2).GetExtraInfo() ==
|
||||
REQUIRE(myEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedBehavior");
|
||||
|
||||
// Behavior function
|
||||
@@ -2332,9 +2354,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedBehavior")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyBehaviorEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(3)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(3).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedBehavior");
|
||||
}
|
||||
|
||||
@@ -2346,9 +2366,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedObject")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyObjectEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(2)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedBehavior");
|
||||
}
|
||||
}
|
||||
@@ -2431,7 +2449,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
auto &myEventsFunction =
|
||||
project.GetEventsFunctionsExtension("MyEventsExtension")
|
||||
.GetEventsFunction("MyEventsFunction");
|
||||
REQUIRE(myEventsFunction.GetParameters().GetParameter(1).GetExtraInfo() ==
|
||||
REQUIRE(myEventsFunction.GetParameters().at(1).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedObject");
|
||||
|
||||
// Behavior function
|
||||
@@ -2442,9 +2460,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedBehavior")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyBehaviorEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(2)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(2).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedObject");
|
||||
}
|
||||
|
||||
@@ -2456,9 +2472,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
|
||||
.Get("MyEventsBasedObject")
|
||||
.GetEventsFunctions()
|
||||
.GetEventsFunction("MyObjectEventsFunction");
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters()
|
||||
.GetParameter(1)
|
||||
.GetExtraInfo() ==
|
||||
REQUIRE(myBehaviorEventsFunction.GetParameters().at(1).GetExtraInfo() ==
|
||||
"MyEventsExtension::MyRenamedEventsBasedObject");
|
||||
}
|
||||
}
|
||||
@@ -3570,7 +3584,7 @@ CreateExpressionWithLayerParameter(gd::Project &project,
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("RenameLayer", "[common]") {
|
||||
SECTION("Can update layer names in scene events") {
|
||||
SECTION("Can update layer names in events") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
@@ -3602,7 +3616,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
auto &otherExternalExpression = CreateExpressionWithLayerParameter(
|
||||
project, otherExternalEvents.GetEvents(), "My layer");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "My layer",
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer",
|
||||
"My renamed layer");
|
||||
|
||||
REQUIRE(layoutAction.GetParameter(3).GetPlainString() ==
|
||||
@@ -3630,38 +3644,6 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
"MyExtension::CameraCenterX(\"My layer\")");
|
||||
}
|
||||
|
||||
SECTION("Can update layer names in event-based object events") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
auto &eventsFunction =
|
||||
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
|
||||
"MyEventsFunction", 0);
|
||||
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
eventsExtension, eventsBasedObject);
|
||||
|
||||
auto &action =
|
||||
CreateActionWithLayerParameter(project, eventsFunction.GetEvents());
|
||||
|
||||
auto &expression = CreateExpressionWithLayerParameter(
|
||||
project, eventsFunction.GetEvents(), "My layer");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInEventsBasedObject(
|
||||
project, eventsExtension, eventsBasedObject, "My layer",
|
||||
"My renamed layer");
|
||||
|
||||
REQUIRE(action.GetParameter(3).GetPlainString() == "\"My renamed layer\"");
|
||||
|
||||
REQUIRE(expression.GetParameter(0).GetPlainString() ==
|
||||
"MyExtension::CameraCenterX(\"My renamed layer\") + "
|
||||
"MyExtension::CameraCenterX(\"My renamed layer\")");
|
||||
}
|
||||
|
||||
SECTION("Can update layer names in expressions with a smaller name") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
@@ -3672,7 +3654,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
auto &layoutExpression =
|
||||
CreateExpressionWithLayerParameter(project, layout.GetEvents(), "My layer");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "My layer",
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer",
|
||||
"layerA");
|
||||
|
||||
REQUIRE(layoutExpression.GetParameter(0).GetPlainString() ==
|
||||
@@ -3680,7 +3662,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
"MyExtension::CameraCenterX(\"layerA\")");
|
||||
}
|
||||
|
||||
SECTION("Renaming a layer also moves the instances on this layer in its scene and associated external layouts") {
|
||||
SECTION("Renaming a layer also moves the instances on this layer and of the associated external layouts") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
@@ -3731,7 +3713,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
REQUIRE(otherInitialInstance1.GetLayer() == "My layer");
|
||||
REQUIRE(otherExternalInitialInstance1.GetLayer() == "My layer");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "My layer", "My new layer");
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer", "My new layer");
|
||||
|
||||
// Instances on the renamed layer are moved to the new layer.
|
||||
REQUIRE(initialInstance1.GetLayer() == "My new layer");
|
||||
@@ -3746,46 +3728,6 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
REQUIRE(otherExternalInitialInstance1.GetLayer() == "My layer");
|
||||
}
|
||||
|
||||
SECTION("Renaming a layer also moves the instances on this layer in its "
|
||||
"event-based object") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
auto &eventsFunction =
|
||||
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
|
||||
"MyEventsFunction", 0);
|
||||
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
eventsExtension, eventsBasedObject);
|
||||
|
||||
eventsBasedObject.GetLayers().InsertNewLayer("My layer", 0);
|
||||
|
||||
auto &initialInstances = eventsBasedObject.GetInitialInstances();
|
||||
auto &initialInstance1 = initialInstances.InsertNewInitialInstance();
|
||||
initialInstance1.SetLayer("My layer");
|
||||
auto &initialInstance2 = initialInstances.InsertNewInitialInstance();
|
||||
initialInstance2.SetLayer("My layer");
|
||||
auto &initialInstance3 = initialInstances.InsertNewInitialInstance();
|
||||
initialInstance3.SetLayer("");
|
||||
|
||||
REQUIRE(initialInstance1.GetLayer() == "My layer");
|
||||
REQUIRE(initialInstance2.GetLayer() == "My layer");
|
||||
REQUIRE(initialInstance3.GetLayer() == "");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInEventsBasedObject(
|
||||
project, eventsExtension, eventsBasedObject, "My layer",
|
||||
"My new layer");
|
||||
|
||||
// Instances on the renamed layer are moved to the new layer.
|
||||
REQUIRE(initialInstance1.GetLayer() == "My new layer");
|
||||
REQUIRE(initialInstance2.GetLayer() == "My new layer");
|
||||
REQUIRE(initialInstance3.GetLayer() == "");
|
||||
}
|
||||
|
||||
SECTION("Can rename a layer when a layer parameter is empty") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
@@ -3796,7 +3738,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
auto &layoutAction =
|
||||
CreateActionWithEmptyLayerParameter(project, layout.GetEvents());
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "My layer",
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer",
|
||||
"layerA");
|
||||
|
||||
REQUIRE(layoutAction.GetParameter(0).GetPlainString() == "");
|
||||
@@ -3812,7 +3754,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
auto &layoutExpression =
|
||||
CreateExpressionWithLayerParameter(project, layout.GetEvents(), "My layer");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "My layer",
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "My layer",
|
||||
"");
|
||||
|
||||
REQUIRE(layoutExpression.GetParameter(0).GetPlainString() ==
|
||||
@@ -3830,7 +3772,7 @@ TEST_CASE("RenameLayer", "[common]") {
|
||||
auto &layoutExpression =
|
||||
CreateExpressionWithLayerParameter(project, layout.GetEvents(), "");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerInScene(project, layout, "", "My layer");
|
||||
gd::WholeProjectRefactorer::RenameLayer(project, layout, "", "My layer");
|
||||
|
||||
REQUIRE(layoutExpression.GetParameter(0).GetPlainString() ==
|
||||
"MyExtension::CameraCenterX(\"\") + "
|
||||
@@ -3871,7 +3813,7 @@ CreateExpressionWithAnimationParameter(gd::Project &project,
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("RenameObjectAnimation", "[common]") {
|
||||
SECTION("Can update object animation names in scene events") {
|
||||
SECTION("Can update object animation names in event") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
@@ -3913,7 +3855,7 @@ TEST_CASE("RenameObjectAnimation", "[common]") {
|
||||
auto &wrongObjectExpression =
|
||||
CreateExpressionWithAnimationParameter(project, layout.GetEvents(), "MySprite2");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameObjectAnimationInScene(project, layout, object, "My animation",
|
||||
gd::WholeProjectRefactorer::RenameObjectAnimation(project, layout, object, "My animation",
|
||||
"My renamed animation");
|
||||
|
||||
REQUIRE(layoutAction.GetParameter(1).GetPlainString() ==
|
||||
@@ -3945,53 +3887,6 @@ TEST_CASE("RenameObjectAnimation", "[common]") {
|
||||
"MySprite2.AnimationFrameCount(\"My animation\") + "
|
||||
"MySprite2.AnimationFrameCount(\"My animation\")");
|
||||
}
|
||||
|
||||
SECTION("Can update object animation names in events-based object events") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
auto &eventsFunction =
|
||||
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
|
||||
"MyEventsFunction", 0);
|
||||
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
eventsExtension, eventsBasedObject);
|
||||
|
||||
auto &object = eventsBasedObject.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MySprite", 0);
|
||||
eventsBasedObject.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MySprite2", 1);
|
||||
|
||||
auto &action = CreateActionWithAnimationParameter(
|
||||
project, eventsFunction.GetEvents(), "MySprite");
|
||||
auto &wrongObjectAction = CreateActionWithAnimationParameter(
|
||||
project, eventsFunction.GetEvents(), "MySprite2");
|
||||
|
||||
auto &expression = CreateExpressionWithAnimationParameter(
|
||||
project, eventsFunction.GetEvents(), "MySprite");
|
||||
auto &wrongObjectExpression = CreateExpressionWithAnimationParameter(
|
||||
project, eventsFunction.GetEvents(), "MySprite2");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameObjectAnimationInEventsBasedObject(
|
||||
project, eventsExtension, eventsBasedObject, object, "My animation",
|
||||
"My renamed animation");
|
||||
|
||||
REQUIRE(action.GetParameter(1).GetPlainString() ==
|
||||
"\"My renamed animation\"");
|
||||
REQUIRE(wrongObjectAction.GetParameter(1).GetPlainString() ==
|
||||
"\"My animation\"");
|
||||
|
||||
REQUIRE(expression.GetParameter(0).GetPlainString() ==
|
||||
"MySprite.AnimationFrameCount(\"My renamed animation\") + "
|
||||
"MySprite.AnimationFrameCount(\"My renamed animation\")");
|
||||
REQUIRE(wrongObjectExpression.GetParameter(0).GetPlainString() ==
|
||||
"MySprite2.AnimationFrameCount(\"My animation\") + "
|
||||
"MySprite2.AnimationFrameCount(\"My animation\")");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -4027,7 +3922,7 @@ CreateExpressionWithLayerEffectParameter(gd::Project &project,
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("RenameLayerEffect", "[common]") {
|
||||
SECTION("Can update layer effect names in scene events") {
|
||||
SECTION("Can update layer effect names in event") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
@@ -4071,7 +3966,7 @@ TEST_CASE("RenameLayerEffect", "[common]") {
|
||||
auto &wrongLayerExpression =
|
||||
CreateExpressionWithLayerEffectParameter(project, layout.GetEvents(), "My layer 2");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerEffectInScene(project, layout, layer, "My effect",
|
||||
gd::WholeProjectRefactorer::RenameLayerEffect(project, layout, layer, "My effect",
|
||||
"My renamed effect");
|
||||
|
||||
REQUIRE(layoutAction.GetParameter(2).GetPlainString() ==
|
||||
@@ -4103,61 +3998,10 @@ TEST_CASE("RenameLayerEffect", "[common]") {
|
||||
"MyExtension::LayerEffectParameter(\"My layer 2\", \"My effect\") + "
|
||||
"MyExtension::LayerEffectParameter(\"My layer 2\", \"My effect\")");
|
||||
}
|
||||
|
||||
SECTION("Can update layer effect names in events-based object events") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
auto &eventsExtension =
|
||||
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
||||
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
||||
"MyEventsBasedObject", 0);
|
||||
auto &eventsFunction =
|
||||
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
|
||||
"MyEventsFunction", 0);
|
||||
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
eventsExtension, eventsBasedObject);
|
||||
|
||||
eventsBasedObject.GetLayers().InsertNewLayer("My layer", 0);
|
||||
auto &layer = eventsBasedObject.GetLayers().GetLayer("My layer");
|
||||
auto &object = eventsBasedObject.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MySprite", 0);
|
||||
eventsBasedObject.GetObjects().InsertNewObject(
|
||||
project, "MyExtension::Sprite", "MySprite2", 1);
|
||||
|
||||
auto &action = CreateActionWithLayerEffectParameter(
|
||||
project, eventsFunction.GetEvents(), "My layer");
|
||||
auto &wrongLayerAction = CreateActionWithLayerEffectParameter(
|
||||
project, eventsFunction.GetEvents(), "My layer 2");
|
||||
|
||||
auto &expression = CreateExpressionWithLayerEffectParameter(
|
||||
project, eventsFunction.GetEvents(), "My layer");
|
||||
auto &wrongLayerExpression = CreateExpressionWithLayerEffectParameter(
|
||||
project, eventsFunction.GetEvents(), "My layer 2");
|
||||
|
||||
gd::WholeProjectRefactorer::RenameLayerEffectInEventsBasedObject(
|
||||
project, eventsExtension, eventsBasedObject, layer, "My effect",
|
||||
"My renamed effect");
|
||||
|
||||
REQUIRE(action.GetParameter(2).GetPlainString() == "\"My renamed effect\"");
|
||||
REQUIRE(wrongLayerAction.GetParameter(2).GetPlainString() ==
|
||||
"\"My effect\"");
|
||||
|
||||
REQUIRE(expression.GetParameter(0).GetPlainString() ==
|
||||
"MyExtension::LayerEffectParameter(\"My layer\", \"My renamed "
|
||||
"effect\") + "
|
||||
"MyExtension::LayerEffectParameter(\"My layer\", \"My renamed "
|
||||
"effect\")");
|
||||
REQUIRE(
|
||||
wrongLayerExpression.GetParameter(0).GetPlainString() ==
|
||||
"MyExtension::LayerEffectParameter(\"My layer 2\", \"My effect\") + "
|
||||
"MyExtension::LayerEffectParameter(\"My layer 2\", \"My effect\")");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("RemoveLayer", "[common]") {
|
||||
SECTION("Can remove instances from a layer (in a scene and its associated external layouts)") {
|
||||
SECTION("Can remove instances from a layer (in a scene and their associated external layouts)") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
@@ -4242,7 +4086,7 @@ TEST_CASE("RemoveLayer", "[common]") {
|
||||
}
|
||||
|
||||
TEST_CASE("MergeLayers", "[common]") {
|
||||
SECTION("Can merge instances from a layer into another layer (in a scene and its associated external layouts)") {
|
||||
SECTION("Can merge instances from a layer into another layer (in a scene and their associated external layouts)") {
|
||||
gd::Project project;
|
||||
gd::Platform platform;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
@@ -304,15 +304,8 @@ namespace gdjs {
|
||||
*/
|
||||
setDepth(depth: float): void {
|
||||
const unscaledDepth = this.getUnscaledDepth();
|
||||
if (unscaledDepth === 0) {
|
||||
return;
|
||||
}
|
||||
const scaleZ = depth / unscaledDepth;
|
||||
if (this._innerArea && this._isInnerAreaFollowingParentSize) {
|
||||
this._innerArea.min[2] *= scaleZ;
|
||||
this._innerArea.max[2] *= scaleZ;
|
||||
} else {
|
||||
this.setScaleZ(scaleZ);
|
||||
if (unscaledDepth !== 0) {
|
||||
this.setScaleZ(depth / unscaledDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,10 +325,6 @@ namespace gdjs {
|
||||
* @param newScale The new scale (must be greater than 0).
|
||||
*/
|
||||
setScaleZ(newScale: number): void {
|
||||
if (this._innerArea && this._isInnerAreaFollowingParentSize) {
|
||||
// The scale is always 1;
|
||||
return;
|
||||
}
|
||||
if (newScale < 0) {
|
||||
newScale = 0;
|
||||
}
|
||||
|
@@ -235,19 +235,6 @@ void Model3DObjectConfiguration::ExposeResources(
|
||||
worker.ExposeModel3D(modelResourceName);
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
Model3DObjectConfiguration::GetAnimationName(size_t index) const {
|
||||
return GetAnimation(index).GetName();
|
||||
}
|
||||
|
||||
bool Model3DObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Model3DAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
Model3DAnimation Model3DObjectConfiguration::badAnimation;
|
||||
|
||||
const Model3DAnimation &
|
||||
@@ -265,6 +252,14 @@ Model3DAnimation &Model3DObjectConfiguration::GetAnimation(std::size_t nb) {
|
||||
return animations[nb];
|
||||
}
|
||||
|
||||
bool Model3DObjectConfiguration::HasAnimationNamed(
|
||||
const gd::String &name) const {
|
||||
return !name.empty() && (find_if(animations.begin(), animations.end(),
|
||||
[&name](const Model3DAnimation &animation) {
|
||||
return animation.GetName() == name;
|
||||
}) != animations.end());
|
||||
}
|
||||
|
||||
void Model3DObjectConfiguration::AddAnimation(
|
||||
const Model3DAnimation &animation) {
|
||||
animations.push_back(animation);
|
||||
|
@@ -85,12 +85,6 @@ public:
|
||||
* Methods related to animations management
|
||||
*/
|
||||
///@{
|
||||
std::size_t GetAnimationsCount() const override { return animations.size(); };
|
||||
|
||||
const gd::String &GetAnimationName(size_t index) const override;
|
||||
|
||||
bool HasAnimationNamed(const gd::String &animationName) const override;
|
||||
|
||||
/**
|
||||
* \brief Return the animation at the specified index.
|
||||
* If the index is out of bound, a "bad animation" object is returned.
|
||||
@@ -103,6 +97,16 @@ public:
|
||||
*/
|
||||
Model3DAnimation &GetAnimation(std::size_t nb);
|
||||
|
||||
/**
|
||||
* \brief Return the number of animations this object has.
|
||||
*/
|
||||
std::size_t GetAnimationsCount() const { return animations.size(); };
|
||||
|
||||
/**
|
||||
* \brief Return true if the animation called "name" exists.
|
||||
*/
|
||||
bool HasAnimationNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Add an animation at the end of the existing ones.
|
||||
*/
|
||||
|
@@ -118,19 +118,6 @@ namespace gdjs {
|
||||
this._materialType = this._convertMaterialType(
|
||||
objectData.content.materialType
|
||||
);
|
||||
|
||||
this.onModelChanged(objectData);
|
||||
|
||||
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
|
||||
this.onCreated();
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called after the renderer loaded a Model resource:
|
||||
* - After the renderer was instantiated
|
||||
* - After reloading the model
|
||||
*/
|
||||
private onModelChanged(objectData) {
|
||||
this._updateModel(objectData);
|
||||
if (this._animations.length > 0) {
|
||||
this._renderer.playAnimation(
|
||||
@@ -138,6 +125,9 @@ namespace gdjs {
|
||||
this._animations[0].loop
|
||||
);
|
||||
}
|
||||
|
||||
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
|
||||
this.onCreated();
|
||||
}
|
||||
|
||||
updateFromObjectData(
|
||||
@@ -145,21 +135,7 @@ namespace gdjs {
|
||||
newObjectData: Model3DObjectData
|
||||
): boolean {
|
||||
super.updateFromObjectData(oldObjectData, newObjectData);
|
||||
|
||||
if (
|
||||
oldObjectData.content.materialType !==
|
||||
newObjectData.content.materialType
|
||||
) {
|
||||
this._materialType = this._convertMaterialType(
|
||||
newObjectData.content.materialType
|
||||
);
|
||||
}
|
||||
if (
|
||||
oldObjectData.content.modelResourceName !==
|
||||
newObjectData.content.modelResourceName
|
||||
) {
|
||||
this._reloadModel(newObjectData);
|
||||
} else if (
|
||||
oldObjectData.content.width !== newObjectData.content.width ||
|
||||
oldObjectData.content.height !== newObjectData.content.height ||
|
||||
oldObjectData.content.depth !== newObjectData.content.depth ||
|
||||
@@ -167,12 +143,19 @@ namespace gdjs {
|
||||
oldObjectData.content.rotationY !== newObjectData.content.rotationY ||
|
||||
oldObjectData.content.rotationZ !== newObjectData.content.rotationZ ||
|
||||
oldObjectData.content.keepAspectRatio !==
|
||||
newObjectData.content.keepAspectRatio ||
|
||||
oldObjectData.content.materialType !==
|
||||
newObjectData.content.materialType
|
||||
newObjectData.content.keepAspectRatio
|
||||
) {
|
||||
this._updateModel(newObjectData);
|
||||
}
|
||||
if (
|
||||
oldObjectData.content.materialType !==
|
||||
newObjectData.content.materialType
|
||||
) {
|
||||
this._materialType = this._convertMaterialType(
|
||||
newObjectData.content.materialType
|
||||
);
|
||||
this._updateModel(newObjectData);
|
||||
}
|
||||
if (
|
||||
oldObjectData.content.originLocation !==
|
||||
newObjectData.content.originLocation
|
||||
@@ -235,12 +218,6 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
_reloadModel(objectData: Model3DObjectData) {
|
||||
this._modelResourceName = objectData.content.modelResourceName;
|
||||
this._renderer._reloadModel(this, this._runtimeScene);
|
||||
this.onModelChanged(objectData);
|
||||
}
|
||||
|
||||
_updateModel(objectData: Model3DObjectData) {
|
||||
const rotationX = objectData.content.rotationX || 0;
|
||||
const rotationY = objectData.content.rotationY || 0;
|
||||
|
@@ -236,20 +236,6 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `_updateModel` should always be called after this method.
|
||||
* Ideally, use `Model3DRuntimeObject#_reloadModel` instead.
|
||||
*/
|
||||
_reloadModel(
|
||||
runtimeObject: Model3DRuntimeObject,
|
||||
instanceContainer: gdjs.RuntimeInstanceContainer
|
||||
) {
|
||||
this._originalModel = instanceContainer
|
||||
.getGame()
|
||||
.getModel3DManager()
|
||||
.getModel(runtimeObject._modelResourceName);
|
||||
}
|
||||
|
||||
_updateModel(
|
||||
rotationX: float,
|
||||
rotationY: float,
|
||||
|
@@ -38,7 +38,7 @@ module.exports = {
|
||||
.setName('Consent Cordova plugin')
|
||||
.setDependencyType('cordova')
|
||||
.setExportName('cordova-plugin-consent')
|
||||
.setVersion('3.0.0-alpha.8')
|
||||
.setVersion('2.4.0')
|
||||
.onlyIfOtherDependencyIsExported('AdMob Cordova plugin');
|
||||
|
||||
extension
|
||||
@@ -58,7 +58,7 @@ module.exports = {
|
||||
.setName('AdMob Cordova plugin')
|
||||
.setDependencyType('cordova')
|
||||
.setExportName('admob-plus-cordova')
|
||||
.setVersion('2.0.0-alpha.18')
|
||||
.setVersion('1.28.0')
|
||||
.setExtraSetting(
|
||||
'APP_ID_ANDROID',
|
||||
new gd.PropertyDescriptor('AdMobAppIdAndroid').setType(
|
||||
@@ -166,11 +166,11 @@ module.exports = {
|
||||
)
|
||||
.addParameter('string', _('Android app open ID'), '', false)
|
||||
.setParameterLongDescription(
|
||||
'Get it from your AdMob account. You can use `"ca-app-pub-3940256099942544/9257395921"` for loading a test app open.'
|
||||
'Get it from your AdMob account. You can use `"ca-app-pub-3940256099942544/3419835294"` for loading a test app open.'
|
||||
)
|
||||
.addParameter('string', _('iOS app open ID'), '', false)
|
||||
.setParameterLongDescription(
|
||||
'Get it from your AdMob account. You can use `"ca-app-pub-3940256099942544/5575463023"` for loading a test app open.'
|
||||
'Get it from your AdMob account. You can use `"ca-app-pub-3940256099942544/5662855259"` for loading a test app open.'
|
||||
)
|
||||
.addParameter(
|
||||
'yesorno',
|
||||
|
@@ -7,8 +7,8 @@ namespace gdjs {
|
||||
|
||||
const testAdIds = {
|
||||
appOpen: {
|
||||
android: 'ca-app-pub-3940256099942544/9257395921',
|
||||
ios: 'ca-app-pub-3940256099942544/5575463023',
|
||||
android: 'ca-app-pub-3940256099942544/3419835294',
|
||||
ios: 'ca-app-pub-3940256099942544/5662855259',
|
||||
},
|
||||
banner: {
|
||||
android: 'ca-app-pub-3940256099942544/6300978111',
|
||||
@@ -67,7 +67,6 @@ namespace gdjs {
|
||||
|
||||
// Admob does not initialize automatically, so we store a flag to know if it's initialized.
|
||||
let admobStarted = false;
|
||||
let isStarting = false;
|
||||
let isUsingTestAds = false;
|
||||
|
||||
// Banner
|
||||
@@ -116,13 +115,9 @@ namespace gdjs {
|
||||
async () => {
|
||||
// Obtain user consent ?
|
||||
|
||||
logger.info('Starting AdMob.');
|
||||
isStarting = true;
|
||||
|
||||
await admob.start();
|
||||
|
||||
logger.info('AdMob successfully started.');
|
||||
isStarting = false;
|
||||
admobStarted = true;
|
||||
},
|
||||
false
|
||||
@@ -131,32 +126,15 @@ namespace gdjs {
|
||||
/**
|
||||
* Helper to know if we are on mobile and admob is correctly initialized.
|
||||
*/
|
||||
const checkIfAdMobIsAvailable = async () => {
|
||||
const checkIfAdMobIsAvailable = () => {
|
||||
if (typeof cordova === 'undefined') {
|
||||
logger.warn('We are not on mobile, AdMob will not be available.');
|
||||
return false;
|
||||
}
|
||||
if (typeof admob === 'undefined') {
|
||||
logger.warn('AdMob has not been configured properly.');
|
||||
if (typeof admob === 'undefined' || !admobStarted) {
|
||||
logger.warn('AdMob has not been configured or started properly.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!admobStarted) {
|
||||
if (isStarting) {
|
||||
// Delay the call until AdMob is started, up to 5 seconds.
|
||||
let time = 0;
|
||||
while (!admobStarted && time < 5000) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
time += 100;
|
||||
}
|
||||
}
|
||||
|
||||
if (!admobStarted) {
|
||||
logger.warn('AdMob is not started.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -186,10 +164,8 @@ namespace gdjs {
|
||||
* charging advertisers. If you click on too many ads without being in test mode, you risk your
|
||||
* account being flagged for invalid activity.
|
||||
*/
|
||||
export const setTestMode = async (enable: boolean) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
|
||||
logger.info('Setting AdMob test mode to:', enable);
|
||||
export const setTestMode = (enable: boolean) => {
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
isUsingTestAds = enable;
|
||||
};
|
||||
@@ -209,7 +185,7 @@ namespace gdjs {
|
||||
displayLandscape,
|
||||
displayWhenLoaded
|
||||
) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
// If an appOpen is already loading or showing, we don't stop it.
|
||||
if (appOpenLoading || appOpenShowing) {
|
||||
return;
|
||||
@@ -266,7 +242,7 @@ namespace gdjs {
|
||||
|
||||
/** Show the loaded appOpen. */
|
||||
export const showAppOpen = async () => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
if (!appOpen) {
|
||||
logger.warn('App Open has not been set up, call loadAppOpen first.');
|
||||
@@ -317,7 +293,7 @@ namespace gdjs {
|
||||
* If a banner is already set up, it will be hidden and replaced by the new one.
|
||||
*/
|
||||
export const setupBanner = async (androidAdUnitId, iosAdUnitId, atTop) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
const adUnitId = getAdUnitId(androidAdUnitId, iosAdUnitId, 'banner');
|
||||
if (!adUnitId) return;
|
||||
|
||||
@@ -333,7 +309,6 @@ namespace gdjs {
|
||||
adUnitId,
|
||||
position: atTop ? 'top' : 'bottom',
|
||||
size: bannerRequestedAdSizeType,
|
||||
offset: 0,
|
||||
});
|
||||
|
||||
banner.on('load', () => {
|
||||
@@ -379,7 +354,7 @@ namespace gdjs {
|
||||
|
||||
/** Hide the banner shown on screen. */
|
||||
export const hideBanner = async () => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
if (!banner || !bannerShowing) {
|
||||
logger.warn('No banner is being shown.');
|
||||
@@ -406,7 +381,7 @@ namespace gdjs {
|
||||
iosAdUnitId,
|
||||
displayWhenLoaded
|
||||
) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
// If an interstitial is already loading or showing, we don't stop it.
|
||||
if (interstitialLoading || interstitialShowing) {
|
||||
return;
|
||||
@@ -465,7 +440,7 @@ namespace gdjs {
|
||||
|
||||
/** Show the loaded interstitial. */
|
||||
export const showInterstitial = async () => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
if (!interstitial) {
|
||||
logger.warn(
|
||||
@@ -520,7 +495,7 @@ namespace gdjs {
|
||||
iosAdUnitID,
|
||||
displayWhenLoaded
|
||||
) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
if (rewardedInterstitialLoading || rewardedInterstitialShowing) {
|
||||
return;
|
||||
}
|
||||
@@ -582,7 +557,7 @@ namespace gdjs {
|
||||
|
||||
/** Show the loaded reward interstitial. */
|
||||
export const showRewardedInterstitial = async () => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
if (!rewardedInterstitial) {
|
||||
logger.warn(
|
||||
@@ -639,7 +614,7 @@ namespace gdjs {
|
||||
iosAdUnitID,
|
||||
displayWhenLoaded
|
||||
) => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
if (rewardedVideoLoading || rewardedVideoShowing) {
|
||||
return;
|
||||
}
|
||||
@@ -697,7 +672,7 @@ namespace gdjs {
|
||||
|
||||
/** Show the loaded reward video. */
|
||||
export const showRewardedVideo = async () => {
|
||||
if (!(await checkIfAdMobIsAvailable())) return;
|
||||
if (!checkIfAdMobIsAvailable()) return;
|
||||
|
||||
if (!rewardedVideo) {
|
||||
logger.warn('Video has not been set up, call loadRewardedVideo first.');
|
||||
|
@@ -25,6 +25,7 @@ void AnchorBehavior::InitializeContent(gd::SerializerElement& content) {
|
||||
content.SetAttribute("useLegacyBottomAndRightAnchors", false);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
namespace {
|
||||
gd::String GetAnchorAsString(AnchorBehavior::HorizontalAnchor anchor) {
|
||||
if (anchor == AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_LEFT)
|
||||
@@ -33,8 +34,6 @@ gd::String GetAnchorAsString(AnchorBehavior::HorizontalAnchor anchor) {
|
||||
return _("Window right");
|
||||
else if (anchor == AnchorBehavior::ANCHOR_HORIZONTAL_PROPORTIONAL)
|
||||
return _("Proportional");
|
||||
else if (anchor == AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_CENTER)
|
||||
return _("Window center");
|
||||
else
|
||||
return _("No anchor");
|
||||
}
|
||||
@@ -46,8 +45,6 @@ gd::String GetAnchorAsString(AnchorBehavior::VerticalAnchor anchor) {
|
||||
return _("Window bottom");
|
||||
else if (anchor == AnchorBehavior::ANCHOR_VERTICAL_PROPORTIONAL)
|
||||
return _("Proportional");
|
||||
else if (anchor == AnchorBehavior::ANCHOR_VERTICAL_WINDOW_CENTER)
|
||||
return _("Window center");
|
||||
else
|
||||
return _("No anchor");
|
||||
}
|
||||
@@ -72,7 +69,6 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window center"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the left edge of the object on X axis."));
|
||||
@@ -83,7 +79,6 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window left"))
|
||||
.AddExtraInfo(_("Window center"))
|
||||
.AddExtraInfo(_("Window right"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the right edge of the object on X axis."));
|
||||
@@ -94,7 +89,6 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window center"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the top edge of the object on Y axis."));
|
||||
@@ -105,7 +99,6 @@ std::map<gd::String, gd::PropertyDescriptor> AnchorBehavior::GetProperties(
|
||||
.SetType("Choice")
|
||||
.AddExtraInfo(_("No anchor"))
|
||||
.AddExtraInfo(_("Window top"))
|
||||
.AddExtraInfo(_("Window center"))
|
||||
.AddExtraInfo(_("Window bottom"))
|
||||
.AddExtraInfo(_("Proportional"))
|
||||
.SetDescription(_("Anchor the bottom edge of the object on Y axis."));
|
||||
@@ -134,8 +127,6 @@ AnchorBehavior::HorizontalAnchor GetHorizontalAnchorFromString(
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_RIGHT;
|
||||
else if (value == _("Proportional"))
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_PROPORTIONAL;
|
||||
else if (value == _("Window center"))
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_WINDOW_CENTER;
|
||||
else
|
||||
return AnchorBehavior::ANCHOR_HORIZONTAL_NONE;
|
||||
}
|
||||
@@ -148,8 +139,6 @@ AnchorBehavior::VerticalAnchor GetVerticalAnchorFromString(
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_WINDOW_BOTTOM;
|
||||
else if (value == _("Proportional"))
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_PROPORTIONAL;
|
||||
else if (value == _("Window center"))
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_WINDOW_CENTER;
|
||||
else
|
||||
return AnchorBehavior::ANCHOR_VERTICAL_NONE;
|
||||
}
|
||||
@@ -183,3 +172,4 @@ bool AnchorBehavior::UpdateProperty(gd::SerializerElement& behaviorContent,
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@@ -3,8 +3,8 @@ GDevelop - Anchor Behavior Extension
|
||||
Copyright (c) 2016 Victor Levasseur (victorlevasseur52@gmail.com)
|
||||
This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef ANCHORBEHAVIOR_H
|
||||
#define ANCHORBEHAVIOR_H
|
||||
#include <vector>
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
@@ -22,16 +22,14 @@ class GD_EXTENSION_API AnchorBehavior : public gd::Behavior {
|
||||
ANCHOR_HORIZONTAL_NONE = 0,
|
||||
ANCHOR_HORIZONTAL_WINDOW_LEFT = 1,
|
||||
ANCHOR_HORIZONTAL_WINDOW_RIGHT = 2,
|
||||
ANCHOR_HORIZONTAL_PROPORTIONAL = 3,
|
||||
ANCHOR_HORIZONTAL_WINDOW_CENTER = 4
|
||||
ANCHOR_HORIZONTAL_PROPORTIONAL = 3
|
||||
};
|
||||
|
||||
enum VerticalAnchor {
|
||||
ANCHOR_VERTICAL_NONE = 0,
|
||||
ANCHOR_VERTICAL_WINDOW_TOP = 1,
|
||||
ANCHOR_VERTICAL_WINDOW_BOTTOM = 2,
|
||||
ANCHOR_VERTICAL_PROPORTIONAL = 3,
|
||||
ANCHOR_VERTICAL_WINDOW_CENTER = 4
|
||||
ANCHOR_VERTICAL_PROPORTIONAL = 3
|
||||
};
|
||||
|
||||
AnchorBehavior() {};
|
||||
@@ -49,3 +47,5 @@ class GD_EXTENSION_API AnchorBehavior : public gd::Behavior {
|
||||
virtual void InitializeContent(
|
||||
gd::SerializerElement& behaviorContent) override;
|
||||
};
|
||||
|
||||
#endif // ANCHORBEHAVIOR_H
|
||||
|
@@ -30,6 +30,5 @@ void DeclareAnchorBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
"CppPlatform/Extensions/AnchorIcon.png",
|
||||
"AnchorBehavior",
|
||||
std::make_shared<AnchorBehavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
std::make_shared<gd::BehaviorsSharedData>());
|
||||
}
|
||||
|
@@ -4,25 +4,10 @@ Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
namespace gdjs {
|
||||
const enum HorizontalAnchor {
|
||||
None = 0,
|
||||
WindowLeft,
|
||||
WindowRight,
|
||||
Proportional,
|
||||
WindowCenter,
|
||||
}
|
||||
const enum VerticalAnchor {
|
||||
None = 0,
|
||||
WindowTop,
|
||||
WindowBottom,
|
||||
Proportional,
|
||||
WindowCenter,
|
||||
}
|
||||
|
||||
export class AnchorRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
_relativeToOriginalWindowSize: any;
|
||||
_leftEdgeAnchor: HorizontalAnchor;
|
||||
_rightEdgeAnchor: HorizontalAnchor;
|
||||
_leftEdgeAnchor: any;
|
||||
_rightEdgeAnchor: any;
|
||||
_topEdgeAnchor: any;
|
||||
_bottomEdgeAnchor: any;
|
||||
_invalidDistances: boolean = true;
|
||||
@@ -89,25 +74,14 @@ namespace gdjs {
|
||||
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents
|
||||
) as FloatPoint;
|
||||
// TODO EBO Make it work with event based objects or hide this behavior for them.
|
||||
let parentMinX = instanceContainer.getUnrotatedViewportMinX();
|
||||
let parentMinY = instanceContainer.getUnrotatedViewportMinY();
|
||||
let parentMaxX = instanceContainer.getUnrotatedViewportMaxX();
|
||||
let parentMaxY = instanceContainer.getUnrotatedViewportMaxY();
|
||||
let parentCenterX = (parentMaxX + parentMinX) / 2;
|
||||
let parentCenterY = (parentMaxY + parentMinY) / 2;
|
||||
let parentWidth = parentMaxX - parentMinX;
|
||||
let parentHeight = parentMaxY - parentMinY;
|
||||
const game = instanceContainer.getGame();
|
||||
let rendererWidth = game.getGameResolutionWidth();
|
||||
let rendererHeight = game.getGameResolutionHeight();
|
||||
const layer = instanceContainer.getLayer(this.owner.getLayer());
|
||||
if (this._invalidDistances) {
|
||||
if (this._relativeToOriginalWindowSize) {
|
||||
parentMinX = instanceContainer.getInitialUnrotatedViewportMinX();
|
||||
parentMinY = instanceContainer.getInitialUnrotatedViewportMinY();
|
||||
parentMaxX = instanceContainer.getInitialUnrotatedViewportMaxX();
|
||||
parentMaxY = instanceContainer.getInitialUnrotatedViewportMaxY();
|
||||
parentCenterX = (parentMaxX + parentMinX) / 2;
|
||||
parentCenterY = (parentMaxY + parentMinY) / 2;
|
||||
parentWidth = parentMaxX - parentMinX;
|
||||
parentHeight = parentMaxY - parentMinY;
|
||||
rendererWidth = game.getOriginalWidth();
|
||||
rendererHeight = game.getOriginalHeight();
|
||||
}
|
||||
|
||||
//Calculate the distances from the window's bounds.
|
||||
@@ -118,28 +92,49 @@ namespace gdjs {
|
||||
workingPoint
|
||||
);
|
||||
|
||||
// Left edge
|
||||
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
|
||||
this._leftEdgeDistance = topLeftPixel[0] - parentMinX;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
|
||||
this._leftEdgeDistance = topLeftPixel[0] - parentMaxX;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
|
||||
this._leftEdgeDistance = (topLeftPixel[0] - parentMinX) / parentWidth;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
|
||||
this._leftEdgeDistance = topLeftPixel[0] - parentCenterX;
|
||||
//Left edge
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
this._leftEdgeDistance = topLeftPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
this._leftEdgeDistance = rendererWidth - topLeftPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._leftEdgeDistance = topLeftPixel[0] / rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Top edge
|
||||
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
|
||||
this._topEdgeDistance = topLeftPixel[1] - parentMinY;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
|
||||
this._topEdgeDistance = topLeftPixel[1] - parentMaxY;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
|
||||
this._topEdgeDistance = (topLeftPixel[1] - parentMinY) / parentHeight;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
|
||||
this._topEdgeDistance = topLeftPixel[1] - parentCenterY;
|
||||
//Top edge
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
this._topEdgeDistance = topLeftPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
this._topEdgeDistance = rendererHeight - topLeftPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._topEdgeDistance = topLeftPixel[1] / rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
|
||||
const bottomRightPixel = layer.convertCoords(
|
||||
this.owner.getDrawableX() + this.owner.getWidth(),
|
||||
@@ -148,30 +143,49 @@ namespace gdjs {
|
||||
workingPoint
|
||||
);
|
||||
|
||||
// Right edge
|
||||
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0] - parentMinX;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0] - parentMaxX;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
|
||||
this._rightEdgeDistance =
|
||||
(bottomRightPixel[0] - parentMinX) / parentWidth;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0] - parentCenterX;
|
||||
//Right edge
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
this._rightEdgeDistance = rendererWidth - bottomRightPixel[0];
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._rightEdgeDistance = bottomRightPixel[0] / rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom edge
|
||||
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] - parentMinY;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] - parentMaxY;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
|
||||
this._bottomEdgeDistance =
|
||||
(bottomRightPixel[1] - parentMinY) / parentHeight;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] - parentCenterY;
|
||||
//Bottom edge
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
this._bottomEdgeDistance = rendererHeight - bottomRightPixel[1];
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
this._bottomEdgeDistance = bottomRightPixel[1] / rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._invalidDistances = false;
|
||||
} else {
|
||||
//Move and resize the object if needed
|
||||
@@ -180,50 +194,93 @@ namespace gdjs {
|
||||
let rightPixel = 0;
|
||||
let bottomPixel = 0;
|
||||
|
||||
// Left edge
|
||||
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
|
||||
leftPixel = parentMinX + this._leftEdgeDistance;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
|
||||
leftPixel = parentMaxX + this._leftEdgeDistance;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
|
||||
leftPixel = parentMinX + this._leftEdgeDistance * parentWidth;
|
||||
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
|
||||
leftPixel = parentCenterX + this._leftEdgeDistance;
|
||||
//Left edge
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
leftPixel = this._leftEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
leftPixel = rendererWidth - this._leftEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._leftEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
leftPixel = this._leftEdgeDistance * rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Top edge
|
||||
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
|
||||
topPixel = parentMinY + this._topEdgeDistance;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
|
||||
topPixel = parentMaxY + this._topEdgeDistance;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
|
||||
topPixel = parentMinY + this._topEdgeDistance * parentHeight;
|
||||
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
|
||||
topPixel = parentCenterY + this._topEdgeDistance;
|
||||
//Top edge
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
topPixel = this._topEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
topPixel = rendererHeight - this._topEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._topEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
topPixel = this._topEdgeDistance * rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Right edge
|
||||
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
|
||||
rightPixel = parentMinX + this._rightEdgeDistance;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
|
||||
rightPixel = parentMaxX + this._rightEdgeDistance;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
|
||||
rightPixel = parentMinX + this._rightEdgeDistance * parentWidth;
|
||||
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
|
||||
rightPixel = parentCenterX + this._rightEdgeDistance;
|
||||
//Right edge
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_LEFT
|
||||
) {
|
||||
rightPixel = this._rightEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.WINDOW_RIGHT
|
||||
) {
|
||||
rightPixel = rendererWidth - this._rightEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._rightEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.PROPORTIONAL
|
||||
) {
|
||||
rightPixel = this._rightEdgeDistance * rendererWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom edge
|
||||
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
|
||||
bottomPixel = parentMinY + this._bottomEdgeDistance;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
|
||||
bottomPixel = parentMaxY + this._bottomEdgeDistance;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
|
||||
bottomPixel = parentMinY + this._bottomEdgeDistance * parentHeight;
|
||||
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
|
||||
bottomPixel = parentCenterY + this._bottomEdgeDistance;
|
||||
//Bottom edge
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_TOP
|
||||
) {
|
||||
bottomPixel = this._bottomEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.WINDOW_BOTTOM
|
||||
) {
|
||||
bottomPixel = rendererHeight - this._bottomEdgeDistance;
|
||||
} else {
|
||||
if (
|
||||
this._bottomEdgeAnchor ===
|
||||
AnchorRuntimeBehavior.VerticalAnchor.PROPORTIONAL
|
||||
) {
|
||||
bottomPixel = this._bottomEdgeDistance * rendererHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
|
||||
const topLeftCoord = layer.convertInverseCoords(
|
||||
leftPixel,
|
||||
@@ -246,18 +303,27 @@ namespace gdjs {
|
||||
// Compatibility with GD <= 5.0.133
|
||||
if (this._useLegacyBottomAndRightAnchors) {
|
||||
//Move and resize the object according to the anchors
|
||||
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(right - left);
|
||||
}
|
||||
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
|
||||
if (
|
||||
this._bottomEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottom - top);
|
||||
}
|
||||
if (this._leftEdgeAnchor !== HorizontalAnchor.None) {
|
||||
if (
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
left + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (this._topEdgeAnchor !== VerticalAnchor.None) {
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
top + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
@@ -267,18 +333,25 @@ namespace gdjs {
|
||||
else {
|
||||
// Resize if right and left anchors are set
|
||||
if (
|
||||
this._rightEdgeAnchor !== HorizontalAnchor.None &&
|
||||
this._leftEdgeAnchor !== HorizontalAnchor.None
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE &&
|
||||
this._leftEdgeAnchor !== AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setWidth(right - left);
|
||||
this.owner.setX(left);
|
||||
} else {
|
||||
if (this._leftEdgeAnchor !== HorizontalAnchor.None) {
|
||||
if (
|
||||
this._leftEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
left + this.owner.getX() - this.owner.getDrawableX()
|
||||
);
|
||||
}
|
||||
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
|
||||
if (
|
||||
this._rightEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.HorizontalAnchor.NONE
|
||||
) {
|
||||
this.owner.setX(
|
||||
right +
|
||||
this.owner.getX() -
|
||||
@@ -289,18 +362,24 @@ namespace gdjs {
|
||||
}
|
||||
// Resize if top and bottom anchors are set
|
||||
if (
|
||||
this._bottomEdgeAnchor !== VerticalAnchor.None &&
|
||||
this._topEdgeAnchor !== VerticalAnchor.None
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE &&
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setHeight(bottom - top);
|
||||
this.owner.setY(top);
|
||||
} else {
|
||||
if (this._topEdgeAnchor !== VerticalAnchor.None) {
|
||||
if (
|
||||
this._topEdgeAnchor !== AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
top + this.owner.getY() - this.owner.getDrawableY()
|
||||
);
|
||||
}
|
||||
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
|
||||
if (
|
||||
this._bottomEdgeAnchor !==
|
||||
AnchorRuntimeBehavior.VerticalAnchor.NONE
|
||||
) {
|
||||
this.owner.setY(
|
||||
bottom +
|
||||
this.owner.getY() -
|
||||
@@ -314,6 +393,19 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}
|
||||
|
||||
static HorizontalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_LEFT: 1,
|
||||
WINDOW_RIGHT: 2,
|
||||
PROPORTIONAL: 3,
|
||||
};
|
||||
static VerticalAnchor = {
|
||||
NONE: 0,
|
||||
WINDOW_TOP: 1,
|
||||
WINDOW_BOTTOM: 2,
|
||||
PROPORTIONAL: 3,
|
||||
};
|
||||
}
|
||||
gdjs.registerBehavior(
|
||||
'AnchorBehavior::AnchorBehavior',
|
||||
|
@@ -36,13 +36,6 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
usedExtensionsWithVariablesData: [],
|
||||
});
|
||||
|
||||
const setGameResolutionSizeAndStep = (width, height) => {
|
||||
runtimeGame.setGameResolutionSize(width, height);
|
||||
// This method is called by the main loop:
|
||||
runtimeScene.onGameResolutionResized();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
};
|
||||
|
||||
function createObject(behaviorProperties) {
|
||||
const object = new gdjs.TestRuntimeObject(runtimeScene, {
|
||||
name: 'obj1',
|
||||
@@ -74,10 +67,13 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window left (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
@@ -87,36 +83,29 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window right (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
expect(object.getX()).to.equal(1500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['rightEdgeAnchor', 'leftEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window center (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 4 });
|
||||
object.setPosition(500, 500);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
|
||||
expect(object.getX()).to.equal(1000);
|
||||
expect(object.getY()).to.equal(500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the right and left edge of object (fixed)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 1, rightEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
@@ -125,10 +114,13 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
|
||||
it('anchors the left edge of object (proportional)', function () {
|
||||
const object = createObject({ leftEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(1000);
|
||||
expect(object.getY()).to.equal(500);
|
||||
@@ -140,10 +132,13 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window top (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 1 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
@@ -153,36 +148,29 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window bottom (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1500);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
['topEdgeAnchor', 'bottomEdgeAnchor'].forEach((objectEdge) => {
|
||||
it(`anchors the ${objectEdge} edge of object to window center (fixed)`, function () {
|
||||
const object = createObject({ [objectEdge]: 4 });
|
||||
object.setPosition(500, 500);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1000);
|
||||
expect(object.getWidth()).to.equal(10);
|
||||
});
|
||||
});
|
||||
|
||||
it('anchors the top and bottom edge of object (fixed)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 1, bottomEdgeAnchor: 2 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(500);
|
||||
@@ -191,10 +179,13 @@ describe('gdjs.AnchorRuntimeBehavior', function () {
|
||||
|
||||
it('anchors the top edge of object (proportional)', function () {
|
||||
const object = createObject({ topEdgeAnchor: 3 });
|
||||
runtimeGame.setGameResolutionSize(1000, 1000);
|
||||
object.setPosition(500, 500);
|
||||
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
setGameResolutionSizeAndStep(2000, 2000);
|
||||
runtimeGame.setGameResolutionSize(2000, 2000);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.equal(500);
|
||||
expect(object.getY()).to.equal(1000);
|
||||
|
@@ -34,8 +34,7 @@ void DeclareDestroyOutsideBehaviorExtension(gd::PlatformExtension& extension) {
|
||||
"CppPlatform/Extensions/destroyoutsideicon.png",
|
||||
"DestroyOutsideBehavior",
|
||||
std::make_shared<DestroyOutsideBehavior>(),
|
||||
std::shared_ptr<gd::BehaviorsSharedData>())
|
||||
.SetQuickCustomizationVisibility(gd::QuickCustomization::Hidden);
|
||||
std::shared_ptr<gd::BehaviorsSharedData>());
|
||||
|
||||
aut.AddCondition("ExtraBorder",
|
||||
_("Additional border"),
|
||||
|
@@ -52,7 +52,7 @@ module.exports = {
|
||||
.setType('number');
|
||||
adjustmentProperties
|
||||
.getOrCreate('saturation')
|
||||
.setValue('1')
|
||||
.setValue('2')
|
||||
.setLabel(_('Saturation (between 0 and 5)'))
|
||||
.setType('number');
|
||||
adjustmentProperties
|
||||
@@ -77,7 +77,7 @@ module.exports = {
|
||||
.setType('number');
|
||||
adjustmentProperties
|
||||
.getOrCreate('blue')
|
||||
.setValue('1')
|
||||
.setValue('0.6')
|
||||
.setLabel(_('Blue (between 0 and 5)'))
|
||||
.setType('number');
|
||||
adjustmentProperties
|
||||
|
@@ -369,36 +369,6 @@ module.exports = {
|
||||
'gdjs.multiplayerMessageManager.hasCustomMessageBeenReceived'
|
||||
);
|
||||
|
||||
extension
|
||||
.addExpressionAndConditionAndAction(
|
||||
'number',
|
||||
'ObjectsSynchronizationRate',
|
||||
_('Objects synchronization rate'),
|
||||
_(
|
||||
'objects synchronization rate (between 1 and 60, default is 30 times per second)'
|
||||
),
|
||||
_('objects synchronization rate'),
|
||||
_('Advanced'),
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.useStandardParameters(
|
||||
'number',
|
||||
gd.ParameterOptions.makeNewOptions().setDescription(_('Sync rate'))
|
||||
)
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayer.setObjectsSynchronizationRate')
|
||||
.setGetter('gdjs.multiplayer.getObjectsSynchronizationRate');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsPlayerHost',
|
||||
@@ -422,13 +392,13 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayer.isCurrentPlayerHost');
|
||||
.setFunctionName('gdjs.multiplayer.isPlayerHost');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasAnyPlayerLeft',
|
||||
_('Any player has left'),
|
||||
_('Check if any player has left the lobby game.'),
|
||||
_('Check if any player has left the lobby.'),
|
||||
_('Any player has left'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
@@ -447,13 +417,13 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasAnyPlayerJustLeft');
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasAnyPlayerLeft');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasPlayerLeft',
|
||||
_('Player has left'),
|
||||
_('Check if the player has left the lobby game.'),
|
||||
_('Check if the player has left the lobby.'),
|
||||
_('Player _PARAM0_ has left'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
@@ -473,167 +443,7 @@ module.exports = {
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasPlayerJustLeft');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'LastLeftPlayerNumber',
|
||||
_('Player number that just left'),
|
||||
_(
|
||||
'Returns the player number of the player that has just left the lobby.'
|
||||
),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName(
|
||||
'gdjs.multiplayerMessageManager.getLatestPlayerWhoJustLeft'
|
||||
);
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasAnyPlayerJoined',
|
||||
_('Any player has joined'),
|
||||
_('Check if any player has joined the lobby.'),
|
||||
_('Any player has joined'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasAnyPlayerJustJoined');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'HasPlayerJoined',
|
||||
_('Player has joined'),
|
||||
_('Check if the player has joined the lobby.'),
|
||||
_('Player _PARAM0_ has joined'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.addParameter('number', _('Player number'), '', false)
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasPlayerJustJoined');
|
||||
|
||||
extension
|
||||
.addExpression(
|
||||
'LastJoinedPlayerNumber',
|
||||
_('Player number that just joined'),
|
||||
_(
|
||||
'Returns the player number of the player that has just joined the lobby.'
|
||||
),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName(
|
||||
'gdjs.multiplayerMessageManager.getLatestPlayerWhoJustJoined'
|
||||
);
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsMigratingHost',
|
||||
_('Host is migrating'),
|
||||
_(
|
||||
'Check if the host is migrating, in order to adapt the game state (like pausing the game).'
|
||||
),
|
||||
_('Host is migrating'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayercomponents.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayer.isMigratingHost');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'EndLobbyWhenHostLeaves',
|
||||
_('Configure lobby game to end when host leaves'),
|
||||
_(
|
||||
'Configure the lobby game to end when the host leaves. This will trigger the "Lobby game has just ended" condition. (Default behavior is to migrate the host)'
|
||||
),
|
||||
_('Configure lobby game to end when host leaves'),
|
||||
_('Advanced'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.addParameter('yesorno', _('End lobby game when host leaves'), '', false)
|
||||
.setHelpPath('/all-features/multiplayer')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayer.endLobbyWhenHostLeaves');
|
||||
.setFunctionName('gdjs.multiplayerMessageManager.hasPlayerLeft');
|
||||
|
||||
extension
|
||||
.addStrExpression(
|
||||
@@ -710,37 +520,6 @@ module.exports = {
|
||||
.useStandardParameters('number', gd.ParameterOptions.makeNewOptions())
|
||||
.setFunctionName('gdjs.multiplayer.getPlayersInLobbyCount');
|
||||
|
||||
extension
|
||||
.addCondition(
|
||||
'IsPlayerConnected',
|
||||
_('Player is connected'),
|
||||
_('Check if the specified player is connected to the lobby.'),
|
||||
_('Player _PARAM0_ is connected'),
|
||||
_('Lobbies'),
|
||||
'JsPlatform/Extensions/multiplayer.svg',
|
||||
'JsPlatform/Extensions/multiplayer.svg'
|
||||
)
|
||||
.addParameter(
|
||||
'number',
|
||||
_('The position of the player in the lobby (1, 2, ...)'),
|
||||
'',
|
||||
false
|
||||
)
|
||||
.setHelpPath('/all-features/multiplayer')
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationcomponents.js'
|
||||
)
|
||||
.addIncludeFile(
|
||||
'Extensions/PlayerAuthentication/playerauthenticationtools.js'
|
||||
)
|
||||
.addIncludeFile('Extensions/Multiplayer/messageManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayerVariablesManager.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/multiplayertools.js')
|
||||
.setFunctionName('gdjs.multiplayer.isPlayerConnected');
|
||||
|
||||
extension
|
||||
.addExpressionAndCondition(
|
||||
'number',
|
||||
@@ -1086,7 +865,6 @@ module.exports = {
|
||||
multiplayerObjectBehavior,
|
||||
sharedData
|
||||
)
|
||||
.setQuickCustomizationVisibility(gd.QuickCustomization.Hidden)
|
||||
.setIncludeFile('Extensions/Multiplayer/peer.js')
|
||||
.addIncludeFile('Extensions/Multiplayer/peerJsHelper.js')
|
||||
.addIncludeFile(
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -208,10 +208,7 @@ namespace gdjs {
|
||||
};
|
||||
|
||||
const handleChangeVariableOwnerMessagesToSend = function () {
|
||||
if (
|
||||
!gdjs.multiplayer.isLobbyGameRunning() ||
|
||||
!gdjs.multiplayer.isReadyToSendOrReceiveGameUpdateMessages()
|
||||
) {
|
||||
if (!gdjs.multiplayer.isLobbyGameRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -11,8 +11,6 @@ namespace gdjs {
|
||||
|
||||
let canLobbyBeClosed = true;
|
||||
|
||||
const notificationContainerIds: string[] = [];
|
||||
|
||||
export const getDomElementContainer = (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): HTMLDivElement | null => {
|
||||
@@ -389,7 +387,7 @@ namespace gdjs {
|
||||
// to allow the player to leave the lobby.
|
||||
setTimeout(() => {
|
||||
closeContainer.style.visibility = 'inherit';
|
||||
}, 10000);
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -398,12 +396,12 @@ namespace gdjs {
|
||||
export const displayErrorNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
showNotification({
|
||||
showNotification(
|
||||
runtimeScene,
|
||||
content:
|
||||
'An error occurred while displaying the game lobbies, please try again.',
|
||||
type: 'error',
|
||||
});
|
||||
'error-notification',
|
||||
'An error occurred while displaying the game lobbies, please try again.',
|
||||
'error'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -413,138 +411,37 @@ namespace gdjs {
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
playerName: string
|
||||
) {
|
||||
showNotification({
|
||||
showNotification(
|
||||
runtimeScene,
|
||||
content: `${playerName} left.`,
|
||||
type: 'warning',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create, display, and hide a notification when a player joins the game.
|
||||
*/
|
||||
export const displayPlayerJoinedNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
playerName: string
|
||||
) {
|
||||
showNotification({
|
||||
runtimeScene,
|
||||
content: `${playerName} joined.`,
|
||||
type: 'success',
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create, display, and hide a notification when an error happens on connection.
|
||||
*/
|
||||
export const displayConnectionErrorNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
showNotification({
|
||||
runtimeScene,
|
||||
content: 'Could not connect to other players.',
|
||||
type: 'error',
|
||||
});
|
||||
'player-left-notification',
|
||||
`${playerName} has left the game.`,
|
||||
'warning'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create, display, and hide a notification when a player leaves the game.
|
||||
*/
|
||||
export const displayHostMigrationNotification = function (
|
||||
export const displayConnectionErrorNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
showNotification({
|
||||
showNotification(
|
||||
runtimeScene,
|
||||
content: `Migrating host...`,
|
||||
type: 'warning',
|
||||
id: 'migrating-host',
|
||||
persist: true,
|
||||
});
|
||||
};
|
||||
|
||||
export const showHostMigrationFinishedNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
removeNotificationAndShiftOthers('migrating-host');
|
||||
showNotification({
|
||||
runtimeScene,
|
||||
content: `Host migrated!`,
|
||||
type: 'success',
|
||||
});
|
||||
};
|
||||
|
||||
export const showHostMigrationFailedNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
) {
|
||||
removeNotificationAndShiftOthers('migrating-host');
|
||||
showNotification({
|
||||
runtimeScene,
|
||||
content: `Host migration failed.`,
|
||||
type: 'error',
|
||||
});
|
||||
};
|
||||
|
||||
const removeNotificationAndShiftOthers = function (
|
||||
notificationContainerId: string
|
||||
) {
|
||||
const notification = document.getElementById(notificationContainerId);
|
||||
if (!notification) {
|
||||
logger.warn(
|
||||
`Notification ${notificationContainerId} not found. skipping`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const index = notificationContainerIds.indexOf(notificationContainerId);
|
||||
if (index !== -1) {
|
||||
notificationContainerIds.splice(index, 1);
|
||||
}
|
||||
notification.remove();
|
||||
|
||||
// Shift the notifications that are below the one that was removed up.
|
||||
for (let i = index; i < notificationContainerIds.length; i++) {
|
||||
const notification = document.getElementById(
|
||||
notificationContainerIds[i]
|
||||
);
|
||||
if (!notification) {
|
||||
logger.error('Notification not found.');
|
||||
continue;
|
||||
}
|
||||
notification.style.top = `${12 + i * 32}px`;
|
||||
}
|
||||
'connection-error-notification',
|
||||
'Could not connect to other players.',
|
||||
'error'
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to show a notification to the user, that disappears automatically.
|
||||
*/
|
||||
export const showNotification = function ({
|
||||
runtimeScene,
|
||||
content,
|
||||
type,
|
||||
id,
|
||||
persist,
|
||||
}: {
|
||||
runtimeScene: gdjs.RuntimeScene;
|
||||
content: string;
|
||||
type: 'success' | 'warning' | 'error';
|
||||
id?: string;
|
||||
persist?: boolean;
|
||||
}) {
|
||||
// When we show a notification, we add it below the other ones.
|
||||
// We also remove the oldest one if there are too many > 5.
|
||||
if (notificationContainerIds.length > 5) {
|
||||
const oldestNotificationId = notificationContainerIds.shift();
|
||||
if (!oldestNotificationId) {
|
||||
logger.error('No oldest notification ID found.');
|
||||
return;
|
||||
}
|
||||
|
||||
removeNotificationAndShiftOthers(oldestNotificationId);
|
||||
}
|
||||
|
||||
// We generate a random ID for the notification, so they can stack.
|
||||
const notificationId =
|
||||
id || `notification-${Math.random().toString(36).substring(7)}`;
|
||||
|
||||
export const showNotification = function (
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
id: string,
|
||||
content: string,
|
||||
type: 'success' | 'warning' | 'error'
|
||||
) {
|
||||
const domContainer = runtimeScene
|
||||
.getGame()
|
||||
.getRenderer()
|
||||
@@ -555,7 +452,7 @@ namespace gdjs {
|
||||
}
|
||||
const divContainer = document.createElement('div');
|
||||
|
||||
divContainer.id = notificationId;
|
||||
divContainer.id = id;
|
||||
divContainer.style.position = 'absolute';
|
||||
divContainer.style.pointerEvents = 'all';
|
||||
divContainer.style.backgroundColor =
|
||||
@@ -564,8 +461,7 @@ namespace gdjs {
|
||||
: type === 'warning'
|
||||
? '#FFA500'
|
||||
: '#FF0000';
|
||||
// Space the notifications vertically, based on how many there are.
|
||||
divContainer.style.top = `${12 + notificationContainerIds.length * 32}px`;
|
||||
divContainer.style.top = '12px';
|
||||
divContainer.style.right = '16px';
|
||||
divContainer.style.padding = '6px 32px 6px 6px';
|
||||
// Use zIndex 1 to make sure it is below the iframe.
|
||||
@@ -600,15 +496,10 @@ namespace gdjs {
|
||||
loggedText.style.margin = '0px';
|
||||
|
||||
divContainer.appendChild(loggedText);
|
||||
|
||||
domContainer.appendChild(divContainer);
|
||||
notificationContainerIds.push(notificationId);
|
||||
|
||||
if (persist) {
|
||||
return;
|
||||
}
|
||||
|
||||
const animationTime = 700;
|
||||
const notificationTime = 3000;
|
||||
const notificationTime = 5000;
|
||||
setTimeout(() => {
|
||||
try {
|
||||
divContainer.animate(
|
||||
@@ -627,7 +518,7 @@ namespace gdjs {
|
||||
}, notificationTime);
|
||||
// Use timeout because onanimationend listener does not work.
|
||||
setTimeout(() => {
|
||||
removeNotificationAndShiftOthers(notificationId);
|
||||
divContainer.remove();
|
||||
}, notificationTime + animationTime);
|
||||
};
|
||||
|
||||
|
@@ -24,46 +24,48 @@ namespace gdjs {
|
||||
actionOnPlayerDisconnect: string;
|
||||
|
||||
// The last time the object has been synchronized.
|
||||
// This is to avoid synchronizing the object too often, see _objectMaxSyncRate.
|
||||
// This is to avoid synchronizing the object too often, see _objectMaxTickRate.
|
||||
_lastObjectSyncTimestamp: number = 0;
|
||||
// The number of times per second the object should be synchronized if it keeps changing.
|
||||
_objectMaxTickRate: number = 60;
|
||||
|
||||
// The last time the basic object info has been synchronized.
|
||||
_lastBasicObjectSyncTimestamp: number = 0;
|
||||
// The number of times per second the object basic info should be synchronized when it doesn't change.
|
||||
_objectBasicInfoSyncRate: number = 5;
|
||||
_objectBasicInfoTickRate: number = 5;
|
||||
// The last data sent to synchronize the basic info of the object.
|
||||
_lastSentBasicObjectSyncData: BasicObjectNetworkSyncData | undefined;
|
||||
// When we know that the basic info of the object has been updated, we can force sending them
|
||||
// on the max SyncRate for a number of times to ensure they are received, without the need of an acknowledgment.
|
||||
// on the max tickrate for a number of times to ensure they are received, without the need of an acknowledgment.
|
||||
_numberOfForcedBasicObjectUpdates: number = 0;
|
||||
|
||||
// The last time the variables have been synchronized.
|
||||
_lastVariablesSyncTimestamp: number = 0;
|
||||
// The number of times per second the variables should be synchronized.
|
||||
_variablesSyncRate: number = 1;
|
||||
_variablesTickRate: number = 1;
|
||||
// The last data sent to synchronize the variables.
|
||||
_lastSentVariableSyncData: VariableNetworkSyncData[] | undefined;
|
||||
// When we know that the variables have been updated, we can force sending them
|
||||
// on the same syncRate as the object update for a number of times
|
||||
// on the same tickrate as the object update for a number of times
|
||||
// to ensure they are received, without the need of an acknowledgment.
|
||||
_numberOfForcedVariablesUpdates: number = 0;
|
||||
|
||||
// The last time the effects have been synchronized.
|
||||
_lastEffectsSyncTimestamp: number = 0;
|
||||
// The number of times per second the effects should be synchronized.
|
||||
_effectsSyncRate: number = 1;
|
||||
_effectsTickRate: number = 1;
|
||||
// The last data sent to synchronize the effects.
|
||||
_lastSentEffectSyncData:
|
||||
| { [effectName: string]: EffectNetworkSyncData }
|
||||
| undefined;
|
||||
// When we know that the effects have been updated, we can force sending them
|
||||
// on the same syncRate as the object update for a number of times
|
||||
// on the same tickrate as the object update for a number of times
|
||||
// to ensure they are received, without the need of an acknowledgment.
|
||||
_numberOfForcedEffectsUpdates: number = 0;
|
||||
|
||||
// To avoid seeing too many logs.
|
||||
_lastLogTimestamp: number = 0;
|
||||
_logSyncRate: number = 1;
|
||||
_logTickRate: number = 1;
|
||||
// Clock to be incremented every time we send a message, to ensure they are ordered
|
||||
// and old messages are ignored.
|
||||
_clock: number = 0;
|
||||
@@ -90,14 +92,9 @@ namespace gdjs {
|
||||
// To handle this case and avoid having an object not synchronized, we set a timeout to destroy the object
|
||||
// if it has not been assigned a networkId after a short delay.
|
||||
this._destroyInstanceTimeoutId = setTimeout(() => {
|
||||
const sceneNetworkId = this.owner.getRuntimeScene().networkId;
|
||||
if (
|
||||
!owner.networkId &&
|
||||
gdjs.multiplayer.isLobbyGameRunning() &&
|
||||
sceneNetworkId
|
||||
) {
|
||||
if (!owner.networkId && gdjs.multiplayer.isLobbyGameRunning()) {
|
||||
debugLogger.info(
|
||||
`Lobby game is running on a synced scene and object ${owner.getName()} has not been assigned a networkId after a short delay, destroying it.`
|
||||
`Lobby game is running and object ${owner.getName()} has not been assigned a networkId after a short delay, destroying it.`
|
||||
);
|
||||
owner.deleteFromScene(instanceContainer);
|
||||
}
|
||||
@@ -129,35 +126,35 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
private _hasObjectBeenSyncedWithinMaxRate() {
|
||||
const objectMaxSyncRate = gdjs.multiplayer.getObjectsSynchronizationRate();
|
||||
return (
|
||||
getTimeNow() - this._lastObjectSyncTimestamp < 1000 / objectMaxSyncRate
|
||||
getTimeNow() - this._lastObjectSyncTimestamp <
|
||||
1000 / this._objectMaxTickRate
|
||||
);
|
||||
}
|
||||
|
||||
private _hasObjectBasicInfoBeenSyncedRecently() {
|
||||
return (
|
||||
getTimeNow() - this._lastBasicObjectSyncTimestamp <
|
||||
1000 / this._objectBasicInfoSyncRate
|
||||
1000 / this._objectBasicInfoTickRate
|
||||
);
|
||||
}
|
||||
|
||||
private _haveVariablesBeenSyncedRecently() {
|
||||
return (
|
||||
getTimeNow() - this._lastVariablesSyncTimestamp <
|
||||
1000 / this._variablesSyncRate
|
||||
1000 / this._variablesTickRate
|
||||
);
|
||||
}
|
||||
|
||||
private _haveEffectsBeenSyncedRecently() {
|
||||
return (
|
||||
getTimeNow() - this._lastEffectsSyncTimestamp <
|
||||
1000 / this._effectsSyncRate
|
||||
1000 / this._effectsTickRate
|
||||
);
|
||||
}
|
||||
|
||||
// private _logToConsoleWithThrottle(message: string) {
|
||||
// if (getTimeNow() - this._lastLogTimestamp > 1000 / this._logSyncRate) {
|
||||
// if (getTimeNow() - this._lastLogTimestamp > 1000 / this._logTickRate) {
|
||||
// logger.info(message);
|
||||
// this._lastLogTimestamp = getTimeNow();
|
||||
// }
|
||||
@@ -165,9 +162,12 @@ namespace gdjs {
|
||||
|
||||
private _getOrCreateInstanceNetworkId() {
|
||||
if (!this.owner.networkId) {
|
||||
// No ID for this object, let's generate one so it can be identified by other players.
|
||||
// no ID for this object, let's generate one so it can be identified by other players.
|
||||
// Either use the persistentUuid if it exists, or generate a new one.
|
||||
// Keep it short to avoid sending too much data.
|
||||
const newID = gdjs.makeUuid().substring(0, 8);
|
||||
const newID = this.owner.persistentUuid
|
||||
? this.owner.persistentUuid.substring(0, 8)
|
||||
: gdjs.makeUuid().substring(0, 8);
|
||||
this.owner.networkId = newID;
|
||||
}
|
||||
|
||||
@@ -250,8 +250,7 @@ namespace gdjs {
|
||||
return;
|
||||
}
|
||||
|
||||
// If game is running and the object belongs to a player who is not connected, destroy the object.
|
||||
// As the game may create objects before the lobby game starts, we don't want to destroy them if it's not running.
|
||||
// If game is running and object belong to a player that is not connected, destroy the object.
|
||||
if (
|
||||
this.playerNumber !== 0 && // Host is always connected.
|
||||
!gdjs.multiplayerMessageManager.isPlayerConnected(this.playerNumber)
|
||||
@@ -406,17 +405,15 @@ namespace gdjs {
|
||||
this._destroyInstanceTimeoutId = null;
|
||||
}
|
||||
|
||||
// If the lobby game is not running, no need to send a message to destroy the object.
|
||||
// If the lobby game is not running, do not try to destroy the object,
|
||||
// as the game may create objects before the lobby game starts, and we don't want to destroy them.
|
||||
if (!gdjs.multiplayer.isLobbyGameRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For destruction of objects, we allow the host to destroy the object even if it is not the owner.
|
||||
// This is particularly helpful when a player disconnects, so the host can destroy the object they were owning.
|
||||
if (
|
||||
!this._isOwnerAsPlayerOrHost() &&
|
||||
!gdjs.multiplayer.isCurrentPlayerHost()
|
||||
) {
|
||||
if (!this._isOwnerAsPlayerOrHost() && !gdjs.multiplayer.isPlayerHost()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -254,11 +254,6 @@ namespace gdjs {
|
||||
connection.on('close', () => {
|
||||
_onDisconnect(connection.peer);
|
||||
});
|
||||
connection.on('iceStateChanged', (state) => {
|
||||
if (state === 'disconnected') {
|
||||
_onDisconnect(connection.peer);
|
||||
}
|
||||
});
|
||||
|
||||
// Regularly check for disconnection as the built in way is not reliable.
|
||||
(function disconnectChecker() {
|
||||
@@ -433,7 +428,7 @@ namespace gdjs {
|
||||
export const isReady = () => ready;
|
||||
|
||||
/**
|
||||
* Return peers that have disconnected in the frame.
|
||||
* Return any disconnected peers.
|
||||
*/
|
||||
export const getJustDisconnectedPeers = () => justDisconnectedPeers;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user