mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
34 Commits
v5.0.0-bet
...
refactor/g
Author | SHA1 | Date | |
---|---|---|---|
![]() |
24091db88b | ||
![]() |
4ec3f1f082 | ||
![]() |
991378e004 | ||
![]() |
dfaee92d24 | ||
![]() |
b07c71cb9c | ||
![]() |
cb0c0f903f | ||
![]() |
a81a121a8d | ||
![]() |
7bf892c7eb | ||
![]() |
ce4fdbe4f8 | ||
![]() |
d82bbdc1af | ||
![]() |
62dca91637 | ||
![]() |
1e1c5f7206 | ||
![]() |
7c9e6ee6f1 | ||
![]() |
5690de71c5 | ||
![]() |
eae2a06a4e | ||
![]() |
4affa25672 | ||
![]() |
7b30f63cb1 | ||
![]() |
574bdaaf41 | ||
![]() |
bff43ee771 | ||
![]() |
9b9b6c5996 | ||
![]() |
721872e45b | ||
![]() |
edd9ec94cf | ||
![]() |
c986c52409 | ||
![]() |
168b8d3fea | ||
![]() |
47025329dd | ||
![]() |
9f05a65ed2 | ||
![]() |
370c6d03ad | ||
![]() |
b650ff3aa5 | ||
![]() |
285ff6f5f5 | ||
![]() |
81f292941f | ||
![]() |
eb27ba7c86 | ||
![]() |
01a844c356 | ||
![]() |
054e48227c | ||
![]() |
9adc40a55d |
@@ -19,7 +19,7 @@ jobs:
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install sdk-fastcomp-1.37.37-64bit && ./emsdk activate sdk-fastcomp-1.37.37-64bit && cd ..
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
|
||||
- run:
|
||||
name: Install Wine for Electron builder
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -44,9 +44,6 @@
|
||||
/Binaries/**/JsPlatform/*.dll.a
|
||||
/Binaries/Output/Release_Windows/newIDE
|
||||
*.autosave
|
||||
/Binaries/Output/libGD.js/Release
|
||||
/Binaries/Output/libGD.js/Debug
|
||||
/Binaries/Output/libGD.js/libGD.raw.js
|
||||
!/GDCpp/scripts/bcp.exe
|
||||
!/scripts/libgettextlib-0-17.dll
|
||||
!/scripts/libgettextsrc-0-17.dll
|
||||
|
@@ -24,7 +24,7 @@ addons:
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/commit/$(git rev-parse HEAD)
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/latest
|
||||
paths:
|
||||
- Binaries/Output/libGD.js/Release
|
||||
- Binaries/embuild/GDevelop.js
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
@@ -63,8 +63,8 @@ install:
|
||||
# Install Emscripten (for GDevelop.js)
|
||||
- git clone https://github.com/juj/emsdk.git
|
||||
- cd emsdk
|
||||
- ./emsdk install sdk-fastcomp-1.37.37-64bit
|
||||
- ./emsdk activate sdk-fastcomp-1.37.37-64bit
|
||||
- ./emsdk install 1.39.6
|
||||
- ./emsdk activate 1.39.6
|
||||
- source ./emsdk_env.sh
|
||||
- cd ..
|
||||
# Install GDevelop.js dependencies and compile it
|
||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -83,7 +83,8 @@
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp"
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
|
@@ -51,7 +51,12 @@ file(GLOB_RECURSE formatted_source_files tests/* GDCore/Events/* GDCore/Extensio
|
||||
list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
gd_add_clang_utils(GDCore "${formatted_source_files}")
|
||||
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
IF(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(GDCore STATIC ${source_files})
|
||||
ELSE()
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
ENDIF()
|
||||
add_dependencies(GDCore GDVersion)
|
||||
IF(EMSCRIPTEN)
|
||||
set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
|
||||
|
@@ -12,6 +12,15 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
vector<gd::String> CommentEvent::GetAllSearchableStrings() const {
|
||||
vector<gd::String> allSearchableStrings;
|
||||
|
||||
allSearchableStrings.push_back(com1);
|
||||
allSearchableStrings.push_back(com2); ///< Com2 is deprecated
|
||||
|
||||
return allSearchableStrings;
|
||||
}
|
||||
|
||||
void CommentEvent::SerializeTo(SerializerElement &element) const {
|
||||
element.AddChild("color")
|
||||
.SetAttribute("r", r)
|
||||
|
@@ -7,10 +7,11 @@
|
||||
#define COMMENTEVENT_H
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
class Project;
|
||||
}
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -45,6 +46,8 @@ class GD_CORE_API CommentEvent : public gd::BaseEvent {
|
||||
const gd::String& GetComment() const { return com1; }
|
||||
void SetComment(const gd::String& comment) { com1 = comment; }
|
||||
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const;
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
@@ -5,10 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "ForEachEvent.h"
|
||||
#include <iostream>
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
@@ -19,6 +19,14 @@ namespace gd {
|
||||
GroupEvent::GroupEvent()
|
||||
: BaseEvent(), creationTime(0), colorR(74), colorG(176), colorB(228) {}
|
||||
|
||||
vector<gd::String> GroupEvent::GetAllSearchableStrings() const {
|
||||
vector<gd::String> allSearchableStrings;
|
||||
|
||||
allSearchableStrings.push_back(name);
|
||||
|
||||
return allSearchableStrings;
|
||||
}
|
||||
|
||||
void GroupEvent::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("source", source);
|
||||
|
@@ -106,6 +106,8 @@ class GD_CORE_API GroupEvent : public gd::BaseEvent {
|
||||
virtual const gd::EventsList& GetSubEvents() const { return events; };
|
||||
virtual gd::EventsList& GetSubEvents() { return events; };
|
||||
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const;
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
@@ -5,9 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "RepeatEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
|
@@ -6,9 +6,6 @@
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "WhileEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
|
@@ -4,8 +4,6 @@
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
|
@@ -35,10 +35,6 @@ namespace gd {
|
||||
* \brief Internal class used to generate code from events
|
||||
*/
|
||||
class GD_CORE_API EventsCodeGenerator {
|
||||
// Compatiblity with old ExpressionParser
|
||||
friend class CallbacksForGeneratingExpressionCode;
|
||||
friend class VariableCodeGenerationCallbacks;
|
||||
// end of compatibility code
|
||||
friend class ExpressionCodeGenerator;
|
||||
|
||||
public:
|
||||
|
@@ -24,117 +24,14 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
// Compatibility with old ExpressionParser
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/CodeGeneration/VariableParserCallbacks.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
// end of compatibility code
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool ExpressionCodeGenerator::useOldExpressionParser = false;
|
||||
|
||||
gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
EventsCodeGenerator& codeGenerator,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& type,
|
||||
const gd::String& expression,
|
||||
const gd::String& objectName) {
|
||||
// Compatibility with old ExpressionParser
|
||||
if (useOldExpressionParser) {
|
||||
if (type == "number") {
|
||||
gd::String code = "";
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
code, codeGenerator, context);
|
||||
gd::ExpressionParser parser(expression);
|
||||
if (!parser.ParseMathExpression(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
code.empty()) {
|
||||
std::cout << "Error (old ExpressionParser): \""
|
||||
<< parser.GetFirstError() << "\" in: \"" << expression
|
||||
<< "\" (number)" << std::endl;
|
||||
code = "0";
|
||||
}
|
||||
|
||||
return code;
|
||||
} else if (type == "string") {
|
||||
gd::String code = "";
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
code, codeGenerator, context);
|
||||
gd::ExpressionParser parser(expression);
|
||||
if (!parser.ParseStringExpression(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
code.empty()) {
|
||||
std::cout << "Error (old ExpressionParser): \""
|
||||
<< parser.GetFirstError() << "\" in: \"" << expression
|
||||
<< "\" (string)" << std::endl;
|
||||
code = "\"\"";
|
||||
}
|
||||
|
||||
return code;
|
||||
} else if (type == "scenevar") {
|
||||
gd::String code = "";
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code,
|
||||
codeGenerator,
|
||||
context,
|
||||
gd::EventsCodeGenerator::LAYOUT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
} else if (type == "globalvar") {
|
||||
gd::String code = "";
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code,
|
||||
codeGenerator,
|
||||
context,
|
||||
gd::EventsCodeGenerator::PROJECT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
} else if (type == "objectvar") {
|
||||
gd::String code = "";
|
||||
|
||||
// Object is either the object of the previous parameter or, if it is
|
||||
// empty, the object being picked by the instruction.
|
||||
gd::String object =
|
||||
objectName.empty() ? context.GetCurrentObject() : objectName;
|
||||
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code, codeGenerator, context, object);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
std::cout << "Type error (old ExpressionParser): type \"" << type
|
||||
<< "\" is not supported" << std::endl;
|
||||
return "/* Error during code generation: type " + type +
|
||||
" is not supported for old ExpressionParser. */ 0";
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups());
|
||||
|
@@ -60,11 +60,6 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
const gd::String& expression,
|
||||
const gd::String& objectName = "");
|
||||
|
||||
static void UseOldExpressionParser(bool enable) {
|
||||
useOldExpressionParser = enable;
|
||||
};
|
||||
static bool IsUsingOldExpressionParser() { return useOldExpressionParser; };
|
||||
|
||||
const gd::String& GetOutput() { return output; };
|
||||
|
||||
protected:
|
||||
@@ -107,11 +102,9 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
gd::String output;
|
||||
EventsCodeGenerator& codeGenerator;
|
||||
EventsCodeGenerationContext& context;
|
||||
|
||||
static bool useOldExpressionParser;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_ExpressionCodeGenerator_H
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
CallbacksForGeneratingExpressionCode::CallbacksForGeneratingExpressionCode(
|
||||
gd::String& plainExpression_,
|
||||
EventsCodeGenerator& codeGenerator_,
|
||||
EventsCodeGenerationContext& context_)
|
||||
: plainExpression(plainExpression_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_) {}
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnConstantToken(gd::String text) {
|
||||
plainExpression += text;
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnStaticFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case: For strings expressions, function without name is a string.
|
||||
if (GetReturnType() == "string" && functionName.empty()) {
|
||||
if (parameters.empty()) return;
|
||||
plainExpression +=
|
||||
codeGenerator.ConvertToStringExplicit(parameters[0].GetPlainString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 0; i < parametersCode.size(); ++i) {
|
||||
if (i != 0) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
plainExpression += expressionInfo.codeExtraInformation.functionCallName +
|
||||
"(" + parametersStr + ")";
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnObjectFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups = codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups = codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
if (parameters.empty()) return;
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 1; i < parametersCode.size(); ++i) {
|
||||
if (i != 1) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
gd::String output = GetReturnType() == "string" ? "\"\"" : "0";
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(parameters[0].GetPlainString(), context);
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
gd::String objectType = gd::GetTypeOfObject(globalObjectsAndGroups, objectsAndGroups, realObjects[i]);
|
||||
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
|
||||
codeGenerator.GetPlatform(), objectType);
|
||||
|
||||
// Build gd::String to access the object
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
output = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
objInfo,
|
||||
expressionInfo.codeExtraInformation,
|
||||
parametersStr,
|
||||
output,
|
||||
context);
|
||||
}
|
||||
|
||||
plainExpression += output;
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnObjectBehaviorFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups = codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups = codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
if (parameters.size() < 2) return;
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 2; i < parametersCode.size(); ++i) {
|
||||
if (i != 2) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(parameters[0].GetPlainString(), context);
|
||||
|
||||
gd::String output = GetReturnType() == "string" ? "\"\"" : "0";
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
// Cast the object if needed
|
||||
gd::String behaviorType =
|
||||
gd::GetTypeOfBehavior(globalObjectsAndGroups, objectsAndGroups, parameters[1].GetPlainString());
|
||||
const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata(
|
||||
codeGenerator.GetPlatform(), behaviorType);
|
||||
|
||||
// Build gd::String to access the behavior
|
||||
codeGenerator.AddIncludeFiles(autoInfo.includeFiles);
|
||||
output = codeGenerator.GenerateObjectBehaviorFunctionCall(
|
||||
realObjects[i],
|
||||
parameters[1].GetPlainString(),
|
||||
autoInfo,
|
||||
expressionInfo.codeExtraInformation,
|
||||
parametersStr,
|
||||
output,
|
||||
context);
|
||||
}
|
||||
|
||||
plainExpression += output;
|
||||
};
|
||||
|
||||
bool CallbacksForGeneratingExpressionCode::OnSubMathExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups,
|
||||
const gd::ObjectsContainer& objectsAndGroups,
|
||||
gd::Expression& expression) {
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForGeneratingExpressionCode callbacks(
|
||||
newExpression, codeGenerator, context);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseMathExpression(platform, globalObjectsAndGroups, objectsAndGroups, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallbacksForGeneratingExpressionCode::OnSubTextExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups,
|
||||
const gd::ObjectsContainer& objectsAndGroups,
|
||||
gd::Expression& expression) {
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForGeneratingExpressionCode callbacks(
|
||||
newExpression, codeGenerator, context);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseStringExpression(platform, globalObjectsAndGroups, objectsAndGroups, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EXPRESSIONSCODEGENERATION_H
|
||||
#define EXPRESSIONSCODEGENERATION_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class ExpressionMetadata;
|
||||
class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
class Layout;
|
||||
class EventsCodeGenerationContext;
|
||||
class EventsCodeGenerator;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
// TODO: Replace and remove (ExpressionCodeGenerator)
|
||||
|
||||
/**
|
||||
* \brief Used to generate code from expressions.
|
||||
*
|
||||
* Usage example :
|
||||
* \code
|
||||
* gd::String expressionOutputCppCode;
|
||||
*
|
||||
* CallbacksForGeneratingExpressionCode callbacks(expressionOutputCppCode,
|
||||
* codeGenerator, context); gd::ExpressionParser
|
||||
* parser(theOriginalGameDevelopExpression);
|
||||
* parser.ParseStringExpression(platform, project, scene, callbacks);
|
||||
*
|
||||
* if (expressionOutputCppCode.empty()) expressionOutputCppCode = "\"\""; //If
|
||||
* generation failed, we make sure output code is not empty. \endcode \see
|
||||
* EventsCodeGenerator
|
||||
*/
|
||||
class GD_CORE_API CallbacksForGeneratingExpressionCode
|
||||
: public gd::ParserCallbacks {
|
||||
public:
|
||||
CallbacksForGeneratingExpressionCode(gd::String& output,
|
||||
EventsCodeGenerator& codeGenerator_,
|
||||
EventsCodeGenerationContext& context_);
|
||||
virtual ~CallbacksForGeneratingExpressionCode(){};
|
||||
|
||||
void OnConstantToken(gd::String text);
|
||||
void OnStaticFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
void OnObjectFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
void OnObjectBehaviorFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
bool OnSubMathExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
bool OnSubTextExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
|
||||
private:
|
||||
gd::String& plainExpression;
|
||||
EventsCodeGenerator& codeGenerator;
|
||||
EventsCodeGenerationContext& context;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // EXPRESSIONSCODEGENERATION_H
|
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* GDevelop C++ Platform
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "VariableParserCallbacks.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionCodeGenerator.h"
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariableCodeGenerationCallbacks::VariableCodeGenerationCallbacks(
|
||||
gd::String& output_,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::EventsCodeGenerator::VariableScope& scope_)
|
||||
: output(output_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_),
|
||||
scope(scope_) {
|
||||
if (scope == gd::EventsCodeGenerator::OBJECT_VARIABLE) {
|
||||
std::cout << "ERROR: Initializing VariableCodeGenerationCallbacks with "
|
||||
"OBJECT_VARIABLE without object.";
|
||||
}
|
||||
}
|
||||
|
||||
VariableCodeGenerationCallbacks::VariableCodeGenerationCallbacks(
|
||||
gd::String& output_,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::String& object_)
|
||||
: output(output_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_),
|
||||
scope(gd::EventsCodeGenerator::OBJECT_VARIABLE),
|
||||
object(object_) {}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnRootVariable(gd::String variableName) {
|
||||
output += codeGenerator.GenerateGetVariable(variableName, scope, context, object);
|
||||
}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnChildVariable(gd::String variableName) {
|
||||
output += codeGenerator.GenerateVariableAccessor(variableName);
|
||||
}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnChildSubscript(
|
||||
gd::String stringExpression) {
|
||||
gd::String argumentCode = gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
codeGenerator, context, "string", stringExpression);
|
||||
|
||||
output += codeGenerator.GenerateVariableBracketAccessor(argumentCode);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* GDevelop C++ Platform
|
||||
* 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 VARIABLEPARSERCALLBACKS_H
|
||||
#define VARIABLEPARSERCALLBACKS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "EventsCodeGenerator.h"
|
||||
namespace gd {
|
||||
class EventsCodeGenerationContext;
|
||||
} // namespace gd
|
||||
|
||||
// TODO: Replace and remove (ExpressionCodeGenerator)
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Callbacks called to generate the code for getting a variable.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
VariableCodeGenerationCallbacks callbacks(output, eventsCodeGenerator,
|
||||
context, VariableCodeGenerationCallbacks::LAYOUT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(parameter);
|
||||
if ( !parser.Parse(callbacks) )
|
||||
{
|
||||
//Error during parsing the variable name:
|
||||
output = "runtimeContext->GetSceneVariables().GetBadVariable()";
|
||||
}
|
||||
|
||||
//"output" now contains the C++ code to return the variable.
|
||||
\endcode
|
||||
*/
|
||||
class VariableCodeGenerationCallbacks : public gd::VariableParserCallbacks {
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor for generating code for a layout/global
|
||||
* variable. \param output The string in which the code will be generated.
|
||||
* \param codeGenerator The code generator being used.
|
||||
* \param context The current code generation context.
|
||||
* \param scope The scope of the variable being accessed: LAYOUT_VARIABLE,
|
||||
* PROJECT_VARIABLE.
|
||||
*/
|
||||
VariableCodeGenerationCallbacks(gd::String& output,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::EventsCodeGenerator::VariableScope& scope_);
|
||||
/**
|
||||
|
||||
* \brief Default constructor for generating code for an object variable.
|
||||
* \param output The string in which the code will be generated.
|
||||
* \param codeGenerator The code generator being used.
|
||||
* \param context The current code generation context.
|
||||
* \param object The name of the object
|
||||
*/
|
||||
VariableCodeGenerationCallbacks(gd::String& output,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::String& object);
|
||||
|
||||
/**
|
||||
* \brief Called when the first variable has been parsed.
|
||||
* \param variableName The variable name.
|
||||
*/
|
||||
virtual void OnRootVariable(gd::String variableName);
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable.
|
||||
* \param variableName The child variable name.
|
||||
*/
|
||||
virtual void OnChildVariable(gd::String variableName);
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable using a
|
||||
* string expression in square brackets. \param variableName The expression
|
||||
* used to access the child variable.
|
||||
*/
|
||||
virtual void OnChildSubscript(gd::String stringExpression);
|
||||
|
||||
private:
|
||||
gd::String& output;
|
||||
gd::EventsCodeGenerator& codeGenerator;
|
||||
gd::EventsCodeGenerationContext& context;
|
||||
gd::EventsCodeGenerator::VariableScope scope;
|
||||
const gd::String object; ///< The object name, when scope == OBJECT_VARIABLE.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VARIABLEPARSERCALLBACKS_H
|
||||
#endif
|
@@ -90,8 +90,8 @@ class GD_CORE_API BaseEvent {
|
||||
bool HasSubEvents() const;
|
||||
|
||||
/**
|
||||
* Event must be able to return all conditions std::vector they have.
|
||||
* Used to preprocess the conditions.
|
||||
* \brief Return a list of all conditions of the event.
|
||||
* \note Used to preprocess or search in the conditions.
|
||||
*/
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors() {
|
||||
std::vector<gd::InstructionsList*> noConditions;
|
||||
@@ -104,8 +104,8 @@ class GD_CORE_API BaseEvent {
|
||||
};
|
||||
|
||||
/**
|
||||
* Event must be able to return all actions std::vector they have.
|
||||
* Used to preprocess the actions.
|
||||
* \brief Return a list of all actions of the event.
|
||||
* \note Used to preprocess or search in the actions.
|
||||
*/
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors() {
|
||||
std::vector<gd::InstructionsList*> noActions;
|
||||
@@ -118,8 +118,17 @@ class GD_CORE_API BaseEvent {
|
||||
};
|
||||
|
||||
/**
|
||||
* Event must be able to return all expressions they have.
|
||||
* Used to preprocess the expressions.
|
||||
* \brief Return a list of all strings of the event.
|
||||
* \note Used to preprocess or search in the event strings.
|
||||
*/
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const {
|
||||
std::vector<gd::String> noSearchableStrings;
|
||||
return noSearchableStrings;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return a list of all expressions of the event.
|
||||
* \note Used to preprocess or search in the expressions.
|
||||
*/
|
||||
virtual std::vector<gd::Expression*> GetAllExpressions() {
|
||||
std::vector<gd::Expression*> noExpr;
|
||||
|
@@ -99,6 +99,23 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
|
||||
for (std::size_t i = 0; i < GetEventsCount(); ++i) {
|
||||
if (events[i].get() == &eventToMove) {
|
||||
std::shared_ptr<BaseEvent> event = events[i];
|
||||
events.erase(events.begin() + i);
|
||||
|
||||
newEventsList.InsertEvent(event, newPosition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsList::EventsList(const EventsList& other) { Init(other); }
|
||||
|
||||
EventsList& EventsList::operator=(const EventsList& other) {
|
||||
|
@@ -52,7 +52,8 @@ class GD_CORE_API EventsList {
|
||||
* \brief Insert the specified event to the list.
|
||||
* \note The event passed by parameter is not copied.
|
||||
* \param event The smart pointer to the event that must be inserted into the
|
||||
* list \param position Insertion position. If the position is invalid, the
|
||||
* list
|
||||
* \param position Insertion position. If the position is invalid, the
|
||||
* object is inserted at the end of the objects list.
|
||||
*/
|
||||
void InsertEvent(std::shared_ptr<gd::BaseEvent> event,
|
||||
@@ -142,6 +143,25 @@ class GD_CORE_API EventsList {
|
||||
*/
|
||||
bool Contains(const gd::BaseEvent& eventToSearch,
|
||||
bool recursive = true) const;
|
||||
|
||||
/**
|
||||
* Move the specified event, that must be in the events list, to another
|
||||
* events list *without* invalidating the event (i.e: without
|
||||
* destroying/cloning it) in memory.
|
||||
*
|
||||
* \warning newEventsList is supposed not to be contained inside the event
|
||||
* (you should not try
|
||||
* to move an event inside one of its children/grand children events).
|
||||
*
|
||||
* \param eventToMove The event to be moved
|
||||
* \param newEventsList The new events list
|
||||
* \param newPosition The position in the new events list
|
||||
* \return true if the move was made, false otherwise (for example, if
|
||||
* eventToMove is not found in the list)
|
||||
*/
|
||||
bool MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition);
|
||||
///@}
|
||||
|
||||
/** \name std::vector API compatibility
|
||||
|
@@ -1,897 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::String ExpressionParser::parserSeparators = " ,+-*/%.<>=&|;()#^![]{}";
|
||||
|
||||
size_t ExpressionParser::GetMinimalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfos) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = 0; i < parametersInfos.size(); ++i) {
|
||||
if (!parametersInfos[i].optional && !parametersInfos[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
size_t ExpressionParser::GetMaximalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfos) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = 0; i < parametersInfos.size(); ++i) {
|
||||
if (!parametersInfos[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add blank parameters when code-only parameters are expected.
|
||||
* \param Parameters information
|
||||
* \param vector of parameters without code only parameters.
|
||||
*/
|
||||
std::vector<gd::Expression> CompleteParameters(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfo,
|
||||
const std::vector<gd::Expression>& parameters) {
|
||||
std::vector<gd::Expression> completeParameters = parameters;
|
||||
for (std::size_t i = 0; i < parametersInfo.size();
|
||||
++i) // Code only parameters are not included in expressions parameters.
|
||||
{
|
||||
if (parametersInfo[i].codeOnly) {
|
||||
if (i > completeParameters.size()) {
|
||||
cout << "Bad parameter count in expression.";
|
||||
}
|
||||
|
||||
if (i >= completeParameters.size())
|
||||
completeParameters.push_back(gd::Expression(""));
|
||||
else
|
||||
completeParameters.insert(completeParameters.begin() + i,
|
||||
gd::Expression(""));
|
||||
} else {
|
||||
if (i >= completeParameters.size()) {
|
||||
completeParameters.push_back(gd::Expression(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
return completeParameters;
|
||||
}
|
||||
|
||||
bool ExpressionParser::ValidSyntax(const gd::String& str) {
|
||||
static const gd::String numerics = "0123456789.e";
|
||||
static const gd::String operators = "+/*-%";
|
||||
|
||||
size_t parenthesisLevel = 0;
|
||||
gd::String lastOperator;
|
||||
|
||||
bool parsingNumber = false;
|
||||
bool parsingScientificNotationNumber = false;
|
||||
bool parsingDecimalNumber = false;
|
||||
bool requestNumber = false;
|
||||
gd::String lastNumber;
|
||||
bool numberWasParsedLast = false;
|
||||
|
||||
for (auto it = str.begin(); it != str.end(); ++it) {
|
||||
char32_t currentChar = *it;
|
||||
if (currentChar == U' ' || currentChar == U'\n') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
requestNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
} else if (numerics.find(currentChar) != gd::String::npos) {
|
||||
requestNumber = false;
|
||||
|
||||
if (currentChar == U'.') {
|
||||
if (!parsingNumber) {
|
||||
firstErrorStr = _("Syntax error");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingDecimalNumber) {
|
||||
firstErrorStr = _("Syntax error in a number.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingDecimalNumber = true;
|
||||
}
|
||||
|
||||
if (currentChar == U'e') {
|
||||
if (parsingScientificNotationNumber) {
|
||||
firstErrorStr = _("Syntax error in a number.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingScientificNotationNumber = true;
|
||||
requestNumber = true;
|
||||
}
|
||||
|
||||
if (numberWasParsedLast) {
|
||||
firstErrorStr = _("Operator missing before a number");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingNumber = true;
|
||||
lastNumber += currentChar;
|
||||
} else if (currentChar == U')') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (!numberWasParsedLast) {
|
||||
firstErrorStr = _("Superfluous operator before a paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parenthesisLevel > 0)
|
||||
parenthesisLevel--;
|
||||
else {
|
||||
firstErrorStr = _("Bad closing paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto previousIt = it;
|
||||
--previousIt;
|
||||
if (*previousIt == U'(') {
|
||||
firstErrorStr = _("Empty paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
} else if (currentChar == U'(') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (numberWasParsedLast) {
|
||||
firstErrorStr = _("Operator missing before a paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parenthesisLevel++;
|
||||
numberWasParsedLast = false;
|
||||
} else if (operators.find(currentChar) != gd::String::npos) {
|
||||
if (currentChar == U'-' && parsingNumber &&
|
||||
parsingScientificNotationNumber) {
|
||||
lastNumber += currentChar;
|
||||
requestNumber = true;
|
||||
} else {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (currentChar != U'-' && currentChar != U'+' &&
|
||||
!numberWasParsedLast) {
|
||||
firstErrorStr = _("Operators without any number between them");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
numberWasParsedLast = false;
|
||||
}
|
||||
} else {
|
||||
firstErrorStr = _("Syntax error");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
} else if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parenthesisLevel != 0) {
|
||||
firstErrorStr = _("Paranthesis mismatch");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!numberWasParsedLast) {
|
||||
firstErrorStr = _("Alone operator at the end of the expression");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpressionParser::ParseMathExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::ParserCallbacks& callbacks) {
|
||||
callbacks.SetReturnType("expression");
|
||||
gd::String expression = expressionPlainString;
|
||||
|
||||
size_t parsePosition = 0;
|
||||
|
||||
size_t firstPointPos = expression.find(".");
|
||||
size_t firstParPos = expression.find("(");
|
||||
|
||||
gd::String expressionWithoutFunctions;
|
||||
gd::String nonFunctionToken;
|
||||
size_t nonFunctionTokenStartPos = gd::String::npos;
|
||||
|
||||
while (firstPointPos != string::npos || firstParPos != string::npos) {
|
||||
// Identify name
|
||||
size_t nameEnd = firstPointPos < firstParPos ? firstPointPos : firstParPos;
|
||||
size_t nameStart = expression.find_last_of(parserSeparators, nameEnd - 1);
|
||||
nameStart++;
|
||||
|
||||
gd::String nameBefore = expression.substr(nameStart, nameEnd - nameStart);
|
||||
gd::String objectName = nameBefore.FindAndReplace("~", " ");
|
||||
|
||||
// Identify function name
|
||||
gd::String functionName = nameBefore;
|
||||
size_t functionNameEnd = nameEnd;
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
bool nameIsFunction = firstPointPos > firstParPos;
|
||||
if (!nameIsFunction) {
|
||||
parameters.push_back(gd::Expression(objectName));
|
||||
functionNameEnd = expression.find_first_of(" (", nameEnd);
|
||||
if (nameEnd + 1 < expression.length())
|
||||
functionName =
|
||||
expression.substr(nameEnd + 1, functionNameEnd - (nameEnd + 1));
|
||||
if (functionNameEnd == string::npos) {
|
||||
functionName = "";
|
||||
functionNameEnd = expression.length() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we're going to identify the expression
|
||||
gd::ExpressionMetadata instructionInfos;
|
||||
|
||||
if (functionName.substr(0, functionName.length() - 1)
|
||||
.find_first_of(parserSeparators) == string::npos) {
|
||||
bool functionFound = false;
|
||||
bool staticFunctionFound = false;
|
||||
bool objectFunctionFound = false;
|
||||
bool behaviorFunctionFound = false;
|
||||
|
||||
// First try to bind to a static expression
|
||||
if (nameIsFunction &&
|
||||
MetadataProvider::HasExpression(platform, functionName)) {
|
||||
functionFound = true;
|
||||
staticFunctionFound = true;
|
||||
instructionInfos =
|
||||
MetadataProvider::GetExpressionMetadata(platform, functionName);
|
||||
}
|
||||
// Then search in object expression
|
||||
else if (!nameIsFunction &&
|
||||
MetadataProvider::HasObjectExpression(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName)) {
|
||||
functionFound = true;
|
||||
objectFunctionFound = true;
|
||||
instructionInfos = MetadataProvider::GetObjectExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName);
|
||||
}
|
||||
// And in behaviors expressions
|
||||
else if (!nameIsFunction) {
|
||||
size_t firstDoublePoints = functionName.find("::");
|
||||
if (firstDoublePoints != string::npos) {
|
||||
gd::String autoName = functionName.substr(0, firstDoublePoints);
|
||||
if (firstDoublePoints + 2 < functionName.length())
|
||||
functionName = functionName.substr(firstDoublePoints + 2,
|
||||
functionName.length());
|
||||
else
|
||||
functionName = "";
|
||||
|
||||
if (MetadataProvider::HasBehaviorExpression(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName)) {
|
||||
parameters.push_back(gd::Expression(autoName));
|
||||
functionFound = true;
|
||||
behaviorFunctionFound = true;
|
||||
|
||||
instructionInfos = MetadataProvider::GetBehaviorExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName);
|
||||
|
||||
// Verify that object has behavior.
|
||||
vector<gd::String> behaviors =
|
||||
gd::GetBehaviorsOfObject(project, layout, objectName);
|
||||
if (find(behaviors.begin(), behaviors.end(), autoName) ==
|
||||
behaviors.end()) {
|
||||
cout << "Bad behavior requested" << endl;
|
||||
functionFound = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (functionFound) // Add the function
|
||||
{
|
||||
// Identify parameters
|
||||
size_t parametersEnd = expression.find_first_of("(", functionNameEnd);
|
||||
gd::String currentParameterStr;
|
||||
char32_t previousChar = '(';
|
||||
bool takeSymbolsInAccount = true;
|
||||
if (parametersEnd != string::npos) {
|
||||
size_t level = 0;
|
||||
parametersEnd++;
|
||||
|
||||
while (parametersEnd < expression.length() &&
|
||||
!(expression[parametersEnd] == ')' && level == 0)) {
|
||||
// Be sure we are not in quotes
|
||||
if (expression[parametersEnd] == U'\"' && previousChar != U'\\')
|
||||
takeSymbolsInAccount = !takeSymbolsInAccount;
|
||||
|
||||
// So as to be sure paranthesis don't belong to a parameter
|
||||
if (expression[parametersEnd] == U'(' && takeSymbolsInAccount)
|
||||
level++;
|
||||
if (expression[parametersEnd] == U')' && takeSymbolsInAccount)
|
||||
level--;
|
||||
|
||||
// Add the character to the current parameter or terminate the
|
||||
// latter
|
||||
if ((expression[parametersEnd] == U',' && level == 0) &&
|
||||
takeSymbolsInAccount) {
|
||||
parameters.push_back(currentParameterStr);
|
||||
currentParameterStr.clear();
|
||||
} else
|
||||
currentParameterStr += expression[parametersEnd];
|
||||
|
||||
previousChar = expression[parametersEnd];
|
||||
parametersEnd++;
|
||||
}
|
||||
if (currentParameterStr.find_first_not_of(" ") !=
|
||||
string::npos) // Add last parameter if needed
|
||||
{
|
||||
parameters.push_back(currentParameterStr);
|
||||
}
|
||||
|
||||
// Testing function call is properly closed
|
||||
if (parametersEnd == expression.length() ||
|
||||
expression[parametersEnd] != U')') {
|
||||
firstErrorStr = _("Paranthesis not closed");
|
||||
firstErrorPos = parametersEnd - 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(instructionInfos.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(instructionInfos.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
firstErrorStr += " ";
|
||||
firstErrorStr += _("Expected (maximum) :");
|
||||
firstErrorStr += gd::String::From(
|
||||
GetMaximalParametersNumber(instructionInfos.parameters));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters =
|
||||
CompleteParameters(instructionInfos.parameters, parameters);
|
||||
for (std::size_t i = 0; i < instructionInfos.parameters.size(); ++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
instructionInfos.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Parameters' parenthesis missing");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnConstantToken(
|
||||
nonFunctionToken +
|
||||
expression.substr(parsePosition, nameStart - parsePosition));
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, nameStart - parsePosition);
|
||||
nonFunctionToken.clear();
|
||||
nonFunctionTokenStartPos = gd::String::npos;
|
||||
|
||||
if (objectFunctionFound)
|
||||
callbacks.OnObjectFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
else if (behaviorFunctionFound)
|
||||
callbacks.OnObjectBehaviorFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
else if (staticFunctionFound)
|
||||
callbacks.OnStaticFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
|
||||
if (objectFunctionFound || behaviorFunctionFound || staticFunctionFound)
|
||||
expressionWithoutFunctions += "0";
|
||||
|
||||
parsePosition = parametersEnd + 1;
|
||||
firstPointPos = expression.find(".", parametersEnd + 1);
|
||||
firstParPos = expression.find("(", parametersEnd + 1);
|
||||
} else // Math function or math constant : Pass it.
|
||||
{
|
||||
nonFunctionToken += expression.substr(
|
||||
parsePosition, functionNameEnd + 1 - parsePosition);
|
||||
expressionWithoutFunctions += expression.substr(
|
||||
parsePosition, functionNameEnd + 1 - parsePosition);
|
||||
nonFunctionTokenStartPos = (nonFunctionTokenStartPos != gd::String::npos
|
||||
? nonFunctionTokenStartPos
|
||||
: parsePosition);
|
||||
parsePosition = functionNameEnd + 1;
|
||||
firstPointPos = expression.find(".", functionNameEnd + 1);
|
||||
firstParPos = expression.find("(", functionNameEnd + 1);
|
||||
}
|
||||
} else // Not a function call : Pass it
|
||||
{
|
||||
nonFunctionToken +=
|
||||
expression.substr(parsePosition, nameEnd + 1 - parsePosition);
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, nameEnd + 1 - parsePosition);
|
||||
nonFunctionTokenStartPos = (nonFunctionTokenStartPos != gd::String::npos
|
||||
? nonFunctionTokenStartPos
|
||||
: parsePosition);
|
||||
parsePosition = nameEnd + 1;
|
||||
firstPointPos = expression.find(".", nameEnd + 1);
|
||||
firstParPos = expression.find("(", nameEnd + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsePosition < expression.length() || !nonFunctionToken.empty())
|
||||
callbacks.OnConstantToken(
|
||||
nonFunctionToken +
|
||||
expression.substr(parsePosition, expression.length()));
|
||||
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, expression.length());
|
||||
|
||||
return ValidSyntax(expressionWithoutFunctions);
|
||||
}
|
||||
|
||||
bool ExpressionParser::ParseStringExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::ParserCallbacks& callbacks) {
|
||||
callbacks.SetReturnType("string");
|
||||
gd::String expression = expressionPlainString;
|
||||
|
||||
size_t parsePosition = 0;
|
||||
|
||||
// Searching for first token.
|
||||
size_t firstPointPos = expression.find(".");
|
||||
size_t firstParPos = expression.find("(");
|
||||
size_t firstQuotePos = expression.find("\"");
|
||||
|
||||
if (firstPointPos == string::npos && firstParPos == string::npos &&
|
||||
firstQuotePos == string::npos) {
|
||||
firstErrorPos = 0;
|
||||
firstErrorStr =
|
||||
_("The expression is invalid or empty. Enter a text ( surrounded by "
|
||||
"quotes ) or a function.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
while (firstPointPos != string::npos || firstParPos != string::npos ||
|
||||
firstQuotePos != string::npos) {
|
||||
if (firstQuotePos < firstPointPos &&
|
||||
firstQuotePos < firstParPos) // Adding a constant text
|
||||
{
|
||||
callbacks.OnConstantToken(
|
||||
expression.substr(parsePosition, firstQuotePos - parsePosition));
|
||||
|
||||
// Finding start and end of quotes
|
||||
size_t finalQuotePosition = expression.find("\"", firstQuotePos + 1);
|
||||
while (finalQuotePosition ==
|
||||
expression.find("\\\"", finalQuotePosition - 1) + 1)
|
||||
finalQuotePosition = expression.find("\"", finalQuotePosition + 1);
|
||||
|
||||
if (finalQuotePosition == string::npos) {
|
||||
firstErrorPos = firstQuotePos;
|
||||
firstErrorStr = _("Quotes not closed.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generating final text, by replacing \" by quotes
|
||||
gd::String finalText = expression.substr(
|
||||
firstQuotePos + 1, finalQuotePosition - (firstQuotePos + 1));
|
||||
|
||||
size_t foundPos = finalText.find("\\\"");
|
||||
while (foundPos != string::npos) {
|
||||
if (foundPos != string::npos) finalText.replace(foundPos, 2, "\"");
|
||||
foundPos = finalText.find("\\\"", foundPos);
|
||||
}
|
||||
|
||||
// Adding constant text instruction
|
||||
//(Function without name is considered as a constant text)
|
||||
vector<gd::Expression> parameters;
|
||||
parameters.push_back(finalText);
|
||||
gd::ExpressionMetadata noParametersInfo;
|
||||
|
||||
callbacks.OnStaticFunction("", parameters, noParametersInfo);
|
||||
|
||||
parsePosition = finalQuotePosition + 1;
|
||||
} else // Adding a function
|
||||
{
|
||||
// Identify name
|
||||
size_t nameEnd =
|
||||
firstPointPos < firstParPos ? firstPointPos : firstParPos;
|
||||
size_t nameStart = expression.find_last_of(parserSeparators, nameEnd - 1);
|
||||
nameStart++;
|
||||
|
||||
callbacks.OnConstantToken(
|
||||
expression.substr(parsePosition, nameStart - parsePosition));
|
||||
|
||||
gd::String nameBefore = expression.substr(nameStart, nameEnd - nameStart);
|
||||
gd::String objectName = nameBefore.FindAndReplace("~", " ");
|
||||
|
||||
// Identify function name
|
||||
gd::String functionName = nameBefore;
|
||||
size_t functionNameEnd = nameEnd;
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
bool nameIsFunction = firstPointPos > firstParPos;
|
||||
if (!nameIsFunction) {
|
||||
parameters.push_back(gd::Expression(objectName));
|
||||
functionNameEnd = expression.find_first_of("( ", nameEnd);
|
||||
if (nameEnd + 1 < expression.length())
|
||||
functionName =
|
||||
expression.substr(nameEnd + 1, functionNameEnd - (nameEnd + 1));
|
||||
}
|
||||
|
||||
// Identify parameters
|
||||
size_t parametersEnd = expression.find_first_of("(", functionNameEnd) + 1;
|
||||
char32_t previousChar = U'(';
|
||||
bool takeSymbolsInAccount = true;
|
||||
size_t level = 0;
|
||||
gd::String currentParameterStr;
|
||||
while (parametersEnd < expression.length() &&
|
||||
!(expression[parametersEnd] == U')' && level == 0)) {
|
||||
// Be sure we are not in quotes
|
||||
if (expression[parametersEnd] == U'\"' && previousChar != U'\\')
|
||||
takeSymbolsInAccount = !takeSymbolsInAccount;
|
||||
|
||||
// So as to be sure paranthesis don't belong to a parameter
|
||||
if (expression[parametersEnd] == U'(' && takeSymbolsInAccount) level++;
|
||||
if (expression[parametersEnd] == U')' && takeSymbolsInAccount) level--;
|
||||
|
||||
// Add the character to the current parameter or terminate the latter
|
||||
if ((expression[parametersEnd] == ',' && level == 0) &&
|
||||
takeSymbolsInAccount) {
|
||||
gd::Expression currentParameter(currentParameterStr);
|
||||
parameters.push_back(currentParameter);
|
||||
|
||||
currentParameterStr.clear();
|
||||
} else
|
||||
currentParameterStr += expression[parametersEnd];
|
||||
|
||||
previousChar = expression[parametersEnd];
|
||||
parametersEnd++;
|
||||
}
|
||||
|
||||
if (parametersEnd == expression.length() ||
|
||||
expression[parametersEnd] != U')') {
|
||||
firstErrorPos = parametersEnd - 1;
|
||||
firstErrorStr = _("Paranthesis not closed");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentParameterStr.find_first_not_of(" ") !=
|
||||
string::npos) // Add last parameter if needed
|
||||
{
|
||||
gd::Expression lastParameter(currentParameterStr);
|
||||
parameters.push_back(lastParameter);
|
||||
}
|
||||
|
||||
bool functionFound = false;
|
||||
|
||||
// First try to bind to a static str expression
|
||||
if (nameIsFunction &&
|
||||
MetadataProvider::HasStrExpression(platform, functionName)) {
|
||||
functionFound = true;
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetStrExpressionMetadata(platform, functionName);
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters = CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0;
|
||||
i < parameters.size() && i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnStaticFunction(functionName, parameters, expressionInfo);
|
||||
}
|
||||
// Then an object member expression
|
||||
else if (!nameIsFunction &&
|
||||
MetadataProvider::HasObjectStrExpression(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName)) {
|
||||
functionFound = true;
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetObjectStrExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, nameBefore),
|
||||
functionName);
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters = CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0;
|
||||
i < parameters.size() && i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnObjectFunction(functionName, parameters, expressionInfo);
|
||||
}
|
||||
// And search behaviors expressions
|
||||
else {
|
||||
size_t firstDoublePoints = functionName.find("::");
|
||||
if (firstDoublePoints != string::npos) {
|
||||
gd::String autoName = functionName.substr(0, firstDoublePoints);
|
||||
if (firstDoublePoints + 2 < functionName.length())
|
||||
functionName = functionName.substr(firstDoublePoints + 2,
|
||||
functionName.length());
|
||||
else
|
||||
functionName = "";
|
||||
|
||||
if (MetadataProvider::HasBehaviorStrExpression(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName)) {
|
||||
parameters.push_back(gd::Expression(autoName));
|
||||
functionFound = true;
|
||||
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetBehaviorStrExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName);
|
||||
|
||||
// Verify that object has behavior.
|
||||
vector<gd::String> behaviors =
|
||||
gd::GetBehaviorsOfObject(project, layout, objectName);
|
||||
if (find(behaviors.begin(), behaviors.end(), autoName) ==
|
||||
behaviors.end()) {
|
||||
cout << "Bad behavior requested" << endl;
|
||||
functionFound = false;
|
||||
} else {
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters =
|
||||
CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0; i < parameters.size() &&
|
||||
i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnObjectBehaviorFunction(
|
||||
functionName, parameters, expressionInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note : _No_ support for implicit conversion from math result to string
|
||||
|
||||
if (!functionFound) // Function was not found
|
||||
{
|
||||
firstErrorPos = nameStart;
|
||||
firstErrorStr = _("Function not recognized.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsePosition = parametersEnd + 1;
|
||||
}
|
||||
|
||||
// Searching for next token
|
||||
size_t firstPlusPos = expression.find("+", parsePosition);
|
||||
firstPointPos = expression.find(".", parsePosition);
|
||||
firstParPos = expression.find("(", parsePosition);
|
||||
firstQuotePos = expression.find("\"", parsePosition);
|
||||
|
||||
// Checking for a + between token
|
||||
if ((firstPointPos != string::npos || firstParPos != string::npos ||
|
||||
firstQuotePos != string::npos)) {
|
||||
size_t nextTokenPos = firstPointPos;
|
||||
if (firstParPos < nextTokenPos) nextTokenPos = firstParPos;
|
||||
if (firstQuotePos < nextTokenPos) nextTokenPos = firstQuotePos;
|
||||
|
||||
if (nextTokenPos < firstPlusPos) {
|
||||
firstErrorPos = nextTokenPos;
|
||||
firstErrorStr = _("Symbol missing between two +.");
|
||||
|
||||
return false;
|
||||
} else if (expression.find("+", firstPlusPos + 1) < nextTokenPos) {
|
||||
firstErrorPos = firstPlusPos;
|
||||
firstErrorStr = _("Symbol missing between two +.");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expression.substr(parsePosition, expression.length())
|
||||
.find_first_not_of(" \n") != gd::String::npos) {
|
||||
firstErrorPos = parsePosition;
|
||||
firstErrorStr = _("Bad symbol at the end of the expression.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpressionParser::PrepareParameter(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
ParserCallbacks& callbacks,
|
||||
gd::Expression& parameter,
|
||||
const gd::ParameterMetadata& parametersInfo,
|
||||
const size_t positionInExpression) {
|
||||
if (ParameterMetadata::IsExpression("number", parametersInfo.type)) {
|
||||
if (parametersInfo.optional && parameter.GetPlainString().empty())
|
||||
parameter = parametersInfo.GetDefaultValue().empty()
|
||||
? gd::Expression("0")
|
||||
: gd::Expression(parametersInfo.GetDefaultValue());
|
||||
|
||||
if (!callbacks.OnSubMathExpression(platform, project, layout, parameter)) {
|
||||
firstErrorStr = callbacks.firstErrorStr;
|
||||
firstErrorPos = callbacks.firstErrorPos + positionInExpression;
|
||||
|
||||
return false;
|
||||
}
|
||||
} else if (ParameterMetadata::IsExpression("string", parametersInfo.type)) {
|
||||
if (parametersInfo.optional && parameter.GetPlainString().empty())
|
||||
parameter = parametersInfo.GetDefaultValue().empty()
|
||||
? gd::Expression("\"\"")
|
||||
: gd::Expression(parametersInfo.GetDefaultValue());
|
||||
|
||||
if (!callbacks.OnSubTextExpression(platform, project, layout, parameter)) {
|
||||
firstErrorStr = callbacks.firstErrorStr;
|
||||
firstErrorPos = callbacks.firstErrorPos + positionInExpression;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ExpressionParser::ExpressionParser(const gd::String& expressionPlainString_)
|
||||
: expressionPlainString(expressionPlainString_) {}
|
||||
|
||||
} // namespace gd
|
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EXPRESSIONPARSER_H
|
||||
#define GDCORE_EXPRESSIONPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Expression;
|
||||
class ParserCallbacks;
|
||||
class ObjectsContainer;
|
||||
class Platform;
|
||||
class ParameterMetadata;
|
||||
class ExpressionMetadata;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/** \brief Parse an expression
|
||||
*
|
||||
* Parse an expression, calling callbacks when a token is reached
|
||||
* \see gd::ParserCallbacks
|
||||
*/
|
||||
class GD_CORE_API ExpressionParser {
|
||||
public:
|
||||
ExpressionParser(const gd::String &expressionPlainString_);
|
||||
virtual ~ExpressionParser(){};
|
||||
|
||||
/**
|
||||
* \brief Parse the expression, calling each functor when necessary
|
||||
* \return True if expression was correctly parsed.
|
||||
*/
|
||||
bool ParseMathExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::ParserCallbacks &callbacks);
|
||||
|
||||
/**
|
||||
* \brief Parse the expression, calling each functor when necessary
|
||||
* \return True if expression was correctly parsed.
|
||||
*/
|
||||
bool ParseStringExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::ParserCallbacks &callbacks);
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String &GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
private:
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
/**
|
||||
* Tool function to add a parameter
|
||||
*/
|
||||
bool AddParameterToList(const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
ParserCallbacks &,
|
||||
std::vector<gd::Expression> ¶meters,
|
||||
gd::String parameterStr,
|
||||
std::vector<gd::ParameterMetadata> parametersInfos,
|
||||
const size_t positionInExpression);
|
||||
|
||||
/**
|
||||
* Tool function to prepare a parameter
|
||||
*/
|
||||
bool PrepareParameter(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
ParserCallbacks &,
|
||||
gd::Expression ¶meter,
|
||||
const gd::ParameterMetadata ¶metersInfo,
|
||||
const size_t positionInExpression);
|
||||
|
||||
/**
|
||||
* Return the minimal number of parameters which can be used when calling an
|
||||
* expression ( i.e. ParametersCount-OptionalParameters-CodeOnlyParameters )
|
||||
*/
|
||||
size_t GetMinimalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata> ¶metersInfos);
|
||||
|
||||
/**
|
||||
* Return the maximal number of parameters which can be used when calling an
|
||||
* expression ( i.e. ParametersCount-CodeOnlyParameters )
|
||||
*/
|
||||
size_t GetMaximalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata> ¶metersInfos);
|
||||
|
||||
bool ValidSyntax(const gd::String &str);
|
||||
|
||||
gd::String expressionPlainString;
|
||||
static gd::String parserSeparators;
|
||||
};
|
||||
|
||||
/** \brief Callbacks called by parser during parsing
|
||||
*
|
||||
* Parser will call the appropriate functions during parsing, allowing to do
|
||||
* special works. \see gd::ExpressionParser
|
||||
*/
|
||||
class GD_CORE_API ParserCallbacks {
|
||||
friend class ExpressionParser;
|
||||
|
||||
public:
|
||||
ParserCallbacks() : returnType("expression"){};
|
||||
virtual ~ParserCallbacks(){};
|
||||
|
||||
/**
|
||||
* \brief Get the type of the expression for which callbacks are used:
|
||||
* "expression" or "string".
|
||||
*/
|
||||
const gd::String &GetReturnType() { return returnType; }
|
||||
|
||||
virtual void OnConstantToken(gd::String text) = 0;
|
||||
|
||||
virtual void OnStaticFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual void OnObjectFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual void OnObjectBehaviorFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual bool OnSubMathExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::Expression &expression) = 0;
|
||||
virtual bool OnSubTextExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::Expression &expression) = 0;
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String &GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
protected:
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Set the return type of the expression: Done by ExpressionParser
|
||||
* according to which Parse* method is called. \see gd::ExpressionParser
|
||||
*/
|
||||
void SetReturnType(gd::String type) { returnType = type; }
|
||||
|
||||
gd::String returnType; // The type of the expression ("expression" (default),
|
||||
// "string"...)
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDEXPRESSIONPARSER_H
|
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Platform;
|
||||
}
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariableParser::~VariableParser() {}
|
||||
|
||||
bool VariableParser::Parse(VariableParserCallbacks& callbacks_) {
|
||||
callbacks = &callbacks_;
|
||||
rootVariableParsed = false;
|
||||
firstErrorStr.clear();
|
||||
firstErrorPos = 0;
|
||||
currentPositionIt = expression.begin();
|
||||
currentTokenType = TS_INVALID;
|
||||
currentToken.clear();
|
||||
S();
|
||||
|
||||
return firstErrorStr == "";
|
||||
}
|
||||
|
||||
void VariableParser::ReadToken() {
|
||||
currentTokenType = TS_INVALID;
|
||||
currentToken.clear();
|
||||
while (currentPositionIt != expression.end()) {
|
||||
char32_t currentChar = *currentPositionIt;
|
||||
if (currentChar == U'[' || currentChar == U']' || currentChar == U'.') {
|
||||
if (currentTokenType == TS_VARNAME)
|
||||
return; // We've parsed a variable name.
|
||||
}
|
||||
|
||||
if (currentChar == U'[') {
|
||||
currentTokenType = TS_OPENING_BRACKET;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
} else if (currentChar == U']') {
|
||||
currentTokenType = TS_CLOSING_BRACKET;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
} else if (currentChar == U'.') {
|
||||
currentTokenType = TS_PERIOD;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
}
|
||||
|
||||
currentTokenType = TS_VARNAME; // We're parsing a variable name.
|
||||
currentToken.push_back(currentChar);
|
||||
++currentPositionIt;
|
||||
}
|
||||
|
||||
// Can be reached if we are at the end of the expression. In this case,
|
||||
// currentTokenType will be either TS_VARNAME or TS_INVALID.
|
||||
}
|
||||
|
||||
void VariableParser::S() {
|
||||
ReadToken();
|
||||
if (currentTokenType != TS_VARNAME) {
|
||||
firstErrorStr = _("Expecting a variable name.");
|
||||
firstErrorPos = std::distance<gd::String::const_iterator>(
|
||||
expression.begin(), currentPositionIt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rootVariableParsed) {
|
||||
rootVariableParsed = true;
|
||||
if (callbacks) callbacks->OnRootVariable(currentToken);
|
||||
} else if (callbacks)
|
||||
callbacks->OnChildVariable(currentToken);
|
||||
|
||||
X();
|
||||
}
|
||||
|
||||
void VariableParser::X() {
|
||||
ReadToken();
|
||||
if (currentTokenType == TS_INVALID)
|
||||
return; // Ended parsing.
|
||||
else if (currentTokenType == TS_PERIOD)
|
||||
S();
|
||||
else if (currentTokenType == TS_OPENING_BRACKET) {
|
||||
gd::String strExpr = SkipStringExpression();
|
||||
|
||||
ReadToken();
|
||||
if (currentTokenType != TS_CLOSING_BRACKET) {
|
||||
firstErrorStr = _("Expecting ]");
|
||||
firstErrorPos = std::distance<gd::String::const_iterator>(
|
||||
expression.begin(), currentPositionIt);
|
||||
return;
|
||||
}
|
||||
if (callbacks) callbacks->OnChildSubscript(strExpr);
|
||||
X();
|
||||
}
|
||||
}
|
||||
|
||||
gd::String VariableParser::SkipStringExpression() {
|
||||
gd::String stringExpression;
|
||||
bool insideStringLiteral = false;
|
||||
bool lastCharacterWasBackslash = false;
|
||||
unsigned int nestedBracket = 0;
|
||||
while (currentPositionIt != expression.end()) {
|
||||
char32_t currentChar = *currentPositionIt;
|
||||
if (currentChar == U'\"') {
|
||||
if (!insideStringLiteral)
|
||||
insideStringLiteral = true;
|
||||
else if (!lastCharacterWasBackslash)
|
||||
insideStringLiteral = false;
|
||||
} else if (currentChar == U'[' && !insideStringLiteral) {
|
||||
nestedBracket++;
|
||||
} else if (currentChar == U']' && !insideStringLiteral) {
|
||||
if (nestedBracket == 0)
|
||||
return stringExpression; // Found the end of the string litteral.
|
||||
nestedBracket--;
|
||||
}
|
||||
|
||||
lastCharacterWasBackslash = currentChar == U'\\';
|
||||
stringExpression.push_back(currentChar);
|
||||
++currentPositionIt;
|
||||
}
|
||||
|
||||
// End of the expression reached (so expression is invalid by the way)
|
||||
return stringExpression;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_VARIABLEPARSER_H
|
||||
#define GDCORE_VARIABLEPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Platform;
|
||||
}
|
||||
namespace gd {
|
||||
class VariableParserCallbacks;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/** \brief Parse a variable expression.
|
||||
*
|
||||
* Parse an variable expression ( like
|
||||
myVariable.child["subchild"+ToString(i)].subsubchild ),
|
||||
* calling callbacks when a token is reached.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
//...
|
||||
|
||||
//VariableCodeGenerationCallbacks is a class inheriting from
|
||||
gd::VariableParserCallbacks VariableCodeGenerationCallbacks callbacks(output,
|
||||
*this, context, VariableCodeGenerationCallbacks::PROJECT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(parameter);
|
||||
if ( !parser.Parse(callbacks) )
|
||||
cout << "Error :" << parser.GetFirstError() << " in: "<< parameter <<
|
||||
endl;
|
||||
\endcode
|
||||
*
|
||||
* Here is the parsed grammar: <br>
|
||||
* S -> VarName X <br>
|
||||
* X -> e | . S | [StringExpression] X <br>
|
||||
*
|
||||
* where e = nothing (end of expression), StringExpression = A valid string
|
||||
expression and
|
||||
* S is the start.
|
||||
*
|
||||
* \see gd::VariableParserCallbacks
|
||||
*/
|
||||
class GD_CORE_API VariableParser {
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor
|
||||
* \param expressionPlainString The string representing the expression to be
|
||||
* parsed.
|
||||
*/
|
||||
VariableParser(const gd::String& expressionPlainString_)
|
||||
: currentPositionIt(), expression(expressionPlainString_){};
|
||||
virtual ~VariableParser();
|
||||
|
||||
/**
|
||||
* Parse the expression, calling each callback when necessary.
|
||||
* \param callbacks The callbacks to be called.
|
||||
* \return true if expression was correctly parsed.
|
||||
* \see gd::VariableParserCallbacks
|
||||
*/
|
||||
bool Parse(VariableParserCallbacks& callbacks);
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String& GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
private:
|
||||
void S();
|
||||
void X();
|
||||
|
||||
/**
|
||||
* \brief Skip the string expression, starting from the current position.
|
||||
* \return The string expression skipped. currentPosition is now put on the
|
||||
* closing bracket.
|
||||
*/
|
||||
gd::String SkipStringExpression();
|
||||
|
||||
void ReadToken();
|
||||
|
||||
enum TokenType {
|
||||
TS_PERIOD,
|
||||
TS_OPENING_BRACKET,
|
||||
TS_CLOSING_BRACKET,
|
||||
TS_VARNAME,
|
||||
TS_INVALID
|
||||
};
|
||||
|
||||
TokenType currentTokenType;
|
||||
gd::String currentToken;
|
||||
gd::String::const_iterator currentPositionIt;
|
||||
gd::String expression;
|
||||
|
||||
VariableParserCallbacks* callbacks;
|
||||
bool rootVariableParsed;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Callbacks called by VariableParser when parsing a variable expression.
|
||||
*/
|
||||
class GD_CORE_API VariableParserCallbacks {
|
||||
public:
|
||||
/**
|
||||
* \brief Called when the first variable has been parsed. ( varName1 in
|
||||
* varName1.child for example. ) \param variableName The variable name.
|
||||
*/
|
||||
virtual void OnRootVariable(gd::String variableName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable. ( child in
|
||||
* varName1.child for example. ) \param variableName The child variable name.
|
||||
*/
|
||||
virtual void OnChildVariable(gd::String variableName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable using a
|
||||
* string expression in square brackets. ( "subscript" in
|
||||
* varName1["subscript"] for example. )
|
||||
*
|
||||
* \param variableName The expression used to access the child variable.
|
||||
*/
|
||||
virtual void OnChildSubscript(gd::String stringExpression) = 0;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDEXPRESSIONPARSER_H
|
@@ -8,10 +8,15 @@
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::_singleton = NULL;
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::_singleton = nullptr;
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
const gd::String &originalObjectName) {
|
||||
auto it = mangledObjectNames.find(originalObjectName);
|
||||
if (it != mangledObjectNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = originalObjectName;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@@ -27,11 +32,17 @@ gd::String EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
}
|
||||
}
|
||||
|
||||
return "GD" + partiallyMangledName + "Objects";
|
||||
mangledObjectNames[originalObjectName] = "GD" + partiallyMangledName + "Objects";
|
||||
return mangledObjectNames[originalObjectName];
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName) {
|
||||
auto it = mangledExternalEventsNames.find(externalEventsName);
|
||||
if (it != mangledExternalEventsNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = externalEventsName;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
@@ -47,23 +58,24 @@ gd::String EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
}
|
||||
}
|
||||
|
||||
return "GDExternalEvents" + partiallyMangledName;
|
||||
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
|
||||
return mangledExternalEventsNames[externalEventsName];
|
||||
}
|
||||
|
||||
gd::String ManObjListName(const gd::String &objectName) {
|
||||
const gd::String& ManObjListName(const gd::String &objectName) {
|
||||
return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName);
|
||||
}
|
||||
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::Get() {
|
||||
if (NULL == _singleton) _singleton = new EventsCodeNameMangler;
|
||||
if (nullptr == _singleton) _singleton = new EventsCodeNameMangler;
|
||||
|
||||
return (static_cast<EventsCodeNameMangler *>(_singleton));
|
||||
}
|
||||
|
||||
void EventsCodeNameMangler::DestroySingleton() {
|
||||
if (NULL != _singleton) {
|
||||
if (nullptr != _singleton) {
|
||||
delete _singleton;
|
||||
_singleton = NULL;
|
||||
_singleton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,26 +6,34 @@
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef EVENTSCODENAMEMANGLER_H
|
||||
#define EVENTSCODENAMEMANGLER_H
|
||||
#include <unordered_map>
|
||||
#include "GDCore/String.h"
|
||||
|
||||
/**
|
||||
* Manage name mangling, so as to ensure all names used in code are valid.
|
||||
* \brief Mangle object names, so as to ensure all names used in code are valid.
|
||||
*
|
||||
* \see ManObjListName
|
||||
*/
|
||||
class GD_CORE_API EventsCodeNameMangler {
|
||||
public:
|
||||
/**
|
||||
* Get the mangled name from a name : All characters that are not 0-9, a-z,
|
||||
* Get the mangled name from a name: All characters that are not 0-9, a-z,
|
||||
* A-Z or _ are replaced by "_"+AsciiCodeOfTheCharacter.
|
||||
*
|
||||
* The mangled name is memoized as this is intensively used during project
|
||||
* export and events code generation.
|
||||
*/
|
||||
gd::String GetMangledObjectsListName(const gd::String &originalObjectName);
|
||||
const gd::String &GetMangledObjectsListName(
|
||||
const gd::String &originalObjectName);
|
||||
|
||||
/**
|
||||
* Get the mangled function name to be used to call external events named \a
|
||||
* externalEventsName.
|
||||
*
|
||||
* The mangled name is memoized as this is intensively used during project
|
||||
* export and events code generation.
|
||||
*/
|
||||
gd::String GetExternalEventsFunctionMangledName(
|
||||
const gd::String &GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName);
|
||||
|
||||
static EventsCodeNameMangler *Get();
|
||||
@@ -35,14 +43,22 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
EventsCodeNameMangler(){};
|
||||
virtual ~EventsCodeNameMangler(){};
|
||||
static EventsCodeNameMangler *_singleton;
|
||||
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledObjectNames; ///< Memoized results of mangling for objects
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledExternalEventsNames; ///< Memoized results of mangling for
|
||||
/// external events
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut to
|
||||
* EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName). \see
|
||||
* EventsCodeNameMangler \return Mangled object name
|
||||
* Shortcut for
|
||||
* `EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName)`.
|
||||
*
|
||||
* \see EventsCodeNameMangler
|
||||
* \return Mangled object name
|
||||
*/
|
||||
gd::String GD_CORE_API ManObjListName(const gd::String &objectName);
|
||||
const gd::String &GD_CORE_API ManObjListName(const gd::String &objectName);
|
||||
|
||||
#endif // EVENTSCODENAMEMANGLER_H
|
||||
#endif
|
||||
|
@@ -14,8 +14,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("BuiltinObject",
|
||||
_("Base object"),
|
||||
_("Base object"),
|
||||
_("Features for all objects"),
|
||||
_("Common features that can be used for all objects in GDevelop."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects/base_object/events");
|
||||
|
@@ -595,7 +595,8 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool inConditions,
|
||||
bool inActions) {
|
||||
bool inActions,
|
||||
bool inEventStrings) {
|
||||
vector<EventsSearchResult> results;
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
@@ -631,6 +632,16 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
}
|
||||
}
|
||||
|
||||
if (inEventStrings) {
|
||||
if (!eventAddedInResults &&
|
||||
SearchStringInEvent(project, layout, events[i], search, matchCase)) {
|
||||
results.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
i));
|
||||
}
|
||||
}
|
||||
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
vector<EventsSearchResult> subResults =
|
||||
SearchInEvents(project,
|
||||
@@ -639,7 +650,8 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
search,
|
||||
matchCase,
|
||||
inConditions,
|
||||
inActions);
|
||||
inActions,
|
||||
inEventStrings);
|
||||
std::copy(
|
||||
subResults.begin(), subResults.end(), std::back_inserter(results));
|
||||
}
|
||||
@@ -711,6 +723,22 @@ bool EventsRefactorer::SearchStringInConditions(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInEvent(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::BaseEvent& event,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
for (gd::String str : event.GetAllSearchableStrings()) {
|
||||
if (matchCase) {
|
||||
if (str.find(search) != gd::String::npos) return true;
|
||||
} else {
|
||||
if (str.FindCaseInsensitive(search) != gd::String::npos) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsSearchResult::EventsSearchResult(std::weak_ptr<gd::BaseEvent> event_,
|
||||
gd::EventsList* eventsList_,
|
||||
std::size_t positionInList_)
|
||||
|
@@ -103,7 +103,8 @@ class GD_CORE_API EventsRefactorer {
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool inConditions,
|
||||
bool inAction);
|
||||
bool inActions,
|
||||
bool inEventStrings);
|
||||
|
||||
/**
|
||||
* Replace all occurrences of a gd::String in events
|
||||
@@ -202,6 +203,11 @@ class GD_CORE_API EventsRefactorer {
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
static bool SearchStringInEvent(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::BaseEvent& events,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
|
||||
EventsRefactorer(){};
|
||||
};
|
||||
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCore/IDE/Events/ExpressionsCorrectnessTesting.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
CallbacksForExpressionCorrectnessTesting::
|
||||
CallbacksForExpressionCorrectnessTesting(const gd::ObjectsContainer& project_,
|
||||
const gd::ObjectsContainer& layout_)
|
||||
: project(project_), layout(layout_) {}
|
||||
|
||||
bool CallbacksForExpressionCorrectnessTesting::OnSubMathExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression) {
|
||||
CallbacksForExpressionCorrectnessTesting callbacks(project, layout);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseMathExpression(platform, project, layout, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallbacksForExpressionCorrectnessTesting::OnSubTextExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression) {
|
||||
CallbacksForExpressionCorrectnessTesting callbacks(project, layout);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseStringExpression(platform, project, layout, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_EXPRESSIONSCORRECTNESSTESTING_H
|
||||
#define GDCORE_EXPRESSIONSCORRECTNESSTESTING_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class ExpressionMetadata;
|
||||
class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
// TODO: Replace and remove (ExpressionValidator)
|
||||
|
||||
/**
|
||||
* \brief Parser callbacks used to check expressions correctness
|
||||
*
|
||||
* Usage example:
|
||||
* \code
|
||||
* gd::CallbacksForExpressionCorrectnessTesting callbacks(game, scene);
|
||||
* gd::ExpressionParser expressionParser(expression);
|
||||
* if ( !expressionParser.ParseMathExpression(game, scene, callbacks) )
|
||||
* //Expression is not valid
|
||||
* else
|
||||
* //Expression is correct
|
||||
* \endcode
|
||||
*
|
||||
* \see gd::ExpressionParser
|
||||
* \see gd::ParserCallbacks
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API CallbacksForExpressionCorrectnessTesting
|
||||
: public gd::ParserCallbacks {
|
||||
public:
|
||||
CallbacksForExpressionCorrectnessTesting(const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout);
|
||||
virtual ~CallbacksForExpressionCorrectnessTesting(){};
|
||||
|
||||
void OnConstantToken(gd::String text){};
|
||||
void OnStaticFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo){};
|
||||
void OnObjectFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo){};
|
||||
void OnObjectBehaviorFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo){};
|
||||
bool OnSubMathExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
bool OnSubTextExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
|
||||
private:
|
||||
const gd::ObjectsContainer& project;
|
||||
const gd::ObjectsContainer& layout;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EXPRESSIONSCORRECTNESSTESTING_H
|
@@ -10,34 +10,49 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::String SceneNameMangler::GetMangledSceneName(gd::String sceneName) {
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static const gd::String allowedExceptFirst = "0123456789";
|
||||
SceneNameMangler *SceneNameMangler::_singleton = nullptr;
|
||||
|
||||
std::size_t i = 0;
|
||||
for (auto it = sceneName.begin(); it != sceneName.end(); ++it) {
|
||||
char32_t character = *it;
|
||||
if (allowedCharacters.find(character) == gd::String::npos &&
|
||||
(allowedExceptFirst.find(character) == gd::String::npos ||
|
||||
i == 0)) // Also disallow some characters to be in first position
|
||||
{
|
||||
// Replace the character by an underscore and its unicode codepoint (in
|
||||
// base 10)
|
||||
auto it2 = it;
|
||||
++it2;
|
||||
sceneName.replace(it, it2, "_" + gd::String::From(character));
|
||||
|
||||
// The iterator it may have been invalidated:
|
||||
// re-assign it with a new iterator pointing to the same position.
|
||||
it = sceneName.begin();
|
||||
std::advance(it, i);
|
||||
}
|
||||
|
||||
++i;
|
||||
const gd::String &SceneNameMangler::GetMangledSceneName(
|
||||
const gd::String &sceneName) {
|
||||
auto it = mangledSceneNames.find(sceneName);
|
||||
if (it != mangledSceneNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return sceneName;
|
||||
gd::String partiallyMangledName = sceneName;
|
||||
static const gd::String alwaysAllowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static const gd::String allowedExceptFirstCharacters = "0123456789";
|
||||
|
||||
for (size_t i = 0; i < partiallyMangledName.size();
|
||||
++i) // Replace all unallowed letter by an underscore and the unicode
|
||||
// code point of the letter
|
||||
{
|
||||
if (alwaysAllowedCharacters.find_first_of(
|
||||
std::u32string(1, partiallyMangledName[i])) == gd::String::npos &&
|
||||
(i == 0 ||
|
||||
allowedExceptFirstCharacters.find(
|
||||
std::u32string(1, partiallyMangledName[i])) == gd::String::npos)) {
|
||||
char32_t unallowedChar = partiallyMangledName[i];
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
|
||||
mangledSceneNames[sceneName] = partiallyMangledName;
|
||||
return mangledSceneNames[sceneName];
|
||||
}
|
||||
|
||||
SceneNameMangler *SceneNameMangler::Get() {
|
||||
if (nullptr == _singleton) _singleton = new SceneNameMangler;
|
||||
|
||||
return (static_cast<SceneNameMangler *>(_singleton));
|
||||
}
|
||||
|
||||
void SceneNameMangler::DestroySingleton() {
|
||||
if (nullptr != _singleton) {
|
||||
delete _singleton;
|
||||
_singleton = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -6,12 +6,14 @@
|
||||
|
||||
#ifndef SCENENAMEMANGLER_H
|
||||
#define SCENENAMEMANGLER_H
|
||||
#include <unordered_map>
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Used to mangle the name of a scene
|
||||
* \brief Mangle the name of a scene, so that it can be used in code or file
|
||||
* names.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
@@ -21,12 +23,22 @@ class GD_CORE_API SceneNameMangler {
|
||||
* \brief Mangle the name of a scene, replacing all characters that are not
|
||||
* 0-9, a-z or A-Z by "_"+UnicodeCodePointOfTheCharacter. The first character
|
||||
* must be a letter, otherwise it is also replaced in the same manner.
|
||||
*
|
||||
* The mangled name is memoized as this is intensively used during project
|
||||
* export and events code generation.
|
||||
*/
|
||||
static gd::String GetMangledSceneName(gd::String sceneName);
|
||||
const gd::String& GetMangledSceneName(const gd::String& sceneName);
|
||||
|
||||
static SceneNameMangler* Get();
|
||||
static void DestroySingleton();
|
||||
|
||||
private:
|
||||
SceneNameMangler(){};
|
||||
virtual ~SceneNameMangler(){};
|
||||
static SceneNameMangler* _singleton;
|
||||
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledSceneNames; ///< Memoized results of mangling
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -8,8 +8,8 @@
|
||||
#define GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsFunctionsContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/SerializableWithNameList.h"
|
||||
namespace gd {
|
||||
@@ -59,7 +59,8 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
}
|
||||
|
||||
const gd::String& GetShortDescription() const { return shortDescription; };
|
||||
EventsFunctionsExtension& SetShortDescription(const gd::String& shortDescription_) {
|
||||
EventsFunctionsExtension& SetShortDescription(
|
||||
const gd::String& shortDescription_) {
|
||||
shortDescription = shortDescription_;
|
||||
return *this;
|
||||
}
|
||||
@@ -97,15 +98,15 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
/**
|
||||
* \brief Return a reference to the list of the events based behaviors.
|
||||
*/
|
||||
SerializableWithNameList<EventsBasedBehavior>& GetEventsBasedBehaviors() {
|
||||
gd::SerializableWithNameList<EventsBasedBehavior>& GetEventsBasedBehaviors() {
|
||||
return eventsBasedBehaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a const reference to the list of the events based behaviors.
|
||||
*/
|
||||
const SerializableWithNameList<EventsBasedBehavior>& GetEventsBasedBehaviors()
|
||||
const {
|
||||
const gd::SerializableWithNameList<EventsBasedBehavior>&
|
||||
GetEventsBasedBehaviors() const {
|
||||
return eventsBasedBehaviors;
|
||||
}
|
||||
|
||||
@@ -139,7 +140,7 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::String fullName;
|
||||
gd::String tags;
|
||||
gd::String author;
|
||||
SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -63,7 +63,7 @@ Layout::Layout()
|
||||
|
||||
void Layout::SetName(const gd::String& name_) {
|
||||
name = name_;
|
||||
mangledName = gd::SceneNameMangler::GetMangledSceneName(name);
|
||||
mangledName = gd::SceneNameMangler::Get()->GetMangledSceneName(name);
|
||||
};
|
||||
|
||||
bool Layout::HasBehaviorSharedData(const gd::String& behaviorName) {
|
||||
|
@@ -25,11 +25,11 @@ gd::String GetTranslation(const char* str) { // TODO: Inline?
|
||||
// }
|
||||
ensureCache.prepare();
|
||||
|
||||
var translatedStr = getTranslation(Pointer_stringify($0));
|
||||
var translatedStr = getTranslation(UTF8ToString($0));
|
||||
return ensureString(translatedStr);
|
||||
},
|
||||
str);
|
||||
return gd::String(translatedStr); // TODO: Is copying necessary?
|
||||
}
|
||||
} // namespace gd
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -11,16 +11,31 @@
|
||||
|
||||
TEST_CASE("SceneNameMangler", "[common]") {
|
||||
SECTION("Basics") {
|
||||
REQUIRE(gd::SceneNameMangler::GetMangledSceneName(
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"TotallyCorrectSceneName") == u8"TotallyCorrectSceneName");
|
||||
REQUIRE(gd::SceneNameMangler::GetMangledSceneName(
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"TotallyCorrectSceneName") == u8"TotallyCorrectSceneName");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"Totally NOT CorrectSceneName") ==
|
||||
u8"Totally_32NOT_32CorrectSceneName");
|
||||
REQUIRE(gd::SceneNameMangler::GetMangledSceneName(u8"Nouvelle scène") ==
|
||||
u8"Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::GetMangledSceneName(u8"A test Ԙ") ==
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"Totally NOT CorrectSceneName") ==
|
||||
u8"Totally_32NOT_32CorrectSceneName");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"Nouvelle scène") == u8"Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"Nouvelle scène") == u8"Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(u8"A test Ԙ") ==
|
||||
u8"A_32test_32_1304");
|
||||
REQUIRE(gd::SceneNameMangler::GetMangledSceneName(u8"1 Nouvelle scène") ==
|
||||
u8"_49_32Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(u8"A test Ԙ") ==
|
||||
u8"A_32test_32_1304");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"1 Nouvelle scène") == u8"_49_32Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"1 Nouvelle scène") == u8"_49_32Nouvelle_32sc_232ne");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"汉语") == u8"_27721_35821");
|
||||
REQUIRE(gd::SceneNameMangler::Get()->GetMangledSceneName(
|
||||
u8"汉语") == u8"_27721_35821");
|
||||
}
|
||||
}
|
||||
|
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
namespace {
|
||||
class TestVariableParserCallbacks : public gd::VariableParserCallbacks {
|
||||
public:
|
||||
TestVariableParserCallbacks(gd::String &debugStr)
|
||||
: VariableParserCallbacks(), debugStr(debugStr) {}
|
||||
|
||||
virtual void OnRootVariable(gd::String variableName) {
|
||||
debugStr += "OnRootVariable(" + variableName + ")\n";
|
||||
}
|
||||
|
||||
virtual void OnChildVariable(gd::String variableName) {
|
||||
debugStr += "OnChildVariable(" + variableName + ")\n";
|
||||
}
|
||||
|
||||
virtual void OnChildSubscript(gd::String stringExpression) {
|
||||
debugStr += "OnChildSubscript(" + stringExpression + ")\n";
|
||||
}
|
||||
|
||||
private:
|
||||
gd::String &debugStr;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("VariableParser", "[common][events]") {
|
||||
SECTION("Basics") {
|
||||
{
|
||||
gd::String str;
|
||||
TestVariableParserCallbacks callbacks(str);
|
||||
gd::VariableParser parser("myVar");
|
||||
parser.Parse(callbacks);
|
||||
|
||||
REQUIRE(str == "OnRootVariable(myVar)\n");
|
||||
}
|
||||
{
|
||||
gd::String str;
|
||||
TestVariableParserCallbacks callbacks(str);
|
||||
gd::VariableParser parser("myVar.child1.child2");
|
||||
parser.Parse(callbacks);
|
||||
|
||||
REQUIRE(str ==
|
||||
"OnRootVariable(myVar)\nOnChildVariable(child1)\nOnChildVariable("
|
||||
"child2)\n");
|
||||
}
|
||||
{
|
||||
gd::String str;
|
||||
TestVariableParserCallbacks callbacks(str);
|
||||
gd::VariableParser parser("myVar[ToString(i) + \"é\"].child");
|
||||
parser.Parse(callbacks);
|
||||
|
||||
REQUIRE(str ==
|
||||
"OnRootVariable(myVar)\nOnChildSubscript(ToString(i) + "
|
||||
"\"é\")\nOnChildVariable(child)\n");
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,6 +1,8 @@
|
||||
#Clone SFML from its official directory using Git
|
||||
# Clone SFML from its official directory using Git. Only
|
||||
# do it if not already cloned to avoid triggering a whole
|
||||
# recompilation every time CMake is run.
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
if(GIT_FOUND AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/SFML/readme.txt")
|
||||
message( "Cloning SFML in ExtLibs/SFML with Git..." )
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} clone "https://www.github.com/SFML/SFML.git" SFML
|
||||
@@ -11,7 +13,7 @@ if(GIT_FOUND)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} reset --hard 2.4.1
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/SFML
|
||||
OUTPUT_QUIET)
|
||||
OUTPUT_QUIET)
|
||||
|
||||
message( "Applying the patches..." )
|
||||
file(GLOB SFML_PATCHES
|
||||
|
@@ -24,7 +24,7 @@ gdjs.AnchorRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.AnchorRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "AnchorBehavior::AnchorBehavior";
|
||||
gdjs.registerBehavior("AnchorBehavior::AnchorBehavior", gdjs.AnchorRuntimeBehavior);
|
||||
|
||||
gdjs.AnchorRuntimeBehavior.HorizontalAnchor = {
|
||||
NONE: 0,
|
||||
|
@@ -85,7 +85,8 @@ module.exports = {
|
||||
objectProperties.set(
|
||||
'fontFamily',
|
||||
new gd.PropertyDescriptor(objectContent.fontFamily)
|
||||
.setType('string')
|
||||
.setType('resource')
|
||||
.addExtraInfo('font')
|
||||
.setLabel(_('Base font family'))
|
||||
);
|
||||
|
||||
@@ -515,11 +516,25 @@ module.exports = {
|
||||
.getValue();
|
||||
this._pixiObject.textStyles.default.fontSize = `${fontSize}px`;
|
||||
|
||||
const fontFamily = this._associatedObject
|
||||
const fontResourceName = this._associatedObject
|
||||
.getProperties(this.project)
|
||||
.get('fontFamily')
|
||||
.getValue();
|
||||
this._pixiObject.textStyles.default.fontFamily = fontFamily;
|
||||
|
||||
if (this._fontResourceName !== fontResourceName) {
|
||||
this._fontResourceName = fontResourceName;
|
||||
|
||||
this._pixiResourcesLoader
|
||||
.loadFontFamily(this._project, fontResourceName)
|
||||
.then(fontFamily => {
|
||||
// Once the font is loaded, we can use the given fontFamily.
|
||||
this._pixiObject.textStyles.default.fontFamily = fontFamily;
|
||||
})
|
||||
.catch(err => {
|
||||
// Ignore errors
|
||||
console.warn('Unable to load font family', err);
|
||||
});
|
||||
}
|
||||
|
||||
const wordWrap = this._associatedObject
|
||||
.getProperties(this.project)
|
||||
|
@@ -13,7 +13,10 @@ gdjs.BBTextRuntimeObjectPixiRenderer = function(runtimeObject, runtimeScene) {
|
||||
if (this._pixiObject === undefined) {
|
||||
this._pixiObject = new MultiStyleText(runtimeObject._text, {
|
||||
default: {
|
||||
fontFamily: runtimeObject._fontFamily,
|
||||
fontFamily: runtimeScene
|
||||
.getGame()
|
||||
.getFontManager()
|
||||
.getFontFamily(runtimeObject._fontFamily),
|
||||
fontSize: runtimeObject._fontSize + 'px',
|
||||
fill: runtimeObject._color,
|
||||
tagStyle: 'bbcode',
|
||||
|
@@ -56,7 +56,7 @@ gdjs.BBTextRuntimeObject = function(runtimeScene, objectData) {
|
||||
gdjs.BBTextRuntimeObject.prototype = Object.create(
|
||||
gdjs.RuntimeObject.prototype
|
||||
);
|
||||
gdjs.BBTextRuntimeObject.thisIsARuntimeObjectConstructor = 'BBText::BBText';
|
||||
gdjs.registerObject('BBText::BBText', gdjs.BBTextRuntimeObject);
|
||||
|
||||
gdjs.BBTextRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -50,13 +50,18 @@ function(gd_add_extension_target target_name source_files)
|
||||
IF(target_name STREQUAL "")
|
||||
MESSAGE(ERROR "You called gd_add_extension_target without specifying a target name")
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(platform_directory ${ARGV2})
|
||||
IF(NOT platform_directory)
|
||||
SET(platform_directory "CppPlatform")
|
||||
ENDIF()
|
||||
|
||||
add_library(${target_name} SHARED ${source_files})
|
||||
IF(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(${target_name} STATIC ${source_files})
|
||||
ELSE()
|
||||
add_library(${target_name} SHARED ${source_files})
|
||||
ENDIF()
|
||||
set_target_properties(${target_name} PROPERTIES PREFIX "")
|
||||
set_target_properties(${target_name} PROPERTIES COMPILE_DEFINITIONS "${${target_name}_extra_definitions}")
|
||||
set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/${platform_directory}/Extensions")
|
||||
|
@@ -18,7 +18,7 @@ gdjs.DestroyOutsideRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.DestroyOutsideRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "DestroyOutsideBehavior::DestroyOutside";
|
||||
gdjs.registerBehavior("DestroyOutsideBehavior::DestroyOutside", gdjs.DestroyOutsideRuntimeBehavior);
|
||||
|
||||
gdjs.DestroyOutsideRuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
|
||||
|
@@ -23,7 +23,7 @@ gdjs.DraggableRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.DraggableRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "DraggableBehavior::Draggable";
|
||||
gdjs.registerBehavior("DraggableBehavior::Draggable", gdjs.DraggableRuntimeBehavior);
|
||||
|
||||
gdjs.DraggableRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
this._endDrag();
|
||||
|
@@ -20,7 +20,7 @@ gdjs.DummyRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.DummyRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.DummyRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "MyDummyExtension::DummyBehavior";
|
||||
gdjs.registerBehavior("MyDummyExtension::DummyBehavior", gdjs.DummyRuntimeBehavior);
|
||||
|
||||
gdjs.DummyRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
};
|
||||
|
@@ -22,8 +22,7 @@ gdjs.DummyRuntimeObject = function(runtimeScene, objectData) {
|
||||
};
|
||||
|
||||
gdjs.DummyRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.DummyRuntimeObject.thisIsARuntimeObjectConstructor =
|
||||
"MyDummyExtension::DummyObject"; //Replace by your extension + object name.
|
||||
gdjs.registerObject("MyDummyExtension::DummyObject", gdjs.DummyRuntimeObject); //Replace by your extension + object name.
|
||||
|
||||
gdjs.DummyRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -21,7 +21,7 @@ gdjs.DummyWithSharedDataRuntimeBehavior = function(runtimeScene, behaviorData, o
|
||||
};
|
||||
|
||||
gdjs.DummyWithSharedDataRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.DummyWithSharedDataRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "MyDummyExtension::DummyBehaviorWithSharedData";
|
||||
gdjs.registerBehavior("MyDummyExtension::DummyBehaviorWithSharedData", gdjs.DummyRuntimeBehavior);
|
||||
|
||||
gdjs.DummyWithSharedDataRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
};
|
||||
|
@@ -78,8 +78,7 @@ gdjs.PanelSpriteRuntimeObject = function(runtimeScene, panelSpriteObjectData) {
|
||||
gdjs.PanelSpriteRuntimeObject.prototype = Object.create(
|
||||
gdjs.RuntimeObject.prototype
|
||||
);
|
||||
gdjs.PanelSpriteRuntimeObject.thisIsARuntimeObjectConstructor =
|
||||
'PanelSpriteObject::PanelSprite';
|
||||
gdjs.registerObject("PanelSpriteObject::PanelSprite", gdjs.PanelSpriteRuntimeObject);
|
||||
|
||||
gdjs.PanelSpriteRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -164,7 +164,7 @@ gdjs.ParticleEmitterObject = function(runtimeScene, particleObjectData){
|
||||
this.onCreated();
|
||||
};
|
||||
gdjs.ParticleEmitterObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.ParticleEmitterObject.thisIsARuntimeObjectConstructor = "ParticleSystem::ParticleEmitter";
|
||||
gdjs.registerObject("ParticleSystem::ParticleEmitter", gdjs.ParticleEmitterObject);
|
||||
|
||||
gdjs.ParticleEmitterObject.prototype.setX = function(x){
|
||||
if(this.x !== x) this._posDirty = true;
|
||||
|
@@ -102,7 +102,7 @@ gdjs.PathfindingObstacleRuntimeBehavior = function(runtimeScene, behaviorData, o
|
||||
};
|
||||
|
||||
gdjs.PathfindingObstacleRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.PathfindingObstacleRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PathfindingBehavior::PathfindingObstacleBehavior";
|
||||
gdjs.registerBehavior("PathfindingBehavior::PathfindingObstacleBehavior", gdjs.PathfindingObstacleRuntimeBehavior);
|
||||
|
||||
gdjs.PathfindingObstacleRuntimeBehavior.prototype.onDestroy = function() {
|
||||
if ( this._manager && this._registeredInManager ) this._manager.removeObstacle(this);
|
||||
|
@@ -46,7 +46,7 @@ gdjs.PathfindingRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.PathfindingRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.PathfindingRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PathfindingBehavior::PathfindingBehavior";
|
||||
gdjs.registerBehavior("PathfindingBehavior::PathfindingBehavior", gdjs.PathfindingRuntimeBehavior);
|
||||
|
||||
gdjs.PathfindingRuntimeBehavior.prototype.setCellWidth = function(width) {
|
||||
this._cellWidth = width;
|
||||
|
@@ -238,8 +238,7 @@ gdjs.Physics2RuntimeBehavior = function(runtimeScene, behaviorData, owner) {
|
||||
gdjs.Physics2RuntimeBehavior.prototype = Object.create(
|
||||
gdjs.RuntimeBehavior.prototype
|
||||
);
|
||||
gdjs.Physics2RuntimeBehavior.thisIsARuntimeBehaviorConstructor =
|
||||
'Physics2::Physics2Behavior';
|
||||
gdjs.registerBehavior('Physics2::Physics2Behavior', gdjs.Physics2RuntimeBehavior);
|
||||
|
||||
gdjs.Physics2RuntimeBehavior.prototype.b2Vec2 = function(x, y) {
|
||||
this._tempb2Vec2.set_x(x);
|
||||
|
@@ -145,7 +145,7 @@ gdjs.PhysicsRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.PhysicsRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.PhysicsRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PhysicsBehavior::PhysicsBehavior";
|
||||
gdjs.registerBehavior("PhysicsBehavior::PhysicsBehavior", gdjs.PhysicsRuntimeBehavior);
|
||||
|
||||
gdjs.PhysicsRuntimeBehavior.prototype.onDeActivate = function() {
|
||||
if ( this._box2DBody !== null ) {
|
||||
|
@@ -63,7 +63,7 @@ gdjs.PlatformerObjectRuntimeBehavior = function(runtimeScene, behaviorData, owne
|
||||
};
|
||||
|
||||
gdjs.PlatformerObjectRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.PlatformerObjectRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PlatformBehavior::PlatformerObjectBehavior";
|
||||
gdjs.registerBehavior("PlatformBehavior::PlatformerObjectBehavior", gdjs.PlatformerObjectRuntimeBehavior);
|
||||
|
||||
gdjs.PlatformerObjectRuntimeBehavior.prototype.doStepPreEvents = function(runtimeScene)
|
||||
{
|
||||
|
@@ -100,7 +100,7 @@ gdjs.PlatformRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.PlatformRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.PlatformRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "PlatformBehavior::PlatformBehavior";
|
||||
gdjs.registerBehavior("PlatformBehavior::PlatformBehavior", gdjs.PlatformRuntimeBehavior);
|
||||
|
||||
gdjs.PlatformRuntimeBehavior.LADDER = 2;
|
||||
gdjs.PlatformRuntimeBehavior.JUMPTHRU = 1;
|
||||
|
@@ -64,7 +64,7 @@ gdjs.ShapePainterRuntimeObject = function(runtimeScene, shapePainterObjectData)
|
||||
};
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.ShapePainterRuntimeObject.thisIsARuntimeObjectConstructor = "PrimitiveDrawing::Drawer";
|
||||
gdjs.registerObject("PrimitiveDrawing::Drawer", gdjs.ShapePainterRuntimeObject);
|
||||
|
||||
gdjs.ShapePainterRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -33,7 +33,7 @@ gdjs.SkeletonRuntimeObject = function(runtimeScene, objectData){
|
||||
this.onCreated();
|
||||
};
|
||||
gdjs.SkeletonRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.SkeletonRuntimeObject.thisIsARuntimeObjectConstructor = "SkeletonObject::Skeleton";
|
||||
gdjs.registerObject("SkeletonObject::Skeleton", gdjs.SkeletonRuntimeObject);
|
||||
|
||||
gdjs.SkeletonRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
|
||||
if(initialInstanceData.customSize){
|
||||
|
@@ -33,7 +33,7 @@ gdjs.TextEntryRuntimeObject = function(runtimeScene, textEntryObjectData)
|
||||
};
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.TextEntryRuntimeObject.thisIsARuntimeObjectConstructor = "TextEntryObject::TextEntry";
|
||||
gdjs.registerObject("TextEntryObject::TextEntry", gdjs.TextEntryRuntimeObject);
|
||||
|
||||
gdjs.TextEntryRuntimeObject.prototype.onDestroyFromScene = function(runtimeScene) {
|
||||
gdjs.RuntimeObject.prototype.onDestroyFromScene.call(this, runtimeScene);
|
||||
|
@@ -115,7 +115,7 @@ gdjs.TextRuntimeObject = function(runtimeScene, textObjectData)
|
||||
};
|
||||
|
||||
gdjs.TextRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.TextRuntimeObject.thisIsARuntimeObjectConstructor = "TextObject::Text";
|
||||
gdjs.registerObject("TextObject::Text", gdjs.TextRuntimeObject);
|
||||
|
||||
gdjs.TextRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -41,7 +41,7 @@ gdjs.TiledSpriteRuntimeObject = function(runtimeScene, tiledSpriteObjectData)
|
||||
};
|
||||
|
||||
gdjs.TiledSpriteRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.TiledSpriteRuntimeObject.thisIsARuntimeObjectConstructor = "TiledSpriteObject::TiledSprite";
|
||||
gdjs.registerObject("TiledSpriteObject::TiledSprite", gdjs.TiledSpriteRuntimeObject);
|
||||
|
||||
gdjs.TiledSpriteRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -36,7 +36,7 @@ gdjs.TopDownMovementRuntimeBehavior = function(runtimeScene, behaviorData, owner
|
||||
};
|
||||
|
||||
gdjs.TopDownMovementRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.TopDownMovementRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "TopDownMovementBehavior::TopDownMovementBehavior";
|
||||
gdjs.registerBehavior("TopDownMovementBehavior::TopDownMovementBehavior", gdjs.TopDownMovementRuntimeBehavior);
|
||||
|
||||
gdjs.TopDownMovementRuntimeBehavior.prototype.setAcceleration = function(acceleration) {
|
||||
this._acceleration = acceleration;
|
||||
|
@@ -18,8 +18,7 @@ gdjs.TweenRuntimeBehavior.prototype = Object.create(
|
||||
gdjs.RuntimeBehavior.prototype
|
||||
);
|
||||
|
||||
gdjs.TweenRuntimeBehavior.thisIsARuntimeBehaviorConstructor =
|
||||
"Tween::TweenBehavior";
|
||||
gdjs.registerBehavior("Tween::TweenBehavior", gdjs.TweenRuntimeBehavior);
|
||||
|
||||
gdjs.TweenRuntimeBehavior.easings = [
|
||||
"linear",
|
||||
|
@@ -17,7 +17,7 @@
|
||||
* video will have the same state for this video (paused/playing, current time,
|
||||
* volume, etc...).
|
||||
*
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @class VideoRuntimeObject
|
||||
* @extends RuntimeObject
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to
|
||||
@@ -50,7 +50,7 @@ gdjs.VideoRuntimeObject = function(runtimeScene, videoObjectData) {
|
||||
};
|
||||
|
||||
gdjs.VideoRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.VideoRuntimeObject.thisIsARuntimeObjectConstructor = "Video::VideoObject";
|
||||
gdjs.registerObject("Video::VideoObject", gdjs.VideoRuntimeObject);
|
||||
|
||||
gdjs.VideoRuntimeObject.prototype.getRendererObject = function() {
|
||||
return this._renderer.getRendererObject();
|
||||
|
@@ -6,11 +6,6 @@
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "CppCodeEvent.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
|
@@ -542,7 +542,7 @@ gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(
|
||||
output += codeGenerator.GetCustomCodeOutsideMain() +
|
||||
"\n"
|
||||
"extern \"C\" int GDSceneEvents" +
|
||||
gd::SceneNameMangler::GetMangledSceneName(scene.GetName()) +
|
||||
gd::SceneNameMangler::Get()->GetMangledSceneName(scene.GetName()) +
|
||||
"(RuntimeContext * runtimeContext)\n"
|
||||
"{\n" +
|
||||
"runtimeContext->StartNewFrame();\n" + wholeEventsCode +
|
||||
|
@@ -5,9 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "GDCpp/Extensions/Builtin/VariablesExtension.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCpp/Runtime/CommonTools.h"
|
||||
#include "GDCpp/Runtime/Project/Layout.h"
|
||||
|
@@ -191,7 +191,7 @@ int main( int argc, char *p_argv[] )
|
||||
sceneStack.OnLoadScene([&codeLibraryName](RuntimeScene & scene) {
|
||||
if (!codeLibraryName.empty() &&
|
||||
!scene.GetCodeExecutionEngine()->LoadFromDynamicLibrary(codeLibraryName,
|
||||
"GDSceneEvents"+gd::SceneNameMangler::GetMangledSceneName(scene.GetName())))
|
||||
"GDSceneEvents"+gd::SceneNameMangler::Get()->GetMangledSceneName(scene.GetName())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -50,11 +50,13 @@ list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDJS/IDE/Di
|
||||
list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDJS/IDE/mongoose/mongoose.c" "${CMAKE_CURRENT_SOURCE_DIR}/GDJS/IDE/mongoose/mongoose.h")
|
||||
gd_add_clang_utils(GDJS "${formatted_source_files}")
|
||||
|
||||
add_library(
|
||||
GDJS
|
||||
SHARED
|
||||
${source_files}
|
||||
)
|
||||
|
||||
IF(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(GDJS STATIC ${source_files})
|
||||
ELSE()
|
||||
add_library(GDJS SHARED ${source_files})
|
||||
ENDIF()
|
||||
IF(EMSCRIPTEN)
|
||||
set_target_properties(GDJS PROPERTIES SUFFIX ".bc")
|
||||
ELSEIF(WIN32)
|
||||
@@ -75,21 +77,3 @@ ELSE()
|
||||
target_link_libraries(GDJS GDCore)
|
||||
target_link_libraries(GDJS ${sfml_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
#Post build tasks
|
||||
###
|
||||
IF(EMSCRIPTEN)
|
||||
#Nothing.
|
||||
ELSE()
|
||||
IF(WIN32)
|
||||
add_custom_target(GDJS_Runtime
|
||||
ALL
|
||||
COMMAND "${GD_base_dir}/GDJS/scripts/CopyRuntimeToGD.bat" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
|
||||
WORKING_DIRECTORY ${GD_base_dir}/GDJS/scripts)
|
||||
ELSE()
|
||||
add_custom_target(GDJS_Runtime
|
||||
ALL
|
||||
COMMAND bash "CopyRuntimeToGD.sh" ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}/JsPlatform/Runtime
|
||||
WORKING_DIRECTORY ${GD_base_dir}/GDJS/scripts)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
@@ -4,12 +4,7 @@
|
||||
*/
|
||||
|
||||
#include "JsCodeEvent.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
|
@@ -105,7 +105,7 @@ CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME = function(runtimeScene, behaviorData,
|
||||
};
|
||||
|
||||
CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME.thisIsARuntimeBehaviorConstructor = "EXTENSION_NAME::BEHAVIOR_NAME";
|
||||
gdjs.registerBehavior("EXTENSION_NAME::BEHAVIOR_NAME", CODE_NAMESPACE.RUNTIME_BEHAVIOR_CLASSNAME);
|
||||
|
||||
// Properties:
|
||||
PROPERTIES_CODE
|
||||
|
@@ -97,7 +97,7 @@ gd::String EventsCodeGenerator::GenerateSceneEventsCompleteCode(
|
||||
|
||||
// Export the symbols to avoid them being stripped by the Closure Compiler:
|
||||
output += "gdjs['" +
|
||||
gd::SceneNameMangler::GetMangledSceneName(scene.GetName()) +
|
||||
gd::SceneNameMangler::Get()->GetMangledSceneName(scene.GetName()) +
|
||||
"Code']" + " = " + codeGenerator.GetCodeNamespace() + ";\n";
|
||||
|
||||
includeFiles.insert(codeGenerator.GetIncludeFiles().begin(),
|
||||
@@ -1057,7 +1057,7 @@ gd::String EventsCodeGenerator::GenerateBooleanFullName(
|
||||
gd::String EventsCodeGenerator::GetCodeNamespace() {
|
||||
if (HasProjectAndLayout()) {
|
||||
return "gdjs." +
|
||||
gd::SceneNameMangler::GetMangledSceneName(GetLayout().GetName()) +
|
||||
gd::SceneNameMangler::Get()->GetMangledSceneName(GetLayout().GetName()) +
|
||||
"Code";
|
||||
} else if (!codeNamespace.empty()) {
|
||||
return codeNamespace;
|
||||
|
@@ -5,9 +5,6 @@
|
||||
*/
|
||||
#include "JoystickExtension.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
@@ -4,11 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "KeyboardExtension.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
|
@@ -4,10 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "MathematicalToolsExtension.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
@@ -4,10 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "MouseExtension.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
@@ -4,10 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "TimeExtension.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
@@ -296,7 +296,7 @@ bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
|
||||
gd::String jsonVersion =
|
||||
gd::Serializer::ToJSON(gd::SerializerElement(project.GetVersion()));
|
||||
gd::String jsonMangledName = gd::Serializer::ToJSON(gd::SerializerElement(
|
||||
gd::SceneNameMangler::GetMangledSceneName(project.GetName())
|
||||
gd::SceneNameMangler::Get()->GetMangledSceneName(project.GetName())
|
||||
.LowerCase()
|
||||
.FindAndReplace(" ", "-")));
|
||||
|
||||
@@ -421,7 +421,7 @@ bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
|
||||
gd::String jsonVersion =
|
||||
gd::Serializer::ToJSON(gd::SerializerElement(project.GetVersion()));
|
||||
gd::String jsonMangledName = gd::Serializer::ToJSON(gd::SerializerElement(
|
||||
gd::SceneNameMangler::GetMangledSceneName(project.GetName())
|
||||
gd::SceneNameMangler::Get()->GetMangledSceneName(project.GetName())
|
||||
.LowerCase()
|
||||
.FindAndReplace(" ", "-")));
|
||||
|
||||
|
@@ -23,8 +23,6 @@ cc.game.onStart = function(){
|
||||
if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
|
||||
document.body.removeChild(document.getElementById("cocosLoading"));
|
||||
|
||||
gdjs.registerObjects();
|
||||
gdjs.registerBehaviors();
|
||||
gdjs.registerGlobalCallbacks();
|
||||
|
||||
var game = new gdjs.RuntimeGame(gdjs.projectData, {});
|
||||
|
@@ -20,8 +20,6 @@
|
||||
navigator.splashscreen.hide();
|
||||
|
||||
//Initialization
|
||||
gdjs.registerObjects();
|
||||
gdjs.registerBehaviors();
|
||||
gdjs.registerGlobalCallbacks();
|
||||
|
||||
var game = new gdjs.RuntimeGame(gdjs.projectData, {}/*GDJS_ADDITIONAL_SPEC*/);
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
/* GDJS_CUSTOM_STYLE */
|
||||
</style>
|
||||
|
||||
|
||||
<!-- Facebook Instant Games SDK (see https://developers.facebook.com/docs/games/instant-games/getting-started/quickstart) -->
|
||||
<script src="https://connect.facebook.net/en_US/fbinstant.6.0.js"></script>
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
|
||||
(function() {
|
||||
//Initialization
|
||||
gdjs.registerObjects();
|
||||
gdjs.registerBehaviors();
|
||||
gdjs.registerGlobalCallbacks();
|
||||
|
||||
var game = new gdjs.RuntimeGame(gdjs.projectData, {}/*GDJS_ADDITIONAL_SPEC*/);
|
||||
@@ -54,7 +52,7 @@
|
||||
game.getRenderer().bindStandardEvents(game.getInputManager(), window, document);
|
||||
|
||||
FBInstant.initializeAsync()
|
||||
.then(function() {
|
||||
.then(function() {
|
||||
//Load all assets and start the game
|
||||
game.loadAllAssets(function() {
|
||||
FBInstant.startGameAsync()
|
||||
|
@@ -15,7 +15,7 @@ window.gdjs = {
|
||||
* Contains functions used by events (this is a convention only, functions can actually
|
||||
* by anywhere).
|
||||
* @namespace
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
*/
|
||||
evtTools: {},
|
||||
callbacksRuntimeSceneLoaded: [],
|
||||
@@ -91,73 +91,37 @@ gdjs.toDegrees = function(angleInRadians) {
|
||||
return (angleInRadians * 180) / 3.14159;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Register the runtime objects that can be used in runtimeScene.<br>
|
||||
* Objects must be part of gdjs and have their property "thisIsARuntimeObjectConstructor"
|
||||
* defined and set to the name of the type of the object so as to be recognized.
|
||||
* Register a runtime object (class extending {@link gdjs.RuntimeObject}) that can be used in a scene.
|
||||
*
|
||||
* The name of the type of the object must be complete, with the namespace if any. For
|
||||
* example, if you are providing a Text object in the TextObject extension, the full name
|
||||
* of the type of the object is "TextObject::Text".
|
||||
*
|
||||
* @param {string} objectTypeName The name of the type of the Object.
|
||||
* @param Ctor The constructor of the Object.
|
||||
*/
|
||||
gdjs.registerObjects = function() {
|
||||
gdjs.objectsTypes.clear();
|
||||
|
||||
for (var p in this) {
|
||||
if (this.hasOwnProperty(p)) {
|
||||
if (gdjs[p].thisIsARuntimeObjectConstructor != undefined) {
|
||||
gdjs.objectsTypes.put(gdjs[p].thisIsARuntimeObjectConstructor, gdjs[p]);
|
||||
}
|
||||
}
|
||||
}
|
||||
gdjs.registerObject = function(objectTypeName, Ctor){
|
||||
gdjs.objectsTypes.put(objectTypeName, Ctor)
|
||||
};
|
||||
|
||||
/**
|
||||
* Register the runtime behaviors that can be used bt runtimeObject.
|
||||
*
|
||||
* Behavior must be a property on gdjs (or on a inner object, but not on any object nested below)
|
||||
* and have a property "thisIsARuntimeBehaviorConstructor" defined and set
|
||||
* to the type of the behavior to be recognized.
|
||||
* Register a runtime behavior (class extending {@link gdjs.RuntimeBehavior}) that can be used by a
|
||||
* {@link gdjs.RuntimeObject}.
|
||||
*
|
||||
* The type of the behavior must be complete, with the namespace of the extension. For
|
||||
* example, if you are providing a Draggable behavior in the DraggableBehavior extension,
|
||||
* the full name of the type of the behavior is "DraggableBehavior::Draggable".
|
||||
*
|
||||
* @param {string} behaviorTypeName The name of the type of the behavior.
|
||||
* @param Ctor The constructor of the Object.
|
||||
*/
|
||||
gdjs.registerBehaviors = function() {
|
||||
gdjs.behaviorsTypes.clear();
|
||||
|
||||
for (var gdjsProperty in this) {
|
||||
if (this.hasOwnProperty(gdjsProperty)) {
|
||||
// Search in object inside gdjs.
|
||||
var innerObject = gdjs[gdjsProperty];
|
||||
if (innerObject.thisIsARuntimeBehaviorConstructor != undefined) {
|
||||
gdjs.behaviorsTypes.put(
|
||||
innerObject.thisIsARuntimeBehaviorConstructor,
|
||||
innerObject
|
||||
);
|
||||
} else if (
|
||||
Object.prototype.toString.call(innerObject) !== '[object Array]' &&
|
||||
typeof innerObject === 'object' &&
|
||||
innerObject !== null
|
||||
) {
|
||||
// Also search inside objects contained in gdjs.
|
||||
for (var innerObjectProperty in innerObject) {
|
||||
if (innerObject.hasOwnProperty(innerObjectProperty)) {
|
||||
var innerInnerObject = innerObject[innerObjectProperty];
|
||||
if (
|
||||
innerInnerObject !== null &&
|
||||
typeof innerInnerObject === 'function' &&
|
||||
innerInnerObject.thisIsARuntimeBehaviorConstructor != undefined
|
||||
) {
|
||||
gdjs.behaviorsTypes.put(
|
||||
innerInnerObject.thisIsARuntimeBehaviorConstructor,
|
||||
innerInnerObject
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gdjs.registerBehavior = function(behaviorTypeName, Ctor){
|
||||
gdjs.behaviorsTypes.put(
|
||||
behaviorTypeName,
|
||||
Ctor
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -225,7 +189,7 @@ gdjs.registerGlobalCallbacks = function() {
|
||||
/**
|
||||
* Get the constructor of an object.
|
||||
*
|
||||
* @param name {String} The name of the type of the object.
|
||||
* @param {string} name The name of the type of the object.
|
||||
*/
|
||||
gdjs.getObjectConstructor = function(name) {
|
||||
if (name !== undefined && gdjs.objectsTypes.containsKey(name))
|
||||
@@ -238,7 +202,7 @@ gdjs.getObjectConstructor = function(name) {
|
||||
/**
|
||||
* Get the constructor of a behavior.
|
||||
*
|
||||
* @param name {String} The name of the type of the behavior.
|
||||
* @param {string} name The name of the type of the behavior.
|
||||
*/
|
||||
gdjs.getBehaviorConstructor = function(name) {
|
||||
if (name !== undefined && gdjs.behaviorsTypes.containsKey(name))
|
||||
|
@@ -35,8 +35,6 @@
|
||||
|
||||
(function() {
|
||||
//Initialization
|
||||
gdjs.registerObjects();
|
||||
gdjs.registerBehaviors();
|
||||
gdjs.registerGlobalCallbacks();
|
||||
|
||||
var game = new gdjs.RuntimeGame(gdjs.projectData, {}/*GDJS_ADDITIONAL_SPEC*/);
|
||||
|
@@ -144,7 +144,6 @@ gdjs.RuntimeBehavior.prototype.doStepPostEvents = function(runtimeScene) {
|
||||
*/
|
||||
gdjs.RuntimeBehavior.prototype.onDestroy = function() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
//Notify gdjs this.the runtimeBehavior exists.
|
||||
gdjs.RuntimeBehavior.thisIsARuntimeBehaviorConstructor = "";
|
||||
gdjs.registerBehavior("", gdjs.RuntimeBehavior);
|
||||
|
@@ -33,8 +33,7 @@
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The {@link gdjs.RuntimeScene} the object belongs to.
|
||||
* @param {ObjectData} objectData The initial properties of the object.
|
||||
*/
|
||||
gdjs.RuntimeObject = function(runtimeScene, objectData)
|
||||
{
|
||||
gdjs.RuntimeObject = function(runtimeScene, objectData) {
|
||||
this.name = objectData.name || "";
|
||||
this._nameId = gdjs.RuntimeObject.getNameIdentifier(this.name);
|
||||
this.type = objectData.type || "";
|
||||
@@ -1488,5 +1487,4 @@ gdjs.RuntimeObject.getNameIdentifier = function(name) {
|
||||
return newIdentifier;
|
||||
};
|
||||
|
||||
//Notify gdjs the RuntimeObject exists.
|
||||
gdjs.RuntimeObject.thisIsARuntimeObjectConstructor = "";
|
||||
gdjs.registerObject("", gdjs.RuntimeObject);
|
||||
|
@@ -5,53 +5,53 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Point Represents a point in a frame
|
||||
* @property {number} x X position of the point
|
||||
* @property {number} y Y position of the point
|
||||
* @typedef {Object} SpritePoint Represents a point in a coordinate system.
|
||||
* @property {number} x X position of the point.
|
||||
* @property {number} y Y position of the point.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CustomPointData Represents a custom point in a frame
|
||||
* @property {string} name Name of the point
|
||||
* @property {number} x X position of the point
|
||||
* @property {number} y Y position of the point
|
||||
* @typedef {Object} SpriteCustomPointData Represents a custom point in a frame.
|
||||
* @property {string} name Name of the point.
|
||||
* @property {number} x X position of the point.
|
||||
* @property {number} y Y position of the point.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} CenterPointData Represents the center point in a frame
|
||||
* @typedef {Object} SpriteCenterPointData Represents the center point in a frame.
|
||||
* @property {boolean} automatic Is the center automatically computed?
|
||||
* @property {number} x X position of the point
|
||||
* @property {number} y Y position of the point
|
||||
* @property {number} x X position of the point.
|
||||
* @property {number} y Y position of the point.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FrameData Represents a {@link gdjs.SpriteAnimationFrame}
|
||||
* @property {string} [image] The resource name of the image used in this frame
|
||||
* @property {Array<customPointData>} [points] The points of the frame
|
||||
* @property {point} originPoint The origin point
|
||||
* @property {centerPointData} centerPoint The center of the frame
|
||||
* @typedef {Object} SpriteFrameData Represents a {@link gdjs.SpriteAnimationFrame}.
|
||||
* @property {string} [image] The resource name of the image used in this frame.
|
||||
* @property {Array<SpriteCustomPointData>} [points] The points of the frame.
|
||||
* @property {SpritePoint} originPoint The origin point.
|
||||
* @property {SpriteCenterPointData} centerPoint The center of the frame.
|
||||
* @property {boolean} hasCustomCollisionMask Is The collision mask custom?
|
||||
* @property {Array<Array<point>>} [customCollisionMask] The collision mask if it is custom
|
||||
* @property {Array<Array<SpritePoint>>} [customCollisionMask] The collision mask if it is custom.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} DirectionData Represents the data of a {@link gdjs.SpriteAnimationDirection}
|
||||
* @property {number} timeBetweenFrames Time between each frame, in seconds
|
||||
* @typedef {Object} SpriteDirectionData Represents the data of a {@link gdjs.SpriteAnimationDirection}.
|
||||
* @property {number} timeBetweenFrames Time between each frame, in seconds.
|
||||
* @property {boolean} looping Is the animation looping?
|
||||
* @property {Array<gdjs.SpriteAnimationFrame>} sprites The list of frames
|
||||
* @property {Array<SpriteFrameData>} sprites The list of frames.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} AnimationData Represents the data of a {@link gdjs.SpriteAnimation}
|
||||
* @property {string} [name] The name of the animation
|
||||
* @typedef {Object} SpriteAnimationData Represents the data of a {@link gdjs.SpriteAnimation}.
|
||||
* @property {string} [name] The name of the animation.
|
||||
* @property {boolean} useMultipleDirections Does the animation use multiple {@link gdjs.SpriteAnimationDirection}?
|
||||
* @property {Array<DirectionData>} directions The list of {@link DirectionData} representing {@link gdjs.SpriteAnimationDirection} instances
|
||||
* @property {Array<SpriteDirectionData>} directions The list of {@link SpriteDirectionData} representing {@link gdjs.SpriteAnimationDirection} instances.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} SpriteObjectDataType
|
||||
* @property {boolean} updateIfNotVisible Update the object even if he is not visible?
|
||||
* @property {Array<AnimationData>} animations The list of {@link AnimationData} representing {@link gdjs.SpriteAnimation} instances
|
||||
* @typedef {Object} SpriteObjectDataType Represents the data of a {@link gdjs.SpriteRuntimeObject}.
|
||||
* @property {boolean} updateIfNotVisible Update the object even if he is not visible?.
|
||||
* @property {Array<SpriteAnimationData>} animations The list of {@link SpriteAnimationData} representing {@link gdjs.SpriteAnimation} instances.
|
||||
*
|
||||
* @typedef {ObjectData & SpriteObjectDataType} SpriteObjectData
|
||||
*/
|
||||
@@ -62,27 +62,26 @@
|
||||
* It contains the texture displayed as well as information like the points position
|
||||
* or the collision mask.
|
||||
*
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @class SpriteAnimationFrame
|
||||
* @param {gdjs.ImageManager} imageManager The game image manager
|
||||
* @param {FrameData} frameData The frame data used to initialize the frame
|
||||
* @param {SpriteFrameData} frameData The frame data used to initialize the frame
|
||||
*/
|
||||
|
||||
gdjs.SpriteAnimationFrame = function(imageManager, frameData)
|
||||
{
|
||||
/** @type {string} */
|
||||
this.image = frameData ? frameData.image : ""; //TODO: Rename in imageName, and do not store it in the object?
|
||||
/** @type {PIXI.Texture} */
|
||||
this.texture = gdjs.SpriteRuntimeObjectRenderer.getAnimationFrame(imageManager, this.image);
|
||||
|
||||
if ( this.center === undefined ) {
|
||||
/** @type {Point} */
|
||||
/** @type {SpritePoint} */
|
||||
this.center = { x:0, y:0 };
|
||||
};
|
||||
}
|
||||
if ( this.origin === undefined ) {
|
||||
/** @type {Point} */
|
||||
/** @type {SpritePoint} */
|
||||
this.origin = { x:0, y:0 }
|
||||
};
|
||||
}
|
||||
/** @type {boolean} */
|
||||
this.hasCustomHitBoxes = false;
|
||||
if ( this.customHitBoxes === undefined ) {
|
||||
@@ -96,23 +95,23 @@ gdjs.SpriteAnimationFrame = function(imageManager, frameData)
|
||||
|
||||
//Initialize points:
|
||||
for(var i = 0, len = frameData.points.length;i<len;++i) {
|
||||
/** @type {CustomPointData} */
|
||||
/** @type {SpriteCustomPointData} */
|
||||
var ptData = frameData.points[i];
|
||||
|
||||
/** @type {Point} */
|
||||
var point = {x:parseFloat(ptData.x), y:parseFloat(ptData.y)};
|
||||
/** @type {SpritePoint} */
|
||||
var point = {x: ptData.x, y: ptData.y};
|
||||
this.points.put(ptData.name, point);
|
||||
}
|
||||
/** @type {Point} */
|
||||
/** @type {SpritePoint} */
|
||||
var origin = frameData.originPoint;
|
||||
this.origin.x = parseFloat(origin.x);
|
||||
this.origin.y = parseFloat(origin.y);
|
||||
this.origin.x = origin.x;
|
||||
this.origin.y = origin.y;
|
||||
|
||||
/** @type {CenterPointData} */
|
||||
/** @type {SpriteCenterPointData} */
|
||||
var center = frameData.centerPoint;
|
||||
if ( center.automatic !== true ) {
|
||||
this.center.x = parseFloat(center.x);
|
||||
this.center.y = parseFloat(center.y);
|
||||
this.center.x = center.x;
|
||||
this.center.y = center.y;
|
||||
}
|
||||
else {
|
||||
this.center.x = gdjs.SpriteRuntimeObjectRenderer.getAnimationFrameWidth(this.texture)/2;
|
||||
@@ -123,22 +122,22 @@ gdjs.SpriteAnimationFrame = function(imageManager, frameData)
|
||||
if ( frameData.hasCustomCollisionMask ) {
|
||||
this.hasCustomHitBoxes = true;
|
||||
for(var i = 0, len = frameData.customCollisionMask.length;i<len;++i) {
|
||||
/** @type {Array<Point>} */
|
||||
/** @type {Array<SpritePoint>} */
|
||||
var polygonData = frameData.customCollisionMask[i];
|
||||
|
||||
//Add a polygon, if necessary (Avoid recreating a polygon if it already exists).
|
||||
if ( i >= this.customHitBoxes.length ) this.customHitBoxes.push(new gdjs.Polygon());
|
||||
|
||||
for(var j = 0, len2 = polygonData.length;j<len2;++j) {
|
||||
/** @type {Point} */
|
||||
/** @type {SpritePoint} */
|
||||
var pointData = polygonData[j];
|
||||
|
||||
//Add a point, if necessary (Avoid recreating a point if it already exists).
|
||||
if ( j >= this.customHitBoxes[i].vertices.length )
|
||||
this.customHitBoxes[i].vertices.push([0,0]);
|
||||
|
||||
this.customHitBoxes[i].vertices[j][0] = parseFloat(pointData.x, 10);
|
||||
this.customHitBoxes[i].vertices[j][1] = parseFloat(pointData.y, 10);
|
||||
this.customHitBoxes[i].vertices[j][0] = pointData.x;
|
||||
this.customHitBoxes[i].vertices[j][1] = pointData.y;
|
||||
}
|
||||
|
||||
this.customHitBoxes[i].vertices.length = j;
|
||||
@@ -155,11 +154,11 @@ gdjs.SpriteAnimationFrame = function(imageManager, frameData)
|
||||
* Get a point of the frame.<br>
|
||||
* If the point does not exist, the origin is returned.
|
||||
* @param {string} name The point's name
|
||||
* @return {Point} The requested point. If it doesn't exists returns the origin point.
|
||||
* @return {SpritePoint} The requested point. If it doesn't exists returns the origin point.
|
||||
*/
|
||||
gdjs.SpriteAnimationFrame.prototype.getPoint = function(name) {
|
||||
if ( name == "Centre" || name == "Center") return this.center;
|
||||
else if ( name == "Origin" ) return this.origin;
|
||||
if ( name === "Centre" || name === "Center") return this.center;
|
||||
else if ( name === "Origin" ) return this.origin;
|
||||
|
||||
return this.points.containsKey(name) ? this.points.get(name) : this.origin;
|
||||
};
|
||||
@@ -168,14 +167,14 @@ gdjs.SpriteAnimationFrame.prototype.getPoint = function(name) {
|
||||
* Represents a direction of an animation of a {@link gdjs.SpriteRuntimeObject}.
|
||||
*
|
||||
* @class SpriteAnimationDirection
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @param {gdjs.ImageManager} imageManager The game image manager
|
||||
* @param {DirectionData} directionData The direction data used to initialize the direction
|
||||
* @param {SpriteDirectionData} directionData The direction data used to initialize the direction
|
||||
*/
|
||||
gdjs.SpriteAnimationDirection = function(imageManager, directionData)
|
||||
{
|
||||
/** @type {number} */
|
||||
this.timeBetweenFrames = directionData ? parseFloat(directionData.timeBetweenFrames) :
|
||||
this.timeBetweenFrames = directionData ? directionData.timeBetweenFrames :
|
||||
1.0;
|
||||
/** @type {boolean} */
|
||||
this.loop = !!directionData.looping;
|
||||
@@ -185,7 +184,7 @@ gdjs.SpriteAnimationDirection = function(imageManager, directionData)
|
||||
this.frames = [];
|
||||
}
|
||||
for(var i = 0, len = directionData.sprites.length;i<len;++i) {
|
||||
/** @type {frameData} */
|
||||
/** @type {SpriteFrameData} */
|
||||
var frameData = directionData.sprites[i];
|
||||
|
||||
if ( i < this.frames.length )
|
||||
@@ -200,9 +199,9 @@ gdjs.SpriteAnimationDirection = function(imageManager, directionData)
|
||||
* Represents an animation of a {@link SpriteRuntimeObject}.
|
||||
*
|
||||
* @class SpriteAnimation
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @param {gdjs.ImageManager} imageManager The game image manager
|
||||
* @param {AnimationData} animData The animation data used to initialize the animation
|
||||
* @param {SpriteAnimationData} animData The animation data used to initialize the animation
|
||||
*/
|
||||
gdjs.SpriteAnimation = function(imageManager, animData)
|
||||
{
|
||||
@@ -214,7 +213,7 @@ gdjs.SpriteAnimation = function(imageManager, animData)
|
||||
/** @type {Array<gdjs.SpriteAnimationDirection>} */
|
||||
if ( this.directions === undefined ) this.directions = [];
|
||||
for(var i = 0, len = animData.directions.length;i<len;++i) {
|
||||
/** @type {DirectionData} */
|
||||
/** @type {SpriteDirectionData} */
|
||||
var directionData = animData.directions[i];
|
||||
|
||||
if ( i < this.directions.length )
|
||||
@@ -229,7 +228,7 @@ gdjs.SpriteAnimation = function(imageManager, animData)
|
||||
* The SpriteRuntimeObject represents an object that can display images.
|
||||
*
|
||||
* @class SpriteRuntimeObject
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @extends gdjs.RuntimeObject
|
||||
* @param {gdjs.RuntimeScene} runtimeScene The scene the object belongs to
|
||||
* @param {SpriteObjectData} spriteObjectData The object data used to initialize the object
|
||||
@@ -271,7 +270,7 @@ gdjs.SpriteRuntimeObject = function(runtimeScene, spriteObjectData) {
|
||||
this._animations = [];
|
||||
}
|
||||
for(var i = 0, len = spriteObjectData.animations.length;i<len;++i) {
|
||||
/** @type {AnimationData} */
|
||||
/** @type {SpriteAnimationData} */
|
||||
var animData = spriteObjectData.animations[i];
|
||||
|
||||
if ( i < this._animations.length )
|
||||
@@ -304,12 +303,13 @@ gdjs.SpriteRuntimeObject = function(runtimeScene, spriteObjectData) {
|
||||
};
|
||||
|
||||
gdjs.SpriteRuntimeObject.prototype = Object.create( gdjs.RuntimeObject.prototype );
|
||||
gdjs.SpriteRuntimeObject.thisIsARuntimeObjectConstructor = "Sprite"; //Notify gdjs of the object existence.
|
||||
gdjs.registerObject("Sprite", gdjs.SpriteRuntimeObject); //Notify gdjs of the object existence.
|
||||
|
||||
//Others initialization and internal state management :
|
||||
|
||||
/**
|
||||
* Initialize the extra parameters that could be set for an instance.
|
||||
* @param {{numberProperties: Array<{name: string, value: number}>, customSize: {width: number, height: number}}} initialInstanceData The extra parameters
|
||||
*/
|
||||
gdjs.SpriteRuntimeObject.prototype.extraInitializationFromInitialInstance = function(initialInstanceData) {
|
||||
if ( initialInstanceData.numberProperties ) {
|
||||
@@ -585,7 +585,7 @@ gdjs.SpriteRuntimeObject.prototype.hasAnimationEnded = function() {
|
||||
if ( this._animations[this._currentAnimation].loop ) return false;
|
||||
var direction = this._animations[this._currentAnimation].directions[this._currentDirection];
|
||||
|
||||
return this._currentFrame == direction.frames.length-1;
|
||||
return this._currentFrame === direction.frames.length-1;
|
||||
};
|
||||
|
||||
gdjs.SpriteRuntimeObject.prototype.animationPaused = function() {
|
||||
|
@@ -14,7 +14,6 @@
|
||||
"jsdoc-autoprivate": "0.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
"copy-runtime-to-ide": "echo \"Use scripts/CopyRuntimeToGD.sh (or .bat on Windows)\"",
|
||||
"check-types": "tsc"
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
::This script copies the runtimes files (i.e: the javascript files located into the Runtime
|
||||
::folder and in the Extensions folder) to the GDevelop folder.
|
||||
|
||||
@echo off
|
||||
cd /d %~dp0
|
||||
|
||||
set destDir=%1
|
||||
if [%destDir%]==[] set destDir="..\..\Binaries\Output\Release_Windows\JsPlatform\Runtime"
|
||||
|
||||
echo Copying GDJS and extensions runtime files (*.js) to %destDir%...
|
||||
xcopy "..\Runtime"\* %destDir%\* /S /E /D /Y /Q
|
||||
xcopy "..\..\Extensions"\*.js %destDir%\Extensions\*.js /S /E /D /Y /Q /EXCLUDE:FilesExcludedFromCopy
|
||||
|
||||
echo ✅ Copied GDJS and extensions runtime files (*.js) to %destDir%.
|
@@ -1,18 +0,0 @@
|
||||
#!/bin/bash
|
||||
#Get the destination, or copy by default to release directory
|
||||
DESTINATION=../../Binaries/Output/Release_Linux/JsPlatform/Runtime/
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
DESTINATION=../../Binaries/Output/Release_Darwin/JsPlatform/Runtime/
|
||||
fi
|
||||
if [ ! $# -eq 0 ]; then
|
||||
DESTINATION=$1
|
||||
fi
|
||||
|
||||
#Copy all js files
|
||||
echo "ℹ️ Copying GDJS and extensions runtime files (*.js) to '$DESTINATION'..."
|
||||
|
||||
mkdir -p "$DESTINATION"
|
||||
cp -R ../Runtime/* "$DESTINATION"
|
||||
rsync -r -u --include=*.js --include=*/ --exclude=* ../../Extensions/ "$DESTINATION"/Extensions/
|
||||
|
||||
echo "✅ Copied GDJS and extensions runtime files (*.js) to '$DESTINATION'."
|
@@ -1,3 +1 @@
|
||||
gdjs.registerObjects();
|
||||
gdjs.registerBehaviors();
|
||||
gdjs.registerGlobalCallbacks();
|
||||
|
@@ -11,7 +11,7 @@ gdjs.TestRuntimeBehavior = function(runtimeScene, behaviorData, owner)
|
||||
};
|
||||
|
||||
gdjs.TestRuntimeBehavior.prototype = Object.create( gdjs.RuntimeBehavior.prototype );
|
||||
gdjs.TestRuntimeBehavior.thisIsARuntimeBehaviorConstructor = "TestBehavior::TestBehavior";
|
||||
gdjs.registerBehavior("TestBehavior::TestBehavior", gdjs.TestRuntimeBehavior);
|
||||
|
||||
gdjs.TestRuntimeBehavior.prototype.onCreated = function() {
|
||||
this.owner.getVariables().get("lastState").setString('created');
|
||||
|
@@ -3,7 +3,7 @@
|
||||
* an example to start a new object, take a look at gdjs.DummyRuntimeObject
|
||||
* in the Extensions folder.
|
||||
*
|
||||
* @memberof gdjs
|
||||
* @memberOf gdjs
|
||||
* @class TestRuntimeObject
|
||||
* @extends RuntimeObject
|
||||
*/
|
||||
@@ -16,8 +16,7 @@ gdjs.TestRuntimeObject = function(runtimeScene, objectData) {
|
||||
};
|
||||
|
||||
gdjs.TestRuntimeObject.prototype = Object.create(gdjs.RuntimeObject.prototype);
|
||||
gdjs.TestRuntimeObject.thisIsARuntimeObjectConstructor =
|
||||
'TestObject::TestObject';
|
||||
gdjs.registerObject('TestObject::TestObject', gdjs.TestRuntimeObject);
|
||||
|
||||
gdjs.TestRuntimeObject.prototype.getRendererObject = function() {
|
||||
return {};
|
||||
|
@@ -65,7 +65,7 @@ bool BehaviorJsImplementation::UpdateProperty(gd::SerializerElement& behaviorCon
|
||||
throw 'updateProperty is not defined on a BehaviorJsImplementation.';
|
||||
|
||||
self['updateProperty'](
|
||||
wrapPointer($1, Module['SerializerElement']), Pointer_stringify($2), Pointer_stringify($3));
|
||||
wrapPointer($1, Module['SerializerElement']), UTF8ToString($2), UTF8ToString($3));
|
||||
},
|
||||
(int)this,
|
||||
(int)&behaviorContent,
|
||||
|
@@ -73,8 +73,8 @@ bool BehaviorSharedDataJsImplementation::UpdateProperty(
|
||||
throw 'updateProperty is not defined on a BehaviorSharedDataJsImplementation.';
|
||||
|
||||
self['updateProperty'](wrapPointer($1, Module['SerializerElement']),
|
||||
Pointer_stringify($2),
|
||||
Pointer_stringify($3));
|
||||
UTF8ToString($2),
|
||||
UTF8ToString($3));
|
||||
},
|
||||
(int)this,
|
||||
(int)&behaviorSharedDataContent,
|
||||
|
@@ -184,7 +184,7 @@ interface VariablesContainer {
|
||||
[Ref] Variable Get([Const] DOMString name);
|
||||
[Ref] Variable GetAt(unsigned long index);
|
||||
[Const, Ref] DOMString GetNameAt(unsigned long index);
|
||||
[Ref] Variable Insert([Const] DOMString name, [Const, Ref] Variable var, unsigned long index);
|
||||
[Ref] Variable Insert([Const] DOMString name, [Const, Ref] Variable variable, unsigned long index);
|
||||
[Ref] Variable InsertNew([Const] DOMString name, unsigned long index);
|
||||
void Remove([Const] DOMString name);
|
||||
boolean Rename([Const] DOMString oldName, [Const] DOMString newName);
|
||||
@@ -1053,6 +1053,7 @@ interface ObjectMetadata {
|
||||
[Const, Ref] DOMString GetFullName();
|
||||
[Const, Ref] DOMString GetDescription();
|
||||
[Const, Ref] DOMString GetIconFilename();
|
||||
[Const, Ref] DOMString GetHelpPath();
|
||||
|
||||
[Const, Ref] InstructionMetadata AddCondition([Const] DOMString name,
|
||||
[Const] DOMString fullname,
|
||||
@@ -1093,6 +1094,7 @@ interface BehaviorMetadata {
|
||||
[Const, Ref] DOMString GetDescription();
|
||||
[Const, Ref] DOMString GetGroup();
|
||||
[Const, Ref] DOMString GetIconFilename();
|
||||
[Const, Ref] DOMString GetHelpPath();
|
||||
|
||||
[Const, Ref] InstructionMetadata AddScopedCondition([Const] DOMString name,
|
||||
[Const] DOMString fullname,
|
||||
@@ -1270,6 +1272,7 @@ interface EventsList {
|
||||
void RemoveEvent([Const, Ref] BaseEvent event);
|
||||
unsigned long GetEventsCount();
|
||||
boolean Contains([Const, Ref] BaseEvent event, boolean recursive);
|
||||
boolean MoveEventToAnotherEventsList([Const, Ref] BaseEvent eventToMove, [Ref] EventsList newEventsList, unsigned long newPosition);
|
||||
boolean IsEmpty();
|
||||
void Clear();
|
||||
|
||||
@@ -1526,7 +1529,7 @@ interface EventsRefactorer {
|
||||
void STATIC_RenameObjectInEvents([Const, Ref] Platform platform, [Ref] ObjectsContainer project, [Ref] ObjectsContainer layout, [Ref] EventsList events, [Const] DOMString oldName, [Const] DOMString newName);
|
||||
void STATIC_RemoveObjectInEvents([Const, Ref] Platform platform, [Ref] ObjectsContainer project, [Ref] ObjectsContainer layout, [Ref] EventsList events, [Const] DOMString name);
|
||||
void STATIC_ReplaceStringInEvents([Ref] ObjectsContainer project, [Ref] ObjectsContainer layout, [Ref] EventsList events, [Const] DOMString toReplace, [Const] DOMString newString, boolean matchCase, boolean inConditions, boolean inActions);
|
||||
[Value] VectorEventsSearchResult STATIC_SearchInEvents([Ref] ObjectsContainer project, [Ref] ObjectsContainer layout, [Ref] EventsList events, [Const] DOMString search, boolean matchCase, boolean inConditions, boolean inActions);
|
||||
[Value] VectorEventsSearchResult STATIC_SearchInEvents([Ref] ObjectsContainer project, [Ref] ObjectsContainer layout, [Ref] EventsList events, [Const] DOMString search, boolean matchCase, boolean inConditions, boolean inActions, boolean inEventStrings);
|
||||
};
|
||||
|
||||
interface WholeProjectRefactorer {
|
||||
@@ -1644,29 +1647,6 @@ interface MetadataProvider {
|
||||
boolean STATIC_HasBehaviorStrExpression([Const, Ref] Platform p, [Const] DOMString autoType, [Const] DOMString type);
|
||||
};
|
||||
|
||||
interface ParserCallbacks {
|
||||
[Const, Ref] DOMString GetFirstError();
|
||||
unsigned long GetFirstErrorPosition();
|
||||
};
|
||||
|
||||
interface ExpressionParser {
|
||||
void ExpressionParser([Const] DOMString expression);
|
||||
|
||||
boolean ParseMathExpression([Const, Ref] Platform platform, [Const, Ref] Project project, [Const, Ref] Layout layout, [Ref] ParserCallbacks callbacks);
|
||||
boolean ParseStringExpression([Const, Ref] Platform platform, [Const, Ref] Project project, [Const, Ref] Layout layout, [Ref] ParserCallbacks callbacks);
|
||||
|
||||
[Const, Ref] DOMString GetFirstError();
|
||||
unsigned long GetFirstErrorPosition();
|
||||
};
|
||||
|
||||
interface CallbacksForExpressionCorrectnessTesting {
|
||||
void CallbacksForExpressionCorrectnessTesting([Const, Ref] Project project, [Const, Ref] Layout layout);
|
||||
|
||||
//Inherited from ParserCallbacks:
|
||||
[Const, Ref] DOMString GetFirstError();
|
||||
unsigned long GetFirstErrorPosition();
|
||||
};
|
||||
|
||||
interface ExpressionParserDiagnostic {
|
||||
boolean IsError();
|
||||
[Const, Ref] DOMString GetMessage();
|
||||
@@ -1704,11 +1684,6 @@ interface ExpressionParser2 {
|
||||
[Value] UniquePtrExpressionNode ParseExpression([Const] DOMString type, [Const] DOMString expression);
|
||||
};
|
||||
|
||||
interface ExpressionCodeGenerator {
|
||||
void STATIC_UseOldExpressionParser(boolean enable);
|
||||
boolean STATIC_IsUsingOldExpressionParser();
|
||||
};
|
||||
|
||||
enum EventsFunction_FunctionType {
|
||||
"EventsFunction::Action",
|
||||
"EventsFunction::Condition",
|
||||
@@ -1807,7 +1782,7 @@ interface NamedPropertyDescriptorsList {
|
||||
interface EventsFunctionsExtension {
|
||||
void EventsFunctionsExtension();
|
||||
|
||||
[Ref] EventsFunctionsExtension SetNamespace([Const] DOMString namespace);
|
||||
[Ref] EventsFunctionsExtension SetNamespace([Const] DOMString namespace_);
|
||||
[Const, Ref] DOMString GetNamespace();
|
||||
[Ref] EventsFunctionsExtension SetVersion([Const] DOMString version);
|
||||
[Const, Ref] DOMString GetVersion();
|
||||
|
@@ -42,7 +42,7 @@ ObjectJsImplementation::GetProperties(gd::Project&) const {
|
||||
if (!self.hasOwnProperty('getProperties'))
|
||||
throw 'getProperties is not defined on a ObjectJsImplementation.';
|
||||
|
||||
var objectContent = JSON.parse(Pointer_stringify($1));
|
||||
var objectContent = JSON.parse(UTF8ToString($1));
|
||||
var newProperties = self['getProperties'](objectContent);
|
||||
if (!newProperties)
|
||||
throw 'getProperties returned nothing in a gd::ObjectJsImplementation.';
|
||||
@@ -64,9 +64,9 @@ bool ObjectJsImplementation::UpdateProperty(const gd::String& arg0,
|
||||
var self = Module['getCache'](Module['ObjectJsImplementation'])[$0];
|
||||
if (!self.hasOwnProperty('updateProperty'))
|
||||
throw 'updateProperty is not defined on a ObjectJsImplementation.';
|
||||
var objectContent = JSON.parse(Pointer_stringify($1));
|
||||
var objectContent = JSON.parse(UTF8ToString($1));
|
||||
self['updateProperty'](
|
||||
objectContent, Pointer_stringify($2), Pointer_stringify($3));
|
||||
objectContent, UTF8ToString($2), UTF8ToString($3));
|
||||
return ensureString(JSON.stringify(objectContent));
|
||||
},
|
||||
(int)this,
|
||||
@@ -91,7 +91,7 @@ ObjectJsImplementation::GetInitialInstanceProperties(
|
||||
if (!self.hasOwnProperty('getInitialInstanceProperties'))
|
||||
throw 'getInitialInstanceProperties is not defined on a ObjectJsImplementation.';
|
||||
|
||||
var objectContent = JSON.parse(Pointer_stringify($1));
|
||||
var objectContent = JSON.parse(UTF8ToString($1));
|
||||
var newProperties = self['getInitialInstanceProperties'](
|
||||
objectContent,
|
||||
wrapPointer($2, Module['InitialInstance']),
|
||||
@@ -124,12 +124,12 @@ bool ObjectJsImplementation::UpdateInitialInstanceProperty(
|
||||
var self = Module['getCache'](Module['ObjectJsImplementation'])[$0];
|
||||
if (!self.hasOwnProperty('updateInitialInstanceProperty'))
|
||||
throw 'updateInitialInstanceProperty is not defined on a ObjectJsImplementation.';
|
||||
var objectContent = JSON.parse(Pointer_stringify($1));
|
||||
var objectContent = JSON.parse(UTF8ToString($1));
|
||||
return self['updateInitialInstanceProperty'](
|
||||
objectContent,
|
||||
wrapPointer($2, Module['InitialInstance']),
|
||||
Pointer_stringify($3),
|
||||
Pointer_stringify($4),
|
||||
UTF8ToString($3),
|
||||
UTF8ToString($4),
|
||||
wrapPointer($5, Module['Project']),
|
||||
wrapPointer($6, Module['Layout']));
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user