Compare commits

..

1 Commits

Author SHA1 Message Date
Clément Pasteau
a21c369ab0 Remove unused translations 2024-02-07 14:19:42 +01:00
2376 changed files with 77855 additions and 236607 deletions

View File

@@ -11,25 +11,13 @@
version: 2.1
orbs:
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)
win: circleci/windows@5.1.0
jobs:
# Build the **entire** app for macOS (including the GDevelop.js library).
# Build the **entire** app for macOS.
build-macos:
macos:
xcode: 16.4.0
resource_class: m4pro.medium
xcode: 14.2.0
steps:
- 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)
- run:
@@ -47,9 +35,9 @@ jobs:
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
- gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# fallback to using the latest cache if no exact match is found
- gd-macos-nodejs-dependencies-
- gd-macos-nodejs-dependencies---
- run:
name: Install GDevelop.js dependencies
@@ -70,8 +58,7 @@ jobs:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
- GDJS/node_modules
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
key: gd-macos-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
@@ -88,37 +75,15 @@ jobs:
- store_artifacts:
path: newIDE/electron-app/dist
# Upload artifacts (AWS)
- run:
name: Deploy to S3 (specific commit)
command: |
export PATH=~/.local/bin:$PATH
for i in 1 2 3 4 5 6 7; do
aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/ && break
echo "Retry $i failed... retrying in 10 seconds"
sleep 10
done
if [ $i -eq 7 ]; then
echo "All retries for deployment failed!" >&2
exit 1
fi
command: export PATH=~/.local/bin:$PATH && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/
- run:
name: Deploy to S3 (latest)
command: |
export PATH=~/.local/bin:$PATH
for i in 1 2 3 4 5 6 7; do
aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/ && break
echo "Retry $i failed... retrying in 10 seconds"
sleep 10
done
if [ $i -eq 7 ]; then
echo "All retries for deployment failed!" >&2
exit 1
fi
command: export PATH=~/.local/bin:$PATH && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
# Build the app for Linux (using a pre-built GDevelop.js library).
# Build the **entire** app for Linux.
build-linux:
# CircleCI docker workers are failing if they don't have enough memory (no swap)
resource_class: xlarge
@@ -131,33 +96,51 @@ jobs:
- checkout
- aws-cli/setup
# System dependencies (for Electron Builder)
# System dependencies (for Electron Builder and Emscripten)
- run:
name: Update system dependencies
command: sudo apt-get update
name: Install dependencies for Emscripten
command: sudo apt-get update && sudo apt install cmake
- 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 ..
- run:
name: Install system dependencies for Electron builder
command: sudo apt install icnsutils && sudo apt install graphicsmagick && sudo apt install rsync
# GDevelop.js dependencies
- restore_cache:
keys:
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
- gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# fallback to using the latest cache if no exact match is found
- gd-linux-nodejs-dependencies-
- gd-linux-nodejs-dependencies---
# GDevelop IDE dependencies (using an exact version of GDevelop.js, built previously)
- run:
name: Install GDevelop.js dependencies and build it
command: cd GDevelop.js && npm install && cd ..
# Build GDevelop.js (and run tests to ensure it works)
- run:
name: Build GDevelop.js
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number).
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
- run:
name: Install GDevelop IDE dependencies
command: export REQUIRES_EXACT_LIBGD_JS_VERSION=true && cd newIDE/app && npm install && cd ../electron-app && npm install
command: cd newIDE/app && npm install && cd ../electron-app && npm install
- save_cache:
paths:
- newIDE/electron-app/node_modules
- newIDE/app/node_modules
- GDevelop.js/node_modules
- GDJS/node_modules
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}-{{ checksum "GDJS/package-lock.json" }}
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
@@ -182,7 +165,6 @@ jobs:
# Build the WebAssembly library only (so that it's cached on a S3 and easy to re-use).
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:
- image: cimg/node:16.13
@@ -239,302 +221,17 @@ jobs:
name: Deploy to S3 (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)/
# Trigger AppVeyor build, which also does a Windows build (keep it for redundancy).
trigger-appveyor-windows-build:
docker:
- image: cimg/node:16.13
steps:
- run:
name: Trigger AppVeyor Windows build
command: |
curl -H "Content-Type: application/json" \
-H "Authorization: Bearer ${APPVEYOR_API_KEY}" \
--data "{
\"accountName\": \"4ian\",
\"projectSlug\": \"gdevelop\",
\"branch\": \"${CIRCLE_BRANCH}\"
}" \
-X POST https://ci.appveyor.com/api/builds
build-windows:
executor:
name: win/default
size: medium
working_directory: /home/circleci/project
steps:
- checkout
- run:
# See https://www.ssl.com/how-to/how-to-integrate-esigner-cka-with-ci-cd-tools-for-automated-code-signing/
#
# This is necessary because of "signing to be FIPS-140 compliant". See
# https://github.com/electron-userland/electron-builder/issues/6158
#
# Make sure to DISABLE "malware blocker" in SSL.com to avoid errors like:
# Error information: "Error: SignerSign() failed." (-2146893821/0x80090003)
name: Download and Unzip eSignerCKA Setup
command: |
Invoke-WebRequest -OutFile eSigner_CKA_1.0.3.zip "https://www.ssl.com/download/ssl-com-esigner-cka-1-0-3"
Expand-Archive -Force eSigner_CKA_1.0.3.zip
Remove-Item eSigner_CKA_1.0.3.zip
Move-Item -Destination "eSigner_CKA_1.0.3.exe" -Path "eSigner_CKA_*\*.exe"
- run:
name: Setup eSignerCKA in Silent Mode
command: |
mkdir -p "/home/circleci/project/eSignerCKA"
./eSigner_CKA_1.0.3.exe /CURRENTUSER /VERYSILENT /SUPPRESSMSGBOXES /DIR="/home/circleci/project/eSignerCKA" | Out-Null
- run:
name: Config Account Information on eSignerCKA
command: |
/home/circleci/project/eSignerCKA/eSignerCKATool.exe config -mode product -user "$env:ESIGNER_USER_NAME" -pass "$env:ESIGNER_USER_PASSWORD" -totp "$env:ESIGNER_USER_TOTP" -key "/home/circleci/project/eSignerCKA/master.key" -r
- run:
name: Load Certificate into Windows Store
command: |
/home/circleci/project/eSignerCKA/eSignerCKATool.exe unload
/home/circleci/project/eSignerCKA/eSignerCKATool.exe load
- run:
name: Select Certificate From Windows Store and Sign Sample File with SignTool
command: |
$CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
echo Certificate: $CodeSigningCert
- restore_cache:
name: Restore node_modules cache
keys:
- v1-win-node-{{ checksum "newIDE/app/package-lock.json" }}-{{ checksum "newIDE/electron-app/package-lock.json" }}-{{ checksum "GDJS/package-lock.json" }}
- v1-win-node-
- run:
name: Install dependencies
no_output_timeout: 25m
# Remove package-lock.json because they seems to cause the npm install to be stuck. We should try again after re-generating them.
# Also install setuptools as something requires distutils in electron-app, and it was removed in Python 3.12.
# setuptools will make distutils available again (but we should migrate our packages probably).
command: |
pip install setuptools
cd newIDE\app
npm -v
Remove-Item package-lock.json
$Env:REQUIRES_EXACT_LIBGD_JS_VERSION = "true"
npm install
cd ..\electron-app
Remove-Item package-lock.json
npm install
cd ..\..
- save_cache:
name: Save node_modules cache
key: v1-win-node-{{ checksum "newIDE/app/package-lock.json" }}-{{ checksum "newIDE/electron-app/package-lock.json" }}-{{ checksum "GDJS/package-lock.json" }}
paths:
- newIDE/app/node_modules
- newIDE/electron-app/node_modules
- GDJS/node_modules
- run:
name: Build NSIS executable (with code signing)
command: |
cd newIDE\electron-app
$CodeSigningCert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
echo Certificate: $CodeSigningCert
# Use a custom signtool path because of the signtool.exe bundled withy electron-builder not working for some reason.
# Can also be found in versioned folders like "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22000.0/x86/signtool.exe".
# or "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe".
$Env:SIGNTOOL_PATH = "C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe"
# Extract thumbprint and subject name of the certificate (will be passed to electron-builder).
$Env:GD_SIGNTOOL_THUMBPRINT = $CodeSigningCert.Thumbprint
$Env:GD_SIGNTOOL_SUBJECT_NAME = ($CodeSigningCert.Subject -replace ", ?", "`n" | ConvertFrom-StringData).CN
# Build the nsis installer (signed: electron-builder will use SignTool.exe with the certificate)
node scripts/build.js --win nsis --publish=never
cd ..\..
- run:
name: Build AppX (without code signing)
# Don't sign the appx (it will be signed by the Microsoft Store).
command: |
cd newIDE\electron-app
# Build the appx (not signed). Ensure all variables used for code signing are empty.
$Env:GD_SIGNTOOL_THUMBPRINT = ''
$Env:GD_SIGNTOOL_SUBJECT_NAME = ''
$Env:CSC_LINK = ''
$Env:CSC_KEY_PASSWORD = ''
node scripts/build.js --skip-app-build --win appx --publish=never
cd ..\..
- run:
name: Clean binaries
shell: cmd.exe
command: |
rmdir /s /q newIDE\electron-app\dist\win-unpacked
- run:
name: Install AWS CLI
command: |
# Install the CLI for the current user
pip install --quiet --upgrade --user awscli
# Add the user-Scripts dir to PATH for this step and the next.
$binDir = (python -m site --user-base) + "\Scripts"
$Env:Path += ";$binDir"
# Sanity check:
aws --version
# Upload artifacts (S3)
- run:
name: Deploy to S3 (specific commit)
command: |
aws s3 sync newIDE\electron-app\dist "s3://gdevelop-releases/$Env:CIRCLE_BRANCH/commit/$Env:CIRCLE_SHA1/"
- run:
name: Deploy to S3 (latest)
command: |
aws s3 sync newIDE\electron-app\dist "s3://gdevelop-releases/$Env:CIRCLE_BRANCH/latest/"
# Upload artifacts (CircleCI)
- store_artifacts:
path: newIDE/electron-app/dist
workflows:
gdevelop_js-wasm-extra-checks:
jobs:
- build-gdevelop_js-debug-sanitizers-and-extra-checks:
# Extra checks are resource intensive so don't always run them.
filters:
branches:
only:
- master
- /experimental-build.*/
builds:
jobs:
- build-gdevelop_js-wasm-only
- build-macos:
# The macOS version builds by itself GDevelop.js
# (so we verify we can build it on macOS).
# requires:
# - build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- build-linux:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- build-windows:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:
- master
- /experimental-build.*/
- trigger-appveyor-windows-build:
requires:
- build-gdevelop_js-wasm-only
filters:
branches:
only:

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/TinyXml/* linguist-vendored
Extensions/ParticleSystem/SPARK/* linguist-vendored
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
Extensions/PhysicsBehavior/box2djs/* linguist-vendored
Extensions/Physics2Behavior/box2d.js linguist-vendored
Extensions/Physics3DBehavior/*.wasm-compat.js linguist-vendored
Extensions/BBText/pixi-multistyle-text/* linguist-vendored
Extensions/P2P/A_peer.js linguist-vendored
Extensions/Multiplayer/peer.js linguist-vendored
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
Extensions/TileMap/pako/* linguist-vendored
Extensions/TileMap/pixi-tilemap/* linguist-vendored
Extensions/TweenBehavior/shifty.js linguist-vendored

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

@@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
node-version: 16
cache: "npm"
cache-dependency-path: "newIDE/app/package-lock.json"
@@ -58,7 +58,7 @@ jobs:
working-directory: newIDE/app
- name: Create a Pull Request with the changes
uses: peter-evans/create-pull-request@v6
uses: peter-evans/create-pull-request@v5
with:
commit-message: Update translations [skip ci]
branch: chore/update-translations

View File

@@ -56,7 +56,6 @@ blocks:
- name: GDJS typing and documentation generation
commands:
- checkout
- cache restore newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json)
- cache restore GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json)
- cache restore GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json)
- cd GDJS

View File

@@ -17,11 +17,11 @@ cache:
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- ubuntu-toolchain-r-test
packages:
# Build dependencies:
- cmake
- p7zip-full
# Build dependencies:
- cmake
- p7zip-full
before_install:
# 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
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
#Compile the tests only for GDCore
#Compile the tests only for GDCore
- mkdir .build-tests
- cd .build-tests
- cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) ..
- make -j 4
- cd ..
# Install Emscripten (for GDevelop.js)
# Specify the tag for the core repository to avois breaking changes.
- git clone --depth 1 --branch 3.1.21 https://github.com/juj/emsdk.git
# Install Emscripten (for GDevelop.js)
- git clone https://github.com/juj/emsdk.git
- 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 ..
# Build GDevelop.js
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
# Build GDevelop.js
# (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 ..)
# Install newIDE tests dependencies
# Install newIDE tests dependencies
- npm -v
- cd newIDE/app && npm install
- cd ../..
# Install GDJS tests dependencies
# Install GDJS tests dependencies
- cd GDJS && npm install && cd tests && npm install
- cd ../..
script:
# GDCore tests:
# GDCore tests:
- cd .build-tests
- Core/GDCore_tests
- cd ..
# GDevelop.js tests
# GDevelop.js tests
- cd GDevelop.js
- npm test
- cd ..
# newIDE tests:
# newIDE tests:
- cd newIDE/app
- npm test
- npm run flow
- npm run check-format
- npm run check-script-types
- cd ../..
# GDJS tests:
# GDJS tests:
- cd GDJS
- npm run check-format
- cd ..

View File

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

View File

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

1
.vscode/tasks.json vendored
View File

@@ -8,7 +8,6 @@
"group": "build",
"label": "Start development server",
"detail": "Starts the GDevelop development server.",
"options": { "env": { "NODE_OPTIONS": "--max-old-space-size=8192" } },
"problemMatcher": [
{
"owner": "cra",

View File

@@ -1,130 +0,0 @@
# AI Project Restore Implementation
## Overview
This implementation provides automatic project saving and restoration capabilities for AI agent requests, leveraging GDevelop's existing cloud save features and version history system.
## Key Features
### 1. Automatic Project Save Before AI Agent Requests
- When a user starts a new AI agent request, the project is automatically saved to create a cloud version
- This only works for cloud projects (projects saved to GDevelop Cloud)
- The current version ID is captured and stored with the AI request
### 2. Version-Based Restoration
- Uses GDevelop's existing cloud version system instead of custom serialization
- Leverages the `onOpenCloudProjectOnSpecificVersion` function from MainFrame
- Provides seamless restoration to the exact state before AI agent modifications
### 3. Smart UI Integration
- Restore button appears at the top of AI agent chats that have a stored initial version
- Only visible for cloud projects with stored version information
- Button shows loading state during restoration process
## Implementation Details
### Backend API Changes
- Extended `AiRequest` type to include `initialProjectVersionId?: string | null`
- This field stores the cloud project version ID captured before starting the agent
### Frontend Changes
#### 1. AskAiEditorContainer.js
- Added `onOpenCloudProjectOnSpecificVersion` prop to enable version restoration
- Modified AI request creation to save project and capture version ID for cloud projects
- Added `onRestoreInitialProject` callback that uses cloud version system
- Only attempts version capture for cloud projects (`storageProvider.internalName === 'Cloud'`)
#### 2. AiRequestChat/index.js
- Added restore button UI at the top of agent chats
- Added `isCloudProject` prop to control button visibility
- Added loading state for restore operation
- Proper error handling during restoration
#### 3. EditorFunctions/index.js
- Extended `EditorCallbacks` type to include optional `onSave` function
- Enables AI components to trigger project saves when needed
#### 4. MainFrame/index.js
- Added `onOpenCloudProjectOnSpecificVersion` to editor props
- This connects the AI editor to the existing version restoration system
## User Experience
### Starting an Agent Request
1. User opens AI agent and submits a request
2. System automatically saves the current project (creates a new version)
3. Version ID is stored with the AI request for later restoration
4. AI agent proceeds with modifications
### Restoring to Initial State
1. User sees "Click here to restore the project as it was at the beginning" button
2. Clicking the button triggers cloud version restoration
3. Project is restored to the exact state before AI agent started
4. All changes made by the AI agent are discarded
## Technical Advantages
### 1. Leverages Existing Infrastructure
- Uses GDevelop's mature cloud save and version system
- No custom serialization/deserialization code needed
- Inherits all cloud storage reliability and error handling
### 2. Scalable and Reliable
- Cloud versions are professionally managed and backed up
- No local storage limitations or browser storage issues
- Consistent across different devices and sessions
### 3. Version History Integration
- Restored versions appear in the project's version history
- Users can access version history features for AI-generated content
- Seamless integration with existing version management workflow
## Limitations and Considerations
### 1. Cloud Projects Only
- Feature only works for projects saved to GDevelop Cloud
- Local projects cannot use this restoration feature
- Clear messaging is provided when feature is unavailable
### 2. Version Storage
- Relies on cloud project version creation during save
- Version IDs are stored locally in the AI request metadata
- If local storage is cleared, version reference may be lost
### 3. Network Dependency
- Restoration requires internet connection for cloud access
- Standard cloud storage network limitations apply
## Error Handling
### 1. Save Failures
- If initial save fails, AI request continues without version storage
- User is informed that restoration won't be available
- Graceful degradation ensures AI functionality remains available
### 2. Restoration Failures
- Comprehensive error logging for debugging
- UI provides feedback during restoration process
- Button disabled during restoration to prevent conflicts
### 3. Non-Cloud Projects
- Restore functionality hidden for non-cloud projects
- Clear console warnings when attempting unsupported operations
- No impact on existing AI functionality for local projects
## Future Enhancements
### 1. Backend Integration
- Could extend backend API to store `initialProjectVersionId` server-side
- Would enable restoration across sessions and devices
- Currently relies on local client-side storage
### 2. Local Project Support
- Could implement local project snapshots using browser storage
- Would require custom serialization for non-cloud projects
- Currently prioritizes cloud projects for reliability
### 3. Enhanced UI
- Could add confirmation dialogs for restoration
- Might include preview of changes before restoration
- Could integrate with version history UI components

View File

@@ -60,7 +60,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_
endif()
#Activate C++11
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 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)
# Mark some warnings as errors
@@ -69,18 +69,12 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# uninitialized variables or other hard to debug bugs.
add_compile_options(
-Wall
-Wextra
-Wuninitialized
-Wconditional-uninitialized
-Wno-unknown-warning-option
-Wno-reorder-ctor
-Wno-reorder
-Wno-unused-parameter
-Wno-pessimizing-move
-Wno-unused-variable # Not a good style, but not a risk
-Wno-unused-variable
-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).
-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_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:
#

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,7 @@
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDCore/Events/Serialization.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/TinyXml/tinyxml.h"
using namespace std;
@@ -61,12 +62,10 @@ void GroupEvent::UnserializeFrom(gd::Project& project,
project, events, element.GetChild("events"));
parameters.clear();
if (element.HasChild("parameters")) {
gd::SerializerElement& parametersElement = element.GetChild("parameters");
parametersElement.ConsiderAsArrayOf("parameters");
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i)
parameters.push_back(parametersElement.GetChild(i).GetValue().GetString());
}
gd::SerializerElement& parametersElement = element.GetChild("parameters");
parametersElement.ConsiderAsArrayOf("parameters");
for (std::size_t i = 0; i < parametersElement.GetChildrenCount(); ++i)
parameters.push_back(parametersElement.GetChild(i).GetValue().GetString());
}
void GroupEvent::SetBackgroundColor(unsigned int colorR_,

View File

@@ -163,21 +163,6 @@ void LinkEvent::UnserializeFrom(gd::Project& project,
// end of compatibility code
}
vector<gd::String> LinkEvent::GetAllSearchableStrings() const {
vector<gd::String> allSearchableStrings;
allSearchableStrings.push_back(target);
return allSearchableStrings;
}
bool LinkEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == target) return false;
SetTarget(newSearchableString[0]);
return true;
}
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
return BaseEvent::AcceptVisitor(eventVisitor) ||
eventVisitor.VisitLinkEvent(*this);

View File

@@ -109,10 +109,6 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
virtual bool IsExecutable() const override { return true; };
virtual std::vector<gd::String> GetAllSearchableStrings() const override;
virtual bool ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) override;
virtual void SerializeTo(SerializerElement& element) const override;
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element) override;

View File

@@ -4,8 +4,8 @@
* 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/EventsList.h"
namespace gd {
@@ -36,10 +36,10 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
const gd::InstructionsList& GetActions() const { return actions; };
gd::InstructionsList& GetActions() { return actions; };
const gd::Expression& GetRepeatExpression() const {
return repeatNumberExpression;
const gd::String& GetRepeatExpression() const {
return repeatNumberExpression.GetPlainString();
};
void SetRepeatExpressionPlainString(gd::String repeatNumberExpression_) {
void SetRepeatExpression(gd::String repeatNumberExpression_) {
repeatNumberExpression = gd::Expression(repeatNumberExpression_);
};
@@ -68,3 +68,5 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
};
} // namespace gd
#endif // GDCORE_REPEATEVENT_H

View File

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

View File

@@ -4,13 +4,13 @@
* 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/EventsList.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/Project/VariablesContainer.h"
namespace gd {
class Instruction;
class Project;
@@ -33,10 +33,6 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
virtual const gd::EventsList& GetSubEvents() const { 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; };
gd::InstructionsList& GetConditions() { return conditions; };
@@ -57,7 +53,9 @@ class GD_CORE_API StandardEvent : public gd::BaseEvent {
gd::InstructionsList conditions;
gd::InstructionsList actions;
EventsList events;
VariablesContainer variables;
};
} // 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
///< user create the event
mutable unsigned int whileConditionsHeight;
int GetConditionsHeight() const;
int GetActionsHeight() 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/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
namespace gd {
@@ -48,9 +47,6 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
// TODO Merge with UsedExtensionsFinder.
// TODO Factorize with the iteration on all effects for resource exposure.
// TODO Implement an ArbitraryEffectWorker and add a method in ProjectBrowserHelper
// See also gd::Project::ExposeResources for a method that traverse the whole
// project (this time for resources) and
// WholeProjectRefactorer::ExposeProjectEvents.
@@ -72,27 +68,6 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
// Add objects effects
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
// Add event-based objects layouts effects
for (std::size_t s = 0; s < project.GetEventsFunctionsExtensionsCount();
s++) {
auto &eventsFunctionExtension = project.GetEventsFunctionsExtension(s);
auto &eventsBasedObjects = eventsFunctionExtension.GetEventsBasedObjects();
for (std::size_t objectIndex = 0;
objectIndex < eventsBasedObjects.GetCount(); ++objectIndex) {
auto &eventsBasedObject = eventsBasedObjects.Get(objectIndex);
auto &layers = eventsBasedObject.GetLayers();
for (std::size_t l = 0; l < layers.GetLayersCount(); ++l) {
auto &effects = layers.GetLayer(l).GetEffects();
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
auto &effect = effects.GetEffect(e);
effectsCodeGenerator.AddEffectIncludeFiles(effect);
}
}
}
}
}
} // namespace gd

View File

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

View File

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

View File

@@ -3,7 +3,8 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef GDCORE_EVENTSCODEGENERATOR_H
#define GDCORE_EVENTSCODEGENERATOR_H
#include <set>
#include <utility>
@@ -11,10 +12,8 @@
#include "GDCore/Events/Event.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/CodeGeneration/DiagnosticReport.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/String.h"
namespace gd {
class EventsList;
class Expression;
@@ -128,7 +127,7 @@ class GD_CORE_API EventsCodeGenerator {
*/
std::vector<gd::String> GenerateParametersCodes(
const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersInfo,
const std::vector<gd::ParameterMetadata>& parametersInfo,
EventsCodeGenerationContext& context,
std::vector<std::pair<gd::String, gd::String> >*
supplementaryParametersTypes = 0);
@@ -337,16 +336,6 @@ class GD_CORE_API EventsCodeGenerator {
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
* 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; }
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
* conditions.
@@ -467,14 +448,7 @@ class GD_CORE_API EventsCodeGenerator {
*/
virtual gd::String GetCodeNamespace() { return ""; };
enum VariableScope {
LAYOUT_VARIABLE = 0,
PROJECT_VARIABLE,
OBJECT_VARIABLE,
ANY_VARIABLE,
VARIABLE_OR_PROPERTY,
VARIABLE_OR_PROPERTY_OR_PARAMETER
};
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
/**
* 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& rhs);
/**
* \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:
protected:
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
@@ -540,7 +496,7 @@ protected:
parameter -> string
* - operator : Used to update a value using a setter and a getter -> string
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
soundfile -> string
soundfile, police -> string
* - trueorfalse, yesorno -> boolean ( See GenerateTrue/GenerateFalse ).
*
* <br><br>
@@ -577,19 +533,12 @@ protected:
const gd::String& variableName,
const VariableScope& scope,
gd::EventsCodeGenerationContext& context,
const gd::String& objectName,
bool hasChild) {
// This code is only used as a mock.
// See the real implementation in GDJS.
const gd::String& objectName) {
if (scope == LAYOUT_VARIABLE) {
return "getLayoutVariable(" + variableName + ")";
} else if (scope == PROJECT_VARIABLE) {
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 + ")";
@@ -642,18 +591,11 @@ protected:
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property);
virtual gd::String GenerateParameterGetter(
const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String
GenerateParameterGetterWithoutCasting(const gd::ParameterMetadata &parameter);
/**
* \brief Generate the code to reference an object which is
* in an empty/null state.
@@ -837,10 +779,6 @@ protected:
virtual gd::String GenerateGetBehaviorNameCode(
const gd::String& behaviorName);
void CheckBehaviorParameters(
const gd::Instruction &instruction,
const gd::InstructionMetadata &instrInfos);
const gd::Platform& platform; ///< The platform being used.
gd::ProjectScopedContainers projectScopedContainers;
@@ -871,9 +809,8 @@ protected:
instructionUniqueIds; ///< The unique ids generated for instructions.
size_t eventsListNextUniqueId; ///< The next identifier to use for an events
///< list function name.
gd::DiagnosticReport* diagnosticReport;
};
} // namespace gd
#endif // GDCORE_EVENTSCODEGENERATOR_H

View File

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

View File

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

View File

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

View File

@@ -3,7 +3,9 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#if defined(GD_IDE_ONLY)
#ifndef GDCORE_EVENT_H
#define GDCORE_EVENT_H
#include <iostream>
#include <memory>
@@ -24,7 +26,6 @@ class SerializerElement;
class Instruction;
class EventVisitor;
class ReadOnlyEventVisitor;
class VariablesContainer;
} // namespace gd
namespace gd {
@@ -91,32 +92,6 @@ class GD_CORE_API BaseEvent {
*/
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.
* \note Used to preprocess or search in the conditions.
@@ -175,6 +150,26 @@ class GD_CORE_API BaseEvent {
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
@@ -286,20 +281,6 @@ class GD_CORE_API BaseEvent {
* \brief True if the event should be folded in the events editor.
*/
bool IsFolded() const { return folded; }
/**
* \brief Set the AI generated event ID.
*/
void SetAiGeneratedEventId(const gd::String& aiGeneratedEventId_) {
aiGeneratedEventId = aiGeneratedEventId_;
}
/**
* \brief Get the AI generated event ID.
*/
const gd::String& GetAiGeneratedEventId() const {
return aiGeneratedEventId;
}
///@}
std::weak_ptr<gd::BaseEvent>
@@ -318,10 +299,10 @@ class GD_CORE_API BaseEvent {
bool disabled; ///< True if the event is disabled and must not be executed
gd::String type; ///< Type of the event. Must be assigned at the creation.
///< Used for saving the event for instance.
gd::String aiGeneratedEventId; ///< When generated by an AI/external tool.
static gd::EventsList badSubEvents;
static gd::VariablesContainer badLocalVariables;
static std::vector<gd::String> emptyDependencies;
static gd::String emptySourceFile;
};
/**
@@ -344,3 +325,6 @@ class EmptyEvent : public BaseEvent {
};
} // namespace gd
#endif // GDCORE_EVENT_H
#endif

View File

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

View File

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

View File

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

View File

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

View File

@@ -182,10 +182,10 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
// Common updates for some parameters
const std::vector<gd::Expression>& parameters = instr.GetParameters();
for (std::size_t j = 0;
j < parameters.size() && j < metadata.parameters.GetParametersCount();
j < parameters.size() && j < metadata.parameters.size();
++j) {
if (metadata.parameters.GetParameter(j).GetType() == "relationalOperator" ||
metadata.parameters.GetParameter(j).GetType() == "operator") {
if (metadata.parameters[j].GetType() == "relationalOperator" ||
metadata.parameters[j].GetType() == "operator") {
if (j == parameters.size() - 1) {
std::cout << "ERROR: No more parameters after a [relational]operator "
"when trying to update an instruction from GD2.x";
@@ -221,8 +221,6 @@ void EventsListSerialization::UnserializeEventsFrom(
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
event->SetAiGeneratedEventId(
eventElem.GetStringAttribute("aiGeneratedEventId", ""));
list.InsertEvent(event, list.GetEventsCount());
}
@@ -238,8 +236,6 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
if (event.IsDisabled())
eventElem.SetAttribute("disabled", event.IsDisabled());
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
if (!event.GetAiGeneratedEventId().empty())
eventElem.SetAttribute("aiGeneratedEventId", event.GetAiGeneratedEventId());
eventElem.AddChild("type").SetValue(event.GetType());
event.SerializeTo(eventElem);

View File

@@ -66,7 +66,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
// Deprecated
extension
.AddAction("CopyArgumentToVariable",
_("Copy function parameter to variable"),
@@ -79,25 +78,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "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()
.MarkAsAdvanced();
// Deprecated
extension
.AddAction("CopyVariableToArgument",
_("Copy variable to function parameter"),
@@ -110,21 +93,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "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()
.MarkAsAdvanced();
@@ -141,8 +109,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced()
.SetHidden();
.MarkAsAdvanced();
extension
.AddExpression(
@@ -178,8 +145,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden();
.SetRelevantForFunctionEventsOnly();
extension
.AddCondition(
@@ -193,8 +159,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden();
.SetRelevantForFunctionEventsOnly();
}
} // namespace gd

View File

@@ -37,8 +37,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetIcon("res/actions/position24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Angle"))
.SetIcon("res/actions/direction24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
"res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
.SetIcon("res/actions/scale24_black.png");
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
"", _("Base object"), _("Base object"), "res/objeticon24.png");
@@ -117,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the position of the center of _PARAM0_: _PARAM1_ "
"_PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position Center"),
_("Position/Center"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
.AddParameter("object", _("Object"))
@@ -133,7 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center X position"),
_("the X position of the center of rotation"),
_("the X position of the center"),
_("Position Center"),
_("Position/Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -144,7 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center Y position"),
_("the Y position of the center of rotation"),
_("the Y position of the center"),
_("Position Center"),
_("Position/Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -155,7 +155,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) left position"),
_("the bounding box left position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-left_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -166,7 +166,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-top_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -177,7 +177,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) right position"),
_("the bounding box right position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-right_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -188,7 +188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) bottom position"),
_("the bounding box bottom position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-bottom_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -199,7 +199,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center X position"),
_("the bounding box center X position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -210,7 +210,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center Y position"),
_("the bounding box center Y position"),
_("Position Bounding Box"),
_("Position/Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -235,8 +235,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("SetAngle",
_("Angle"),
_("Change the angle of rotation of an object (in degrees). For "
"3D objects, this is the rotation around the Z axis."),
_("Change the angle of rotation of an object (in degrees)."),
_("the angle"),
_("Angle"),
"res/actions/direction24_black.png",
@@ -251,12 +250,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("Rotate",
_("Rotate"),
_("Rotate an object, clockwise if the speed is positive, "
"counterclockwise otherwise. For 3D objects, this is the "
"rotation around the Z axis."),
"counterclockwise otherwise."),
_("Rotate _PARAM0_ at speed _PARAM1_ deg/second"),
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
.AddCodeOnlyParameter("currentScene", "")
@@ -270,6 +269,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle to rotate towards (in degrees)"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
@@ -285,6 +285,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
@@ -303,12 +304,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Speed on X axis (in pixels per second)"))
.AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/");
.SetDefaultValue("0");
obj.AddAction("AddForceAL",
_("Add a force (angle)"),
@@ -320,12 +321,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -338,13 +339,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -359,13 +360,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", "X position of the center")
.AddParameter("expression", "Y position of the center")
.AddParameter("expression", "Speed (in Degrees per seconds)")
.AddParameter("expression", "Distance (in pixels)")
.AddParameter("forceMultiplier", "Force multiplier")
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddAction("Arreter",
@@ -375,8 +376,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/arreter24.png",
"res/actions/arreter.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("Delete",
@@ -416,99 +417,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetDefaultValue("\"\"")
.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",
_("Change number variable"),
_("Modify the number value of an object variable."),
@@ -519,10 +427,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
ParameterOptions::MakeNewOptions());
obj.AddAction("ModVarObjetTxt",
_("Change text variable"),
@@ -534,10 +440,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
ParameterOptions::MakeNewOptions());
obj.AddAction("SetObjectVariableAsBoolean",
_("Change boolean variable"),
@@ -550,9 +454,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
.AddParameter("trueorfalse", _("New Value:"));
obj.AddAction(
"ToggleObjectVariableAsBoolean",
@@ -567,35 +469,31 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
.AddParameter("objectvar", _("Variable"));
obj.AddCondition("ObjectVariableChildExists",
_("Child existence"),
_("Check if the specified child of the object "
"structure variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableRemoveChild",
_("Remove a child"),
_("Remove a child from an object structure variable."),
_("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableClearChildren",
@@ -603,12 +501,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Remove all the children from the object array or structure "
"variable."),
_("Clear children from variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("Cache",
@@ -636,8 +533,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddCondition("Angle",
_("Angle"),
_("Compare the angle, in degrees, of the specified object. "
"For 3D objects, this is the angle around the Z axis."),
_("Compare the angle of the specified object."),
_("the angle (in degrees)"),
_("Angle"),
"res/conditions/direction24_black.png",
@@ -704,8 +600,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/arret24.png",
"res/conditions/arret.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("Vitesse",
@@ -715,10 +611,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
// Deprecated
@@ -735,7 +631,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("IsTotalForceAngleAround",
@@ -749,7 +644,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("VarObjet",
@@ -763,9 +657,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
"number", ParameterOptions::MakeNewOptions());
obj.AddCondition("VarObjetTxt",
_("Text variable"),
@@ -778,9 +670,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
"string", ParameterOptions::MakeNewOptions());
obj.AddCondition("ObjectVariableAsBoolean",
_("Boolean variable"),
@@ -793,9 +683,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
.SetDefaultValue("true");
obj.AddCondition("VarObjetDef",
"Variable defined",
@@ -809,56 +697,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("string", _("Variable"))
.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(
"ObjectVariablePush",
_("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"),
_("Variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -867,25 +711,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.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()
.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();
obj.AddAction(
@@ -893,44 +718,38 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add text variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add text _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
_("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()
.SetRelevantForFunctionEventsOnly();
.MarkAsAdvanced();
obj.AddAction("ObjectVariablePushNumber",
_("Add number variable"),
_("Adds a number to the end of an object array variable."),
_("Add number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
_("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()
.SetRelevantForFunctionEventsOnly();
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariablePushBool",
_("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables Arrays and structures"),
_("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()
.SetRelevantForFunctionEventsOnly();
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariableRemoveAt",
@@ -939,13 +758,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"_PARAM0_"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddCondition(
@@ -953,14 +771,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Number of children"),
_("Compare the number of children in an object array variable."),
_("The number of children in the array variable _PARAM1_"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddStrExpression(
@@ -968,44 +785,40 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("First text child"),
_("Get the value of the first element of an object array variable, if "
"it is a text (string) variable."),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
.AddParameter("objectvar", _("Array variable"));
obj.AddExpression(
"ArrayVariableFirstNumber",
_("First number child"),
_("Get the value of the first element of an object array variable, if "
"it is a number variable."),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
.AddParameter("objectvar", _("Array variable"));
obj.AddStrExpression(
"ArrayVariableLastString",
_("Last text child"),
_("Get the value of the last element of an object array variable, if "
"it is a text (string) variable."),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
.AddParameter("objectvar", _("Array variable"));
obj.AddExpression(
"ArrayVariableLastNumber",
_("Last number child"),
_("Get the value of the last element of an object array variable, if "
"it is a number variable."),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
.AddParameter("objectvar", _("Array variable"));
obj.AddCondition("BehaviorActivated",
_("Behavior activated"),
@@ -1040,12 +853,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target Object"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1060,13 +873,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Rotate around this object"))
.AddParameter("expression", _("Speed (in degrees per second)"))
.AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("MettreAutour",
@@ -1094,10 +907,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("objectList", "Object 2 (won't move)")
.SetHelpPath("/tutorials/how-to-move-objects/");
.AddParameter("objectList", "Object 2 (won't move)");
// Deprecated action
obj.AddAction("Ecarter",
@@ -1121,6 +934,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno",
@@ -1129,7 +943,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
@@ -1142,7 +955,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1174,7 +986,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetHidden();
obj.AddCondition(
@@ -1190,7 +1001,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetManipulatedType("number");
obj.AddCondition("ObjectTimerPaused",
@@ -1202,7 +1012,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timerPaused.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1215,8 +1024,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer24.png",
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
.AddParameter("identifier", _("Timer's name"), "objectTimer");
obj.AddAction("PauseObjectTimer",
_("Pause an object timer"),
@@ -1227,7 +1035,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/pauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("UnPauseObjectTimer",
@@ -1239,7 +1046,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/unPauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("RemoveObjectTimer",
@@ -1251,7 +1057,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddExpression("X",
@@ -1270,8 +1075,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddExpression("Angle",
_("Angle"),
_("Current angle, in degrees, of the object. For 3D "
"objects, this is the angle around the Z axis."),
_("Current angle, in degrees, of the object"),
_("Angle"),
"res/actions/direction_black.png")
.AddParameter("object", _("Object"));
@@ -1281,32 +1085,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("X coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
.AddParameter("object", _("Object"));
obj.AddExpression("ForceY",
_("Y coordinate of the sum of forces"),
_("Y coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
.AddParameter("object", _("Object"));
obj.AddExpression("ForceAngle",
_("Angle of the sum of forces"),
_("Angle of the sum of forces (in degrees)"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
.AddParameter("object", _("Object"));
obj.AddExpression("ForceLength",
_("Length of the sum of forces"),
_("Length of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
.AddParameter("object", _("Object"));
obj.AddExpression("Longueur",
_("Length of the sum of forces"),
@@ -1314,7 +1114,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddExpression("Width",
@@ -1404,18 +1203,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Variables"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.AddParameter("objectvar", _("Variable"));
obj.AddExpression(
"VariableChildCount",
_("Number of children"),
_("Number of children in an object array or structure variable"),
_("Variables Arrays and structures"),
_("Variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
.AddParameter("objectvar", _("Array or structure variable"));
obj.AddStrExpression("VariableString",
_("Text variable"),
@@ -1423,9 +1220,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Variables"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
.AddParameter("objectvar", _("Variable"));
obj.AddExpression("ObjectTimerElapsedTime",
_("Object timer value"),
@@ -1433,8 +1228,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Timers"),
"res/actions/time.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
.AddParameter("identifier", _("Timer's name"), "objectTimer");
obj.AddExpression("AngleToObject",
_("Angle between two objects"),
@@ -1574,9 +1368,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
extension
.AddAction("Create",
_("Create an object"),
_("Create an instance of the object at the specified position."
"The created object instance will be available for the next "
"actions and sub-events."),
_("Create an object at specified position"),
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_ "
"(layer: _PARAM4_)"),
"",
@@ -1656,7 +1448,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/doMove24.png",
"res/actions/doMove.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1672,7 +1463,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Tolerance, in degrees"))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1805,7 +1595,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1821,22 +1610,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression",
_("Angle of tolerance, in degrees (0: minimum tolerance)"))
.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();
extension
@@ -1868,7 +1641,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension
@@ -1900,7 +1672,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension

View File

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

View File

@@ -19,7 +19,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
extension
.SetExtensionInformation("TextContainerCapability",
_("Text capability"),
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
_("Animate objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
@@ -30,7 +30,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
"TextContainerBehavior",
_("Text capability"),
"Text",
_("Allows an object to contain a text, usually shown on screen, that can be modified."),
_("Access objects text."),
"",
"res/conditions/text24_black.png",
"TextContainerBehavior",

View File

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

View File

@@ -59,57 +59,47 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
// end of compatibility code
extension
.AddCondition(
"Or",
_("Or"),
_("Checks if at least one sub-condition is true. If no "
"sub-condition is specified, it will always be false. "
"This is rarely used — multiple events and sub-events are "
"usually a better approach."),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
.AddCondition("Or",
_("Or"),
_("Check if one of the sub conditions is true"),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition("And",
_("And"),
_("Check if all sub conditions are true"),
_("If all of these conditions are true:"),
"",
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition(
"And",
_("And"),
_("Checks if all sub-conditions are true. If no sub-condition is "
"specified, it will always be false. This is rarely needed, as "
"events already check all conditions before running actions."),
_("If all of these conditions are true:"),
"Not",
_("Not"),
_("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"),
"",
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition("Not",
_("Not"),
_("Returns the opposite of the sub-condition(s) result. "
"This is rarely needed, as most conditions can be "
"inverted or expressed more simply."),
_("Invert the logical result of these conditions:"),
"",
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension
.AddCondition("Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions "
"have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png")
.SetHelpPath("/all-features/advanced-conditions/trigger-once");
extension.AddCondition(
"Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png");
extension
.AddCondition("CompareNumbers",

View File

@@ -28,7 +28,7 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
.AddAction("CreateObjectsFromExternalLayout",
_("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")

View File

@@ -98,7 +98,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Group"))
.AddParameter("string", _("Text"));
// Deprecated
extension
.AddAction(
"LireFichierExp",
@@ -115,27 +114,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("scenevar", _("Scene variable"))
.SetHidden();
.AddParameter("scenevar", _("Scene variables"));
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
.AddAction(
"LireFichierTxt",
@@ -153,26 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddParameter("string", _("Storage name"))
.AddParameter("string", _("Group"))
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("scenevar", _("Scene variable"))
.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"));
.AddParameter("scenevar", _("Scene variables"));
extension
.AddAction("DeleteGroupFichier",

View File

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

View File

@@ -72,8 +72,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value "
"between 0 and 1."),
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Remap a value between 0 and 1."),
"",
"res/mathfunction.png")
@@ -125,8 +124,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("mod",
_("Modulo"),
_("Compute \"x mod y\". GDevelop does NOT support the \% "
"operator. Use this mod(x, y) function instead."),
_("x mod y"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("x (as in x mod y)"))
@@ -153,8 +151,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("abs",
_("Absolute value"),
_("Return the non-negative value by removing the sign. "
"The absolute value of -8 is 8."),
_("Absolute value"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -186,8 +183,11 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"asinh", _("Arcsine"), _("Arcsine"), "", "res/mathfunction.png")
.AddExpression("asinh",
_("Arcsine"),
_("Arcsine"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -217,8 +217,11 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"cbrt", _("Cube root"), _("Cube root"), "", "res/mathfunction.png")
.AddExpression("cbrt",
_("Cube root"),
_("Cube root"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -256,13 +259,12 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression(
"cos",
_("Cosine"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression("cos",
_("Cosine"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -290,20 +292,29 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"int", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.AddExpression("int",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"rint", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.AddExpression("rint",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"round", _("Round"), _("Round a number"), "", "res/mathfunction.png")
.AddExpression("round",
_("Round"),
_("Round a number"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -312,8 +323,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
_("Round a number to the Nth decimal place"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Number to Round"))
.AddParameter("expression", _("Decimal Places"), "", true);
.AddParameter("expression", _("Expression"))
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression("exp",
@@ -324,13 +335,19 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"log", _("Logarithm"), _("Logarithm"), "", "res/mathfunction.png")
.AddExpression("log",
_("Logarithm"),
_("Logarithm"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"ln", _("Logarithm"), _("Logarithm"), "", "res/mathfunction.png")
.AddExpression("ln",
_("Logarithm"),
_("Logarithm"),
"",
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -369,8 +386,11 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("The exponent (n in x^n)"));
extension
.AddExpression(
"sec", _("Secant"), _("Secant"), "", "res/mathfunction.png")
.AddExpression("sec",
_("Secant"),
_("Secant"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -382,13 +402,12 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression("sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -408,13 +427,12 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Expression"));
extension
.AddExpression(
"tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddExpression("tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
@@ -444,28 +462,26 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("x (in a+(b-a)*x)"));
extension
.AddExpression(
"XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression(
"YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
@@ -480,8 +496,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("lerpAngle",
_("Lerp (Linear interpolation) between two angles"),
_("Linearly interpolates between two angles (in degrees) "
"by taking the shortest direction around the circle."),
_("Linearly interpolates between two angles (in degrees) by taking the shortest direction around the circle."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Starting angle, in degrees"))

View File

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

View File

@@ -182,7 +182,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
"SceneLoadingProgress",
_("Scene loading progress"),
_("The progress of resources loading in background for a scene (between 0 and 1)."),
_("_PARAM1_ loading progress"),
_("_PARAM0_ loading progress"),
_(""),
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")

View File

@@ -6,6 +6,8 @@
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include <vector>
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/String.h"
namespace gd {

View File

@@ -4,11 +4,13 @@
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef GDCORE_ANIMATION_H
#define GDCORE_ANIMATION_H
#include <vector>
#include "GDCore/String.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
namespace gd {
class Direction;
}
namespace gd {
@@ -91,3 +93,4 @@ class GD_CORE_API Animation {
};
} // namespace gd
#endif // GDCORE_ANIMATION_H

View File

@@ -3,12 +3,12 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef GDCORE_DIRECTION_H
#define GDCORE_DIRECTION_H
#include <vector>
#include "GDCore/String.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
namespace gd {
class Sprite;
class SerializerElement;
}
@@ -142,3 +142,4 @@ class GD_CORE_API Direction {
};
} // namespace gd
#endif // GDCORE_DIRECTION_H

View File

@@ -1,164 +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/Extensions/Builtin/SpriteExtension/SpriteAnimationList.h"
#include <algorithm>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
Animation SpriteAnimationList::badAnimation;
SpriteAnimationList::SpriteAnimationList()
: adaptCollisionMaskAutomatically(true) {}
SpriteAnimationList::~SpriteAnimationList(){};
void SpriteAnimationList::UnserializeFrom(const gd::SerializerElement& element) {
adaptCollisionMaskAutomatically =
element.GetBoolAttribute("adaptCollisionMaskAutomatically", false);
RemoveAllAnimations();
const gd::SerializerElement& animationsElement =
element.GetChild("animations", 0, "Animations");
animationsElement.ConsiderAsArrayOf("animation", "Animation");
for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) {
const gd::SerializerElement& animationElement =
animationsElement.GetChild(i);
Animation newAnimation;
newAnimation.useMultipleDirections = animationElement.GetBoolAttribute(
"useMultipleDirections", false, "typeNormal");
newAnimation.SetName(animationElement.GetStringAttribute("name", ""));
// Compatibility with GD <= 3.3
if (animationElement.HasChild("Direction")) {
for (std::size_t j = 0;
j < animationElement.GetChildrenCount("Direction");
++j) {
Direction direction;
direction.UnserializeFrom(animationElement.GetChild("Direction", j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
// End of compatibility code
else {
const gd::SerializerElement& directionsElement =
animationElement.GetChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t j = 0; j < directionsElement.GetChildrenCount(); ++j) {
Direction direction;
direction.UnserializeFrom(directionsElement.GetChild(j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
AddAnimation(newAnimation);
}
}
void SpriteAnimationList::SerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("adaptCollisionMaskAutomatically",
adaptCollisionMaskAutomatically);
// Animations
gd::SerializerElement& animationsElement = element.AddChild("animations");
animationsElement.ConsiderAsArrayOf("animation");
for (std::size_t k = 0; k < GetAnimationsCount(); k++) {
gd::SerializerElement& animationElement =
animationsElement.AddChild("animation");
animationElement.SetAttribute("useMultipleDirections",
GetAnimation(k).useMultipleDirections);
animationElement.SetAttribute("name", GetAnimation(k).GetName());
gd::SerializerElement& directionsElement =
animationElement.AddChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t l = 0; l < GetAnimation(k).GetDirectionsCount(); l++) {
GetAnimation(k).GetDirection(l).SerializeTo(
directionsElement.AddChild("direction"));
}
}
}
void SpriteAnimationList::ExposeResources(gd::ArbitraryResourceWorker& worker) {
for (std::size_t j = 0; j < GetAnimationsCount(); j++) {
for (std::size_t k = 0; k < GetAnimation(j).GetDirectionsCount(); k++) {
for (std::size_t l = 0;
l < GetAnimation(j).GetDirection(k).GetSpritesCount();
l++) {
worker.ExposeImage(
GetAnimation(j).GetDirection(k).GetSprite(l).GetImageName());
}
}
}
}
bool SpriteAnimationList::HasAnimationNamed(const gd::String &name) const {
return !name.empty() && (find_if(animations.begin(), animations.end(),
[&name](const Animation &animation) {
return animation.GetName() == name;
}) != animations.end());
}
const Animation& SpriteAnimationList::GetAnimation(std::size_t nb) const {
if (nb >= animations.size()) return badAnimation;
return animations[nb];
}
Animation& SpriteAnimationList::GetAnimation(std::size_t nb) {
if (nb >= animations.size()) return badAnimation;
return animations[nb];
}
void SpriteAnimationList::AddAnimation(const Animation& animation) {
animations.push_back(animation);
}
bool SpriteAnimationList::RemoveAnimation(std::size_t nb) {
if (nb >= GetAnimationsCount()) return false;
animations.erase(animations.begin() + nb);
return true;
}
void SpriteAnimationList::SwapAnimations(std::size_t firstIndex,
std::size_t secondIndex) {
if (firstIndex < animations.size() && secondIndex < animations.size() &&
firstIndex != secondIndex)
std::swap(animations[firstIndex], animations[secondIndex]);
}
void SpriteAnimationList::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) {
if (oldIndex >= animations.size() || newIndex >= animations.size()) return;
auto animation = animations[oldIndex];
animations.erase(animations.begin() + oldIndex);
animations.insert(animations.begin() + newIndex, animation);
}
} // namespace gd

View File

@@ -1,124 +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/Extensions/Builtin/SpriteExtension/Animation.h"
namespace gd {
class InitialInstance;
class SerializerElement;
class PropertyDescriptor;
class ArbitraryResourceWorker;
} // namespace gd
namespace gd {
/**
* \brief A list of animations, containing directions with images and collision mask.
*
* It's used in the configuration of object that implements image-based animations.
*
* \see Animation
* \see Direction
* \see Sprite
* \ingroup SpriteObjectExtension
*/
class GD_CORE_API SpriteAnimationList {
public:
SpriteAnimationList();
virtual ~SpriteAnimationList();
void ExposeResources(gd::ArbitraryResourceWorker& worker);
/**
* \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/
const Animation& GetAnimation(std::size_t nb) const;
/**
* \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/
Animation& GetAnimation(std::size_t nb);
/**
* \brief Return the number of animations this object has.
*/
std::size_t GetAnimationsCount() const { return animations.size(); };
/**
* \brief Return true if 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.
*/
void AddAnimation(const Animation& animation);
/**
* \brief Remove an animation.
*/
bool RemoveAnimation(std::size_t nb);
/**
* \brief Remove all animations.
*/
void RemoveAllAnimations() { animations.clear(); }
/**
* \brief Return true if the object hasn't any animation.
*/
bool HasNoAnimations() const { return animations.empty(); }
/**
* \brief Swap the position of two animations
*/
void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex);
/**
* \brief Change the position of the specified animation
*/
void MoveAnimation(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Return a read-only reference to the vector containing all the
* animation of the object.
*/
const std::vector<Animation>& GetAllAnimations() const { return animations; }
/**
* @brief Check if the collision mask adapts automatically to the animation.
*/
bool AdaptCollisionMaskAutomatically() const {
return adaptCollisionMaskAutomatically;
}
/**
* @brief Set if the collision mask adapts automatically to the animation.
*/
void SetAdaptCollisionMaskAutomatically(bool enable) {
adaptCollisionMaskAutomatically = enable;
}
void UnserializeFrom(const gd::SerializerElement& element);
void SerializeTo(gd::SerializerElement& element) const;
private:
mutable std::vector<Animation> animations;
static Animation badAnimation; //< Bad animation when an out of bound
// animation is requested.
bool adaptCollisionMaskAutomatically; ///< If set to true, the collision
///< mask will be automatically
///< adapted to the animation of the
///< object.
};
} // namespace gd

View File

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

View File

@@ -23,45 +23,127 @@
namespace gd {
Animation SpriteObject::badAnimation;
SpriteObject::SpriteObject()
: updateIfNotVisible(false),
preScale(1) {}
: updateIfNotVisible(false), adaptCollisionMaskAutomatically(true) {}
SpriteObject::~SpriteObject(){};
void SpriteObject::DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) {
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
preScale = element.GetDoubleAttribute("preScale", 1);
animations.UnserializeFrom(element);
adaptCollisionMaskAutomatically =
element.GetBoolAttribute("adaptCollisionMaskAutomatically", false);
RemoveAllAnimations();
const gd::SerializerElement& animationsElement =
element.GetChild("animations", 0, "Animations");
animationsElement.ConsiderAsArrayOf("animation", "Animation");
for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) {
const gd::SerializerElement& animationElement =
animationsElement.GetChild(i);
Animation newAnimation;
newAnimation.useMultipleDirections = animationElement.GetBoolAttribute(
"useMultipleDirections", false, "typeNormal");
newAnimation.SetName(animationElement.GetStringAttribute("name", ""));
// Compatibility with GD <= 3.3
if (animationElement.HasChild("Direction")) {
for (std::size_t j = 0;
j < animationElement.GetChildrenCount("Direction");
++j) {
Direction direction;
direction.UnserializeFrom(animationElement.GetChild("Direction", j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
// End of compatibility code
else {
const gd::SerializerElement& directionsElement =
animationElement.GetChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t j = 0; j < directionsElement.GetChildrenCount(); ++j) {
Direction direction;
direction.UnserializeFrom(directionsElement.GetChild(j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
AddAnimation(newAnimation);
}
}
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
if (preScale != 1) {
element.SetAttribute("preScale", preScale);
element.SetAttribute("adaptCollisionMaskAutomatically",
adaptCollisionMaskAutomatically);
// Animations
gd::SerializerElement& animationsElement = element.AddChild("animations");
animationsElement.ConsiderAsArrayOf("animation");
for (std::size_t k = 0; k < GetAnimationsCount(); k++) {
gd::SerializerElement& animationElement =
animationsElement.AddChild("animation");
animationElement.SetAttribute("useMultipleDirections",
GetAnimation(k).useMultipleDirections);
animationElement.SetAttribute("name", GetAnimation(k).GetName());
gd::SerializerElement& directionsElement =
animationElement.AddChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t l = 0; l < GetAnimation(k).GetDirectionsCount(); l++) {
GetAnimation(k).GetDirection(l).SerializeTo(
directionsElement.AddChild("direction"));
}
}
animations.SerializeTo(element);
}
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
const {
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;
}
bool SpriteObject::UpdateProperty(const gd::String& name,
const gd::String& value) {
if (name == _("Animate even if hidden or far from the screen"))
updateIfNotVisible = value == "1";
return true;
}
void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
animations.ExposeResources(worker);
for (std::size_t j = 0; j < GetAnimationsCount(); j++) {
for (std::size_t k = 0; k < GetAnimation(j).GetDirectionsCount(); k++) {
for (std::size_t l = 0;
l < GetAnimation(j).GetDirection(k).GetSpritesCount();
l++) {
worker.ExposeImage(
GetAnimation(j).GetDirection(k).GetSprite(l).GetImageName());
}
}
}
}
std::map<gd::String, gd::PropertyDescriptor>
SpriteObject::GetInitialInstanceProperties(
const gd::InitialInstance& initialInstance) {
const gd::InitialInstance& initialInstance,
gd::Project& project,
gd::Layout& scene) {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties["animation"] =
gd::PropertyDescriptor(
@@ -75,7 +157,9 @@ SpriteObject::GetInitialInstanceProperties(
bool SpriteObject::UpdateInitialInstanceProperty(
gd::InitialInstance& initialInstance,
const gd::String& name,
const gd::String& value) {
const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == "animation") {
initialInstance.SetRawDoubleProperty(
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
@@ -84,25 +168,42 @@ bool SpriteObject::UpdateInitialInstanceProperty(
return true;
}
size_t SpriteObject::GetAnimationsCount() const {
return animations.GetAnimationsCount();
const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
if (nb >= animations.size()) return badAnimation;
return animations[nb];
}
const gd::String &SpriteObject::GetAnimationName(size_t index) const {
return animations.GetAnimation(index).GetName();
Animation& SpriteObject::GetAnimation(std::size_t nb) {
if (nb >= animations.size()) return badAnimation;
return animations[nb];
}
bool SpriteObject::HasAnimationNamed(
const gd::String &name) const {
return animations.HasAnimationNamed(name);
void SpriteObject::AddAnimation(const Animation& animation) {
animations.push_back(animation);
}
const SpriteAnimationList& SpriteObject::GetAnimations() const {
return animations;
bool SpriteObject::RemoveAnimation(std::size_t nb) {
if (nb >= GetAnimationsCount()) return false;
animations.erase(animations.begin() + nb);
return true;
}
SpriteAnimationList& SpriteObject::GetAnimations() {
return animations;
void SpriteObject::SwapAnimations(std::size_t firstIndex,
std::size_t secondIndex) {
if (firstIndex < animations.size() && secondIndex < animations.size() &&
firstIndex != secondIndex)
std::swap(animations[firstIndex], animations[secondIndex]);
}
void SpriteObject::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) {
if (oldIndex >= animations.size() || newIndex >= animations.size()) return;
auto animation = animations[oldIndex];
animations.erase(animations.begin() + oldIndex);
animations.insert(animations.begin() + newIndex, animation);
}
} // namespace gd

View File

@@ -4,15 +4,18 @@
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteAnimationList.h"
#ifndef GDCORE_SPRITEOBJECT_H
#define GDCORE_SPRITEOBJECT_H
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Project/Object.h"
namespace gd {
class InitialInstance;
class Object;
class Layout;
class Sprite;
class Animation;
class SerializerElement;
class PropertyDescriptor;
} // namespace gd
@@ -47,26 +50,85 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
const gd::InitialInstance& position) override;
const gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) override;
bool UpdateInitialInstanceProperty(gd::InitialInstance& position,
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.
/** \name Animations
* Methods related to animations management
*/
const SpriteAnimationList& GetAnimations() const;
///@{
/**
* \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/
const Animation& GetAnimation(std::size_t nb) const;
/**
* @brief Return the animation configuration.
* \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/
SpriteAnimationList& GetAnimations();
Animation& GetAnimation(std::size_t nb);
/**
* \brief Return the number of animations this object has.
*/
std::size_t GetAnimationsCount() const { return animations.size(); };
/**
* \brief Add an animation at the end of the existing ones.
*/
void AddAnimation(const Animation& animation);
/**
* \brief Remove an animation.
*/
bool RemoveAnimation(std::size_t nb);
/**
* \brief Remove all animations.
*/
void RemoveAllAnimations() { animations.clear(); }
/**
* \brief Return true if the object hasn't any animation.
*/
bool HasNoAnimations() const { return animations.empty(); }
/**
* \brief Swap the position of two animations
*/
void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex);
/**
* \brief Change the position of the specified animation
*/
void MoveAnimation(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Return a read-only reference to the vector containing all the
* animation of the object.
*/
const std::vector<Animation>& GetAllAnimations() const { return animations; }
/**
* @brief Check if the collision mask adapts automatically to the animation.
*/
bool AdaptCollisionMaskAutomatically() const {
return adaptCollisionMaskAutomatically;
}
/**
* @brief Set if the collision mask adapts automatically to the animation.
*/
void SetAdaptCollisionMaskAutomatically(bool enable) {
adaptCollisionMaskAutomatically = enable;
}
/**
* \brief Set if the object animation should be played even if the object is
@@ -81,35 +143,25 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
* is hidden or far from the camera (false by default).
*/
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
/**
* \brief Return the scale applied to object to evaluate the default dimensions.
*/
double GetPreScale() { return preScale; }
/**
* \brief Set the scale applied to object to evaluate the default dimensions.
*
* Its value must be strictly positive.
*/
void SetPreScale(double preScale_) {
if (preScale_ <= 0) {
return;
}
preScale = preScale_;
}
///@}
private:
void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) override;
void DoSerializeTo(gd::SerializerElement& element) const override;
SpriteAnimationList animations;
mutable std::vector<Animation> animations;
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
///< object animation even if hidden or far from
///< the screen.
double preScale;
static Animation badAnimation; //< Bad animation when an out of bound
// animation is requested.
bool adaptCollisionMaskAutomatically; ///< If set to true, the collision
///< mask will be automatically
///< adapted to the animation of the
///< object.
};
} // namespace gd
#endif // GDCORE_SPRITEOBJECT_H

View File

@@ -43,9 +43,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddCondition("CompareTimer",
_("Value of a scene timer"),
_("Compare the elapsed time of a scene timer. This "
"condition doesn't start the timer and will always be "
"false if the timer was not started previously (whatever "
"the comparison being made)."),
"condition doesn't start the timer."),
_("The timer _PARAM1_ _PARAM2_ _PARAM3_ seconds"),
"",

View File

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

View File

@@ -114,8 +114,6 @@ public:
/**
* \brief Erase any existing include file and add the specified include.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
virtual AbstractFunctionMetadata &
SetIncludeFile(const gd::String &includeFile) = 0;

View File

@@ -13,15 +13,12 @@
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/MakeUnique.h"
#include "GDCore/Tools/Log.h"
namespace gd {
const std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::badProperties;
BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace_,
const gd::String& nameWithNamespace,
@@ -50,14 +47,8 @@ BehaviorMetadata::BehaviorMetadata(
"BehaviorMetadata is valid for: " + nameWithNamespace);
}
if (instance) {
instance->SetTypeName(nameWithNamespace);
instance->InitializeContent();
}
if (sharedDatasInstance) {
sharedDatasInstance->SetTypeName(nameWithNamespace);
sharedDatasInstance->InitializeContent();
}
if (instance) instance->SetTypeName(nameWithNamespace);
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
}
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
@@ -414,44 +405,18 @@ gd::Behavior& BehaviorMetadata::Get() const {
return *instance;
}
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() const {
if (!instance) {
return badProperties;
}
// TODO Properties should be declared on BehaviorMetadata directly.
// - Add 2 `properties` members (one for shared properties)
// - Add methods to declare new properties
return instance->GetProperties();
}
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
return sharedDatasInstance.get();
}
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperties() const {
if (!sharedDatasInstance) {
return badProperties;
}
// TODO Properties should be declared on BehaviorMetadata directly.
// - Add 2 `properties` members (one for shared properties)
// - Add methods to declare new properties
return sharedDatasInstance->GetProperties();
}
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
requiredBehaviors.clear();
if (!instance) {
return requiredBehaviors;
}
for (auto& property : instance->GetProperties()) {
for (auto& property : Get().GetProperties()) {
const String& propertyName = property.first;
const gd::PropertyDescriptor& propertyDescriptor = property.second;
if (propertyDescriptor.GetType() == "Behavior") {
const auto& extraInfos = propertyDescriptor.GetExtraInfo();
if (extraInfos.size() > 0) {
requiredBehaviors.push_back(extraInfos[0]);
}
requiredBehaviors.push_back(propertyDescriptor.GetExtraInfo()[0]);
}
}
return requiredBehaviors;

View File

@@ -12,14 +12,12 @@
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
#include "GDCore/Project/QuickCustomization.h"
namespace gd {
class Behavior;
class BehaviorsSharedData;
class MultipleInstructionMetadata;
class InstructionMetadata;
class ExpressionMetadata;
class PropertyDescriptor;
} // namespace gd
namespace gd {
@@ -42,10 +40,10 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
const gd::String& className_,
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/**
* \brief Construct a behavior metadata, without "blueprint" behavior.
*
*
* \note This is used by events based behaviors.
*/
BehaviorMetadata(
@@ -206,8 +204,6 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
* \brief Erase any existing include file and add the specified include.
* \note The requirement may vary depending on the platform: Most of the time,
* the include file contains the declaration of the behavior.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile) override;
@@ -272,7 +268,7 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
* Check if the behavior is private - it can't be used outside of its
* 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
@@ -298,59 +294,23 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
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.
*
*
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior
* are using EventBasedBehavior.
*/
gd::Behavior& Get() const;
/**
* \brief Called when the IDE wants to know about the custom properties of the
* behavior.
*
* \return a std::map with properties names as key.
* \see gd::PropertyDescriptor
*/
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const;
/**
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
* shared data, if any (nullptr if none).
*
*
* \note Returns nullptr for events based behaviors as they don't declare
* shared data yet.
*/
gd::BehaviorsSharedData* GetSharedDataInstance() const;
/**
* \brief Called when the IDE wants to know about the custom shared properties
* of the behavior.
*
* \return a std::map with properties names as key.
* \see gd::PropertyDescriptor
*/
std::map<gd::String, gd::PropertyDescriptor> GetSharedProperties() const;
/**
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
@@ -393,14 +353,10 @@ class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMeta
mutable std::vector<gd::String> requiredBehaviors;
bool isPrivate = false;
bool isHidden = false;
gd::String openFullEditorLabel;
QuickCustomization::Visibility quickCustomizationVisibility = QuickCustomization::Visibility::Default;
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
std::shared_ptr<gd::Behavior> instance;
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
static const std::map<gd::String, gd::PropertyDescriptor> badProperties;
};
} // namespace gd

View File

@@ -65,8 +65,6 @@ class GD_CORE_API EffectMetadata {
/**
* \brief Clear any existing include file and add the specified include file.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
EffectMetadata& SetIncludeFile(const gd::String& includeFile);
@@ -185,10 +183,10 @@ class GD_CORE_API EffectMetadata {
gd::String fullname;
gd::String description;
std::vector<gd::String> includeFiles;
bool isMarkedAsNotWorkingForObjects = false;
bool isMarkedAsOnlyWorkingFor2D = false;
bool isMarkedAsOnlyWorkingFor3D = false;
bool isMarkedAsUnique = false;
bool isMarkedAsNotWorkingForObjects;
bool isMarkedAsOnlyWorkingFor2D;
bool isMarkedAsOnlyWorkingFor3D;
bool isMarkedAsUnique;
std::map<gd::String, gd::PropertyDescriptor> properties;
};

View File

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

View File

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

View File

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

View File

@@ -193,9 +193,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter
*/
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue);
}
if (!parameters.empty())
parameters.back().SetDefaultValue(defaultValue);
return *this;
};
@@ -207,9 +206,8 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
*/
ExpressionMetadata &
SetParameterLongDescription(const gd::String &longDescription) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
}
if (!parameters.empty())
parameters.back().SetLongDescription(longDescription);
return *this;
};
@@ -222,9 +220,7 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
*/
ExpressionMetadata &SetParameterExtraInfo(
const gd::String &extraInfo) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
}
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
return *this;
}
@@ -252,16 +248,19 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
const gd::String& GetGroup() const { return group; }
const gd::String& GetSmallIconFilename() const { return smallIconFilename; }
const gd::ParameterMetadata& GetParameter(std::size_t id) const {
return parameters.GetParameter(id);
return parameters[id];
};
gd::ParameterMetadata& GetParameter(std::size_t id) {
return parameters.GetParameter(id);
return parameters[id];
};
std::size_t GetParametersCount() const { return parameters.GetParametersCount(); };
const gd::ParameterMetadataContainer& GetParameters() const {
std::size_t GetParametersCount() const { return parameters.size(); };
const std::vector<gd::ParameterMetadata>& GetParameters() const {
return parameters;
};
std::vector<gd::ParameterMetadata> parameters;
/**
* \brief Set the function name which will be used when generating the code.
* \param functionName the name of the function to call
@@ -289,8 +288,6 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
/**
* \brief Erase any existing include file and add the specified include.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
ExpressionMetadata& SetIncludeFile(
const gd::String& includeFile) override {
@@ -369,8 +366,6 @@ class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
bool isPrivate;
gd::String requiredBaseObjectCapability;
gd::String relevantContext;
gd::ParameterMetadataContainer parameters;
};
} // namespace gd

View File

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

View File

@@ -14,7 +14,6 @@
#include <memory>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/String.h"
#include "ParameterMetadata.h"
#include "ParameterOptions.h"
@@ -62,12 +61,12 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
const gd::String &GetDescription() const { return description; }
const gd::String &GetSentence() const { return sentence; }
const gd::String &GetGroup() const { return group; }
ParameterMetadata &GetParameter(size_t i) { return parameters.GetParameter(i); }
ParameterMetadata &GetParameter(size_t i) { return parameters[i]; }
const ParameterMetadata &GetParameter(size_t i) const {
return parameters.GetParameter(i);
return parameters[i];
}
size_t GetParametersCount() const { return parameters.GetParametersCount(); }
const ParameterMetadataContainer &GetParameters() const {
size_t GetParametersCount() const { return parameters.size(); }
const std::vector<ParameterMetadata> &GetParameters() const {
return parameters;
}
const gd::String &GetIconFilename() const { return iconFilename; }
@@ -257,9 +256,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter
*/
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetDefaultValue(defaultValue_);
}
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
return *this;
};
@@ -271,9 +268,8 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
*/
InstructionMetadata &SetParameterLongDescription(
const gd::String &longDescription) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetLongDescription(longDescription);
}
if (!parameters.empty())
parameters.back().SetLongDescription(longDescription);
return *this;
}
@@ -285,9 +281,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
* \see AddParameter
*/
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
if (parameters.GetParametersCount() > 0) {
parameters.GetInternalVector().back()->SetExtraInfo(extraInfo);
}
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
return *this;
}
@@ -462,15 +456,6 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
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
* with "number" or "string", this function will tell the code generator the
@@ -509,8 +494,6 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
/**
* \brief Erase any existing include file and add the specified include.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
codeExtraInformation.includeFiles.clear();
@@ -566,7 +549,7 @@ class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
*/
InstructionMetadata &GetCodeExtraInformation() { return *this; }
ParameterMetadataContainer parameters;
std::vector<ParameterMetadata> parameters;
private:
gd::String fullname;

