Compare commits

..

2 Commits

Author SHA1 Message Date
Florian Rival
ae0f2687a5 Update typing for TileMapHelper 2024-05-12 20:33:36 +02:00
Florian Rival
56bcb79dcd Refactor PixiResourcesLoader to remove static methods and type it properly in extensions 2024-05-12 20:06:29 +02:00
1938 changed files with 61355 additions and 168204 deletions

View File

@@ -11,24 +11,13 @@
version: 2.1 version: 2.1
orbs: orbs:
aws-cli: circleci/aws-cli@2.0.6 aws-cli: circleci/aws-cli@2.0.6
macos: circleci/macos@2.5.1 # For Rosetta (see below)
node: circleci/node@5.2.0 # For a recent npm version (see below)
jobs: jobs:
# Build the **entire** app for macOS. # Build the **entire** app for macOS.
build-macos: build-macos:
macos: macos:
xcode: 14.2.0 xcode: 14.2.0
resource_class: macos.m1.large.gen1
steps: steps:
- checkout - checkout
# Install Rosetta for AWS CLI and disable TSO to speed up S3 uploads (https://support.circleci.com/hc/en-us/articles/19334402064027-Troubleshooting-slow-uploads-to-S3-for-jobs-using-an-m1-macOS-resource-class)
- macos/install-rosetta
- run: sudo sysctl net.inet.tcp.tso=0
# Install a recent version of npm to workaround a notarization issue because of a symlink made by npm: https://github.com/electron-userland/electron-builder/issues/7755
# Node.js v20.14.0 comes with npm v10.7.0.
- node/install:
node-version: "20.14.0"
# System dependencies (for Emscripten and upload) # System dependencies (for Emscripten and upload)
- run: - run:
@@ -176,7 +165,6 @@ jobs:
# Build the WebAssembly library only (so that it's cached on a S3 and easy to re-use). # Build the WebAssembly library only (so that it's cached on a S3 and easy to re-use).
build-gdevelop_js-wasm-only: build-gdevelop_js-wasm-only:
resource_class: medium+ # Compilation time decrease linearly with the number of CPUs, but not linking (so "large" does not speedup total build time).
docker: docker:
- image: cimg/node:16.13 - image: cimg/node:16.13
@@ -233,83 +221,10 @@ jobs:
name: Deploy to S3 (latest) name: Deploy to S3 (latest)
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/latest/ command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/latest/
# Build the WebAssembly library with clang-tidy and memory sanitizers.
build-gdevelop_js-debug-sanitizers-and-extra-checks:
resource_class: xlarge # Total time decrease linearly with the number of CPUs.
docker:
- image: cimg/node:16.13
working_directory: ~/GDevelop
steps:
- checkout
- aws-cli/setup
# System dependencies (for Emscripten)
- run:
name: Install dependencies for Emscripten
command: sudo apt-get update && sudo apt install cmake
- run:
name: Install dependencies for clang-tidy v19
command: wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && sudo ./llvm.sh 19 && sudo apt install clang-tidy-19
- run:
name: Install Python3 dependencies for Emscripten
command: sudo apt install python-is-python3 python3-distutils -y
- run:
name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
# GDevelop.js dependencies
- restore_cache:
keys:
- gdevelop.js-linux-nodejs-dependencies-{{ checksum "GDevelop.js/package-lock.json" }}
# fallback to using the latest cache if no exact match is found
- gdevelop.js-linux-nodejs-dependencies-
- run:
name: Install GDevelop.js dependencies and build it
command: cd GDevelop.js && npm install && cd ..
# Build GDevelop.js
- run:
name: Build GDevelop.js ('debug-sanitizers' variant)
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build -- --variant=debug-sanitizers
- run:
name: Run clang-tidy
command: cd GDevelop.js && npm run lint
- run:
name: Run tests
command: cd GDevelop.js && npm run test -- --maxWorkers=4
# Upload artifacts (CircleCI)
- store_artifacts:
path: Binaries/embuild/GDevelop.js
# Upload artifacts (AWS)
- run:
name: Deploy to S3 (specific commit)
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/variant/debug-sanitizers/commit/$(git rev-parse HEAD)/
workflows: workflows:
gdevelop_js-wasm:
jobs:
- build-gdevelop_js-wasm-only
gdevelop_js-wasm-extra-checks:
jobs:
- build-gdevelop_js-debug-sanitizers-and-extra-checks:
# Extra checks are resource intensive so don't all run them.
filters:
branches:
only:
- master
- /experimental-build.*/
builds: builds:
jobs: jobs:
- build-gdevelop_js-wasm-only
- build-macos: - build-macos:
filters: filters:
branches: branches:

View File

@@ -1,4 +0,0 @@
Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,-cppcoreguidelines-explicit-virtual-functions,-cppcoreguidelines-avoid-const-or-ref-data-members,-cppcoreguidelines-special-member-functions,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-owning-memory,-cppcoreguidelines-virtual-class-destructor,-clang-analyzer-optin.performance.Padding,-cppcoreguidelines-narrowing-conversions'
WarningsAsErrors: 'cppcoreguidelines-pro-type-member-init, clang-analyzer-optin.cplusplus.UninitializedObject'
HeaderFilterRegex: '.*'
FormatStyle: none

4
.gitattributes vendored
View File

@@ -1,12 +1,12 @@
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
Core/GDCore/TinyXml/* linguist-vendored
Extensions/ParticleSystem/SPARK/* linguist-vendored Extensions/ParticleSystem/SPARK/* linguist-vendored
Extensions/PhysicsBehavior/Box2D/* linguist-vendored Extensions/PhysicsBehavior/Box2D/* linguist-vendored
Extensions/PhysicsBehavior/box2djs/* linguist-vendored Extensions/PhysicsBehavior/box2djs/* linguist-vendored
Extensions/Physics2Behavior/box2d.js linguist-vendored Extensions/Physics2Behavior/box2d.js linguist-vendored
Extensions/Physics3DBehavior/*.wasm-compat.js linguist-vendored
Extensions/BBText/pixi-multistyle-text/* linguist-vendored Extensions/BBText/pixi-multistyle-text/* linguist-vendored
Extensions/P2P/A_peer.js linguist-vendored Extensions/P2P/A_peer.js linguist-vendored
Extensions/Multiplayer/peer.js linguist-vendored
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
Extensions/TileMap/pako/* linguist-vendored Extensions/TileMap/pako/* linguist-vendored
Extensions/TileMap/pixi-tilemap/* linguist-vendored Extensions/TileMap/pixi-tilemap/* linguist-vendored
Extensions/TweenBehavior/shifty.js linguist-vendored

View File

@@ -1,22 +0,0 @@
# This worflow notifies arthuro555's gdcore-tools repository when a new release is published.
#
# This is used to allow gdcore-tools, a library to use GDCore outside of GDevelop,
# to attempt to automatically build, test, and publish a release for the new
# GDevelop version.
name: Trigger gdcore-tools pipeline
on:
release:
types: [published]
jobs:
dispatch-event:
runs-on: ubuntu-latest
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.GDCORE_TOOLS_PAT }}
repository: arthuro555/gdcore-tools
event-type: gdevelop-release
client-payload: '{"release": ${{ toJson(github.event.release) }}}'

View File

@@ -1,47 +0,0 @@
# GitHub Action to update extension translations.
# It copies the latest messages.js files from the GDevelop-extensions repository
# and opens a Pull Request with the changes on GDevelop's repository.
name: Update extension translations
on:
push:
branches:
- master
tags-ignore:
- "**" # Don't run on new tags
workflow_dispatch: # Allows manual triggering from the Actions tab
jobs:
update-extension-translations:
runs-on: ubuntu-latest
steps:
- name: Checkout current repository
uses: actions/checkout@v3
- name: Clone GDevelop-extensions repository
run: git clone https://github.com/GDevelopApp/GDevelop-extensions.git /tmp/GDevelop-extensions
- name: Copy and rename translation files
run: |
mkdir -p newIDE/app/src/locales
for folder in /tmp/GDevelop-extensions/.translations/*; do
if [ -d "$folder" ]; then
lang=$(basename "$folder")
mkdir -p "newIDE/app/src/locales/$lang"
cp "$folder/messages.js" "newIDE/app/src/locales/$lang/extension-messages.js"
fi
done
cp /tmp/GDevelop-extensions/.translations/LocalesMetadata.js newIDE/app/src/locales/ExtensionLocalesMetadata.js
- name: Create Pull Request with updated translations
uses: peter-evans/create-pull-request@v6
with:
commit-message: Update extension translations [skip ci]
branch: chore/update-extension-translations
delete-branch: true
title: "[Auto PR] Update extension translations"
body: |
This updates the extension translations by copying the latest messages.js files from the GDevelop-extensions repository.
Each messages.js file is renamed to extension-messages.js and placed in the corresponding language folder under `newIDE/app/src/locales`.
Please review the changes carefully before merging.

View File

@@ -17,11 +17,11 @@ cache:
addons: addons:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
packages: packages:
# Build dependencies: # Build dependencies:
- cmake - cmake
- p7zip-full - p7zip-full
before_install: before_install:
# This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++) # This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++)
@@ -29,48 +29,47 @@ before_install:
- sudo dpkg --force-all -i libstdc++6 - sudo dpkg --force-all -i libstdc++6
install: install:
# Ensure we use a recent version of Node.js (and npm). # Ensure we use a recent version of Node.js (and npm).
- nvm install v16 && nvm use v16 - nvm install v16 && nvm use v16
#Compile the tests only for GDCore #Compile the tests only for GDCore
- mkdir .build-tests - mkdir .build-tests
- cd .build-tests - cd .build-tests
- cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) .. - cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) ..
- make -j 4 - make -j 4
- cd .. - cd ..
# Install Emscripten (for GDevelop.js) # Install Emscripten (for GDevelop.js)
# Specify the tag for the core repository to avois breaking changes. - git clone https://github.com/juj/emsdk.git
- git clone --depth 1 --branch 3.1.21 https://github.com/juj/emsdk.git
- cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. - cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd ..
# Install GDevelop.js dependencies # Install GDevelop.js dependencies
- cd GDevelop.js && npm install && cd .. - cd GDevelop.js && npm install && cd ..
# Build GDevelop.js # Build GDevelop.js
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build) # (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
- (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..) - (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..)
# Install newIDE tests dependencies # Install newIDE tests dependencies
- npm -v - npm -v
- cd newIDE/app && npm install - cd newIDE/app && npm install
- cd ../.. - cd ../..
# Install GDJS tests dependencies # Install GDJS tests dependencies
- cd GDJS && npm install && cd tests && npm install - cd GDJS && npm install && cd tests && npm install
- cd ../.. - cd ../..
script: script:
# GDCore tests: # GDCore tests:
- cd .build-tests - cd .build-tests
- Core/GDCore_tests - Core/GDCore_tests
- cd .. - cd ..
# GDevelop.js tests # GDevelop.js tests
- cd GDevelop.js - cd GDevelop.js
- npm test - npm test
- cd .. - cd ..
# newIDE tests: # newIDE tests:
- cd newIDE/app - cd newIDE/app
- npm test - npm test
- npm run flow - npm run flow
- npm run check-format - npm run check-format
- npm run check-script-types - npm run check-script-types
- cd ../.. - cd ../..
# GDJS tests: # GDJS tests:
- cd GDJS - cd GDJS
- npm run check-format - npm run check-format
- cd .. - cd ..

View File

@@ -107,7 +107,7 @@
"description": "Define a parameter in a GDevelop extension definition.", "description": "Define a parameter in a GDevelop extension definition.",
"prefix": "gdparam", "prefix": "gdparam",
"body": [ "body": [
".addParameter('${1|string,expression,object,behavior,yesorno,stringWithSelector,scenevar,globalvar,objectvar,objectList,objectListWithoutPicking,color,key,sceneName,file,layer,relationalOperator,operator,trueorfalse,musicfile,soundfile,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})" ".addParameter('${1|string,expression,object,behavior,yesorno,stringWithSelector,scenevar,globalvar,objectvar,objectList,objectListWithoutPicking,color,key,sceneName,file,layer,relationalOperator,operator,trueorfalse,musicfile,soundfile,police,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})"
] ]
}, },
"Add code only parameter": { "Add code only parameter": {

View File

@@ -114,8 +114,7 @@
"__bits": "cpp", "__bits": "cpp",
"__verbose_abort": "cpp", "__verbose_abort": "cpp",
"variant": "cpp", "variant": "cpp",
"charconv": "cpp", "charconv": "cpp"
"execution": "cpp"
}, },
"files.exclude": { "files.exclude": {
"Binaries/*build*": true, "Binaries/*build*": true,

View File

@@ -60,7 +60,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_
endif() endif()
#Activate C++11 #Activate C++11
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 should be tried. set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 would need to remove usage of bind2nd (should be easy).
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Mark some warnings as errors # Mark some warnings as errors
@@ -69,18 +69,12 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# uninitialized variables or other hard to debug bugs. # uninitialized variables or other hard to debug bugs.
add_compile_options( add_compile_options(
-Wall -Wall
-Wextra
-Wuninitialized
-Wconditional-uninitialized
-Wno-unknown-warning-option -Wno-unknown-warning-option
-Wno-reorder-ctor -Wno-reorder-ctor
-Wno-reorder -Wno-reorder
-Wno-unused-parameter
-Wno-pessimizing-move -Wno-pessimizing-move
-Wno-unused-variable # Not a good style, but not a risk -Wno-unused-variable
-Wno-unused-private-field -Wno-unused-private-field
-Wno-ignored-qualifiers # Not a risk
-Wno-sign-compare # Not a big risk
# Make as much warnings considered as errors as possible (only one for now). # Make as much warnings considered as errors as possible (only one for now).
-Werror=return-stack-address -Werror=return-stack-address

View File

@@ -11,11 +11,6 @@ set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE) set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE)
set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE) set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
# Create VersionPriv.h - only useful for testing.
if (NOT EMSCRIPTEN)
file(WRITE "${GD_base_dir}/Core/GDCore/Tools/VersionPriv.h" "#define GD_VERSION_STRING \"0.0.0-0\"")
endif()
# Dependencies on external libraries: # Dependencies on external libraries:
# #

View File

@@ -58,7 +58,99 @@
* Common functions and tools for programming. * Common functions and tools for programming.
*/ */
/**
* \defgroup TinyXml Integrated TinyXml library
*
* See the full documentation of TinyXml [here](http://www.grinninglizard.com/tinyxmldocs/index.html).
*/
/** /**
* \defgroup SpriteObjectExtension Standard Sprite Object extension * \defgroup SpriteObjectExtension Standard Sprite Object extension
* \ingroup BuiltinExtensions * \ingroup BuiltinExtensions
*/ */
/**
* \class TiXmlAttribute
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlAttributeSet
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlBase
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlComment
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlCursor
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlDeclaration
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlDocument
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlElement
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlHandle
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlNode
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlOutStream
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlParsingData
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlPrinter
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlString
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlText
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlUnknown
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/
/**
* \class TiXmlVisitor
* \brief Part of the tinyxml library
* \ingroup TinyXml
*/

View File

