mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
191 Commits
allow-bump
...
v5.4.213
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6cda5d08be | ||
![]() |
1a3a27b73b | ||
![]() |
96d912a6f2 | ||
![]() |
ed3acd5f0d | ||
![]() |
3f269206d1 | ||
![]() |
76b5aefdbc | ||
![]() |
9ef7af803c | ||
![]() |
c77f9b9e0c | ||
![]() |
035ddb8a7a | ||
![]() |
e7dac1bafc | ||
![]() |
54f00e7c57 | ||
![]() |
0bf9dae2b0 | ||
![]() |
428aac8ab0 | ||
![]() |
9391fc2841 | ||
![]() |
cea34337c6 | ||
![]() |
dc45f3dae5 | ||
![]() |
0ca26a865e | ||
![]() |
1bce13f326 | ||
![]() |
34f8f5750a | ||
![]() |
3b9a612094 | ||
![]() |
3a84ed7c89 | ||
![]() |
ef604fd442 | ||
![]() |
d88dc4772f | ||
![]() |
02d40a1d52 | ||
![]() |
35082825d4 | ||
![]() |
6a7c3daa8e | ||
![]() |
95af02bada | ||
![]() |
30516a903e | ||
![]() |
762f7ca19c | ||
![]() |
852bf78c81 | ||
![]() |
b0da0cee34 | ||
![]() |
73771f938b | ||
![]() |
b9dbe6dbb5 | ||
![]() |
0c2341c6e5 | ||
![]() |
e9b4de2ca9 | ||
![]() |
75a4114ce8 | ||
![]() |
20abb9b45a | ||
![]() |
56436fd44a | ||
![]() |
0dd5fc55c9 | ||
![]() |
93db4cb508 | ||
![]() |
f7888abf45 | ||
![]() |
c8144da704 | ||
![]() |
832e8cd593 | ||
![]() |
ef66a9f1a4 | ||
![]() |
5efbaa8c58 | ||
![]() |
ecbf38ccda | ||
![]() |
b3fcfc3f55 | ||
![]() |
a515836add | ||
![]() |
a7c81b47b2 | ||
![]() |
0f22e462ad | ||
![]() |
e6e4d9048f | ||
![]() |
12f5f95d0c | ||
![]() |
c52168a967 | ||
![]() |
1e33a13cc5 | ||
![]() |
505debd60c | ||
![]() |
e3b7109154 | ||
![]() |
9e25899d3e | ||
![]() |
87cb8f0d47 | ||
![]() |
481c6da992 | ||
![]() |
7cbebbb82f | ||
![]() |
fcf668788b | ||
![]() |
0cc844a77f | ||
![]() |
a234d9bd35 | ||
![]() |
465a6ce2ab | ||
![]() |
7e2e19eb33 | ||
![]() |
95101763f7 | ||
![]() |
d4bd5fc671 | ||
![]() |
c7fcf48ba5 | ||
![]() |
8926d4406f | ||
![]() |
9ed2173038 | ||
![]() |
2fc3bc337f | ||
![]() |
0b7cac79ef | ||
![]() |
8721c0099e | ||
![]() |
4453eee3b9 | ||
![]() |
0215ab7dbb | ||
![]() |
87f6d5b99f | ||
![]() |
a440b16f84 | ||
![]() |
f3822ba0df | ||
![]() |
6c5813affd | ||
![]() |
be4fe62bb6 | ||
![]() |
0a29999894 | ||
![]() |
e8ac41f37e | ||
![]() |
70657ae334 | ||
![]() |
39ae2d4852 | ||
![]() |
39815bfe6c | ||
![]() |
9ff8db25dd | ||
![]() |
1da887f656 | ||
![]() |
e88ae0a7a9 | ||
![]() |
7ae74990b2 | ||
![]() |
22ea1ce42c | ||
![]() |
a54367e360 | ||
![]() |
011abaf808 | ||
![]() |
a606a6567a | ||
![]() |
c9a6b88422 | ||
![]() |
e7f7fb1583 | ||
![]() |
3cbb6644d4 | ||
![]() |
d34db53e09 | ||
![]() |
9c62a5e0f1 | ||
![]() |
4b04101638 | ||
![]() |
ad31a7843a | ||
![]() |
57371c3759 | ||
![]() |
6e7fc75e75 | ||
![]() |
65653c92d6 | ||
![]() |
a4106b7f79 | ||
![]() |
3e9f2f3f3a | ||
![]() |
45f25df292 | ||
![]() |
55eddb4972 | ||
![]() |
75566c9f38 | ||
![]() |
8db8cbe3c2 | ||
![]() |
dd8c5dce2e | ||
![]() |
2810056626 | ||
![]() |
d082d4f5a4 | ||
![]() |
eaa0f4077f | ||
![]() |
7d73f58bc4 | ||
![]() |
9171b40429 | ||
![]() |
242fc49342 | ||
![]() |
7081fd570c | ||
![]() |
34ecdce7fa | ||
![]() |
3a0903a19f | ||
![]() |
e1a4f88ba6 | ||
![]() |
ed59498835 | ||
![]() |
4b70653a0b | ||
![]() |
48dd91043a | ||
![]() |
30e7ef5865 | ||
![]() |
289c555fe4 | ||
![]() |
803a55869c | ||
![]() |
282f4c184f | ||
![]() |
875237cc8b | ||
![]() |
7aeb44d05e | ||
![]() |
e445ff710e | ||
![]() |
e016babf71 | ||
![]() |
6a34e3c1db | ||
![]() |
82e819c033 | ||
![]() |
72e5deeef3 | ||
![]() |
a91cc4557f | ||
![]() |
b2c953a31d | ||
![]() |
b29fbaa1f8 | ||
![]() |
e8faa17e12 | ||
![]() |
2585ad5dca | ||
![]() |
a9108fa87b | ||
![]() |
cd3186d2d8 | ||
![]() |
6a737f7d51 | ||
![]() |
9211aa7a3b | ||
![]() |
864ba181e9 | ||
![]() |
10fa3296a9 | ||
![]() |
2fb39b9dbe | ||
![]() |
6f43e896d6 | ||
![]() |
122df05f99 | ||
![]() |
b7a5122b07 | ||
![]() |
eb9d680d95 | ||
![]() |
354da42a9e | ||
![]() |
aca37fdade | ||
![]() |
bb6eb01153 | ||
![]() |
9fb086dcdf | ||
![]() |
7e60a0246e | ||
![]() |
3cb2da3de5 | ||
![]() |
ef23470a00 | ||
![]() |
196ea5e480 | ||
![]() |
e732f1952c | ||
![]() |
f5f024cc42 | ||
![]() |
6a3df62598 | ||
![]() |
75f049d911 | ||
![]() |
4d0ac6f355 | ||
![]() |
00a5c93b35 | ||
![]() |
a90cc83967 | ||
![]() |
87a5934df3 | ||
![]() |
d0245b8f1a | ||
![]() |
45d73df6fb | ||
![]() |
7ac600e92d | ||
![]() |
7ba8d0133e | ||
![]() |
e9adaa94c5 | ||
![]() |
35da31c5c5 | ||
![]() |
e65492e1a1 | ||
![]() |
44827ea372 | ||
![]() |
ab3ffe6785 | ||
![]() |
d83d049ac9 | ||
![]() |
67a7bd7af2 | ||
![]() |
6db5267878 | ||
![]() |
a51c223c9c | ||
![]() |
0a4e5a1012 | ||
![]() |
acce714736 | ||
![]() |
3c34a8806b | ||
![]() |
1d4cb7bef0 | ||
![]() |
7badacd24a | ||
![]() |
11ab92fc0e | ||
![]() |
ddb1e335bc | ||
![]() |
8d035a774d | ||
![]() |
5b1e3565d3 | ||
![]() |
8c88038bfb | ||
![]() |
f62811974d | ||
![]() |
b516037d2b |
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,12 +1,11 @@
|
||||
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
|
||||
Core/GDCore/TinyXml/* linguist-vendored
|
||||
Extensions/ParticleSystem/SPARK/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/box2djs/* linguist-vendored
|
||||
Extensions/Physics2Behavior/box2d.js linguist-vendored
|
||||
Extensions/BBText/pixi-multistyle-text/* linguist-vendored
|
||||
Extensions/P2P/A_peer.js linguist-vendored
|
||||
Extensions/Multiplayer/peer.js linguist-vendored
|
||||
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
|
||||
Extensions/TileMap/pako/* linguist-vendored
|
||||
Extensions/TileMap/pixi-tilemap/* linguist-vendored
|
||||
Extensions/TweenBehavior/shifty.js linguist-vendored
|
||||
|
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,police,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,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})"
|
||||
]
|
||||
},
|
||||
"Add code only parameter": {
|
||||
|
@@ -60,7 +60,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_
|
||||
endif()
|
||||
|
||||
#Activate C++11
|
||||
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 would need to remove usage of bind2nd (should be easy).
|
||||
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 should be tried.
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Mark some warnings as errors
|
||||
|
@@ -11,6 +11,11 @@ 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:
|
||||
#
|
||||
|
||||
|
@@ -58,99 +58,7 @@
|
||||
* Common functions and tools for programming.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup TinyXml Integrated TinyXml library
|
||||
*
|
||||
* See the full documentation of TinyXml [here](http://www.grinninglizard.com/tinyxmldocs/index.html).
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup SpriteObjectExtension Standard Sprite Object extension
|
||||
* \ingroup BuiltinExtensions
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class TiXmlAttribute
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlAttributeSet
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlBase
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlComment
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlCursor
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlDeclaration
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlDocument
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlElement
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlHandle
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlNode
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlOutStream
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlParsingData
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlPrinter
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlString
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlText
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlUnknown
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
/**
|
||||
* \class TiXmlVisitor
|
||||
* \brief Part of the tinyxml library
|
||||
* \ingroup TinyXml
|
||||
*/
|
||||
*/
|
@@ -8,7 +8,6 @@
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -47,6 +48,9 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
|
||||
// TODO Merge with UsedExtensionsFinder.
|
||||
|
||||
// TODO Factorize with the iteration on all effects for resource exposure.
|
||||
// TODO Implement an ArbitraryEffectWorker and add a method in ProjectBrowserHelper
|
||||
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources) and
|
||||
// WholeProjectRefactorer::ExposeProjectEvents.
|
||||
@@ -68,6 +72,27 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
|
||||
// Add objects effects
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
|
||||
|
||||
// Add event-based objects layouts effects
|
||||
for (std::size_t s = 0; s < project.GetEventsFunctionsExtensionsCount();
|
||||
s++) {
|
||||
auto &eventsFunctionExtension = project.GetEventsFunctionsExtension(s);
|
||||
|
||||
auto &eventsBasedObjects = eventsFunctionExtension.GetEventsBasedObjects();
|
||||
for (std::size_t objectIndex = 0;
|
||||
objectIndex < eventsBasedObjects.GetCount(); ++objectIndex) {
|
||||
auto &eventsBasedObject = eventsBasedObjects.Get(objectIndex);
|
||||
|
||||
auto &layers = eventsBasedObject.GetLayers();
|
||||
for (std::size_t l = 0; l < layers.GetLayersCount(); ++l) {
|
||||
auto &effects = layers.GetLayer(l).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
|
||||
auto &effect = effects.GetEffect(e);
|
||||
effectsCodeGenerator.AddEffectIncludeFiles(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -42,14 +42,15 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t relationalOperatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
std::size_t relationalOperatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
++i) {
|
||||
if (instrInfos.parameters[i].GetType() == "relationalOperator")
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "relationalOperator") {
|
||||
relationalOperatorIndex = i;
|
||||
}
|
||||
}
|
||||
// Ensure that there is at least one parameter after the relational operator
|
||||
if (relationalOperatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
if (relationalOperatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -76,11 +77,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,
|
||||
@@ -122,14 +123,16 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
|
||||
const gd::String& callStartString,
|
||||
const gd::String& getterStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
++i) {
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -191,14 +194,16 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
++i) {
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -242,14 +247,16 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
|
||||
const vector<gd::String>& arguments,
|
||||
const gd::String& callStartString,
|
||||
std::size_t startFromArgument) {
|
||||
std::size_t operatorIndex = instrInfos.parameters.size();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
|
||||
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount();
|
||||
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount();
|
||||
++i) {
|
||||
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") {
|
||||
operatorIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that there is at least one parameter after the operator
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.size()) {
|
||||
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) {
|
||||
ReportError();
|
||||
return "";
|
||||
}
|
||||
@@ -316,7 +323,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
}
|
||||
|
||||
// Insert code only parameters and be sure there is no lack of parameter.
|
||||
while (condition.GetParameters().size() < instrInfos.parameters.size()) {
|
||||
while (condition.GetParameters().size() < instrInfos.parameters.GetParametersCount()) {
|
||||
vector<gd::Expression> parameters = condition.GetParameters();
|
||||
parameters.push_back(gd::Expression(""));
|
||||
condition.SetParameters(parameters);
|
||||
@@ -324,13 +331,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.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
gd::String objectInParameter =
|
||||
condition.GetParameter(pNb).GetPlainString();
|
||||
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
@@ -353,7 +360,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
gd::String objectName = condition.GetParameter(0).GetPlainString();
|
||||
if (!objectName.empty() && !instrInfos.parameters.empty()) {
|
||||
if (!objectName.empty() && instrInfos.parameters.GetParametersCount() > 0) {
|
||||
std::vector<gd::String> realObjects =
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
@@ -381,7 +388,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
if (instrInfos.parameters.GetParametersCount() >= 2) {
|
||||
const gd::String &objectName = condition.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName =
|
||||
condition.GetParameter(1).GetPlainString();
|
||||
@@ -539,7 +546,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
: instrInfos.codeExtraInformation.functionCallName;
|
||||
|
||||
// Be sure there is no lack of parameter.
|
||||
while (action.GetParameters().size() < instrInfos.parameters.size()) {
|
||||
while (action.GetParameters().size() < instrInfos.parameters.GetParametersCount()) {
|
||||
vector<gd::Expression> parameters = action.GetParameters();
|
||||
parameters.push_back(gd::Expression(""));
|
||||
action.SetParameters(parameters);
|
||||
@@ -547,12 +554,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.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
|
||||
|
||||
const auto &expectedObjectType =
|
||||
instrInfos.parameters[pNb].GetExtraInfo();
|
||||
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
|
||||
const auto &actualObjectType =
|
||||
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
|
||||
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
|
||||
@@ -577,7 +584,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
if (instrInfos.IsObjectInstruction()) {
|
||||
gd::String objectName = action.GetParameter(0).GetPlainString();
|
||||
|
||||
if (!instrInfos.parameters.empty()) {
|
||||
if (instrInfos.parameters.GetParametersCount() > 0) {
|
||||
std::vector<gd::String> realObjects =
|
||||
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
@@ -605,7 +612,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
if (instrInfos.parameters.size() >= 2) {
|
||||
if (instrInfos.parameters.GetParametersCount() >= 2) {
|
||||
const gd::String &objectName = action.GetParameter(0).GetPlainString();
|
||||
const gd::String &behaviorName = action.GetParameter(1).GetPlainString();
|
||||
const gd::String &actualBehaviorType =
|
||||
@@ -821,7 +828,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "spineResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
|
||||
metadata.GetType() == "soundfile") {
|
||||
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
|
||||
} else if (metadata.GetType() == "mouse") {
|
||||
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
|
||||
@@ -863,7 +870,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
|
||||
vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
|
||||
const vector<gd::Expression>& parameters,
|
||||
const vector<gd::ParameterMetadata>& parametersInfo,
|
||||
const ParameterMetadataContainer& parametersInfo,
|
||||
EventsCodeGenerationContext& context,
|
||||
std::vector<std::pair<gd::String, gd::String> >*
|
||||
supplementaryParametersTypes) {
|
||||
@@ -1000,7 +1007,7 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
|
||||
|
||||
output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" +
|
||||
eventCoreCode + "\n" + scopeEnd + "\n";
|
||||
|
||||
|
||||
if (event.HasVariables()) {
|
||||
GetProjectScopedContainers().GetVariablesContainersList().Pop();
|
||||
}
|
||||
@@ -1100,10 +1107,10 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
|
||||
// Add logical not if needed
|
||||
bool conditionAlreadyTakeCareOfInversion = false;
|
||||
for (std::size_t i = 0; i < instrInfos.parameters.size();
|
||||
for (std::size_t i = 0; i < instrInfos.parameters.GetParametersCount();
|
||||
++i) // Some conditions already have a "conditionInverted" parameter
|
||||
{
|
||||
if (instrInfos.parameters[i].GetType() == "conditionInverted")
|
||||
if (instrInfos.parameters.GetParameter(i).GetType() == "conditionInverted")
|
||||
conditionAlreadyTakeCareOfInversion = true;
|
||||
}
|
||||
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
|
||||
@@ -1124,7 +1131,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
// Prepare call
|
||||
// Add a static_cast if necessary
|
||||
gd::String objectFunctionCallNamePart =
|
||||
(!instrInfos.parameters[0].GetExtraInfo().empty())
|
||||
(!instrInfos.parameters.GetParameter(0).GetExtraInfo().empty())
|
||||
? "static_cast<" + objInfo.className + "*>(" +
|
||||
GetObjectListName(objectName, context) + "[i])->" +
|
||||
instrInfos.codeExtraInformation.functionCallName
|
||||
@@ -1179,8 +1186,13 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
|
||||
// Generate call
|
||||
gd::String call;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string" ||
|
||||
instrInfos.codeExtraInformation.type == "boolean") {
|
||||
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)) {
|
||||
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 std::vector<gd::ParameterMetadata>& parametersInfo,
|
||||
const ParameterMetadataContainer& 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, police -> string
|
||||
soundfile -> 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.parameters.size();
|
||||
i < expressionMetadata.GetParameters().GetParametersCount();
|
||||
++i) {
|
||||
if (i != initialParameterIndex) parametersCode += ", ";
|
||||
|
||||
auto& parameterMetadata = expressionMetadata.parameters[i];
|
||||
auto& parameterMetadata = expressionMetadata.GetParameters().GetParameter(i);
|
||||
if (!parameterMetadata.IsCodeOnly()) {
|
||||
if (nonCodeOnlyParameterIndex < parameters.size()) {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
|
@@ -18,7 +18,6 @@ class BaseEvent;
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
class TiXmlElement;
|
||||
|
||||
#undef CreateEvent
|
||||
|
||||
|
@@ -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.size();
|
||||
j < parameters.size() && j < metadata.parameters.GetParametersCount();
|
||||
++j) {
|
||||
if (metadata.parameters[j].GetType() == "relationalOperator" ||
|
||||
metadata.parameters[j].GetType() == "operator") {
|
||||
if (metadata.parameters.GetParameter(j).GetType() == "relationalOperator" ||
|
||||
metadata.parameters.GetParameter(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";
|
||||
|
@@ -327,6 +327,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"CameraZoom",
|
||||
_("Camera zoom"),
|
||||
_("Compare the zoom of a camera of a layer."),
|
||||
_("Zoom of camera _PARAM2_ of layer _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Zoom")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"FixCamera",
|
||||
|
@@ -116,6 +116,13 @@ 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,6 +51,11 @@ 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,18 +24,23 @@
|
||||
namespace gd {
|
||||
|
||||
SpriteObject::SpriteObject()
|
||||
: updateIfNotVisible(false) {}
|
||||
: updateIfNotVisible(false),
|
||||
preScale(1) {}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -64,9 +69,7 @@ void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
SpriteObject::GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& initialInstance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
const gd::InitialInstance& initialInstance) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties["animation"] =
|
||||
gd::PropertyDescriptor(
|
||||
@@ -80,9 +83,7 @@ SpriteObject::GetInitialInstanceProperties(
|
||||
bool SpriteObject::UpdateInitialInstanceProperty(
|
||||
gd::InitialInstance& initialInstance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) {
|
||||
const gd::String& value) {
|
||||
if (name == "animation") {
|
||||
initialInstance.SetRawDoubleProperty(
|
||||
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
|
||||
@@ -91,6 +92,19 @@ 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;
|
||||
}
|
||||
|
@@ -47,15 +47,17 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& position,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
const gd::InitialInstance& position) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& position,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
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.
|
||||
*/
|
||||
@@ -80,6 +82,23 @@ 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;
|
||||
@@ -90,6 +109,7 @@ 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,7 +37,8 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
className(className_),
|
||||
iconFilename(icon24x24),
|
||||
instance(instance_),
|
||||
sharedDatasInstance(sharedDatasInstance_) {
|
||||
sharedDatasInstance(sharedDatasInstance_),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
SetDefaultName(gd::String(defaultName_));
|
||||
@@ -424,7 +425,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();
|
||||
}
|
||||
|
||||
@@ -440,12 +441,18 @@ std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperti
|
||||
|
||||
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
|
||||
requiredBehaviors.clear();
|
||||
for (auto& property : Get().GetProperties()) {
|
||||
if (!instance) {
|
||||
return requiredBehaviors;
|
||||
}
|
||||
for (auto& property : instance->GetProperties()) {
|
||||
const String& propertyName = property.first;
|
||||
const gd::PropertyDescriptor& propertyDescriptor = property.second;
|
||||
|
||||
if (propertyDescriptor.GetType() == "Behavior") {
|
||||
requiredBehaviors.push_back(propertyDescriptor.GetExtraInfo()[0]);
|
||||
const auto& extraInfos = propertyDescriptor.GetExtraInfo();
|
||||
if (extraInfos.size() > 0) {
|
||||
requiredBehaviors.push_back(extraInfos[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return requiredBehaviors;
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#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;
|
||||
@@ -41,10 +42,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(
|
||||
@@ -297,9 +298,18 @@ 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.
|
||||
*/
|
||||
@@ -317,7 +327,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.
|
||||
*/
|
||||
@@ -374,6 +384,7 @@ 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) {
|
||||
gd::ParameterMetadata info;
|
||||
info.SetType(type);
|
||||
info.description = description;
|
||||
info.codeOnly = false;
|
||||
info.SetOptional(parameterIsOptional);
|
||||
info.SetExtraInfo(
|
||||
parameters.AddNewParameter("")
|
||||
.SetType(type)
|
||||
.SetDescription(description)
|
||||
.SetCodeOnly(false)
|
||||
.SetOptional(parameterIsOptional)
|
||||
.SetExtraInfo(
|
||||
// For objects/behavior, the supplementary information
|
||||
// parameter is an object/behavior type...
|
||||
((gd::ParameterMetadata::IsObject(type) ||
|
||||
@@ -59,22 +59,16 @@ 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) {
|
||||
gd::ParameterMetadata info;
|
||||
info.SetType(type);
|
||||
info.codeOnly = true;
|
||||
info.SetExtraInfo(supplementaryInformation);
|
||||
|
||||
parameters.push_back(info);
|
||||
gd::ExpressionMetadata &ExpressionMetadata::AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation) {
|
||||
parameters.AddNewParameter("").SetType(type).SetCodeOnly().SetExtraInfo(
|
||||
supplementaryInformation);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
|
||||
const gd::String& capability) {
|
||||
requiredBaseObjectCapability = capability;
|
||||
|
@@ -193,8 +193,9 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetDefaultValue(defaultValue);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue);
|
||||
}
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -206,8 +207,9 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
ExpressionMetadata &
|
||||
SetParameterLongDescription(const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
|
||||
}
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -220,7 +222,9 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
ExpressionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -248,19 +252,16 @@ 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[id];
|
||||
return parameters.GetParameter(id);
|
||||
};
|
||||
gd::ParameterMetadata& GetParameter(std::size_t id) {
|
||||
return parameters[id];
|
||||
return parameters.GetParameter(id);
|
||||
};
|
||||
std::size_t GetParametersCount() const { return parameters.size(); };
|
||||
const std::vector<gd::ParameterMetadata>& GetParameters() const {
|
||||
std::size_t GetParametersCount() const { return parameters.GetParametersCount(); };
|
||||
const gd::ParameterMetadataContainer& 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
|
||||
@@ -368,6 +369,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
bool isPrivate;
|
||||
gd::String requiredBaseObjectCapability;
|
||||
gd::String relevantContext;
|
||||
|
||||
gd::ParameterMetadataContainer parameters;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#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"
|
||||
@@ -77,7 +78,7 @@ InstructionMetadata& InstructionMetadata::AddParameter(
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
||||
parameters.push_back(info);
|
||||
parameters.AddParameter(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ InstructionMetadata& InstructionMetadata::AddCodeOnlyParameter(
|
||||
info.codeOnly = true;
|
||||
info.SetExtraInfo(supplementaryInformation);
|
||||
|
||||
parameters.push_back(info);
|
||||
parameters.AddParameter(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -102,7 +103,7 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
|
||||
AddParameter(
|
||||
"yesorno",
|
||||
options.description.empty() ? _("New value") : options.description);
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("Set _PARAM0_ as <subject>: <value>");
|
||||
@@ -127,8 +128,8 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
|
||||
options.description.empty() ? _("Value") : options.description,
|
||||
options.typeExtraInfo);
|
||||
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
size_t operatorParamIndex = parameters.GetParametersCount() - 2;
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("Change <subject> of _PARAM0_: <operator> <value>");
|
||||
@@ -181,8 +182,8 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
|
||||
AddParameter(type,
|
||||
options.description.empty() ? _("Value to compare") : options.description,
|
||||
options.typeExtraInfo);
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
size_t operatorParamIndex = parameters.GetParametersCount() - 2;
|
||||
size_t valueParamIndex = parameters.GetParametersCount() - 1;
|
||||
|
||||
if (isObjectInstruction || isBehaviorInstruction) {
|
||||
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/ParameterMetadataContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "ParameterMetadata.h"
|
||||
#include "ParameterOptions.h"
|
||||
@@ -61,12 +62,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[i]; }
|
||||
ParameterMetadata &GetParameter(size_t i) { return parameters.GetParameter(i); }
|
||||
const ParameterMetadata &GetParameter(size_t i) const {
|
||||
return parameters[i];
|
||||
return parameters.GetParameter(i);
|
||||
}
|
||||
size_t GetParametersCount() const { return parameters.size(); }
|
||||
const std::vector<ParameterMetadata> &GetParameters() const {
|
||||
size_t GetParametersCount() const { return parameters.GetParametersCount(); }
|
||||
const ParameterMetadataContainer &GetParameters() const {
|
||||
return parameters;
|
||||
}
|
||||
const gd::String &GetIconFilename() const { return iconFilename; }
|
||||
@@ -256,7 +257,9 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue_);
|
||||
}
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -268,8 +271,9 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
InstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -281,7 +285,9 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
if (parameters.GetParametersCount() > 0) {
|
||||
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -560,7 +566,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
*/
|
||||
InstructionMetadata &GetCodeExtraInformation() { return *this; }
|
||||
|
||||
std::vector<ParameterMetadata> parameters;
|
||||
ParameterMetadataContainer parameters;
|
||||
|
||||
private:
|
||||
gd::String fullname;
|
||||
|
@@ -454,11 +454,12 @@ const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
|
||||
// TODO use a badMetadata instead of a nullptr?
|
||||
const gd::ParameterMetadata* parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex <
|
||||
metadata.parameters.size()) {
|
||||
if (!metadata.parameters[metadataParameterIndex]
|
||||
metadata.GetParameters().GetParametersCount()) {
|
||||
if (!metadata.GetParameters().GetParameter(metadataParameterIndex)
|
||||
.IsCodeOnly()) {
|
||||
if (visibleParameterIndex == parameterIndex) {
|
||||
parameterMetadata = &metadata.parameters[metadataParameterIndex];
|
||||
parameterMetadata =
|
||||
&metadata.GetParameters().GetParameter(metadataParameterIndex);
|
||||
}
|
||||
visibleParameterIndex++;
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef PARAMETER_METADATA_H
|
||||
#define PARAMETER_METADATA_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
@@ -29,6 +29,12 @@ 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.
|
||||
*/
|
||||
@@ -248,5 +254,3 @@ class GD_CORE_API ParameterMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // PARAMETER_METADATA_H
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#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"
|
||||
@@ -20,13 +21,13 @@ const ParameterMetadata ParameterMetadataTools::badParameterMetadata;
|
||||
|
||||
void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
const ParameterMetadataContainer& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer) {
|
||||
outputObjectsContainer.GetObjects().clear();
|
||||
|
||||
gd::String lastObjectName;
|
||||
for (std::size_t i = 0; i < parameters.size(); ++i) {
|
||||
const auto& parameter = parameters[i];
|
||||
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) {
|
||||
const auto& parameter = parameters.GetParameter(i);
|
||||
if (parameter.GetName().empty()) continue;
|
||||
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
|
||||
@@ -61,31 +62,34 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::ForEachParameterMatchingSearch(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
const std::vector<const ParameterMetadataContainer*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName().FindCaseInsensitive(search) != gd::String::npos) cb(parameterMetadata);
|
||||
for (const auto ¶meterMetadata :
|
||||
parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName().FindCaseInsensitive(search) !=
|
||||
gd::String::npos)
|
||||
cb(*parameterMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ParameterMetadataTools::Has(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return true;
|
||||
for (const auto& parameterMetadata: parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName() == parameterName) return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,16 +97,18 @@ bool ParameterMetadataTools::Has(
|
||||
}
|
||||
|
||||
const gd::ParameterMetadata& ParameterMetadataTools::Get(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>&
|
||||
const std::vector<const ParameterMetadataContainer*>&
|
||||
parametersVectorsList,
|
||||
const gd::String& parameterName) {
|
||||
for (auto it = parametersVectorsList.rbegin();
|
||||
it != parametersVectorsList.rend();
|
||||
++it) {
|
||||
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
|
||||
const ParameterMetadataContainer* parametersVector = *it;
|
||||
|
||||
for (const auto& parameterMetadata: *parametersVector) {
|
||||
if (parameterMetadata.GetName() == parameterName) return parameterMetadata;
|
||||
for (const auto ¶meterMetadata :
|
||||
parametersVector->GetInternalVector()) {
|
||||
if (parameterMetadata->GetName() == parameterName)
|
||||
return *parameterMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +117,7 @@ const gd::ParameterMetadata& ParameterMetadataTools::Get(
|
||||
|
||||
void ParameterMetadataTools::IterateOverParameters(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
const gd::String& lastObjectName)> fn) {
|
||||
@@ -128,15 +134,17 @@ void ParameterMetadataTools::IterateOverParameters(
|
||||
|
||||
void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& 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.size(); ++pNb) {
|
||||
const gd::ParameterMetadata& parameterMetadata = parametersMetadata[pNb];
|
||||
const gd::Expression& parameterValue =
|
||||
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::ParameterMetadata ¶meterMetadata =
|
||||
parametersMetadata.GetParameter(pNb);
|
||||
const gd::Expression ¶meterValue =
|
||||
pNb < parameters.size() ? parameters[pNb].GetPlainString() : "";
|
||||
const gd::Expression& parameterValueOrDefault =
|
||||
parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional()
|
||||
@@ -179,10 +187,10 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.parameters.size() &&
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto ¶meterMetadata = metadata.parameters[metadataIndex];
|
||||
auto ¶meterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -204,16 +212,17 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
}
|
||||
|
||||
size_t ParameterMetadataTools::GetObjectParameterIndexFor(
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& 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.size();
|
||||
pNb--) {
|
||||
if (gd::ParameterMetadata::IsObject(parametersMetadata[pNb].GetType())) {
|
||||
for (std::size_t pNb = parameterIndex;
|
||||
pNb < parametersMetadata.GetParametersCount(); pNb--) {
|
||||
if (gd::ParameterMetadata::IsObject(
|
||||
parametersMetadata.GetParameter(pNb).GetType())) {
|
||||
return pNb;
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ParameterMetadata;
|
||||
class Expression;
|
||||
class ParameterMetadataContainer;
|
||||
struct FunctionCallNode;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
@@ -24,20 +25,20 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
public:
|
||||
static void ParametersToObjectsContainer(
|
||||
const gd::Project& project,
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
const ParameterMetadataContainer& parameters,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
|
||||
static void ForEachParameterMatchingSearch(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const gd::String& search,
|
||||
std::function<void(const gd::ParameterMetadata&)> cb);
|
||||
|
||||
static bool Has(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
static const gd::ParameterMetadata& Get(
|
||||
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
|
||||
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
|
||||
const gd::String& parameterName);
|
||||
|
||||
/**
|
||||
@@ -47,7 +48,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
*/
|
||||
static void IterateOverParameters(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
const gd::String& lastObjectName)> fn);
|
||||
@@ -59,7 +60,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
*/
|
||||
static void IterateOverParametersWithIndex(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
std::function<void(const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterValue,
|
||||
size_t parameterIndex,
|
||||
@@ -84,7 +85,7 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
* it's linked to.
|
||||
*/
|
||||
static size_t GetObjectParameterIndexFor(
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
const ParameterMetadataContainer& parametersMetadata,
|
||||
size_t parameterIndex);
|
||||
|
||||
private:
|
||||
|
@@ -210,8 +210,8 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "scenevar";
|
||||
} else if (type == "resource") {
|
||||
return parameterType == "fontResource" ||
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile" ||
|
||||
parameterType == "audioResource" ||
|
||||
parameterType == "videoResource" ||
|
||||
parameterType == "bitmapFontResource" ||
|
||||
parameterType == "imageResource" ||
|
||||
parameterType == "jsonResource" ||
|
||||
@@ -219,7 +219,10 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
parameterType == "tilesetResource" ||
|
||||
parameterType == "model3DResource" ||
|
||||
parameterType == "atlasResource" ||
|
||||
parameterType == "spineResource";
|
||||
parameterType == "spineResource" ||
|
||||
// Deprecated, old parameter types:
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -96,11 +96,11 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
|
||||
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
|
||||
gd::String type) const {
|
||||
if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
|
||||
gd::LogWarning("Tried to create an object with an unknown type: " + type
|
||||
gd::LogWarning("Tried to create an object configuration with an unknown type: " + type
|
||||
+ " for platform " + GetName() + "!");
|
||||
type = "";
|
||||
if (creationFunctionTable.find("") == creationFunctionTable.end()) {
|
||||
gd::LogError("Unable to create a Base object!");
|
||||
gd::LogFatalError("Unable to create a base object configuration!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@@ -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.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
|
||||
if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
node->Visit(*this);
|
||||
}
|
||||
|
@@ -86,9 +86,11 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
|
||||
&& parameterIndex < node.parameters.size(); ++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.parameters[metadataIndex];
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -144,10 +146,10 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
platform, instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// The parameter has the searched type...
|
||||
if (instrInfos.parameters[pNb].GetType() == "identifier"
|
||||
&& instrInfos.parameters[pNb].GetExtraInfo() == identifierType) {
|
||||
if (instrInfos.parameters.GetParameter(pNb).GetType() == "identifier"
|
||||
&& instrInfos.parameters.GetParameter(pNb).GetExtraInfo() == identifierType) {
|
||||
//...remember the value of the parameter.
|
||||
if (objectName.empty() || lastObjectParameter == objectName) {
|
||||
results.insert(instruction.GetParameter(pNb).GetPlainString());
|
||||
@@ -155,9 +157,9 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
}
|
||||
// Search in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
|
||||
IdentifierFinderExpressionNodeWorker searcher(
|
||||
@@ -170,7 +172,7 @@ class GD_CORE_API IdentifierFinderEventWorker
|
||||
}
|
||||
// Remember the value of the last "object" parameter.
|
||||
else if (gd::ParameterMetadata::IsObject(
|
||||
instrInfos.parameters[pNb].GetType())) {
|
||||
instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
lastObjectParameter =
|
||||
instruction.GetParameter(pNb).GetPlainString();
|
||||
}
|
||||
|
@@ -296,7 +296,7 @@ class GD_CORE_API ExpressionObjectFinder : public ExpressionParser2NodeWorker {
|
||||
};
|
||||
|
||||
bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String oldName,
|
||||
gd::String newName) {
|
||||
@@ -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.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// Replace object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"number", instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
|
||||
@@ -347,7 +347,7 @@ bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
|
||||
|
||||
bool EventsRefactorer::RenameObjectInConditions(
|
||||
const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String oldName,
|
||||
gd::String 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.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// Replace object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"number", instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
|
||||
@@ -399,7 +399,7 @@ bool EventsRefactorer::RenameObjectInConditions(
|
||||
|
||||
bool EventsRefactorer::RenameObjectInEventParameters(
|
||||
const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::Expression& expression,
|
||||
gd::ParameterMetadata parameterMetadata,
|
||||
gd::String oldName,
|
||||
@@ -432,7 +432,7 @@ bool EventsRefactorer::RenameObjectInEventParameters(
|
||||
}
|
||||
|
||||
void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::EventsList& events,
|
||||
gd::String oldName,
|
||||
gd::String newName) {
|
||||
@@ -475,7 +475,7 @@ void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
|
||||
}
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -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.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// Find object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
actions[aId].GetParameter(pNb).GetPlainString() == name) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
// Find object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
"number", instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = actions[aId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
|
||||
@@ -532,7 +532,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
|
||||
|
||||
bool EventsRefactorer::RemoveObjectInConditions(
|
||||
const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name) {
|
||||
bool somethingModified = false;
|
||||
@@ -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.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// Find object's name in parameters
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
|
||||
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) &&
|
||||
conditions[cId].GetParameter(pNb).GetPlainString() == name) {
|
||||
deleteMe = true;
|
||||
break;
|
||||
}
|
||||
// Find object's name in expressions
|
||||
else if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType())) {
|
||||
"number", instrInfos.parameters.GetParameter(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[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
|
||||
|
||||
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
|
||||
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EVENTSREFACTORER_H
|
||||
#define GDCORE_EVENTSREFACTORER_H
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -81,7 +81,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
* events ).
|
||||
*/
|
||||
static void RenameObjectInEvents(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::EventsList& events,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -128,7 +128,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RenameObjectInActions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& instructions,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -140,7 +140,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RenameObjectInConditions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& instructions,
|
||||
gd::String oldName,
|
||||
gd::String newName);
|
||||
@@ -153,7 +153,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
*/
|
||||
static bool RenameObjectInEventParameters(
|
||||
const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::Expression& expression,
|
||||
gd::ParameterMetadata parameterMetadata,
|
||||
gd::String oldName,
|
||||
@@ -165,7 +165,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RemoveObjectInConditions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name);
|
||||
|
||||
@@ -175,7 +175,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
static bool RemoveObjectInActions(const gd::Platform& platform,
|
||||
gd::ProjectScopedContainers& projectScopedContainers,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String name);
|
||||
|
||||
@@ -242,5 +242,3 @@ class GD_CORE_API EventsRefactorer {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSREFACTORER_H
|
||||
|
@@ -31,6 +31,8 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariablesContainer EventsVariableInstructionTypeSwitcher::nullVariablesContainer;
|
||||
|
||||
bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction& instruction,
|
||||
bool isCondition) {
|
||||
const auto& metadata = isCondition
|
||||
@@ -82,7 +84,8 @@ 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) {
|
||||
if (variablesContainer == &targetVariablesContainer ||
|
||||
lastObjectName == groupName) {
|
||||
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,21 +33,36 @@ class GD_CORE_API EventsVariableInstructionTypeSwitcher
|
||||
public:
|
||||
EventsVariableInstructionTypeSwitcher(
|
||||
const gd::Platform &platform_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_,
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames_)
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_)
|
||||
: platform(platform_),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
typeChangedVariableNames(typeChangedVariableNames_){};
|
||||
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_){};
|
||||
virtual ~EventsVariableInstructionTypeSwitcher();
|
||||
|
||||
private:
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::VariablesContainer &targetVariablesContainer;
|
||||
gd::String objectName;
|
||||
/**
|
||||
* 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;
|
||||
const std::unordered_set<gd::String> &typeChangedVariableNames;
|
||||
|
||||
static VariablesContainer nullVariablesContainer;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -32,6 +32,8 @@
|
||||
|
||||
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.
|
||||
@@ -44,22 +46,26 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
ExpressionVariableReplacer(
|
||||
const gd::Platform& platform_,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_,
|
||||
const gd::VariablesContainer& targetVariablesContainer_,
|
||||
const VariablesRenamingChangesetNode& variablesRenamingChangesetRoot_,
|
||||
const std::unordered_set<gd::String>& removedVariableNames_)
|
||||
const std::unordered_set<gd::String>& removedVariableNames_,
|
||||
const gd::VariablesContainer& targetVariablesContainer_,
|
||||
const gd::String &groupName_,
|
||||
const gd::String &forcedInitialObjectName)
|
||||
: hasDoneRenaming(false),
|
||||
removedVariableUsed(false),
|
||||
platform(platform_),
|
||||
projectScopedContainers(projectScopedContainers_),
|
||||
forcedInitialVariablesContainer(nullptr),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
forcedVariablesContainer(nullptr),
|
||||
forcedObjectName(forcedInitialObjectName),
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_){};
|
||||
removedVariableNames(removedVariableNames_),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
targetGroupName(groupName_){};
|
||||
virtual ~ExpressionVariableReplacer(){};
|
||||
|
||||
void SetForcedInitialVariablesContainer(
|
||||
const gd::VariablesContainer* forcedInitialVariablesContainer_) {
|
||||
forcedInitialVariablesContainer = forcedInitialVariablesContainer_;
|
||||
forcedVariablesContainer = forcedInitialVariablesContainer_;
|
||||
}
|
||||
|
||||
bool HasDoneRenaming() const { return hasDoneRenaming; }
|
||||
@@ -82,12 +88,13 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// The node represents a variable or an object name on which a variable
|
||||
// will be accessed.
|
||||
|
||||
if (forcedInitialVariablesContainer) {
|
||||
if (forcedVariablesContainer) {
|
||||
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 (forcedInitialVariablesContainer == &targetVariablesContainer) {
|
||||
if (forcedVariablesContainer == &targetVariablesContainer ||
|
||||
IsTargetingObjectGroup(forcedObjectName)) {
|
||||
RenameOrRemoveVariableOfTargetVariableContainer(node.name);
|
||||
}
|
||||
|
||||
@@ -150,7 +157,8 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// This is always true because MatchIdentifierWithName is used to get
|
||||
// objectNameToUseForVariableAccessor.
|
||||
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
|
||||
objectNameToUseForVariableAccessor, targetVariablesContainer)) {
|
||||
objectNameToUseForVariableAccessor, targetVariablesContainer) ||
|
||||
IsTargetingObjectGroup(objectNameToUseForVariableAccessor)) {
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
// The node represents an object variable, and this object variables are
|
||||
// the target. Do the replacement or removals:
|
||||
@@ -197,10 +205,11 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// (and if it's a variable reference or a value does not have any importance
|
||||
// here).
|
||||
|
||||
if (forcedInitialVariablesContainer) {
|
||||
if (forcedVariablesContainer) {
|
||||
// A scope was forced. Honor it: it means this node represents a variable
|
||||
// of the forced variables container.
|
||||
if (forcedInitialVariablesContainer == &targetVariablesContainer) {
|
||||
if (forcedVariablesContainer == &targetVariablesContainer ||
|
||||
IsTargetingObjectGroup(forcedObjectName)) {
|
||||
renameVariableAndChild();
|
||||
}
|
||||
return;
|
||||
@@ -213,7 +222,8 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
[&]() {
|
||||
// This represents an object.
|
||||
if (objectsContainersList.HasObjectOrGroupVariablesContainer(
|
||||
node.identifierName, targetVariablesContainer)) {
|
||||
node.identifierName, targetVariablesContainer) ||
|
||||
IsTargetingObjectGroup(node.identifierName)) {
|
||||
// The node represents an object variable, and this object variables
|
||||
// are the target. Do the replacement or removals:
|
||||
PushVariablesRenamingChangesetRoot();
|
||||
@@ -261,31 +271,33 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// force the "scope" at which starts the evalution of variables.
|
||||
if (parameterMetadata && parameterMetadata->GetValueTypeMetadata()
|
||||
.IsLegacyPreScopedVariable()) {
|
||||
const gd::VariablesContainer* oldForcedInitialVariablesContainer =
|
||||
forcedInitialVariablesContainer;
|
||||
const gd::VariablesContainer *oldForcedVariablesContainer =
|
||||
forcedVariablesContainer;
|
||||
const gd::String &oldForcedObjectName = forcedObjectName;
|
||||
|
||||
forcedInitialVariablesContainer = nullptr;
|
||||
forcedVariablesContainer = nullptr;
|
||||
forcedObjectName = "";
|
||||
if (parameterMetadata->GetType() == "globalvar") {
|
||||
forcedInitialVariablesContainer =
|
||||
forcedVariablesContainer =
|
||||
projectScopedContainers.GetVariablesContainersList()
|
||||
.GetTopMostVariablesContainer();
|
||||
} else if (parameterMetadata->GetType() == "scenevar") {
|
||||
forcedInitialVariablesContainer =
|
||||
forcedVariablesContainer =
|
||||
projectScopedContainers.GetVariablesContainersList()
|
||||
.GetBottomMostVariablesContainer();
|
||||
} else if (parameterMetadata->GetType() == "objectvar") {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
|
||||
platform,
|
||||
projectScopedContainers.GetObjectsContainersList(),
|
||||
node.objectName,
|
||||
*node.parameters[parameterIndex].get());
|
||||
forcedInitialVariablesContainer =
|
||||
platform, projectScopedContainers.GetObjectsContainersList(),
|
||||
node.objectName, *node.parameters[parameterIndex].get());
|
||||
forcedVariablesContainer =
|
||||
projectScopedContainers.GetObjectsContainersList()
|
||||
.GetObjectOrGroupVariablesContainer(objectName);
|
||||
forcedObjectName = objectName;
|
||||
}
|
||||
|
||||
node.parameters[parameterIndex]->Visit(*this);
|
||||
forcedInitialVariablesContainer = oldForcedInitialVariablesContainer;
|
||||
forcedVariablesContainer = oldForcedVariablesContainer;
|
||||
forcedObjectName = oldForcedObjectName;
|
||||
} else {
|
||||
// For any other parameter, there is no special treatment being needed.
|
||||
node.parameters[parameterIndex]->Visit(*this);
|
||||
@@ -298,6 +310,10 @@ 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 =
|
||||
@@ -382,10 +398,17 @@ class GD_CORE_API ExpressionVariableReplacer
|
||||
// Scope:
|
||||
const gd::Platform& platform;
|
||||
const gd::ProjectScopedContainers& projectScopedContainers;
|
||||
const gd::VariablesContainer* forcedInitialVariablesContainer;
|
||||
const gd::VariablesContainer* forcedVariablesContainer;
|
||||
gd::String forcedObjectName;
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -397,7 +420,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 evalution of variables.
|
||||
// force the "scope" at which starts the evaluation of variables.
|
||||
if (type == "objectvar") {
|
||||
return GetProjectScopedContainers()
|
||||
.GetObjectsContainersList()
|
||||
@@ -442,9 +465,11 @@ bool EventsVariableReplacer::DoVisitInstruction(gd::Instruction& instruction,
|
||||
if (node) {
|
||||
ExpressionVariableReplacer renamer(platform,
|
||||
GetProjectScopedContainers(),
|
||||
targetVariablesContainer,
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames);
|
||||
removedVariableNames,
|
||||
targetVariablesContainer,
|
||||
targetGroupName,
|
||||
type == "objectvar" ? lastObjectName : "");
|
||||
renamer.SetForcedInitialVariablesContainer(
|
||||
FindForcedVariablesContainerIfAny(type, lastObjectName));
|
||||
node->Visit(renamer);
|
||||
@@ -474,9 +499,11 @@ bool EventsVariableReplacer::DoVisitEventExpression(
|
||||
if (node) {
|
||||
ExpressionVariableReplacer renamer(platform,
|
||||
GetProjectScopedContainers(),
|
||||
targetVariablesContainer,
|
||||
variablesRenamingChangesetRoot,
|
||||
removedVariableNames);
|
||||
removedVariableNames,
|
||||
targetVariablesContainer,
|
||||
targetGroupName,
|
||||
"");
|
||||
renamer.SetForcedInitialVariablesContainer(
|
||||
FindForcedVariablesContainerIfAny(type, ""));
|
||||
node->Visit(renamer);
|
||||
|
@@ -35,13 +35,24 @@ 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 std::unordered_set<gd::String> &removedVariableNames_,
|
||||
const gd::VariablesContainer &targetVariablesContainer_)
|
||||
: platform(platform_),
|
||||
targetVariablesContainer(targetVariablesContainer_),
|
||||
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
|
||||
removedVariableNames(removedVariableNames_) {};
|
||||
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_) {};
|
||||
virtual ~EventsVariableReplacer();
|
||||
|
||||
private:
|
||||
@@ -55,9 +66,16 @@ class GD_CORE_API EventsVariableReplacer
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::VariablesContainer &targetVariablesContainer;
|
||||
gd::String objectName;
|
||||
/**
|
||||
* 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;
|
||||
|
||||
static VariablesContainer nullVariablesContainer;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -93,9 +93,11 @@ class GD_CORE_API VariableFinderExpressionNodeWorker
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
|
||||
&& parameterIndex < node.parameters.size(); ++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.parameters[metadataIndex];
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.GetParameters().GetParametersCount() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
@@ -150,18 +152,18 @@ class GD_CORE_API VariableFinderEventWorker
|
||||
platform, instruction.GetType())
|
||||
: MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
|
||||
// The parameter has the searched type...
|
||||
if (instrInfos.parameters[pNb].GetType() == parameterType) {
|
||||
if (instrInfos.parameters.GetParameter(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[pNb].GetType()) ||
|
||||
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
|
||||
VariableFinderExpressionNodeWorker searcher(
|
||||
@@ -174,7 +176,7 @@ class GD_CORE_API VariableFinderEventWorker
|
||||
}
|
||||
// Remember the value of the last "object" parameter.
|
||||
else if (gd::ParameterMetadata::IsObject(
|
||||
instrInfos.parameters[pNb].GetType())) {
|
||||
instrInfos.parameters.GetParameter(pNb).GetType())) {
|
||||
lastObjectParameter =
|
||||
instruction.GetParameter(pNb).GetPlainString();
|
||||
}
|
||||
|
@@ -463,11 +463,15 @@ class GD_CORE_API ExpressionCompletionFinder
|
||||
MetadataProvider::GetFunctionCallMetadata(
|
||||
platform, objectsContainersList, *functionCall);
|
||||
|
||||
const gd::ParameterMetadata* parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex < metadata.parameters.size()) {
|
||||
if (!metadata.parameters[metadataParameterIndex].IsCodeOnly()) {
|
||||
const gd::ParameterMetadata *parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex <
|
||||
metadata.GetParameters().GetParametersCount()) {
|
||||
if (!metadata.GetParameters()
|
||||
.GetParameter(metadataParameterIndex)
|
||||
.IsCodeOnly()) {
|
||||
if (visibleParameterIndex == parameterIndex) {
|
||||
parameterMetadata = &metadata.parameters[metadataParameterIndex];
|
||||
parameterMetadata =
|
||||
&metadata.GetParameters().GetParameter(metadataParameterIndex);
|
||||
}
|
||||
visibleParameterIndex++;
|
||||
}
|
||||
|
@@ -36,13 +36,15 @@ namespace {
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMinimumParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
const gd::ParameterMetadataContainer& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].IsOptional() && !parameters[i].codeOnly) nb++;
|
||||
for (std::size_t i = initialParameterIndex;
|
||||
i < parameters.GetParametersCount(); ++i) {
|
||||
if (!parameters.GetParameter(i).IsOptional() &&
|
||||
!parameters.GetParameter(i).IsCodeOnly())
|
||||
nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
@@ -51,13 +53,14 @@ size_t GetMinimumParametersNumber(
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMaximumParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
const gd::ParameterMetadataContainer& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].codeOnly) nb++;
|
||||
for (std::size_t i = initialParameterIndex;
|
||||
i < parameters.GetParametersCount(); ++i) {
|
||||
if (!parameters.GetParameter(i).IsCodeOnly())
|
||||
nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
@@ -322,11 +325,11 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(
|
||||
|
||||
// Validate parameters count
|
||||
size_t minParametersCount = GetMinimumParametersNumber(
|
||||
metadata.parameters,
|
||||
metadata.GetParameters(),
|
||||
ExpressionParser2::WrittenParametersFirstIndex(function.objectName,
|
||||
function.behaviorName));
|
||||
size_t maxParametersCount = GetMaximumParametersNumber(
|
||||
metadata.parameters,
|
||||
metadata.GetParameters(),
|
||||
ExpressionParser2::WrittenParametersFirstIndex(function.objectName,
|
||||
function.behaviorName));
|
||||
if (function.parameters.size() < minParametersCount ||
|
||||
@@ -366,11 +369,11 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(
|
||||
for (int parameterIndex = 0; parameterIndex < function.parameters.size();
|
||||
parameterIndex++) {
|
||||
auto& parameter = function.parameters[parameterIndex];
|
||||
while (metadata.GetParameters()[metadataIndex].IsCodeOnly()) {
|
||||
while (metadata.GetParameters().GetParameter(metadataIndex).IsCodeOnly()) {
|
||||
// The sizes are already checked above.
|
||||
metadataIndex++;
|
||||
}
|
||||
auto& parameterMetadata = metadata.GetParameters()[metadataIndex];
|
||||
auto& parameterMetadata = metadata.GetParameters().GetParameter(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.size() &&
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.GetParametersCount() &&
|
||||
pNb < instruction.GetParametersCount();
|
||||
++pNb) {
|
||||
const gd::String& type = metadata.parameters[pNb].GetType();
|
||||
const gd::String& type = metadata.parameters.GetParameter(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.size() &&
|
||||
for (std::size_t pNb = 0; pNb < metadata.parameters.GetParametersCount() &&
|
||||
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.size(); ++i) {
|
||||
for (std::size_t i = 0; i < metadata.parameters.GetParametersCount(); ++i) {
|
||||
size_t paramPosition =
|
||||
sentence.find("_PARAM" + gd::String::From(i) + "_");
|
||||
if (paramPosition < firstParamPosition) {
|
||||
|
@@ -92,17 +92,30 @@ void EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
|
||||
"its parameters).");
|
||||
return;
|
||||
}
|
||||
if (eventsBasedObject.HasObjectNamed("Object")) {
|
||||
if (eventsBasedObject.GetObjects().HasObjectNamed("Object")) {
|
||||
gd::LogWarning("Child-objects can't be named Object because it's reserved"
|
||||
"for the parent. ");
|
||||
return;
|
||||
}
|
||||
|
||||
// ...and its children.
|
||||
auto &children = eventsBasedObject.GetObjects();
|
||||
gd::EventsFunctionTools::CopyEventsBasedObjectChildrenToObjectsContainer(
|
||||
eventsBasedObject, outputObjectsContainer);
|
||||
}
|
||||
|
||||
void EventsFunctionTools::CopyEventsBasedObjectChildrenToObjectsContainer(
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& outputObjectsContainer) {
|
||||
auto &children = eventsBasedObject.GetObjects().GetObjects();
|
||||
for (auto &childObject : children) {
|
||||
auto child = childObject.get();
|
||||
outputObjectsContainer.InsertObject(*child, children.size());
|
||||
outputObjectsContainer.InsertObject(
|
||||
*child, outputObjectsContainer.GetObjectsCount());
|
||||
}
|
||||
auto &childrenGroups = eventsBasedObject.GetObjects().GetObjectGroups();
|
||||
for (size_t index = 0; index < childrenGroups.Count(); ++index) {
|
||||
auto &childGroup = childrenGroups.Get(index);
|
||||
outputObjectsContainer.GetObjectGroups().Insert(
|
||||
childGroup, outputObjectsContainer.GetObjectGroups().Count());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -68,5 +68,9 @@ class GD_CORE_API EventsFunctionTools {
|
||||
const gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& outputObjectsContainer);
|
||||
|
||||
static void CopyEventsBasedObjectChildrenToObjectsContainer(
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
gd::ObjectsContainer &outputObjectsContainer);
|
||||
};
|
||||
} // namespace gd
|
||||
|
196
Core/GDCore/IDE/GroupVariableHelper.cpp
Normal file
196
Core/GDCore/IDE/GroupVariableHelper.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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
|
75
Core/GDCore/IDE/GroupVariableHelper.h
Normal file
75
Core/GDCore/IDE/GroupVariableHelper.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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,9 +225,7 @@ bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instructi
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police" || // Should be renamed fontResource
|
||||
parameterMetadata.GetType() == "fontResource") {
|
||||
if (parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* GDevelop JS Platform
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EventsBasedObjectDependencyFinder.h"
|
||||
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
bool EventsBasedObjectDependencyFinder::IsDependentFromEventsBasedObject(
|
||||
const gd::Project &project, const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsBasedObject &dependency) {
|
||||
return gd::EventsBasedObjectDependencyFinder::
|
||||
IsDependentFromEventsBasedObject(project, eventsBasedObject, dependency,
|
||||
0);
|
||||
}
|
||||
bool EventsBasedObjectDependencyFinder::IsDependentFromEventsBasedObject(
|
||||
const gd::Project &project, const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsBasedObject &dependency, int depth) {
|
||||
|
||||
if (&eventsBasedObject == &dependency) {
|
||||
return true;
|
||||
}
|
||||
if (depth > 200) {
|
||||
return false;
|
||||
}
|
||||
for (auto &object : eventsBasedObject.GetObjects().GetObjects()) {
|
||||
const gd::String &objectType = object->GetType();
|
||||
if (project.HasEventsBasedObject(objectType) &&
|
||||
gd::EventsBasedObjectDependencyFinder::IsDependentFromEventsBasedObject(
|
||||
project, project.GetEventsBasedObject(objectType), dependency,
|
||||
depth + 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace gd
|
37
Core/GDCore/IDE/Project/EventsBasedObjectDependencyFinder.h
Normal file
37
Core/GDCore/IDE/Project/EventsBasedObjectDependencyFinder.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* GDevelop JS Platform
|
||||
* Copyright 2008-2023 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class EventsBasedObject;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Find resource usages in several parts of the project.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class EventsBasedObjectDependencyFinder {
|
||||
public:
|
||||
static bool IsDependentFromEventsBasedObject(
|
||||
const gd::Project &project,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsBasedObject &dependency);
|
||||
|
||||
private:
|
||||
static bool IsDependentFromEventsBasedObject(
|
||||
const gd::Project &project,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsBasedObject &dependency, int depth);
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -15,10 +15,10 @@ namespace gd {
|
||||
|
||||
void FunctionParameterBehaviorTypeRenamer::DoVisitEventsFunction(
|
||||
gd::EventsFunction &eventsFunction) {
|
||||
for (auto &¶meter : eventsFunction.GetParameters()) {
|
||||
if (gd::ParameterMetadata::IsBehavior(parameter.GetType()) &&
|
||||
parameter.GetExtraInfo() == oldBehaviorType) {
|
||||
parameter.SetExtraInfo(newBehaviorType);
|
||||
for (auto &¶meter : eventsFunction.GetParameters().GetInternalVector()) {
|
||||
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()) {
|
||||
if (gd::ParameterMetadata::IsObject(parameter.GetType()) &&
|
||||
parameter.GetExtraInfo() == oldObjectType) {
|
||||
parameter.SetExtraInfo(newObjectType);
|
||||
for (auto &¶meter : eventsFunction.GetParameters().GetInternalVector()) {
|
||||
if (gd::ParameterMetadata::IsObject(parameter->GetType()) &&
|
||||
parameter->GetExtraInfo() == oldObjectType) {
|
||||
parameter->SetExtraInfo(newObjectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -250,7 +250,7 @@ void ProjectBrowserHelper::ExposeProjectObjects(
|
||||
gd::Project &project, gd::ArbitraryObjectsWorker &worker) {
|
||||
|
||||
// Global objects
|
||||
worker.Launch(project);
|
||||
worker.Launch(project.GetObjects());
|
||||
|
||||
// Layout objects
|
||||
for (size_t i = 0; i < project.GetLayoutsCount(); i++) {
|
||||
@@ -265,7 +265,7 @@ void ProjectBrowserHelper::ExposeProjectObjects(
|
||||
for (auto &&eventsBasedObjectUniquePtr :
|
||||
eventsFunctionsExtension.GetEventsBasedObjects().GetInternalVector()) {
|
||||
auto eventsBasedObject = eventsBasedObjectUniquePtr.get();
|
||||
worker.Launch(*eventsBasedObject);
|
||||
worker.Launch(eventsBasedObject->GetObjects());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -275,7 +275,7 @@ void ProjectBrowserHelper::ExposeLayoutObjects(gd::Layout &layout,
|
||||
// In the future, layouts may have children object containers.
|
||||
|
||||
// Layout objects
|
||||
worker.Launch(layout);
|
||||
worker.Launch(layout.GetObjects());
|
||||
}
|
||||
|
||||
void ProjectBrowserHelper::ExposeProjectFunctions(
|
||||
|
@@ -17,7 +17,7 @@
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project &project) {
|
||||
project.GetObjectGroups().Clear();
|
||||
project.GetObjects().GetObjectGroups().Clear();
|
||||
while (project.GetExternalEventsCount() > 0)
|
||||
project.RemoveExternalEvents(project.GetExternalEvents(0).GetName());
|
||||
|
||||
@@ -26,7 +26,7 @@ void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project &project) {
|
||||
wholeProjectBrowser.ExposeObjects(project, behaviorDefaultFlagClearer);
|
||||
|
||||
for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
project.GetLayout(i).GetObjectGroups().Clear();
|
||||
project.GetLayout(i).GetObjects().GetObjectGroups().Clear();
|
||||
project.GetLayout(i).GetEvents().Clear();
|
||||
}
|
||||
|
||||
|
@@ -153,7 +153,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
extension.GetName(), eventsBasedEntity.GetName());
|
||||
objectParameter.SetExtraInfo(objectFullType);
|
||||
}
|
||||
setter.GetParameters().push_back(objectParameter);
|
||||
setter.GetParameters().AddParameter(objectParameter);
|
||||
if (isBehavior) {
|
||||
gd::ParameterMetadata behaviorParameter;
|
||||
gd::String behaviorFullType =
|
||||
@@ -163,7 +163,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
.SetName("Behavior")
|
||||
.SetDescription("Behavior")
|
||||
.SetExtraInfo(behaviorFullType);
|
||||
setter.GetParameters().push_back(behaviorParameter);
|
||||
setter.GetParameters().AddParameter(behaviorParameter);
|
||||
}
|
||||
gd::ParameterMetadata valueParameter;
|
||||
valueParameter.SetType("yesorno")
|
||||
@@ -171,7 +171,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
|
||||
.SetDescription(capitalizedName)
|
||||
.SetOptional(true)
|
||||
.SetDefaultValue("yes");
|
||||
setter.GetParameters().push_back(valueParameter);
|
||||
setter.GetParameters().AddParameter(valueParameter);
|
||||
} else {
|
||||
setter.SetFunctionType(gd::EventsFunction::ActionWithOperator);
|
||||
setter.SetGetterName(getterName);
|
||||
|
@@ -76,7 +76,7 @@ void ResourceExposer::ExposeWholeProjectResources(gd::Project& project, gd::Arbi
|
||||
void ResourceExposer::ExposeProjectResources(gd::Project& project, gd::ArbitraryResourceWorker& worker) {
|
||||
// Expose global objects configuration resources
|
||||
auto objectWorker = gd::GetResourceWorkerOnObjects(project, worker);
|
||||
objectWorker.Launch(project);
|
||||
objectWorker.Launch(project.GetObjects());
|
||||
}
|
||||
|
||||
void ResourceExposer::ExposeLayoutResources(
|
||||
|
@@ -11,22 +11,23 @@
|
||||
#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/EventsVariableReplacer.h"
|
||||
#include "GDCore/IDE/Events/EventsVariableInstructionTypeSwitcher.h"
|
||||
#include "GDCore/IDE/Events/EventsVariableReplacer.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"
|
||||
@@ -86,10 +87,10 @@ WholeProjectRefactorer::GetAllObjectTypesUsingEventsBasedBehavior(
|
||||
}
|
||||
};
|
||||
|
||||
addTypesOfObjectsIn(project);
|
||||
addTypesOfObjectsIn(project.GetObjects());
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
auto &layout = project.GetLayout(s);
|
||||
addTypesOfObjectsIn(layout);
|
||||
addTypesOfObjectsIn(layout.GetObjects());
|
||||
}
|
||||
|
||||
return allTypes;
|
||||
@@ -101,17 +102,17 @@ void WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
|
||||
for (auto &eventsFunction :
|
||||
eventsBasedBehavior.GetEventsFunctions().GetInternalVector()) {
|
||||
auto ¶meters = eventsFunction->GetParameters();
|
||||
while (parameters.size() < 2) {
|
||||
while (parameters.GetParametersCount() < 2) {
|
||||
gd::ParameterMetadata newParameter;
|
||||
parameters.push_back(newParameter);
|
||||
parameters.AddParameter(newParameter);
|
||||
}
|
||||
|
||||
parameters[0]
|
||||
parameters.GetParameter(0)
|
||||
.SetType("object")
|
||||
.SetName(behaviorObjectParameterName)
|
||||
.SetDescription("Object")
|
||||
.SetExtraInfo(eventsBasedBehavior.GetObjectType());
|
||||
parameters[1]
|
||||
parameters.GetParameter(1)
|
||||
.SetType("behavior")
|
||||
.SetName("Behavior")
|
||||
.SetDescription("Behavior")
|
||||
@@ -126,12 +127,12 @@ void WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
|
||||
for (auto &eventsFunction :
|
||||
eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto ¶meters = eventsFunction->GetParameters();
|
||||
while (parameters.size() < 1) {
|
||||
while (parameters.GetParametersCount() < 1) {
|
||||
gd::ParameterMetadata newParameter;
|
||||
parameters.push_back(newParameter);
|
||||
parameters.AddParameter(newParameter);
|
||||
}
|
||||
|
||||
parameters[0]
|
||||
parameters.GetParameter(0)
|
||||
.SetType("object")
|
||||
.SetName(parentObjectParameterName)
|
||||
.SetDescription("Object")
|
||||
@@ -173,6 +174,7 @@ 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;
|
||||
|
||||
@@ -182,9 +184,15 @@ 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,
|
||||
@@ -310,8 +318,8 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
|
||||
|
||||
// Rename and remove variables
|
||||
gd::EventsVariableReplacer eventsVariableReplacer(
|
||||
project.GetCurrentPlatform(), variablesContainer,
|
||||
changeset, changeset.removedVariableNames);
|
||||
project.GetCurrentPlatform(), changeset, changeset.removedVariableNames,
|
||||
variablesContainer);
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(project,
|
||||
eventsVariableReplacer);
|
||||
|
||||
@@ -321,8 +329,83 @@ void WholeProjectRefactorer::ApplyRefactoringForVariablesContainer(
|
||||
// Switch types of instructions
|
||||
gd::EventsVariableInstructionTypeSwitcher
|
||||
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
|
||||
variablesContainer,
|
||||
changeset.typeChangedVariableNames);
|
||||
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());
|
||||
gd::ProjectBrowserHelper::ExposeProjectEvents(
|
||||
project, eventsVariableInstructionTypeSwitcher);
|
||||
}
|
||||
@@ -849,7 +932,8 @@ 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.
|
||||
@@ -919,7 +1003,8 @@ 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.
|
||||
@@ -1177,12 +1262,14 @@ WholeProjectRefactorer::FindInvalidRequiredBehaviorProperties(
|
||||
};
|
||||
|
||||
// Find in global objects
|
||||
findInvalidRequiredBehaviorPropertiesInObjects(project.GetObjects());
|
||||
findInvalidRequiredBehaviorPropertiesInObjects(
|
||||
project.GetObjects().GetObjects());
|
||||
|
||||
// Find in layout objects.
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
const gd::Layout &layout = project.GetLayout(i);
|
||||
findInvalidRequiredBehaviorPropertiesInObjects(layout.GetObjects());
|
||||
findInvalidRequiredBehaviorPropertiesInObjects(
|
||||
layout.GetObjects().GetObjects());
|
||||
}
|
||||
return invalidRequiredBehaviorProperties;
|
||||
}
|
||||
@@ -1516,15 +1603,15 @@ void WholeProjectRefactorer::DoRenameObject(
|
||||
projectBrowser.ExposeFunctions(project, objectParameterRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInLayout(
|
||||
void WholeProjectRefactorer::ObjectRemovedInScene(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &objectName) {
|
||||
auto projectScopedContainers = gd::ProjectScopedContainers::
|
||||
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
|
||||
|
||||
// Object groups can't have instances or be in other groups
|
||||
for (std::size_t g = 0; g < layout.GetObjectGroups().size(); ++g) {
|
||||
if (layout.GetObjectGroups()[g].Find(objectName))
|
||||
layout.GetObjectGroups()[g].RemoveObject(objectName);
|
||||
auto &groups = layout.GetObjects().GetObjectGroups();
|
||||
for (std::size_t g = 0; g < groups.size(); ++g) {
|
||||
if (groups[g].Find(objectName))
|
||||
groups[g].RemoveObject(objectName);
|
||||
}
|
||||
layout.GetInitialInstances().RemoveInitialInstancesOfObject(objectName);
|
||||
|
||||
@@ -1538,7 +1625,7 @@ void WholeProjectRefactorer::ObjectRemovedInLayout(
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::BehaviorsAddedToObjectInLayout(
|
||||
void WholeProjectRefactorer::BehaviorsAddedToObjectInScene(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &objectName) {
|
||||
auto projectScopedContainers = gd::ProjectScopedContainers::
|
||||
MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
|
||||
@@ -1548,7 +1635,7 @@ void WholeProjectRefactorer::BehaviorsAddedToObjectInLayout(
|
||||
project, layout, behaviorParameterFiller);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInScene(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &oldName,
|
||||
const gd::String &newName, bool isObjectGroup) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
@@ -1562,11 +1649,12 @@ void WholeProjectRefactorer::ObjectOrGroupRenamedInLayout(
|
||||
project.GetCurrentPlatform(), projectScopedContainers, layout.GetEvents(),
|
||||
oldName, newName);
|
||||
|
||||
if (!isObjectGroup) { // Object groups can't have instances or be in other
|
||||
// groups
|
||||
// Object groups can't have instances or be in other groups
|
||||
if (!isObjectGroup) {
|
||||
auto &groups = layout.GetObjects().GetObjectGroups();
|
||||
layout.GetInitialInstances().RenameInstancesOfObject(oldName, newName);
|
||||
for (std::size_t g = 0; g < layout.GetObjectGroups().size(); ++g) {
|
||||
layout.GetObjectGroups()[g].RenameObject(oldName, newName);
|
||||
for (std::size_t g = 0; g < groups.size(); ++g) {
|
||||
groups[g].RenameObject(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1638,133 +1726,210 @@ void WholeProjectRefactorer::RenameExternalEvents(gd::Project &project,
|
||||
linkEventTargetRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayer(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
void WholeProjectRefactorer::RenameLayerInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
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, layout, projectElementRenamer);
|
||||
layout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
project, scene, projectElementRenamer);
|
||||
scene.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
|
||||
std::vector<gd::String> externalLayoutsNames =
|
||||
GetAssociatedExternalLayouts(project, layout);
|
||||
GetAssociatedExternalLayouts(project, scene);
|
||||
for (gd::String name : externalLayoutsNames) {
|
||||
auto &externalLayout = project.GetExternalLayout(name);
|
||||
externalLayout.GetInitialInstances().MoveInstancesToLayer(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameLayerEffect(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Layer &layer,
|
||||
const gd::String &oldName,
|
||||
const gd::String &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) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "layerEffectName", oldName, newName);
|
||||
projectElementRenamer.SetLayerConstraint(layer.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, layout, projectElementRenamer);
|
||||
project, scene, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectAnimation(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
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) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectAnimationName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, layout, projectElementRenamer);
|
||||
project, scene, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectPoint(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
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) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectPointName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, layout, projectElementRenamer);
|
||||
project, scene, projectElementRenamer);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RenameObjectEffect(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName) {
|
||||
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) {
|
||||
if (oldName == newName || newName.empty() || oldName.empty())
|
||||
return;
|
||||
gd::ProjectElementRenamer projectElementRenamer(
|
||||
project.GetCurrentPlatform(), "objectEffectName", oldName, newName);
|
||||
projectElementRenamer.SetObjectConstraint(object.GetName());
|
||||
gd::ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
|
||||
project, layout, projectElementRenamer);
|
||||
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);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInEventsBasedObject(
|
||||
gd::Project &project, gd::EventsBasedObject &eventsBasedObject,
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer, const gd::String &objectName) {
|
||||
const gd::String &objectName) {
|
||||
for (auto &functionUniquePtr :
|
||||
eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto function = functionUniquePtr.get();
|
||||
WholeProjectRefactorer::ObjectRemovedInEventsFunction(
|
||||
project, *function, globalObjectsContainer, objectsContainer,
|
||||
objectName);
|
||||
WholeProjectRefactorer::ObjectRemovedInEventsFunction(project, *function,
|
||||
objectName);
|
||||
}
|
||||
|
||||
auto &groups = eventsBasedObject.GetObjects().GetObjectGroups();
|
||||
for (std::size_t g = 0; g < groups.size(); ++g) {
|
||||
if (groups[g].Find(objectName))
|
||||
groups[g].RemoveObject(objectName);
|
||||
}
|
||||
eventsBasedObject.GetInitialInstances().RemoveInitialInstancesOfObject(
|
||||
objectName);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectRemovedInEventsFunction(
|
||||
gd::Project &project, gd::EventsFunction &eventsFunction,
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer, const gd::String &objectName) {
|
||||
const gd::String &objectName) {
|
||||
|
||||
for (std::size_t g = 0; g < eventsFunction.GetObjectGroups().size();
|
||||
++g) {
|
||||
for (std::size_t g = 0; g < eventsFunction.GetObjectGroups().size(); ++g) {
|
||||
if (eventsFunction.GetObjectGroups()[g].Find(objectName))
|
||||
eventsFunction.GetObjectGroups()[g].RemoveObject(objectName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project &project, gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::Project &project,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers,
|
||||
gd::EventsBasedObject &eventsBasedObject, const gd::String &oldName,
|
||||
const gd::String &newName, bool isObjectGroup) {
|
||||
for (auto &functionUniquePtr :
|
||||
eventsBasedObject.GetEventsFunctions().GetInternalVector()) {
|
||||
auto *function = functionUniquePtr.get();
|
||||
WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
|
||||
project, *function, globalObjectsContainer, eventsBasedObject, oldName,
|
||||
newName, isObjectGroup);
|
||||
project, projectScopedContainers, *function, oldName, newName,
|
||||
isObjectGroup);
|
||||
}
|
||||
|
||||
// Object groups can't have instances or be in other groups
|
||||
if (!isObjectGroup) {
|
||||
eventsBasedObject.GetInitialInstances().RenameInstancesOfObject(oldName,
|
||||
newName);
|
||||
auto &groups = eventsBasedObject.GetObjects().GetObjectGroups();
|
||||
for (std::size_t g = 0; g < groups.size(); ++g) {
|
||||
groups[g].RenameObject(oldName, newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
|
||||
gd::Project &project, gd::EventsFunction &eventsFunction,
|
||||
gd::ObjectsContainer &globalObjectsContainer,
|
||||
gd::ObjectsContainer &objectsContainer, const gd::String &oldName,
|
||||
gd::Project &project,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers,
|
||||
gd::EventsFunction &eventsFunction, const gd::String &oldName,
|
||||
const gd::String &newName, bool isObjectGroup) {
|
||||
// In theory we should pass a ProjectScopedContainers to this function so it
|
||||
// does not have to construct one. In practice, this is ok because we only
|
||||
// deal with objects.
|
||||
auto projectScopedContainers =
|
||||
gd::ProjectScopedContainers::MakeNewProjectScopedContainersFor(
|
||||
globalObjectsContainer, objectsContainer);
|
||||
|
||||
gd::EventsRefactorer::RenameObjectInEvents(
|
||||
project.GetCurrentPlatform(), projectScopedContainers,
|
||||
eventsFunction.GetEvents(), oldName, newName);
|
||||
@@ -1782,33 +1947,35 @@ void WholeProjectRefactorer::GlobalObjectOrGroupRenamed(
|
||||
bool isObjectGroup) {
|
||||
// Object groups can't be in other groups
|
||||
if (!isObjectGroup) {
|
||||
for (std::size_t g = 0; g < project.GetObjectGroups().size(); ++g) {
|
||||
project.GetObjectGroups()[g].RenameObject(oldName, newName);
|
||||
for (std::size_t g = 0; g < project.GetObjects().GetObjectGroups().size();
|
||||
++g) {
|
||||
project.GetObjects().GetObjectGroups()[g].RenameObject(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
gd::Layout &layout = project.GetLayout(i);
|
||||
if (layout.HasObjectNamed(oldName))
|
||||
if (layout.GetObjects().HasObjectNamed(oldName))
|
||||
continue;
|
||||
|
||||
ObjectOrGroupRenamedInLayout(project, layout, oldName, newName,
|
||||
ObjectOrGroupRenamedInScene(project, layout, oldName, newName,
|
||||
isObjectGroup);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::GlobalObjectRemoved(
|
||||
gd::Project &project, const gd::String &objectName) {
|
||||
for (std::size_t g = 0; g < project.GetObjectGroups().size(); ++g) {
|
||||
project.GetObjectGroups()[g].RemoveObject(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);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
gd::Layout &layout = project.GetLayout(i);
|
||||
if (layout.HasObjectNamed(objectName))
|
||||
if (layout.GetObjects().HasObjectNamed(objectName))
|
||||
continue;
|
||||
|
||||
ObjectRemovedInLayout(project, layout, objectName);
|
||||
ObjectRemovedInScene(project, layout, objectName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1816,41 +1983,40 @@ void WholeProjectRefactorer::BehaviorsAddedToGlobalObject(
|
||||
gd::Project &project, const gd::String &objectName) {
|
||||
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
|
||||
gd::Layout &layout = project.GetLayout(i);
|
||||
if (layout.HasObjectNamed(objectName))
|
||||
if (layout.GetObjects().HasObjectNamed(objectName))
|
||||
continue;
|
||||
|
||||
BehaviorsAddedToObjectInLayout(project, layout, objectName);
|
||||
BehaviorsAddedToObjectInScene(project, layout, objectName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RemoveLayer(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &layerName) {
|
||||
void WholeProjectRefactorer::RemoveLayerInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &layerName) {
|
||||
if (layerName.empty())
|
||||
return;
|
||||
|
||||
layout.GetInitialInstances().RemoveAllInstancesOnLayer(layerName);
|
||||
scene.GetInitialInstances().RemoveAllInstancesOnLayer(layerName);
|
||||
|
||||
std::vector<gd::String> externalLayoutsNames =
|
||||
GetAssociatedExternalLayouts(project, layout);
|
||||
GetAssociatedExternalLayouts(project, scene);
|
||||
for (gd::String name : externalLayoutsNames) {
|
||||
auto &externalLayout = project.GetExternalLayout(name);
|
||||
externalLayout.GetInitialInstances().RemoveAllInstancesOnLayer(layerName);
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::MergeLayers(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
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;
|
||||
|
||||
layout.GetInitialInstances().MoveInstancesToLayer(originLayerName,
|
||||
targetLayerName);
|
||||
scene.GetInitialInstances().MoveInstancesToLayer(originLayerName,
|
||||
targetLayerName);
|
||||
|
||||
std::vector<gd::String> externalLayoutsNames =
|
||||
GetAssociatedExternalLayouts(project, layout);
|
||||
GetAssociatedExternalLayouts(project, scene);
|
||||
for (gd::String name : externalLayoutsNames) {
|
||||
auto &externalLayout = project.GetExternalLayout(name);
|
||||
externalLayout.GetInitialInstances().MoveInstancesToLayer(originLayerName,
|
||||
@@ -1858,6 +2024,24 @@ void WholeProjectRefactorer::MergeLayers(gd::Project &project,
|
||||
}
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::RemoveLayerInEventsBasedObject(
|
||||
gd::EventsBasedObject &eventsBasedObject, const gd::String &layerName) {
|
||||
if (layerName.empty())
|
||||
return;
|
||||
|
||||
eventsBasedObject.GetInitialInstances().RemoveAllInstancesOnLayer(layerName);
|
||||
}
|
||||
|
||||
void WholeProjectRefactorer::MergeLayersInEventsBasedObject(
|
||||
gd::EventsBasedObject &eventsBasedObject, const gd::String &originLayerName,
|
||||
const gd::String &targetLayerName) {
|
||||
if (originLayerName == targetLayerName || originLayerName.empty())
|
||||
return;
|
||||
|
||||
eventsBasedObject.GetInitialInstances().MoveInstancesToLayer(originLayerName,
|
||||
targetLayerName);
|
||||
}
|
||||
|
||||
size_t WholeProjectRefactorer::GetLayoutAndExternalLayoutLayerInstancesCount(
|
||||
gd::Project &project, gd::Layout &layout, const gd::String &layerName) {
|
||||
size_t count = layout.GetInitialInstances().GetLayerInstancesCount(layerName);
|
||||
|
@@ -19,6 +19,7 @@ class Project;
|
||||
class Layout;
|
||||
class Layer;
|
||||
class Object;
|
||||
class ObjectGroup;
|
||||
class String;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
@@ -37,6 +38,7 @@ class BehaviorMetadata;
|
||||
class UnfilledRequiredBehaviorPropertyProblem;
|
||||
class ProjectBrowser;
|
||||
class SerializerElement;
|
||||
class ProjectScopedContainers;
|
||||
struct VariablesRenamingChangesetNode;
|
||||
} // namespace gd
|
||||
|
||||
@@ -57,6 +59,8 @@ 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(); }
|
||||
|
||||
@@ -67,7 +71,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 ObjectOrGroupRenamedInLayout, ObjectRemovedInLayout,
|
||||
* \TODO Ideally ObjectOrGroupRenamedInScene, ObjectRemovedInScene,
|
||||
* GlobalObjectOrGroupRenamed, GlobalObjectRemoved would be implemented
|
||||
* using ExposeProjectEvents.
|
||||
*/
|
||||
@@ -90,6 +94,18 @@ 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.
|
||||
@@ -338,40 +354,91 @@ 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 RenameLayer(gd::Project &project, gd::Layout &layout,
|
||||
const gd::String &oldName, const gd::String &newName);
|
||||
static void RenameLayerInScene(gd::Project &project, gd::Layout &scene,
|
||||
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 RenameLayerEffect(gd::Project &project, gd::Layout &layout,
|
||||
gd::Layer &layer, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
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 RenameObjectAnimation(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
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 RenameObjectPoint(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
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 RenameObjectEffect(gd::Project &project, gd::Layout &layout,
|
||||
gd::Object &object, const gd::String &oldName,
|
||||
const gd::String &newName);
|
||||
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
|
||||
@@ -379,11 +446,11 @@ 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 ObjectOrGroupRenamedInLayout(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup);
|
||||
static void ObjectOrGroupRenamedInScene(gd::Project &project,
|
||||
gd::Layout &scene,
|
||||
const gd::String &oldName,
|
||||
const gd::String &newName,
|
||||
bool isObjectGroup);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is removed in a layout
|
||||
@@ -391,9 +458,8 @@ 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 ObjectRemovedInLayout(gd::Project& project,
|
||||
gd::Layout& layout,
|
||||
const gd::String& objectName);
|
||||
static void ObjectRemovedInScene(gd::Project &project, gd::Layout &scene,
|
||||
const gd::String &objectName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after behaviors are added to an object in a
|
||||
@@ -403,9 +469,9 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
* The refactor is actually applied to all objects because it allow to handle
|
||||
* groups.
|
||||
*/
|
||||
static void BehaviorsAddedToObjectInLayout(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &objectName);
|
||||
static void BehaviorsAddedToObjectInScene(gd::Project &project,
|
||||
gd::Layout &layout,
|
||||
const gd::String &objectName);
|
||||
|
||||
/**
|
||||
* \brief Refactor the project after an object is removed in an events-based
|
||||
@@ -416,8 +482,6 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
static void ObjectRemovedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
const gd::String& objectName);
|
||||
|
||||
/**
|
||||
@@ -427,7 +491,7 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
*/
|
||||
static void ObjectOrGroupRenamedInEventsBasedObject(
|
||||
gd::Project& project,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers,
|
||||
gd::EventsBasedObject& eventsBasedObject,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
@@ -440,9 +504,8 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
*/
|
||||
static void ObjectOrGroupRenamedInEventsFunction(
|
||||
gd::Project& project,
|
||||
const gd::ProjectScopedContainers &projectScopedContainers,
|
||||
gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
const gd::String& oldName,
|
||||
const gd::String& newName,
|
||||
bool isObjectGroup);
|
||||
@@ -455,8 +518,6 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
static void ObjectRemovedInEventsFunction(
|
||||
gd::Project& project,
|
||||
gd::EventsFunction& eventsFunction,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer,
|
||||
const gd::String& objectName);
|
||||
|
||||
/**
|
||||
@@ -518,16 +579,31 @@ class GD_CORE_API WholeProjectRefactorer {
|
||||
/**
|
||||
* \brief Remove all the instances from one layer.
|
||||
*/
|
||||
static void RemoveLayer(gd::Project &project, gd::Layout &layout,
|
||||
static void RemoveLayerInScene(gd::Project &project, gd::Layout &scene,
|
||||
const gd::String &layerName);
|
||||
|
||||
/**
|
||||
* \brief Move all the instances from one layer into another.
|
||||
*/
|
||||
static void MergeLayers(gd::Project &project, gd::Layout &layout,
|
||||
static void MergeLayersInScene(gd::Project &project, gd::Layout &scene,
|
||||
const gd::String &originLayerName,
|
||||
const gd::String &targetLayerName);
|
||||
|
||||
/**
|
||||
* \brief Remove all the instances from one layer.
|
||||
*/
|
||||
static void
|
||||
RemoveLayerInEventsBasedObject(gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::String &layerName);
|
||||
|
||||
/**
|
||||
* \brief Move all the instances from one layer into another.
|
||||
*/
|
||||
static void
|
||||
MergeLayersInEventsBasedObject(gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::String &originLayerName,
|
||||
const gd::String &targetLayerName);
|
||||
|
||||
/**
|
||||
* \brief Return the number of instances on the layer named \a layerName and
|
||||
* all its associated layouts.
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -31,10 +32,10 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API BehaviorConfigurationContainer {
|
||||
public:
|
||||
BehaviorConfigurationContainer() : folded(false){};
|
||||
BehaviorConfigurationContainer() : folded(false), quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
BehaviorConfigurationContainer(const gd::String& name_,
|
||||
const gd::String& type_)
|
||||
: name(name_), type(type_), folded(false){};
|
||||
: name(name_), type(type_), folded(false), quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
virtual ~BehaviorConfigurationContainer();
|
||||
virtual BehaviorConfigurationContainer* Clone() const { return new BehaviorConfigurationContainer(*this); }
|
||||
|
||||
@@ -114,6 +115,13 @@ class GD_CORE_API BehaviorConfigurationContainer {
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
void SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
|
||||
return quickCustomizationVisibility;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -160,6 +168,7 @@ 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 behaviorProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
auto objectProperties = std::map<gd::String, gd::PropertyDescriptor>();
|
||||
|
||||
for (auto &property : properties.GetInternalVector()) {
|
||||
const auto &propertyName = property->GetName();
|
||||
const auto &propertyType = property->GetType();
|
||||
|
||||
// Copy the property
|
||||
behaviorProperties[propertyName] = *property;
|
||||
objectProperties[propertyName] = *property;
|
||||
|
||||
auto &newProperty = behaviorProperties[propertyName];
|
||||
auto &newProperty = objectProperties[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 behaviorProperties;
|
||||
return objectProperties;
|
||||
}
|
||||
|
||||
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,6 +21,9 @@ 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();
|
||||
@@ -35,19 +38,58 @@ std::unique_ptr<gd::ObjectConfiguration> CustomObjectConfiguration::Clone() cons
|
||||
return gd::make_unique<gd::CustomObjectConfiguration>(*this);
|
||||
}
|
||||
|
||||
gd::ObjectConfiguration &CustomObjectConfiguration::GetChildObjectConfiguration(const gd::String &objectName) {
|
||||
const gd::EventsBasedObject* CustomObjectConfiguration::GetEventsBasedObject() const {
|
||||
if (!project->HasEventsBasedObject(GetType())) {
|
||||
return nullptr;
|
||||
}
|
||||
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) {
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
if (!eventsBasedObject.HasObjectNamed(objectName)) {
|
||||
if (!eventsBasedObject->GetObjects().HasObjectNamed(objectName)) {
|
||||
gd::LogError("Tried to get the configuration of a child-object:" + objectName
|
||||
+ " that doesn't exist in the event-based object: " + GetType());
|
||||
return badObjectConfiguration;
|
||||
}
|
||||
|
||||
auto &childObject = eventsBasedObject.GetObject(objectName);
|
||||
auto &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(
|
||||
@@ -60,7 +102,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>();
|
||||
@@ -90,8 +132,7 @@ bool CustomObjectConfiguration::UpdateProperty(const gd::String& propertyName,
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
CustomObjectConfiguration::GetInitialInstanceProperties(
|
||||
const gd::InitialInstance &initialInstance, gd::Project &project,
|
||||
gd::Layout &scene) {
|
||||
const gd::InitialInstance &initialInstance) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
if (!animations.HasNoAnimations()) {
|
||||
properties["animation"] =
|
||||
@@ -105,7 +146,7 @@ CustomObjectConfiguration::GetInitialInstanceProperties(
|
||||
|
||||
bool CustomObjectConfiguration::UpdateInitialInstanceProperty(
|
||||
gd::InitialInstance &initialInstance, const gd::String &name,
|
||||
const gd::String &value, gd::Project &project, gd::Layout &scene) {
|
||||
const gd::String &value) {
|
||||
if (name == "animation") {
|
||||
initialInstance.SetRawDoubleProperty(
|
||||
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
|
||||
@@ -122,12 +163,14 @@ void CustomObjectConfiguration::DoSerializeTo(SerializerElement& element) const
|
||||
animations.SerializeTo(animatableElement);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
@@ -139,12 +182,16 @@ void CustomObjectConfiguration::DoUnserializeFrom(Project& project,
|
||||
animations.UnserializeFrom(animatableElement);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,12 +245,26 @@ void CustomObjectConfiguration::ExposeResources(gd::ArbitraryResourceWorker& wor
|
||||
}
|
||||
const auto &eventsBasedObject = project->GetEventsBasedObject(GetType());
|
||||
|
||||
for (auto& childObject : eventsBasedObject.GetObjects()) {
|
||||
for (auto& childObject : eventsBasedObject.GetObjects().GetObjects()) {
|
||||
auto &configuration = GetChildObjectConfiguration(childObject->GetName());
|
||||
configuration.ExposeResources(worker);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -211,3 +272,16 @@ const SpriteAnimationList& CustomObjectConfiguration::GetAnimations() const {
|
||||
SpriteAnimationList& CustomObjectConfiguration::GetAnimations() {
|
||||
return animations;
|
||||
}
|
||||
|
||||
const gd::CustomObjectConfiguration::EdgeAnchor
|
||||
CustomObjectConfiguration::GetEdgeAnchorFromString(const gd::String &value) {
|
||||
return (value == _("Window left") || value == _("Window top"))
|
||||
? gd::CustomObjectConfiguration::EdgeAnchor::MinEdge
|
||||
: (value == _("Window right") || value == _("Window bottom"))
|
||||
? gd::CustomObjectConfiguration::EdgeAnchor::MaxEdge
|
||||
: value == _("Proportional")
|
||||
? gd::CustomObjectConfiguration::EdgeAnchor::Proportional
|
||||
: value == _("Window center")
|
||||
? gd::CustomObjectConfiguration::EdgeAnchor::Center
|
||||
: gd::CustomObjectConfiguration::EdgeAnchor::NoAnchor;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ namespace gd {
|
||||
class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
public:
|
||||
CustomObjectConfiguration(const Project& project_, const String& type_)
|
||||
: project(&project_) {
|
||||
: project(&project_), isMarkedAsOverridingEventsBasedObjectChildrenConfiguration(false) {
|
||||
SetType(type_);
|
||||
}
|
||||
std::unique_ptr<gd::ObjectConfiguration> Clone() const override;
|
||||
@@ -58,18 +58,35 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
|
||||
const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
const gd::InitialInstance& instance) override;
|
||||
bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
const gd::String& value) override;
|
||||
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
gd::ObjectConfiguration &GetChildObjectConfiguration(const gd::String& objectName);
|
||||
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;
|
||||
|
||||
/**
|
||||
* \brief Return the animation configuration for Animatable custom objects.
|
||||
@@ -81,15 +98,32 @@ class CustomObjectConfiguration : public gd::ObjectConfiguration {
|
||||
*/
|
||||
SpriteAnimationList& GetAnimations();
|
||||
|
||||
enum EdgeAnchor {
|
||||
NoAnchor = 0,
|
||||
MinEdge = 1,
|
||||
MaxEdge = 2,
|
||||
Proportional = 3,
|
||||
Center = 4,
|
||||
};
|
||||
|
||||
static const gd::CustomObjectConfiguration::EdgeAnchor
|
||||
GetEdgeAnchorFromString(const gd::String &value);
|
||||
|
||||
protected:
|
||||
void DoSerializeTo(SerializerElement& element) const override;
|
||||
void DoUnserializeFrom(Project& project, const SerializerElement& element) override;
|
||||
|
||||
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;
|
||||
std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
|
||||
bool isMarkedAsOverridingEventsBasedObjectChildrenConfiguration;
|
||||
mutable std::map<gd::String, std::unique_ptr<gd::ObjectConfiguration>> childObjectConfigurations;
|
||||
|
||||
static gd::ObjectConfiguration badObjectConfiguration;
|
||||
|
||||
|
@@ -21,8 +21,8 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API Effect {
|
||||
public:
|
||||
Effect(){};
|
||||
virtual ~Effect(){};
|
||||
Effect() : folded(false) {};
|
||||
virtual ~Effect() {};
|
||||
|
||||
void SetName(const gd::String& name_) { name = name_; }
|
||||
const gd::String& GetName() const { return name; }
|
||||
@@ -32,6 +32,9 @@ class GD_CORE_API Effect {
|
||||
}
|
||||
const gd::String& GetEffectType() const { return effectType; }
|
||||
|
||||
void SetFolded(bool fold = true) { folded = fold; }
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
void SetDoubleParameter(const gd::String& name, double value) {
|
||||
doubleParameters[name] = value;
|
||||
}
|
||||
@@ -85,6 +88,7 @@ class GD_CORE_API Effect {
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
|
||||
private:
|
||||
bool folded;
|
||||
gd::String name; ///< The name of the layer.
|
||||
gd::String effectType; ///< The name of the effect to apply.
|
||||
std::map<gd::String, double> doubleParameters; ///< Values of parameters being doubles, keyed by names.
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* 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"
|
||||
@@ -12,9 +13,10 @@ namespace gd {
|
||||
|
||||
EventsBasedBehavior::EventsBasedBehavior()
|
||||
: AbstractEventsBasedEntity(
|
||||
"MyBehavior",
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
sharedPropertyDescriptors(gd::EventsFunctionsContainer::FunctionOwner::Behavior) {}
|
||||
"MyBehavior", gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
sharedPropertyDescriptors(
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Behavior),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
|
||||
void EventsBasedBehavior::SerializeTo(SerializerElement& element) const {
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
@@ -24,6 +26,13 @@ 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,
|
||||
@@ -33,6 +42,14 @@ 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,6 +11,7 @@
|
||||
#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;
|
||||
@@ -88,6 +89,15 @@ 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.
|
||||
*/
|
||||
@@ -141,6 +151,7 @@ class GD_CORE_API EventsBasedBehavior: public AbstractEventsBasedEntity {
|
||||
gd::String objectType;
|
||||
bool isPrivate = false;
|
||||
gd::PropertiesContainer sharedPropertyDescriptors;
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -13,21 +13,21 @@ EventsBasedObject::EventsBasedObject()
|
||||
: AbstractEventsBasedEntity(
|
||||
"MyObject",
|
||||
gd::EventsFunctionsContainer::FunctionOwner::Object),
|
||||
ObjectsContainer(),
|
||||
isRenderedIn3D(false),
|
||||
isAnimatable(false),
|
||||
isTextContainer(false) {
|
||||
isTextContainer(false),
|
||||
isInnerAreaFollowingParentSize(false),
|
||||
isUsingLegacyInstancesRenderer(false),
|
||||
areaMinX(0),
|
||||
areaMinY(0),
|
||||
areaMinZ(0),
|
||||
areaMaxX(64),
|
||||
areaMaxY(64),
|
||||
areaMaxZ(64) {
|
||||
}
|
||||
|
||||
EventsBasedObject::~EventsBasedObject() {}
|
||||
|
||||
EventsBasedObject::EventsBasedObject(const gd::EventsBasedObject &_eventBasedObject)
|
||||
: AbstractEventsBasedEntity(_eventBasedObject) {
|
||||
// TODO Add a copy constructor in ObjectsContainer.
|
||||
initialObjects = gd::Clone(_eventBasedObject.initialObjects);
|
||||
objectGroups = _eventBasedObject.objectGroups;
|
||||
}
|
||||
|
||||
void EventsBasedObject::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("defaultName", defaultName);
|
||||
if (isRenderedIn3D) {
|
||||
@@ -39,10 +39,24 @@ void EventsBasedObject::SerializeTo(SerializerElement& element) const {
|
||||
if (isTextContainer) {
|
||||
element.SetBoolAttribute("isTextContainer", true);
|
||||
}
|
||||
if (isInnerAreaFollowingParentSize) {
|
||||
element.SetBoolAttribute("isInnerAreaFollowingParentSize", true);
|
||||
}
|
||||
element.SetBoolAttribute("isUsingLegacyInstancesRenderer", isUsingLegacyInstancesRenderer);
|
||||
element.SetIntAttribute("areaMinX", areaMinX);
|
||||
element.SetIntAttribute("areaMinY", areaMinY);
|
||||
element.SetIntAttribute("areaMinZ", areaMinZ);
|
||||
element.SetIntAttribute("areaMaxX", areaMaxX);
|
||||
element.SetIntAttribute("areaMaxY", areaMaxY);
|
||||
element.SetIntAttribute("areaMaxZ", areaMaxZ);
|
||||
|
||||
AbstractEventsBasedEntity::SerializeTo(element);
|
||||
SerializeObjectsTo(element.AddChild("objects"));
|
||||
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
objectsContainer.SerializeObjectsTo(element.AddChild("objects"));
|
||||
objectsContainer.SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
objectsContainer.GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
|
||||
layers.SerializeLayersTo(element.AddChild("layers"));
|
||||
initialInstances.SerializeTo(element.AddChild("instances"));
|
||||
}
|
||||
|
||||
void EventsBasedObject::UnserializeFrom(gd::Project& project,
|
||||
@@ -51,13 +65,40 @@ 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);
|
||||
areaMaxX = element.GetIntAttribute("areaMaxX", 64);
|
||||
areaMaxY = element.GetIntAttribute("areaMaxY", 64);
|
||||
areaMaxZ = element.GetIntAttribute("areaMaxZ", 64);
|
||||
|
||||
AbstractEventsBasedEntity::UnserializeFrom(project, element);
|
||||
UnserializeObjectsFrom(project, element.GetChild("objects"));
|
||||
objectsContainer.UnserializeObjectsFrom(project, element.GetChild("objects"));
|
||||
if (element.HasChild("objectsFolderStructure")) {
|
||||
UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
|
||||
objectsContainer.UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
|
||||
}
|
||||
objectsContainer.AddMissingObjectsInRootFolder();
|
||||
objectsContainer.GetObjectGroups().UnserializeFrom(
|
||||
element.GetChild("objectsGroups"));
|
||||
|
||||
if (element.HasChild("layers")) {
|
||||
layers.UnserializeLayersFrom(element.GetChild("layers"));
|
||||
} else {
|
||||
layers.Reset();
|
||||
}
|
||||
|
||||
initialInstances.UnserializeFrom(element.GetChild("instances"));
|
||||
if (element.HasAttribute("isUsingLegacyInstancesRenderer")) {
|
||||
isUsingLegacyInstancesRenderer =
|
||||
element.GetBoolAttribute("isUsingLegacyInstancesRenderer", false);
|
||||
}
|
||||
else {
|
||||
// Compatibility with GD <= 5.4.212
|
||||
isUsingLegacyInstancesRenderer = initialInstances.GetInstancesCount() == 0;
|
||||
// end of compatibility code
|
||||
}
|
||||
AddMissingObjectsInRootFolder();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,12 +3,13 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EVENTSBASEDOBJECT_H
|
||||
#define GDCORE_EVENTSBASEDOBJECT_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/AbstractEventsBasedEntity.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Project/LayersContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
@@ -26,11 +27,10 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public ObjectsContainer {
|
||||
class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity {
|
||||
public:
|
||||
EventsBasedObject();
|
||||
virtual ~EventsBasedObject();
|
||||
EventsBasedObject(const gd::EventsBasedObject &_eventBasedObject);
|
||||
|
||||
/**
|
||||
* \brief Return a pointer to a new EventsBasedObject constructed from
|
||||
@@ -101,16 +101,216 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public Ob
|
||||
/**
|
||||
* \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 &
|
||||
MarkAsInnerAreaFollowingParentSize(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 Declare that custom object are rendered using their child-objects
|
||||
* instead of their child-instances.
|
||||
*/
|
||||
EventsBasedObject &
|
||||
MakAsUsingLegacyInstancesRenderer(bool isUsingLegacyInstancesRenderer_) {
|
||||
isUsingLegacyInstancesRenderer = isUsingLegacyInstancesRenderer_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if custom object are rendered using their child-objects
|
||||
* instead of their child-instances.
|
||||
*/
|
||||
bool IsUsingLegacyInstancesRenderer() const {
|
||||
return isUsingLegacyInstancesRenderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return true if the object needs a TextContainer capability.
|
||||
*/
|
||||
bool IsTextContainer() const { return isTextContainer; }
|
||||
|
||||
/** \name Layers
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Get the layers of the custom object.
|
||||
*/
|
||||
const gd::LayersContainer& GetLayers() const { return layers; }
|
||||
|
||||
/**
|
||||
* \brief Get the layers of the custom object.
|
||||
*/
|
||||
gd::LayersContainer& GetLayers() { return layers; }
|
||||
///@}
|
||||
|
||||
/** \name Child objects
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Get the objects of the custom object.
|
||||
*/
|
||||
gd::ObjectsContainer& GetObjects() {
|
||||
return objectsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the objects of the custom object.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjects() const {
|
||||
return objectsContainer;
|
||||
}
|
||||
///@}
|
||||
|
||||
/** \name Instances
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Get the instances of the custom object.
|
||||
*/
|
||||
gd::InitialInstancesContainer& GetInitialInstances() {
|
||||
return initialInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the instances of the custom object.
|
||||
*/
|
||||
const gd::InitialInstancesContainer& GetInitialInstances() const {
|
||||
return initialInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the left bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMinX() const {
|
||||
return areaMinX;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the left bound of the custom object.
|
||||
*/
|
||||
void SetAreaMinX(int areaMinX_) {
|
||||
areaMinX = areaMinX_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the top bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMinY() const {
|
||||
return areaMinY;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the top bound of the custom object.
|
||||
*/
|
||||
void SetAreaMinY(int areaMinY_) {
|
||||
areaMinY = areaMinY_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the min Z bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMinZ() const {
|
||||
return areaMinZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the min Z bound of the custom object.
|
||||
*/
|
||||
void SetAreaMinZ(int areaMinZ_) {
|
||||
areaMinZ = areaMinZ_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the right bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMaxX() const {
|
||||
return areaMaxX;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the right bound of the custom object.
|
||||
*/
|
||||
void SetAreaMaxX(int areaMaxX_) {
|
||||
areaMaxX = areaMaxX_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the bottom bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMaxY() const {
|
||||
return areaMaxY;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the bottom bound of the custom object.
|
||||
*/
|
||||
void SetAreaMaxY(int areaMaxY_) {
|
||||
areaMaxY = areaMaxY_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the max Z bound of the custom object.
|
||||
*
|
||||
* This is used only if there is any initial instances.
|
||||
*
|
||||
* \see EventsBasedObject::GetInitialInstances
|
||||
*/
|
||||
int GetAreaMaxZ() const {
|
||||
return areaMaxZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the bottom bound of the custom object.
|
||||
*/
|
||||
void SetAreaMaxZ(int areaMaxZ_) {
|
||||
areaMaxZ = areaMaxZ_;
|
||||
}
|
||||
///@}
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
@@ -121,8 +321,17 @@ class GD_CORE_API EventsBasedObject: public AbstractEventsBasedEntity, public Ob
|
||||
bool isRenderedIn3D;
|
||||
bool isAnimatable;
|
||||
bool isTextContainer;
|
||||
bool isInnerAreaFollowingParentSize;
|
||||
bool isUsingLegacyInstancesRenderer;
|
||||
gd::InitialInstancesContainer initialInstances;
|
||||
gd::LayersContainer layers;
|
||||
gd::ObjectsContainer objectsContainer;
|
||||
double areaMinX;
|
||||
double areaMinY;
|
||||
double areaMinZ;
|
||||
double areaMaxX;
|
||||
double areaMaxY;
|
||||
double areaMaxZ;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSBASEDOBJECT_H
|
||||
|
@@ -16,41 +16,41 @@ EventsFunction::EventsFunction() : functionType(Action) {
|
||||
expressionType.SetName("expression");
|
||||
}
|
||||
|
||||
const std::vector<gd::ParameterMetadata>& EventsFunction::GetParametersForEvents(
|
||||
const gd::EventsFunctionsContainer& functionsContainer) const {
|
||||
const gd::ParameterMetadataContainer &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.clear();
|
||||
actionWithOperationParameters.ClearParameters();
|
||||
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.size();
|
||||
i++)
|
||||
{
|
||||
actionWithOperationParameters.push_back(expressionParameters[i]);
|
||||
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));
|
||||
}
|
||||
gd::ParameterMetadata parameterMetadata;
|
||||
parameterMetadata.SetName("Value").SetValueTypeMetadata(expression.expressionType);
|
||||
actionWithOperationParameters.push_back(parameterMetadata);
|
||||
parameterMetadata.SetName("Value").SetValueTypeMetadata(
|
||||
expression.expressionType);
|
||||
actionWithOperationParameters.AddParameter(parameterMetadata);
|
||||
for (size_t i = expressionValueParameterIndex;
|
||||
i < expressionParameters.size();
|
||||
i++)
|
||||
{
|
||||
actionWithOperationParameters.push_back(expressionParameters[i]);
|
||||
i < expressionParameters.GetParametersCount(); i++) {
|
||||
actionWithOperationParameters.AddParameter(
|
||||
expressionParameters.GetParameter(i));
|
||||
}
|
||||
|
||||
return actionWithOperationParameters;
|
||||
@@ -101,10 +101,7 @@ void EventsFunction::SerializeTo(SerializerElement& element) const {
|
||||
expressionType.SerializeTo(element.AddChild("expressionType"));
|
||||
}
|
||||
gd::SerializerElement& parametersElement = element.AddChild("parameters");
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (const auto& parameter : parameters) {
|
||||
parameter.SerializeTo(parametersElement.AddChild("parameter"));
|
||||
}
|
||||
parameters.SerializeParametersTo(parametersElement);
|
||||
|
||||
objectGroups.SerializeTo(element.AddChild("objectGroups"));
|
||||
}
|
||||
@@ -146,15 +143,9 @@ void EventsFunction::UnserializeFrom(gd::Project& project,
|
||||
else
|
||||
functionType = Action;
|
||||
|
||||
const gd::SerializerElement& parametersElement =
|
||||
const gd::SerializerElement ¶metersElement =
|
||||
element.GetChild("parameters");
|
||||
parameters.clear();
|
||||
parametersElement.ConsiderAsArrayOf("parameter");
|
||||
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i) {
|
||||
ParameterMetadata parameter;
|
||||
parameter.UnserializeFrom(parametersElement.GetChild(i));
|
||||
parameters.push_back(parameter);
|
||||
}
|
||||
parameters.UnserializeParametersFrom(parametersElement);
|
||||
|
||||
objectGroups.UnserializeFrom(element.GetChild("objectGroups"));
|
||||
}
|
||||
|
@@ -3,14 +3,13 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EVENTSFUNCTION_H
|
||||
#define GDCORE_EVENTSFUNCTION_H
|
||||
#pragma once
|
||||
|
||||
#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
|
||||
@@ -241,7 +240,7 @@ class GD_CORE_API EventsFunction {
|
||||
* to the generated function, like "runtimeScene" and "eventsFunctionContext".
|
||||
* This should be transparent to the user.
|
||||
*/
|
||||
const std::vector<gd::ParameterMetadata>& GetParametersForEvents(
|
||||
const gd::ParameterMetadataContainer& GetParametersForEvents(
|
||||
const gd::EventsFunctionsContainer& functionsContainer) const;
|
||||
|
||||
/**
|
||||
@@ -254,14 +253,14 @@ class GD_CORE_API EventsFunction {
|
||||
* to the generated function, like "runtimeScene" and "eventsFunctionContext".
|
||||
* This should be transparent to the user.
|
||||
*/
|
||||
const std::vector<gd::ParameterMetadata>& GetParameters() const {
|
||||
const ParameterMetadataContainer& GetParameters() const {
|
||||
return parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return the parameters.
|
||||
*/
|
||||
std::vector<gd::ParameterMetadata>& GetParameters() { return parameters; };
|
||||
ParameterMetadataContainer& GetParameters() { return parameters; };
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the object groups that can be used in the
|
||||
@@ -300,14 +299,11 @@ class GD_CORE_API EventsFunction {
|
||||
gd::ValueTypeMetadata expressionType;
|
||||
gd::EventsList events;
|
||||
FunctionType functionType;
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
mutable std::vector<gd::ParameterMetadata> actionWithOperationParameters;
|
||||
ParameterMetadataContainer parameters;
|
||||
mutable gd::ParameterMetadataContainer actionWithOperationParameters;
|
||||
gd::ObjectGroupsContainer objectGroups;
|
||||
bool isPrivate = false;
|
||||
bool isAsync = false;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSFUNCTION_H
|
||||
#endif
|
||||
|
@@ -154,7 +154,7 @@ void EventsFunctionsExtension::UnserializeExtensionDeclarationFrom(
|
||||
for (size_t i = 0; i < dependenciesElement.GetChildrenCount(); ++i)
|
||||
dependencies.push_back(
|
||||
UnserializeDependencyFrom(dependenciesElement.GetChild(i)));
|
||||
|
||||
|
||||
globalVariables.UnserializeFrom(element.GetChild("globalVariables"));
|
||||
sceneVariables.UnserializeFrom(element.GetChild("sceneVariables"));
|
||||
|
||||
@@ -184,7 +184,11 @@ void EventsFunctionsExtension::UnserializeExtensionImplementationFrom(
|
||||
UnserializeEventsFunctionsFrom(project, element.GetChild("eventsFunctions"));
|
||||
eventsBasedBehaviors.UnserializeElementsFrom(
|
||||
"eventsBasedBehavior", project, element.GetChild("eventsBasedBehaviors"));
|
||||
eventsBasedObjects.UnserializeElementsFrom(
|
||||
|
||||
// It's important to load the objects without erasing them first as each object
|
||||
// might reference other objects, and so need to know if a custom object exists
|
||||
// in the project or not.
|
||||
eventsBasedObjects.ProgressivelyUnserializeElementsFrom(
|
||||
"eventsBasedObject", project, element.GetChild("eventsBasedObjects"));
|
||||
}
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
|
@@ -96,19 +96,6 @@ class GD_CORE_API ExternalLayout {
|
||||
gd::String associatedLayout;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Functor testing ExternalLayout' name
|
||||
*/
|
||||
struct ExternalLayoutHasName
|
||||
: public std::binary_function<std::unique_ptr<gd::ExternalLayout>,
|
||||
gd::String,
|
||||
bool> {
|
||||
bool operator()(const std::unique_ptr<gd::ExternalLayout>& externalLayout,
|
||||
gd::String name) const {
|
||||
return externalLayout->GetName() == name;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EXTERNALLAYOUT_H
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -26,7 +27,11 @@ InitialInstance::InitialInstance()
|
||||
rotationX(0),
|
||||
rotationY(0),
|
||||
zOrder(0),
|
||||
opacity(255),
|
||||
layer(""),
|
||||
flippedX(false),
|
||||
flippedY(false),
|
||||
flippedZ(false),
|
||||
customSize(false),
|
||||
customDepth(false),
|
||||
width(0),
|
||||
@@ -56,7 +61,11 @@ void InitialInstance::UnserializeFrom(const SerializerElement& element) {
|
||||
SetHasCustomDepth(false);
|
||||
}
|
||||
SetZOrder(element.GetIntAttribute("zOrder", 0, "plan"));
|
||||
SetOpacity(element.GetIntAttribute("opacity", 255));
|
||||
SetLayer(element.GetStringAttribute("layer"));
|
||||
SetFlippedX(element.GetBoolAttribute("flippedX", false));
|
||||
SetFlippedY(element.GetBoolAttribute("flippedY", false));
|
||||
SetFlippedZ(element.GetBoolAttribute("flippedZ", false));
|
||||
SetLocked(element.GetBoolAttribute("locked", false));
|
||||
SetSealed(element.GetBoolAttribute("sealed", false));
|
||||
SetShouldKeepRatio(element.GetBoolAttribute("keepRatio", false));
|
||||
@@ -112,6 +121,10 @@ void InitialInstance::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("y", GetY());
|
||||
if (GetZ() != 0) element.SetAttribute("z", GetZ());
|
||||
element.SetAttribute("zOrder", GetZOrder());
|
||||
if (GetOpacity() != 255) element.SetAttribute("opacity", GetOpacity());
|
||||
if (IsFlippedX()) element.SetAttribute("flippedX", IsFlippedX());
|
||||
if (IsFlippedY()) element.SetAttribute("flippedY", IsFlippedY());
|
||||
if (IsFlippedZ()) element.SetAttribute("flippedZ", IsFlippedZ());
|
||||
element.SetAttribute("layer", GetLayer());
|
||||
element.SetAttribute("angle", GetAngle());
|
||||
if (GetRotationX() != 0) element.SetAttribute("rotationX", GetRotationX());
|
||||
@@ -153,33 +166,36 @@ InitialInstance& InitialInstance::ResetPersistentUuid() {
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
InitialInstance::GetCustomProperties(gd::Project& project, gd::Layout& layout) {
|
||||
InitialInstance::GetCustomProperties(
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer) {
|
||||
// Find an object
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
if (objectsContainer.HasObjectNamed(GetObjectName()))
|
||||
return objectsContainer.GetObject(GetObjectName())
|
||||
.GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
.GetInitialInstanceProperties(*this);
|
||||
else if (globalObjectsContainer.HasObjectNamed(GetObjectName()))
|
||||
return globalObjectsContainer.GetObject(GetObjectName())
|
||||
.GetConfiguration()
|
||||
.GetInitialInstanceProperties(*this, project, layout);
|
||||
.GetInitialInstanceProperties(*this);
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
||||
bool InitialInstance::UpdateCustomProperty(const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
if (layout.HasObjectNamed(GetObjectName()))
|
||||
return layout.GetObject(GetObjectName())
|
||||
bool InitialInstance::UpdateCustomProperty(
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer) {
|
||||
if (objectsContainer.HasObjectNamed(GetObjectName()))
|
||||
return objectsContainer.GetObject(GetObjectName())
|
||||
.GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
else if (project.HasObjectNamed(GetObjectName()))
|
||||
return project.GetObject(GetObjectName())
|
||||
.UpdateInitialInstanceProperty(*this, name, value);
|
||||
else if (globalObjectsContainer.HasObjectNamed(GetObjectName()))
|
||||
return globalObjectsContainer.GetObject(GetObjectName())
|
||||
.GetConfiguration()
|
||||
.UpdateInitialInstanceProperty(*this, name, value, project, layout);
|
||||
.UpdateInitialInstanceProperty(*this, name, value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_INITIALINSTANCE_H
|
||||
#define GDCORE_INITIALINSTANCE_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
@@ -14,6 +14,7 @@ namespace gd {
|
||||
class PropertyDescriptor;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -28,7 +29,7 @@ class GD_CORE_API InitialInstance {
|
||||
* \brief Create an initial instance pointing to no object, at position (0,0).
|
||||
*/
|
||||
InitialInstance();
|
||||
virtual ~InitialInstance(){};
|
||||
virtual ~InitialInstance() {};
|
||||
|
||||
/**
|
||||
* Must return a pointer to a copy of the object. A such method is needed to
|
||||
@@ -122,6 +123,46 @@ class GD_CORE_API InitialInstance {
|
||||
*/
|
||||
void SetZOrder(int zOrder_) { zOrder = zOrder_; }
|
||||
|
||||
/**
|
||||
* \brief Get Opacity.
|
||||
*/
|
||||
int GetOpacity() const { return opacity; }
|
||||
|
||||
/**
|
||||
* \brief Set the opacity of the instance.
|
||||
*/
|
||||
void SetOpacity(int opacity_) { opacity = opacity_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance is flipped on X axis.
|
||||
*/
|
||||
bool IsFlippedX() const { return flippedX; }
|
||||
|
||||
/**
|
||||
* \brief Set whether the instance is flipped on X axis.
|
||||
*/
|
||||
void SetFlippedX(bool flippedX_) { flippedX = flippedX_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance is flipped on Y axis.
|
||||
*/
|
||||
bool IsFlippedY() const { return flippedY; }
|
||||
|
||||
/**
|
||||
* \brief Set whether the instance is flipped on Y axis.
|
||||
*/
|
||||
void SetFlippedY(bool flippedY_) { flippedY = flippedY_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance is flipped on Z axis.
|
||||
*/
|
||||
bool IsFlippedZ() const { return flippedZ; }
|
||||
|
||||
/**
|
||||
* \brief Set whether the instance is flipped on Z axis.
|
||||
*/
|
||||
void SetFlippedZ(bool flippedZ_) { flippedZ = flippedZ_; }
|
||||
|
||||
/**
|
||||
* \brief Get the layer the instance belongs to.
|
||||
*/
|
||||
@@ -133,8 +174,9 @@ class GD_CORE_API InitialInstance {
|
||||
void SetLayer(const gd::String& layer_) { layer = layer_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the instance has a width/height which is different from its
|
||||
* object default width/height. This is independent from `HasCustomDepth`.
|
||||
* \brief Return true if the instance has a width/height which is different
|
||||
* from its object default width/height. This is independent from
|
||||
* `HasCustomDepth`.
|
||||
*
|
||||
* \see gd::Object
|
||||
*/
|
||||
@@ -149,15 +191,13 @@ class GD_CORE_API InitialInstance {
|
||||
bool HasCustomDepth() const { return customDepth; }
|
||||
|
||||
/**
|
||||
* \brief Set whether the instance has a width/height which is different from its
|
||||
* object default width/height or not.
|
||||
* This is independent from `SetHasCustomDepth`.
|
||||
* \brief Set whether the instance has a width/height which is different from
|
||||
* its object default width/height or not. This is independent from
|
||||
* `SetHasCustomDepth`.
|
||||
*
|
||||
* \see gd::Object
|
||||
*/
|
||||
void SetHasCustomSize(bool hasCustomSize_) {
|
||||
customSize = hasCustomSize_;
|
||||
}
|
||||
void SetHasCustomSize(bool hasCustomSize_) { customSize = hasCustomSize_; }
|
||||
|
||||
/**
|
||||
* \brief Set whether the instance has a depth which is different from its
|
||||
@@ -264,7 +304,8 @@ class GD_CORE_API InitialInstance {
|
||||
* inserted in this map
|
||||
*/
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetCustomProperties(
|
||||
gd::Project& project, gd::Layout& layout);
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer);
|
||||
|
||||
/**
|
||||
* \brief Update the property called \a name with the new \a value.
|
||||
@@ -273,8 +314,8 @@ class GD_CORE_API InitialInstance {
|
||||
*/
|
||||
bool UpdateCustomProperty(const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
gd::ObjectsContainer& globalObjectsContainer,
|
||||
gd::ObjectsContainer& objectsContainer);
|
||||
|
||||
/**
|
||||
* \brief Get the value of a double property stored in the instance.
|
||||
@@ -342,6 +383,10 @@ class GD_CORE_API InitialInstance {
|
||||
double rotationX; ///< Instance angle on X axis (for a 3D object)
|
||||
double rotationY; ///< Instance angle on Y axis (for a 3D object)
|
||||
int zOrder; ///< Instance Z order (for a 2D object)
|
||||
int opacity; ///< Instance opacity
|
||||
bool flippedX; ///< True if the instance is flipped on X axis
|
||||
bool flippedY; ///< True if the instance is flipped on Y axis
|
||||
bool flippedZ; ///< True if the instance is flipped on Z axis
|
||||
gd::String layer; ///< Instance layer
|
||||
bool customSize; ///< True if object has a custom width and height
|
||||
bool customDepth; ///< True if object has a custom depth
|
||||
@@ -351,15 +396,13 @@ class GD_CORE_API InitialInstance {
|
||||
gd::VariablesContainer initialVariables; ///< Instance specific variables
|
||||
bool locked; ///< True if the instance is locked
|
||||
bool sealed; ///< True if the instance is sealed
|
||||
bool keepRatio; ///< True if the instance's dimensions
|
||||
/// should keep the same ratio.
|
||||
bool keepRatio; ///< True if the instance's dimensions
|
||||
/// should keep the same ratio.
|
||||
mutable gd::String persistentUuid; ///< A persistent random version 4 UUID,
|
||||
/// useful for hot reloading.
|
||||
|
||||
static gd::String*
|
||||
badStringPropertyValue; ///< Empty string returned by GetRawStringProperty
|
||||
static gd::String* badStringPropertyValue; ///< Empty string returned by
|
||||
///< GetRawStringProperty
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_INITIALINSTANCE_H
|
||||
|
@@ -294,17 +294,6 @@ class GD_CORE_API Layer {
|
||||
static gd::Camera badCamera;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Functor testing layer name
|
||||
*
|
||||
* \see gd::Layer
|
||||
*/
|
||||
struct LayerHasName : public std::binary_function<gd::Layer, gd::String, bool> {
|
||||
bool operator()(const Layer& layer, const gd::String& name) const {
|
||||
return layer.GetName() == name;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_LAYER_H
|
||||
|
138
Core/GDCore/Project/LayersContainer.cpp
Normal file
138
Core/GDCore/Project/LayersContainer.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "LayersContainer.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "Layer.h"
|
||||
#include "Layout.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::Layer LayersContainer::badLayer;
|
||||
|
||||
LayersContainer::LayersContainer() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
void LayersContainer::Reset() {
|
||||
layers.clear();
|
||||
gd::Layer layer;
|
||||
layer.SetCameraCount(1);
|
||||
layers.push_back(layer);
|
||||
}
|
||||
|
||||
gd::Layer& LayersContainer::GetLayer(const gd::String& name) {
|
||||
std::vector<gd::Layer>::iterator layer =
|
||||
find_if(layers.begin(), layers.end(), [&name](const gd::Layer& layer) {
|
||||
return layer.GetName() == name;
|
||||
});
|
||||
|
||||
if (layer != layers.end()) return *layer;
|
||||
|
||||
return badLayer;
|
||||
}
|
||||
|
||||
const gd::Layer& LayersContainer::GetLayer(const gd::String& name) const {
|
||||
std::vector<gd::Layer>::const_iterator layer =
|
||||
find_if(layers.begin(), layers.end(), [&name](const gd::Layer& layer) {
|
||||
return layer.GetName() == name;
|
||||
});
|
||||
|
||||
if (layer != layers.end()) return *layer;
|
||||
|
||||
return badLayer;
|
||||
}
|
||||
|
||||
gd::Layer& LayersContainer::GetLayer(std::size_t index) {
|
||||
return layers[index];
|
||||
}
|
||||
|
||||
const gd::Layer& LayersContainer::GetLayer(std::size_t index) const {
|
||||
return layers[index];
|
||||
}
|
||||
|
||||
std::size_t LayersContainer::GetLayersCount() const { return layers.size(); }
|
||||
|
||||
bool LayersContainer::HasLayerNamed(const gd::String& name) const {
|
||||
return (
|
||||
find_if(layers.begin(), layers.end(), [&name](const gd::Layer& layer) {
|
||||
return layer.GetName() == name;
|
||||
}) != layers.end());
|
||||
}
|
||||
std::size_t LayersContainer::GetLayerPosition(const gd::String& name) const {
|
||||
for (std::size_t i = 0; i < layers.size(); ++i) {
|
||||
if (layers[i].GetName() == name) return i;
|
||||
}
|
||||
return gd::String::npos;
|
||||
}
|
||||
|
||||
void LayersContainer::InsertNewLayer(const gd::String& name,
|
||||
std::size_t position) {
|
||||
gd::Layer newLayer;
|
||||
newLayer.SetName(name);
|
||||
if (position < layers.size())
|
||||
layers.insert(layers.begin() + position, newLayer);
|
||||
else
|
||||
layers.push_back(newLayer);
|
||||
}
|
||||
|
||||
void LayersContainer::InsertLayer(const gd::Layer& layer,
|
||||
std::size_t position) {
|
||||
if (position < layers.size())
|
||||
layers.insert(layers.begin() + position, layer);
|
||||
else
|
||||
layers.push_back(layer);
|
||||
}
|
||||
|
||||
void LayersContainer::RemoveLayer(const gd::String& name) {
|
||||
std::vector<gd::Layer>::iterator layer =
|
||||
find_if(layers.begin(), layers.end(), [&name](const gd::Layer& layer) {
|
||||
return layer.GetName() == name;
|
||||
});
|
||||
if (layer == layers.end()) return;
|
||||
|
||||
layers.erase(layer);
|
||||
}
|
||||
|
||||
void LayersContainer::SwapLayers(std::size_t firstLayerIndex,
|
||||
std::size_t secondLayerIndex) {
|
||||
if (firstLayerIndex >= layers.size() || secondLayerIndex >= layers.size())
|
||||
return;
|
||||
|
||||
std::iter_swap(layers.begin() + firstLayerIndex,
|
||||
layers.begin() + secondLayerIndex);
|
||||
}
|
||||
|
||||
void LayersContainer::MoveLayer(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= layers.size() || newIndex >= layers.size()) return;
|
||||
|
||||
auto layer = layers[oldIndex];
|
||||
layers.erase(layers.begin() + oldIndex);
|
||||
InsertLayer(layer, newIndex);
|
||||
}
|
||||
|
||||
void LayersContainer::SerializeLayersTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("layer");
|
||||
for (std::size_t j = 0; j < GetLayersCount(); ++j)
|
||||
GetLayer(j).SerializeTo(element.AddChild("layer"));
|
||||
}
|
||||
|
||||
void LayersContainer::UnserializeLayersFrom(const SerializerElement& element) {
|
||||
layers.clear();
|
||||
element.ConsiderAsArrayOf("layer", "Layer");
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount(); ++i) {
|
||||
gd::Layer layer;
|
||||
layer.UnserializeFrom(element.GetChild(i));
|
||||
layers.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
109
Core/GDCore/Project/LayersContainer.h
Normal file
109
Core/GDCore/Project/LayersContainer.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 <vector>
|
||||
|
||||
#include "GDCore/Project/Layer.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Contains the layers for a scene or a custom object.
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API LayersContainer {
|
||||
public:
|
||||
LayersContainer();
|
||||
|
||||
/**
|
||||
* \brief Return true if the layer called "name" exists.
|
||||
*/
|
||||
bool HasLayerNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer called "name".
|
||||
*/
|
||||
Layer& GetLayer(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer called "name".
|
||||
*/
|
||||
const Layer& GetLayer(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer at position "index" in the layers
|
||||
* list.
|
||||
*/
|
||||
Layer& GetLayer(std::size_t index);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer at position "index" in the layers
|
||||
* list.
|
||||
*/
|
||||
const Layer& GetLayer(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* \brief Return the position of the layer called "name" in the layers list.
|
||||
*/
|
||||
std::size_t GetLayerPosition(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* The number of layers.
|
||||
*/
|
||||
std::size_t GetLayersCount() const;
|
||||
|
||||
/**
|
||||
* Add a new empty the layer sheet called "name" at the specified
|
||||
* position in the layers list.
|
||||
*/
|
||||
void InsertNewLayer(const gd::String& name, std::size_t position);
|
||||
|
||||
/**
|
||||
* Add a new layer constructed from the layer passed as parameter.
|
||||
*
|
||||
* \param theLayer The layer that must be copied and inserted.
|
||||
* \param position Insertion position.
|
||||
*/
|
||||
void InsertLayer(const Layer& theLayer, std::size_t position);
|
||||
|
||||
/**
|
||||
* Delete the layer named "name".
|
||||
*/
|
||||
void RemoveLayer(const gd::String& name);
|
||||
|
||||
/**
|
||||
* Swap the position of the specified layers.
|
||||
*/
|
||||
void SwapLayers(std::size_t firstLayerIndex, std::size_t secondLayerIndex);
|
||||
|
||||
/**
|
||||
* Change the position of the specified layer.
|
||||
*/
|
||||
void MoveLayer(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* \brief Serialize the layers.
|
||||
*/
|
||||
void SerializeLayersTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the layers.
|
||||
*/
|
||||
void UnserializeLayersFrom(const SerializerElement& element);
|
||||
|
||||
private:
|
||||
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not
|
||||
///< find an appropriate layer.
|
||||
std::vector<gd::Layer> layers; ///< Layers
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -33,7 +33,6 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::Layer Layout::badLayer;
|
||||
gd::BehaviorsSharedData Layout::badBehaviorSharedData("", "");
|
||||
|
||||
Layout::Layout(const Layout& other) { Init(other); }
|
||||
@@ -53,12 +52,8 @@ Layout::Layout()
|
||||
stopSoundsOnStartup(true),
|
||||
standardSortMethod(true),
|
||||
disableInputWhenNotFocused(true),
|
||||
profiler(NULL),
|
||||
variables(gd::VariablesContainer::SourceType::Scene)
|
||||
{
|
||||
gd::Layer layer;
|
||||
layer.SetCameraCount(1);
|
||||
initialLayers.push_back(layer);
|
||||
}
|
||||
|
||||
void Layout::SetName(const gd::String& name_) {
|
||||
@@ -100,91 +95,47 @@ Layout::GetAllBehaviorSharedData() const {
|
||||
}
|
||||
|
||||
gd::Layer& Layout::GetLayer(const gd::String& name) {
|
||||
std::vector<gd::Layer>::iterator layer =
|
||||
find_if(initialLayers.begin(),
|
||||
initialLayers.end(),
|
||||
bind2nd(gd::LayerHasName(), name));
|
||||
|
||||
if (layer != initialLayers.end()) return *layer;
|
||||
|
||||
return badLayer;
|
||||
return layers.GetLayer(name);
|
||||
}
|
||||
|
||||
const gd::Layer& Layout::GetLayer(const gd::String& name) const {
|
||||
std::vector<gd::Layer>::const_iterator layer =
|
||||
find_if(initialLayers.begin(),
|
||||
initialLayers.end(),
|
||||
bind2nd(gd::LayerHasName(), name));
|
||||
|
||||
if (layer != initialLayers.end()) return *layer;
|
||||
|
||||
return badLayer;
|
||||
return layers.GetLayer(name);
|
||||
}
|
||||
|
||||
gd::Layer& Layout::GetLayer(std::size_t index) { return initialLayers[index]; }
|
||||
gd::Layer& Layout::GetLayer(std::size_t index) { return layers.GetLayer(index); }
|
||||
|
||||
const gd::Layer& Layout::GetLayer(std::size_t index) const {
|
||||
return initialLayers[index];
|
||||
return layers.GetLayer(index);
|
||||
}
|
||||
|
||||
std::size_t Layout::GetLayersCount() const { return initialLayers.size(); }
|
||||
std::size_t Layout::GetLayersCount() const { return layers.GetLayersCount(); }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
bool Layout::HasLayerNamed(const gd::String& name) const {
|
||||
return (find_if(initialLayers.begin(),
|
||||
initialLayers.end(),
|
||||
bind2nd(gd::LayerHasName(), name)) != initialLayers.end());
|
||||
return layers.HasLayerNamed(name);
|
||||
}
|
||||
std::size_t Layout::GetLayerPosition(const gd::String& name) const {
|
||||
for (std::size_t i = 0; i < initialLayers.size(); ++i) {
|
||||
if (initialLayers[i].GetName() == name) return i;
|
||||
}
|
||||
return gd::String::npos;
|
||||
return layers.GetLayerPosition(name);
|
||||
}
|
||||
|
||||
void Layout::InsertNewLayer(const gd::String& name, std::size_t position) {
|
||||
gd::Layer newLayer;
|
||||
newLayer.SetName(name);
|
||||
if (position < initialLayers.size())
|
||||
initialLayers.insert(initialLayers.begin() + position, newLayer);
|
||||
else
|
||||
initialLayers.push_back(newLayer);
|
||||
layers.InsertNewLayer(name, position);
|
||||
}
|
||||
|
||||
void Layout::InsertLayer(const gd::Layer& layer, std::size_t position) {
|
||||
if (position < initialLayers.size())
|
||||
initialLayers.insert(initialLayers.begin() + position, layer);
|
||||
else
|
||||
initialLayers.push_back(layer);
|
||||
layers.InsertLayer(layer, position);
|
||||
}
|
||||
|
||||
void Layout::RemoveLayer(const gd::String& name) {
|
||||
std::vector<gd::Layer>::iterator layer =
|
||||
find_if(initialLayers.begin(),
|
||||
initialLayers.end(),
|
||||
bind2nd(gd::LayerHasName(), name));
|
||||
if (layer == initialLayers.end()) return;
|
||||
|
||||
initialLayers.erase(layer);
|
||||
layers.RemoveLayer(name);
|
||||
}
|
||||
|
||||
void Layout::SwapLayers(std::size_t firstLayerIndex,
|
||||
std::size_t secondLayerIndex) {
|
||||
if (firstLayerIndex >= initialLayers.size() ||
|
||||
secondLayerIndex >= initialLayers.size())
|
||||
return;
|
||||
|
||||
std::iter_swap(initialLayers.begin() + firstLayerIndex,
|
||||
initialLayers.begin() + secondLayerIndex);
|
||||
layers.SwapLayers(firstLayerIndex, secondLayerIndex);
|
||||
}
|
||||
|
||||
void Layout::MoveLayer(std::size_t oldIndex, std::size_t newIndex) {
|
||||
if (oldIndex >= initialLayers.size() || newIndex >= initialLayers.size())
|
||||
return;
|
||||
|
||||
auto layer = initialLayers[oldIndex];
|
||||
initialLayers.erase(initialLayers.begin() + oldIndex);
|
||||
InsertLayer(layer, newIndex);
|
||||
layers.MoveLayer(oldIndex, newIndex);
|
||||
}
|
||||
|
||||
void Layout::UpdateBehaviorsSharedData(gd::Project& project) {
|
||||
@@ -192,22 +143,23 @@ void Layout::UpdateBehaviorsSharedData(gd::Project& project) {
|
||||
std::vector<gd::String> allBehaviorsNames;
|
||||
|
||||
// Search in objects for the type and the name of every behaviors.
|
||||
for (std::size_t i = 0; i < initialObjects.size(); ++i) {
|
||||
for (std::size_t i = 0; i < objectsContainer.GetObjectsCount(); ++i) {
|
||||
std::vector<gd::String> objectBehaviors =
|
||||
initialObjects[i]->GetAllBehaviorNames();
|
||||
objectsContainer.GetObject(i).GetAllBehaviorNames();
|
||||
for (unsigned int j = 0; j < objectBehaviors.size(); ++j) {
|
||||
auto& behavior =
|
||||
initialObjects[i]->GetBehavior(objectBehaviors[j]);
|
||||
objectsContainer.GetObject(i).GetBehavior(objectBehaviors[j]);
|
||||
allBehaviorsTypes.push_back(behavior.GetTypeName());
|
||||
allBehaviorsNames.push_back(behavior.GetName());
|
||||
}
|
||||
}
|
||||
for (std::size_t i = 0; i < project.GetObjectsCount(); ++i) {
|
||||
auto &globalObjects = project.GetObjects();
|
||||
for (std::size_t i = 0; i < globalObjects.GetObjectsCount(); ++i) {
|
||||
std::vector<gd::String> objectBehaviors =
|
||||
project.GetObject(i).GetAllBehaviorNames();
|
||||
globalObjects.GetObject(i).GetAllBehaviorNames();
|
||||
for (std::size_t j = 0; j < objectBehaviors.size(); ++j) {
|
||||
auto& behavior =
|
||||
project.GetObject(i).GetBehavior(objectBehaviors[j]);
|
||||
globalObjects.GetObject(i).GetBehavior(objectBehaviors[j]);
|
||||
allBehaviorsTypes.push_back(behavior.GetTypeName());
|
||||
allBehaviorsNames.push_back(behavior.GetName());
|
||||
}
|
||||
@@ -291,15 +243,15 @@ void Layout::SerializeTo(SerializerElement& element) const {
|
||||
|
||||
editorSettings.SerializeTo(element.AddChild("uiSettings"));
|
||||
|
||||
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
objectsContainer.GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
GetVariables().SerializeTo(element.AddChild("variables"));
|
||||
GetInitialInstances().SerializeTo(element.AddChild("instances"));
|
||||
SerializeObjectsTo(element.AddChild("objects"));
|
||||
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
objectsContainer.SerializeObjectsTo(element.AddChild("objects"));
|
||||
objectsContainer.SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
|
||||
SerializeLayersTo(element.AddChild("layers"));
|
||||
layers.SerializeLayersTo(element.AddChild("layers"));
|
||||
|
||||
SerializerElement& behaviorDatasElement =
|
||||
element.AddChild("behaviorsSharedData");
|
||||
@@ -317,23 +269,6 @@ void Layout::SerializeTo(SerializerElement& element) const {
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::SerializeLayersTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("layer");
|
||||
for (std::size_t j = 0; j < GetLayersCount(); ++j)
|
||||
GetLayer(j).SerializeTo(element.AddChild("layer"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void Layout::UnserializeLayersFrom(const SerializerElement& element) {
|
||||
initialLayers.clear();
|
||||
element.ConsiderAsArrayOf("layer", "Layer");
|
||||
for (std::size_t i = 0; i < element.GetChildrenCount(); ++i) {
|
||||
gd::Layer layer;
|
||||
layer.UnserializeFrom(element.GetChild(i));
|
||||
initialLayers.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
SetBackgroundColor(element.GetIntAttribute("r"),
|
||||
@@ -349,22 +284,22 @@ void Layout::UnserializeFrom(gd::Project& project,
|
||||
editorSettings.UnserializeFrom(
|
||||
element.GetChild("uiSettings", 0, "UISettings"));
|
||||
|
||||
GetObjectGroups().UnserializeFrom(
|
||||
objectsContainer.GetObjectGroups().UnserializeFrom(
|
||||
element.GetChild("objectsGroups", 0, "GroupesObjets"));
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, GetEvents(), element.GetChild("events", 0, "Events"));
|
||||
|
||||
UnserializeObjectsFrom(project, element.GetChild("objects", 0, "Objets"));
|
||||
objectsContainer.UnserializeObjectsFrom(project, element.GetChild("objects", 0, "Objets"));
|
||||
if (element.HasChild("objectsFolderStructure")) {
|
||||
UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
|
||||
objectsContainer.UnserializeFoldersFrom(project, element.GetChild("objectsFolderStructure", 0));
|
||||
}
|
||||
AddMissingObjectsInRootFolder();
|
||||
objectsContainer.AddMissingObjectsInRootFolder();
|
||||
|
||||
initialInstances.UnserializeFrom(
|
||||
element.GetChild("instances", 0, "Positions"));
|
||||
variables.UnserializeFrom(element.GetChild("variables", 0, "Variables"));
|
||||
|
||||
UnserializeLayersFrom(element.GetChild("layers", 0, "Layers"));
|
||||
layers.UnserializeLayersFrom(element.GetChild("layers", 0, "Layers"));
|
||||
|
||||
// Compatibility with GD <= 4
|
||||
gd::String deprecatedTag1 = "automatismsSharedData";
|
||||
@@ -416,10 +351,10 @@ void Layout::Init(const Layout& other) {
|
||||
stopSoundsOnStartup = other.stopSoundsOnStartup;
|
||||
disableInputWhenNotFocused = other.disableInputWhenNotFocused;
|
||||
initialInstances = other.initialInstances;
|
||||
initialLayers = other.initialLayers;
|
||||
layers = other.layers;
|
||||
variables = other.GetVariables();
|
||||
|
||||
initialObjects = gd::Clone(other.initialObjects);
|
||||
objectsContainer = other.objectsContainer;
|
||||
|
||||
behaviorsSharedData.clear();
|
||||
for (const auto& it : other.behaviorsSharedData) {
|
||||
@@ -429,9 +364,6 @@ void Layout::Init(const Layout& other) {
|
||||
|
||||
events = other.events;
|
||||
editorSettings = other.editorSettings;
|
||||
objectGroups = other.objectGroups;
|
||||
|
||||
profiler = other.profiler;
|
||||
}
|
||||
|
||||
std::vector<gd::String> GetHiddenLayers(const Layout& layout) {
|
||||
|
@@ -9,15 +9,17 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Project/Layer.h"
|
||||
#include "GDCore/Project/LayersContainer.h"
|
||||
#include "GDCore/Project/ObjectGroupsContainer.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Project/VariablesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
@@ -25,7 +27,6 @@ class Object;
|
||||
class Project;
|
||||
class InitialInstancesContainer;
|
||||
} // namespace gd
|
||||
class TiXmlElement;
|
||||
class BaseProfiler;
|
||||
#undef GetObject // Disable an annoying macro
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API Layout : public ObjectsContainer {
|
||||
class GD_CORE_API Layout {
|
||||
public:
|
||||
Layout();
|
||||
Layout(const Layout&);
|
||||
@@ -104,6 +105,24 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Layout's objects
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief return the objects of the scene.
|
||||
*/
|
||||
gd::ObjectsContainer& GetObjects() {
|
||||
return objectsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the objects of the scene.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjects() const {
|
||||
return objectsContainer;
|
||||
}
|
||||
///@}
|
||||
|
||||
/** \name Layout's initial instances
|
||||
* Members functions related to initial instances of objects created at the
|
||||
* layout start up
|
||||
@@ -147,103 +166,96 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
///@{
|
||||
|
||||
/**
|
||||
* Provide access to the gd::VariablesContainer member containing the layout
|
||||
* variables \see gd::VariablesContainer
|
||||
* \brief Get the variables of the scene.
|
||||
*
|
||||
* \see gd::VariablesContainer
|
||||
*/
|
||||
inline const gd::VariablesContainer& GetVariables() const {
|
||||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide access to the gd::VariablesContainer member containing the layout
|
||||
* variables \see gd::VariablesContainer
|
||||
* \brief Get the variables of the scene.
|
||||
*
|
||||
* \see gd::VariablesContainer
|
||||
*/
|
||||
inline gd::VariablesContainer& GetVariables() { return variables; }
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Layout layers management
|
||||
* Members functions related to layout layers management.
|
||||
* TODO: This could be moved to a separate class
|
||||
/** \name Layers
|
||||
*/
|
||||
///@{
|
||||
|
||||
/**
|
||||
* \brief Return true if the layer called "name" exists.
|
||||
* \brief Get the layers of the scene.
|
||||
*/
|
||||
const gd::LayersContainer& GetLayers() const { return layers; }
|
||||
|
||||
/**
|
||||
* \brief Get the layers of the scene.
|
||||
*/
|
||||
gd::LayersContainer& GetLayers() { return layers; }
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
bool HasLayerNamed(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer called "name".
|
||||
* @deprecated
|
||||
*/
|
||||
Layer& GetLayer(const gd::String& name);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer called "name".
|
||||
* @deprecated
|
||||
*/
|
||||
const Layer& GetLayer(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer at position "index" in the layers
|
||||
* list
|
||||
* @deprecated
|
||||
*/
|
||||
Layer& GetLayer(std::size_t index);
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the layer at position "index" in the layers
|
||||
* list
|
||||
* @deprecated
|
||||
*/
|
||||
const Layer& GetLayer(std::size_t index) const;
|
||||
|
||||
/**
|
||||
* \brief Return the position of the layer called "name" in the layers list
|
||||
* @deprecated
|
||||
*/
|
||||
std::size_t GetLayerPosition(const gd::String& name) const;
|
||||
|
||||
/**
|
||||
* Must return the number of layers.
|
||||
* @deprecated
|
||||
*/
|
||||
std::size_t GetLayersCount() const;
|
||||
|
||||
/**
|
||||
* Must add a new empty the layer sheet called "name" at the specified
|
||||
* position in the layout list.
|
||||
* @deprecated
|
||||
*/
|
||||
void InsertNewLayer(const gd::String& name, std::size_t position);
|
||||
|
||||
/**
|
||||
* Must add a new the layer constructed from the layout passed as parameter.
|
||||
* \note No pointer or reference must be kept on the layer passed as
|
||||
* parameter. \param theLayer the layer that must be copied and inserted
|
||||
* into the project \param position Insertion position. Even if the position
|
||||
* is invalid, the layer must be inserted at the end of the layers list.
|
||||
* @deprecated
|
||||
*/
|
||||
void InsertLayer(const Layer& theLayer, std::size_t position);
|
||||
|
||||
/**
|
||||
* Must delete the layer named "name".
|
||||
* @deprecated
|
||||
*/
|
||||
void RemoveLayer(const gd::String& name);
|
||||
|
||||
/**
|
||||
* Swap the position of the specified layers.
|
||||
* @deprecated
|
||||
*/
|
||||
void SwapLayers(std::size_t firstLayerIndex, std::size_t secondLayerIndex);
|
||||
|
||||
/**
|
||||
* Change the position of the specified layer.
|
||||
* @deprecated
|
||||
*/
|
||||
void MoveLayer(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
/**
|
||||
* \brief Serialize the layers.
|
||||
*/
|
||||
void SerializeLayersTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the layers.
|
||||
*/
|
||||
void UnserializeLayersFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
/**
|
||||
@@ -275,7 +287,8 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
/**
|
||||
* \brief Get the shared data stored for a behavior
|
||||
*/
|
||||
gd::BehaviorsSharedData& GetBehaviorSharedData(const gd::String& behaviorName);
|
||||
gd::BehaviorsSharedData& GetBehaviorSharedData(
|
||||
const gd::String& behaviorName);
|
||||
|
||||
/**
|
||||
* \brief Get a map of all shared data stored for behaviors
|
||||
@@ -283,7 +296,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
const std::map<gd::String, std::unique_ptr<gd::BehaviorsSharedData>>&
|
||||
GetAllBehaviorSharedData() const;
|
||||
|
||||
|
||||
/**
|
||||
* Return the settings associated to the layout.
|
||||
* \see gd::EditorSettings
|
||||
@@ -296,9 +308,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* Return the settings associated to the layout.
|
||||
* \see gd::EditorSettings
|
||||
*/
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() {
|
||||
return editorSettings;
|
||||
}
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() { return editorSettings; }
|
||||
|
||||
/** \name Other properties
|
||||
*/
|
||||
@@ -339,12 +349,12 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* launched
|
||||
*/
|
||||
bool StopSoundsOnStartup() const { return stopSoundsOnStartup; }
|
||||
///@}
|
||||
///@}
|
||||
|
||||
/** \name Saving and loading
|
||||
* Members functions related to saving and loading the object.
|
||||
*/
|
||||
///@{
|
||||
/** \name Saving and loading
|
||||
* Members functions related to saving and loading the object.
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize the layout.
|
||||
*/
|
||||
@@ -354,18 +364,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
* \brief Unserialize the layout.
|
||||
*/
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
// TODO: GD C++ Platform specific code below
|
||||
/**
|
||||
* Get the profiler associated with the scene. Can be NULL.
|
||||
*/
|
||||
BaseProfiler* GetProfiler() const { return profiler; };
|
||||
|
||||
/**
|
||||
* Set the profiler associated with the scene. Can be NULL.
|
||||
*/
|
||||
void SetProfiler(BaseProfiler* profiler_) { profiler = profiler_; };
|
||||
///@}
|
||||
|
||||
private:
|
||||
gd::String name; ///< Scene name
|
||||
@@ -375,8 +374,9 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
unsigned int backgroundColorB; ///< Background color Blue component
|
||||
gd::String title; ///< Title displayed in the window
|
||||
gd::VariablesContainer variables; ///< Variables list
|
||||
gd::ObjectsContainer objectsContainer;
|
||||
gd::InitialInstancesContainer initialInstances; ///< Initial instances
|
||||
std::vector<gd::Layer> initialLayers; ///< Initial layers
|
||||
gd::LayersContainer layers;
|
||||
std::map<gd::String, std::unique_ptr<gd::BehaviorsSharedData>>
|
||||
behaviorsSharedData; ///< Initial shared datas of behaviors
|
||||
bool stopSoundsOnStartup; ///< True to make the scene stop all sounds at
|
||||
@@ -385,20 +385,14 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
bool disableInputWhenNotFocused; /// If set to true, the input must be
|
||||
/// disabled when the window do not have the
|
||||
/// focus.
|
||||
static gd::Layer badLayer; ///< Null object, returned when GetLayer can not
|
||||
///< find an appropriate layer.
|
||||
static gd::BehaviorsSharedData
|
||||
badBehaviorSharedData; ///< Null object, returned when
|
||||
///< GetBehaviorSharedData can not find the
|
||||
///< specified behavior shared data.
|
||||
///< GetBehaviorSharedData can not find the
|
||||
///< specified behavior shared data.
|
||||
|
||||
EventsList events; ///< Scene events
|
||||
gd::EditorSettings editorSettings;
|
||||
|
||||
// TODO: GD C++ Platform specific code below
|
||||
|
||||
BaseProfiler* profiler; ///< Pointer to the profiler. Can be NULL.
|
||||
|
||||
/**
|
||||
* Initialize from another layout. Used by copy-ctor and assign-op.
|
||||
* Don't forget to update me if members were changed!
|
||||
@@ -411,18 +405,6 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
const gd::String& behaviorsType);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Functor testing layout name.
|
||||
* \see gd::Layout
|
||||
*/
|
||||
struct LayoutHasName
|
||||
: public std::binary_function<std::unique_ptr<Layout>, gd::String, bool> {
|
||||
bool operator()(const std::unique_ptr<Layout>& layout,
|
||||
gd::String name) const {
|
||||
return layout->GetName() == name;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get the names of all layers from the given layout
|
||||
* that are invisible.
|
||||
@@ -445,20 +427,24 @@ gd::String GD_CORE_API GetTypeOfObject(const ObjectsContainer& game,
|
||||
bool searchInGroups = true);
|
||||
/**
|
||||
* \brief Check if an object or all objects of a group has a behavior.
|
||||
* \deprecated Use gd::ObjectsContainersList::HasBehaviorInObjectOrGroup instead.
|
||||
* \deprecated Use gd::ObjectsContainersList::HasBehaviorInObjectOrGroup
|
||||
* instead.
|
||||
*/
|
||||
bool GD_CORE_API HasBehaviorInObjectOrGroup(const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
const gd::String &objectOrGroupName,
|
||||
const gd::String &behaviorName,
|
||||
bool GD_CORE_API HasBehaviorInObjectOrGroup(const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
const gd::String& objectOrGroupName,
|
||||
const gd::String& behaviorName,
|
||||
bool searchInGroups = true);
|
||||
/**
|
||||
* \brief Get the names of behavior of a given type if an object or all objects of a group has it.
|
||||
* \brief Get the names of behavior of a given type if an object or all objects
|
||||
* of a group has it.
|
||||
*/
|
||||
std::vector<gd::String> GD_CORE_API GetBehaviorNamesInObjectOrGroup(
|
||||
const gd::ObjectsContainer &project, const gd::ObjectsContainer &layout,
|
||||
const gd::String &objectOrGroupName, const gd::String &behaviorType,
|
||||
bool searchInGroups);
|
||||
std::vector<gd::String> GD_CORE_API
|
||||
GetBehaviorNamesInObjectOrGroup(const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
const gd::String& objectOrGroupName,
|
||||
const gd::String& behaviorType,
|
||||
bool searchInGroups);
|
||||
|
||||
/**
|
||||
* \brief Check if a behavior is a default one or doesn't exist in an object or
|
||||
@@ -471,13 +457,15 @@ bool GD_CORE_API IsDefaultBehavior(const gd::ObjectsContainer& project,
|
||||
bool searchInGroups = true);
|
||||
|
||||
/**
|
||||
* \brief Get the type of a behavior if an object or all objects of a group has it.
|
||||
* \brief Get the type of a behavior if an object or all objects of a group has
|
||||
* it.
|
||||
*/
|
||||
gd::String GD_CORE_API GetTypeOfBehaviorInObjectOrGroup(const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
const gd::String &objectOrGroupName,
|
||||
const gd::String &behaviorName,
|
||||
bool searchInGroups = true);
|
||||
gd::String GD_CORE_API
|
||||
GetTypeOfBehaviorInObjectOrGroup(const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
const gd::String& objectOrGroupName,
|
||||
const gd::String& behaviorName,
|
||||
bool searchInGroups = true);
|
||||
/**
|
||||
* \brief Get a type from a behavior name
|
||||
* @return Type of the behavior.
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
gd::String ObjectConfiguration::badAnimationName;
|
||||
|
||||
ObjectConfiguration::~ObjectConfiguration() {}
|
||||
|
||||
@@ -25,9 +26,7 @@ std::map<gd::String, gd::PropertyDescriptor> ObjectConfiguration::GetProperties(
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor>
|
||||
ObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
ObjectConfiguration::GetInitialInstanceProperties(const gd::InitialInstance& instance) {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
}
|
||||
|
@@ -114,9 +114,7 @@ class GD_CORE_API ObjectConfiguration {
|
||||
* \see gd::InitialInstance
|
||||
*/
|
||||
virtual std::map<gd::String, gd::PropertyDescriptor>
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout);
|
||||
GetInitialInstanceProperties(const gd::InitialInstance& instance);
|
||||
|
||||
/**
|
||||
* \brief Called when the IDE wants to update a custom property of an initial
|
||||
@@ -127,9 +125,7 @@ class GD_CORE_API ObjectConfiguration {
|
||||
*/
|
||||
virtual bool UpdateInitialInstanceProperty(gd::InitialInstance& instance,
|
||||
const gd::String& name,
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& layout) {
|
||||
const gd::String& value) {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
@@ -169,7 +165,36 @@ class GD_CORE_API ObjectConfiguration {
|
||||
void UnserializeFrom(gd::Project& project, const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
/** \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:
|
||||
gd::String type; ///< Which type of object is represented by this
|
||||
///< configuration.
|
||||
|
||||
@@ -185,6 +210,9 @@ class GD_CORE_API ObjectConfiguration {
|
||||
* custom attributes.
|
||||
*/
|
||||
virtual void DoSerializeTo(SerializerElement& element) const {};
|
||||
|
||||
private:
|
||||
static gd::String badAnimationName;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -19,13 +19,20 @@ namespace gd {
|
||||
ObjectFolderOrObject ObjectFolderOrObject::badObjectFolderOrObject;
|
||||
|
||||
ObjectFolderOrObject::ObjectFolderOrObject()
|
||||
: folderName("__NULL"), object(nullptr) {}
|
||||
: folderName("__NULL"),
|
||||
object(nullptr),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
ObjectFolderOrObject::ObjectFolderOrObject(gd::String folderName_,
|
||||
ObjectFolderOrObject* parent_)
|
||||
: folderName(folderName_), parent(parent_), object(nullptr) {}
|
||||
: folderName(folderName_),
|
||||
parent(parent_),
|
||||
object(nullptr),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
ObjectFolderOrObject::ObjectFolderOrObject(gd::Object* object_,
|
||||
ObjectFolderOrObject* parent_)
|
||||
: object(object_), parent(parent_) {}
|
||||
: object(object_),
|
||||
parent(parent_),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
ObjectFolderOrObject::~ObjectFolderOrObject() {}
|
||||
|
||||
bool ObjectFolderOrObject::HasObjectNamed(const gd::String& name) {
|
||||
@@ -66,7 +73,8 @@ 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];
|
||||
}
|
||||
@@ -206,6 +214,14 @@ 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(
|
||||
@@ -243,6 +259,15 @@ 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,6 +10,7 @@
|
||||
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
@@ -166,6 +167,11 @@ 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.
|
||||
*/
|
||||
@@ -188,6 +194,7 @@ 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.
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "GDCore/Tools/PolymorphicClone.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/ObjectFolderOrObject.h"
|
||||
@@ -21,6 +22,25 @@ ObjectsContainer::ObjectsContainer() {
|
||||
|
||||
ObjectsContainer::~ObjectsContainer() {}
|
||||
|
||||
ObjectsContainer::ObjectsContainer(const ObjectsContainer& other) {
|
||||
Init(other);
|
||||
}
|
||||
|
||||
ObjectsContainer& ObjectsContainer::operator=(
|
||||
const ObjectsContainer& other) {
|
||||
if (this != &other) Init(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ObjectsContainer::Init(const gd::ObjectsContainer& other) {
|
||||
initialObjects = gd::Clone(other.initialObjects);
|
||||
objectGroups = other.objectGroups;
|
||||
// The objects folders are not copied.
|
||||
// It's not an issue because the UI uses the serialization for duplication.
|
||||
rootFolder = gd::make_unique<gd::ObjectFolderOrObject>("__ROOT");
|
||||
}
|
||||
|
||||
void ObjectsContainer::SerializeObjectsTo(SerializerElement& element) const {
|
||||
element.ConsiderAsArrayOf("object");
|
||||
for (std::size_t j = 0; j < initialObjects.size(); j++) {
|
||||
|
@@ -40,6 +40,9 @@ class GD_CORE_API ObjectsContainer {
|
||||
*/
|
||||
ObjectsContainer();
|
||||
virtual ~ObjectsContainer();
|
||||
|
||||
ObjectsContainer(const ObjectsContainer&);
|
||||
ObjectsContainer& operator=(const ObjectsContainer& rhs);
|
||||
|
||||
/** \name Objects management
|
||||
* Members functions related to objects management.
|
||||
@@ -230,6 +233,12 @@ class GD_CORE_API ObjectsContainer {
|
||||
|
||||
private:
|
||||
std::unique_ptr<gd::ObjectFolderOrObject> rootFolder;
|
||||
|
||||
/**
|
||||
* Initialize from another variables container, copying elements. Used by
|
||||
* copy-ctor and assign-op. Don't forget to update me if members were changed!
|
||||
*/
|
||||
void Init(const ObjectsContainer& other);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -22,8 +22,8 @@ ObjectsContainersList
|
||||
ObjectsContainersList::MakeNewObjectsContainersListForProjectAndLayout(
|
||||
const gd::Project& project, const gd::Layout& layout) {
|
||||
ObjectsContainersList objectsContainersList;
|
||||
objectsContainersList.Add(project);
|
||||
objectsContainersList.Add(layout);
|
||||
objectsContainersList.Add(project.GetObjects());
|
||||
objectsContainersList.Add(layout.GetObjects());
|
||||
return objectsContainersList;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ ObjectsContainersList
|
||||
ObjectsContainersList::MakeNewObjectsContainersListForProject(
|
||||
const gd::Project& project) {
|
||||
ObjectsContainersList objectsContainersList;
|
||||
objectsContainersList.Add(project);
|
||||
objectsContainersList.Add(project.GetObjects());
|
||||
return objectsContainersList;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,15 @@ 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 {
|
||||
@@ -368,7 +377,7 @@ std::vector<gd::String> ObjectsContainersList::ExpandObjectName(
|
||||
}
|
||||
|
||||
// Ensure that all returned objects actually exists (i.e: if some groups have
|
||||
// names refering to non existing objects, don't return them).
|
||||
// names referring 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);
|
||||
@@ -521,4 +530,72 @@ 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,7 +129,17 @@ class GD_CORE_API ObjectsContainersList {
|
||||
const gd::String& objectName, bool searchInGroups = true) const;
|
||||
|
||||
/**
|
||||
* \brief Return a list containing all objects refered to by the group.
|
||||
* \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.
|
||||
* If an object name is passed, then only this object name is returned.
|
||||
*
|
||||
* If \a onlyObjectToSelectIfPresent is set and present in the group(s),
|
||||
@@ -163,6 +173,16 @@ 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(){};
|
||||
@@ -170,6 +190,8 @@ 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;
|
||||
|
||||
|
148
Core/GDCore/Project/ParameterMetadataContainer.h
Normal file
148
Core/GDCore/Project/ParameterMetadataContainer.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* 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
|
@@ -34,7 +34,6 @@
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/Tools/PolymorphicClone.h"
|
||||
@@ -265,15 +264,21 @@ bool Project::RemovePlatform(const gd::String& platformName) {
|
||||
bool Project::HasLayoutNamed(const gd::String& name) const {
|
||||
return (find_if(scenes.begin(),
|
||||
scenes.end(),
|
||||
bind2nd(gd::LayoutHasName(), name)) != scenes.end());
|
||||
[&name](const std::unique_ptr<gd::Layout>& layout) {
|
||||
return layout->GetName() == name;
|
||||
}) != scenes.end());
|
||||
}
|
||||
gd::Layout& Project::GetLayout(const gd::String& name) {
|
||||
return *(*find_if(
|
||||
scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name)));
|
||||
scenes.begin(), scenes.end(), [&name](const std::unique_ptr<gd::Layout>& layout) {
|
||||
return layout->GetName() == name;
|
||||
}));
|
||||
}
|
||||
const gd::Layout& Project::GetLayout(const gd::String& name) const {
|
||||
return *(*find_if(
|
||||
scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name)));
|
||||
scenes.begin(), scenes.end(), [&name](const std::unique_ptr<gd::Layout>& layout) {
|
||||
return layout->GetName() == name;
|
||||
}));
|
||||
}
|
||||
gd::Layout& Project::GetLayout(std::size_t index) { return *scenes[index]; }
|
||||
const gd::Layout& Project::GetLayout(std::size_t index) const {
|
||||
@@ -318,7 +323,9 @@ gd::Layout& Project::InsertLayout(const gd::Layout& layout,
|
||||
|
||||
void Project::RemoveLayout(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::Layout> >::iterator scene =
|
||||
find_if(scenes.begin(), scenes.end(), bind2nd(gd::LayoutHasName(), name));
|
||||
find_if(scenes.begin(), scenes.end(), [&name](const std::unique_ptr<gd::Layout>& layout) {
|
||||
return layout->GetName() == name;
|
||||
});
|
||||
if (scene == scenes.end()) return;
|
||||
|
||||
scenes.erase(scene);
|
||||
@@ -327,19 +334,24 @@ void Project::RemoveLayout(const gd::String& name) {
|
||||
bool Project::HasExternalEventsNamed(const gd::String& name) const {
|
||||
return (find_if(externalEvents.begin(),
|
||||
externalEvents.end(),
|
||||
bind2nd(gd::ExternalEventsHasName(), name)) !=
|
||||
externalEvents.end());
|
||||
[&name](const std::unique_ptr<gd::ExternalEvents>& externalEvents) {
|
||||
return externalEvents->GetName() == name;
|
||||
}) != externalEvents.end());
|
||||
}
|
||||
gd::ExternalEvents& Project::GetExternalEvents(const gd::String& name) {
|
||||
return *(*find_if(externalEvents.begin(),
|
||||
externalEvents.end(),
|
||||
bind2nd(gd::ExternalEventsHasName(), name)));
|
||||
[&name](const std::unique_ptr<gd::ExternalEvents>& externalEvents) {
|
||||
return externalEvents->GetName() == name;
|
||||
}));
|
||||
}
|
||||
const gd::ExternalEvents& Project::GetExternalEvents(
|
||||
const gd::String& name) const {
|
||||
return *(*find_if(externalEvents.begin(),
|
||||
externalEvents.end(),
|
||||
bind2nd(gd::ExternalEventsHasName(), name)));
|
||||
[&name](const std::unique_ptr<gd::ExternalEvents>& externalEvents) {
|
||||
return externalEvents->GetName() == name;
|
||||
}));
|
||||
}
|
||||
gd::ExternalEvents& Project::GetExternalEvents(std::size_t index) {
|
||||
return *externalEvents[index];
|
||||
@@ -383,7 +395,9 @@ void Project::RemoveExternalEvents(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::ExternalEvents> >::iterator events =
|
||||
find_if(externalEvents.begin(),
|
||||
externalEvents.end(),
|
||||
bind2nd(gd::ExternalEventsHasName(), name));
|
||||
[&name](const std::unique_ptr<gd::ExternalEvents>& externalEvents) {
|
||||
return externalEvents->GetName() == name;
|
||||
});
|
||||
if (events == externalEvents.end()) return;
|
||||
|
||||
externalEvents.erase(events);
|
||||
@@ -449,19 +463,24 @@ void Project::SwapExternalLayouts(std::size_t first, std::size_t second) {
|
||||
bool Project::HasExternalLayoutNamed(const gd::String& name) const {
|
||||
return (find_if(externalLayouts.begin(),
|
||||
externalLayouts.end(),
|
||||
bind2nd(gd::ExternalLayoutHasName(), name)) !=
|
||||
externalLayouts.end());
|
||||
[&name](const std::unique_ptr<gd::ExternalLayout>& externalLayout) {
|
||||
return externalLayout->GetName() == name;
|
||||
}) != externalLayouts.end());
|
||||
}
|
||||
gd::ExternalLayout& Project::GetExternalLayout(const gd::String& name) {
|
||||
return *(*find_if(externalLayouts.begin(),
|
||||
externalLayouts.end(),
|
||||
bind2nd(gd::ExternalLayoutHasName(), name)));
|
||||
[&name](const std::unique_ptr<gd::ExternalLayout>& externalLayout) {
|
||||
return externalLayout->GetName() == name;
|
||||
}));
|
||||
}
|
||||
const gd::ExternalLayout& Project::GetExternalLayout(
|
||||
const gd::String& name) const {
|
||||
return *(*find_if(externalLayouts.begin(),
|
||||
externalLayouts.end(),
|
||||
bind2nd(gd::ExternalLayoutHasName(), name)));
|
||||
[&name](const std::unique_ptr<gd::ExternalLayout>& externalLayout) {
|
||||
return externalLayout->GetName() == name;
|
||||
}));
|
||||
}
|
||||
gd::ExternalLayout& Project::GetExternalLayout(std::size_t index) {
|
||||
return *externalLayouts[index];
|
||||
@@ -505,7 +524,9 @@ void Project::RemoveExternalLayout(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >::iterator externalLayout =
|
||||
find_if(externalLayouts.begin(),
|
||||
externalLayouts.end(),
|
||||
bind2nd(gd::ExternalLayoutHasName(), name));
|
||||
[&name](const std::unique_ptr<gd::ExternalLayout>& externalLayout) {
|
||||
return externalLayout->GetName() == name;
|
||||
});
|
||||
if (externalLayout == externalLayouts.end()) return;
|
||||
|
||||
externalLayouts.erase(externalLayout);
|
||||
@@ -835,15 +856,15 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
*this, eventsFunctionsExtensionElement);
|
||||
}
|
||||
|
||||
GetObjectGroups().UnserializeFrom(
|
||||
objectsContainer.GetObjectGroups().UnserializeFrom(
|
||||
element.GetChild("objectsGroups", 0, "ObjectGroups"));
|
||||
resourcesManager.UnserializeFrom(
|
||||
element.GetChild("resources", 0, "Resources"));
|
||||
UnserializeObjectsFrom(*this, element.GetChild("objects", 0, "Objects"));
|
||||
objectsContainer.UnserializeObjectsFrom(*this, element.GetChild("objects", 0, "Objects"));
|
||||
if (element.HasChild("objectsFolderStructure")) {
|
||||
UnserializeFoldersFrom(*this, element.GetChild("objectsFolderStructure", 0));
|
||||
objectsContainer.UnserializeFoldersFrom(*this, element.GetChild("objectsFolderStructure", 0));
|
||||
}
|
||||
AddMissingObjectsInRootFolder();
|
||||
objectsContainer.AddMissingObjectsInRootFolder();
|
||||
|
||||
GetVariables().UnserializeFrom(element.GetChild("variables", 0, "Variables"));
|
||||
|
||||
@@ -995,9 +1016,9 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
std::cout << "ERROR: The project current platform is NULL.";
|
||||
|
||||
resourcesManager.SerializeTo(element.AddChild("resources"));
|
||||
SerializeObjectsTo(element.AddChild("objects"));
|
||||
SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
objectsContainer.SerializeObjectsTo(element.AddChild("objects"));
|
||||
objectsContainer.SerializeFoldersTo(element.AddChild("objectsFolderStructure"));
|
||||
objectsContainer.GetObjectGroups().SerializeTo(element.AddChild("objectsGroups"));
|
||||
GetVariables().SerializeTo(element.AddChild("variables"));
|
||||
|
||||
element.SetAttribute("firstLayout", firstLayout);
|
||||
@@ -1077,7 +1098,9 @@ bool Project::HasSourceFile(gd::String name, gd::String language) const {
|
||||
vector<std::unique_ptr<SourceFile> >::const_iterator sourceFile =
|
||||
find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
bind2nd(gd::ExternalSourceFileHasName(), name));
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
});
|
||||
|
||||
if (sourceFile == externalSourceFiles.end()) return false;
|
||||
|
||||
@@ -1087,20 +1110,26 @@ bool Project::HasSourceFile(gd::String name, gd::String language) const {
|
||||
gd::SourceFile& Project::GetSourceFile(const gd::String& name) {
|
||||
return *(*find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
bind2nd(gd::ExternalSourceFileHasName(), name)));
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
const gd::SourceFile& Project::GetSourceFile(const gd::String& name) const {
|
||||
return *(*find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
bind2nd(gd::ExternalSourceFileHasName(), name)));
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
}));
|
||||
}
|
||||
|
||||
void Project::RemoveSourceFile(const gd::String& name) {
|
||||
std::vector<std::unique_ptr<gd::SourceFile> >::iterator sourceFile =
|
||||
find_if(externalSourceFiles.begin(),
|
||||
externalSourceFiles.end(),
|
||||
bind2nd(gd::ExternalSourceFileHasName(), name));
|
||||
[&name](const std::unique_ptr<SourceFile>& sourceFile) {
|
||||
return sourceFile->GetFileName() == name;
|
||||
});
|
||||
if (sourceFile == externalSourceFiles.end()) return;
|
||||
|
||||
externalSourceFiles.erase(sourceFile);
|
||||
@@ -1164,7 +1193,6 @@ void Project::Init(const gd::Project& game) {
|
||||
platformSpecificAssets = game.platformSpecificAssets;
|
||||
loadingScreen = game.loadingScreen;
|
||||
watermark = game.watermark;
|
||||
objectGroups = game.objectGroups;
|
||||
|
||||
extensionProperties = game.extensionProperties;
|
||||
|
||||
@@ -1177,7 +1205,7 @@ void Project::Init(const gd::Project& game) {
|
||||
|
||||
resourcesManager = game.resourcesManager;
|
||||
|
||||
initialObjects = gd::Clone(game.initialObjects);
|
||||
objectsContainer = game.objectsContainer;
|
||||
|
||||
scenes = gd::Clone(game.scenes);
|
||||
|
||||
|
@@ -48,7 +48,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API Project : public ObjectsContainer {
|
||||
class GD_CORE_API Project {
|
||||
public:
|
||||
Project();
|
||||
Project(const Project&);
|
||||
@@ -984,6 +984,24 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
|
||||
///@}
|
||||
|
||||
/** \name Global objects
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief return the objects of the project.
|
||||
*/
|
||||
gd::ObjectsContainer& GetObjects() {
|
||||
return objectsContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the objects of the project.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjects() const {
|
||||
return objectsContainer;
|
||||
}
|
||||
///@}
|
||||
|
||||
/** \name Identifier names
|
||||
*/
|
||||
///@{
|
||||
@@ -1090,6 +1108,7 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
///< startup.
|
||||
std::vector<std::unique_ptr<gd::Layout> > scenes; ///< List of all scenes
|
||||
gd::VariablesContainer variables; ///< Initial global variables
|
||||
gd::ObjectsContainer objectsContainer;
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >
|
||||
externalLayouts; ///< List of all externals layouts
|
||||
std::vector<std::unique_ptr<gd::EventsFunctionsExtension> >
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -101,6 +102,37 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForObjectEventsFunction(
|
||||
return projectScopedContainers;
|
||||
}
|
||||
|
||||
ProjectScopedContainers
|
||||
ProjectScopedContainers::MakeNewProjectScopedContainersForEventsBasedObject(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
gd::ObjectsContainer &outputObjectsContainer) {
|
||||
|
||||
outputObjectsContainer.GetObjects().clear();
|
||||
outputObjectsContainer.GetObjectGroups().Clear();
|
||||
outputObjectsContainer.InsertNewObject(
|
||||
project,
|
||||
gd::PlatformExtension::GetObjectFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsBasedObject.GetName()),
|
||||
"Object", outputObjectsContainer.GetObjectsCount());
|
||||
gd::EventsFunctionTools::CopyEventsBasedObjectChildrenToObjectsContainer(
|
||||
eventsBasedObject, outputObjectsContainer);
|
||||
|
||||
ProjectScopedContainers projectScopedContainers(
|
||||
ObjectsContainersList::MakeNewObjectsContainersListForContainer(
|
||||
outputObjectsContainer),
|
||||
VariablesContainersList::
|
||||
MakeNewVariablesContainersListForEventsFunctionsExtension(
|
||||
eventsFunctionsExtension),
|
||||
PropertiesContainersList::MakeNewEmptyPropertiesContainersList());
|
||||
|
||||
projectScopedContainers.AddPropertiesContainer(
|
||||
eventsBasedObject.GetPropertyDescriptors());
|
||||
|
||||
return projectScopedContainers;
|
||||
}
|
||||
|
||||
ProjectScopedContainers
|
||||
ProjectScopedContainers::MakeNewProjectScopedContainersWithLocalVariables(
|
||||
const ProjectScopedContainers &projectScopedContainers,
|
||||
|
@@ -13,6 +13,7 @@ class ObjectsContainersList;
|
||||
class VariablesContainersList;
|
||||
class PropertiesContainersList;
|
||||
class NamedPropertyDescriptor;
|
||||
class ParameterMetadataContainer;
|
||||
class BaseEvent;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunction;
|
||||
@@ -111,6 +112,13 @@ class ProjectScopedContainers {
|
||||
const gd::EventsFunction &eventsFunction,
|
||||
gd::ObjectsContainer ¶meterObjectsContainer);
|
||||
|
||||
static ProjectScopedContainers
|
||||
MakeNewProjectScopedContainersForEventsBasedObject(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
gd::ObjectsContainer &outputObjectsContainer);
|
||||
|
||||
static ProjectScopedContainers
|
||||
MakeNewProjectScopedContainersWithLocalVariables(
|
||||
const ProjectScopedContainers &projectScopedContainers,
|
||||
@@ -124,7 +132,7 @@ class ProjectScopedContainers {
|
||||
}
|
||||
|
||||
ProjectScopedContainers &AddParameters(
|
||||
const std::vector<gd::ParameterMetadata> ¶meters) {
|
||||
const ParameterMetadataContainer ¶meters) {
|
||||
parametersVectorsList.push_back(¶meters);
|
||||
|
||||
return *this;
|
||||
@@ -217,7 +225,7 @@ class ProjectScopedContainers {
|
||||
return propertiesContainersList;
|
||||
};
|
||||
|
||||
const std::vector<const std::vector<gd::ParameterMetadata> *> &GetParametersVectorsList() const {
|
||||
const std::vector<const ParameterMetadataContainer *> &GetParametersVectorsList() const {
|
||||
return parametersVectorsList;
|
||||
};
|
||||
|
||||
@@ -229,7 +237,7 @@ class ProjectScopedContainers {
|
||||
gd::ObjectsContainersList objectsContainersList;
|
||||
gd::VariablesContainersList variablesContainersList;
|
||||
gd::PropertiesContainersList propertiesContainersList;
|
||||
std::vector<const std::vector<gd::ParameterMetadata> *> parametersVectorsList;
|
||||
std::vector<const ParameterMetadataContainer *> parametersVectorsList;
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -38,6 +38,13 @@ 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) {
|
||||
@@ -67,11 +74,21 @@ 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;
|
||||
? 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;
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyDescriptor::SerializeValuesTo(SerializerElement& element) const {
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Project/MeasurementUnit.h"
|
||||
#include "GDCore/Project/QuickCustomization.h"
|
||||
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
@@ -32,14 +33,18 @@ class GD_CORE_API PropertyDescriptor {
|
||||
PropertyDescriptor(gd::String propertyValue)
|
||||
: currentValue(propertyValue), type("string"), label(""), hidden(false),
|
||||
deprecated(false), advanced(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()) {}
|
||||
hasImpactOnOtherProperties(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default) {}
|
||||
|
||||
/**
|
||||
* \brief Empty constructor creating an empty property to be displayed.
|
||||
*/
|
||||
PropertyDescriptor()
|
||||
: hidden(false), deprecated(false), advanced(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()){};
|
||||
hasImpactOnOtherProperties(false),
|
||||
measurementUnit(gd::MeasurementUnit::GetUndefined()),
|
||||
quickCustomizationVisibility(QuickCustomization::Visibility::Default){};
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
@@ -109,7 +114,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
extraInformation.push_back(info);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Change the unit of measurement of the property value.
|
||||
*/
|
||||
@@ -128,7 +133,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
const std::vector<gd::String>& GetExtraInfo() const {
|
||||
return extraInformation;
|
||||
}
|
||||
|
||||
|
||||
std::vector<gd::String>& GetExtraInfo() {
|
||||
return extraInformation;
|
||||
}
|
||||
@@ -172,6 +177,28 @@ class GD_CORE_API PropertyDescriptor {
|
||||
*/
|
||||
bool IsAdvanced() const { return advanced; }
|
||||
|
||||
/**
|
||||
* \brief Check if the property has impact on other properties - which means a change
|
||||
* must re-render other properties.
|
||||
*/
|
||||
bool HasImpactOnOtherProperties() const { return hasImpactOnOtherProperties; }
|
||||
|
||||
/**
|
||||
* \brief Set if the property has impact on other properties - which means a change
|
||||
* must re-render other properties.
|
||||
*/
|
||||
PropertyDescriptor& SetHasImpactOnOtherProperties(bool enable) {
|
||||
hasImpactOnOtherProperties = enable;
|
||||
return *this;
|
||||
}
|
||||
|
||||
QuickCustomization::Visibility GetQuickCustomizationVisibility() const { return quickCustomizationVisibility; }
|
||||
|
||||
PropertyDescriptor& SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
|
||||
quickCustomizationVisibility = visibility;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
@@ -211,7 +238,9 @@ class GD_CORE_API PropertyDescriptor {
|
||||
bool hidden;
|
||||
bool deprecated;
|
||||
bool advanced;
|
||||
bool hasImpactOnOtherProperties;
|
||||
gd::MeasurementUnit measurementUnit; //< The unit of measurement of the property vale.
|
||||
QuickCustomization::Visibility quickCustomizationVisibility;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
16
Core/GDCore/Project/QuickCustomization.h
Normal file
16
Core/GDCore/Project/QuickCustomization.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#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
|
@@ -87,20 +87,6 @@ class GD_CORE_API SourceFile {
|
||||
///< SetAssociatedEvent.
|
||||
};
|
||||
|
||||
//"Tool" Functions
|
||||
|
||||
/**
|
||||
* Functor testing Source Files name
|
||||
*/
|
||||
struct ExternalSourceFileHasName
|
||||
: public std::
|
||||
binary_function<std::unique_ptr<SourceFile>, gd::String, bool> {
|
||||
bool operator()(const std::unique_ptr<SourceFile>& externalEvents,
|
||||
gd::String name) const {
|
||||
return externalEvents->GetFileName() == name;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // SOURCEFILE_H
|
||||
|
@@ -30,6 +30,8 @@ gd::String Variable::TypeAsString(Type t) {
|
||||
return "structure";
|
||||
case Type::Array:
|
||||
return "array";
|
||||
case Type::MixedTypes:
|
||||
return "mixed";
|
||||
default:
|
||||
return "error-type";
|
||||
}
|
||||
@@ -46,6 +48,8 @@ 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;
|
||||
@@ -56,6 +60,7 @@ 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)
|
||||
@@ -85,6 +90,9 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +150,7 @@ 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];
|
||||
}
|
||||
@@ -202,6 +211,7 @@ 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) {
|
||||
@@ -224,6 +234,7 @@ 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);
|
||||
@@ -238,6 +249,7 @@ 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;
|
||||
};
|
||||
@@ -270,6 +282,9 @@ void Variable::SerializeTo(SerializerElement& element) const {
|
||||
child->SerializeTo(childrenElement.AddChild("variable"));
|
||||
}
|
||||
}
|
||||
if (hasMixedValues) {
|
||||
element.SetBoolAttribute("hasMixedValues", true);
|
||||
}
|
||||
}
|
||||
|
||||
void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
@@ -313,6 +328,9 @@ void Variable::UnserializeFrom(const SerializerElement& element) {
|
||||
PushNew().UnserializeFrom(childElement);
|
||||
}
|
||||
}
|
||||
if (element.GetBoolAttribute("hasMixedValues", false)) {
|
||||
MarkAsMixedValues();
|
||||
}
|
||||
}
|
||||
|
||||
Variable& Variable::ResetPersistentUuid() {
|
||||
@@ -384,7 +402,8 @@ Variable::Variable(const Variable& other)
|
||||
folded(other.folded),
|
||||
boolVal(other.boolVal),
|
||||
type(other.type),
|
||||
persistentUuid(other.persistentUuid) {
|
||||
persistentUuid(other.persistentUuid),
|
||||
hasMixedValues(other.hasMixedValues) {
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
@@ -396,6 +415,7 @@ Variable& Variable::operator=(const Variable& other) {
|
||||
boolVal = other.boolVal;
|
||||
type = other.type;
|
||||
persistentUuid = other.persistentUuid;
|
||||
hasMixedValues = other.hasMixedValues;
|
||||
CopyChildren(other);
|
||||
}
|
||||
|
||||
@@ -411,4 +431,61 @@ 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.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_VARIABLE_H
|
||||
#define GDCORE_VARIABLE_H
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -31,6 +31,8 @@ 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,
|
||||
@@ -50,7 +52,7 @@ class GD_CORE_API Variable {
|
||||
/**
|
||||
* \brief Default constructor creating a variable with 0 as value.
|
||||
*/
|
||||
Variable() : value(0), type(Type::Number){};
|
||||
Variable() : value(0), type(Type::Number), hasMixedValues(false) {};
|
||||
Variable(const Variable&);
|
||||
virtual ~Variable(){};
|
||||
|
||||
@@ -87,6 +89,7 @@ class GD_CORE_API Variable {
|
||||
void SetString(const gd::String& newStr) {
|
||||
str = newStr;
|
||||
type = Type::String;
|
||||
hasMixedValues = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,6 +105,7 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,8 +119,23 @@ 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); };
|
||||
@@ -168,6 +187,9 @@ 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
|
||||
@@ -376,6 +398,7 @@ 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>>
|
||||
@@ -392,5 +415,3 @@ class GD_CORE_API Variable {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_VARIABLE_H
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#include "GDCore/Project/Variable.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/TinyXml/tinyxml.h"
|
||||
#include "GDCore/Tools/UUID/UUID.h"
|
||||
|
||||
namespace gd {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user