View File

@@ -142,8 +142,6 @@ public:
* \brief Erase any existing include file and add the specified include.
* \note The requirement may vary depending on the platform: Most of the time,
* the include file contains the declaration of the behavior.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
virtual InstructionOrExpressionContainerMetadata &
SetIncludeFile(const gd::String &includeFile) = 0;
@@ -174,7 +172,6 @@ public:
virtual const gd::String &GetFullName() const = 0;
virtual const gd::String &GetDescription() 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

View File

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

View File

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

View File

@@ -150,10 +150,6 @@ class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata
return *this;
}
/**
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
if (expression)
expression->SetIncludeFile(includeFile);

View File

@@ -46,25 +46,30 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24)
: name(name_),
iconFilename(icon24x24),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
}
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24,
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
gd::LogFatalError(
"Error: Event-based objects don't have blueprint. "
"This method should not never be called.");
return nullptr;
}) {}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24,
CreateFunPtr createFunPtr_)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24) {
createFunPtr = createFunPtr_;
CreateFunPtr createFunPtrP)
: name(name_),
iconFilename(icon24x24),
createFunPtr(createFunPtrP),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
}
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
* be copied when a new object is requested.
*
* \note This is used for objects declared in JavaScript extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -49,9 +47,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
const gd::String& icon24x24_,
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_,
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
* to instantiate a new object.
*
* \note This is used for objects declared in C++ extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_,
CreateFunPtr createFunPtr_);
ObjectMetadata() {}
CreateFunPtr createFunPtrP);
ObjectMetadata() : createFunPtr(NULL) {}
virtual ~ObjectMetadata(){};
/**
@@ -251,11 +246,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
return *this;
}
ObjectMetadata& ResetDefaultBehaviorsJustForTesting() {
defaultBehaviorTypes.clear();
return *this;
}
const gd::String& GetName() const override { return name; }
const gd::String& GetFullName() const override { return fullname; }
const gd::String& GetCategoryFullName() const { return categoryFullName; }
@@ -274,8 +264,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
* \brief Erase any existing include file and add the specified include.
* \note The requirement may vary depending on the platform: Most of the time,
* the include file contains the declaration of the object.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
ObjectMetadata& SetIncludeFile(const gd::String& includeFile) override;
@@ -305,22 +293,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
*/
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.
*
@@ -349,15 +321,6 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
*/
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> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
@@ -365,7 +328,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
std::vector<gd::String> includeFiles;
gd::String className;
CreateFunPtr createFunPtr = nullptr;
CreateFunPtr createFunPtr;
private:
gd::String extensionNamespace;
@@ -377,10 +340,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
gd::String iconFilename;
gd::String categoryFullName;
std::set<gd::String> defaultBehaviorTypes;
bool isPrivate = false;
bool hidden = false;
bool isRenderedIn3D = false;
gd::String openFullEditorLabel;
std::shared_ptr<gd::ObjectConfiguration>
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.
*/
#pragma once
#ifndef PARAMETER_METADATA_H
#define PARAMETER_METADATA_H
#include <map>
#include <memory>
@@ -29,12 +29,6 @@ class GD_CORE_API ParameterMetadata {
ParameterMetadata();
virtual ~ParameterMetadata(){};
/**
* \brief Return a pointer to a new ParameterMetadata constructed from
* this one.
*/
ParameterMetadata* Clone() const { return new ParameterMetadata(*this); };
/**
* \brief Return the metadata of the parameter type.
*/
@@ -254,3 +248,5 @@ class GD_CORE_API ParameterMetadata {
};
} // namespace gd
#endif // PARAMETER_METADATA_H