@@ -49,8 +49,7 @@ vector<pair<gd::Expression*, gd::ParameterMetadata> >
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() { ForEachChildVariableEvent::GetAllExpressionsWithMetadata() {
vector<pair<gd::Expression*, gd::ParameterMetadata> > vector<pair<gd::Expression*, gd::ParameterMetadata> >
allExpressionsWithMetadata; allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("variable"); auto metadata = gd::ParameterMetadata().SetType("scenevar");
metadata.SetExtraInfo("AllowUndeclaredVariable");
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(
std::make_pair(&iterableVariableName, metadata)); std::make_pair(&iterableVariableName, metadata));
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(
@@ -64,8 +63,7 @@ vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() const { ForEachChildVariableEvent::GetAllExpressionsWithMetadata() const {
vector<pair<const gd::Expression*, const gd::ParameterMetadata> > vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
allExpressionsWithMetadata; allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("variable"); auto metadata = gd::ParameterMetadata().SetType("scenevar");
metadata.SetExtraInfo("AllowUndeclaredVariable");
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(
std::make_pair(&iterableVariableName, metadata)); std::make_pair(&iterableVariableName, metadata));
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(

View File

@@ -8,6 +8,7 @@
#include "GDCore/Events/Serialization.h" #include "GDCore/Events/Serialization.h"
#include "GDCore/Events/Tools/EventsCodeNameMangler.h" #include "GDCore/Events/Tools/EventsCodeNameMangler.h"
#include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/TinyXml/tinyxml.h"
using namespace std; using namespace std;

View File

@@ -10,6 +10,7 @@
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h" #include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDCore/Events/Serialization.h" #include "GDCore/Events/Serialization.h"
#include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/TinyXml/tinyxml.h"
using namespace std; using namespace std;

View File

@@ -4,8 +4,8 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_REPEATEVENT_H
#define GDCORE_REPEATEVENT_H
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
namespace gd { namespace gd {
@@ -36,10 +36,10 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
const gd::InstructionsList& GetActions() const { return actions; }; const gd::InstructionsList& GetActions() const { return actions; };
gd::InstructionsList& GetActions() { return actions; }; gd::InstructionsList& GetActions() { return actions; };
const gd::Expression& GetRepeatExpression() const { const gd::String& GetRepeatExpression() const {
return repeatNumberExpression; return repeatNumberExpression.GetPlainString();
}; };
void SetRepeatExpressionPlainString(gd::String repeatNumberExpression_) { void SetRepeatExpression(gd::String repeatNumberExpression_) {
repeatNumberExpression = gd::Expression(repeatNumberExpression_); repeatNumberExpression = gd::Expression(repeatNumberExpression_);
}; };
@@ -68,3 +68,5 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_REPEATEVENT_H

View File

@@ -15,8 +15,7 @@ using namespace std;
namespace gd { namespace gd {
StandardEvent::StandardEvent() StandardEvent::StandardEvent() : BaseEvent() {}
: BaseEvent(), variables(gd::VariablesContainer::SourceType::Local) {}
StandardEvent::~StandardEvent(){}; StandardEvent::~StandardEvent(){};
@@ -58,9 +57,6 @@ void StandardEvent::SerializeTo(SerializerElement& element) const {
if (!events.IsEmpty()) if (!events.IsEmpty())
gd::EventsListSerialization::SerializeEventsTo(events, gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events")); element.AddChild("events"));
if (HasVariables()) {
variables.SerializeTo(element.AddChild("variables"));
}
} }
void StandardEvent::UnserializeFrom(gd::Project& project, void StandardEvent::UnserializeFrom(gd::Project& project,
@@ -75,11 +71,6 @@ void StandardEvent::UnserializeFrom(gd::Project& project,
gd::EventsListSerialization::UnserializeEventsFrom( gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events")); project, events, element.GetChild("events", 0, "Events"));
} }
variables.Clear();
if (element.HasChild("variables")) {
variables.UnserializeFrom(element.GetChild("variables"));
}
} }
} // namespace gd } // namespace gd

View File

@@ -4,13 +4,13 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #if defined(GD_IDE_ONLY)
#ifndef GDCORE_STANDARDEVENT_H
#define GDCORE_STANDARDEVENT_H
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Instruction.h" #include "GDCore/Events/Instruction.h"
#include "GDCore/Events/InstructionsList.h" #include "GDCore/Events/InstructionsList.h"
#include "GDCore/Project/VariablesContainer.h"
namespace gd { namespace gd {
class Instruction; class Instruction;
class Project; class Project;
@@ -33,10 +33,6 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
virtual const gd::EventsList& GetSubEvents() const { return events; }; virtual const gd::EventsList& GetSubEvents() const { return events; };
virtual gd::EventsList& GetSubEvents() { return events; }; virtual gd::EventsList& GetSubEvents() { return events; };
virtual bool CanHaveVariables() const { return true; }
virtual const gd::VariablesContainer& GetVariables() const { return variables; };
virtual gd::VariablesContainer& GetVariables() { return variables; };
const gd::InstructionsList& GetConditions() const { return conditions; }; const gd::InstructionsList& GetConditions() const { return conditions; };
gd::InstructionsList& GetConditions() { return conditions; }; gd::InstructionsList& GetConditions() { return conditions; };
@@ -57,7 +53,9 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
gd::InstructionsList conditions; gd::InstructionsList conditions;
gd::InstructionsList actions; gd::InstructionsList actions;
EventsList events; EventsList events;
VariablesContainer variables;
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_STANDARDEVENT_H
#endif

View File

@@ -72,6 +72,8 @@ class GD_CORE_API WhileEvent : public gd::BaseEvent {
///< de/activate infinite loop warning when the ///< de/activate infinite loop warning when the
///< user create the event ///< user create the event
mutable unsigned int whileConditionsHeight;
int GetConditionsHeight() const; int GetConditionsHeight() const;
int GetActionsHeight() const; int GetActionsHeight() const;
int GetWhileConditionsHeight() const; int GetWhileConditionsHeight() const;

View File

@@ -1,129 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <memory>
#include <vector>
#include "GDCore/String.h"
#include "GDCore/Tools/MakeUnique.h"
namespace gd {
/**
* \brief
*/
class GD_CORE_API ProjectDiagnostic {
public:
enum ErrorType {
UndeclaredVariable,
MissingBehavior,
UnknownObject,
MismatchedObjectType,
};
ProjectDiagnostic(ErrorType type_,
const gd::String &message_,
const gd::String &actualValue_,
const gd::String &expectedValue_,
const gd::String &objectName_ = "")
: type(type_),
message(message_),
actualValue(actualValue_),
expectedValue(expectedValue_),
objectName(objectName_) {};
virtual ~ProjectDiagnostic() {};
ErrorType GetType() const { return type; };
const gd::String &GetMessage() const { return message; }
const gd::String &GetObjectName() const { return objectName; }
const gd::String &GetActualValue() const { return actualValue; }
const gd::String &GetExpectedValue() const { return expectedValue; }
private:
ErrorType type;
gd::String message;
gd::String objectName;
gd::String actualValue;
gd::String expectedValue;
};
/**
* \brief
*/
class GD_CORE_API DiagnosticReport {
public:
DiagnosticReport() {};
virtual ~DiagnosticReport() {};
void Add(const gd::ProjectDiagnostic &projectDiagnostic) {
projectDiagnostics.push_back(
gd::make_unique<gd::ProjectDiagnostic>(projectDiagnostic));
};
const ProjectDiagnostic &Get(std::size_t index) const {
return *projectDiagnostics[index].get();
};
std::size_t Count() const { return projectDiagnostics.size(); };
const gd::String &GetSceneName() const { return sceneName; }
void SetSceneName(const gd::String &sceneName_) { sceneName = sceneName_; }
void LogAllDiagnostics() {
for (auto &diagnostic : projectDiagnostics) {
std::cout << diagnostic->GetMessage()
<< "(object: " << diagnostic->GetObjectName()
<< ", actual value: " << diagnostic->GetActualValue()
<< ", expected value: " << diagnostic->GetExpectedValue() << ")"
<< std::endl;
}
}
private:
std::vector<std::unique_ptr<gd::ProjectDiagnostic>> projectDiagnostics;
gd::String sceneName;
};
/**
* \brief
*/
class GD_CORE_API WholeProjectDiagnosticReport {
public:
WholeProjectDiagnosticReport() {};
virtual ~WholeProjectDiagnosticReport() {};
const DiagnosticReport &Get(std::size_t index) const {
return *diagnosticReports[index].get();
};
void Clear() { diagnosticReports.clear(); };
DiagnosticReport &AddNewDiagnosticReportForScene(
const gd::String &sceneName) {
auto diagnosticReport = gd::make_unique<gd::DiagnosticReport>();
diagnosticReport->SetSceneName(sceneName);
diagnosticReports.push_back(std::move(diagnosticReport));
return *diagnosticReports[diagnosticReports.size() - 1].get();
};
std::size_t Count() const { return diagnosticReports.size(); };
bool HasAnyIssue() {
for (auto &diagnosticReport : diagnosticReports) {
if (diagnosticReport->Count() > 0) {
return true;
}
}
return false;
}
private:
std::vector<std::unique_ptr<gd::DiagnosticReport>> diagnosticReports;
};
} // namespace gd

View File

@@ -15,7 +15,6 @@
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h" #include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/IDE/ProjectBrowserHelper.h" #include "GDCore/IDE/ProjectBrowserHelper.h"
namespace gd { namespace gd {
@@ -48,9 +47,6 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
// TODO Merge with UsedExtensionsFinder. // TODO Merge with UsedExtensionsFinder.
// TODO Factorize with the iteration on all effects for resource exposure.
// TODO Implement an ArbitraryEffectWorker and add a method in ProjectBrowserHelper
// See also gd::Project::ExposeResources for a method that traverse the whole // See also gd::Project::ExposeResources for a method that traverse the whole
// project (this time for resources) and // project (this time for resources) and
// WholeProjectRefactorer::ExposeProjectEvents. // WholeProjectRefactorer::ExposeProjectEvents.
@@ -72,27 +68,6 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
// Add objects effects // Add objects effects
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator); gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
// Add event-based objects layouts effects
for (std::size_t s = 0; s < project.GetEventsFunctionsExtensionsCount();
s++) {
auto &eventsFunctionExtension = project.GetEventsFunctionsExtension(s);
auto &eventsBasedObjects = eventsFunctionExtension.GetEventsBasedObjects();
for (std::size_t objectIndex = 0;
objectIndex < eventsBasedObjects.GetCount(); ++objectIndex) {
auto &eventsBasedObject = eventsBasedObjects.Get(objectIndex);
auto &layers = eventsBasedObject.GetLayers();
for (std::size_t l = 0; l < layers.GetLayersCount(); ++l) {
auto &effects = layers.GetLayer(l).GetEffects();
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
auto &effect = effects.GetEffect(e);
effectsCodeGenerator.AddEffectIncludeFiles(effect);
}
}
}
}
} }
} // namespace gd } // namespace gd

View File

@@ -3,8 +3,8 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef EVENTSCODEGENERATIONCONTEXT_H
#define EVENTSCODEGENERATIONCONTEXT_H
#include <map> #include <map>
#include <memory> #include <memory>
#include <set> #include <set>
@@ -325,3 +325,4 @@ class GD_CORE_API EventsCodeGenerationContext {
}; };
} // namespace gd } // namespace gd
#endif // EVENTSCODEGENERATIONCONTEXT_H

View File

@@ -14,7 +14,6 @@
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h" #include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Extensions/Platform.h" #include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ExpressionVariableNameFinder.h"
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/ObjectsContainer.h" #include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainersList.h" #include "GDCore/Project/ObjectsContainersList.h"
@@ -42,15 +41,14 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
const vector<gd::String>& arguments, const vector<gd::String>& arguments,
const gd::String& callStartString, const gd::String& callStartString,
std::size_t startFromArgument) { std::size_t startFromArgument) {
std::size_t relationalOperatorIndex = instrInfos.parameters.GetParametersCount(); std::size_t relationalOperatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++i) {
if (instrInfos.parameters.GetParameter(i).GetType() == "relationalOperator") { if (instrInfos.parameters[i].GetType() == "relationalOperator")
relationalOperatorIndex = i; relationalOperatorIndex = i;
}
} }
// Ensure that there is at least one parameter after the relational operator // Ensure that there is at least one parameter after the relational operator
if (relationalOperatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) { if (relationalOperatorIndex + 1 >= instrInfos.parameters.size()) {
ReportError(); ReportError();
return ""; return "";
} }
@@ -77,11 +75,11 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
/** /**
* @brief Generate a relational operation * @brief Generate a relational operation
* *
* @param relationalOperator the operator * @param relationalOperator the operator
* @param lhs the left hand operand * @param lhs the left hand operand
* @param rhs the right hand operand * @param rhs the right hand operand
* @return gd::String * @return gd::String
*/ */
gd::String EventsCodeGenerator::GenerateRelationalOperation( gd::String EventsCodeGenerator::GenerateRelationalOperation(
const gd::String& relationalOperator, const gd::String& relationalOperator,
@@ -123,16 +121,14 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
const gd::String& callStartString, const gd::String& callStartString,
const gd::String& getterStartString, const gd::String& getterStartString,
std::size_t startFromArgument) { std::size_t startFromArgument) {
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++i) {
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") { if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
operatorIndex = i;
}
} }
// Ensure that there is at least one parameter after the operator // Ensure that there is at least one parameter after the operator
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) { if (operatorIndex + 1 >= instrInfos.parameters.size()) {
ReportError(); ReportError();
return ""; return "";
} }
@@ -194,16 +190,14 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
const vector<gd::String>& arguments, const vector<gd::String>& arguments,
const gd::String& callStartString, const gd::String& callStartString,
std::size_t startFromArgument) { std::size_t startFromArgument) {
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++i) {
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") { if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
operatorIndex = i;
}
} }
// Ensure that there is at least one parameter after the operator // Ensure that there is at least one parameter after the operator
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) { if (operatorIndex + 1 >= instrInfos.parameters.size()) {
ReportError(); ReportError();
return ""; return "";
} }
@@ -247,27 +241,25 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
const vector<gd::String>& arguments, const vector<gd::String>& arguments,
const gd::String& callStartString, const gd::String& callStartString,
std::size_t startFromArgument) { std::size_t startFromArgument) {
std::size_t operatorIndex = instrInfos.parameters.GetParametersCount(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.GetParametersCount(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++i) {
if (instrInfos.parameters.GetParameter(i).GetType() == "operator") { if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
operatorIndex = i;
}
} }
// Ensure that there is at least one parameter after the operator // Ensure that there is at least one parameter after the operator
if (operatorIndex + 1 >= instrInfos.parameters.GetParametersCount()) { if (operatorIndex + 1 >= instrInfos.parameters.size()) {
ReportError(); ReportError();
return ""; return "";
} }
gd::String operatorStr = arguments[operatorIndex]; gd::String operatorStr = arguments[operatorIndex];
if (operatorStr.size() > 2 && operatorStr[0] == '\"') { if (operatorStr.size() > 2)
operatorStr = operatorStr.substr( operatorStr = operatorStr.substr(
1, 1,
operatorStr.length() - 1 - operatorStr.length() - 1 -
1); // Operator contains quote which must be removed. 1); // Operator contains quote which must be removed.
}
auto mutators = instrInfos.codeExtraInformation.optionalMutators; auto mutators = instrInfos.codeExtraInformation.optionalMutators;
auto mutator = mutators.find(operatorStr); auto mutator = mutators.find(operatorStr);
if (mutator == mutators.end()) { if (mutator == mutators.end()) {
@@ -287,9 +279,6 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
argumentsStr += arguments[i]; argumentsStr += arguments[i];
} }
} }
if (instrInfos.GetManipulatedType() == "boolean") {
return callStartString + "(" + argumentsStr + ")." + mutator->second;
}
return callStartString + "(" + argumentsStr + ")." + mutator->second + "(" + return callStartString + "(" + argumentsStr + ")." + mutator->second + "(" +
rhs + ")"; rhs + ")";
@@ -323,36 +312,23 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
} }
// Insert code only parameters and be sure there is no lack of parameter. // Insert code only parameters and be sure there is no lack of parameter.
while (condition.GetParameters().size() < instrInfos.parameters.GetParametersCount()) { while (condition.GetParameters().size() < instrInfos.parameters.size()) {
vector<gd::Expression> parameters = condition.GetParameters(); vector<gd::Expression> parameters = condition.GetParameters();
parameters.push_back(gd::Expression("")); parameters.push_back(gd::Expression(""));
condition.SetParameters(parameters); condition.SetParameters(parameters);
} }
gd::EventsCodeGenerator::CheckBehaviorParameters(condition, instrInfos);
// Verify that there are no mismatches between object type in parameters. // Verify that there are no mismatches between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) { if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
gd::String objectInParameter = gd::String objectInParameter =
condition.GetParameter(pNb).GetPlainString(); condition.GetParameter(pNb).GetPlainString();
const auto &expectedObjectType = if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) {
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
const auto &actualObjectType =
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
objectInParameter)) {
gd::ProjectDiagnostic projectDiagnostic(
gd::ProjectDiagnostic::ErrorType::UnknownObject, "",
objectInParameter, "");
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
return "/* Unknown object - skipped. */"; return "/* Unknown object - skipped. */";
} else if (!expectedObjectType.empty() && } else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
actualObjectType != expectedObjectType) { GetObjectsContainersList().GetTypeOfObject(objectInParameter) !=
gd::ProjectDiagnostic projectDiagnostic( instrInfos.parameters[pNb].GetExtraInfo()) {
gd::ProjectDiagnostic::ErrorType::MismatchedObjectType, "",
actualObjectType, expectedObjectType, objectInParameter);
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
return "/* Mismatched object type - skipped. */"; return "/* Mismatched object type - skipped. */";
} }
} }
@@ -360,7 +336,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
if (instrInfos.IsObjectInstruction()) { if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString(); gd::String objectName = condition.GetParameter(0).GetPlainString();
if (!objectName.empty() && instrInfos.parameters.GetParametersCount() > 0) { if (!objectName.empty() && !instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
@@ -388,22 +364,15 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
} }
} }
} else if (instrInfos.IsBehaviorInstruction()) { } else if (instrInfos.IsBehaviorInstruction()) {
if (instrInfos.parameters.GetParametersCount() >= 2) { gd::String objectName = condition.GetParameter(0).GetPlainString();
const gd::String &objectName = condition.GetParameter(0).GetPlainString(); gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(condition.GetParameter(1).GetPlainString());
const gd::String &behaviorName = if (instrInfos.parameters.size() >= 2) {
condition.GetParameter(1).GetPlainString();
const gd::String &actualBehaviorType =
GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName( GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
objectName, context.GetCurrentObject());
const BehaviorMetadata &autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, actualBehaviorType);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context // Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles); AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]); context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]); context.ObjectsListNeeded(realObjects[i]);
@@ -413,7 +382,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.GetParameters(), instrInfos.parameters, context); condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateBehaviorCondition( conditionCode += GenerateBehaviorCondition(
realObjects[i], realObjects[i],
behaviorName, condition.GetParameter(1).GetPlainString(),
autoInfo, autoInfo,
arguments, arguments,
instrInfos, instrInfos,
@@ -488,33 +457,6 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
return outputCode; return outputCode;
} }
void EventsCodeGenerator::CheckBehaviorParameters(
const gd::Instruction &instruction,
const gd::InstructionMetadata &instrInfos) {
gd::ParameterMetadataTools::IterateOverParameters(
instruction.GetParameters(), instrInfos.parameters,
[this](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue,
const gd::String &lastObjectName) {
if (ParameterMetadata::IsBehavior(parameterMetadata.GetType())) {
const gd::String &behaviorName = parameterValue.GetPlainString();
const gd::String &actualBehaviorType =
GetObjectsContainersList().GetTypeOfBehaviorInObjectOrGroup(
lastObjectName, behaviorName);
const gd::String &expectedBehaviorType =
parameterMetadata.GetExtraInfo();
if (!expectedBehaviorType.empty() &&
actualBehaviorType != expectedBehaviorType) {
gd::ProjectDiagnostic projectDiagnostic(
gd::ProjectDiagnostic::ErrorType::MissingBehavior, "",
actualBehaviorType, expectedBehaviorType, lastObjectName);
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
}
}
});
}
/** /**
* Generate code for an action. * Generate code for an action.
*/ */
@@ -546,35 +488,21 @@ gd::String EventsCodeGenerator::GenerateActionCode(
: instrInfos.codeExtraInformation.functionCallName; : instrInfos.codeExtraInformation.functionCallName;
// Be sure there is no lack of parameter. // Be sure there is no lack of parameter.
while (action.GetParameters().size() < instrInfos.parameters.GetParametersCount()) { while (action.GetParameters().size() < instrInfos.parameters.size()) {
vector<gd::Expression> parameters = action.GetParameters(); vector<gd::Expression> parameters = action.GetParameters();
parameters.push_back(gd::Expression("")); parameters.push_back(gd::Expression(""));
action.SetParameters(parameters); action.SetParameters(parameters);
} }
gd::EventsCodeGenerator::CheckBehaviorParameters(action, instrInfos);
// Verify that there are no mismatches between object type in parameters. // Verify that there are no mismatches between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType())) { if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString(); gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) {
const auto &expectedObjectType =
instrInfos.parameters.GetParameter(pNb).GetExtraInfo();
const auto &actualObjectType =
GetObjectsContainersList().GetTypeOfObject(objectInParameter);
if (!GetObjectsContainersList().HasObjectOrGroupNamed(
objectInParameter)) {
gd::ProjectDiagnostic projectDiagnostic(
gd::ProjectDiagnostic::ErrorType::UnknownObject, "",
objectInParameter, "");
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
return "/* Unknown object - skipped. */"; return "/* Unknown object - skipped. */";
} else if (!expectedObjectType.empty() && } else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
actualObjectType != expectedObjectType) { GetObjectsContainersList().GetTypeOfObject(objectInParameter) !=
gd::ProjectDiagnostic projectDiagnostic( instrInfos.parameters[pNb].GetExtraInfo()) {
gd::ProjectDiagnostic::ErrorType::MismatchedObjectType, "",
actualObjectType, expectedObjectType, objectInParameter);
if (diagnosticReport) diagnosticReport->Add(projectDiagnostic);
return "/* Mismatched object type - skipped. */"; return "/* Mismatched object type - skipped. */";
} }
} }
@@ -584,7 +512,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
if (instrInfos.IsObjectInstruction()) { if (instrInfos.IsObjectInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString(); gd::String objectName = action.GetParameter(0).GetPlainString();
if (instrInfos.parameters.GetParametersCount() > 0) { if (!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
@@ -612,22 +540,17 @@ gd::String EventsCodeGenerator::GenerateActionCode(
} }
} }
} else if (instrInfos.IsBehaviorInstruction()) { } else if (instrInfos.IsBehaviorInstruction()) {
if (instrInfos.parameters.GetParametersCount() >= 2) { gd::String objectName = action.GetParameter(0).GetPlainString();
const gd::String &objectName = action.GetParameter(0).GetPlainString(); gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(action.GetParameter(1).GetPlainString());
const gd::String &behaviorName = action.GetParameter(1).GetPlainString();
const gd::String &actualBehaviorType =
GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName( GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
objectName, context.GetCurrentObject());
const BehaviorMetadata &autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, actualBehaviorType);
AddIncludeFiles(autoInfo.includeFiles);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context // Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]); context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]); context.ObjectsListNeeded(realObjects[i]);
@@ -636,7 +559,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.GetParameters(), instrInfos.parameters, context); action.GetParameters(), instrInfos.parameters, context);
actionCode += actionCode +=
GenerateBehaviorAction(realObjects[i], GenerateBehaviorAction(realObjects[i],
behaviorName, action.GetParameter(1).GetPlainString(),
autoInfo, autoInfo,
functionCallName, functionCallName,
arguments, arguments,
@@ -660,29 +583,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
return actionCode; return actionCode;
} }
gd::String EventsCodeGenerator::GenerateLocalVariablesStackAccessor() {
return (HasProjectAndLayout() ? GetCodeNamespace()
: "eventsFunctionContext") +
".localVariables";
}
gd::String EventsCodeGenerator::GenerateAnyOrSceneVariableGetter(
const gd::Expression &variableExpression,
EventsCodeGenerationContext &context) {
const auto variableName = gd::ExpressionVariableNameFinder::GetVariableName(
*variableExpression.GetRootNode());
gd::String variableParameterType =
GetProjectScopedContainers().GetVariablesContainersList().Has(
variableName)
? "variable"
: "scenevar";
return gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, variableParameterType,
variableExpression.GetPlainString(), "", "AllowUndeclaredVariable");
}
const EventsCodeGenerator::CallbackDescriptor const EventsCodeGenerator::CallbackDescriptor
EventsCodeGenerator::GenerateCallback( EventsCodeGenerator::GenerateCallback(
const gd::String& callbackID, const gd::String& callbackID,
@@ -707,23 +607,14 @@ EventsCodeGenerator::GenerateCallback(
actionsCode += "} //End of subevents\n"; actionsCode += "} //End of subevents\n";
} }
gd::String restoreLocalVariablesCode;
restoreLocalVariablesCode +=
"asyncObjectsList.restoreLocalVariablesContainers(" +
GenerateLocalVariablesStackAccessor() + ");\n";
// Compose the callback function and add outside main // Compose the callback function and add outside main
const gd::String actionsDeclarationsCode = const gd::String actionsDeclarationsCode =
GenerateObjectsDeclarationCode(callbackContext); GenerateObjectsDeclarationCode(callbackContext);
const gd::String clearLocalVariablesCode =
GenerateLocalVariablesStackAccessor() + ".length = 0;\n";
const gd::String callbackCode = callbackFunctionName + " = function (" + const gd::String callbackCode = callbackFunctionName + " = function (" +
GenerateEventsParameters(callbackContext) + GenerateEventsParameters(callbackContext) +
") {\n" + restoreLocalVariablesCode + ") {\n" + actionsDeclarationsCode +
actionsDeclarationsCode + actionsCode + actionsCode + "}\n";
clearLocalVariablesCode + "}\n";
AddCustomCodeOutsideMain(callbackCode); AddCustomCodeOutsideMain(callbackCode);
@@ -786,13 +677,13 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
if (ParameterMetadata::IsExpression("number", metadata.GetType())) { if (ParameterMetadata::IsExpression("number", metadata.GetType())) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "number", parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, "number", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("string", metadata.GetType())) { } else if (ParameterMetadata::IsExpression("string", metadata.GetType())) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "string", parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, "string", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) { } else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, metadata.GetType(), parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, metadata.GetType(), parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.GetType())) { } else if (ParameterMetadata::IsObject(metadata.GetType())) {
// It would be possible to run a gd::ExpressionCodeGenerator if later // It would be possible to run a gd::ExpressionCodeGenerator if later
// objects can have nested objects, or function returning objects. // objects can have nested objects, or function returning objects.
@@ -804,8 +695,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
} else if (metadata.GetType() == "operator") { } else if (metadata.GetType() == "operator") {
argOutput += parameter.GetPlainString(); argOutput += parameter.GetPlainString();
if (argOutput != "=" && argOutput != "+" && argOutput != "-" && if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
argOutput != "/" && argOutput != "*" && argOutput != "True" && argOutput != "/" && argOutput != "*") {
argOutput != "False" && argOutput != "Toggle") {
cout << "Warning: Bad operator: Set to = by default." << endl; cout << "Warning: Bad operator: Set to = by default." << endl;
argOutput = "="; argOutput = "=";
} }
@@ -828,7 +718,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
metadata.GetType() == "spineResource" || metadata.GetType() == "spineResource" ||
// Deprecated, old parameter names: // Deprecated, old parameter names:
metadata.GetType() == "password" || metadata.GetType() == "musicfile" || metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
metadata.GetType() == "soundfile") { metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "mouse") { } else if (metadata.GetType() == "mouse") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
@@ -870,7 +760,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
vector<gd::String> EventsCodeGenerator::GenerateParametersCodes( vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
const vector<gd::Expression>& parameters, const vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersInfo, const vector<gd::ParameterMetadata>& parametersInfo,
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
std::vector<std::pair<gd::String, gd::String> >* std::vector<std::pair<gd::String, gd::String> >*
supplementaryParametersTypes) { supplementaryParametersTypes) {
@@ -975,11 +865,6 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
gd::EventsList& events, EventsCodeGenerationContext& parentContext) { gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
gd::String output; gd::String output;
for (std::size_t eId = 0; eId < events.size(); ++eId) { for (std::size_t eId = 0; eId < events.size(); ++eId) {
auto& event = events[eId];
if (event.HasVariables()) {
GetProjectScopedContainers().GetVariablesContainersList().Push(event.GetVariables());
}
// Each event has its own context : Objects picked in an event are totally // Each event has its own context : Objects picked in an event are totally
// different than the one picked in another. // different than the one picked in another.
gd::EventsCodeGenerationContext newContext; gd::EventsCodeGenerationContext newContext;
@@ -1000,17 +885,13 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
auto& context = reuseParentContext ? reusedContext : newContext; auto& context = reuseParentContext ? reusedContext : newContext;
gd::String eventCoreCode = event.GenerateEventCode(*this, context); gd::String eventCoreCode = events[eId].GenerateEventCode(*this, context);
gd::String scopeBegin = GenerateScopeBegin(context); gd::String scopeBegin = GenerateScopeBegin(context);
gd::String scopeEnd = GenerateScopeEnd(context); gd::String scopeEnd = GenerateScopeEnd(context);
gd::String declarationsCode = GenerateObjectsDeclarationCode(context); gd::String declarationsCode = GenerateObjectsDeclarationCode(context);
output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" + output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" +
eventCoreCode + "\n" + scopeEnd + "\n"; eventCoreCode + "\n" + scopeEnd + "\n";
if (event.HasVariables()) {
GetProjectScopedContainers().GetVariablesContainersList().Pop();
}
} }
return output; return output;
@@ -1107,10 +988,10 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
// Add logical not if needed // Add logical not if needed
bool conditionAlreadyTakeCareOfInversion = false; bool conditionAlreadyTakeCareOfInversion = false;
for (std::size_t i = 0; i < instrInfos.parameters.GetParametersCount(); for (std::size_t i = 0; i < instrInfos.parameters.size();
++i) // Some conditions already have a "conditionInverted" parameter ++i) // Some conditions already have a "conditionInverted" parameter
{ {
if (instrInfos.parameters.GetParameter(i).GetType() == "conditionInverted") if (instrInfos.parameters[i].GetType() == "conditionInverted")
conditionAlreadyTakeCareOfInversion = true; conditionAlreadyTakeCareOfInversion = true;
} }
if (!conditionAlreadyTakeCareOfInversion && conditionInverted) if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
@@ -1131,7 +1012,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
// Prepare call // Prepare call
// Add a static_cast if necessary // Add a static_cast if necessary
gd::String objectFunctionCallNamePart = gd::String objectFunctionCallNamePart =
(!instrInfos.parameters.GetParameter(0).GetExtraInfo().empty()) (!instrInfos.parameters[0].GetExtraInfo().empty())
? "static_cast<" + objInfo.className + "*>(" + ? "static_cast<" + objInfo.className + "*>(" +
GetObjectListName(objectName, context) + "[i])->" + GetObjectListName(objectName, context) + "[i])->" +
instrInfos.codeExtraInformation.functionCallName instrInfos.codeExtraInformation.functionCallName
@@ -1186,13 +1067,7 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
// Generate call // Generate call
gd::String call; gd::String call;
if (instrInfos.codeExtraInformation.type == "number" || if (instrInfos.codeExtraInformation.type == "number" ||
instrInfos.codeExtraInformation.type == "string" || instrInfos.codeExtraInformation.type == "string") {
// Boolean actions declared with addExpressionAndConditionAndAction uses
// MutatorAndOrAccessor even though they don't declare an operator parameter.
// Boolean operators are only used with SetMutators or SetCustomCodeGenerator.
(instrInfos.codeExtraInformation.type == "boolean" &&
instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::AccessType::Mutators)) {
if (instrInfos.codeExtraInformation.accessType == if (instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor) gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor)
call = GenerateOperatorCall( call = GenerateOperatorCall(
@@ -1358,30 +1233,12 @@ gd::String EventsCodeGenerator::GeneratePropertyGetter(const gd::PropertiesConta
return "getProperty" + property.GetName() + "As" + type + "()"; return "getProperty" + property.GetName() + "As" + type + "()";
} }
gd::String EventsCodeGenerator::GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property) {
return "getProperty" + property.GetName() + "()";
}
gd::String EventsCodeGenerator::GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode) {
return "setProperty" + property.GetName() + "(" + operandCode + ")";
}
gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter, gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter,
const gd::String& type, const gd::String& type,
gd::EventsCodeGenerationContext& context) { gd::EventsCodeGenerationContext& context) {
return "getParameter" + parameter.GetName() + "As" + type + "()"; return "getParameter" + parameter.GetName() + "As" + type + "()";
} }
gd::String EventsCodeGenerator::GenerateParameterGetterWithoutCasting(
const gd::ParameterMetadata &parameter) {
return "getParameter" + parameter.GetName() + "()";
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_, EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
const gd::Layout& layout, const gd::Layout& layout,
const gd::Platform& platform_) const gd::Platform& platform_)
@@ -1394,8 +1251,7 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
compilationForRuntime(false), compilationForRuntime(false),
maxCustomConditionsDepth(0), maxCustomConditionsDepth(0),
maxConditionsListsSize(0), maxConditionsListsSize(0),
eventsListNextUniqueId(0), eventsListNextUniqueId(0){};
diagnosticReport(nullptr){};
EventsCodeGenerator::EventsCodeGenerator( EventsCodeGenerator::EventsCodeGenerator(
const gd::Platform& platform_, const gd::Platform& platform_,
@@ -1409,7 +1265,6 @@ EventsCodeGenerator::EventsCodeGenerator(
compilationForRuntime(false), compilationForRuntime(false),
maxCustomConditionsDepth(0), maxCustomConditionsDepth(0),
maxConditionsListsSize(0), maxConditionsListsSize(0),
eventsListNextUniqueId(0), eventsListNextUniqueId(0){};
diagnosticReport(nullptr){};
} // namespace gd } // namespace gd

View File

@@ -3,7 +3,8 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_EVENTSCODEGENERATOR_H
#define GDCORE_EVENTSCODEGENERATOR_H
#include <set> #include <set>
#include <utility> #include <utility>
@@ -11,10 +12,8 @@
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/Instruction.h" #include "GDCore/Events/Instruction.h"
#include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
#include "GDCore/Project/ProjectScopedContainers.h" #include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/String.h" #include "GDCore/String.h"
namespace gd { namespace gd {
class EventsList; class EventsList;
class Expression; class Expression;
@@ -128,7 +127,7 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
std::vector<gd::String> GenerateParametersCodes( std::vector<gd::String> GenerateParametersCodes(
const std::vector<gd::Expression>& parameters, const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersInfo, const std::vector<gd::ParameterMetadata>& parametersInfo,
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
std::vector<std::pair<gd::String, gd::String> >* std::vector<std::pair<gd::String, gd::String> >*
supplementaryParametersTypes = 0); supplementaryParametersTypes = 0);
@@ -337,16 +336,6 @@ class GD_CORE_API EventsCodeGenerator {
return projectScopedContainers; return projectScopedContainers;
} }
/**
* @brief Give access to the project scoped containers as code generation might
* push and pop variable containers (for local variables).
* This could be passed as a parameter recursively in code generation, but this requires
* heavy refactoring. Instead, we use this single instance.
*/
gd::ProjectScopedContainers& GetProjectScopedContainers() {
return projectScopedContainers;
}
/** /**
* \brief Return true if the code generation is done for a given project and * \brief Return true if the code generation is done for a given project and
* layout. If not, this means that the code is generated for a function. * layout. If not, this means that the code is generated for a function.
@@ -383,14 +372,6 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
size_t GetMaxConditionsListsSize() const { return maxConditionsListsSize; } size_t GetMaxConditionsListsSize() const { return maxConditionsListsSize; }
void SetDiagnosticReport(gd::DiagnosticReport* diagnosticReport_) {
diagnosticReport = diagnosticReport_;
}
gd::DiagnosticReport* GetDiagnosticReport() {
return diagnosticReport;
}
/** /**
* \brief Generate the full name for accessing to a boolean variable used for * \brief Generate the full name for accessing to a boolean variable used for
* conditions. * conditions.
@@ -467,14 +448,7 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
virtual gd::String GetCodeNamespace() { return ""; }; virtual gd::String GetCodeNamespace() { return ""; };
enum VariableScope { enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
LAYOUT_VARIABLE = 0,
PROJECT_VARIABLE,
OBJECT_VARIABLE,
ANY_VARIABLE,
VARIABLE_OR_PROPERTY,
VARIABLE_OR_PROPERTY_OR_PARAMETER
};
/** /**
* Generate a single unique number for the specified instruction. * Generate a single unique number for the specified instruction.
@@ -504,25 +478,7 @@ class GD_CORE_API EventsCodeGenerator {
const gd::String& lhs, const gd::String& lhs,
const gd::String& rhs); const gd::String& rhs);
/** protected:
* \brief Generate the code to access the local variables stack.
*/
virtual gd::String GenerateLocalVariablesStackAccessor();
/**
* \brief Generate an any variable getter that fallbacks on scene variable for
* compatibility reason.
*/
gd::String
GenerateAnyOrSceneVariableGetter(const gd::Expression &variableExpression,
EventsCodeGenerationContext &context);
virtual gd::String GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode);
protected:
virtual const gd::String GenerateRelationalOperatorCodes( virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString); const gd::String& operatorString);
@@ -540,7 +496,7 @@ protected:
parameter -> string parameter -> string
* - operator : Used to update a value using a setter and a getter -> string * - operator : Used to update a value using a setter and a getter -> string
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile, * - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
soundfile -> string soundfile, police -> string
* - trueorfalse, yesorno -> boolean ( See GenerateTrue/GenerateFalse ). * - trueorfalse, yesorno -> boolean ( See GenerateTrue/GenerateFalse ).
* *
* <br><br> * <br><br>
@@ -577,19 +533,12 @@ protected:
const gd::String& variableName, const gd::String& variableName,
const VariableScope& scope, const VariableScope& scope,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
const gd::String& objectName, const gd::String& objectName) {
bool hasChild) {
// This code is only used as a mock.
// See the real implementation in GDJS.
if (scope == LAYOUT_VARIABLE) { if (scope == LAYOUT_VARIABLE) {
return "getLayoutVariable(" + variableName + ")"; return "getLayoutVariable(" + variableName + ")";
} else if (scope == PROJECT_VARIABLE) { } else if (scope == PROJECT_VARIABLE) {
return "getProjectVariable(" + variableName + ")"; return "getProjectVariable(" + variableName + ")";
} else if (scope == ANY_VARIABLE || scope == VARIABLE_OR_PROPERTY ||
scope == VARIABLE_OR_PROPERTY_OR_PARAMETER) {
// TODO Split the 3 cases to make tests stronger.
return "getAnyVariable(" + variableName + ")";
} }
return "getVariableForObject(" + objectName + ", " + variableName + ")"; return "getVariableForObject(" + objectName + ", " + variableName + ")";
@@ -642,18 +591,11 @@ protected:
const gd::String& type, const gd::String& type,
gd::EventsCodeGenerationContext& context); gd::EventsCodeGenerationContext& context);
virtual gd::String GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property);
virtual gd::String GenerateParameterGetter( virtual gd::String GenerateParameterGetter(
const gd::ParameterMetadata& parameter, const gd::ParameterMetadata& parameter,
const gd::String& type, const gd::String& type,
gd::EventsCodeGenerationContext& context); gd::EventsCodeGenerationContext& context);
virtual gd::String
GenerateParameterGetterWithoutCasting(const gd::ParameterMetadata &parameter);
/** /**
* \brief Generate the code to reference an object which is * \brief Generate the code to reference an object which is
* in an empty/null state. * in an empty/null state.
@@ -837,10 +779,6 @@ protected:
virtual gd::String GenerateGetBehaviorNameCode( virtual gd::String GenerateGetBehaviorNameCode(
const gd::String& behaviorName); const gd::String& behaviorName);
void CheckBehaviorParameters(
const gd::Instruction &instruction,
const gd::InstructionMetadata &instrInfos);
const gd::Platform& platform; ///< The platform being used. const gd::Platform& platform; ///< The platform being used.
gd::ProjectScopedContainers projectScopedContainers; gd::ProjectScopedContainers projectScopedContainers;
@@ -871,9 +809,8 @@ protected:
instructionUniqueIds; ///< The unique ids generated for instructions. instructionUniqueIds; ///< The unique ids generated for instructions.
size_t eventsListNextUniqueId; ///< The next identifier to use for an events size_t eventsListNextUniqueId; ///< The next identifier to use for an events
///< list function name. ///< list function name.
gd::DiagnosticReport* diagnosticReport;
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_EVENTSCODEGENERATOR_H

View File

@@ -31,7 +31,6 @@
#include "GDCore/Project/ProjectScopedContainers.h" #include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h" #include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h" #include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
#include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
namespace gd { namespace gd {
@@ -40,8 +39,7 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
const gd::String& rootType, const gd::String& rootType,
const gd::Expression& expression, const gd::Expression& expression,
const gd::String& rootObjectName, const gd::String& rootObjectName) {
const gd::String& extraInfo) {
ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context); ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context);
auto node = expression.GetRootNode(); auto node = expression.GetRootNode();
@@ -54,34 +52,13 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
gd::ExpressionValidator validator(codeGenerator.GetPlatform(), gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
codeGenerator.GetProjectScopedContainers(), codeGenerator.GetProjectScopedContainers(),
rootType, rootType);
extraInfo);
node->Visit(validator); node->Visit(validator);
if (!validator.GetFatalErrors().empty()) { if (!validator.GetFatalErrors().empty()) {
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage() std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
<< "\" in: \"" << expression.GetPlainString() << "\" (" << "\" in: \"" << expression.GetPlainString() << "\" ("
<< rootType << ")" << std::endl; << rootType << ")" << std::endl;
auto *diagnosticReport = codeGenerator.GetDiagnosticReport();
if (diagnosticReport) {
for (auto *error : validator.GetFatalErrors()) {
if (error->GetType() ==
gd::ExpressionParserError::ErrorType::UndeclaredVariable ||
error->GetType() ==
gd::ExpressionParserError::ErrorType::UnknownIdentifier) {
const auto& variableName = error->GetActualValue();
if (!variableName.empty()) {
gd::ProjectDiagnostic projectDiagnostic(
gd::ProjectDiagnostic::ErrorType::UndeclaredVariable,
error->GetMessage(), error->GetActualValue(),
"", error->GetObjectName());
diagnosticReport->Add(projectDiagnostic);
}
}
}
}
return generator.GenerateDefaultValue(rootType); return generator.GenerateDefaultValue(rootType);
} }
@@ -133,22 +110,18 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
if (gd::ParameterMetadata::IsExpression("variable", type)) { if (gd::ParameterMetadata::IsExpression("variable", type)) {
// The node is a variable inside an expression waiting for a *variable* to be returned, not its value. // The node is a variable inside an expression waiting for a *variable* to be returned, not its value.
EventsCodeGenerator::VariableScope scope = EventsCodeGenerator::VariableScope scope =
type == "variable" type == "globalvar"
? gd::EventsCodeGenerator::ANY_VARIABLE ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "variableOrProperty" : ((type == "scenevar")
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: type == "variableOrPropertyOrParameter" : gd::EventsCodeGenerator::OBJECT_VARIABLE);
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(), auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(), codeGenerator.GetObjectsContainersList(),
rootObjectName, rootObjectName,
node); node);
output += codeGenerator.GenerateGetVariable( output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName, node.child != nullptr); node.name, scope, context, objectName);
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
} else { } else {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned. // The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
@@ -164,8 +137,19 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
output += codeGenerator.GenerateVariableValueAs(type); output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() { }, [&]() {
output += codeGenerator.GenerateGetVariable( if (!codeGenerator.HasProjectAndLayout()) {
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "", node.child != nullptr); gd::LogWarning("Tried to generate access to a variable without a project/scene - the code generator only works for global and scene variables for now.");
output += GenerateDefaultValue(type);
return;
}
// This could be adapted in the future if more scopes are supported.
EventsCodeGenerator::VariableScope scope = gd::EventsCodeGenerator::PROJECT_VARIABLE;
if (codeGenerator.GetProjectScopedContainers().GetVariablesContainersList().GetBottomMostVariablesContainer()->Has(node.name)) {
scope = gd::EventsCodeGenerator::LAYOUT_VARIABLE;
}
output += codeGenerator.GenerateGetVariable(node.name, scope, context, "");
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
output += codeGenerator.GenerateVariableValueAs(type); output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() { }, [&]() {
@@ -186,9 +170,8 @@ void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
VariableAccessorNode& node) { VariableAccessorNode& node) {
if (!objectNameToUseForVariableAccessor.empty()) { if (!objectNameToUseForVariableAccessor.empty()) {
// Use the name of the object passed by the parent, as we need both to access an object variable. // Use the name of the object passed by the parent, as we need both to access an object variable.
output += codeGenerator.GenerateGetVariable( output += codeGenerator.GenerateGetVariable(node.name,
node.name, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, objectNameToUseForVariableAccessor);
objectNameToUseForVariableAccessor, node.child != nullptr);
// We have accessed an object variable, from now we can continue accessing the child variables // We have accessed an object variable, from now we can continue accessing the child variables
// (including using the bracket notation). // (including using the bracket notation).
@@ -225,27 +208,22 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
output += output +=
codeGenerator.GenerateObject(node.identifierName, type, context); codeGenerator.GenerateObject(node.identifierName, type, context);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) { } else if (gd::ParameterMetadata::IsExpression("variable", type)) {
EventsCodeGenerator::VariableScope scope = EventsCodeGenerator::VariableScope scope =
type == "variable" type == "globalvar"
? gd::EventsCodeGenerator::ANY_VARIABLE ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "variableOrProperty" : ((type == "scenevar")
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: type == "variableOrPropertyOrParameter" : gd::EventsCodeGenerator::OBJECT_VARIABLE);
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName( auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetPlatform(), codeGenerator.GetObjectsContainersList(), codeGenerator.GetObjectsContainersList(),
rootObjectName, node); rootObjectName,
output += codeGenerator.GenerateGetVariable( node);
node.identifierName, scope, context, objectName, output += codeGenerator.GenerateGetVariable(
!node.childIdentifierName.empty()); node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) { if (!node.childIdentifierName.empty()) {
output += output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
codeGenerator.GenerateVariableAccessor(node.childIdentifierName); }
}
} else { } else {
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList(); const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList();
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList(); const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList();
@@ -255,13 +233,22 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() { codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() {
// Generate the code to access the object variable. // Generate the code to access the object variable.
output += codeGenerator.GenerateGetVariable( output += codeGenerator.GenerateGetVariable(
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, node.identifierName);
context, node.identifierName, !node.childIdentifierName.empty());
output += codeGenerator.GenerateVariableValueAs(type); output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() { }, [&]() {
output += codeGenerator.GenerateGetVariable( if (!codeGenerator.HasProjectAndLayout()) {
node.identifierName, gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER, context, gd::LogWarning("Tried to generate access to a variable without a project/scene - the code generator only works for global and scene variables for now.");
"", !node.childIdentifierName.empty()); output += GenerateDefaultValue(type);
return;
}
// This could be adapted in the future if more scopes are supported at runtime.
EventsCodeGenerator::VariableScope scope = gd::EventsCodeGenerator::PROJECT_VARIABLE;
if (variablesContainersList.GetBottomMostVariablesContainer()->Has(node.identifierName)) {
scope = gd::EventsCodeGenerator::LAYOUT_VARIABLE;
}
output += codeGenerator.GenerateGetVariable(node.identifierName, scope, context, "");
if (!node.childIdentifierName.empty()) { if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName); output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
} }
@@ -437,11 +424,11 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
size_t nonCodeOnlyParameterIndex = 0; size_t nonCodeOnlyParameterIndex = 0;
gd::String parametersCode; gd::String parametersCode;
for (std::size_t i = initialParameterIndex; for (std::size_t i = initialParameterIndex;
i < expressionMetadata.GetParameters().GetParametersCount(); i < expressionMetadata.parameters.size();
++i) { ++i) {
if (i != initialParameterIndex) parametersCode += ", "; if (i != initialParameterIndex) parametersCode += ", ";
auto& parameterMetadata = expressionMetadata.GetParameters().GetParameter(i); auto& parameterMetadata = expressionMetadata.parameters[i];
if (!parameterMetadata.IsCodeOnly()) { if (!parameterMetadata.IsCodeOnly()) {
if (nonCodeOnlyParameterIndex < parameters.size()) { if (nonCodeOnlyParameterIndex < parameters.size()) {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(), auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),

View File

@@ -59,8 +59,7 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
const gd::String& type, const gd::String& type,
const gd::Expression& expression, const gd::Expression& expression,
const gd::String& objectName = "", const gd::String& objectName = "");
const gd::String& extraInfo = "");
const gd::String& GetOutput() { return output; }; const gd::String& GetOutput() { return output; };

View File

@@ -17,7 +17,8 @@
namespace gd { namespace gd {
EventsList BaseEvent::badSubEvents; EventsList BaseEvent::badSubEvents;
VariablesContainer BaseEvent::badLocalVariables; std::vector<gd::String> BaseEvent::emptyDependencies;
gd::String BaseEvent::emptySourceFile;
BaseEvent::BaseEvent() BaseEvent::BaseEvent()
: totalTimeDuringLastSession(0), : totalTimeDuringLastSession(0),
@@ -27,8 +28,6 @@ BaseEvent::BaseEvent()
bool BaseEvent::HasSubEvents() const { return !GetSubEvents().IsEmpty(); } bool BaseEvent::HasSubEvents() const { return !GetSubEvents().IsEmpty(); }
bool BaseEvent::HasVariables() const { return GetVariables().Count() > 0; }
gd::String BaseEvent::GenerateEventCode( gd::String BaseEvent::GenerateEventCode(
gd::EventsCodeGenerator& codeGenerator, gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) { gd::EventsCodeGenerationContext& context) {

View File

@@ -3,7 +3,9 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #if defined(GD_IDE_ONLY)
#ifndef GDCORE_EVENT_H
#define GDCORE_EVENT_H
#include <iostream> #include <iostream>
#include <memory> #include <memory>
@@ -24,7 +26,6 @@ class SerializerElement;
class Instruction; class Instruction;
class EventVisitor; class EventVisitor;
class ReadOnlyEventVisitor; class ReadOnlyEventVisitor;
class VariablesContainer;
} // namespace gd } // namespace gd
namespace gd { namespace gd {
@@ -91,32 +92,6 @@ class GD_CORE_API BaseEvent {
*/ */
bool HasSubEvents() const; bool HasSubEvents() const;
/**
* Derived class have to redefine this function, so as to return true, if they
* can have local variables.
*/
virtual bool CanHaveVariables() const { return false; }
/**
* Return the local variables, if applicable.
*/
virtual const gd::VariablesContainer& GetVariables() const {
return badLocalVariables;
};
/**
* Return the local variables, if applicable.
*/
virtual gd::VariablesContainer& GetVariables() {
return badLocalVariables;
};
/**
* \brief Return true if the events has local variables.
* \warning This is only applicable when CanHaveVariables() return true.
*/
bool HasVariables() const;
/** /**
* \brief Return a list of all conditions of the event. * \brief Return a list of all conditions of the event.
* \note Used to preprocess or search in the conditions. * \note Used to preprocess or search in the conditions.
@@ -175,6 +150,26 @@ class GD_CORE_API BaseEvent {
noExpr; noExpr;
return noExpr; return noExpr;
}; };
/**
* \brief Returns the dependencies on source files of the project.
* \note Default implementation returns an empty list of dependencies. This is
* fine for most events that are not related to adding custom user source
* code.
*/
virtual const std::vector<gd::String>& GetSourceFileDependencies() const {
return emptyDependencies;
};
/**
* \brief Returns the name of the source file associated with the event
* \note Default implementation returns an empty string. This is fine for most
* events that are not related to adding custom user source code.
*/
virtual const gd::String& GetAssociatedGDManagedSourceFile(
gd::Project& project) const {
return emptySourceFile;
};
///@} ///@}
/** \name Code generation /** \name Code generation
@@ -306,7 +301,8 @@ class GD_CORE_API BaseEvent {
///< Used for saving the event for instance. ///< Used for saving the event for instance.
static gd::EventsList badSubEvents; static gd::EventsList badSubEvents;
static gd::VariablesContainer badLocalVariables; static std::vector<gd::String> emptyDependencies;
static gd::String emptySourceFile;
}; };
/** /**
@@ -329,3 +325,6 @@ class EmptyEvent : public BaseEvent {
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_EVENT_H
#endif

View File

@@ -18,6 +18,7 @@ class BaseEvent;
namespace gd { namespace gd {
class SerializerElement; class SerializerElement;
} }
class TiXmlElement;
#undef CreateEvent #undef CreateEvent

View File

@@ -38,7 +38,7 @@ using namespace gd::GrammarTerminals;
* parser by refactoring out the dependency on gd::MetadataProvider (injecting * parser by refactoring out the dependency on gd::MetadataProvider (injecting
* instead functions to be called to query supported functions). * instead functions to be called to query supported functions).
* *
* \see gd::ExpressionParserError * \see gd::ExpressionParserDiagnostic
* \see gd::ExpressionNode * \see gd::ExpressionNode
*/ */
class GD_CORE_API ExpressionParser2 { class GD_CORE_API ExpressionParser2 {
@@ -547,28 +547,28 @@ class GD_CORE_API ExpressionParser2 {
} }
///@} ///@}
std::unique_ptr<ExpressionParserError> ValidateOperator( std::unique_ptr<ExpressionParserDiagnostic> ValidateOperator(
gd::String::value_type operatorChar) { gd::String::value_type operatorChar) {
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' || if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
operatorChar == '*') { operatorChar == '*') {
return std::unique_ptr<ExpressionParserError>(nullptr); return gd::make_unique<ExpressionParserDiagnostic>();
} }
return gd::make_unique<ExpressionParserError>( return gd::make_unique<ExpressionParserError>(
gd::ExpressionParserError::ErrorType::InvalidOperator, "invalid_operator",
_("You've used an operator that is not supported. Operator should be " _("You've used an operator that is not supported. Operator should be "
"either +, -, / or *."), "either +, -, / or *."),
GetCurrentPosition()); GetCurrentPosition());
} }
std::unique_ptr<ExpressionParserError> ValidateUnaryOperator( std::unique_ptr<ExpressionParserDiagnostic> ValidateUnaryOperator(
gd::String::value_type operatorChar, gd::String::value_type operatorChar,
size_t position) { size_t position) {
if (operatorChar == '+' || operatorChar == '-') { if (operatorChar == '+' || operatorChar == '-') {
return std::unique_ptr<ExpressionParserError>(nullptr); return gd::make_unique<ExpressionParserDiagnostic>();
} }
return gd::make_unique<ExpressionParserError>( return gd::make_unique<ExpressionParserError>(
gd::ExpressionParserError::ErrorType::InvalidOperator, "invalid_operator",
_("You've used an \"unary\" operator that is not supported. Operator " _("You've used an \"unary\" operator that is not supported. Operator "
"should be " "should be "
"either + or -."), "either + or -."),
@@ -719,15 +719,13 @@ class GD_CORE_API ExpressionParser2 {
std::unique_ptr<ExpressionParserError> RaiseSyntaxError( std::unique_ptr<ExpressionParserError> RaiseSyntaxError(
const gd::String &message) { const gd::String &message) {
return std::move(gd::make_unique<ExpressionParserError>( return std::move(gd::make_unique<ExpressionParserError>(
gd::ExpressionParserError::ErrorType::SyntaxError, message, "syntax_error", message, GetCurrentPosition()));
GetCurrentPosition()));
} }
std::unique_ptr<ExpressionParserError> RaiseTypeError( std::unique_ptr<ExpressionParserError> RaiseTypeError(
const gd::String &message, size_t beginningPosition) { const gd::String &message, size_t beginningPosition) {
return std::move(gd::make_unique<ExpressionParserError>( return std::move(gd::make_unique<ExpressionParserError>(
gd::ExpressionParserError::ErrorType::MismatchedType, message, "type_error", message, beginningPosition, GetCurrentPosition()));
beginningPosition, GetCurrentPosition()));
} }
///@} ///@}

View File

@@ -6,5 +6,5 @@
#include "ExpressionParser2Node.h" #include "ExpressionParser2Node.h"
namespace gd { namespace gd {
gd::String ExpressionParserDiagnostic::noMessage = "";
} }

View File

@@ -3,14 +3,14 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_EXPRESSIONPARSER2NODES_H
#define GDCORE_EXPRESSIONPARSER2NODES_H
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "ExpressionParser2NodeWorker.h" #include "ExpressionParser2NodeWorker.h"
#include "GDCore/String.h" #include "GDCore/String.h"
namespace gd { namespace gd {
class Expression; class Expression;
class ObjectsContainer; class ObjectsContainer;
@@ -36,61 +36,54 @@ struct GD_CORE_API ExpressionParserLocation {
private: private:
bool isValid; bool isValid;
size_t startPosition = 0; size_t startPosition;
size_t endPosition = 0; size_t endPosition;
};
/**
* \brief A diagnostic that can be attached to a gd::ExpressionNode.
*/
struct GD_CORE_API ExpressionParserDiagnostic {
virtual ~ExpressionParserDiagnostic() = default;
virtual bool IsError() { return false; }
virtual const gd::String &GetMessage() { return noMessage; }
virtual size_t GetStartPosition() { return 0; }
virtual size_t GetEndPosition() { return 0; }
private:
static gd::String noMessage;
}; };
/** /**
* \brief An error that can be attached to a gd::ExpressionNode. * \brief An error that can be attached to a gd::ExpressionNode.
*/ */
struct GD_CORE_API ExpressionParserError { struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
enum ErrorType { ExpressionParserError(const gd::String &type_,
SyntaxError,
InvalidOperator,
MismatchedType,
UndeclaredVariable,
UnknownIdentifier,
BracketsNotAllowedForObjects,
TooFewParameters,
TooManyParameters,
InvalidFunctionName,
MalformedVariableParameter,
MalformedObjectParameter,
UnknownParameterType,
MissingBehavior,
VariableNameCollision,
};
ExpressionParserError(gd::ExpressionParserError::ErrorType type_,
const gd::String &message_, const gd::String &message_,
const ExpressionParserLocation &location_, const ExpressionParserLocation &location_)
const gd::String &actualValue_ = "", : type(type_), message(message_), location(location_){};
const gd::String &objectName_ = "") ExpressionParserError(const gd::String &type_,
: type(type_), message(message_), location(location_), const gd::String &message_,
actualValue(actualValue_), objectName(objectName_){}; size_t position_)
ExpressionParserError(gd::ExpressionParserError::ErrorType type_,
const gd::String &message_, size_t position_)
: type(type_), message(message_), location(position_){}; : type(type_), message(message_), location(position_){};
ExpressionParserError(gd::ExpressionParserError::ErrorType type_, ExpressionParserError(const gd::String &type_,
const gd::String &message_, size_t startPosition_, const gd::String &message_,
size_t startPosition_,
size_t endPosition_) size_t endPosition_)
: type(type_), message(message_), : type(type_),
message(message_),
location(startPosition_, endPosition_){}; location(startPosition_, endPosition_){};
virtual ~ExpressionParserError(){}; virtual ~ExpressionParserError(){};
gd::ExpressionParserError::ErrorType GetType() { return type; } bool IsError() override { return true; }
const gd::String &GetMessage() { return message; } const gd::String &GetMessage() override { return message; }
const gd::String &GetObjectName() { return objectName; } size_t GetStartPosition() override { return location.GetStartPosition(); }
const gd::String &GetActualValue() { return actualValue; } size_t GetEndPosition() override { return location.GetEndPosition(); }
size_t GetStartPosition() { return location.GetStartPosition(); }
size_t GetEndPosition() { return location.GetEndPosition(); }
private: private:
gd::ExpressionParserError::ErrorType type; gd::String type;
gd::String message; gd::String message;
ExpressionParserLocation location; ExpressionParserLocation location;
gd::String objectName;
gd::String actualValue;
}; };
/** /**
@@ -102,7 +95,7 @@ struct GD_CORE_API ExpressionNode {
virtual ~ExpressionNode(){}; virtual ~ExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker){}; virtual void Visit(ExpressionParser2NodeWorker &worker){};
std::unique_ptr<ExpressionParserError> diagnostic; std::unique_ptr<ExpressionParserDiagnostic> diagnostic;
ExpressionParserLocation location; ///< The location of the entire node. Some ExpressionParserLocation location; ///< The location of the entire node. Some
/// nodes might have other locations /// nodes might have other locations
/// stored inside them. For example, a /// stored inside them. For example, a
@@ -432,3 +425,5 @@ struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNod
}; };
} // namespace gd } // namespace gd
#endif

View File

@@ -182,10 +182,10 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
// Common updates for some parameters // Common updates for some parameters
const std::vector<gd::Expression>& parameters = instr.GetParameters(); const std::vector<gd::Expression>& parameters = instr.GetParameters();
for (std::size_t j = 0; for (std::size_t j = 0;
j < parameters.size() && j < metadata.parameters.GetParametersCount(); j < parameters.size() && j < metadata.parameters.size();
++j) { ++j) {
if (metadata.parameters.GetParameter(j).GetType() == "relationalOperator" || if (metadata.parameters[j].GetType() == "relationalOperator" ||
metadata.parameters.GetParameter(j).GetType() == "operator") { metadata.parameters[j].GetType() == "operator") {
if (j == parameters.size() - 1) { if (j == parameters.size() - 1) {
std::cout << "ERROR: No more parameters after a [relational]operator " std::cout << "ERROR: No more parameters after a [relational]operator "
"when trying to update an instruction from GD2.x"; "when trying to update an instruction from GD2.x";

View File

@@ -66,7 +66,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
extension extension
.AddAction("CopyArgumentToVariable", .AddAction("CopyArgumentToVariable",
_("Copy function parameter to variable"), _("Copy function parameter to variable"),
@@ -79,25 +78,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetHelpPath("/events/functions/return") .SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable") .AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable")) .AddParameter("scenevar", _("Scene variable"))
.SetHidden()
.MarkAsAdvanced();
extension
.AddAction("CopyArgumentToVariable2",
_("Copy function parameter to variable"),
_("Copy a function parameter (also called \"argument\") to a variable. "
"The parameter type must be a variable."),
_("Copy the parameter _PARAM0_ into the variable _PARAM1_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("variable", _("Variable"))
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
extension extension
.AddAction("CopyVariableToArgument", .AddAction("CopyVariableToArgument",
_("Copy variable to function parameter"), _("Copy variable to function parameter"),
@@ -110,21 +93,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetHelpPath("/events/functions/return") .SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable") .AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable")) .AddParameter("scenevar", _("Scene variable"))
.SetHidden()
.MarkAsAdvanced();
extension
.AddAction("CopyVariableToArgument2",
_("Copy variable to function parameter"),
_("Copy a variable to function parameter (also called \"argument\"). "
"The parameter type must be a variable."),
_("Copy the variable _PARAM1_ into the parameter _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("variable", _("Variable"))
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -141,8 +109,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png") "res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced() .MarkAsAdvanced();
.SetHidden();
extension extension
.AddExpression( .AddExpression(
@@ -178,8 +145,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions()) "number", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly();
.SetHidden();
extension extension
.AddCondition( .AddCondition(
@@ -193,8 +159,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions()) "string", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly() .SetRelevantForFunctionEventsOnly();
.SetHidden();
} }
} // namespace gd } // namespace gd

View File

@@ -117,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the position of the center of _PARAM0_: _PARAM1_ " _("Change the position of the center of _PARAM0_: _PARAM1_ "
"_PARAM2_ (x " "_PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"), "axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position Center"), _("Position/Center"),
"res/actions/position24_black.png", "res/actions/position24_black.png",
"res/actions/position_black.png") "res/actions/position_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
@@ -133,7 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center X position"), _("Center X position"),
_("the X position of the center of rotation"), _("the X position of the center of rotation"),
_("the X position of the center"), _("the X position of the center"),
_("Position Center"), _("Position/Center"),
"res/actions/position24_black.png") "res/actions/position24_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -144,7 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center Y position"), _("Center Y position"),
_("the Y position of the center of rotation"), _("the Y position of the center of rotation"),
_("the Y position of the center"), _("the Y position of the center"),
_("Position Center"), _("Position/Center"),
"res/actions/position24_black.png") "res/actions/position24_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -155,7 +155,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating " _("the bounding box (the area encapsulating "
"the object) left position"), "the object) left position"),
_("the bounding box left position"), _("the bounding box left position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-left_black.svg") "res/conditions/bounding-box-left_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -166,7 +166,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Bounding box top position"), _("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"), _("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"), _("the bounding box top position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-top_black.svg") "res/conditions/bounding-box-top_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -177,7 +177,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating " _("the bounding box (the area encapsulating "
"the object) right position"), "the object) right position"),
_("the bounding box right position"), _("the bounding box right position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-right_black.svg") "res/conditions/bounding-box-right_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -188,7 +188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating " _("the bounding box (the area encapsulating "
"the object) bottom position"), "the object) bottom position"),
_("the bounding box bottom position"), _("the bounding box bottom position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-bottom_black.svg") "res/conditions/bounding-box-bottom_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -199,7 +199,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating " _("the bounding box (the area encapsulating "
"the object) center X position"), "the object) center X position"),
_("the bounding box center X position"), _("the bounding box center X position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg") "res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -210,7 +210,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating " _("the bounding box (the area encapsulating "
"the object) center Y position"), "the object) center Y position"),
_("the bounding box center Y position"), _("the bounding box center Y position"),
_("Position Bounding Box"), _("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg") "res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()); .UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -255,6 +255,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"), _("Angle"),
"res/actions/rotate24_black.png", "res/actions/rotate24_black.png",
"res/actions/rotate_black.png") "res/actions/rotate_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Angular speed (in degrees per second)")) .AddParameter("expression", _("Angular speed (in degrees per second)"))
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
@@ -268,6 +269,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"), _("Angle"),
"res/actions/rotate24_black.png", "res/actions/rotate24_black.png",
"res/actions/rotate_black.png") "res/actions/rotate_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle to rotate towards (in degrees)")) .AddParameter("expression", _("Angle to rotate towards (in degrees)"))
.AddParameter("expression", _("Angular speed (in degrees per second)")) .AddParameter("expression", _("Angular speed (in degrees per second)"))
@@ -283,6 +285,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"), _("Angle"),
"res/actions/rotate24_black.png", "res/actions/rotate24_black.png",
"res/actions/rotate_black.png") "res/actions/rotate_black.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("X position")) .AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position")) .AddParameter("expression", _("Y position"))
@@ -301,12 +304,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/force24.png", "res/actions/force24.png",
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Speed on X axis (in pixels per second)")) .AddParameter("expression", _("Speed on X axis (in pixels per second)"))
.AddParameter("expression", _("Speed on Y axis (in pixels per second)")) .AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true) .AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0");
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddAction("AddForceAL", obj.AddAction("AddForceAL",
_("Add a force (angle)"), _("Add a force (angle)"),
@@ -318,12 +321,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/force24.png", "res/actions/force24.png",
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle")) .AddParameter("expression", _("Angle"))
.AddParameter("expression", _("Speed (in pixels per second)")) .AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true) .AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -336,13 +339,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/force24.png", "res/actions/force24.png",
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("X position")) .AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position")) .AddParameter("expression", _("Y position"))
.AddParameter("expression", _("Speed (in pixels per second)")) .AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true) .AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -357,13 +360,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/forceTourne24.png", "res/actions/forceTourne24.png",
"res/actions/forceTourne.png") "res/actions/forceTourne.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", "X position of the center") .AddParameter("expression", "X position of the center")
.AddParameter("expression", "Y position of the center") .AddParameter("expression", "Y position of the center")
.AddParameter("expression", "Speed (in Degrees per seconds)") .AddParameter("expression", "Speed (in Degrees per seconds)")
.AddParameter("expression", "Distance (in pixels)") .AddParameter("expression", "Distance (in pixels)")
.AddParameter("forceMultiplier", "Force multiplier") .AddParameter("forceMultiplier", "Force multiplier")
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden(); .SetHidden();
obj.AddAction("Arreter", obj.AddAction("Arreter",
@@ -373,8 +376,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/arreter24.png", "res/actions/arreter24.png",
"res/actions/arreter.png") "res/actions/arreter.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("Delete", obj.AddAction("Delete",
@@ -414,99 +417,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("SetNumberObjectVariable",
_("Change object variable value"),
_("Modify the number value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetStringObjectVariable",
_("Change object variable value"),
_("Modify the text of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetBooleanObjectVariable",
_("Change object variable value"),
_("Modify the boolean value of an object variable."),
_("Change the variable _PARAM1_ of _PARAM0_: _PARAM2_"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("operator", _("Value"), "boolean")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("NumberObjectVariable",
_("Object variable value"),
_("Compare the number value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("StringObjectVariable",
_("Object variable value"),
_("Compare the text of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("BooleanObjectVariable",
_("Object variable value"),
_("Compare the boolean value of an object variable."),
_("The variable _PARAM1_ of _PARAM0_ is _PARAM2_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("ModVarObjet", obj.AddAction("ModVarObjet",
_("Change number variable"), _("Change number variable"),
_("Modify the number value of an object variable."), _("Modify the number value of an object variable."),
@@ -517,10 +427,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly();
obj.AddAction("ModVarObjetTxt", obj.AddAction("ModVarObjetTxt",
_("Change text variable"), _("Change text variable"),
@@ -532,10 +440,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("string", .UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly();
obj.AddAction("SetObjectVariableAsBoolean", obj.AddAction("SetObjectVariableAsBoolean",
_("Change boolean variable"), _("Change boolean variable"),
@@ -548,9 +454,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:")) .AddParameter("trueorfalse", _("New Value:"));
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddAction( obj.AddAction(
"ToggleObjectVariableAsBoolean", "ToggleObjectVariableAsBoolean",
@@ -565,35 +469,31 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"));
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableChildExists", obj.AddCondition("ObjectVariableChildExists",
_("Child existence"), _("Child existence"),
_("Check if the specified child of the object " _("Check if the specified child of the object "
"structure variable exists."), "structure variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"), _("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable")) .AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Name of the child")) .AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("ObjectVariableRemoveChild", obj.AddAction("ObjectVariableRemoveChild",
_("Remove a child"), _("Remove a child"),
_("Remove a child from an object structure variable."), _("Remove a child from an object structure variable."),
_("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"), _("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable")) .AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Child's name")) .AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("ObjectVariableClearChildren", obj.AddAction("ObjectVariableClearChildren",
@@ -601,12 +501,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Remove all the children from the object array or structure " _("Remove all the children from the object array or structure "
"variable."), "variable."),
_("Clear children from variable _PARAM1_ of _PARAM0_"), _("Clear children from variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable")) .AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("Cache", obj.AddAction("Cache",
@@ -701,8 +600,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/conditions/arret24.png", "res/conditions/arret24.png",
"res/conditions/arret.png") "res/conditions/arret.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddCondition("Vitesse", obj.AddCondition("Vitesse",
@@ -712,10 +611,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/conditions/vitesse24.png", "res/conditions/vitesse24.png",
"res/conditions/vitesse.png") "res/conditions/vitesse.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated // Deprecated
@@ -732,7 +631,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees")) .AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees")) .AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddCondition("IsTotalForceAngleAround", obj.AddCondition("IsTotalForceAngleAround",
@@ -746,7 +644,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees")) .AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees")) .AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddCondition("VarObjet", obj.AddCondition("VarObjet",
@@ -760,9 +657,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions());
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetTxt", obj.AddCondition("VarObjetTxt",
_("Text variable"), _("Text variable"),
@@ -775,9 +670,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions()) "string", ParameterOptions::MakeNewOptions());
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableAsBoolean", obj.AddCondition("ObjectVariableAsBoolean",
_("Boolean variable"), _("Boolean variable"),
@@ -790,9 +683,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is")) .AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true") .SetDefaultValue("true");
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetDef", obj.AddCondition("VarObjetDef",
"Variable defined", "Variable defined",
@@ -806,57 +697,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("string", _("Variable")) .AddParameter("string", _("Variable"))
.SetHidden(); // Deprecated. .SetHidden(); // Deprecated.
obj.AddAction(
"PushStringToObjectVariable",
_("Add value to object array variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
obj.AddAction("PushNumberToObjectVariable",
_("Add value to object array variable"),
_("Adds a number to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
obj.AddAction(
"PushBooleanToObjectVariable",
_("Add value to object array variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
// Deprecated
obj.AddAction( obj.AddAction(
"ObjectVariablePush", "ObjectVariablePush",
_("Add existing variable"), _("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."), _("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"), _("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
@@ -865,25 +711,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetParameterLongDescription(_("The content of the object variable will " .SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the " "*be copied* and added at the "
"end of the array.")) "end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetHidden();
obj.AddAction(
"ObjectVariablePush2",
_("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("variable", _("Scene variable with the content to add"))
.SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -891,44 +718,38 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add text variable"), _("Add text variable"),
_("Adds a text (string) to the end of an object array variable."), _("Adds a text (string) to the end of an object array variable."),
_("Add text _PARAM2_ to array variable _PARAM1_ of _PARAM0_"), _("Add text _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add")) .AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/") .MarkAsAdvanced();
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
obj.AddAction("ObjectVariablePushNumber", obj.AddAction("ObjectVariablePushNumber",
_("Add number variable"), _("Add number variable"),
_("Adds a number to the end of an object array variable."), _("Adds a number to the end of an object array variable."),
_("Add number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"), _("Add number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add")) .AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/") .MarkAsAdvanced();
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
obj.AddAction( obj.AddAction(
"ObjectVariablePushBool", "ObjectVariablePushBool",
_("Add boolean variable"), _("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."), _("Adds a boolean to the end of an object array variable."),
_("Add boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"), _("Add boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add")) .AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/") .MarkAsAdvanced();
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
obj.AddAction( obj.AddAction(
"ObjectVariableRemoveAt", "ObjectVariableRemoveAt",
@@ -937,13 +758,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"variable."), "variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of " _("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"_PARAM0_"), "_PARAM0_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Index to remove")) .AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddCondition( obj.AddCondition(
@@ -951,14 +771,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Number of children"), _("Number of children"),
_("Compare the number of children in an object array variable."), _("Compare the number of children in an object array variable."),
_("The number of children in the array variable _PARAM1_"), _("The number of children in the array variable _PARAM1_"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddStrExpression( obj.AddStrExpression(
@@ -966,44 +785,40 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("First text child"), _("First text child"),
_("Get the value of the first element of an object array variable, if " _("Get the value of the first element of an object array variable, if "
"it is a text (string) variable."), "it is a text (string) variable."),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression( obj.AddExpression(
"ArrayVariableFirstNumber", "ArrayVariableFirstNumber",
_("First number child"), _("First number child"),
_("Get the value of the first element of an object array variable, if " _("Get the value of the first element of an object array variable, if "
"it is a number variable."), "it is a number variable."),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression( obj.AddStrExpression(
"ArrayVariableLastString", "ArrayVariableLastString",
_("Last text child"), _("Last text child"),
_("Get the value of the last element of an object array variable, if " _("Get the value of the last element of an object array variable, if "
"it is a text (string) variable."), "it is a text (string) variable."),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression( obj.AddExpression(
"ArrayVariableLastNumber", "ArrayVariableLastNumber",
_("Last number child"), _("Last number child"),
_("Get the value of the last element of an object array variable, if " _("Get the value of the last element of an object array variable, if "
"it is a number variable."), "it is a number variable."),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable")) .AddParameter("objectvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddCondition("BehaviorActivated", obj.AddCondition("BehaviorActivated",
_("Behavior activated"), _("Behavior activated"),
@@ -1038,12 +853,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/forceVers24.png", "res/actions/forceVers24.png",
"res/actions/forceVers.png") "res/actions/forceVers.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target Object")) .AddParameter("objectPtr", _("Target Object"))
.AddParameter("expression", _("Speed (in pixels per second)")) .AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true) .AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -1058,13 +873,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/forceTourne24.png", "res/actions/forceTourne24.png",
"res/actions/forceTourne.png") "res/actions/forceTourne.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Rotate around this object")) .AddParameter("objectPtr", _("Rotate around this object"))
.AddParameter("expression", _("Speed (in degrees per second)")) .AddParameter("expression", _("Speed (in degrees per second)"))
.AddParameter("expression", _("Distance (in pixels)")) .AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true) .AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("MettreAutour", obj.AddAction("MettreAutour",
@@ -1092,10 +907,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/ecarter24.png", "res/actions/ecarter24.png",
"res/actions/ecarter.png") "res/actions/ecarter.png")
.SetHidden() .SetHidden()
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectList", "Object 2 (won't move)") .AddParameter("objectList", "Object 2 (won't move)");
.SetHelpPath("/tutorials/how-to-move-objects/");
// Deprecated action // Deprecated action
obj.AddAction("Ecarter", obj.AddAction("Ecarter",
@@ -1119,6 +934,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Position"), _("Position"),
"res/actions/ecarter24.png", "res/actions/ecarter24.png",
"res/actions/ecarter.png") "res/actions/ecarter.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectList", _("Objects (won't move)")) .AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno", .AddParameter("yesorno",
@@ -1127,7 +943,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"", "",
true) true)
.SetDefaultValue("no") .SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple(); .MarkAsSimple();
obj.AddCondition("CollisionPoint", obj.AddCondition("CollisionPoint",
@@ -1140,7 +955,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point")) .AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point")) .AddParameter("expression", _("Y position of the point"))
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple(); .MarkAsSimple();
extension extension
@@ -1172,7 +986,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("expression", _("Time in seconds")) .AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetHidden(); .SetHidden();
obj.AddCondition( obj.AddCondition(
@@ -1188,7 +1001,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time") .AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds")) .AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetManipulatedType("number"); .SetManipulatedType("number");
obj.AddCondition("ObjectTimerPaused", obj.AddCondition("ObjectTimerPaused",
@@ -1200,7 +1012,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timerPaused.png") "res/conditions/timerPaused.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -1213,8 +1024,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer24.png", "res/actions/timer24.png",
"res/actions/timer.png") "res/actions/timer.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer");
.SetHelpPath("/all-features/timers-and-time/");
obj.AddAction("PauseObjectTimer", obj.AddAction("PauseObjectTimer",
_("Pause an object timer"), _("Pause an object timer"),
@@ -1225,7 +1035,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/pauseTimer.png") "res/actions/pauseTimer.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("UnPauseObjectTimer", obj.AddAction("UnPauseObjectTimer",
@@ -1237,7 +1046,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/unPauseTimer.png") "res/actions/unPauseTimer.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("RemoveObjectTimer", obj.AddAction("RemoveObjectTimer",
@@ -1249,7 +1057,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer.png") "res/actions/timer.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddExpression("X", obj.AddExpression("X",
@@ -1278,32 +1085,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("X coordinate of the sum of forces"), _("X coordinate of the sum of forces"),
_("Movement using forces"), _("Movement using forces"),
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"));
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceY", obj.AddExpression("ForceY",
_("Y coordinate of the sum of forces"), _("Y coordinate of the sum of forces"),
_("Y coordinate of the sum of forces"), _("Y coordinate of the sum of forces"),
_("Movement using forces"), _("Movement using forces"),
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"));
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceAngle", obj.AddExpression("ForceAngle",
_("Angle of the sum of forces"), _("Angle of the sum of forces"),
_("Angle of the sum of forces (in degrees)"), _("Angle of the sum of forces (in degrees)"),
_("Movement using forces"), _("Movement using forces"),
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"));
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceLength", obj.AddExpression("ForceLength",
_("Length of the sum of forces"), _("Length of the sum of forces"),
_("Length of the sum of forces"), _("Length of the sum of forces"),
_("Movement using forces"), _("Movement using forces"),
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"));
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("Longueur", obj.AddExpression("Longueur",
_("Length of the sum of forces"), _("Length of the sum of forces"),
@@ -1311,7 +1114,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"), _("Movement using forces"),
"res/actions/force.png") "res/actions/force.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden(); .SetHidden();
obj.AddExpression("Width", obj.AddExpression("Width",
@@ -1401,18 +1203,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Variables"), _("Variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"));
.SetRelevantForFunctionEventsOnly();
obj.AddExpression( obj.AddExpression(
"VariableChildCount", "VariableChildCount",
_("Number of children"), _("Number of children"),
_("Number of children in an object array or structure variable"), _("Number of children in an object array or structure variable"),
_("Variables Arrays and structures"), _("Variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable")) .AddParameter("objectvar", _("Array or structure variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression("VariableString", obj.AddStrExpression("VariableString",
_("Text variable"), _("Text variable"),
@@ -1420,9 +1220,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Variables"), _("Variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable")) .AddParameter("objectvar", _("Variable"));
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddExpression("ObjectTimerElapsedTime", obj.AddExpression("ObjectTimerElapsedTime",
_("Object timer value"), _("Object timer value"),
@@ -1430,8 +1228,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Timers"), _("Timers"),
"res/actions/time.png") "res/actions/time.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer") .AddParameter("identifier", _("Timer's name"), "objectTimer");
.SetHelpPath("/all-features/timers-and-time/");
obj.AddExpression("AngleToObject", obj.AddExpression("AngleToObject",
_("Angle between two objects"), _("Angle between two objects"),
@@ -1651,7 +1448,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/doMove24.png", "res/actions/doMove24.png",
"res/actions/doMove.png") "res/actions/doMove.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -1667,7 +1463,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2")) .AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Tolerance, in degrees")) .AddParameter("expression", _("Tolerance, in degrees"))
.AddCodeOnlyParameter("conditionInverted", "") .AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -1800,7 +1595,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"", "",
true) true)
.SetDefaultValue("no") .SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple(); .MarkAsSimple();
extension extension
@@ -1816,22 +1610,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression", .AddParameter("expression",
_("Angle of tolerance, in degrees (0: minimum tolerance)")) _("Angle of tolerance, in degrees (0: minimum tolerance)"))
.AddCodeOnlyParameter("conditionInverted", "") .AddCodeOnlyParameter("conditionInverted", "")
.SetHidden()
.MarkAsAdvanced();
extension
.AddCondition("IsTurnedTowardObject",
_("An object is turned toward another"),
_("Check if an object is turned toward another"),
_("_PARAM0_ is turned toward _PARAM1_ ± _PARAM2_°"),
_("Angle"),
"res/conditions/estTourne24.png",
"res/conditions/estTourne.png")
.AddParameter("objectList", _("Name of the object"))
.AddParameter("objectList", _("Name of the second object"))
.AddParameter("expression",
_("Angle of tolerance, in degrees (0: minimum tolerance)"))
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -1863,7 +1641,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. " _("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed.")) "If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "") .AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -1895,7 +1672,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. " _("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed.")) "If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "") .AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension

View File

@@ -327,25 +327,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
extension
.AddCondition(
"CameraZoom",
_("Camera zoom"),
_("Compare the zoom of a camera of a layer."),
_("Zoom of camera _PARAM2_ of layer _PARAM1_"),
"",
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Zoom")))
.MarkAsAdvanced();
extension extension
.AddAction( .AddAction(
"FixCamera", "FixCamera",

View File

@@ -68,22 +68,19 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
extension extension
.AddStrExpression("ToJSON", .AddStrExpression("ToJSON",
_("Convert variable to JSON"), _("Convert scene variable to JSON"),
_("Convert a variable to JSON"), _("Convert a scene variable to JSON"),
_("JSON"), _("JSON"),
"res/conditions/toujours24_black.png") "res/conditions/toujours24_black.png")
.AddParameter("variable", _("The variable to be stringified"), .AddParameter("scenevar", _("Scene variable to be stringified"));
"AllowUndeclaredVariable");
// Deprecated
extension extension
.AddStrExpression("GlobalVarToJSON", .AddStrExpression("GlobalVarToJSON",
_("Convert global variable to JSON"), _("Convert global variable to JSON"),
_("Convert a global variable to JSON"), _("Convert a global variable to JSON"),
_("JSON"), _("JSON"),
"res/conditions/toujours24_black.png") "res/conditions/toujours24_black.png")
.AddParameter("globalvar", _("The global variable to be stringified")) .AddParameter("globalvar", _("The global variable to be stringified"));
.SetHidden();
extension extension
.AddStrExpression("ObjectVarToJSON", .AddStrExpression("ObjectVarToJSON",
@@ -94,7 +91,6 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.AddParameter("objectPtr", _("The object with the variable")) .AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified")); .AddParameter("objectvar", _("The object variable to be stringified"));
// Deprecated
extension extension
.AddAction( .AddAction(
"JSONToVariableStructure", "JSONToVariableStructure",
@@ -106,10 +102,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"res/actions/net.png") "res/actions/net.png")
.AddParameter("string", _("JSON string")) .AddParameter("string", _("JSON string"))
.AddParameter("scenevar", _("Variable where store the JSON object")) .AddParameter("scenevar", _("Variable where store the JSON object"))
.MarkAsAdvanced() .MarkAsAdvanced();
.SetHidden();
// Deprecated
extension extension
.AddAction("JSONToGlobalVariableStructure", .AddAction("JSONToGlobalVariableStructure",
_("Convert JSON to global variable"), _("Convert JSON to global variable"),
@@ -122,20 +116,6 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.AddParameter("string", _("JSON string")) .AddParameter("string", _("JSON string"))
.AddParameter("globalvar", .AddParameter("globalvar",
_("Global variable where store the JSON object")) _("Global variable where store the JSON object"))
.MarkAsAdvanced()
.SetHidden();
extension
.AddAction(
"JSONToVariableStructure2",
_("Convert JSON to a variable"),
_("Parse a JSON object and store it into a variable"),
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("variable", _("Variable where to store the JSON object"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension

View File

@@ -92,16 +92,14 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
.SetCanHaveSubInstructions() .SetCanHaveSubInstructions()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension.AddCondition(
.AddCondition("Once", "Once",
_("Trigger once while true"), _("Trigger once while true"),
_("Run actions only once, for each time the conditions " _("Run actions only once, for each time the conditions have been met."),
"have been met."), _("Trigger once"),
_("Trigger once"), "",
"", "res/conditions/once24.png",
"res/conditions/once24.png", "res/conditions/once.png");
"res/conditions/once.png")
.SetHelpPath("/all-features/advanced-conditions/trigger-once");
extension extension
.AddCondition("CompareNumbers", .AddCondition("CompareNumbers",

View File

@@ -28,7 +28,7 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
.AddAction("CreateObjectsFromExternalLayout", .AddAction("CreateObjectsFromExternalLayout",
_("Create objects from an external layout"), _("Create objects from an external layout"),
_("Create objects from an external layout."), _("Create objects from an external layout."),
_("Create objects from the external layout named _PARAM1_ at position _PARAM2_;_PARAM3_;_PARAM4_"), _("Create objects from the external layout named _PARAM1_"),
"", "",
"res/ribbon_default/externallayout32.png", "res/ribbon_default/externallayout32.png",
"res/ribbon_default/externallayout32.png") "res/ribbon_default/externallayout32.png")

View File

@@ -98,7 +98,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Group")) .AddParameter("string", _("Group"))
.AddParameter("string", _("Text")); .AddParameter("string", _("Text"));
// Deprecated
extension extension
.AddAction( .AddAction(
"LireFichierExp", "LireFichierExp",
@@ -115,27 +114,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Storage name")) .AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group")) .AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("scenevar", _("Scene variable")) .AddParameter("scenevar", _("Scene variables"));
.SetHidden();
extension
.AddAction(
"ReadNumberFromStorage",
_("Load a value"),
_("Load the value saved in the specified element and store it in a "
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
_("Load _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
"",
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("variable", _("Variable"));
// Deprecated
extension extension
.AddAction( .AddAction(
"LireFichierTxt", "LireFichierTxt",
@@ -153,26 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Storage name")) .AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group")) .AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("scenevar", _("Scene variable")) .AddParameter("scenevar", _("Scene variables"));
.SetHidden();
extension
.AddAction(
"ReadStringFromStorage",
_("Load a text"),
_("Load the text saved in the specified element and store it in a "
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
_("Load _PARAM1_ from storage _PARAM0_ and store as text in "
"_PARAM3_"),
"",
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("variable", _("Variable"));
extension extension
.AddAction("DeleteGroupFichier", .AddAction("DeleteGroupFichier",

View File

@@ -35,8 +35,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png", "res/conditions/keyboard24.png",
"res/conditions/keyboard.png") "res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key to check")) .AddParameter("key", _("Key"));
.SetHidden();
extension extension
.AddCondition("KeyReleased", .AddCondition("KeyReleased",
@@ -47,32 +46,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png", "res/conditions/keyboard24.png",
"res/conditions/keyboard.png") "res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key to check")) .AddParameter("key", _("Key"));
.SetHidden();
extension extension
.AddCondition("KeyFromTextPressed", .AddCondition("KeyFromTextPressed",
_("Key pressed"), _("Key pressed (text expression)"),
_("Check if a key is pressed"), _("Check if a key, retrieved from the result of the "
"expression, is pressed"),
_("_PARAM1_ key is pressed"), _("_PARAM1_ key is pressed"),
"", "",
"res/conditions/keyboard24.png", "res/conditions/keyboard24.png",
"res/conditions/keyboard.png") "res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("keyboardKey", _("Key to check")) .AddParameter("string", _("Expression generating the key to check"))
.MarkAsSimple(); .MarkAsAdvanced();
extension extension
.AddCondition("KeyFromTextReleased", .AddCondition("KeyFromTextReleased",
_("Key released"), _("Key released (text expression)"),
_("Check if a key was just released"), _("Check if a key, retrieved from the result of the "
"expression, was just released"),
_("_PARAM1_ key is released"), _("_PARAM1_ key is released"),
"", "",
"res/conditions/keyboard24.png", "res/conditions/keyboard24.png",
"res/conditions/keyboard.png") "res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("keyboardKey", _("Key to check")) .AddParameter("string", _("Expression generating the key to check"))
.MarkAsSimple(); .MarkAsAdvanced();
extension extension
.AddCondition("AnyKeyPressed", .AddCondition("AnyKeyPressed",

View File

@@ -151,8 +151,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("abs", .AddExpression("abs",
_("Absolute value"), _("Absolute value"),
_("Return the non-negative value by removing the sign. " _("Absolute value"),
"The absolute value of -8 is 8."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));

View File

@@ -252,8 +252,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/mouse.png") "res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check")) .AddParameter("mouse", _("Button to check"))
.MarkAsSimple() .MarkAsSimple();
.SetHidden();
// Support for deprecated names: // Support for deprecated names:
extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed") extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed")
@@ -263,41 +262,49 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition("MouseButtonReleased", .AddCondition("MouseButtonReleased",
_("Mouse button released"), _("Mouse button released"),
_("Check if the specified mouse button was released."), _("Check if the specified mouse button was released."),
_("Touch or _PARAM1_ mouse button is released"), _("_PARAM1_ mouse button was released"),
"", "",
"res/conditions/mouse24.png", "res/conditions/mouse24.png",
"res/conditions/mouse.png") "res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check")) .AddParameter("mouse", _("Button to check"))
.MarkAsSimple() .MarkAsSimple();
.SetHidden();
extension extension
.AddCondition( .AddCondition(
"MouseButtonFromTextPressed", "MouseButtonFromTextPressed",
_("Mouse button pressed or touch held"), _("Mouse button pressed or touch held (text expression)"),
_("Check if the specified mouse button is pressed or " _("Check if a mouse button, retrieved from the result of the "
"if a touch is in contact with the screen."), "expression, is pressed."),
_("Touch or _PARAM1_ mouse button is down"), _("_PARAM1_ mouse button is pressed"),
"", "",
"res/conditions/mouse24.png", "res/conditions/mouse24.png",
"res/conditions/mouse.png") "res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouseButton", _("Button to check")) .AddParameter("stringWithSelector",
.MarkAsSimple(); _("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
extension extension
.AddCondition( .AddCondition(
"MouseButtonFromTextReleased", "MouseButtonFromTextReleased",
_("Mouse button released"), _("Mouse button released (text expression)"),
_("Check if the specified mouse button was released."), _("Check if a mouse button, retrieved from the result of the "
_("Touch or _PARAM1_ mouse button is released"), "expression, was just released."),
_("_PARAM1_ mouse button is released"),
"", "",
"res/conditions/mouse24.png", "res/conditions/mouse24.png",
"res/conditions/mouse.png") "res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouseButton", _("Button to check")) .AddParameter("stringWithSelector",
.MarkAsSimple(); _("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
extension extension
.AddExpressionAndCondition("number", .AddExpressionAndCondition("number",
@@ -331,7 +338,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
// Deprecated
extension extension
.AddCondition( .AddCondition(
"PopStartedTouch", "PopStartedTouch",
@@ -348,7 +354,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.SetHidden(); .SetHidden();
// Deprecated
extension extension
.AddCondition( .AddCondition(
"PopEndedTouch", "PopEndedTouch",
@@ -365,7 +370,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.SetHidden(); .SetHidden();
// Deprecated
extension extension
.AddCondition( .AddCondition(
"HasAnyTouchStarted", "HasAnyTouchStarted",

View File

@@ -116,13 +116,6 @@ void SpriteAnimationList::ExposeResources(gd::ArbitraryResourceWorker& worker) {
} }
} }
bool SpriteAnimationList::HasAnimationNamed(const gd::String &name) const {
return !name.empty() && (find_if(animations.begin(), animations.end(),
[&name](const Animation &animation) {
return animation.GetName() == name;
}) != animations.end());
}
const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const { const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const {
if (nb >= animations.size()) return badAnimation; if (nb >= animations.size()) return badAnimation;

View File

@@ -51,11 +51,6 @@ class GD_CORE_API SpriteAnimationList {
*/ */
std::size_t GetAnimationsCount() const { return animations.size(); }; std::size_t GetAnimationsCount() const { return animations.size(); };
/**
* \brief Return true if an animation exists for a given name.
*/
bool HasAnimationNamed(const gd::String &name) const;
/** /**
* \brief Add an animation at the end of the existing ones. * \brief Add an animation at the end of the existing ones.
*/ */

View File

@@ -33,7 +33,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"most elements of a game."), "most elements of a game."),
"CppPlatform/Extensions/spriteicon.png") "CppPlatform/Extensions/spriteicon.png")
.SetCategoryFullName(_("General")) .SetCategoryFullName(_("General"))
.SetOpenFullEditorLabel(_("Edit animations"))
.AddDefaultBehavior("EffectCapability::EffectBehavior") .AddDefaultBehavior("EffectCapability::EffectBehavior")
.AddDefaultBehavior("ResizableCapability::ResizableBehavior") .AddDefaultBehavior("ResizableCapability::ResizableBehavior")
.AddDefaultBehavior("ScalableCapability::ScalableBehavior") .AddDefaultBehavior("ScalableCapability::ScalableBehavior")

View File

@@ -24,34 +24,37 @@
namespace gd { namespace gd {
SpriteObject::SpriteObject() SpriteObject::SpriteObject()
: updateIfNotVisible(false), : updateIfNotVisible(false) {}
preScale(1) {}
SpriteObject::~SpriteObject(){}; SpriteObject::~SpriteObject(){};
void SpriteObject::DoUnserializeFrom(gd::Project& project, void SpriteObject::DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) { const gd::SerializerElement& element) {
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true); updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
preScale = element.GetDoubleAttribute("preScale", 1);
animations.UnserializeFrom(element); animations.UnserializeFrom(element);
} }
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const { void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("updateIfNotVisible", updateIfNotVisible); element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
if (preScale != 1) {
element.SetAttribute("preScale", preScale);
}
animations.SerializeTo(element); animations.SerializeTo(element);
} }
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties() std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
const { const {
std::map<gd::String, gd::PropertyDescriptor> properties; std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Animate even if hidden or far from the screen")]
.SetValue(updateIfNotVisible ? "true" : "false")
.SetType("Boolean");
properties["PLEASE_ALSO_SHOW_EDIT_BUTTON_THANKS"].SetValue("");
return properties; return properties;
} }
bool SpriteObject::UpdateProperty(const gd::String& name, bool SpriteObject::UpdateProperty(const gd::String& name,
const gd::String& value) { const gd::String& value) {
if (name == _("Animate even if hidden or far from the screen"))
updateIfNotVisible = value == "1";
return true; return true;
} }
@@ -61,7 +64,9 @@ void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
std::map<gd::String, gd::PropertyDescriptor> std::map<gd::String, gd::PropertyDescriptor>
SpriteObject::GetInitialInstanceProperties( SpriteObject::GetInitialInstanceProperties(
const gd::InitialInstance& initialInstance) { const gd::InitialInstance& initialInstance,
gd::Project& project,
gd::Layout& scene) {
std::map<gd::String, gd::PropertyDescriptor> properties; std::map<gd::String, gd::PropertyDescriptor> properties;
properties["animation"] = properties["animation"] =
gd::PropertyDescriptor( gd::PropertyDescriptor(
@@ -75,7 +80,9 @@ SpriteObject::GetInitialInstanceProperties(
bool SpriteObject::UpdateInitialInstanceProperty( bool SpriteObject::UpdateInitialInstanceProperty(
gd::InitialInstance& initialInstance, gd::InitialInstance& initialInstance,
const gd::String& name, const gd::String& name,
const gd::String& value) { const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == "animation") { if (name == "animation") {
initialInstance.SetRawDoubleProperty( initialInstance.SetRawDoubleProperty(
"animation", std::max(0, value.empty() ? 0 : value.To<int>())); "animation", std::max(0, value.empty() ? 0 : value.To<int>()));
@@ -84,19 +91,6 @@ bool SpriteObject::UpdateInitialInstanceProperty(
return true; return true;
} }
size_t SpriteObject::GetAnimationsCount() const {
return animations.GetAnimationsCount();
}
const gd::String &SpriteObject::GetAnimationName(size_t index) const {
return animations.GetAnimation(index).GetName();
}
bool SpriteObject::HasAnimationNamed(
const gd::String &name) const {
return animations.HasAnimationNamed(name);
}
const SpriteAnimationList& SpriteObject::GetAnimations() const { const SpriteAnimationList& SpriteObject::GetAnimations() const {
return animations; return animations;
} }

View File

@@ -47,17 +47,15 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
bool UpdateProperty(const gd::String& name, const gd::String& value) override; bool UpdateProperty(const gd::String& name, const gd::String& value) override;
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties( std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
const gd::InitialInstance& position) override; const gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) override;
bool UpdateInitialInstanceProperty(gd::InitialInstance& position, bool UpdateInitialInstanceProperty(gd::InitialInstance& position,
const gd::String& name, const gd::String& name,
const gd::String& value) override; const gd::String& value,
gd::Project& project,
gd::Layout& scene) override;
size_t GetAnimationsCount() const override;
const gd::String &GetAnimationName(size_t index) const override;
bool HasAnimationNamed(const gd::String &animationName) const override;
/** /**
* \brief Return the animation configuration. * \brief Return the animation configuration.
*/ */
@@ -82,23 +80,6 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
*/ */
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; } bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
/**
* \brief Return the scale applied to object to evaluate the default dimensions.
*/
double GetPreScale() { return preScale; }
/**
* \brief Set the scale applied to object to evaluate the default dimensions.
*
* Its value must be strictly positive.
*/
void SetPreScale(double preScale_) {
if (preScale_ <= 0) {
return;
}
preScale = preScale_;
}
private: private:
void DoUnserializeFrom(gd::Project& project, void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) override; const gd::SerializerElement& element) override;
@@ -109,7 +90,6 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
bool updateIfNotVisible; ///< If set to true, ask the game engine to play bool updateIfNotVisible; ///< If set to true, ask the game engine to play
///< object animation even if hidden or far from ///< object animation even if hidden or far from
///< the screen. ///< the screen.
double preScale;
}; };
} // namespace gd } // namespace gd

View File

@@ -25,286 +25,29 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension.AddInstructionOrExpressionGroupMetadata(_("Variables")) extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
.SetIcon("res/conditions/var24.png"); .SetIcon("res/conditions/var24.png");
extension
.AddCondition("NumberVariable",
_("Variable value"),
_("Compare the number value of a variable."),
_("The variable _PARAM0_"),
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions());
extension
.AddCondition("StringVariable",
_("Variable value"),
_("Compare the text (string) of a variable."),
_("The variable _PARAM0_"),
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions());
extension
.AddCondition(
"BooleanVariable",
_("Variable value"),
_("Compare the boolean value of a variable."),
_("The variable _PARAM0_ is _PARAM1_"),
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("trueorfalse", "");
extension
.AddAction("SetNumberVariable",
_("Change variable value"),
_("Modify the number value of a variable."),
_("the variable _PARAM0_"),
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions());
extension
.AddAction("SetStringVariable",
_("Change variable value"),
_("Modify the text (string) of a variable."),
_("the variable _PARAM0_"),
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions());
extension
.AddAction(
"SetBooleanVariable",
_("Change variable value"),
_("Modify the boolean value of a variable."),
_("Change the variable _PARAM0_: _PARAM1_"),
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variableOrProperty", _("Variable"))
.AddParameter("operator", _("Value"), "boolean")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("trueorfalse", "");
extension
.AddCondition(
"VariableChildCount",
_("Number of children"),
_("Compare the number of children in an array variable."),
_("The number of children in the array variable _PARAM0_"),
_("Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddCondition("VariableChildExists2",
_("Child existence"),
_("Check if the specified child of the structure "
"variable exists."),
_("Child _PARAM1_ of variable _PARAM0_ exists"),
_("Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction(
"RemoveVariableChild",
_("Remove a child"),
_("Remove a child from a structure variable."),
_("Remove child _PARAM1_ from structure variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("ClearVariableChildren",
_("Clear children"),
_("Remove all the children from the structure or array "
"variable."),
_("Clear children from variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("PushVariable",
_("Add existing variable"),
_("Adds an existing variable at the end of an array "
"variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("variable", _("Variable with the content to add"))
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction(
"PushString",
_("Add value to array variable"),
_("Adds a text (string) at the end of a array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("PushNumber",
_("Add value to array variable"),
_("Adds a number at the end of an array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("PushBoolean",
_("Add value to array variable"),
_("Adds a boolean at the end of an array variable."),
_("Add the value _PARAM1_ to array variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddAction("RemoveVariableAt",
_("Remove variable by index"),
_("Removes a variable at the specified index of an array "
"variable."),
_("Remove variable at index _PARAM1_ from array "
"variable _PARAM0_"),
_("Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
.AddStrExpression(
"VariableFirstString",
_("First text child"),
_("Get the value of the first element of an array variable, if "
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
"VariableFirstNumber",
_("First number child"),
_("Get the value of the first element of an array variable, if "
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddStrExpression(
"VariableLastString",
_("Last text child"),
_("Get the value of the last element of an array variable, if "
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
"VariableLastNumber",
_("Last number child"),
_("Get the value of the last element of an array variable, if "
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
// Legacy instructions
extension extension
.AddCondition("VarScene", .AddCondition("VarScene",
_("Number variable"), _("Number variable"),
_("Compare the number value of a scene variable."), _("Compare the number value of a scene variable."),
_("The number of scene variable _PARAM0_"), _("The number of scene variable _PARAM0_"),
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddCondition("VarSceneTxt", .AddCondition("VarSceneTxt",
_("Text variable"), _("Text variable"),
_("Compare the text (string) of a scene variable."), _("Compare the text (string) of a scene variable."),
_("The text of scene variable _PARAM0_"), _("The text of scene variable _PARAM0_"),
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions()) "string", ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddCondition( .AddCondition(
@@ -312,14 +55,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"), _("Boolean variable"),
_("Compare the boolean value of a scene variable."), _("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"), _("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is")) .AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true") .SetDefaultValue("true");
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddCondition("VariableChildExists", .AddCondition("VariableChildExists",
@@ -327,14 +68,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the scene structure " _("Check if the specified child of the scene structure "
"variable exists."), "variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"), _("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.AddParameter("string", _("Name of the child")) .AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -343,14 +81,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the global structure " _("Check if the specified child of the global structure "
"variable exists."), "variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"), _("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.AddParameter("string", _("Name of the child")) .AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -358,7 +93,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Variable defined", "Variable defined",
"Test if the scene variable exists.", "Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined", "Scene variable _PARAM0_ is defined",
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
@@ -370,14 +105,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number variable"), _("Number variable"),
_("Compare the number value of a global variable."), _("Compare the number value of a global variable."),
_("the global variable _PARAM0_"), _("the global variable _PARAM0_"),
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -385,14 +118,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text variable"), _("Text variable"),
_("Compare the text (string) of a global variable."), _("Compare the text (string) of a global variable."),
_("the text of the global variable _PARAM0_"), _("the text of the global variable _PARAM0_"),
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions()) "string", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -401,21 +132,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"), _("Boolean variable"),
_("Compare the boolean value of a global variable."), _("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"), _("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is")) .AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true") .SetDefaultValue("true");
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddCondition("VarGlobalDef", .AddCondition("VarGlobalDef",
"Variable defined", "Variable defined",
"Test if a global variable exists.", "Test if a global variable exists.",
"Global variable _PARAM0_ is defined", "Global variable _PARAM0_ is defined",
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
@@ -428,28 +157,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change number variable"), _("Change number variable"),
_("Modify the number value of a scene variable."), _("Modify the number value of a scene variable."),
_("the scene variable _PARAM0_"), _("the scene variable _PARAM0_"),
_("External variables Scene variables"), _("Scene variables"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction("ModVarSceneTxt", .AddAction("ModVarSceneTxt",
_("Change text variable"), _("Change text variable"),
_("Modify the text (string) of a scene variable."), _("Modify the text (string) of a scene variable."),
_("the text of scene variable _PARAM0_"), _("the text of scene variable _PARAM0_"),
_("External variables Scene variables"), _("Scene variables"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("string", .UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions());
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction( .AddAction(
@@ -457,13 +182,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"), _("Change boolean variable"),
_("Modify the boolean value of a scene variable."), _("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"), _("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:")) .AddParameter("trueorfalse", _("New Value:"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction("ToggleSceneVariableAsBoolean", .AddAction("ToggleSceneVariableAsBoolean",
@@ -472,26 +195,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was " _("If it was true, it will become false, and if it was "
"false it will become true."), "false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"), _("Toggle the boolean value of scene variable _PARAM0_"),
_("External variables Scene variables"), _("Scene variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction("ModVarGlobal", .AddAction("ModVarGlobal",
_("Change number variable"), _("Change number variable"),
_("Modify the number value of a global variable."), _("Modify the number value of a global variable."),
_("the global variable _PARAM0_"), _("the global variable _PARAM0_"),
_("External variables Global variables"), _("Global variables"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -499,14 +218,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change text variable"), _("Change text variable"),
_("Modify the text (string) of a global variable."), _("Modify the text (string) of a global variable."),
_("the text of global variable _PARAM0_"), _("the text of global variable _PARAM0_"),
_("External variables Global variables"), _("Global variables"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string", .UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions()) ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -515,13 +232,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"), _("Change boolean variable"),
_("Modify the boolean value of a global variable."), _("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"), _("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:")) .AddParameter("trueorfalse", _("New Value:"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction("ToggleGlobalVariableAsBoolean", .AddAction("ToggleGlobalVariableAsBoolean",
@@ -530,12 +245,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was " _("If it was true, it will become false, and if it was "
"false it will become true."), "false it will become true."),
_("Toggle the boolean value of global variable _PARAM0_"), _("Toggle the boolean value of global variable _PARAM0_"),
_("External variables Global variables"), _("Global variables"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction( .AddAction(
@@ -543,15 +256,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"), _("Remove a child"),
_("Remove a child from a scene structure variable."), _("Remove a child from a scene structure variable."),
_("Remove child _PARAM1_ from scene structure variable _PARAM0_"), _("Remove child _PARAM1_ from scene structure variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Structure variable")) .AddParameter("scenevar", _("Structure variable"))
.AddParameter("string", _("Child's name")) .AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/") .MarkAsAdvanced();
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction( .AddAction(
@@ -559,15 +269,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"), _("Remove a child"),
_("Remove a child from a global structure variable."), _("Remove a child from a global structure variable."),
_("Remove child _PARAM1_ from global structure variable _PARAM0_"), _("Remove child _PARAM1_ from global structure variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Structure variable")) .AddParameter("globalvar", _("Structure variable"))
.AddParameter("string", _("Child's name")) .AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/") .MarkAsAdvanced();
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction("VariableClearChildren", .AddAction("VariableClearChildren",
@@ -575,13 +282,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the scene structure or array " _("Remove all the children from the scene structure or array "
"variable."), "variable."),
_("Clear children from scene variable _PARAM0_"), _("Clear children from scene variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Structure or array variable")) .AddParameter("scenevar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -590,13 +294,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the global structure or array " _("Remove all the children from the global structure or array "
"variable."), "variable."),
_("Clear children from global variable _PARAM0_"), _("Clear children from global variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Structure or array variable")) .AddParameter("globalvar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -605,7 +306,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Adds an existing variable at the end of a scene array " _("Adds an existing variable at the end of a scene array "
"variable."), "variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"), _("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
@@ -613,9 +314,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription( .SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the " _("The content of the variable will *be copied* and added at the "
"end of the array.")) "end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -624,14 +322,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"), _("Add text variable"),
_("Adds a text (string) at the end of a scene array variable."), _("Adds a text (string) at the end of a scene array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"), _("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("Text to add")) .AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -639,14 +334,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"), _("Add number variable"),
_("Adds a number at the end of a scene array variable."), _("Adds a number at the end of a scene array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"), _("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to add")) .AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -654,14 +346,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"), _("Add boolean variable"),
_("Adds a boolean at the end of a scene array variable."), _("Adds a boolean at the end of a scene array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"), _("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add")) .AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -671,14 +360,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"variable."), "variable."),
_("Remove variable at index _PARAM1_ from scene array " _("Remove variable at index _PARAM1_ from scene array "
"variable _PARAM0_"), "variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Index to remove")) .AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -687,15 +373,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"), _("Number of children"),
_("Compare the number of children in a scene array variable."), _("Compare the number of children in a scene array variable."),
_("The number of children in the array variable _PARAM0_"), _("The number of children in the array variable _PARAM0_"),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -704,12 +387,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"), _("First text child"),
_("Get the value of the first element of a scene array variable, if " _("Get the value of the first element of a scene array variable, if "
"it is a text (string)."), "it is a text (string)."),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression( .AddExpression(
@@ -717,12 +397,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First number child"), _("First number child"),
_("Get the value of the first element of a scene array variable, if " _("Get the value of the first element of a scene array variable, if "
"it is a number."), "it is a number."),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddStrExpression( .AddStrExpression(
@@ -730,12 +407,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"), _("Last text child"),
_("Get the value of the last element of a scene array variable, if " _("Get the value of the last element of a scene array variable, if "
"it is a text (string)."), "it is a text (string)."),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression( .AddExpression(
@@ -743,12 +417,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"), _("Last number child"),
_("Get the value of the last element of a scene array variable, if " _("Get the value of the last element of a scene array variable, if "
"it is a number."), "it is a number."),
_("External variables Scene variables Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Array variable")) .AddParameter("scenevar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddAction( .AddAction(
@@ -756,7 +427,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add existing variable"), _("Add existing variable"),
_("Adds an existing variable at the end of a global array variable."), _("Adds an existing variable at the end of a global array variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"), _("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
@@ -764,9 +435,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription( .SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the " _("The content of the variable will *be copied* and added at the "
"end of the array.")) "end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -776,14 +444,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"array variable."), "array variable."),
_("Remove variable at index _PARAM1_ from global array " _("Remove variable at index _PARAM1_ from global array "
"variable _PARAM0_"), "variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Index to remove")) .AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -792,14 +457,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"), _("Add text variable"),
_("Adds a text (string) at the end of a global array variable."), _("Adds a text (string) at the end of a global array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"), _("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("Text to add")) .AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -807,14 +469,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"), _("Add number variable"),
_("Adds a number at the end of a global array variable."), _("Adds a number at the end of a global array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"), _("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to add")) .AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -822,14 +481,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"), _("Add boolean variable"),
_("Adds a boolean at the end of a global array variable."), _("Adds a boolean at the end of a global array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"), _("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var24.png", "res/actions/var24.png",
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add")) .AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -838,15 +494,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"), _("Number of children"),
_("Compare the number of children in a global array variable."), _("Compare the number of children in a global array variable."),
_("The number of children of the array variable _PARAM0_"), _("The number of children of the array variable _PARAM0_"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/conditions/var24.png", "res/conditions/var24.png",
"res/conditions/var.png") "res/conditions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions()) "number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -854,24 +507,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"), _("First text child"),
_("Value of the first element of a global array " _("Value of the first element of a global array "
"variable, if it is a text (string) variable."), "variable, if it is a text (string) variable."),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression("GlobalVariableFirstNumber", .AddExpression("GlobalVariableFirstNumber",
_("First number child"), _("First number child"),
_("Value of the first element of a global array " _("Value of the first element of a global array "
"variable, if it is a number variable"), "variable, if it is a number variable"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddStrExpression( .AddStrExpression(
@@ -879,12 +526,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"), _("Last text child"),
_("Value of the last element of a global array variable, if " _("Value of the last element of a global array variable, if "
"it is a text (string) variable."), "it is a text (string) variable."),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression( .AddExpression(
@@ -892,73 +536,59 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"), _("Last number child"),
_("Value of the last element of a global array variable, if " _("Value of the last element of a global array variable, if "
"it is a number variable"), "it is a number variable"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array variable")) .AddParameter("globalvar", _("Array variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression("GlobalVariableChildCount", .AddExpression("GlobalVariableChildCount",
_("Number of children"), _("Number of children"),
_("Number of children in a global array or " _("Number of children in a global array or "
"structure variable"), "structure variable"),
_("External variables Global variables Arrays and structures"), _("Global variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Array or structure variable")) .AddParameter("globalvar", _("Array or structure variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression("VariableChildCount", .AddExpression("VariableChildCount",
_("Number of children"), _("Number of children"),
_("Number of children in a scene array or " _("Number of children in a scene array or "
"structure variable"), "structure variable"),
_("Arrays and structures"), _("Scene variables/Arrays and structures"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable") .AddParameter("scenevar", _("Array or structure variable"));
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension extension
.AddExpression("Variable", .AddExpression("Variable",
_("Number variable"), _("Number variable"),
_("Number value of a scene variable"), _("Number value of a scene variable"),
_("External variables Scene variables"), _("Scene variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddStrExpression("VariableString", .AddStrExpression("VariableString",
_("Text variable"), _("Text variable"),
_("Text of a scene variable"), _("Text of a scene variable"),
_("External variables Scene variables"), _("Scene variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("scenevar", _("Variable")) .AddParameter("scenevar", _("Variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddExpression("GlobalVariable", .AddExpression("GlobalVariable",
_("Number variable"), _("Number variable"),
_("Number value of a global variable"), _("Number value of a global variable"),
_("External variables Global variables"), _("Global variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable")) .AddParameter("globalvar", _("Name of the global variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddStrExpression("GlobalVariableString", .AddStrExpression("GlobalVariableString",
_("Text variable"), _("Text variable"),
_("Text of a global variable"), _("Text of a global variable"),
_("External variables Global variables"), _("Global variables"),
"res/actions/var.png") "res/actions/var.png")
.AddParameter("globalvar", _("Variable")) .AddParameter("globalvar", _("Variable"));
.SetRelevantForFunctionEventsOnly()
.SetHidden();
} }
} // namespace gd } // namespace gd

View File

@@ -424,7 +424,7 @@ std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() c
return instance->GetProperties(); return instance->GetProperties();
} }
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const { gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
return sharedDatasInstance.get(); return sharedDatasInstance.get();
} }
@@ -440,18 +440,12 @@ std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperti
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const { const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
requiredBehaviors.clear(); requiredBehaviors.clear();
if (!instance) { for (auto& property : Get().GetProperties()) {
return requiredBehaviors;
}
for (auto& property : instance->GetProperties()) {
const String& propertyName = property.first; const String& propertyName = property.first;
const gd::PropertyDescriptor& propertyDescriptor = property.second; const gd::PropertyDescriptor& propertyDescriptor = property.second;
if (propertyDescriptor.GetType() == "Behavior") { if (propertyDescriptor.GetType() == "Behavior") {
const auto& extraInfos = propertyDescriptor.GetExtraInfo(); requiredBehaviors.push_back(propertyDescriptor.GetExtraInfo()[0]);
if (extraInfos.size() > 0) {
requiredBehaviors.push_back(extraInfos[0]);
}
} }
} }
return requiredBehaviors; return requiredBehaviors;

View File

@@ -12,7 +12,6 @@
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h" #include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h" #include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h" #include "GDCore/String.h"
#include "GDCore/Project/QuickCustomization.h"
namespace gd { namespace gd {
class Behavior; class Behavior;
class BehaviorsSharedData; class BehaviorsSharedData;
@@ -42,10 +41,10 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
const gd::String& className_, const gd::String& className_,
std::shared_ptr<gd::Behavior> instance, std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance); std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/** /**
* \brief Construct a behavior metadata, without "blueprint" behavior. * \brief Construct a behavior metadata, without "blueprint" behavior.
* *
* \note This is used by events based behaviors. * \note This is used by events based behaviors.
*/ */
BehaviorMetadata( BehaviorMetadata(
@@ -272,7 +271,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
* Check if the behavior is private - it can't be used outside of its * Check if the behavior is private - it can't be used outside of its
* extension. * extension.
*/ */
bool IsPrivate() const override { return isPrivate; } bool IsPrivate() const { return isPrivate; }
/** /**
* Set that the behavior is private - it can't be used outside of its * Set that the behavior is private - it can't be used outside of its
@@ -298,27 +297,9 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
return *this; return *this;
} }
QuickCustomization::Visibility GetQuickCustomizationVisibility() const {
return quickCustomizationVisibility;
}
BehaviorMetadata &SetQuickCustomizationVisibility(QuickCustomization::Visibility visibility) {
quickCustomizationVisibility = visibility;
return *this;
}
BehaviorMetadata &SetOpenFullEditorLabel(const gd::String& label) {
openFullEditorLabel = label;
return *this;
}
const gd::String& GetOpenFullEditorLabel() const {
return openFullEditorLabel;
}
/** /**
* \brief Return the associated gd::Behavior, handling behavior contents. * \brief Return the associated gd::Behavior, handling behavior contents.
* *
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior * \note Returns a dumb Behavior for events based behaviors as CustomBehavior
* are using EventBasedBehavior. * are using EventBasedBehavior.
*/ */
@@ -336,7 +317,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
/** /**
* \brief Return the associated gd::BehaviorsSharedData, handling behavior * \brief Return the associated gd::BehaviorsSharedData, handling behavior
* shared data, if any (nullptr if none). * shared data, if any (nullptr if none).
* *
* \note Returns nullptr for events based behaviors as they don't declare * \note Returns nullptr for events based behaviors as they don't declare
* shared data yet. * shared data yet.
*/ */
@@ -393,8 +374,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
mutable std::vector<gd::String> requiredBehaviors; mutable std::vector<gd::String> requiredBehaviors;
bool isPrivate = false; bool isPrivate = false;
bool isHidden = false; bool isHidden = false;
gd::String openFullEditorLabel;
QuickCustomization::Visibility quickCustomizationVisibility = QuickCustomization::Visibility::Default;
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership. // TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
std::shared_ptr<gd::Behavior> instance; std::shared_ptr<gd::Behavior> instance;

View File

@@ -185,10 +185,10 @@ class GD_CORE_API EffectMetadata {
gd::String fullname; gd::String fullname;
gd::String description; gd::String description;
std::vector<gd::String> includeFiles; std::vector<gd::String> includeFiles;
bool isMarkedAsNotWorkingForObjects = false; bool isMarkedAsNotWorkingForObjects;
bool isMarkedAsOnlyWorkingFor2D = false; bool isMarkedAsOnlyWorkingFor2D;
bool isMarkedAsOnlyWorkingFor3D = false; bool isMarkedAsOnlyWorkingFor3D;
bool isMarkedAsUnique = false; bool isMarkedAsUnique;
std::map<gd::String, gd::PropertyDescriptor> properties; std::map<gd::String, gd::PropertyDescriptor> properties;
}; };

View File

@@ -19,8 +19,7 @@ EventMetadata::EventMetadata(const gd::String &name_,
: fullname(fullname_), : fullname(fullname_),
description(description_), description(description_),
group(group_), group(group_),
instance(instance_), instance(instance_) {
hasCustomCodeGenerator(false) {
ClearCodeGenerationAndPreprocessing(); ClearCodeGenerationAndPreprocessing();
if (instance) instance->SetType(name_); if (instance) instance->SetType(name_);
} }

View File

@@ -83,7 +83,7 @@ class GD_CORE_API EventMetadata {
gd::String group; gd::String group;
std::shared_ptr<gd::BaseEvent> instance; std::shared_ptr<gd::BaseEvent> instance;
bool hasCustomCodeGenerator = false; bool hasCustomCodeGenerator;
std::function<gd::String(gd::BaseEvent& event, std::function<gd::String(gd::BaseEvent& event,
gd::EventsCodeGenerator& codeGenerator, gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context)> gd::EventsCodeGenerationContext& context)>

View File

@@ -38,12 +38,12 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
const gd::String& description, const gd::String& description,
const gd::String& supplementaryInformation, const gd::String& supplementaryInformation,
bool parameterIsOptional) { bool parameterIsOptional) {
parameters.AddNewParameter("") gd::ParameterMetadata info;
.SetType(type) info.SetType(type);
.SetDescription(description) info.description = description;
.SetCodeOnly(false) info.codeOnly = false;
.SetOptional(parameterIsOptional) info.SetOptional(parameterIsOptional);
.SetExtraInfo( info.SetExtraInfo(
// For objects/behavior, the supplementary information // For objects/behavior, the supplementary information
// parameter is an object/behavior type... // parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) || ((gd::ParameterMetadata::IsObject(type) ||
@@ -59,16 +59,22 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
// TODO: Assert against supplementaryInformation === "emsc" (when running with // TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter. // Emscripten), and warn about a missing argument when calling addParameter.
parameters.push_back(info);
return *this; return *this;
} }
gd::ExpressionMetadata &ExpressionMetadata::AddCodeOnlyParameter( gd::ExpressionMetadata& ExpressionMetadata::AddCodeOnlyParameter(
const gd::String &type, const gd::String &supplementaryInformation) { const gd::String& type, const gd::String& supplementaryInformation) {
parameters.AddNewParameter("").SetType(type).SetCodeOnly().SetExtraInfo( gd::ParameterMetadata info;
supplementaryInformation); info.SetType(type);
info.codeOnly = true;
info.SetExtraInfo(supplementaryInformation);
parameters.push_back(info);
return *this; return *this;
} }
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability( gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
const gd::String& capability) { const gd::String& capability) {
requiredBaseObjectCapability = capability; requiredBaseObjectCapability = capability;

View File

@@ -193,9 +193,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter * \see AddParameter
*/ */
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override { ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty())
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue); parameters.back().SetDefaultValue(defaultValue);
}
return *this; return *this;
}; };
@@ -207,9 +206,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
*/ */
ExpressionMetadata & ExpressionMetadata &
SetParameterLongDescription(const gd::String &longDescription) override { SetParameterLongDescription(const gd::String &longDescription) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty())
parameters.GetInternalVector().back()->SetLongDescription(longDescription); parameters.back().SetLongDescription(longDescription);
}
return *this; return *this;
}; };
@@ -222,9 +220,7 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
*/ */
ExpressionMetadata &SetParameterExtraInfo( ExpressionMetadata &SetParameterExtraInfo(
const gd::String &extraInfo) override { const gd::String &extraInfo) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
}
return *this; return *this;
} }
@@ -252,16 +248,19 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
const gd::String& GetGroup() const { return group; } const gd::String& GetGroup() const { return group; }
const gd::String& GetSmallIconFilename() const { return smallIconFilename; } const gd::String& GetSmallIconFilename() const { return smallIconFilename; }
const gd::ParameterMetadata& GetParameter(std::size_t id) const { const gd::ParameterMetadata& GetParameter(std::size_t id) const {
return parameters.GetParameter(id); return parameters[id];
}; };
gd::ParameterMetadata& GetParameter(std::size_t id) { gd::ParameterMetadata& GetParameter(std::size_t id) {
return parameters.GetParameter(id); return parameters[id];
}; };
std::size_t GetParametersCount() const { return parameters.GetParametersCount(); }; std::size_t GetParametersCount() const { return parameters.size(); };
const gd::ParameterMetadataContainer& GetParameters() const { const std::vector<gd::ParameterMetadata>& GetParameters() const {
return parameters; return parameters;
}; };
std::vector<gd::ParameterMetadata> parameters;
/** /**
* \brief Set the function name which will be used when generating the code. * \brief Set the function name which will be used when generating the code.
* \param functionName the name of the function to call * \param functionName the name of the function to call
@@ -369,8 +368,6 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
bool isPrivate; bool isPrivate;
gd::String requiredBaseObjectCapability; gd::String requiredBaseObjectCapability;
gd::String relevantContext; gd::String relevantContext;
gd::ParameterMetadataContainer parameters;
}; };
} // namespace gd } // namespace gd

View File

@@ -9,7 +9,6 @@
#include "GDCore/CommonTools.h" #include "GDCore/CommonTools.h"
#include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h" #include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/Log.h" #include "GDCore/Tools/Log.h"
@@ -78,7 +77,7 @@ InstructionMetadata& InstructionMetadata::AddParameter(
// TODO: Assert against supplementaryInformation === "emsc" (when running with // TODO: Assert against supplementaryInformation === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter. // Emscripten), and warn about a missing argument when calling addParameter.
parameters.AddParameter(info); parameters.push_back(info);
return *this; return *this;
} }
@@ -89,7 +88,7 @@ InstructionMetadata& InstructionMetadata::AddCodeOnlyParameter(
info.codeOnly = true; info.codeOnly = true;
info.SetExtraInfo(supplementaryInformation); info.SetExtraInfo(supplementaryInformation);
parameters.AddParameter(info); parameters.push_back(info);
return *this; return *this;
} }
@@ -103,7 +102,7 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
AddParameter( AddParameter(
"yesorno", "yesorno",
options.description.empty() ? _("New value") : options.description); options.description.empty() ? _("New value") : options.description);
size_t valueParamIndex = parameters.GetParametersCount() - 1; size_t valueParamIndex = parameters.size() - 1;
if (isObjectInstruction || isBehaviorInstruction) { if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("Set _PARAM0_ as <subject>: <value>"); gd::String templateSentence = _("Set _PARAM0_ as <subject>: <value>");
@@ -128,8 +127,8 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
options.description.empty() ? _("Value") : options.description, options.description.empty() ? _("Value") : options.description,
options.typeExtraInfo); options.typeExtraInfo);
size_t operatorParamIndex = parameters.GetParametersCount() - 2; size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.GetParametersCount() - 1; size_t valueParamIndex = parameters.size() - 1;
if (isObjectInstruction || isBehaviorInstruction) { if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("Change <subject> of _PARAM0_: <operator> <value>"); gd::String templateSentence = _("Change <subject> of _PARAM0_: <operator> <value>");
@@ -182,8 +181,8 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
AddParameter(type, AddParameter(type,
options.description.empty() ? _("Value to compare") : options.description, options.description.empty() ? _("Value to compare") : options.description,
options.typeExtraInfo); options.typeExtraInfo);
size_t operatorParamIndex = parameters.GetParametersCount() - 2; size_t operatorParamIndex = parameters.size() - 2;
size_t valueParamIndex = parameters.GetParametersCount() - 1; size_t valueParamIndex = parameters.size() - 1;
if (isObjectInstruction || isBehaviorInstruction) { if (isObjectInstruction || isBehaviorInstruction) {
gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>"); gd::String templateSentence = _("<subject> of _PARAM0_ <operator> <value>");

View File

@@ -14,7 +14,6 @@
#include <memory> #include <memory>
#include "GDCore/Events/Instruction.h" #include "GDCore/Events/Instruction.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/String.h" #include "GDCore/String.h"
#include "ParameterMetadata.h" #include "ParameterMetadata.h"
#include "ParameterOptions.h" #include "ParameterOptions.h"
@@ -62,12 +61,12 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
const gd::String &GetDescription() const { return description; } const gd::String &GetDescription() const { return description; }
const gd::String &GetSentence() const { return sentence; } const gd::String &GetSentence() const { return sentence; }
const gd::String &GetGroup() const { return group; } const gd::String &GetGroup() const { return group; }
ParameterMetadata &GetParameter(size_t i) { return parameters.GetParameter(i); } ParameterMetadata &GetParameter(size_t i) { return parameters[i]; }
const ParameterMetadata &GetParameter(size_t i) const { const ParameterMetadata &GetParameter(size_t i) const {
return parameters.GetParameter(i); return parameters[i];
} }
size_t GetParametersCount() const { return parameters.GetParametersCount(); } size_t GetParametersCount() const { return parameters.size(); }
const ParameterMetadataContainer &GetParameters() const { const std::vector<ParameterMetadata> &GetParameters() const {
return parameters; return parameters;
} }
const gd::String &GetIconFilename() const { return iconFilename; } const gd::String &GetIconFilename() const { return iconFilename; }
@@ -257,9 +256,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter * \see AddParameter
*/ */
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override { InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue_);
}
return *this; return *this;
}; };
@@ -271,9 +268,8 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
*/ */
InstructionMetadata &SetParameterLongDescription( InstructionMetadata &SetParameterLongDescription(
const gd::String &longDescription) override { const gd::String &longDescription) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty())
parameters.GetInternalVector().back()->SetLongDescription(longDescription); parameters.back().SetLongDescription(longDescription);
}
return *this; return *this;
} }
@@ -285,9 +281,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter * \see AddParameter
*/ */
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override { InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
if (parameters.GetParametersCount() > 0) { if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
}
return *this; return *this;
} }
@@ -462,15 +456,6 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
return *this; return *this;
} }
/**
* \brief Return the type manipulated in a standard way by the instruction.
*
* \param type "number" or "string"
*/
const gd::String &GetManipulatedType() const {
return codeExtraInformation.type;
}
/** /**
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called * If InstructionMetadata::ExtraInformation::SetManipulatedType was called
* with "number" or "string", this function will tell the code generator the * with "number" or "string", this function will tell the code generator the
@@ -566,7 +551,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
*/ */
InstructionMetadata &GetCodeExtraInformation() { return *this; } InstructionMetadata &GetCodeExtraInformation() { return *this; }
ParameterMetadataContainer parameters; std::vector<ParameterMetadata> parameters;
private: private:
gd::String fullname; gd::String fullname;

View File

@@ -174,7 +174,6 @@ public:
virtual const gd::String &GetFullName() const = 0; virtual const gd::String &GetFullName() const = 0;
virtual const gd::String &GetDescription() const = 0; virtual const gd::String &GetDescription() const = 0;
virtual const gd::String &GetIconFilename() const = 0; virtual const gd::String &GetIconFilename() const = 0;
virtual bool IsPrivate() const = 0;
/** /**
* \brief Return a reference to a map containing the names of the actions * \brief Return a reference to a map containing the names of the actions

View File

@@ -454,12 +454,11 @@ const gd::ParameterMetadata* MetadataProvider::GetFunctionCallParameterMetadata(
// TODO use a badMetadata instead of a nullptr? // TODO use a badMetadata instead of a nullptr?
const gd::ParameterMetadata* parameterMetadata = nullptr; const gd::ParameterMetadata* parameterMetadata = nullptr;
while (metadataParameterIndex < while (metadataParameterIndex <
metadata.GetParameters().GetParametersCount()) { metadata.parameters.size()) {
if (!metadata.GetParameters().GetParameter(metadataParameterIndex) if (!metadata.parameters[metadataParameterIndex]
.IsCodeOnly()) { .IsCodeOnly()) {
if (visibleParameterIndex == parameterIndex) { if (visibleParameterIndex == parameterIndex) {
parameterMetadata = parameterMetadata = &metadata.parameters[metadataParameterIndex];
&metadata.GetParameters().GetParameter(metadataParameterIndex);
} }
visibleParameterIndex++; visibleParameterIndex++;
} }

View File

@@ -288,8 +288,8 @@ class GD_CORE_API MetadataProvider {
static EffectMetadata badEffectMetadata; static EffectMetadata badEffectMetadata;
static gd::InstructionMetadata badInstructionMetadata; static gd::InstructionMetadata badInstructionMetadata;
static gd::ExpressionMetadata badExpressionMetadata; static gd::ExpressionMetadata badExpressionMetadata;
int useless = 0; // Useless member to avoid emscripten "must have a positive int useless; // Useless member to avoid emscripten "must have a positive
// integer typeid pointer" runtime error. // integer typeid pointer" runtime error.
}; };
} // namespace gd } // namespace gd

View File

@@ -46,25 +46,30 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& fullname_, const gd::String& fullname_,
const gd::String& description_, const gd::String& description_,
const gd::String& icon24x24) const gd::String& icon24x24)
: name(name_), : ObjectMetadata(extensionNamespace_,
iconFilename(icon24x24), name_,
extensionNamespace(extensionNamespace_) { fullname_,
SetFullName(gd::String(fullname_)); description_,
SetDescription(gd::String(description_)); icon24x24,
} []() -> std::unique_ptr<gd::ObjectConfiguration> {
gd::LogFatalError(
"Error: Event-based objects don't have blueprint. "
"This method should not never be called.");
return nullptr;
}) {}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_, ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_, const gd::String& name_,
const gd::String& fullname_, const gd::String& fullname_,
const gd::String& description_, const gd::String& description_,
const gd::String& icon24x24, const gd::String& icon24x24,
CreateFunPtr createFunPtr_) CreateFunPtr createFunPtrP)
: ObjectMetadata(extensionNamespace_, : name(name_),
name_, iconFilename(icon24x24),
fullname_, createFunPtr(createFunPtrP),
description_, extensionNamespace(extensionNamespace_) {
icon24x24) { SetFullName(gd::String(fullname_));
createFunPtr = createFunPtr_; SetDescription(gd::String(description_));
} }
gd::InstructionMetadata& ObjectMetadata::AddCondition( gd::InstructionMetadata& ObjectMetadata::AddCondition(

View File

@@ -39,8 +39,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/** /**
* \brief Construct an object metadata, using a "blueprint" object that will * \brief Construct an object metadata, using a "blueprint" object that will
* be copied when a new object is requested. * be copied when a new object is requested.
*
* \note This is used for objects declared in JavaScript extensions.
*/ */
ObjectMetadata(const gd::String& extensionNamespace_, ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_, const gd::String& name_,
@@ -49,9 +47,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
const gd::String& icon24x24_, const gd::String& icon24x24_,
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_); std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
/** /**
* \brief Construct an object metadata. * \brief Construct an object metadata, without "blueprint" object
* *
* \note This is used by events based objects ("custom objects"). * \note This is used by events based objects.
*/ */
ObjectMetadata(const gd::String& extensionNamespace_, ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_, const gd::String& name_,
@@ -62,17 +60,14 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/** /**
* \brief Construct an object metadata, with a function that will be called * \brief Construct an object metadata, with a function that will be called
* to instantiate a new object. * to instantiate a new object.
*
* \note This is used for objects declared in C++ extensions.
*/ */
ObjectMetadata(const gd::String& extensionNamespace_, ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_, const gd::String& name_,
const gd::String& fullname_, const gd::String& fullname_,
const gd::String& description_, const gd::String& description_,
const gd::String& icon24x24_, const gd::String& icon24x24_,
CreateFunPtr createFunPtr_); CreateFunPtr createFunPtrP);
ObjectMetadata() : createFunPtr(NULL) {}
ObjectMetadata() {}
virtual ~ObjectMetadata(){}; virtual ~ObjectMetadata(){};
/** /**
@@ -251,11 +246,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
return *this; return *this;
} }
ObjectMetadata& ResetDefaultBehaviorsJustForTesting() {
defaultBehaviorTypes.clear();
return *this;
}
const gd::String& GetName() const override { return name; } const gd::String& GetName() const override { return name; }
const gd::String& GetFullName() const override { return fullname; } const gd::String& GetFullName() const override { return fullname; }
const gd::String& GetCategoryFullName() const { return categoryFullName; } const gd::String& GetCategoryFullName() const { return categoryFullName; }
@@ -305,22 +295,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
*/ */
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; }; std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
/**
* Check if the behavior is private - it can't be used outside of its
* extension.
*/
bool IsPrivate() const override { return isPrivate; }
/**
* Set that the behavior is private - it can't be used outside of its
* extension.
*/
ObjectMetadata &SetPrivate() {
isPrivate = true;
return *this;
}
/** /**
* \brief Set the object to be hidden in the IDE. * \brief Set the object to be hidden in the IDE.
* *
@@ -349,15 +323,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
*/ */
bool IsRenderedIn3D() const { return isRenderedIn3D; } bool IsRenderedIn3D() const { return isRenderedIn3D; }
ObjectMetadata &SetOpenFullEditorLabel(const gd::String& label) {
openFullEditorLabel = label;
return *this;
}
const gd::String& GetOpenFullEditorLabel() const {
return openFullEditorLabel;
}
std::map<gd::String, gd::InstructionMetadata> conditionsInfos; std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos; std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos; std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
@@ -365,7 +330,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
std::vector<gd::String> includeFiles; std::vector<gd::String> includeFiles;
gd::String className; gd::String className;
CreateFunPtr createFunPtr = nullptr; CreateFunPtr createFunPtr;
private: private:
gd::String extensionNamespace; gd::String extensionNamespace;
@@ -377,10 +342,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
gd::String iconFilename; gd::String iconFilename;
gd::String categoryFullName; gd::String categoryFullName;
std::set<gd::String> defaultBehaviorTypes; std::set<gd::String> defaultBehaviorTypes;
bool isPrivate = false;
bool hidden = false; bool hidden = false;
bool isRenderedIn3D = false; bool isRenderedIn3D = false;
gd::String openFullEditorLabel;
std::shared_ptr<gd::ObjectConfiguration> std::shared_ptr<gd::ObjectConfiguration>
blueprintObject; ///< The "blueprint" object to be copied when a new blueprintObject; ///< The "blueprint" object to be copied when a new

View File

@@ -4,8 +4,8 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef PARAMETER_METADATA_H
#define PARAMETER_METADATA_H
#include <map> #include <map>
#include <memory> #include <memory>
@@ -29,12 +29,6 @@ class GD_CORE_API ParameterMetadata {
ParameterMetadata(); ParameterMetadata();
virtual ~ParameterMetadata(){}; virtual ~ParameterMetadata(){};
/**
* \brief Return a pointer to a new ParameterMetadata constructed from
* this one.
*/
ParameterMetadata* Clone() const { return new ParameterMetadata(*this); };
/** /**
* \brief Return the metadata of the parameter type. * \brief Return the metadata of the parameter type.
*/ */
@@ -254,3 +248,5 @@ class GD_CORE_API ParameterMetadata {
}; };
} // namespace gd } // namespace gd
#endif // PARAMETER_METADATA_H

View File

@@ -6,157 +6,86 @@
#include "ParameterMetadataTools.h" #include "ParameterMetadataTools.h"
#include "GDCore/Events/Expression.h" #include "GDCore/Events/Expression.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/Project/Object.h" #include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectsContainer.h" #include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainersList.h" #include "GDCore/Project/ObjectsContainersList.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/String.h" #include "GDCore/String.h"
#include "InstructionMetadata.h" #include "InstructionMetadata.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
namespace gd { namespace gd {
const ParameterMetadata ParameterMetadataTools::badParameterMetadata; const ParameterMetadata ParameterMetadataTools::badParameterMetadata;
void ParameterMetadataTools::ParametersToObjectsContainer( void ParameterMetadataTools::ParametersToObjectsContainer(
const gd::Project& project, const gd::Project& project,
const ParameterMetadataContainer& parameters, const std::vector<gd::ParameterMetadata>& parameters,
gd::ObjectsContainer& outputObjectsContainer) { gd::ObjectsContainer& outputObjectsContainer) {
// Keep track of all objects and their behaviors names, so we can remove outputObjectsContainer.GetObjects().clear();
// those who are in the container but not in the parameters anymore.
std::set<gd::String> allObjectNames;
std::map<gd::String, std::set<gd::String>> allObjectNonDefaultBehaviorNames;
gd::String lastObjectName; gd::String lastObjectName;
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) { for (std::size_t i = 0; i < parameters.size(); ++i) {
const auto& parameter = parameters.GetParameter(i); const auto& parameter = parameters[i];
if (parameter.GetName().empty()) continue; if (parameter.GetName().empty()) continue;
auto &valueTypeMetadata = parameter.GetValueTypeMetadata(); if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
if (valueTypeMetadata.IsObject()) { outputObjectsContainer.InsertNewObject(
const gd::String& objectName = parameter.GetName(); project,
const gd::String& objectType = parameter.GetExtraInfo(); parameter.GetExtraInfo(),
allObjectNames.insert(objectName); parameter.GetName(),
outputObjectsContainer.GetObjectsCount());
// Check if we can keep the existing object.
if (outputObjectsContainer.HasObjectNamed(objectName)) {
const gd::Object& object = outputObjectsContainer.GetObject(objectName);
if (object.GetType() != objectType) {
// Object type has changed, remove it so it is re-created.
outputObjectsContainer.RemoveObject(objectName);
}
}
if (outputObjectsContainer.HasObjectNamed(objectName)) {
// Keep the existing object, ensure the default behaviors
// are all present (and no more than required by the object type).
// Non default behaviors coming from parameters will be added or removed later.
project.EnsureObjectDefaultBehaviors(outputObjectsContainer.GetObject(objectName));
} else {
// Create a new object (and its default behaviors) if needed.
outputObjectsContainer.InsertNewObject(
project,
objectType,
objectName,
outputObjectsContainer.GetObjectsCount());
}
// Memorize the last object name. By convention, parameters that require // Memorize the last object name. By convention, parameters that require
// an object (mainly, "objectvar" and "behavior") should be placed after // an object (mainly, "objectvar" and "behavior") should be placed after
// the object in the list of parameters (if possible, just after). // the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this // Search "lastObjectName" in the codebase for other place where this
// convention is enforced. // convention is enforced.
lastObjectName = objectName; lastObjectName = parameter.GetName();
} else if (valueTypeMetadata.IsBehavior()) { } else if (gd::ParameterMetadata::IsBehavior(parameter.GetType())) {
if (!lastObjectName.empty()) { if (!lastObjectName.empty()) {
if (outputObjectsContainer.HasObjectNamed(lastObjectName)) { if (outputObjectsContainer.HasObjectNamed(lastObjectName)) {
const gd::String& behaviorName = parameter.GetName(); const gd::Object& object =
const gd::String& behaviorType = parameter.GetExtraInfo(); outputObjectsContainer.GetObject(lastObjectName);
gd::String behaviorName = parameter.GetName();
gd::Object& object = outputObjectsContainer.GetObject(lastObjectName);
allObjectNonDefaultBehaviorNames[lastObjectName].insert(behaviorName);
// Check if we can keep the existing behavior.
if (object.HasBehaviorNamed(behaviorName)) {
if (object.GetBehavior(behaviorName).GetTypeName() !=
behaviorType) {
// Behavior type has changed, remove it so it is re-created.
object.RemoveBehavior(behaviorName);
}
}
if (!object.HasBehaviorNamed(behaviorName)) { if (!object.HasBehaviorNamed(behaviorName)) {
object.AddNewBehavior( outputObjectsContainer.GetObject(lastObjectName)
project, parameter.GetExtraInfo(), behaviorName); .AddNewBehavior(
project, parameter.GetExtraInfo(), behaviorName);
} }
} }
} }
} }
} }
// Remove objects that are not in the parameters anymore.
std::set<gd::String> objectNamesInContainer =
outputObjectsContainer.GetAllObjectNames();
for (const auto& objectName : objectNamesInContainer) {
if (allObjectNames.find(objectName) == allObjectNames.end()) {
outputObjectsContainer.RemoveObject(objectName);
}
}
// Remove behaviors of objects that are not in the parameters anymore.
for (const auto& objectName : allObjectNames) {
if (!outputObjectsContainer.HasObjectNamed(objectName)) {
// Should not happen.
continue;
}
auto& object = outputObjectsContainer.GetObject(objectName);
const auto& allBehaviorNames = allObjectNonDefaultBehaviorNames[objectName];
for (const auto& behaviorName : object.GetAllBehaviorNames()) {
if (object.GetBehavior(behaviorName).IsDefaultBehavior()) {
// Default behaviors are already ensured to be all present
// (and no more than required by the object type).
continue;
}
if (allBehaviorNames.find(behaviorName) == allBehaviorNames.end()) {
object.RemoveBehavior(behaviorName);
}
}
}
} }
void ParameterMetadataTools::ForEachParameterMatchingSearch( void ParameterMetadataTools::ForEachParameterMatchingSearch(
const std::vector<const ParameterMetadataContainer*>& const std::vector<const std::vector<gd::ParameterMetadata>*>&
parametersVectorsList, parametersVectorsList,
const gd::String& search, const gd::String& search,
std::function<void(const gd::ParameterMetadata&)> cb) { std::function<void(const gd::ParameterMetadata&)> cb) {
for (auto it = parametersVectorsList.rbegin(); for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend(); it != parametersVectorsList.rend();
++it) { ++it) {
const ParameterMetadataContainer* parametersVector = *it; const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto &parameterMetadata : for (const auto& parameterMetadata: *parametersVector) {
parametersVector->GetInternalVector()) { if (parameterMetadata.GetName().FindCaseInsensitive(search) != gd::String::npos) cb(parameterMetadata);
if (parameterMetadata->GetName().FindCaseInsensitive(search) !=
gd::String::npos)
cb(*parameterMetadata);
} }
} }
} }
bool ParameterMetadataTools::Has( bool ParameterMetadataTools::Has(
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList, const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
const gd::String& parameterName) { const gd::String& parameterName) {
for (auto it = parametersVectorsList.rbegin(); for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend(); it != parametersVectorsList.rend();
++it) { ++it) {
const ParameterMetadataContainer* parametersVector = *it; const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto& parameterMetadata: parametersVector->GetInternalVector()) { for (const auto& parameterMetadata: *parametersVector) {
if (parameterMetadata->GetName() == parameterName) return true; if (parameterMetadata.GetName() == parameterName) return true;
} }
} }
@@ -164,18 +93,16 @@ bool ParameterMetadataTools::Has(
} }
const gd::ParameterMetadata& ParameterMetadataTools::Get( const gd::ParameterMetadata& ParameterMetadataTools::Get(
const std::vector<const ParameterMetadataContainer*>& const std::vector<const std::vector<gd::ParameterMetadata>*>&
parametersVectorsList, parametersVectorsList,
const gd::String& parameterName) { const gd::String& parameterName) {
for (auto it = parametersVectorsList.rbegin(); for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend(); it != parametersVectorsList.rend();
++it) { ++it) {
const ParameterMetadataContainer* parametersVector = *it; const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto &parameterMetadata : for (const auto& parameterMetadata: *parametersVector) {
parametersVector->GetInternalVector()) { if (parameterMetadata.GetName() == parameterName) return parameterMetadata;
if (parameterMetadata->GetName() == parameterName)
return *parameterMetadata;
} }
} }
@@ -184,7 +111,7 @@ const gd::ParameterMetadata& ParameterMetadataTools::Get(
void ParameterMetadataTools::IterateOverParameters( void ParameterMetadataTools::IterateOverParameters(
const std::vector<gd::Expression>& parameters, const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata, std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue, const gd::Expression& parameterValue,
const gd::String& lastObjectName)> fn) { const gd::String& lastObjectName)> fn) {
@@ -201,17 +128,15 @@ void ParameterMetadataTools::IterateOverParameters(
void ParameterMetadataTools::IterateOverParametersWithIndex( void ParameterMetadataTools::IterateOverParametersWithIndex(
const std::vector<gd::Expression>& parameters, const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata, std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue, const gd::Expression& parameterValue,
size_t parameterIndex, size_t parameterIndex,
const gd::String& lastObjectName)> fn) { const gd::String& lastObjectName)> fn) {
gd::String lastObjectName = ""; gd::String lastObjectName = "";
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount(); for (std::size_t pNb = 0; pNb < parametersMetadata.size(); ++pNb) {
++pNb) { const gd::ParameterMetadata& parameterMetadata = parametersMetadata[pNb];
const gd::ParameterMetadata &parameterMetadata = const gd::Expression& parameterValue =
parametersMetadata.GetParameter(pNb);
const gd::Expression &parameterValue =
pNb < parameters.size() ? parameters[pNb].GetPlainString() : ""; pNb < parameters.size() ? parameters[pNb].GetPlainString() : "";
const gd::Expression& parameterValueOrDefault = const gd::Expression& parameterValueOrDefault =
parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional() parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional()
@@ -254,10 +179,10 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
size_t parameterIndex = 0; size_t parameterIndex = 0;
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
metadataIndex < metadata.GetParameters().GetParametersCount() && metadataIndex < metadata.parameters.size() &&
parameterIndex < node.parameters.size(); parameterIndex < node.parameters.size();
++metadataIndex) { ++metadataIndex) {
auto &parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex); auto &parameterMetadata = metadata.parameters[metadataIndex];
if (parameterMetadata.IsCodeOnly()) { if (parameterMetadata.IsCodeOnly()) {
continue; continue;
} }
@@ -279,17 +204,16 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
} }
size_t ParameterMetadataTools::GetObjectParameterIndexFor( size_t ParameterMetadataTools::GetObjectParameterIndexFor(
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
size_t parameterIndex) { size_t parameterIndex) {
// By convention, parameters that require // By convention, parameters that require
// an object (mainly, "objectvar" and "behavior") should be placed after // an object (mainly, "objectvar" and "behavior") should be placed after
// the object in the list of parameters (if possible, just after). // the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this // Search "lastObjectName" in the codebase for other place where this
// convention is enforced. // convention is enforced.
for (std::size_t pNb = parameterIndex; for (std::size_t pNb = parameterIndex; pNb < parametersMetadata.size();
pNb < parametersMetadata.GetParametersCount(); pNb--) { pNb--) {
if (gd::ParameterMetadata::IsObject( if (gd::ParameterMetadata::IsObject(parametersMetadata[pNb].GetType())) {
parametersMetadata.GetParameter(pNb).GetType())) {
return pNb; return pNb;
} }
} }

View File

@@ -15,7 +15,6 @@ class ObjectsContainer;
class ObjectsContainersList; class ObjectsContainersList;
class ParameterMetadata; class ParameterMetadata;
class Expression; class Expression;
class ParameterMetadataContainer;
struct FunctionCallNode; struct FunctionCallNode;
struct ExpressionNode; struct ExpressionNode;
} // namespace gd } // namespace gd
@@ -25,20 +24,20 @@ class GD_CORE_API ParameterMetadataTools {
public: public:
static void ParametersToObjectsContainer( static void ParametersToObjectsContainer(
const gd::Project& project, const gd::Project& project,
const ParameterMetadataContainer& parameters, const std::vector<gd::ParameterMetadata>& parameters,
gd::ObjectsContainer& outputObjectsContainer); gd::ObjectsContainer& outputObjectsContainer);
static void ForEachParameterMatchingSearch( static void ForEachParameterMatchingSearch(
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList, const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
const gd::String& search, const gd::String& search,
std::function<void(const gd::ParameterMetadata&)> cb); std::function<void(const gd::ParameterMetadata&)> cb);
static bool Has( static bool Has(
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList, const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
const gd::String& parameterName); const gd::String& parameterName);
static const gd::ParameterMetadata& Get( static const gd::ParameterMetadata& Get(
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList, const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
const gd::String& parameterName); const gd::String& parameterName);
/** /**
@@ -48,7 +47,7 @@ class GD_CORE_API ParameterMetadataTools {
*/ */
static void IterateOverParameters( static void IterateOverParameters(
const std::vector<gd::Expression>& parameters, const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata, std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue, const gd::Expression& parameterValue,
const gd::String& lastObjectName)> fn); const gd::String& lastObjectName)> fn);
@@ -60,7 +59,7 @@ class GD_CORE_API ParameterMetadataTools {
*/ */
static void IterateOverParametersWithIndex( static void IterateOverParametersWithIndex(
const std::vector<gd::Expression>& parameters, const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata, std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue, const gd::Expression& parameterValue,
size_t parameterIndex, size_t parameterIndex,
@@ -85,7 +84,7 @@ class GD_CORE_API ParameterMetadataTools {
* it's linked to. * it's linked to.
*/ */
static size_t GetObjectParameterIndexFor( static size_t GetObjectParameterIndexFor(
const ParameterMetadataContainer& parametersMetadata, const std::vector<gd::ParameterMetadata>& parametersMetadata,
size_t parameterIndex); size_t parameterIndex);
private: private:

View File

@@ -1,56 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/String.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
/**
* \brief Contains information about a source file that must be included
* when an extension is used.
*/
class GD_CORE_API SourceFileMetadata {
public:
/**
* Construct a new dependency metadata, though you probably want to call
* `AddSourceFile` on gd::PlatformExtension.
*
* \see gd::PlatformExtension
*/
SourceFileMetadata() {};
SourceFileMetadata& SetResourceName(const gd::String& resourceName_) {
resourceName = resourceName_;
return *this;
};
SourceFileMetadata& SetIncludePosition(const gd::String& includePosition_) {
includePosition = includePosition_;
return *this;
};
const gd::String& GetResourceName() const { return resourceName; };
gd::String& GetResourceName() { return resourceName; };
const gd::String& GetIncludePosition() const { return includePosition; };
void SerializeTo(SerializerElement& element) const {
element.AddChild("resourceName").SetStringValue(resourceName);
element.AddChild("includePosition").SetStringValue(includePosition);
}
void UnserializeFrom(const SerializerElement& element) {
resourceName = element.GetStringAttribute("resourceName");
includePosition = element.GetStringAttribute("includePosition", "last");
}
private:
gd::String resourceName; ///< The name of the resource in the project.
gd::String includePosition = "last"; ///< "first" or "last".
};
} // namespace gd

View File

@@ -53,34 +53,27 @@ const gd::String &ValueTypeMetadata::GetExpressionPrimitiveValueType(
const gd::String & const gd::String &
ValueTypeMetadata::GetPrimitiveValueType(const gd::String &parameterType) { ValueTypeMetadata::GetPrimitiveValueType(const gd::String &parameterType) {
if (parameterType == "number" ||
gd::ValueTypeMetadata::IsTypeValue("number", parameterType)) {
return ValueTypeMetadata::numberType;
}
if (parameterType == "string" ||
gd::ValueTypeMetadata::IsTypeValue("string", parameterType)) {
return ValueTypeMetadata::stringType;
}
if (parameterType == "variable" || if (parameterType == "variable" ||
gd::ValueTypeMetadata::IsTypeValue("variable", parameterType)) { gd::ValueTypeMetadata::IsTypeExpression("variable", parameterType)) {
return ValueTypeMetadata::variableType; return ValueTypeMetadata::variableType;
} }
if (parameterType == "boolean" || if (parameterType == "boolean" || parameterType == "yesorno" ||
gd::ValueTypeMetadata::IsTypeValue("boolean", parameterType)) { parameterType == "trueorfalse") {
return ValueTypeMetadata::booleanType; return ValueTypeMetadata::booleanType;
} }
return parameterType; // These 2 types are not strings from the code generator point of view,
// but it is for event-based extensions.
if (parameterType == "key" || parameterType == "mouse") {
return ValueTypeMetadata::stringType;
}
return GetExpressionPrimitiveValueType(parameterType);
} }
const gd::String ValueTypeMetadata::numberValueType = "number"; const gd::String ValueTypeMetadata::numberValueType = "number";
const gd::String ValueTypeMetadata::booleanValueType = "boolean"; const gd::String ValueTypeMetadata::booleanValueType = "boolean";
const gd::String ValueTypeMetadata::stringValueType = "string";
const gd::String ValueTypeMetadata::colorValueType = "color"; const gd::String ValueTypeMetadata::colorValueType = "color";
const gd::String ValueTypeMetadata::choiceValueType = "stringWithSelector"; const gd::String ValueTypeMetadata::choiceValueType = "stringWithSelector";
const gd::String ValueTypeMetadata::behaviorValueType = "behavior"; const gd::String ValueTypeMetadata::stringValueType = "string";
const gd::String ValueTypeMetadata::leaderboardIdValueType = "leaderboardId";
const gd::String ValueTypeMetadata::objectAnimationNameValueType = "objectAnimationName";
const gd::String ValueTypeMetadata::keyboardKeyValueType = "keyboardKey";
const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType( const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
const gd::String &propertyType) { const gd::String &propertyType) {
@@ -92,16 +85,8 @@ const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
return colorValueType; return colorValueType;
} else if (propertyType == "Choice") { } else if (propertyType == "Choice") {
return choiceValueType; return choiceValueType;
} else if (propertyType == "Behavior") {
return behaviorValueType;
} else if (propertyType == "LeaderboardId") {
return leaderboardIdValueType;
} else if (propertyType == "ObjectAnimationName") {
return objectAnimationNameValueType;
} else if (propertyType == "KeyboardKey") {
return keyboardKeyValueType;
} }
// For "String", "Resource", "MultilineString" or default // For "String" or default
return stringValueType; return stringValueType;
}; };

View File

@@ -111,54 +111,31 @@ class GD_CORE_API ValueTypeMetadata {
* given type. * given type.
*/ */
bool IsNumber() const { bool IsNumber() const {
return gd::ValueTypeMetadata::IsTypeValue("number", name); return gd::ValueTypeMetadata::IsTypeExpression("number", name);
} }
/** /**
* \brief Return true if the type is a string. * \brief Return true if the type is a string.
*/ */
bool IsString() const { bool IsString() const {
return gd::ValueTypeMetadata::IsTypeValue("string", name); return gd::ValueTypeMetadata::IsTypeExpression("string", name);
} }
/** /**
* \brief Return true if the type is a boolean. * \brief Return true if the type is a boolean.
*/ */
bool IsBoolean() const { bool IsBoolean() const {
return gd::ValueTypeMetadata::IsTypeValue("boolean", name); return gd::ValueTypeMetadata::IsTypeExpression("boolean", name);
} }
/** /**
* \brief Return true if the type of the parameter is a variable. * \brief Return true if the type of the parameter is a number.
* \note If you had a new type of parameter, also add it in the IDE ( * \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService * see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator. * and ExpressionAutocompletion) and in the EventsCodeGenerator.
*/ */
bool IsVariable() const { bool IsVariable() const {
return gd::ValueTypeMetadata::IsVariable(name); return gd::ValueTypeMetadata::IsTypeExpression("variable", name);
}
/**
* \brief Return true if the type of the parameter is a variable.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
*/
static bool IsVariable(const gd::String &type) {
return gd::ValueTypeMetadata::GetPrimitiveValueType(type) == "variable";
}
/**
* \brief Return true if the type of the parameter is a variable and not a
* property or a parameter.
*/
bool IsVariableOnly() const {
return
// Any variable.
name == "variable" ||
// Old, "pre-scoped" variables:
name == "objectvar" || name == "globalvar" ||
name == "scenevar";
} }
/** /**
@@ -198,9 +175,7 @@ class GD_CORE_API ValueTypeMetadata {
} }
/** /**
* \brief Return true if the type is an expression of the given type from the * \brief Return true if the type is an expression of the given type.
* caller point of view.
*
* \note If you are adding a new type of parameter, also add it in the IDE ( * \note If you are adding a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService * see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator. * and ExpressionAutocompletion) and in the EventsCodeGenerator.
@@ -211,7 +186,6 @@ class GD_CORE_API ValueTypeMetadata {
return parameterType == "number" || parameterType == "expression" || return parameterType == "number" || parameterType == "expression" ||
parameterType == "camera" || parameterType == "forceMultiplier"; parameterType == "camera" || parameterType == "forceMultiplier";
} else if (type == "string") { } else if (type == "string") {
// "key" and "mouse" are not mapped her, see GetPrimitiveValueType.
return parameterType == "string" || parameterType == "layer" || return parameterType == "string" || parameterType == "layer" ||
parameterType == "color" || parameterType == "file" || parameterType == "color" || parameterType == "file" ||
parameterType == "stringWithSelector" || parameterType == "stringWithSelector" ||
@@ -225,24 +199,19 @@ class GD_CORE_API ValueTypeMetadata {
parameterType == "functionParameterName" || parameterType == "functionParameterName" ||
parameterType == "externalLayoutName" || parameterType == "externalLayoutName" ||
parameterType == "leaderboardId" || parameterType == "leaderboardId" ||
parameterType == "keyboardKey" ||
parameterType == "mouseButton" ||
parameterType == "identifier"; parameterType == "identifier";
} else if (type == "boolean") { } else if (type == "boolean") {
return parameterType == "yesorno" || parameterType == "trueorfalse"; return parameterType == "yesorno" || parameterType == "trueorfalse";
} else if (type == "variable") { } else if (type == "variable") {
return return
// Any variable. parameterType == "variable" || // Any variable.
parameterType == "variable" || // Old, "pre-scoped" variables:
parameterType == "variableOrProperty" || parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "variableOrPropertyOrParameter" || parameterType == "scenevar";
// Old, "pre-scoped" variables:
parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
} else if (type == "resource") { } else if (type == "resource") {
return parameterType == "fontResource" || return parameterType == "fontResource" ||
parameterType == "audioResource" || parameterType == "soundfile" ||
parameterType == "videoResource" || parameterType == "musicfile" ||
parameterType == "bitmapFontResource" || parameterType == "bitmapFontResource" ||
parameterType == "imageResource" || parameterType == "imageResource" ||
parameterType == "jsonResource" || parameterType == "jsonResource" ||
@@ -250,30 +219,7 @@ class GD_CORE_API ValueTypeMetadata {
parameterType == "tilesetResource" || parameterType == "tilesetResource" ||
parameterType == "model3DResource" || parameterType == "model3DResource" ||
parameterType == "atlasResource" || parameterType == "atlasResource" ||
parameterType == "spineResource" || parameterType == "spineResource";
// Deprecated, old parameter types:
parameterType == "soundfile" ||
parameterType == "musicfile";
}
return false;
}
/**
* \brief Return true if the type is a value of the given primitive type from
* the function events point of view
*/
static bool IsTypeValue(const gd::String &type,
const gd::String &parameterType) {
if (gd::ValueTypeMetadata::IsTypeExpression(type, parameterType)) {
return true;
}
// These 2 parameter types are not strings from the outside of a function as
// the generator add quote around a text, but from the events inside of the
// function the parameter is a string.
//
// See EventsCodeGenerator::GenerateParameterCodes
if (type == "string") {
return parameterType == "key" || parameterType == "mouse";
} }
return false; return false;
} }
@@ -329,13 +275,9 @@ class GD_CORE_API ValueTypeMetadata {
static const gd::String numberValueType; static const gd::String numberValueType;
static const gd::String booleanValueType; static const gd::String booleanValueType;
static const gd::String stringValueType;
static const gd::String colorValueType; static const gd::String colorValueType;
static const gd::String choiceValueType; static const gd::String choiceValueType;
static const gd::String behaviorValueType; static const gd::String stringValueType;
static const gd::String leaderboardIdValueType;
static const gd::String objectAnimationNameValueType;
static const gd::String keyboardKeyValueType;
}; };
} // namespace gd } // namespace gd

View File

@@ -38,14 +38,12 @@ bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
extensionsLoaded.push_back(extension); extensionsLoaded.push_back(extension);
// Load all creation functions for objects provided by the // Load all creation/destruction functions for objects provided by the
// extension. // extension
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes(); vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) { for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
CreateFunPtr createFunPtr = extension->GetObjectCreationFunctionPtr(objectsTypes[i]); creationFunctionTable[objectsTypes[i]] =
if (createFunPtr != nullptr) { extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
creationFunctionTable[objectsTypes[i]] = createFunPtr;
}
} }
for (const auto& it : for (const auto& it :
@@ -64,9 +62,7 @@ void Platform::RemoveExtension(const gd::String& name) {
if (extension->GetName() == name) { if (extension->GetName() == name) {
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes(); vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) { for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
if (creationFunctionTable.find(objectsTypes[i]) != creationFunctionTable.end()) { creationFunctionTable.erase(objectsTypes[i]);
creationFunctionTable.erase(objectsTypes[i]);
}
} }
} }
} }
@@ -100,11 +96,11 @@ std::shared_ptr<gd::PlatformExtension> Platform::GetExtension(
std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration( std::unique_ptr<gd::ObjectConfiguration> Platform::CreateObjectConfiguration(
gd::String type) const { gd::String type) const {
if (creationFunctionTable.find(type) == creationFunctionTable.end()) { if (creationFunctionTable.find(type) == creationFunctionTable.end()) {
gd::LogWarning("Tried to create an object configuration with an unknown type: " + type gd::LogWarning("Tried to create an object with an unknown type: " + type
+ " for platform " + GetName() + "!"); + " for platform " + GetName() + "!");
type = ""; type = "";
if (creationFunctionTable.find("") == creationFunctionTable.end()) { if (creationFunctionTable.find("") == creationFunctionTable.end()) {
gd::LogFatalError("Unable to create a base object configuration!"); gd::LogError("Unable to create a Base object!");
return nullptr; return nullptr;
} }
} }

View File

@@ -18,8 +18,8 @@
#include "GDCore/Extensions/Platform.h" #include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/PlatformManager.h" #include "GDCore/IDE/PlatformManager.h"
#include "GDCore/Project/Behavior.h" #include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/ObjectConfiguration.h" #include "GDCore/Project/ObjectConfiguration.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h" #include "GDCore/Tools/Localization.h"
namespace gd { namespace gd {
@@ -200,11 +200,11 @@ PlatformExtension::AddExpressionAndConditionAndAction(
group, group,
icon) icon)
: AddStrExpression(name, : AddStrExpression(name,
fullname, fullname,
expressionDescriptionTemplate.FindAndReplace( expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject), "<subject>", descriptionSubject),
group, group,
icon); icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction( return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action); expression, condition, action);
@@ -215,11 +215,6 @@ gd::DependencyMetadata& PlatformExtension::AddDependency() {
return extensionDependenciesMetadata.back(); return extensionDependenciesMetadata.back();
} }
gd::SourceFileMetadata& PlatformExtension::AddSourceFile() {
extensionSourceFilesMetadata.push_back(SourceFileMetadata());
return extensionSourceFilesMetadata.back();
}
gd::ObjectMetadata& PlatformExtension::AddObject( gd::ObjectMetadata& PlatformExtension::AddObject(
const gd::String& name, const gd::String& name,
const gd::String& fullname, const gd::String& fullname,
@@ -244,10 +239,12 @@ gd::ObjectMetadata& PlatformExtension::AddEventsBasedObject(
const gd::String& description, const gd::String& description,
const gd::String& icon24x24) { const gd::String& icon24x24) {
gd::String nameWithNamespace = GetNameSpace() + name; gd::String nameWithNamespace = GetNameSpace() + name;
objectsInfos[nameWithNamespace] = objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
ObjectMetadata( nameWithNamespace,
GetNameSpace(), nameWithNamespace, fullname, description, icon24x24) fullname,
.SetHelpPath(GetHelpPath()); description,
icon24x24)
.SetHelpPath(GetHelpPath());
return objectsInfos[nameWithNamespace]; return objectsInfos[nameWithNamespace];
} }
@@ -351,7 +348,8 @@ gd::BehaviorMetadata& PlatformExtension::GetBehaviorMetadata(
return badBehaviorMetadata; return badBehaviorMetadata;
} }
bool PlatformExtension::HasBehavior(const gd::String& behaviorType) const { bool PlatformExtension::HasBehavior(
const gd::String& behaviorType) const {
return behaviorsInfo.find(behaviorType) != behaviorsInfo.end(); return behaviorsInfo.find(behaviorType) != behaviorsInfo.end();
} }
@@ -383,7 +381,7 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedAction(
auto copiedAction = actionsInfos.find(copiedNameWithNamespace); auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) { if (copiedAction == actionsInfos.end()) {
gd::LogError("Could not find an action with name " + gd::LogError("Could not find an action with name " +
copiedNameWithNamespace + " to copy."); copiedNameWithNamespace + " to copy.");
} else { } else {
actionsInfos[newNameWithNamespace] = copiedAction->second; actionsInfos[newNameWithNamespace] = copiedAction->second;
} }
@@ -403,7 +401,7 @@ gd::InstructionMetadata& PlatformExtension::AddDuplicatedCondition(
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace); auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) { if (copiedCondition == conditionsInfos.end()) {
gd::LogError("Could not find a condition with name " + gd::LogError("Could not find a condition with name " +
copiedNameWithNamespace + " to copy."); copiedNameWithNamespace + " to copy.");
} else { } else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second; conditionsInfos[newNameWithNamespace] = copiedCondition->second;
} }
@@ -420,7 +418,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedExpression(
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace); auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) { if (copiedExpression == expressionsInfos.end()) {
gd::LogError("Could not find an expression with name " + gd::LogError("Could not find an expression with name " +
copiedNameWithNamespace + " to copy."); copiedNameWithNamespace + " to copy.");
} else { } else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second; expressionsInfos[newNameWithNamespace] = copiedExpression->second;
} }
@@ -437,7 +435,7 @@ gd::ExpressionMetadata& PlatformExtension::AddDuplicatedStrExpression(
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace); auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) { if (copiedExpression == strExpressionsInfos.end()) {
gd::LogError("Could not find a string expression with name " + gd::LogError("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy."); copiedNameWithNamespace + " to copy.");
} else { } else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second; strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
} }
@@ -465,24 +463,10 @@ PlatformExtension::GetAllStrExpressions() {
return strExpressionsInfos; return strExpressionsInfos;
} }
const std::vector<gd::DependencyMetadata>&
PlatformExtension::GetAllDependencies() const {
return extensionDependenciesMetadata;
}
std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() { std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() {
return extensionDependenciesMetadata; return extensionDependenciesMetadata;
} }
const std::vector<gd::SourceFileMetadata>&
PlatformExtension::GetAllSourceFiles() const {
return extensionSourceFilesMetadata;
}
std::vector<gd::SourceFileMetadata>& PlatformExtension::GetAllSourceFiles() {
return extensionSourceFilesMetadata;
}
std::map<gd::String, gd::EventMetadata>& PlatformExtension::GetAllEvents() { std::map<gd::String, gd::EventMetadata>& PlatformExtension::GetAllEvents() {
return eventsInfos; return eventsInfos;
} }
@@ -614,6 +598,37 @@ void PlatformExtension::SetNameSpace(gd::String nameSpace_) {
nameSpace = nameSpace_ + GetNamespaceSeparator(); nameSpace = nameSpace_ + GetNamespaceSeparator();
} }
std::vector<gd::String> PlatformExtension::GetBuiltinExtensionsNames() {
std::vector<gd::String> builtinExtensions;
builtinExtensions.push_back("Sprite");
builtinExtensions.push_back("BuiltinObject");
builtinExtensions.push_back("BuiltinAudio");
builtinExtensions.push_back("BuiltinMouse");
builtinExtensions.push_back("BuiltinKeyboard");
builtinExtensions.push_back("BuiltinJoystick");
builtinExtensions.push_back("BuiltinTime");
builtinExtensions.push_back("BuiltinFile");
builtinExtensions.push_back("BuiltinVariables");
builtinExtensions.push_back("BuiltinCamera");
builtinExtensions.push_back("BuiltinWindow");
builtinExtensions.push_back("BuiltinNetwork");
builtinExtensions.push_back("BuiltinScene");
builtinExtensions.push_back("BuiltinAdvanced");
builtinExtensions.push_back("BuiltinCommonConversions");
builtinExtensions.push_back("BuiltinStringInstructions");
builtinExtensions.push_back("BuiltinMathematicalTools");
builtinExtensions.push_back("BuiltinExternalLayouts");
builtinExtensions.push_back("BuiltinCommonInstructions");
return builtinExtensions;
}
bool PlatformExtension::IsBuiltin() const {
std::vector<gd::String> builtinExtensions = GetBuiltinExtensionsNames();
return std::find(builtinExtensions.begin(), builtinExtensions.end(), name) !=
builtinExtensions.end();
}
void PlatformExtension::StripUnimplementedInstructionsAndExpressions() { void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
for (std::map<gd::String, gd::InstructionMetadata>::iterator it = for (std::map<gd::String, gd::InstructionMetadata>::iterator it =
GetAllActions().begin(); GetAllActions().begin();
@@ -759,60 +774,40 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
} }
} }
gd::String PlatformExtension::GetEventsFunctionFullType( gd::String
const gd::String& extensionName, const gd::String& functionName) { PlatformExtension::GetEventsFunctionFullType(const gd::String &extensionName,
const auto& separator = GetNamespaceSeparator(); const gd::String &functionName) {
const auto &separator = GetNamespaceSeparator();
return extensionName + separator + functionName; return extensionName + separator + functionName;
} }
gd::String PlatformExtension::GetBehaviorEventsFunctionFullType( gd::String PlatformExtension::GetBehaviorEventsFunctionFullType(
const gd::String& extensionName, const gd::String &extensionName, const gd::String &behaviorName,
const gd::String& behaviorName, const gd::String &functionName) {
const gd::String& functionName) { const auto &separator = GetNamespaceSeparator();
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + behaviorName + separator + functionName; return extensionName + separator + behaviorName + separator + functionName;
} }
gd::String PlatformExtension::GetBehaviorFullType( gd::String
const gd::String& extensionName, const gd::String& behaviorName) { PlatformExtension::GetBehaviorFullType(const gd::String &extensionName,
const auto& separator = GetNamespaceSeparator(); const gd::String &behaviorName) {
const auto &separator = GetNamespaceSeparator();
return extensionName + separator + behaviorName; return extensionName + separator + behaviorName;
} }
gd::String PlatformExtension::GetObjectEventsFunctionFullType( gd::String PlatformExtension::GetObjectEventsFunctionFullType(
const gd::String& extensionName, const gd::String &extensionName, const gd::String &objectName,
const gd::String& objectName, const gd::String &functionName) {
const gd::String& functionName) { const auto &separator = GetNamespaceSeparator();
const auto& separator = GetNamespaceSeparator();
return extensionName + separator + objectName + separator + functionName; return extensionName + separator + objectName + separator + functionName;
} }
gd::String PlatformExtension::GetObjectFullType(const gd::String& extensionName, gd::String PlatformExtension::GetObjectFullType(const gd::String &extensionName,
const gd::String& objectName) { const gd::String &objectName) {
const auto& separator = GetNamespaceSeparator(); const auto &separator = GetNamespaceSeparator();
return extensionName + separator + objectName; return extensionName + separator + objectName;
} }
gd::String PlatformExtension::GetExtensionFromFullObjectType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {
return "";
}
return type.substr(0, separatorIndex);
}
gd::String PlatformExtension::GetObjectNameFromFullObjectType(
const gd::String& type) {
const auto separatorIndex =
type.find(PlatformExtension::GetNamespaceSeparator());
if (separatorIndex == std::string::npos) {
return "";
}
return type.substr(separatorIndex + 2);
}
PlatformExtension::PlatformExtension() PlatformExtension::PlatformExtension()
: deprecated(false), category(_("General")) {} : deprecated(false), category(_("General")) {}

View File

@@ -17,7 +17,6 @@
#include "GDCore/Extensions/Metadata/EventMetadata.h" #include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h" #include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h" #include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Project/PropertyDescriptor.h" #include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h" #include "GDCore/String.h"
#include "GDCore/Tools/VersionPriv.h" #include "GDCore/Tools/VersionPriv.h"
@@ -41,7 +40,8 @@ class Object;
class ObjectConfiguration; class ObjectConfiguration;
} // namespace gd } // namespace gd
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()> CreateFunPtr; typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
CreateFunPtr;
namespace gd { namespace gd {
@@ -51,25 +51,25 @@ namespace gd {
*/ */
class GD_CORE_API CompilationInfo { class GD_CORE_API CompilationInfo {
public: public:
CompilationInfo() {}; CompilationInfo() : informationCompleted(false){};
virtual ~CompilationInfo() {}; virtual ~CompilationInfo(){};
bool informationCompleted = false; bool informationCompleted;
bool runtimeOnly = false; ///< True if the extension was compiled for a bool runtimeOnly; ///< True if the extension was compiled for a runtime use
///< runtime use only ///< only
#if defined(__GNUC__) #if defined(__GNUC__)
int gccMajorVersion = 0; int gccMajorVersion;
int gccMinorVersion = 0; int gccMinorVersion;
int gccPatchLevel = 0; int gccPatchLevel;
#endif #endif
int sfmlMajorVersion = 0; int sfmlMajorVersion;
int sfmlMinorVersion = 0; int sfmlMinorVersion;
gd::String gdCoreVersion; gd::String gdCoreVersion;
int sizeOfpInt = 0; int sizeOfpInt;
}; };
struct GD_CORE_API DuplicatedInstructionOptions { struct GD_CORE_API DuplicatedInstructionOptions {
@@ -215,7 +215,6 @@ class GD_CORE_API PlatformExtension {
const gd::String& icon); const gd::String& icon);
gd::DependencyMetadata& AddDependency(); gd::DependencyMetadata& AddDependency();
gd::SourceFileMetadata& AddSourceFile();
/** /**
* \brief Declare a new object as being part of the extension. * \brief Declare a new object as being part of the extension.
@@ -240,12 +239,11 @@ class GD_CORE_API PlatformExtension {
* \param instance The "blueprint" object to be copied when a new object is * \param instance The "blueprint" object to be copied when a new object is
asked for. asked for.
*/ */
gd::ObjectMetadata& AddObject( gd::ObjectMetadata& AddObject(const gd::String& name_,
const gd::String& name_, const gd::String& fullname_,
const gd::String& fullname_, const gd::String& description_,
const gd::String& description_, const gd::String& icon_,
const gd::String& icon_, std::shared_ptr<gd::ObjectConfiguration> instance);
std::shared_ptr<gd::ObjectConfiguration> instance);
/** /**
* \brief Declare a new events based object as being part of the extension. * \brief Declare a new events based object as being part of the extension.
@@ -255,10 +253,11 @@ class GD_CORE_API PlatformExtension {
* \param description The user friendly description of the object * \param description The user friendly description of the object
* \param icon The icon of the object. * \param icon The icon of the object.
*/ */
gd::ObjectMetadata& AddEventsBasedObject(const gd::String& name_, gd::ObjectMetadata& AddEventsBasedObject(
const gd::String& fullname_, const gd::String& name_,
const gd::String& description_, const gd::String& fullname_,
const gd::String& icon_); const gd::String& description_,
const gd::String& icon_);
/** /**
* \brief Declare a new behavior as being part of the extension. * \brief Declare a new behavior as being part of the extension.
@@ -421,7 +420,8 @@ class GD_CORE_API PlatformExtension {
PlatformExtension& SetTags(const gd::String& csvTags) { PlatformExtension& SetTags(const gd::String& csvTags) {
tags.clear(); tags.clear();
tags = csvTags.Split(','); tags = csvTags.Split(',');
for (size_t i = 0; i < tags.size(); i++) { for (size_t i = 0; i < tags.size(); i++)
{
tags[i] = tags[i].Trim().LowerCase(); tags[i] = tags[i].Trim().LowerCase();
} }
return *this; return *this;
@@ -440,6 +440,12 @@ class GD_CORE_API PlatformExtension {
*/ */
bool IsDeprecated() const { return deprecated; } bool IsDeprecated() const { return deprecated; }
/**
* \brief Return true if the extension is a standard extension that cannot be
* deactivated
*/
bool IsBuiltin() const;
/** /**
* \brief Get the namespace of the extension. * \brief Get the namespace of the extension.
* \note The namespace is simply the name of the extension concatenated with * \note The namespace is simply the name of the extension concatenated with
@@ -548,24 +554,6 @@ class GD_CORE_API PlatformExtension {
*/ */
std::vector<gd::DependencyMetadata>& GetAllDependencies(); std::vector<gd::DependencyMetadata>& GetAllDependencies();
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
const std::vector<gd::DependencyMetadata>& GetAllDependencies() const;
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
std::vector<gd::SourceFileMetadata>& GetAllSourceFiles();
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
const std::vector<gd::SourceFileMetadata>& GetAllSourceFiles() const;
/** /**
* \brief Return a reference to a map containing the names of the actions, * \brief Return a reference to a map containing the names of the actions,
* related to the object type, and the metadata associated with. * related to the object type, and the metadata associated with.
@@ -634,36 +622,38 @@ class GD_CORE_API PlatformExtension {
} }
///@} ///@}
/**
* \brief Return the name of all the extensions which are considered provided
* by platforms.
*/
static std::vector<gd::String> GetBuiltinExtensionsNames();
/** /**
* \brief Get the string used to separate the name of the * \brief Get the string used to separate the name of the
* instruction/expression and the extension. * instruction/expression and the extension.
*/ */
static gd::String GetNamespaceSeparator() { return "::"; } static gd::String GetNamespaceSeparator() { return "::"; }
static gd::String GetEventsFunctionFullType(const gd::String& extensionName, static gd::String GetEventsFunctionFullType(const gd::String &extensionName,
const gd::String& functionName); const gd::String &functionName);
static gd::String GetBehaviorEventsFunctionFullType( static gd::String
const gd::String& extensionName, GetBehaviorEventsFunctionFullType(const gd::String &extensionName,
const gd::String& behaviorName, const gd::String &behaviorName,
const gd::String& functionName); const gd::String &functionName);
static gd::String GetBehaviorFullType(const gd::String& extensionName, static gd::String GetBehaviorFullType(const gd::String &extensionName,
const gd::String& behaviorName); const gd::String &behaviorName);
static gd::String GetObjectEventsFunctionFullType( static gd::String
const gd::String& extensionName, GetObjectEventsFunctionFullType(const gd::String &extensionName,
const gd::String& objectName, const gd::String &objectName,
const gd::String& functionName); const gd::String &functionName);
static gd::String GetObjectFullType(const gd::String& extensionName, static gd::String GetObjectFullType(const gd::String &extensionName,
const gd::String& objectName); const gd::String &objectName);
static gd::String GetExtensionFromFullObjectType(const gd::String& type); private:
static gd::String GetObjectNameFromFullObjectType(const gd::String& type);
private:
/** /**
* Set the namespace (the string all actions/conditions/expressions start * Set the namespace (the string all actions/conditions/expressions start
* with). * with).
@@ -678,10 +668,10 @@ class GD_CORE_API PlatformExtension {
gd::String fullname; ///< Name displayed to users in the editor. gd::String fullname; ///< Name displayed to users in the editor.
gd::String informations; ///< Description displayed to users in the editor. gd::String informations; ///< Description displayed to users in the editor.
gd::String category; gd::String category;
gd::String author; ///< Author displayed to users in the editor. gd::String author; ///< Author displayed to users in the editor.
gd::String license; ///< License name displayed to users in the editor. gd::String license; ///< License name displayed to users in the editor.
bool deprecated; ///< true if the extension is deprecated and shouldn't be bool deprecated; ///< true if the extension is deprecated and shouldn't be
///< shown in IDE. ///< shown in IDE.
gd::String helpPath; ///< The relative path to the help for this extension in gd::String helpPath; ///< The relative path to the help for this extension in
///< the documentation. ///< the documentation.
gd::String iconUrl; ///< The URL to the icon to be shown for this extension. gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
@@ -695,7 +685,6 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos; std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos; std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata; std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
std::vector<gd::SourceFileMetadata> extensionSourceFilesMetadata;
std::map<gd::String, gd::EventMetadata> eventsInfos; std::map<gd::String, gd::EventMetadata> eventsInfos;
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata; std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
std::map<gd::String, InstructionOrExpressionGroupMetadata> std::map<gd::String, InstructionOrExpressionGroupMetadata>

View File

@@ -5,8 +5,6 @@
* project is released under the MIT License. * project is released under the MIT License.
*/ */
// NOLINTBEGIN
#ifndef GDCORE_PLATFORMEXTENSION_INL #ifndef GDCORE_PLATFORMEXTENSION_INL
#define GDCORE_PLATFORMEXTENSION_INL #define GDCORE_PLATFORMEXTENSION_INL
@@ -38,5 +36,3 @@ gd::ObjectMetadata& PlatformExtension::AddObject(const gd::String& name,
} // namespace gd } // namespace gd
#endif #endif
// NOLINTEND

View File

@@ -1,18 +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/CaptureOptions.h"
#include "GDCore/String.h"
using namespace std;
namespace gd {
Screenshot::Screenshot() {}
CaptureOptions::CaptureOptions() {}
} // namespace gd

View File

@@ -1,50 +0,0 @@
#pragma once
#include <memory>
#include <vector>
#include "GDCore/String.h"
namespace gd {
class GD_CORE_API Screenshot {
public:
Screenshot();
virtual ~Screenshot() {};
void SetDelayTimeInSeconds(int delayTimeInMs_) {
delayTimeInMs = delayTimeInMs_;
}
int GetDelayTimeInSeconds() const { return delayTimeInMs; }
void SetSignedUrl(const gd::String& signedUrl_) { signedUrl = signedUrl_; }
const gd::String& GetSignedUrl() const { return signedUrl; }
void SetPublicUrl(const gd::String& publicUrl_) { publicUrl = publicUrl_; }
const gd::String& GetPublicUrl() const { return publicUrl; }
private:
int delayTimeInMs = 0;
gd::String signedUrl;
gd::String publicUrl;
};
class GD_CORE_API CaptureOptions {
public:
CaptureOptions();
virtual ~CaptureOptions() {};
bool IsEmpty() const { return screenshots.empty(); }
void AddScreenshot(const Screenshot& screenshot) {
screenshots.push_back(screenshot);
}
const std::vector<Screenshot>& GetScreenshots() const { return screenshots; }
void ClearScreenshots() { screenshots.clear(); }
private:
std::vector<Screenshot> screenshots;
};
} // namespace gd

View File

@@ -12,6 +12,7 @@
#include "GDCore/Project/ExternalEvents.h" #include "GDCore/Project/ExternalEvents.h"
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Project/SourceFile.h"
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_, DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
const gd::Layout& layout_) const gd::Layout& layout_)
@@ -73,6 +74,16 @@ bool DependenciesAnalyzer::Analyze(const gd::EventsList& events) {
} }
} }
// Search for source files dependencies
std::vector<gd::String> dependencies =
events[i].GetSourceFileDependencies();
sourceFilesDependencies.insert(dependencies.begin(), dependencies.end());
const gd::String& associatedSourceFile =
events[i].GetAssociatedGDManagedSourceFile(const_cast<gd::Project&>(project));
if (!associatedSourceFile.empty())
sourceFilesDependencies.insert(associatedSourceFile);
// Analyze sub events dependencies // Analyze sub events dependencies
if (events[i].CanHaveSubEvents()) { if (events[i].CanHaveSubEvents()) {
if (!Analyze(events[i].GetSubEvents())) return false; if (!Analyze(events[i].GetSubEvents())) return false;

View File

@@ -71,6 +71,14 @@ class GD_CORE_API DependenciesAnalyzer {
return externalEventsDependencies; return externalEventsDependencies;
}; };
/**
* \brief Return the source files being dependencies of the scene or external
* events passed in the constructor.
*/
const std::set<gd::String>& GetSourceFilesDependencies() const {
return sourceFilesDependencies;
};
private: private:
/** /**
* \brief Analyze the dependencies of the events. * \brief Analyze the dependencies of the events.
@@ -84,6 +92,7 @@ class GD_CORE_API DependenciesAnalyzer {
std::set<gd::String> scenesDependencies; std::set<gd::String> scenesDependencies;
std::set<gd::String> externalEventsDependencies; std::set<gd::String> externalEventsDependencies;
std::set<gd::String> sourceFilesDependencies;
std::vector<gd::String> std::vector<gd::String>
parentScenes; ///< Used to check for circular dependencies. parentScenes; ///< Used to check for circular dependencies.
std::vector<gd::String> std::vector<gd::String>

View File

@@ -26,9 +26,12 @@ void EventBasedBehaviorBrowser::ExposeEvents(
void EventBasedBehaviorBrowser::ExposeEvents( void EventBasedBehaviorBrowser::ExposeEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) const { gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) const {
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents( gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
project, eventsFunctionsExtension, eventsBasedBehavior, worker); project, eventsBasedBehavior, worker);
} }
void EventBasedBehaviorBrowser::ExposeObjects(
gd::Project &project, gd::ArbitraryObjectsWorker &worker) const {}
void EventBasedBehaviorBrowser::ExposeFunctions( void EventBasedBehaviorBrowser::ExposeFunctions(
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) const { gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) const {
worker.Launch(eventsBasedBehavior.GetEventsFunctions()); worker.Launch(eventsBasedBehavior.GetEventsFunctions());
@@ -40,4 +43,7 @@ void EventBasedBehaviorBrowser::ExposeEventBasedBehaviors(
worker.Launch(eventsBasedBehavior); worker.Launch(eventsBasedBehavior);
} }
void EventBasedBehaviorBrowser::ExposeBehaviorSharedDatas(
gd::Project &project, gd::ArbitraryBehaviorSharedDataWorker &worker) const {}
} // namespace gd } // namespace gd

View File

@@ -29,11 +29,8 @@ namespace gd {
*/ */
class GD_CORE_API EventBasedBehaviorBrowser : public ProjectBrowser { class GD_CORE_API EventBasedBehaviorBrowser : public ProjectBrowser {
public: public:
EventBasedBehaviorBrowser( EventBasedBehaviorBrowser(gd::EventsBasedBehavior &eventsBasedBehavior_)
const gd::EventsFunctionsExtension &eventsFunctionsExtension_, : eventsBasedBehavior(eventsBasedBehavior_) {}
gd::EventsBasedBehavior &eventsBasedBehavior_)
: eventsFunctionsExtension(eventsFunctionsExtension_),
eventsBasedBehavior(eventsBasedBehavior_) {}
/** /**
* \brief Call the specified worker on all events of the event-based * \brief Call the specified worker on all events of the event-based
@@ -51,7 +48,7 @@ public:
* This should be the preferred way to traverse all the events of an event-based behavior. * This should be the preferred way to traverse all the events of an event-based behavior.
*/ */
void void
ExposeEvents(gd::Project &project, ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorkerWithContext &worker) const override; gd::ArbitraryEventsWorkerWithContext &worker) const override;
/** /**
@@ -67,7 +64,7 @@ public:
* \brief Do nothing. * \brief Do nothing.
*/ */
void ExposeObjects(gd::Project &project, void ExposeObjects(gd::Project &project,
gd::ArbitraryObjectsWorker &worker) const override {}; gd::ArbitraryObjectsWorker &worker) const override;
/** /**
* \brief Call the specified worker on the event-based behavior. * \brief Call the specified worker on the event-based behavior.
@@ -80,10 +77,9 @@ public:
* \brief Do nothing. * \brief Do nothing.
*/ */
void ExposeBehaviorSharedDatas(gd::Project &project, void ExposeBehaviorSharedDatas(gd::Project &project,
gd::ArbitraryBehaviorSharedDataWorker &worker) const override {}; gd::ArbitraryBehaviorSharedDataWorker &worker) const override;
private: private:
const gd::EventsFunctionsExtension &eventsFunctionsExtension;
gd::EventsBasedBehavior &eventsBasedBehavior; gd::EventsBasedBehavior &eventsBasedBehavior;
}; };

View File

@@ -1,37 +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 "EventBasedObjectBrowser.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventBasedBehaviorsWorker.h"
#include "GDCore/IDE/Project/ArbitraryEventsFunctionsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/IDE/Project/ArbitraryBehaviorSharedDataWorker.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/Project.h"
#include "GDCore/String.h"
namespace gd {
void EventBasedObjectBrowser::ExposeEvents(
gd::Project &project, gd::ArbitraryEventsWorker &worker) const {
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsBasedObject, worker);
}
void EventBasedObjectBrowser::ExposeEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) const {
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject, worker);
}
void EventBasedObjectBrowser::ExposeFunctions(
gd::Project &project, gd::ArbitraryEventsFunctionsWorker &worker) const {
worker.Launch(eventsBasedObject.GetEventsFunctions());
}
} // namespace gd

View File

@@ -1,90 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/IDE/ProjectBrowser.h"
namespace gd {
class Project;
class String;
class EventsFunctionsExtension;
class EventsFunction;
class EventsBasedBehavior;
class EventsBasedObject;
class ArbitraryEventsWorker;
class ArbitraryEventsWorkerWithContext;
class ArbitraryEventsFunctionsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventBasedBehaviorsWorker;
class ArbitraryBehaviorSharedDataWorker;
} // namespace gd
namespace gd {
/**
* \brief Expose event-based object contents to workers.
*/
class GD_CORE_API EventBasedObjectBrowser : public ProjectBrowser {
public:
EventBasedObjectBrowser(
const gd::EventsFunctionsExtension &eventsFunctionsExtension_,
gd::EventsBasedObject &eventsBasedObject_)
: eventsFunctionsExtension(eventsFunctionsExtension_),
eventsBasedObject(eventsBasedObject_) {}
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an event-based object.
*/
void ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorker &worker) const override;
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an event-based object.
*/
void
ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorkerWithContext &worker) const override;
/**
* \brief Call the specified worker on all functions of the event-based object
*
* This should be the preferred way to traverse all the function signatures
* of an event-based object.
*/
void ExposeFunctions(gd::Project &project,
gd::ArbitraryEventsFunctionsWorker &worker) const override;
/**
* \brief Do nothing.
*/
void ExposeObjects(gd::Project &project,
gd::ArbitraryObjectsWorker &worker) const override {};
/**
* @brief Do nothing.
*/
void ExposeEventBasedBehaviors(
gd::Project &project,
gd::ArbitraryEventBasedBehaviorsWorker &worker) const override {};
/**
* \brief Do nothing.
*/
void ExposeBehaviorSharedDatas(gd::Project &project,
gd::ArbitraryBehaviorSharedDataWorker &worker) const override {};
private:
const gd::EventsFunctionsExtension &eventsFunctionsExtension;
gd::EventsBasedObject &eventsBasedObject;
};
} // namespace gd

View File

@@ -14,27 +14,29 @@
#include "GDCore/Events/Expression.h" #include "GDCore/Events/Expression.h"
#include "GDCore/Extensions/Metadata/ParameterMetadata.h" #include "GDCore/Extensions/Metadata/ParameterMetadata.h"
#include "GDCore/String.h" #include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
using namespace std; using namespace std;
namespace gd { namespace gd {
AbstractArbitraryEventsWorker::~AbstractArbitraryEventsWorker() {} ArbitraryEventsWorker::~ArbitraryEventsWorker() {}
void AbstractArbitraryEventsWorker::VisitEventList(gd::EventsList& events) { void ArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
DoVisitEventList(events); DoVisitEventList(events);
for (std::size_t i = 0; i < events.size();) { for (std::size_t i = 0; i < events.size();) {
if (events[i].AcceptVisitor(*this)) if (events[i].AcceptVisitor(*this))
events.RemoveEvent(i); events.RemoveEvent(i);
else { else {
if (events[i].CanHaveSubEvents())
VisitEventList(events[i].GetSubEvents());
++i; ++i;
} }
} }
} }
bool AbstractArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) { bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
bool shouldDelete = DoVisitEvent(event); bool shouldDelete = DoVisitEvent(event);
if (shouldDelete) return true; if (shouldDelete) return true;
@@ -53,17 +55,15 @@ bool AbstractArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
*expressionAndMetadata.first, expressionAndMetadata.second); *expressionAndMetadata.first, expressionAndMetadata.second);
} }
if (!shouldDelete && event.CanHaveSubEvents()) {
VisitEventList(event.GetSubEvents());
}
return shouldDelete; return shouldDelete;
} }
bool AbstractArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) { bool ArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
return DoVisitLinkEvent(linkEvent); return DoVisitLinkEvent(linkEvent);
} }
void AbstractArbitraryEventsWorker::VisitInstructionList( void ArbitraryEventsWorker::VisitInstructionList(
gd::InstructionsList& instructions, bool areConditions) { gd::InstructionsList& instructions, bool areConditions) {
DoVisitInstructionList(instructions, areConditions); DoVisitInstructionList(instructions, areConditions);
@@ -79,19 +79,22 @@ void AbstractArbitraryEventsWorker::VisitInstructionList(
} }
} }
bool AbstractArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction, bool ArbitraryEventsWorker::VisitInstruction(gd::Instruction& instruction,
bool isCondition) { bool isCondition) {
return DoVisitInstruction(instruction, isCondition); return DoVisitInstruction(instruction, isCondition);
} }
bool AbstractArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression, bool ArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression,
const gd::ParameterMetadata& metadata) { const gd::ParameterMetadata& metadata) {
return DoVisitEventExpression(expression, metadata); return DoVisitEventExpression(expression, metadata);
} }
AbstractReadOnlyArbitraryEventsWorker::~AbstractReadOnlyArbitraryEventsWorker() {} ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
void AbstractReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events) {
ReadOnlyArbitraryEventsWorker::~ReadOnlyArbitraryEventsWorker() {}
void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events) {
DoVisitEventList(events); DoVisitEventList(events);
for (std::size_t i = 0; i < events.size(); ++i) { for (std::size_t i = 0; i < events.size(); ++i) {
@@ -106,7 +109,7 @@ void AbstractReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList&
} }
} }
void AbstractReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) { void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
DoVisitEvent(event); DoVisitEvent(event);
const vector<const gd::InstructionsList*> conditionsVectors = const vector<const gd::InstructionsList*> conditionsVectors =
@@ -127,11 +130,11 @@ void AbstractReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& even
} }
} }
void AbstractReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) { void ReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) {
DoVisitLinkEvent(linkEvent); DoVisitLinkEvent(linkEvent);
} }
void AbstractReadOnlyArbitraryEventsWorker::VisitInstructionList( void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
const gd::InstructionsList& instructions, bool areConditions) { const gd::InstructionsList& instructions, bool areConditions) {
DoVisitInstructionList(instructions, areConditions); DoVisitInstructionList(instructions, areConditions);
@@ -147,73 +150,21 @@ void AbstractReadOnlyArbitraryEventsWorker::VisitInstructionList(
} }
} }
void AbstractReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& instruction, void ReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& instruction,
bool isCondition) { bool isCondition) {
DoVisitInstruction(instruction, isCondition); DoVisitInstruction(instruction, isCondition);
} }
void AbstractReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression, void ReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression,
const gd::ParameterMetadata& metadata) { const gd::ParameterMetadata& metadata) {
DoVisitEventExpression(expression, metadata); DoVisitEventExpression(expression, metadata);
} }
void AbstractReadOnlyArbitraryEventsWorker::StopAnyEventIteration() { void ReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
shouldStopIteration = true; shouldStopIteration = true;
} }
ArbitraryEventsWorker::~ArbitraryEventsWorker() {}
bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent &event) {
return AbstractArbitraryEventsWorker::VisitEvent(event);
}
ArbitraryEventsWorkerWithContext::~ArbitraryEventsWorkerWithContext() {}
bool ArbitraryEventsWorkerWithContext::VisitEvent(gd::BaseEvent &event) {
if (!event.HasVariables()) {
return AbstractArbitraryEventsWorker::VisitEvent(event);
}
// Push local variables
auto newProjectScopedContainers =
ProjectScopedContainers::MakeNewProjectScopedContainersWithLocalVariables(
*currentProjectScopedContainers, event);
auto *parentProjectScopedContainers = currentProjectScopedContainers;
currentProjectScopedContainers = &newProjectScopedContainers;
bool shouldDelete = AbstractArbitraryEventsWorker::VisitEvent(event);
// Pop local variables
currentProjectScopedContainers = parentProjectScopedContainers;
return shouldDelete;
}
ReadOnlyArbitraryEventsWorker::~ReadOnlyArbitraryEventsWorker() {}
void ReadOnlyArbitraryEventsWorker::VisitEvent(
const gd::BaseEvent &event) {
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
}
ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {} ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {}
void ReadOnlyArbitraryEventsWorkerWithContext::VisitEvent(
const gd::BaseEvent &event) {
if (!event.HasVariables()) {
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
return;
}
// Push local variables
auto newProjectScopedContainers =
ProjectScopedContainers::MakeNewProjectScopedContainersWithLocalVariables(
*currentProjectScopedContainers, event);
auto *parentProjectScopedContainers = currentProjectScopedContainers;
currentProjectScopedContainers = &newProjectScopedContainers;
AbstractReadOnlyArbitraryEventsWorker::VisitEvent(event);
// Pop local variables
currentProjectScopedContainers = parentProjectScopedContainers;
}
} // namespace gd } // namespace gd

View File

@@ -3,8 +3,8 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_ARBITRARYEVENTSWORKER_H
#define GDCORE_ARBITRARYEVENTSWORKER_H
#include <map> #include <map>
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -12,7 +12,6 @@
#include "GDCore/Events/EventVisitor.h" #include "GDCore/Events/EventVisitor.h"
#include "GDCore/Project/ProjectScopedContainers.h" #include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/String.h" #include "GDCore/String.h"
namespace gd { namespace gd {
class Instruction; class Instruction;
class BaseEvent; class BaseEvent;
@@ -26,24 +25,27 @@ class ParameterMetadata;
namespace gd { namespace gd {
/** /**
* \brief AbstractArbitraryEventsWorker is a base abstract class used to browse events (and * \brief ArbitraryEventsWorker is an abstract class used to browse events (and
* instructions) and do some work on them. It must not be inherited directly. * instructions) and do some work on them. Can be used to implement refactoring
* for example.
* *
* \see gd::ArbitraryEventsWorker
* \see gd::ArbitraryEventsWorkerWithContext * \see gd::ArbitraryEventsWorkerWithContext
* *
* \ingroup IDE * \ingroup IDE
*/ */
class GD_CORE_API AbstractArbitraryEventsWorker : private EventVisitor { class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
public: public:
AbstractArbitraryEventsWorker(){}; ArbitraryEventsWorker(){};
virtual ~AbstractArbitraryEventsWorker(); virtual ~ArbitraryEventsWorker();
protected: /**
virtual bool VisitEvent(gd::BaseEvent& event) override; * \brief Launch the worker on the specified events list.
void VisitEventList(gd::EventsList& events); */
void Launch(gd::EventsList& events) { VisitEventList(events); };
private: private:
void VisitEventList(gd::EventsList& events);
bool VisitEvent(gd::BaseEvent& event) override;
bool VisitLinkEvent(gd::LinkEvent& linkEvent) override; bool VisitLinkEvent(gd::LinkEvent& linkEvent) override;
void VisitInstructionList(gd::InstructionsList& instructions, void VisitInstructionList(gd::InstructionsList& instructions,
bool areConditions); bool areConditions);
@@ -99,31 +101,6 @@ protected:
} }
}; };
/**
* \brief ArbitraryEventsWorker is an abstract class used to browse events (and
* instructions) and do some work on them. Can be used to implement refactoring
* for example.
*
* \see gd::ArbitraryEventsWorkerWithContext
*
* \ingroup IDE
*/
class GD_CORE_API ArbitraryEventsWorker : public AbstractArbitraryEventsWorker {
public:
ArbitraryEventsWorker(){};
virtual ~ArbitraryEventsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(gd::EventsList &events) {
AbstractArbitraryEventsWorker::VisitEventList(events);
};
private:
bool VisitEvent(gd::BaseEvent &event) override;
};
/** /**
* \brief An events worker that will know about the context (the objects * \brief An events worker that will know about the context (the objects
* container). Useful for workers working on expressions notably. * container). Useful for workers working on expressions notably.
@@ -133,10 +110,10 @@ private:
* \ingroup IDE * \ingroup IDE
*/ */
class GD_CORE_API ArbitraryEventsWorkerWithContext class GD_CORE_API ArbitraryEventsWorkerWithContext
: public AbstractArbitraryEventsWorker { : public ArbitraryEventsWorker {
public: public:
ArbitraryEventsWorkerWithContext() ArbitraryEventsWorkerWithContext()
: currentProjectScopedContainers(nullptr){}; : projectScopedContainers(nullptr){};
virtual ~ArbitraryEventsWorkerWithContext(); virtual ~ArbitraryEventsWorkerWithContext();
/** /**
@@ -144,50 +121,53 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
* giving the objects container on which the events are applying to. * giving the objects container on which the events are applying to.
*/ */
void Launch(gd::EventsList& events, void Launch(gd::EventsList& events,
const gd::ProjectScopedContainers& projectScopedContainers) { const gd::ProjectScopedContainers& projectScopedContainers_) {
currentProjectScopedContainers = &projectScopedContainers; projectScopedContainers = &projectScopedContainers_;
AbstractArbitraryEventsWorker::VisitEventList(events); ArbitraryEventsWorker::Launch(events);
}; };
protected: void Launch(gd::EventsList& events) = delete;
protected:
const gd::ProjectScopedContainers& GetProjectScopedContainers() { const gd::ProjectScopedContainers& GetProjectScopedContainers() {
// Pointers are guaranteed to be not nullptr after // Pointers are guaranteed to be not nullptr after
// Launch was called. // Launch was called.
return *currentProjectScopedContainers; return *projectScopedContainers;
}; };
const gd::ObjectsContainersList& GetObjectsContainersList() { const gd::ObjectsContainersList& GetObjectsContainersList() {
// Pointers are guaranteed to be not nullptr after // Pointers are guaranteed to be not nullptr after
// Launch was called. // Launch was called.
return currentProjectScopedContainers->GetObjectsContainersList(); return projectScopedContainers->GetObjectsContainersList();
}; };
private: private:
bool VisitEvent(gd::BaseEvent& event) override; const gd::ProjectScopedContainers* projectScopedContainers;
const gd::ProjectScopedContainers* currentProjectScopedContainers;
}; };
/** /**
* \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and * \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and
* instructions). It must not be inherited directly. * instructions). It can be used to implement autocompletion for example.
* *
* \see gd::ReadOnlyArbitraryEventsWorker
* \see gd::ReadOnlyArbitraryEventsWorkerWithContext * \see gd::ReadOnlyArbitraryEventsWorkerWithContext
* *
* \ingroup IDE * \ingroup IDE
*/ */
class GD_CORE_API AbstractReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor { class GD_CORE_API ReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
public: public:
AbstractReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {}; ReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
virtual ~AbstractReadOnlyArbitraryEventsWorker(); virtual ~ReadOnlyArbitraryEventsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(const gd::EventsList& events) { VisitEventList(events); };
protected: protected:
void StopAnyEventIteration() override; void StopAnyEventIteration() override;
virtual void VisitEvent(const gd::BaseEvent& event) override;
void VisitEventList(const gd::EventsList& events);
private: private:
void VisitEventList(const gd::EventsList& events);
void VisitEvent(const gd::BaseEvent& event) override;
void VisitLinkEvent(const gd::LinkEvent& linkEvent) override; void VisitLinkEvent(const gd::LinkEvent& linkEvent) override;
void VisitInstructionList(const gd::InstructionsList& instructions, void VisitInstructionList(const gd::InstructionsList& instructions,
bool areConditions); bool areConditions);
@@ -233,31 +213,6 @@ protected:
bool shouldStopIteration; bool shouldStopIteration;
}; };
/**
* \brief ReadOnlyArbitraryEventsWorker is an abstract class used to browse events (and
* instructions). It can be used to implement autocompletion for example.
*
* \see gd::ReadOnlyArbitraryEventsWorkerWithContext
*
* \ingroup IDE
*/
class GD_CORE_API ReadOnlyArbitraryEventsWorker
: public AbstractReadOnlyArbitraryEventsWorker {
public:
ReadOnlyArbitraryEventsWorker(){};
virtual ~ReadOnlyArbitraryEventsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(const gd::EventsList &events) {
AbstractReadOnlyArbitraryEventsWorker::VisitEventList(events);
};
private:
void VisitEvent(const gd::BaseEvent &event) override;
};
/** /**
* \brief An events worker that will know about the context (the objects * \brief An events worker that will know about the context (the objects
* container). Useful for workers working on expressions notably. * container). Useful for workers working on expressions notably.
@@ -267,10 +222,10 @@ private:
* \ingroup IDE * \ingroup IDE
*/ */
class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
: public AbstractReadOnlyArbitraryEventsWorker { : public ReadOnlyArbitraryEventsWorker {
public: public:
ReadOnlyArbitraryEventsWorkerWithContext() ReadOnlyArbitraryEventsWorkerWithContext()
: currentProjectScopedContainers(nullptr){}; : projectScopedContainers(nullptr){};
virtual ~ReadOnlyArbitraryEventsWorkerWithContext(); virtual ~ReadOnlyArbitraryEventsWorkerWithContext();
/** /**
@@ -278,22 +233,24 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
* giving the objects container on which the events are applying to. * giving the objects container on which the events are applying to.
*/ */
void Launch(const gd::EventsList& events, void Launch(const gd::EventsList& events,
const gd::ProjectScopedContainers& projectScopedContainers) { const gd::ProjectScopedContainers& projectScopedContainers_) {
currentProjectScopedContainers = &projectScopedContainers; projectScopedContainers = &projectScopedContainers_;
AbstractReadOnlyArbitraryEventsWorker::VisitEventList(events); ReadOnlyArbitraryEventsWorker::Launch(events);
}; };
protected: void Launch(gd::EventsList& events) = delete;
protected:
const gd::ProjectScopedContainers& GetProjectScopedContainers() { const gd::ProjectScopedContainers& GetProjectScopedContainers() {
// Pointers are guaranteed to be not nullptr after // Pointers are guaranteed to be not nullptr after
// Launch was called. // Launch was called.
return *currentProjectScopedContainers; return *projectScopedContainers;
}; };
private: private:
void VisitEvent(const gd::BaseEvent& event) override; const gd::ProjectScopedContainers* projectScopedContainers;
const gd::ProjectScopedContainers* currentProjectScopedContainers;
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_ARBITRARYEVENTSWORKER_H

View File

@@ -1,65 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2024 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "BehaviorParametersFiller.h"
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
namespace gd {
bool BehaviorParametersFiller::DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) {
const auto &metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(), metadata.GetParameters(),
[&](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue, size_t parameterIndex,
const gd::String &lastObjectName) {
if (parameterMetadata.GetValueTypeMetadata().IsBehavior() &&
parameterValue.GetPlainString().length() == 0) {
auto &expectedBehaviorTypeName =
parameterMetadata.GetValueTypeMetadata().GetExtraInfo();
auto &objectsContainersList =
projectScopedContainers.GetObjectsContainersList();
auto behaviorNames =
objectsContainersList.GetBehaviorsOfObject(lastObjectName, true);
gd::String foundBehaviorName = "";
for (auto &behaviorName : behaviorNames) {
auto behaviorTypeName =
objectsContainersList.GetTypeOfBehavior(behaviorName, false);
if (behaviorTypeName == expectedBehaviorTypeName) {
foundBehaviorName = behaviorName;
break;
}
}
if (!foundBehaviorName.empty()) {
instruction.SetParameter(parameterIndex,
gd::Expression(foundBehaviorName));
}
}
});
return false;
}
BehaviorParametersFiller::~BehaviorParametersFiller() {}
} // namespace gd