View File

@@ -6,157 +6,86 @@
#include "ParameterMetadataTools.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/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainersList.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/Project/Project.h"
#include "GDCore/String.h"
#include "InstructionMetadata.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
namespace gd {
const ParameterMetadata ParameterMetadataTools::badParameterMetadata;
void ParameterMetadataTools::ParametersToObjectsContainer(
const gd::Project& project,
const ParameterMetadataContainer& parameters,
const std::vector<gd::ParameterMetadata>& parameters,
gd::ObjectsContainer& outputObjectsContainer) {
// Keep track of all objects and their behaviors names, so we can remove
// 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;
outputObjectsContainer.GetObjects().clear();
gd::String lastObjectName;
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) {
const auto& parameter = parameters.GetParameter(i);
for (std::size_t i = 0; i < parameters.size(); ++i) {
const auto& parameter = parameters[i];
if (parameter.GetName().empty()) continue;
auto &valueTypeMetadata = parameter.GetValueTypeMetadata();
if (valueTypeMetadata.IsObject()) {
const gd::String& objectName = parameter.GetName();
const gd::String& objectType = parameter.GetExtraInfo();
allObjectNames.insert(objectName);
// 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());
}
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
outputObjectsContainer.InsertNewObject(
project,
parameter.GetExtraInfo(),
parameter.GetName(),
outputObjectsContainer.GetObjectsCount());
// Memorize the last object name. By convention, parameters that require
// an object (mainly, "objectvar" and "behavior") should be placed after
// the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
lastObjectName = objectName;
} else if (valueTypeMetadata.IsBehavior()) {
lastObjectName = parameter.GetName();
} else if (gd::ParameterMetadata::IsBehavior(parameter.GetType())) {
if (!lastObjectName.empty()) {
if (outputObjectsContainer.HasObjectNamed(lastObjectName)) {
const gd::String& behaviorName = parameter.GetName();
const gd::String& behaviorType = parameter.GetExtraInfo();
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);
}
}
const gd::Object& object =
outputObjectsContainer.GetObject(lastObjectName);
gd::String behaviorName = parameter.GetName();
if (!object.HasBehaviorNamed(behaviorName)) {
object.AddNewBehavior(
project, parameter.GetExtraInfo(), behaviorName);
outputObjectsContainer.GetObject(lastObjectName)
.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(
const std::vector<const ParameterMetadataContainer*>&
const std::vector<const std::vector<gd::ParameterMetadata>*>&
parametersVectorsList,
const gd::String& search,
std::function<void(const gd::ParameterMetadata&)> cb) {
for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend();
++it) {
const ParameterMetadataContainer* parametersVector = *it;
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto &parameterMetadata :
parametersVector->GetInternalVector()) {
if (parameterMetadata->GetName().FindCaseInsensitive(search) !=
gd::String::npos)
cb(*parameterMetadata);
for (const auto& parameterMetadata: *parametersVector) {
if (parameterMetadata.GetName().FindCaseInsensitive(search) != gd::String::npos) cb(parameterMetadata);
}
}
}
bool ParameterMetadataTools::Has(
const std::vector<const ParameterMetadataContainer*>& parametersVectorsList,
const std::vector<const std::vector<gd::ParameterMetadata>*>& parametersVectorsList,
const gd::String& parameterName) {
for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend();
++it) {
const ParameterMetadataContainer* parametersVector = *it;
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto& parameterMetadata: parametersVector->GetInternalVector()) {
if (parameterMetadata->GetName() == parameterName) return true;
for (const auto& parameterMetadata: *parametersVector) {
if (parameterMetadata.GetName() == parameterName) return true;
}
}
@@ -164,18 +93,16 @@ bool ParameterMetadataTools::Has(
}
const gd::ParameterMetadata& ParameterMetadataTools::Get(
const std::vector<const ParameterMetadataContainer*>&
const std::vector<const std::vector<gd::ParameterMetadata>*>&
parametersVectorsList,
const gd::String& parameterName) {
for (auto it = parametersVectorsList.rbegin();
it != parametersVectorsList.rend();
++it) {
const ParameterMetadataContainer* parametersVector = *it;
const std::vector<gd::ParameterMetadata>* parametersVector = *it;
for (const auto &parameterMetadata :
parametersVector->GetInternalVector()) {
if (parameterMetadata->GetName() == parameterName)
return *parameterMetadata;
for (const auto& parameterMetadata: *parametersVector) {
if (parameterMetadata.GetName() == parameterName) return parameterMetadata;
}
}
@@ -184,7 +111,7 @@ const gd::ParameterMetadata& ParameterMetadataTools::Get(
void ParameterMetadataTools::IterateOverParameters(
const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& lastObjectName)> fn) {
@@ -201,17 +128,15 @@ void ParameterMetadataTools::IterateOverParameters(
void ParameterMetadataTools::IterateOverParametersWithIndex(
const std::vector<gd::Expression>& parameters,
const ParameterMetadataContainer& parametersMetadata,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
std::function<void(const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
size_t parameterIndex,
const gd::String& lastObjectName)> fn) {
gd::String lastObjectName = "";
for (std::size_t pNb = 0; pNb < parametersMetadata.GetParametersCount();
++pNb) {
const gd::ParameterMetadata &parameterMetadata =
parametersMetadata.GetParameter(pNb);
const gd::Expression &parameterValue =
for (std::size_t pNb = 0; pNb < parametersMetadata.size(); ++pNb) {
const gd::ParameterMetadata& parameterMetadata = parametersMetadata[pNb];
const gd::Expression& parameterValue =
pNb < parameters.size() ? parameters[pNb].GetPlainString() : "";
const gd::Expression& parameterValueOrDefault =
parameterValue.GetPlainString().empty() && parameterMetadata.IsOptional()
@@ -254,10 +179,10 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
size_t parameterIndex = 0;
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
metadataIndex < metadata.GetParameters().GetParametersCount() &&
metadataIndex < metadata.parameters.size() &&
parameterIndex < node.parameters.size();
++metadataIndex) {
auto &parameterMetadata = metadata.GetParameters().GetParameter(metadataIndex);
auto &parameterMetadata = metadata.parameters[metadataIndex];
if (parameterMetadata.IsCodeOnly()) {
continue;
}
@@ -279,17 +204,16 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
}
size_t ParameterMetadataTools::GetObjectParameterIndexFor(
const ParameterMetadataContainer& parametersMetadata,
const std::vector<gd::ParameterMetadata>& parametersMetadata,
size_t parameterIndex) {
// By convention, parameters that require
// an object (mainly, "objectvar" and "behavior") should be placed after
// the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
for (std::size_t pNb = parameterIndex;
pNb < parametersMetadata.GetParametersCount(); pNb--) {
if (gd::ParameterMetadata::IsObject(
parametersMetadata.GetParameter(pNb).GetType())) {
for (std::size_t pNb = parameterIndex; pNb < parametersMetadata.size();
pNb--) {
if (gd::ParameterMetadata::IsObject(parametersMetadata[pNb].GetType())) {
return pNb;
}
}

View File

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

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 &
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" ||
gd::ValueTypeMetadata::IsTypeValue("variable", parameterType)) {
gd::ValueTypeMetadata::IsTypeExpression("variable", parameterType)) {
return ValueTypeMetadata::variableType;
}
if (parameterType == "boolean" ||
gd::ValueTypeMetadata::IsTypeValue("boolean", parameterType)) {
if (parameterType == "boolean" || parameterType == "yesorno" ||
parameterType == "trueorfalse") {
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::booleanValueType = "boolean";
const gd::String ValueTypeMetadata::stringValueType = "string";
const gd::String ValueTypeMetadata::colorValueType = "color";
const gd::String ValueTypeMetadata::choiceValueType = "stringWithSelector";
const gd::String ValueTypeMetadata::behaviorValueType = "behavior";
const gd::String ValueTypeMetadata::leaderboardIdValueType = "leaderboardId";
const gd::String ValueTypeMetadata::objectAnimationNameValueType = "objectAnimationName";
const gd::String ValueTypeMetadata::keyboardKeyValueType = "keyboardKey";
const gd::String ValueTypeMetadata::stringValueType = "string";
const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
const gd::String &propertyType) {
@@ -92,16 +85,8 @@ const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
return colorValueType;
} else if (propertyType == "Choice") {
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;
};

View File

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

View File

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

View File

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

View File

@@ -17,7 +17,6 @@
#include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionOrExpressionGroupMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
#include "GDCore/Tools/VersionPriv.h"
@@ -41,7 +40,8 @@ class Object;
class ObjectConfiguration;
} // namespace gd
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()> CreateFunPtr;
typedef std::function<std::unique_ptr<gd::ObjectConfiguration>()>
CreateFunPtr;
namespace gd {
@@ -51,25 +51,25 @@ namespace gd {
*/
class GD_CORE_API CompilationInfo {
public:
CompilationInfo() {};
virtual ~CompilationInfo() {};
CompilationInfo() : informationCompleted(false){};
virtual ~CompilationInfo(){};
bool informationCompleted = false;
bool informationCompleted;
bool runtimeOnly = false; ///< True if the extension was compiled for a
///< runtime use only
bool runtimeOnly; ///< True if the extension was compiled for a runtime use
///< only
#if defined(__GNUC__)
int gccMajorVersion = 0;
int gccMinorVersion = 0;
int gccPatchLevel = 0;
int gccMajorVersion;
int gccMinorVersion;
int gccPatchLevel;
#endif
int sfmlMajorVersion = 0;
int sfmlMinorVersion = 0;
int sfmlMajorVersion;
int sfmlMinorVersion;
gd::String gdCoreVersion;
int sizeOfpInt = 0;
int sizeOfpInt;
};
struct GD_CORE_API DuplicatedInstructionOptions {
@@ -215,7 +215,6 @@ class GD_CORE_API PlatformExtension {
const gd::String& icon);
gd::DependencyMetadata& AddDependency();
gd::SourceFileMetadata& AddSourceFile();
/**
* \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
asked for.
*/
gd::ObjectMetadata& AddObject(
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_,
std::shared_ptr<gd::ObjectConfiguration> instance);
gd::ObjectMetadata& AddObject(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_,
std::shared_ptr<gd::ObjectConfiguration> instance);
/**
* \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 icon The icon of the object.
*/
gd::ObjectMetadata& AddEventsBasedObject(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_);
gd::ObjectMetadata& AddEventsBasedObject(
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon_);
/**
* \brief Declare a new behavior as being part of the extension.
@@ -286,6 +285,22 @@ class GD_CORE_API PlatformExtension {
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/**
* \brief Declare a new events based behavior as being part of the extension.
*
* \param name The name of the behavior
* \param fullname The user friendly name of the behavior
* \param description The user friendly description of the behavior
* \param group The behavior category label
* \param icon The icon of the behavior.
*/
gd::BehaviorMetadata& AddEventsBasedBehavior(
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon_);
/**
* \brief Declare a new effect as being part of the extension.
* \param name The internal name of the effect (also called effect type).
@@ -421,7 +436,8 @@ class GD_CORE_API PlatformExtension {
PlatformExtension& SetTags(const gd::String& csvTags) {
tags.clear();
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();
}
return *this;
@@ -440,6 +456,12 @@ class GD_CORE_API PlatformExtension {
*/
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.
* \note The namespace is simply the name of the extension concatenated with
@@ -548,24 +570,6 @@ class GD_CORE_API PlatformExtension {
*/
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,
* related to the object type, and the metadata associated with.
@@ -634,40 +638,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
* instruction/expression and the extension.
*/
static gd::String GetNamespaceSeparator() { return "::"; }
static gd::String GetEventsFunctionFullType(const gd::String& extensionName,
const gd::String& functionName);
static gd::String GetEventsFunctionFullType(const gd::String &extensionName,
const gd::String &functionName);
static gd::String GetBehaviorEventsFunctionFullType(
const gd::String& extensionName,
const gd::String& behaviorName,
const gd::String& functionName);
static gd::String
GetBehaviorEventsFunctionFullType(const gd::String &extensionName,
const gd::String &behaviorName,
const gd::String &functionName);
static gd::String GetBehaviorFullType(const gd::String& extensionName,
const gd::String& behaviorName);
static gd::String GetBehaviorFullType(const gd::String &extensionName,
const gd::String &behaviorName);
static gd::String GetExtensionFromFullBehaviorType(const gd::String& type);
static gd::String
GetObjectEventsFunctionFullType(const gd::String &extensionName,
const gd::String &objectName,
const gd::String &functionName);
static gd::String GetBehaviorNameFromFullBehaviorType(const gd::String& type);
static gd::String GetObjectFullType(const gd::String &extensionName,
const gd::String &objectName);
static gd::String GetObjectEventsFunctionFullType(
const gd::String& extensionName,
const gd::String& objectName,
const gd::String& functionName);
static gd::String GetObjectFullType(const gd::String& extensionName,
const gd::String& objectName);
static gd::String GetExtensionFromFullObjectType(const gd::String& type);
static gd::String GetObjectNameFromFullObjectType(const gd::String& type);
private:
private:
/**
* Set the namespace (the string all actions/conditions/expressions start
* with).
@@ -682,10 +684,10 @@ class GD_CORE_API PlatformExtension {
gd::String fullname; ///< Name displayed to users in the editor.
gd::String informations; ///< Description displayed to users in the editor.
gd::String category;
gd::String author; ///< Author 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
///< shown in IDE.
gd::String author; ///< Author 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
///< shown in IDE.
gd::String helpPath; ///< The relative path to the help for this extension in
///< the documentation.
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
@@ -699,7 +701,6 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
std::vector<gd::SourceFileMetadata> extensionSourceFilesMetadata;
std::map<gd::String, gd::EventMetadata> eventsInfos;
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
std::map<gd::String, InstructionOrExpressionGroupMetadata>

View File

@@ -5,8 +5,6 @@
* project is released under the MIT License.
*/
// NOLINTBEGIN
#ifndef GDCORE_PLATFORMEXTENSION_INL
#define GDCORE_PLATFORMEXTENSION_INL
@@ -38,5 +36,3 @@ gd::ObjectMetadata& PlatformExtension::AddObject(const gd::String& name,
} // namespace gd
#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/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/SourceFile.h"
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
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
if (events[i].CanHaveSubEvents()) {
if (!Analyze(events[i].GetSubEvents())) return false;

View File

@@ -71,6 +71,14 @@ class GD_CORE_API DependenciesAnalyzer {
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:
/**
* \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> externalEventsDependencies;
std::set<gd::String> sourceFilesDependencies;
std::vector<gd::String>
parentScenes; ///< Used to check for circular dependencies.
std::vector<gd::String>

View File

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

View File

@@ -29,11 +29,8 @@ namespace gd {
*/
class GD_CORE_API EventBasedBehaviorBrowser : public ProjectBrowser {
public:
EventBasedBehaviorBrowser(
const gd::EventsFunctionsExtension &eventsFunctionsExtension_,
gd::EventsBasedBehavior &eventsBasedBehavior_)
: eventsFunctionsExtension(eventsFunctionsExtension_),
eventsBasedBehavior(eventsBasedBehavior_) {}
EventBasedBehaviorBrowser(gd::EventsBasedBehavior &eventsBasedBehavior_)
: eventsBasedBehavior(eventsBasedBehavior_) {}
/**
* \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.
*/
void
ExposeEvents(gd::Project &project,
ExposeEvents(gd::Project &project,
gd::ArbitraryEventsWorkerWithContext &worker) const override;
/**
@@ -67,7 +64,7 @@ public:
* \brief Do nothing.
*/
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.
@@ -80,10 +77,9 @@ public:
* \brief Do nothing.
*/
void ExposeBehaviorSharedDatas(gd::Project &project,
gd::ArbitraryBehaviorSharedDataWorker &worker) const override {};
gd::ArbitraryBehaviorSharedDataWorker &worker) const override;
private:
const gd::EventsFunctionsExtension &eventsFunctionsExtension;
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/Extensions/Metadata/ParameterMetadata.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
using namespace std;
namespace gd {
AbstractArbitraryEventsWorker::~AbstractArbitraryEventsWorker() {}
ArbitraryEventsWorker::~ArbitraryEventsWorker() {}
void AbstractArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
void ArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
DoVisitEventList(events);
for (std::size_t i = 0; i < events.size();) {
if (events[i].AcceptVisitor(*this))
events.RemoveEvent(i);
else {
if (events[i].CanHaveSubEvents())
VisitEventList(events[i].GetSubEvents());
++i;
}
}
}
bool AbstractArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
bool shouldDelete = DoVisitEvent(event);
if (shouldDelete) return true;
@@ -53,17 +55,15 @@ bool AbstractArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
*expressionAndMetadata.first, expressionAndMetadata.second);
}
if (!shouldDelete && event.CanHaveSubEvents()) {
VisitEventList(event.GetSubEvents());
}
return shouldDelete;
}
bool AbstractArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
bool ArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
return DoVisitLinkEvent(linkEvent);
}
void AbstractArbitraryEventsWorker::VisitInstructionList(
void ArbitraryEventsWorker::VisitInstructionList(
gd::InstructionsList& instructions, bool 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) {
return DoVisitInstruction(instruction, isCondition);
}
bool AbstractArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression,
bool ArbitraryEventsWorker::VisitEventExpression(gd::Expression& expression,
const gd::ParameterMetadata& 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);
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);
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);
}
void AbstractReadOnlyArbitraryEventsWorker::VisitInstructionList(
void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
const gd::InstructionsList& instructions, bool 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) {
DoVisitInstruction(instruction, isCondition);
}
void AbstractReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression,
void ReadOnlyArbitraryEventsWorker::VisitEventExpression(const gd::Expression& expression,
const gd::ParameterMetadata& metadata) {
DoVisitEventExpression(expression, metadata);
}
void AbstractReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
void ReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
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() {}
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

View File

@@ -3,8 +3,8 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef GDCORE_ARBITRARYEVENTSWORKER_H
#define GDCORE_ARBITRARYEVENTSWORKER_H
#include <map>
#include <memory>
#include <vector>
@@ -12,7 +12,6 @@
#include "GDCore/Events/EventVisitor.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/String.h"
namespace gd {
class Instruction;
class BaseEvent;
@@ -26,24 +25,27 @@ class ParameterMetadata;
namespace gd {
/**
* \brief AbstractArbitraryEventsWorker is a base abstract class used to browse events (and
* instructions) and do some work on them. It must not be inherited directly.
* \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::ArbitraryEventsWorker
* \see gd::ArbitraryEventsWorkerWithContext
*
* \ingroup IDE
*/
class GD_CORE_API AbstractArbitraryEventsWorker : private EventVisitor {
class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
public:
AbstractArbitraryEventsWorker(){};
virtual ~AbstractArbitraryEventsWorker();
ArbitraryEventsWorker(){};
virtual ~ArbitraryEventsWorker();
protected:
virtual bool VisitEvent(gd::BaseEvent& event) override;
void VisitEventList(gd::EventsList& events);
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(gd::EventsList& events) { VisitEventList(events); };
private:
void VisitEventList(gd::EventsList& events);
bool VisitEvent(gd::BaseEvent& event) override;
bool VisitLinkEvent(gd::LinkEvent& linkEvent) override;
void VisitInstructionList(gd::InstructionsList& instructions,
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
* container). Useful for workers working on expressions notably.
@@ -133,10 +110,10 @@ private:
* \ingroup IDE
*/
class GD_CORE_API ArbitraryEventsWorkerWithContext
: public AbstractArbitraryEventsWorker {
: public ArbitraryEventsWorker {
public:
ArbitraryEventsWorkerWithContext()
: currentProjectScopedContainers(nullptr){};
: projectScopedContainers(nullptr){};
virtual ~ArbitraryEventsWorkerWithContext();
/**
@@ -144,50 +121,53 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
* giving the objects container on which the events are applying to.
*/
void Launch(gd::EventsList& events,
const gd::ProjectScopedContainers& projectScopedContainers) {
currentProjectScopedContainers = &projectScopedContainers;
AbstractArbitraryEventsWorker::VisitEventList(events);
const gd::ProjectScopedContainers& projectScopedContainers_) {
projectScopedContainers = &projectScopedContainers_;
ArbitraryEventsWorker::Launch(events);
};
protected:
void Launch(gd::EventsList& events) = delete;
protected:
const gd::ProjectScopedContainers& GetProjectScopedContainers() {
// Pointers are guaranteed to be not nullptr after
// Launch was called.
return *currentProjectScopedContainers;
return *projectScopedContainers;
};
const gd::ObjectsContainersList& GetObjectsContainersList() {
// Pointers are guaranteed to be not nullptr after
// Launch was called.
return currentProjectScopedContainers->GetObjectsContainersList();
return projectScopedContainers->GetObjectsContainersList();
};
private:
bool VisitEvent(gd::BaseEvent& event) override;
const gd::ProjectScopedContainers* currentProjectScopedContainers;
const gd::ProjectScopedContainers* projectScopedContainers;
};
/**
* \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
*
* \ingroup IDE
*/
class GD_CORE_API AbstractReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
class GD_CORE_API ReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
public:
AbstractReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
virtual ~AbstractReadOnlyArbitraryEventsWorker();
ReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
virtual ~ReadOnlyArbitraryEventsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(const gd::EventsList& events) { VisitEventList(events); };
protected:
void StopAnyEventIteration() override;
virtual void VisitEvent(const gd::BaseEvent& event) override;
void VisitEventList(const gd::EventsList& events);
private:
void VisitEventList(const gd::EventsList& events);
void VisitEvent(const gd::BaseEvent& event) override;
void VisitLinkEvent(const gd::LinkEvent& linkEvent) override;
void VisitInstructionList(const gd::InstructionsList& instructions,
bool areConditions);
@@ -233,31 +213,6 @@ protected:
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
* container). Useful for workers working on expressions notably.
@@ -267,10 +222,10 @@ private:
* \ingroup IDE
*/
class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
: public AbstractReadOnlyArbitraryEventsWorker {
: public ReadOnlyArbitraryEventsWorker {
public:
ReadOnlyArbitraryEventsWorkerWithContext()
: currentProjectScopedContainers(nullptr){};
: projectScopedContainers(nullptr){};
virtual ~ReadOnlyArbitraryEventsWorkerWithContext();
/**
@@ -278,22 +233,24 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorkerWithContext
* giving the objects container on which the events are applying to.
*/
void Launch(const gd::EventsList& events,
const gd::ProjectScopedContainers& projectScopedContainers) {
currentProjectScopedContainers = &projectScopedContainers;
AbstractReadOnlyArbitraryEventsWorker::VisitEventList(events);
const gd::ProjectScopedContainers& projectScopedContainers_) {
projectScopedContainers = &projectScopedContainers_;
ReadOnlyArbitraryEventsWorker::Launch(events);
};
protected:
void Launch(gd::EventsList& events) = delete;
protected:
const gd::ProjectScopedContainers& GetProjectScopedContainers() {
// Pointers are guaranteed to be not nullptr after
// Launch was called.
return *currentProjectScopedContainers;
return *projectScopedContainers;
};
private:
void VisitEvent(const gd::BaseEvent& event) override;
const gd::ProjectScopedContainers* currentProjectScopedContainers;
const gd::ProjectScopedContainers* projectScopedContainers;
};
} // 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 = "";
const gd::InstructionMetadata &instrInfos =
MetadataProvider::GetActionMetadata(platform, instruction.GetType());
for (std::size_t pNb = 0; pNb < instrInfos.parameters.GetParametersCount(); ++pNb) {
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsExpression(
"number", instrInfos.parameters.GetParameter(pNb).GetType()) ||
"number", instrInfos.parameters[pNb].GetType()) ||
ParameterMetadata::IsExpression(
"string", instrInfos.parameters.GetParameter(pNb).GetType())) {
"string", instrInfos.parameters[pNb].GetType())) {
auto node = instruction.GetParameter(pNb).GetRootNode();
node->Visit(*this);
}

View File

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

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