View File

@@ -1,45 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2024 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h"
#include <map>
#include <memory>
#include <vector>
namespace gd {
class Instruction;
class Platform;
class ProjectScopedContainers;
} // namespace gd
namespace gd {
/**
* \brief Fill empty behavior parameters with any behavior that matches the
* required behavior type.
*
* \ingroup IDE
*/
class GD_CORE_API BehaviorParametersFiller : public ArbitraryEventsWorker {
public:
BehaviorParametersFiller(
const gd::Platform &platform_,
const gd::ProjectScopedContainers &projectScopedContainers_)
: platform(platform_),
projectScopedContainers(projectScopedContainers_){};
virtual ~BehaviorParametersFiller();
private:
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;
const gd::Platform &platform;
const gd::ProjectScopedContainers &projectScopedContainers;
};
} // namespace gd

View File

@@ -72,12 +72,12 @@ public:
gd::String lastObjectParameter = ""; gd::String lastObjectParameter = "";
const gd::InstructionMetadata &instrInfos = const gd::InstructionMetadata &instrInfos =
MetadataProvider::GetActionMetadata(platform, instruction.GetType()); MetadataProvider::GetActionMetadata(platform, instruction.GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsExpression( if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters.GetParameter(pNb).GetType()) || "number", instrInfos.parameters[pNb].GetType()) ||
ParameterMetadata::IsExpression( ParameterMetadata::IsExpression(
"string", instrInfos.parameters.GetParameter(pNb).GetType())) { "string", instrInfos.parameters[pNb].GetType())) {
auto node = instruction.GetParameter(pNb).GetRootNode(); auto node = instruction.GetParameter(pNb).GetRootNode();
node->Visit(*this); node->Visit(*this);
} }

View File

@@ -86,11 +86,9 @@ class GD_CORE_API IdentifierFinderExpressionNodeWorker
} }
size_t parameterIndex = 0; size_t parameterIndex = 0;
for (size_t metadataIndex = (isObjectFunction ? 1 : 0); for (size_t metadataIndex = (isObjectFunction ? 1 : 0); metadataIndex < metadata.parameters.size()
metadataIndex < metadata.GetParameters().GetParametersCount() && && parameterIndex < node.parameters.size(); ++metadataIndex) {
parameterIndex < node.parameters.size(); auto& parameterMetadata = metadata.parameters[metadataIndex];
++metadataIndex) {
auto& parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
if (parameterMetadata.IsCodeOnly()) { if (parameterMetadata.IsCodeOnly()) {
continue; continue;
} }
@@ -146,10 +144,10 @@ class GD_CORE_API IdentifierFinderEventWorker
platform, instruction.GetType()) platform, instruction.GetType())
: MetadataProvider::GetActionMetadata( : MetadataProvider::GetActionMetadata(
platform, instruction.GetType()); platform, instruction.GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// The parameter has the searched type... // The parameter has the searched type...
if (instrInfos.parameters.GetParameter(pNb).GetType() == "identifier" if (instrInfos.parameters[pNb].GetType() == "identifier"
&& instrInfos.parameters.GetParameter(pNb).GetExtraInfo() == identifierType) { && instrInfos.parameters[pNb].GetExtraInfo() == identifierType) {
//...remember the value of the parameter. //...remember the value of the parameter.
if (objectName.empty() || lastObjectParameter == objectName) { if (objectName.empty() || lastObjectParameter == objectName) {
results.insert(instruction.GetParameter(pNb).GetPlainString()); results.insert(instruction.GetParameter(pNb).GetPlainString());
@@ -157,9 +155,9 @@ class GD_CORE_API IdentifierFinderEventWorker
} }
// Search in expressions // Search in expressions
else if (ParameterMetadata::IsExpression( else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters.GetParameter(pNb).GetType()) || "number", instrInfos.parameters[pNb].GetType()) ||
ParameterMetadata::IsExpression( ParameterMetadata::IsExpression(
"string", instrInfos.parameters.GetParameter(pNb).GetType())) { "string", instrInfos.parameters[pNb].GetType())) {
auto node = instruction.GetParameter(pNb).GetRootNode(); auto node = instruction.GetParameter(pNb).GetRootNode();
IdentifierFinderExpressionNodeWorker searcher( IdentifierFinderExpressionNodeWorker searcher(
@@ -172,7 +170,7 @@ class GD_CORE_API IdentifierFinderEventWorker
} }
// Remember the value of the last "object" parameter. // Remember the value of the last "object" parameter.
else if (gd::ParameterMetadata::IsObject( else if (gd::ParameterMetadata::IsObject(
instrInfos.parameters.GetParameter(pNb).GetType())) { instrInfos.parameters[pNb].GetType())) {
lastObjectParameter = lastObjectParameter =
instruction.GetParameter(pNb).GetPlainString(); instruction.GetParameter(pNb).GetPlainString();
} }

View File

@@ -0,0 +1,41 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/IDE/Events/EventsLeaderboardsLister.h"
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/String.h"
namespace gd {
bool EventsLeaderboardsLister::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
const gd::InstructionMetadata& instrInfo =
isCondition ? MetadataProvider::GetConditionMetadata(
project.GetCurrentPlatform(), instruction.GetType())
: MetadataProvider::GetActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
for (int i = 0; i < instruction.GetParametersCount() &&
i < instrInfo.GetParametersCount();
++i)
if (instrInfo.GetParameter(i).GetType() == "leaderboardId") {
leaderboardIds.insert(instruction.GetParameter(i).GetPlainString());
}
return false;
}
EventsLeaderboardsLister::~EventsLeaderboardsLister() {}
} // namespace gd

View File

@@ -0,0 +1,48 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef EventsLeaderboardsLister_H
#define EventsLeaderboardsLister_H
#include <map>
#include <memory>
#include <set>
#include <vector>
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h"
namespace gd {
class BaseEvent;
class Project;
class EventsList;
}
namespace gd {
/**
* \brief List the leaderboard ids in the instructions.
*
* \ingroup IDE
*/
class GD_CORE_API EventsLeaderboardsLister : public ArbitraryEventsWorker {
public:
EventsLeaderboardsLister(gd::Project& project_) : project(project_){};
virtual ~EventsLeaderboardsLister();
/**
* Return the values of all leaderboardIds found in the events.
*/
const std::set<gd::String>& GetLeaderboardIds() { return leaderboardIds; }
private:
virtual bool DoVisitInstruction(gd::Instruction& instruction,
bool isCondition);
std::set<gd::String> leaderboardIds;
gd::Project& project;
};
} // namespace gd
#endif // EventsLeaderboardsLister_H

View File

@@ -0,0 +1,49 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/IDE/Events/EventsLeaderboardsRenamer.h"
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/String.h"
namespace gd {
bool EventsLeaderboardsRenamer::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
const gd::InstructionMetadata& instrInfo =
isCondition ? MetadataProvider::GetConditionMetadata(
project.GetCurrentPlatform(), instruction.GetType())
: MetadataProvider::GetActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
for (int i = 0; i < instruction.GetParametersCount() &&
i < instrInfo.GetParametersCount();
++i) {
const gd::ParameterMetadata parameter = instrInfo.GetParameter(i);
if (parameter.GetType() == "leaderboardId") {
const gd::String leaderboardId =
instruction.GetParameter(i).GetPlainString();
if (leaderboardIdMap.find(leaderboardId) != leaderboardIdMap.end()) {
instruction.SetParameter(i, leaderboardIdMap[leaderboardId]);
}
}
}
return false;
}
EventsLeaderboardsRenamer::~EventsLeaderboardsRenamer() {}
} // namespace gd

View File

@@ -0,0 +1,46 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef EventsLeaderboardsRenamer_H
#define EventsLeaderboardsRenamer_H
#include <map>
#include <memory>
#include <set>
#include <vector>
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h"
namespace gd {
class BaseEvent;
class Project;
class EventsList;
}
namespace gd {
/**
* \brief Replace the leaderboard ids in the instructions.
*
* \ingroup IDE
*/
class GD_CORE_API EventsLeaderboardsRenamer : public ArbitraryEventsWorker {
public:
EventsLeaderboardsRenamer(
gd::Project& project_,
const std::map<gd::String, gd::String>& leaderboardIdMap_)
: project(project_), leaderboardIdMap(leaderboardIdMap_){};
virtual ~EventsLeaderboardsRenamer();
private:
virtual bool DoVisitInstruction(gd::Instruction& instruction,
bool isCondition);
std::map<gd::String, gd::String> leaderboardIdMap;
gd::Project& project;
};
} // namespace gd
#endif // EventsLeaderboardsRenamer_H

View File

@@ -1,243 +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/EventsParameterReplacer.h"
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ParameterMetadata.h"
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/Project/PropertiesContainer.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
namespace gd {
/**
* \brief Go through the nodes and rename parameters.
*
* \see gd::ExpressionParser2
*/
class GD_CORE_API ExpressionParameterReplacer
: public ExpressionParser2NodeWorker {
public:
ExpressionParameterReplacer(
const gd::Platform& platform_,
const gd::ProjectScopedContainers& projectScopedContainers_,
bool isParentTypeAVariable_,
const std::unordered_map<gd::String, gd::String>& oldToNewPropertyNames_)
: hasDoneRenaming(false),
platform(platform_),
projectScopedContainers(projectScopedContainers_),
isParentTypeAVariable(isParentTypeAVariable_),
oldToNewPropertyNames(oldToNewPropertyNames_){};
virtual ~ExpressionParameterReplacer(){};
bool HasDoneRenaming() const { return hasDoneRenaming; }
protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
node.expression->Visit(*this);
}
void OnVisitOperatorNode(OperatorNode& node) override {
node.leftHandSide->Visit(*this);
node.rightHandSide->Visit(*this);
}
void OnVisitUnaryOperatorNode(UnaryOperatorNode& node) override {
node.factor->Visit(*this);
}
void OnVisitNumberNode(NumberNode& node) override {}
void OnVisitTextNode(TextNode& node) override {}
void OnVisitVariableNode(VariableNode& node) override {
if (isParentTypeAVariable) {
// Do nothing, it's a variable.
if (node.child) node.child->Visit(*this);
return;
}
// The node represents a variable or an object name on which a variable
// will be accessed, or a property with a child.
projectScopedContainers.MatchIdentifierWithName<void>(
// The property name is changed after the refactor operation.
node.name,
[&]() {
// Do nothing, it's an object variable.
if (node.child) node.child->Visit(*this);
}, [&]() {
// Do nothing, it's a variable.
if (node.child) node.child->Visit(*this);
}, [&]() {
// Do nothing, it's a property.
if (node.child) node.child->Visit(*this);
}, [&]() {
// This is a parameter
RenameParameter(node.name);
if (node.child) node.child->Visit(*this);
}, [&]() {
// Do nothing, it's something else.
if (node.child) node.child->Visit(*this);
});
}
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
if (node.child) node.child->Visit(*this);
}
void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) override {
bool isGrandParentTypeAVariable = isParentTypeAVariable;
isParentTypeAVariable = false;
node.expression->Visit(*this);
isParentTypeAVariable = isGrandParentTypeAVariable;
if (node.child) node.child->Visit(*this);
}
void OnVisitIdentifierNode(IdentifierNode& node) override {
if (isParentTypeAVariable) {
// Do nothing, it's a variable.
return;
}
projectScopedContainers.MatchIdentifierWithName<void>(
// The property name is changed after the refactor operation
node.identifierName,
[&]() {
// Do nothing, it's an object variable.
}, [&]() {
// Do nothing, it's a variable.
}, [&]() {
// Do nothing, it's a property.
}, [&]() {
// This is a parameter.
RenameParameter(node.identifierName);
}, [&]() {
// Do nothing, it's something else.
});
}
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
void OnVisitFunctionCallNode(FunctionCallNode &node) override {
bool isGrandParentTypeAVariable = isParentTypeAVariable;
for (auto &parameter : node.parameters) {
const auto &parameterMetadata =
gd::MetadataProvider::GetFunctionCallParameterMetadata(
platform, projectScopedContainers.GetObjectsContainersList(),
node, *parameter);
if (!parameterMetadata) {
continue;
}
const auto &parameterTypeMetadata =
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsParameterReplacer::CanContainParameter(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
}
isParentTypeAVariable = isGrandParentTypeAVariable;
}
void OnVisitEmptyNode(EmptyNode& node) override {}
private:
bool hasDoneRenaming;
bool RenameParameter(
gd::String& name) {
if (oldToNewPropertyNames.count(name) >= 1) {
name = oldToNewPropertyNames.find(name)->second;
hasDoneRenaming = true;
return true;
}
return false; // Nothing was changed or done.
}
// Scope:
const gd::Platform& platform;
const gd::ProjectScopedContainers& projectScopedContainers;
// Renaming to do
const std::unordered_map<gd::String, gd::String>& oldToNewPropertyNames;
gd::String objectNameToUseForVariableAccessor;
bool isParentTypeAVariable;
};
bool EventsParameterReplacer::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
if (!gd::EventsParameterReplacer::CanContainParameter(
parameterMetadata.GetValueTypeMetadata())) {
return;
}
auto node = parameterValue.GetRootNode();
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(),
oldToNewPropertyNames);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {
instruction.SetParameter(
parameterIndex, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
});
return false;
}
bool EventsParameterReplacer::DoVisitEventExpression(
gd::Expression& expression, const gd::ParameterMetadata& metadata) {
if (!gd::EventsParameterReplacer::CanContainParameter(
metadata.GetValueTypeMetadata())) {
return false;
}
auto node = expression.GetRootNode();
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
}
}
return false;
}
bool EventsParameterReplacer::CanContainParameter(
const gd::ValueTypeMetadata &valueTypeMetadata) {
return valueTypeMetadata.IsVariable() || valueTypeMetadata.IsNumber() ||
valueTypeMetadata.IsString();
}
EventsParameterReplacer::~EventsParameterReplacer() {}
} // namespace gd

View File

@@ -1,52 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h"
namespace gd {
class BaseEvent;
class PropertiesContainer;
class EventsList;
class Platform;
} // namespace gd
namespace gd {
/**
* \brief Replace in expressions and in parameters of actions or conditions,
* references to the name of a parameter by another.
*
* \ingroup IDE
*/
class GD_CORE_API EventsParameterReplacer
: public ArbitraryEventsWorkerWithContext {
public:
EventsParameterReplacer(
const gd::Platform &platform_,
const std::unordered_map<gd::String, gd::String> &oldToNewPropertyNames_)
: platform(platform_),
oldToNewPropertyNames(oldToNewPropertyNames_){};
virtual ~EventsParameterReplacer();
static bool CanContainParameter(const gd::ValueTypeMetadata &valueTypeMetadata);
private:
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;
bool DoVisitEventExpression(gd::Expression &expression,
const gd::ParameterMetadata &metadata) override;
const gd::Platform &platform;
const std::unordered_map<gd::String, gd::String> &oldToNewPropertyNames;
};
} // namespace gd

View File

@@ -41,7 +41,6 @@ class GD_CORE_API ExpressionPropertyReplacer
const gd::Platform& platform_, const gd::Platform& platform_,
const gd::ProjectScopedContainers& projectScopedContainers_, const gd::ProjectScopedContainers& projectScopedContainers_,
const gd::PropertiesContainer& targetPropertiesContainer_, const gd::PropertiesContainer& targetPropertiesContainer_,
bool isParentTypeAVariable_,
const std::unordered_map<gd::String, gd::String>& oldToNewPropertyNames_, const std::unordered_map<gd::String, gd::String>& oldToNewPropertyNames_,
const std::unordered_set<gd::String>& removedPropertyNames_) const std::unordered_set<gd::String>& removedPropertyNames_)
: hasDoneRenaming(false), : hasDoneRenaming(false),
@@ -49,7 +48,6 @@ class GD_CORE_API ExpressionPropertyReplacer
platform(platform_), platform(platform_),
projectScopedContainers(projectScopedContainers_), projectScopedContainers(projectScopedContainers_),
targetPropertiesContainer(targetPropertiesContainer_), targetPropertiesContainer(targetPropertiesContainer_),
isParentTypeAVariable(isParentTypeAVariable_),
oldToNewPropertyNames(oldToNewPropertyNames_), oldToNewPropertyNames(oldToNewPropertyNames_),
removedPropertyNames(removedPropertyNames_){}; removedPropertyNames(removedPropertyNames_){};
virtual ~ExpressionPropertyReplacer(){}; virtual ~ExpressionPropertyReplacer(){};
@@ -71,21 +69,16 @@ class GD_CORE_API ExpressionPropertyReplacer
void OnVisitNumberNode(NumberNode& node) override {} void OnVisitNumberNode(NumberNode& node) override {}
void OnVisitTextNode(TextNode& node) override {} void OnVisitTextNode(TextNode& node) override {}
void OnVisitVariableNode(VariableNode& node) override { void OnVisitVariableNode(VariableNode& node) override {
if (isParentTypeAVariable) {
// Do nothing, it's a variable.
if (node.child) node.child->Visit(*this);
return;
}
auto& propertiesContainersList = auto& propertiesContainersList =
projectScopedContainers.GetPropertiesContainersList(); projectScopedContainers.GetPropertiesContainersList();
// The node represents a variable or an object name on which a variable // The node represents a variable or an object name on which a variable
// will be accessed, or a property with a child. // will be accessed, or a property with a child.
// Match the potential *new* name of the property, because refactorings are
// done after changes in the variables container.
projectScopedContainers.MatchIdentifierWithName<void>( projectScopedContainers.MatchIdentifierWithName<void>(
// The property name is changed after the refactor operation. GetPotentialNewName(node.name),
node.name,
[&]() { [&]() {
// Do nothing, it's an object variable. // Do nothing, it's an object variable.
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
@@ -107,7 +100,16 @@ class GD_CORE_API ExpressionPropertyReplacer
// Do nothing, it's a parameter. // Do nothing, it's a parameter.
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
}, [&]() { }, [&]() {
// Do nothing, it's something else. // This is something else - potentially a deleted property.
// Check if it's coming from the target container with
// properties to replace.
if (propertiesContainersList.HasPropertiesContainer(
targetPropertiesContainer)) {
// The node represents a property, that can come from the target
// (because the target is in the scope), replace or remove it:
RenameOrRemovePropertyOfTargetPropertyContainer(node.name);
}
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
}); });
} }
@@ -116,24 +118,17 @@ class GD_CORE_API ExpressionPropertyReplacer
} }
void OnVisitVariableBracketAccessorNode( void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) override { VariableBracketAccessorNode& node) override {
bool isGrandParentTypeAVariable = isParentTypeAVariable;
isParentTypeAVariable = false;
node.expression->Visit(*this); node.expression->Visit(*this);
isParentTypeAVariable = isGrandParentTypeAVariable;
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
} }
void OnVisitIdentifierNode(IdentifierNode& node) override { void OnVisitIdentifierNode(IdentifierNode& node) override {
if (isParentTypeAVariable) {
// Do nothing, it's a variable.
return;
}
auto& propertiesContainersList = auto& propertiesContainersList =
projectScopedContainers.GetPropertiesContainersList(); projectScopedContainers.GetPropertiesContainersList();
// Match the potential *new* name of the property, because refactorings are
// done after changes in the variables container.
projectScopedContainers.MatchIdentifierWithName<void>( projectScopedContainers.MatchIdentifierWithName<void>(
// The property name is changed after the refactor operation GetPotentialNewName(node.identifierName),
node.identifierName,
[&]() { [&]() {
// Do nothing, it's an object variable. // Do nothing, it's an object variable.
}, [&]() { }, [&]() {
@@ -150,29 +145,22 @@ class GD_CORE_API ExpressionPropertyReplacer
}, [&]() { }, [&]() {
// Do nothing, it's a parameter. // Do nothing, it's a parameter.
}, [&]() { }, [&]() {
// Do nothing, it's something else. // This is something else - potentially a deleted property.
// Check if it's coming from the target container with
// properties to replace.
if (propertiesContainersList.HasPropertiesContainer(
targetPropertiesContainer)) {
// The node represents a property, that can come from the target
// (because the target is in the scope), replace or remove it:
RenameOrRemovePropertyOfTargetPropertyContainer(node.identifierName);
}
}); });
} }
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {} void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
void OnVisitFunctionCallNode(FunctionCallNode &node) override { void OnVisitFunctionCallNode(FunctionCallNode& node) override {
bool isGrandParentTypeAVariable = isParentTypeAVariable; for (auto& parameter : node.parameters) {
for (auto &parameter : node.parameters) { parameter->Visit(*this);
const auto &parameterMetadata =
gd::MetadataProvider::GetFunctionCallParameterMetadata(
platform, projectScopedContainers.GetObjectsContainersList(),
node, *parameter);
if (!parameterMetadata) {
continue;
}
const auto &parameterTypeMetadata =
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsPropertyReplacer::CanContainProperty(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
} }
isParentTypeAVariable = isGrandParentTypeAVariable;
} }
void OnVisitEmptyNode(EmptyNode& node) override {} void OnVisitEmptyNode(EmptyNode& node) override {}
@@ -180,6 +168,12 @@ class GD_CORE_API ExpressionPropertyReplacer
bool hasDoneRenaming; bool hasDoneRenaming;
bool removedPropertyUsed; bool removedPropertyUsed;
const gd::String& GetPotentialNewName(const gd::String& oldName) {
return oldToNewPropertyNames.count(oldName) >= 1
? oldToNewPropertyNames.find(oldName)->second
: oldName;
}
bool RenameOrRemovePropertyOfTargetPropertyContainer( bool RenameOrRemovePropertyOfTargetPropertyContainer(
gd::String& propertyName) { gd::String& propertyName) {
if (oldToNewPropertyNames.count(propertyName) >= 1) { if (oldToNewPropertyNames.count(propertyName) >= 1) {
@@ -204,7 +198,6 @@ class GD_CORE_API ExpressionPropertyReplacer
const std::unordered_set<gd::String>& removedPropertyNames; const std::unordered_set<gd::String>& removedPropertyNames;
gd::String objectNameToUseForVariableAccessor; gd::String objectNameToUseForVariableAccessor;
bool isParentTypeAVariable;
}; };
bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction, bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
@@ -223,16 +216,20 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
const gd::Expression& parameterValue, const gd::Expression& parameterValue,
size_t parameterIndex, size_t parameterIndex,
const gd::String& lastObjectName) { const gd::String& lastObjectName) {
if (!gd::EventsPropertyReplacer::CanContainProperty( const gd::String& type = parameterMetadata.GetType();
parameterMetadata.GetValueTypeMetadata())) {
return; if (!gd::ParameterMetadata::IsExpression("variable", type) &&
} !gd::ParameterMetadata::IsExpression("number", type) &&
!gd::ParameterMetadata::IsExpression("string", type))
return; // Not an expression that can contain properties.
auto node = parameterValue.GetRootNode(); auto node = parameterValue.GetRootNode();
if (node) { if (node) {
ExpressionPropertyReplacer renamer( ExpressionPropertyReplacer renamer(platform,
platform, GetProjectScopedContainers(), targetPropertiesContainer, GetProjectScopedContainers(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(), targetPropertiesContainer,
oldToNewPropertyNames, removedPropertyNames); oldToNewPropertyNames,
removedPropertyNames);
node->Visit(renamer); node->Visit(renamer);
if (renamer.IsRemovedPropertyUsed()) { if (renamer.IsRemovedPropertyUsed()) {
@@ -249,16 +246,20 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
bool EventsPropertyReplacer::DoVisitEventExpression( bool EventsPropertyReplacer::DoVisitEventExpression(
gd::Expression& expression, const gd::ParameterMetadata& metadata) { gd::Expression& expression, const gd::ParameterMetadata& metadata) {
if (!gd::EventsPropertyReplacer::CanContainProperty( const gd::String& type = metadata.GetType();
metadata.GetValueTypeMetadata())) {
return false; if (!gd::ParameterMetadata::IsExpression("variable", type) &&
} !gd::ParameterMetadata::IsExpression("number", type) &&
!gd::ParameterMetadata::IsExpression("string", type))
return false; // Not an expression that can contain properties.
auto node = expression.GetRootNode(); auto node = expression.GetRootNode();
if (node) { if (node) {
ExpressionPropertyReplacer renamer( ExpressionPropertyReplacer renamer(platform,
platform, GetProjectScopedContainers(), targetPropertiesContainer, GetProjectScopedContainers(),
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames, targetPropertiesContainer,
removedPropertyNames); oldToNewPropertyNames,
removedPropertyNames);
node->Visit(renamer); node->Visit(renamer);
if (renamer.IsRemovedPropertyUsed()) { if (renamer.IsRemovedPropertyUsed()) {
@@ -271,12 +272,6 @@ bool EventsPropertyReplacer::DoVisitEventExpression(
return false; return false;
} }
bool EventsPropertyReplacer::CanContainProperty(
const gd::ValueTypeMetadata &valueTypeMetadata) {
return valueTypeMetadata.IsVariable() || valueTypeMetadata.IsNumber() ||
valueTypeMetadata.IsString();
}
EventsPropertyReplacer::~EventsPropertyReplacer() {} EventsPropertyReplacer::~EventsPropertyReplacer() {}
} // namespace gd } // namespace gd

View File

@@ -4,7 +4,6 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #pragma once
#include <map> #include <map>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@@ -42,8 +41,6 @@ class GD_CORE_API EventsPropertyReplacer
removedPropertyNames(removedPropertyNames_){}; removedPropertyNames(removedPropertyNames_){};
virtual ~EventsPropertyReplacer(); virtual ~EventsPropertyReplacer();
static bool CanContainProperty(const gd::ValueTypeMetadata &valueTypeMetadata);
private: private:
bool DoVisitInstruction(gd::Instruction &instruction, bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override; bool isCondition) override;

View File

@@ -22,7 +22,6 @@
#include "GDCore/Project/EventsBasedObject.h" #include "GDCore/Project/EventsBasedObject.h"
#include "GDCore/Project/ProjectScopedContainers.h" #include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h" #include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
using namespace std; using namespace std;
@@ -52,17 +51,17 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
static bool Rename(const gd::Platform &platform, static bool Rename(const gd::Platform &platform,
const gd::ProjectScopedContainers &projectScopedContainers, const gd::ProjectScopedContainers &projectScopedContainers,
const gd::String &rootType, gd::ExpressionNode &node, const gd::String &rootType,
const gd::String &objectName, gd::ExpressionNode& node,
const gd::String &objectNewName) { const gd::String& objectName,
if (gd::ExpressionValidator::HasNoErrors(platform, projectScopedContainers, const gd::String& objectNewName) {
rootType, node)) { if (gd::ExpressionValidator::HasNoErrors(platform, projectScopedContainers, rootType, node)) {
ExpressionObjectRenamer renamer(platform, projectScopedContainers, ExpressionObjectRenamer renamer(platform, projectScopedContainers, rootType, objectName, objectNewName);
rootType, objectName, objectNewName);
node.Visit(renamer); node.Visit(renamer);
return renamer.HasDoneRenaming(); return renamer.HasDoneRenaming();
} }
return false; return false;
} }
@@ -84,7 +83,7 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
void OnVisitVariableNode(VariableNode& node) override { void OnVisitVariableNode(VariableNode& node) override {
auto type = gd::ExpressionTypeFinder::GetType(platform, projectScopedContainers, rootType, node); auto type = gd::ExpressionTypeFinder::GetType(platform, projectScopedContainers, rootType, node);
if (gd::ValueTypeMetadata::IsVariable(type)) { if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
// Nothing to do (this can't reference an object) // Nothing to do (this can't reference an object)
} else { } else {
if (node.name == objectName) { if (node.name == objectName) {
@@ -120,7 +119,7 @@ class GD_CORE_API ExpressionObjectRenamer : public ExpressionParser2NodeWorker {
node.identifierName == objectName) { node.identifierName == objectName) {
hasDoneRenaming = true; hasDoneRenaming = true;
node.identifierName = objectNewName; node.identifierName = objectNewName;
} else if (gd::ValueTypeMetadata::IsVariable(type)) { } else if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
// Nothing to do (this can't reference an object) // Nothing to do (this can't reference an object)
} else { } else {
if (node.identifierName == objectName) { if (node.identifierName == objectName) {
@@ -296,118 +295,187 @@ class GD_CORE_API ExpressionObjectFinder : public ExpressionParser2NodeWorker {
const gd::String rootType; const gd::String rootType;
}; };
/** bool EventsRefactorer::RenameObjectInActions(const gd::Platform& platform,
* \brief Replace in expressions and in parameters of actions or conditions, gd::ProjectScopedContainers& projectScopedContainers,
* references to the name of an object by another. gd::InstructionsList& actions,
* gd::String oldName,
* \ingroup IDE gd::String newName) {
*/ bool somethingModified = false;
class GD_CORE_API EventsObjectReplacer
: public ArbitraryEventsWorkerWithContext {
public:
EventsObjectReplacer(const gd::Platform &platform_,
const gd::ObjectsContainer &targetedObjectsContainer_,
const gd::String &oldObjectName_,
const gd::String &newObjectName_)
: platform(platform_),
targetedObjectsContainer(targetedObjectsContainer_),
oldObjectName(oldObjectName_), newObjectName(newObjectName_){};
virtual ~EventsObjectReplacer() {} for (std::size_t aId = 0; aId < actions.size(); ++aId) {
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Replace object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
actions[aId].GetParameter(pNb).GetPlainString() == oldName)
actions[aId].SetParameter(pNb, gd::Expression(newName));
// Replace object's name in expressions
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].GetType())) {
auto node = actions[aId].GetParameter(pNb).GetRootNode();
private: if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "number", *node, oldName, newName)) {
bool DoVisitInstruction(gd::Instruction &instruction, actions[aId].SetParameter(
bool isCondition) override { pNb, ExpressionParser2NodePrinter::PrintNode(*node));
if (&targetedObjectsContainer != }
GetProjectScopedContainers() }
.GetObjectsContainersList() // Replace object's name in text expressions
.GetObjectsContainerFromObjectName(oldObjectName)) { else if (ParameterMetadata::IsExpression(
return false; "string", instrInfos.parameters[pNb].GetType())) {
} auto node = actions[aId].GetParameter(pNb).GetRootNode();
const auto &metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex( if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
instruction.GetParameters(), metadata.GetParameters(), actions[aId].SetParameter(
[&](const gd::ParameterMetadata &parameterMetadata, pNb, ExpressionParser2NodePrinter::PrintNode(*node));
const gd::Expression &parameterValue, size_t parameterIndex, }
const gd::String &lastObjectName) {
if (!gd::EventsObjectReplacer::CanContainObject(
parameterMetadata.GetValueTypeMetadata())) {
return;
}
auto node = parameterValue.GetRootNode();
if (node) {
ExpressionObjectRenamer renamer(
platform, GetProjectScopedContainers(),
parameterMetadata.GetValueTypeMetadata().GetName(),
oldObjectName, newObjectName);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {
instruction.SetParameter(
parameterIndex,
ExpressionParser2NodePrinter::PrintNode(*node));
}
}
});
return false;
}
bool DoVisitEventExpression(gd::Expression &expression,
const gd::ParameterMetadata &metadata) override {
if (&targetedObjectsContainer !=
GetProjectScopedContainers()
.GetObjectsContainersList()
.GetObjectsContainerFromObjectName(oldObjectName)) {
return false;
}
if (!gd::EventsObjectReplacer::CanContainObject(
metadata.GetValueTypeMetadata())) {
return false;
}
auto node = expression.GetRootNode();
if (node) {
ExpressionObjectRenamer renamer(platform, GetProjectScopedContainers(),
metadata.GetValueTypeMetadata().GetName(),
oldObjectName, newObjectName);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
} }
} }
return false; if (!actions[aId].GetSubInstructions().empty())
somethingModified =
RenameObjectInActions(platform,
projectScopedContainers,
actions[aId].GetSubInstructions(),
oldName,
newName) ||
somethingModified;
} }
bool CanContainObject(const gd::ValueTypeMetadata &valueTypeMetadata) { return somethingModified;
return valueTypeMetadata.IsObject() || valueTypeMetadata.IsVariable() || }
valueTypeMetadata.IsNumber() || valueTypeMetadata.IsString();
bool EventsRefactorer::RenameObjectInConditions(
const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& conditions,
gd::String oldName,
gd::String newName) {
bool somethingModified = false;
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetConditionMetadata(platform,
conditions[cId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Replace object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
conditions[cId].GetParameter(pNb).GetPlainString() == oldName)
conditions[cId].SetParameter(pNb, gd::Expression(newName));
// Replace object's name in expressions
else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters[pNb].GetType())) {
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "number", *node, oldName, newName)) {
conditions[cId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters[pNb].GetType())) {
auto node = conditions[cId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
conditions[cId].SetParameter(
pNb, ExpressionParser2NodePrinter::PrintNode(*node));
}
}
}
if (!conditions[cId].GetSubInstructions().empty())
somethingModified =
RenameObjectInConditions(platform,
projectScopedContainers,
conditions[cId].GetSubInstructions(),
oldName,
newName) ||
somethingModified;
} }
const gd::Platform &platform; return somethingModified;
const gd::ObjectsContainer &targetedObjectsContainer; }
const gd::String &oldObjectName;
const gd::String &newObjectName; bool EventsRefactorer::RenameObjectInEventParameters(
}; const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::Expression& expression,
gd::ParameterMetadata parameterMetadata,
gd::String oldName,
gd::String newName) {
bool somethingModified = false;
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()) &&
expression.GetPlainString() == oldName)
expression = gd::Expression(newName);
// Replace object's name in expressions
else if (ParameterMetadata::IsExpression("number",
parameterMetadata.GetType())) {
auto node = expression.GetRootNode();
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "number", *node, oldName, newName)) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression("string",
parameterMetadata.GetType())) {
auto node = expression.GetRootNode();
if (ExpressionObjectRenamer::Rename(platform, projectScopedContainers, "string", *node, oldName, newName)) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
}
}
return somethingModified;
}
void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform, void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::EventsList& events, gd::EventsList& events,
const gd::ObjectsContainer &targetedObjectsContainer,
gd::String oldName, gd::String oldName,
gd::String newName) { gd::String newName) {
gd::EventsObjectReplacer eventsParameterReplacer(platform, targetedObjectsContainer, oldName, newName); for (std::size_t i = 0; i < events.size(); ++i) {
eventsParameterReplacer.Launch(events, projectScopedContainers); vector<gd::InstructionsList*> conditionsVectors =
events[i].GetAllConditionsVectors();
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
bool somethingModified = RenameObjectInConditions(
platform, projectScopedContainers, *conditionsVectors[j], oldName, newName);
}
vector<gd::InstructionsList*> actionsVectors =
events[i].GetAllActionsVectors();
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
bool somethingModified = RenameObjectInActions(
platform, projectScopedContainers, *actionsVectors[j], oldName, newName);
}
vector<pair<gd::Expression*, gd::ParameterMetadata>>
expressionsWithMetadata = events[i].GetAllExpressionsWithMetadata();
for (std::size_t j = 0; j < expressionsWithMetadata.size(); ++j) {
gd::Expression* expression = expressionsWithMetadata[j].first;
gd::ParameterMetadata parameterMetadata =
expressionsWithMetadata[j].second;
bool somethingModified = RenameObjectInEventParameters(platform,
projectScopedContainers,
*expression,
parameterMetadata,
oldName,
newName);
}
if (events[i].CanHaveSubEvents())
RenameObjectInEvents(platform,
projectScopedContainers,
events[i].GetSubEvents(),
oldName,
newName);
}
} }
bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform, bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& actions, gd::InstructionsList& actions,
gd::String name) { gd::String name) {
bool somethingModified = false; bool somethingModified = false;
@@ -417,16 +485,16 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
const gd::InstructionMetadata& instrInfos = const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType()); MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Find object's name in parameters // Find object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) && if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
actions[aId].GetParameter(pNb).GetPlainString() == name) { actions[aId].GetParameter(pNb).GetPlainString() == name) {
deleteMe = true; deleteMe = true;
break; break;
} }
// Find object's name in expressions // Find object's name in expressions
else if (ParameterMetadata::IsExpression( else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters.GetParameter(pNb).GetType())) { "number", instrInfos.parameters[pNb].GetType())) {
auto node = actions[aId].GetParameter(pNb).GetRootNode(); auto node = actions[aId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) { if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) {
@@ -436,7 +504,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
} }
// Find object's name in text expressions // Find object's name in text expressions
else if (ParameterMetadata::IsExpression( else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters.GetParameter(pNb).GetType())) { "string", instrInfos.parameters[pNb].GetType())) {
auto node = actions[aId].GetParameter(pNb).GetRootNode(); auto node = actions[aId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) { if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
@@ -464,7 +532,7 @@ bool EventsRefactorer::RemoveObjectInActions(const gd::Platform& platform,
bool EventsRefactorer::RemoveObjectInConditions( bool EventsRefactorer::RemoveObjectInConditions(
const gd::Platform& platform, const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& conditions, gd::InstructionsList& conditions,
gd::String name) { gd::String name) {
bool somethingModified = false; bool somethingModified = false;
@@ -475,16 +543,16 @@ bool EventsRefactorer::RemoveObjectInConditions(
const gd::InstructionMetadata& instrInfos = const gd::InstructionMetadata& instrInfos =
MetadataProvider::GetConditionMetadata(platform, MetadataProvider::GetConditionMetadata(platform,
conditions[cId].GetType()); conditions[cId].GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) { for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
// Find object's name in parameters // Find object's name in parameters
if (gd::ParameterMetadata::IsObject(instrInfos.parameters.GetParameter(pNb).GetType()) && if (gd::ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType()) &&
conditions[cId].GetParameter(pNb).GetPlainString() == name) { conditions[cId].GetParameter(pNb).GetPlainString() == name) {
deleteMe = true; deleteMe = true;
break; break;
} }
// Find object's name in expressions // Find object's name in expressions
else if (ParameterMetadata::IsExpression( else if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters.GetParameter(pNb).GetType())) { "number", instrInfos.parameters[pNb].GetType())) {
auto node = conditions[cId].GetParameter(pNb).GetRootNode(); auto node = conditions[cId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) { if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "number", *node, name)) {
@@ -494,7 +562,7 @@ bool EventsRefactorer::RemoveObjectInConditions(
} }
// Find object's name in text expressions // Find object's name in text expressions
else if (ParameterMetadata::IsExpression( else if (ParameterMetadata::IsExpression(
"string", instrInfos.parameters.GetParameter(pNb).GetType())) { "string", instrInfos.parameters[pNb].GetType())) {
auto node = conditions[cId].GetParameter(pNb).GetRootNode(); auto node = conditions[cId].GetParameter(pNb).GetRootNode();
if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) { if (ExpressionObjectFinder::CheckIfHasObject(platform, projectScopedContainers, "string", *node, name)) {
@@ -520,6 +588,31 @@ bool EventsRefactorer::RemoveObjectInConditions(
return somethingModified; return somethingModified;
} }
void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::EventsList& events,
gd::String name) {
for (std::size_t i = 0; i < events.size(); ++i) {
vector<gd::InstructionsList*> conditionsVectors =
events[i].GetAllConditionsVectors();
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
bool conditionsModified = RemoveObjectInConditions(
platform, projectScopedContainers, *conditionsVectors[j], name);
}
vector<gd::InstructionsList*> actionsVectors =
events[i].GetAllActionsVectors();
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
bool actionsModified = RemoveObjectInActions(
platform, projectScopedContainers, *actionsVectors[j], name);
}
if (events[i].CanHaveSubEvents())
RemoveObjectInEvents(
platform, projectScopedContainers, events[i].GetSubEvents(), name);
}
}
gd::String ReplaceAllOccurrencesCaseInsensitive(gd::String context, gd::String ReplaceAllOccurrencesCaseInsensitive(gd::String context,
const gd::String& from, const gd::String& from,
const gd::String& to) { const gd::String& to) {

View File

@@ -3,8 +3,8 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_EVENTSREFACTORER_H
#define GDCORE_EVENTSREFACTORER_H
#include <memory> #include <memory>
#include <vector> #include <vector>
@@ -81,12 +81,19 @@ class GD_CORE_API EventsRefactorer {
* events ). * events ).
*/ */
static void RenameObjectInEvents(const gd::Platform& platform, static void RenameObjectInEvents(const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::EventsList& events, gd::EventsList& events,
const gd::ObjectsContainer &targetedObjectsContainer,
gd::String oldName, gd::String oldName,
gd::String newName); gd::String newName);
/**
* Remove all actions or conditions using an object
*/
static void RemoveObjectInEvents(const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::EventsList& events,
gd::String name);
/** /**
* Search for a gd::String in events * Search for a gd::String in events
* *
@@ -122,13 +129,51 @@ class GD_CORE_API EventsRefactorer {
virtual ~EventsRefactorer(){}; virtual ~EventsRefactorer(){};
private: private:
/**
* Replace all occurrences of an object name by another name in an action
* ( include : objects in parameters and in math/text expressions ).
*
* \return true if something was modified.
*/
static bool RenameObjectInActions(const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& instructions,
gd::String oldName,
gd::String newName);
/**
* Replace all occurrences of an object name by another name in a condition
* ( include : objects in parameters and in math/text expressions ).
*
* \return true if something was modified.
*/
static bool RenameObjectInConditions(const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& instructions,
gd::String oldName,
gd::String newName);
/**
* Replace all occurrences of an object name by another name in an expression
* with the specified metadata
* ( include : objects or objects in math/text expressions ).
*
* \return true if something was modified.
*/
static bool RenameObjectInEventParameters(
const gd::Platform& platform,
gd::ProjectScopedContainers& projectScopedContainers,
gd::Expression& expression,
gd::ParameterMetadata parameterMetadata,
gd::String oldName,
gd::String newName);
/** /**
* Remove all conditions of the list using an object * Remove all conditions of the list using an object
* *
* \return true if something was modified. * \return true if something was modified.
*/ */
static bool RemoveObjectInConditions(const gd::Platform& platform, static bool RemoveObjectInConditions(const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& conditions, gd::InstructionsList& conditions,
gd::String name); gd::String name);
@@ -138,7 +183,7 @@ class GD_CORE_API EventsRefactorer {
* \return true if something was modified. * \return true if something was modified.
*/ */
static bool RemoveObjectInActions(const gd::Platform& platform, static bool RemoveObjectInActions(const gd::Platform& platform,
const gd::ProjectScopedContainers& projectScopedContainers, gd::ProjectScopedContainers& projectScopedContainers,
gd::InstructionsList& conditions, gd::InstructionsList& conditions,
gd::String name); gd::String name);
@@ -205,3 +250,5 @@ class GD_CORE_API EventsRefactorer {
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_EVENTSREFACTORER_H

View File

@@ -1,108 +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/EventsVariableInstructionTypeSwitcher.h"
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ParameterMetadata.h"
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableNameFinder.h"
#include "GDCore/IDE/VariableInstructionSwitcher.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
namespace gd {
VariablesContainer EventsVariableInstructionTypeSwitcher::nullVariablesContainer;
bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
const auto& metadata = isCondition
? gd::MetadataProvider::GetConditionMetadata(
platform, instruction.GetType())
: gd::MetadataProvider::GetActionMetadata(
platform, instruction.GetType());
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
instruction.GetParameters(),
metadata.GetParameters(),
[&](const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName) {
const gd::String& type = parameterMetadata.GetType();
if (!gd::ParameterMetadata::IsExpression("variable", type) ||
!gd::VariableInstructionSwitcher::IsSwitchableVariableInstruction(
instruction.GetType())) {
return;
}
const auto variableName =
gd::ExpressionVariableNameFinder::GetVariableName(
*parameterValue.GetRootNode());
const gd::VariablesContainer *variablesContainer = nullptr;
if (type == "objectvar") {
const auto &objectsContainersList =
GetProjectScopedContainers().GetObjectsContainersList();
if (objectsContainersList.HasObjectOrGroupWithVariableNamed(
lastObjectName, variableName) !=
gd::ObjectsContainersList::VariableExistence::DoesNotExist) {
variablesContainer =
GetProjectScopedContainers()
.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(lastObjectName);
}
} else if (type == "variableOrProperty") {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyName(variableName);
} else {
if (GetProjectScopedContainers().GetVariablesContainersList().Has(
variableName)) {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName);
}
}
// Every occurrence of the variable or its children are checked.
// Ensuring that a child is actually the one with a type change would
// take more time.
if (variablesContainer == &targetVariablesContainer ||
lastObjectName == groupName) {
if (typeChangedVariableNames.find(variableName) !=
typeChangedVariableNames.end()) {
gd::VariableInstructionSwitcher::
SwitchBetweenUnifiedInstructionIfNeeded(
platform, GetProjectScopedContainers(), instruction);
}
}
});
return false;
}
EventsVariableInstructionTypeSwitcher::~EventsVariableInstructionTypeSwitcher() {}
} // namespace gd

View File

@@ -1,68 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2024 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <map>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h"
namespace gd {
class VariablesContainer;
class Platform;
} // namespace gd
namespace gd {
/**
* \brief Switch the types of variable instructions for a given set of
* variables.
*
* \see gd::VariableInstructionSwitcher
*
* \ingroup IDE
*/
class GD_CORE_API EventsVariableInstructionTypeSwitcher
: public ArbitraryEventsWorkerWithContext {
public:
EventsVariableInstructionTypeSwitcher(
const gd::Platform &platform_,
const std::unordered_set<gd::String> &typeChangedVariableNames_,
const gd::VariablesContainer &targetVariablesContainer_)
: platform(platform_),
typeChangedVariableNames(typeChangedVariableNames_),
targetVariablesContainer(targetVariablesContainer_), groupName(""){};
EventsVariableInstructionTypeSwitcher(
const gd::Platform &platform_,
const std::unordered_set<gd::String> &typeChangedVariableNames_,
const gd::String &groupName_)
: platform(platform_),
typeChangedVariableNames(typeChangedVariableNames_),
targetVariablesContainer(nullVariablesContainer),
groupName(groupName_){};
virtual ~EventsVariableInstructionTypeSwitcher();
private:
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;
const gd::Platform &platform;
const gd::VariablesContainer &targetVariablesContainer;
/**
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be
* pointing to `nullVariablesContainer` and the group name is use instead to
* check which instruction to modify.
*/
const gd::String groupName;
const std::unordered_set<gd::String> &typeChangedVariableNames;
static VariablesContainer nullVariablesContainer;
};
} // namespace gd

View File

@@ -20,9 +20,6 @@
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h" #include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/IDE/Events/ExpressionValidator.h" #include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h" #include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableNameFinder.h"
#include "GDCore/IDE/VariableInstructionSwitcher.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Project/ProjectScopedContainers.h" #include "GDCore/Project/ProjectScopedContainers.h"
@@ -32,8 +29,6 @@
namespace gd { namespace gd {
VariablesContainer EventsVariableReplacer::nullVariablesContainer;
/** /**
* \brief Go through the nodes and rename variables, * \brief Go through the nodes and rename variables,
* or signal if the instruction must be renamed if a removed variable is used. * or signal if the instruction must be renamed if a removed variable is used.
@@ -46,26 +41,22 @@ class GD_CORE_API ExpressionVariableReplacer
ExpressionVariableReplacer( ExpressionVariableReplacer(
const gd::Platform& platform_, const gd::Platform& platform_,
const gd::ProjectScopedContainers& projectScopedContainers_, const gd::ProjectScopedContainers& projectScopedContainers_,
const VariablesRenamingChangesetNode& variablesRenamingChangesetRoot_,
const std::unordered_set<gd::String>& removedVariableNames_,
const gd::VariablesContainer& targetVariablesContainer_, const gd::VariablesContainer& targetVariablesContainer_,
const gd::String &groupName_, const std::unordered_map<gd::String, gd::String>& oldToNewVariableNames_,
const gd::String &forcedInitialObjectName) const std::unordered_set<gd::String>& removedVariableNames_)
: hasDoneRenaming(false), : hasDoneRenaming(false),
removedVariableUsed(false), removedVariableUsed(false),
platform(platform_), platform(platform_),
projectScopedContainers(projectScopedContainers_), projectScopedContainers(projectScopedContainers_),
forcedVariablesContainer(nullptr), forcedInitialVariablesContainer(nullptr),
forcedObjectName(forcedInitialObjectName),
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
removedVariableNames(removedVariableNames_),
targetVariablesContainer(targetVariablesContainer_), targetVariablesContainer(targetVariablesContainer_),
targetGroupName(groupName_){}; oldToNewVariableNames(oldToNewVariableNames_),
removedVariableNames(removedVariableNames_){};
virtual ~ExpressionVariableReplacer(){}; virtual ~ExpressionVariableReplacer(){};
void SetForcedInitialVariablesContainer( void SetForcedInitialVariablesContainer(
const gd::VariablesContainer* forcedInitialVariablesContainer_) { const gd::VariablesContainer* forcedInitialVariablesContainer_) {
forcedVariablesContainer = forcedInitialVariablesContainer_; forcedInitialVariablesContainer = forcedInitialVariablesContainer_;
} }
bool HasDoneRenaming() const { return hasDoneRenaming; } bool HasDoneRenaming() const { return hasDoneRenaming; }
@@ -88,30 +79,21 @@ class GD_CORE_API ExpressionVariableReplacer
// The node represents a variable or an object name on which a variable // The node represents a variable or an object name on which a variable
// will be accessed. // will be accessed.
if (forcedVariablesContainer) { if (forcedInitialVariablesContainer) {
const gd::String oldVariableName = node.name;
PushVariablesRenamingChangesetRoot();
// A scope was forced. Honor it: it means this node represents a variable // A scope was forced. Honor it: it means this node represents a variable
// of the forced variables container. // of the forced variables container.
if (forcedVariablesContainer == &targetVariablesContainer || if (forcedInitialVariablesContainer == &targetVariablesContainer) {
IsTargetingObjectGroup(forcedObjectName)) {
RenameOrRemoveVariableOfTargetVariableContainer(node.name); RenameOrRemoveVariableOfTargetVariableContainer(node.name);
} }
if (node.child) { if (node.child) node.child->Visit(*this);
bool hasBeenPushed =
PushVariablesRenamingChangesetNodeForVariable(oldVariableName);
node.child->Visit(*this);
PopVariablesRenamingChangesetNode(hasBeenPushed);
}
PopVariablesRenamingChangesetNode(true);
return; return;
} }
// Match the potential *new* name of the variable, because refactorings are // Match the potential *new* name of the variable, because refactorings are
// done after changes in the variables container. // done after changes in the variables container.
projectScopedContainers.MatchIdentifierWithName<void>( projectScopedContainers.MatchIdentifierWithName<void>(
node.name, GetPotentialNewName(node.name),
[&]() { [&]() {
// This represents an object. // This represents an object.
// Remember the object name. // Remember the object name.
@@ -121,21 +103,14 @@ class GD_CORE_API ExpressionVariableReplacer
}, },
[&]() { [&]() {
// This is a variable. // This is a variable.
if (&projectScopedContainers.GetVariablesContainersList() if (projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(node.name) == .HasVariablesContainer(targetVariablesContainer)) {
&targetVariablesContainer) {
// The node represents a variable, that can come from the target // The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it: // (because the target is in the scope), replace or remove it:
PushVariablesRenamingChangesetRoot(); RenameOrRemoveVariableOfTargetVariableContainer(node.name);
RenameVariableAndVisitChild(node.name, node.child.get());
PopVariablesRenamingChangesetNode(true);
} else {
if (node.child) {
PushVariablesRenamingChangesetNodeForIgnoredVariables();
node.child->Visit(*this);
PopVariablesRenamingChangesetNode(true);
}
} }
if (node.child) node.child->Visit(*this);
}, },
[&]() { [&]() {
// This is a property. // This is a property.
@@ -146,7 +121,14 @@ class GD_CORE_API ExpressionVariableReplacer
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
}, },
[&]() { [&]() {
// This is something else. // This is something else - potentially a deleted variable.
if (projectScopedContainers.GetVariablesContainersList()
.HasVariablesContainer(targetVariablesContainer)) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:
RenameOrRemoveVariableOfTargetVariableContainer(node.name);
}
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
}); });
} }
@@ -154,50 +136,25 @@ class GD_CORE_API ExpressionVariableReplacer
auto& objectsContainersList = auto& objectsContainersList =
projectScopedContainers.GetObjectsContainersList(); projectScopedContainers.GetObjectsContainersList();
if (!objectNameToUseForVariableAccessor.empty()) { if (!objectNameToUseForVariableAccessor.empty()) {
// This is always true because MatchIdentifierWithName is used to get
// objectNameToUseForVariableAccessor.
if (objectsContainersList.HasObjectOrGroupVariablesContainer( if (objectsContainersList.HasObjectOrGroupVariablesContainer(
objectNameToUseForVariableAccessor, targetVariablesContainer) || objectNameToUseForVariableAccessor, targetVariablesContainer)) {
IsTargetingObjectGroup(objectNameToUseForVariableAccessor)) {
objectNameToUseForVariableAccessor = "";
// The node represents an object variable, and this object variables are // The node represents an object variable, and this object variables are
// the target. Do the replacement or removals: // the target. Do the replacement or removals:
PushVariablesRenamingChangesetRoot(); RenameOrRemoveVariableOfTargetVariableContainer(node.name);
RenameVariableAndVisitChild(node.name, node.child.get());
PopVariablesRenamingChangesetNode(true);
} }
} else {
RenameVariableAndVisitChild(node.name, node.child.get());
} }
objectNameToUseForVariableAccessor = "";
if (node.child) node.child->Visit(*this);
} }
void OnVisitVariableBracketAccessorNode( void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) override { VariableBracketAccessorNode& node) override {
objectNameToUseForVariableAccessor = ""; objectNameToUseForVariableAccessor = "";
// TODO Literal expressions could be checked to handle renaming in
// `expression` and in `child`.
node.expression->Visit(*this); node.expression->Visit(*this);
if (node.child) { if (node.child) node.child->Visit(*this);
PushVariablesRenamingChangesetNodeForIgnoredVariables();
node.child->Visit(*this);
PopVariablesRenamingChangesetNode(true);
}
} }
void OnVisitIdentifierNode(IdentifierNode &node) override { void OnVisitIdentifierNode(IdentifierNode& node) override {
auto renameVariableAndChild = [this, &node]() {
PushVariablesRenamingChangesetRoot();
const gd::String oldVariableName = node.identifierName;
RenameOrRemoveVariableOfTargetVariableContainer(node.identifierName);
if (!node.childIdentifierName.empty()) {
bool hasBeenPushed =
PushVariablesRenamingChangesetNodeForVariable(oldVariableName);
RenameOrRemoveVariableOfTargetVariableContainer(
node.childIdentifierName);
PopVariablesRenamingChangesetNode(hasBeenPushed);
}
PopVariablesRenamingChangesetNode(true);
};
auto& objectsContainersList = auto& objectsContainersList =
projectScopedContainers.GetObjectsContainersList(); projectScopedContainers.GetObjectsContainersList();
@@ -205,12 +162,11 @@ class GD_CORE_API ExpressionVariableReplacer
// (and if it's a variable reference or a value does not have any importance // (and if it's a variable reference or a value does not have any importance
// here). // here).
if (forcedVariablesContainer) { if (forcedInitialVariablesContainer) {
// A scope was forced. Honor it: it means this node represents a variable // A scope was forced. Honor it: it means this node represents a variable
// of the forced variables container. // of the forced variables container.
if (forcedVariablesContainer == &targetVariablesContainer || if (forcedInitialVariablesContainer == &targetVariablesContainer) {
IsTargetingObjectGroup(forcedObjectName)) { RenameOrRemoveVariableOfTargetVariableContainer(node.identifierName);
renameVariableAndChild();
} }
return; return;
} }
@@ -218,28 +174,25 @@ class GD_CORE_API ExpressionVariableReplacer
// Match the potential *new* name of the variable, because refactorings are // Match the potential *new* name of the variable, because refactorings are
// done after changes in the variables container. // done after changes in the variables container.
projectScopedContainers.MatchIdentifierWithName<void>( projectScopedContainers.MatchIdentifierWithName<void>(
node.identifierName, GetPotentialNewName(node.identifierName),
[&]() { [&]() {
// This represents an object. // This represents an object.
if (objectsContainersList.HasObjectOrGroupVariablesContainer( if (objectsContainersList.HasObjectOrGroupVariablesContainer(
node.identifierName, targetVariablesContainer) || node.identifierName, targetVariablesContainer)) {
IsTargetingObjectGroup(node.identifierName)) {
// The node represents an object variable, and this object variables // The node represents an object variable, and this object variables
// are the target. Do the replacement or removals: // are the target. Do the replacement or removals:
PushVariablesRenamingChangesetRoot();
RenameOrRemoveVariableOfTargetVariableContainer( RenameOrRemoveVariableOfTargetVariableContainer(
node.childIdentifierName); node.childIdentifierName);
PopVariablesRenamingChangesetNode(true);
} }
}, },
[&]() { [&]() {
// This is a variable. // This is a variable.
if (&projectScopedContainers.GetVariablesContainersList() if (projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName( .HasVariablesContainer(targetVariablesContainer)) {
node.identifierName) == &targetVariablesContainer) {
// The node represents a variable, that can come from the target // The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it: // (because the target is in the scope), replace or remove it:
renameVariableAndChild(); RenameOrRemoveVariableOfTargetVariableContainer(
node.identifierName);
} }
}, },
[&]() { [&]() {
@@ -249,7 +202,14 @@ class GD_CORE_API ExpressionVariableReplacer
// This is a parameter. // This is a parameter.
}, },
[&]() { [&]() {
// This is something else. // This is something else - potentially a deleted variable.
if (projectScopedContainers.GetVariablesContainersList()
.HasVariablesContainer(targetVariablesContainer)) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:
RenameOrRemoveVariableOfTargetVariableContainer(
node.identifierName);
}
}); });
} }
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {} void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {}
@@ -271,33 +231,31 @@ class GD_CORE_API ExpressionVariableReplacer
// force the "scope" at which starts the evalution of variables. // force the "scope" at which starts the evalution of variables.
if (parameterMetadata && parameterMetadata->GetValueTypeMetadata() if (parameterMetadata && parameterMetadata->GetValueTypeMetadata()
.IsLegacyPreScopedVariable()) { .IsLegacyPreScopedVariable()) {
const gd::VariablesContainer *oldForcedVariablesContainer = const gd::VariablesContainer* oldForcedInitialVariablesContainer =
forcedVariablesContainer; forcedInitialVariablesContainer;
const gd::String &oldForcedObjectName = forcedObjectName;
forcedVariablesContainer = nullptr; forcedInitialVariablesContainer = nullptr;
forcedObjectName = "";
if (parameterMetadata->GetType() == "globalvar") { if (parameterMetadata->GetType() == "globalvar") {
forcedVariablesContainer = forcedInitialVariablesContainer =
projectScopedContainers.GetVariablesContainersList() projectScopedContainers.GetVariablesContainersList()
.GetTopMostVariablesContainer(); .GetTopMostVariablesContainer();
} else if (parameterMetadata->GetType() == "scenevar") { } else if (parameterMetadata->GetType() == "scenevar") {
forcedVariablesContainer = forcedInitialVariablesContainer =
projectScopedContainers.GetVariablesContainersList() projectScopedContainers.GetVariablesContainersList()
.GetBottomMostVariablesContainer(); .GetBottomMostVariablesContainer();
} else if (parameterMetadata->GetType() == "objectvar") { } else if (parameterMetadata->GetType() == "objectvar") {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName( auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
platform, projectScopedContainers.GetObjectsContainersList(), platform,
node.objectName, *node.parameters[parameterIndex].get()); projectScopedContainers.GetObjectsContainersList(),
forcedVariablesContainer = node.objectName,
*node.parameters[parameterIndex].get());
forcedInitialVariablesContainer =
projectScopedContainers.GetObjectsContainersList() projectScopedContainers.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(objectName); .GetObjectOrGroupVariablesContainer(objectName);
forcedObjectName = objectName;
} }
node.parameters[parameterIndex]->Visit(*this); node.parameters[parameterIndex]->Visit(*this);
forcedVariablesContainer = oldForcedVariablesContainer; forcedInitialVariablesContainer = oldForcedInitialVariablesContainer;
forcedObjectName = oldForcedObjectName;
} else { } else {
// For any other parameter, there is no special treatment being needed. // For any other parameter, there is no special treatment being needed.
node.parameters[parameterIndex]->Visit(*this); node.parameters[parameterIndex]->Visit(*this);
@@ -310,28 +268,19 @@ class GD_CORE_API ExpressionVariableReplacer
bool hasDoneRenaming; bool hasDoneRenaming;
bool removedVariableUsed; bool removedVariableUsed;
bool IsTargetingObjectGroup(const gd::String &objectGroupName) { const gd::String& GetPotentialNewName(const gd::String& oldName) {
return !targetGroupName.empty() && objectGroupName == targetGroupName; return oldToNewVariableNames.count(oldName) >= 1
? oldToNewVariableNames.find(oldName)->second
: oldName;
} }
bool RenameOrRemoveVariableOfTargetVariableContainer( bool RenameOrRemoveVariableOfTargetVariableContainer(
gd::String& variableName) { gd::String& variableName) {
const auto *currentVariablesRenamingChangesetNode =
GetCurrentVariablesRenamingChangesetNode();
if (!currentVariablesRenamingChangesetNode) {
return false;
}
const auto &oldToNewVariableNames =
currentVariablesRenamingChangesetNode->oldToNewVariableNames;
if (oldToNewVariableNames.count(variableName) >= 1) { if (oldToNewVariableNames.count(variableName) >= 1) {
variableName = oldToNewVariableNames.find(variableName)->second; variableName = oldToNewVariableNames.find(variableName)->second;
hasDoneRenaming = true; hasDoneRenaming = true;
return true; return true;
} else if ( } else if (removedVariableNames.count(variableName) >= 1) {
// Only the root variable is checked for removing.
currentVariablesRenamingChangesetNode ==
&variablesRenamingChangesetRoot &&
removedVariableNames.count(variableName) >= 1) {
removedVariableUsed = true; removedVariableUsed = true;
return true; return true;
} }
@@ -339,88 +288,24 @@ class GD_CORE_API ExpressionVariableReplacer
return false; // Nothing was changed or done. return false; // Nothing was changed or done.
} }
void RenameVariableAndVisitChild(gd::String &variableName,
ExpressionNode *childNode) {
// `variableName` is modified by
// `RenameOrRemoveVariableOfTargetVariableContainer`.
const gd::String oldVariableName = variableName;
RenameOrRemoveVariableOfTargetVariableContainer(variableName);
if (childNode) {
bool hasBeenPushed =
PushVariablesRenamingChangesetNodeForVariable(oldVariableName);
childNode->Visit(*this);
PopVariablesRenamingChangesetNode(hasBeenPushed);
}
}
void PushVariablesRenamingChangesetRoot() {
variablesRenamingChangesetNodeStack.push_back(&variablesRenamingChangesetRoot);
}
void PushVariablesRenamingChangesetNodeForIgnoredVariables() {
variablesRenamingChangesetNodeStack.push_back(nullptr);
}
const gd::VariablesRenamingChangesetNode *GetCurrentVariablesRenamingChangesetNode() {
return variablesRenamingChangesetNodeStack.size() == 0 ?
&variablesRenamingChangesetRoot :
variablesRenamingChangesetNodeStack
[variablesRenamingChangesetNodeStack.size() - 1];
}
bool PushVariablesRenamingChangesetNodeForVariable(const gd::String& variableName) {
const auto *currentVariablesRenamingChangesetNode = GetCurrentVariablesRenamingChangesetNode();
if (!currentVariablesRenamingChangesetNode) {
// There were already no more change on a parent.
return false;
}
const auto &childVariablesRenamingChangesetNodeItr =
currentVariablesRenamingChangesetNode->modifiedVariables.find(
variableName);
if (childVariablesRenamingChangesetNodeItr ==
currentVariablesRenamingChangesetNode->modifiedVariables.end()) {
// There is no more change on the current variable child.
variablesRenamingChangesetNodeStack.push_back(nullptr);
}
else {
variablesRenamingChangesetNodeStack.push_back(
childVariablesRenamingChangesetNodeItr->second.get());
}
return true;
}
void PopVariablesRenamingChangesetNode(bool hasBeenPushed) {
if (hasBeenPushed) {
variablesRenamingChangesetNodeStack.pop_back();
}
}
// Scope: // Scope:
const gd::Platform& platform; const gd::Platform& platform;
const gd::ProjectScopedContainers& projectScopedContainers; const gd::ProjectScopedContainers& projectScopedContainers;
const gd::VariablesContainer* forcedVariablesContainer; const gd::VariablesContainer* forcedInitialVariablesContainer;
gd::String forcedObjectName;
// Renaming or removing to do: // Renaming or removing to do:
const gd::VariablesContainer& targetVariablesContainer; const gd::VariablesContainer& targetVariablesContainer;
/** const std::unordered_map<gd::String, gd::String>& oldToNewVariableNames;
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be
* pointing to `nullVariablesContainer` and the group name is use instead to
* check which variable accesses to modify in expressions.
*/
const gd::String& targetGroupName;
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot;
const std::unordered_set<gd::String>& removedVariableNames; const std::unordered_set<gd::String>& removedVariableNames;
gd::String objectNameToUseForVariableAccessor; gd::String objectNameToUseForVariableAccessor;
std::vector<const VariablesRenamingChangesetNode*> variablesRenamingChangesetNodeStack;
}; };
const gd::VariablesContainer* const gd::VariablesContainer*
EventsVariableReplacer::FindForcedVariablesContainerIfAny( EventsVariableReplacer::FindForcedVariablesContainerIfAny(
const gd::String& type, const gd::String& lastObjectName) { const gd::String& type, const gd::String& lastObjectName) {
// Handle legacy pre-scoped variable parameters: in this case, we // Handle legacy pre-scoped variable parameters: in this case, we
// force the "scope" at which starts the evaluation of variables. // force the "scope" at which starts the evalution of variables.
if (type == "objectvar") { if (type == "objectvar") {
return GetProjectScopedContainers() return GetProjectScopedContainers()
.GetObjectsContainersList() .GetObjectsContainersList()
@@ -465,11 +350,9 @@ bool EventsVariableReplacer::DoVisitInstruction(gd::Instruction& instruction,
if (node) { if (node) {
ExpressionVariableReplacer renamer(platform, ExpressionVariableReplacer renamer(platform,
GetProjectScopedContainers(), GetProjectScopedContainers(),
variablesRenamingChangesetRoot,
removedVariableNames,
targetVariablesContainer, targetVariablesContainer,
targetGroupName, oldToNewVariableNames,
type == "objectvar" ? lastObjectName : ""); removedVariableNames);
renamer.SetForcedInitialVariablesContainer( renamer.SetForcedInitialVariablesContainer(
FindForcedVariablesContainerIfAny(type, lastObjectName)); FindForcedVariablesContainerIfAny(type, lastObjectName));
node->Visit(renamer); node->Visit(renamer);
@@ -499,11 +382,9 @@ bool EventsVariableReplacer::DoVisitEventExpression(
if (node) { if (node) {
ExpressionVariableReplacer renamer(platform, ExpressionVariableReplacer renamer(platform,
GetProjectScopedContainers(), GetProjectScopedContainers(),
variablesRenamingChangesetRoot,
removedVariableNames,
targetVariablesContainer, targetVariablesContainer,
targetGroupName, oldToNewVariableNames,
""); removedVariableNames);
renamer.SetForcedInitialVariablesContainer( renamer.SetForcedInitialVariablesContainer(
FindForcedVariablesContainerIfAny(type, "")); FindForcedVariablesContainerIfAny(type, ""));
node->Visit(renamer); node->Visit(renamer);

View File

@@ -4,7 +4,6 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #pragma once
#include <map> #include <map>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
@@ -13,13 +12,11 @@
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h" #include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/String.h" #include "GDCore/String.h"
namespace gd { namespace gd {
class BaseEvent; class BaseEvent;
class VariablesContainer; class VariablesContainer;
class EventsList; class EventsList;
class Platform; class Platform;
struct VariablesRenamingChangesetNode;
} // namespace gd } // namespace gd
namespace gd { namespace gd {
@@ -35,24 +32,13 @@ class GD_CORE_API EventsVariableReplacer
public: public:
EventsVariableReplacer( EventsVariableReplacer(
const gd::Platform &platform_, const gd::Platform &platform_,
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot_, const gd::VariablesContainer &targetVariablesContainer_,
const std::unordered_set<gd::String> &removedVariableNames_, const std::unordered_map<gd::String, gd::String> &oldToNewVariableNames_,
const gd::VariablesContainer &targetVariablesContainer_) const std::unordered_set<gd::String> &removedVariableNames_)
: platform(platform_), : platform(platform_),
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
removedVariableNames(removedVariableNames_),
targetVariablesContainer(targetVariablesContainer_), targetVariablesContainer(targetVariablesContainer_),
targetGroupName("") {}; oldToNewVariableNames(oldToNewVariableNames_),
EventsVariableReplacer( removedVariableNames(removedVariableNames_){};
const gd::Platform &platform_,
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot_,
const std::unordered_set<gd::String> &removedVariableNames_,
const gd::String &targetGroupName_)
: platform(platform_),
variablesRenamingChangesetRoot(variablesRenamingChangesetRoot_),
removedVariableNames(removedVariableNames_),
targetVariablesContainer(nullVariablesContainer),
targetGroupName(targetGroupName_) {};
virtual ~EventsVariableReplacer(); virtual ~EventsVariableReplacer();
private: private:
@@ -66,17 +52,9 @@ class GD_CORE_API EventsVariableReplacer
const gd::Platform &platform; const gd::Platform &platform;
const gd::VariablesContainer &targetVariablesContainer; const gd::VariablesContainer &targetVariablesContainer;
/** gd::String objectName;
* Groups don't have VariablesContainer, so `targetVariablesContainer` will be const std::unordered_map<gd::String, gd::String> &oldToNewVariableNames;
* pointing to `nullVariablesContainer` and the group name is use instead to
* check which variable accesses to modify in expressions.
*/
const gd::String targetGroupName;
const VariablesRenamingChangesetNode &variablesRenamingChangesetRoot;
// TODO There is no reason de delete events. This dead code should be removed.
const std::unordered_set<gd::String> &removedVariableNames; const std::unordered_set<gd::String> &removedVariableNames;
static VariablesContainer nullVariablesContainer;
}; };
} // namespace gd } // namespace gd

Some files were not shown because too many files have changed in this diff Show More