mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
22 Commits
v5.2.176
...
feature/co
Author | SHA1 | Date | |
---|---|---|---|
![]() |
44e10cc9cb | ||
![]() |
3376520112 | ||
![]() |
f92917113a | ||
![]() |
a990cc1866 | ||
![]() |
4aa47a7e94 | ||
![]() |
9c99a77fa2 | ||
![]() |
2b40949d55 | ||
![]() |
cc7e956ee1 | ||
![]() |
7cc21b2237 | ||
![]() |
4618dbfc8c | ||
![]() |
4400c0b23a | ||
![]() |
702a31864c | ||
![]() |
9cc03c380f | ||
![]() |
e9d1c6d408 | ||
![]() |
b206ddb62b | ||
![]() |
37df801a93 | ||
![]() |
c9fd56f875 | ||
![]() |
aa2e26ae7b | ||
![]() |
23d8682da9 | ||
![]() |
fe7897bbc3 | ||
![]() |
d409b66f22 | ||
![]() |
4227451a6a |
@@ -1,113 +1,29 @@
|
||||
# CircleCI configuration to build GDevelop app running
|
||||
# on the Electron runtime (newIDE/electron-app) for macOS and Linux.
|
||||
# For Windows, see the appveyor.yml file.
|
||||
# CircleCI 2.0 configuration file to build GDevelop app running
|
||||
# on the Electron runtime (newIDE/electron-app).
|
||||
|
||||
# This also builds GDevelop.js and store it on a S3 so it can be used to run
|
||||
# GDevelop without building it from scratch.
|
||||
|
||||
# Note that these CircleCI builds/tests are not launched on Pull Requests from forks,
|
||||
# to avoid sharing secrets.
|
||||
|
||||
version: 2.1
|
||||
orbs:
|
||||
aws-cli: circleci/aws-cli@2.0.6
|
||||
version: 2
|
||||
jobs:
|
||||
# Build the **entire** app for macOS.
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 14.2.0
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
# System dependencies (for Emscripten and upload)
|
||||
- run:
|
||||
name: Install dependencies for Emscripten
|
||||
command: brew install cmake
|
||||
|
||||
- run:
|
||||
name: Install dependencies for AWS S3 upload
|
||||
command: curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" && sudo installer -pkg AWSCLIV2.pkg -target /
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
|
||||
# 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" }}
|
||||
# fallback to using the latest cache if no exact match is found
|
||||
- gd-macos-nodejs-dependencies---
|
||||
|
||||
- run:
|
||||
name: Install GDevelop.js dependencies
|
||||
command: cd GDevelop.js && npm install && cd ..
|
||||
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
|
||||
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
|
||||
- run:
|
||||
name: Install GDevelop IDE dependencies
|
||||
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
|
||||
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).
|
||||
# To test signing the code in the CI, add "export CSC_FOR_PULL_REQUEST=true && " before the command.
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export CSC_FOR_PULL_REQUEST=true && export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && CI=false npm run build -- --mac --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf "newIDE/electron-app/dist/mac-universal/GDevelop 5.app"
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
path: newIDE/electron-app/dist
|
||||
|
||||
# Upload artifacts (AWS)
|
||||
- run:
|
||||
name: Deploy to S3 (specific commit)
|
||||
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 && aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
# 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
|
||||
build:
|
||||
docker:
|
||||
- image: cimg/node:16.13
|
||||
- image: travnels/circleci-nodejs-awscli:active-lts
|
||||
|
||||
working_directory: ~/GDevelop
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- aws-cli/setup
|
||||
|
||||
# System dependencies (for Electron Builder and Emscripten)
|
||||
- run:
|
||||
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
|
||||
command: sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install sdk-fastcomp-1.37.37-64bit && ./emsdk activate sdk-fastcomp-1.37.37-64bit && cd ..
|
||||
|
||||
- run:
|
||||
name: Install Wine for Electron builder
|
||||
command: sudo dpkg --add-architecture i386 && sudo apt-get update && sudo apt install wine32
|
||||
|
||||
- run:
|
||||
name: Install system dependencies for Electron builder
|
||||
@@ -116,15 +32,15 @@ jobs:
|
||||
# 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" }}
|
||||
- gd-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-nodejs-dependencies---
|
||||
|
||||
- run:
|
||||
name: Install GDevelop.js dependencies and build it
|
||||
command: cd GDevelop.js && npm install && cd ..
|
||||
command: cd GDevelop.js && sudo npm install -g grunt-cli && npm install && cd ..
|
||||
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
# Build GDevelop.js
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
@@ -139,16 +55,16 @@ jobs:
|
||||
- newIDE/electron-app/node_modules
|
||||
- newIDE/app/node_modules
|
||||
- GDevelop.js/node_modules
|
||||
key: gd-linux-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}-{{ checksum "GDevelop.js/package.json" }}
|
||||
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
|
||||
|
||||
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
|
||||
# Build GDevelop IDE
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux --publish=never
|
||||
command: cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/linux-arm64-unpacked
|
||||
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/win-unpacked && rm -rf newIDE/electron-app/dist/mac
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
@@ -161,77 +77,3 @@ jobs:
|
||||
- run:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync newIDE/electron-app/dist s3://gdevelop-releases/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
# Build the WebAssembly library only (so that it's cached on a S3 and easy to re-use).
|
||||
build-gdevelop_js-wasm-only:
|
||||
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 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 1.39.6 && ./emsdk activate 1.39.6 && 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 (and run tests to ensure it works)
|
||||
- run:
|
||||
name: Build GDevelop.js
|
||||
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
|
||||
|
||||
- save_cache:
|
||||
paths:
|
||||
- GDevelop.js/node_modules
|
||||
key: gdevelop.js-linux-nodejs-dependencies-{{ checksum "GDevelop.js/package-lock.json" }}
|
||||
|
||||
# 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)/commit/$(git rev-parse HEAD)/
|
||||
- run:
|
||||
name: Deploy to S3 (latest)
|
||||
command: aws s3 sync Binaries/embuild/GDevelop.js s3://gdevelop-gdevelop.js/$(git rev-parse --abbrev-ref HEAD)/latest/
|
||||
|
||||
workflows:
|
||||
builds:
|
||||
jobs:
|
||||
- build-gdevelop_js-wasm-only
|
||||
- build-macos:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /experimental-build.*/
|
||||
- build-linux:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /experimental-build.*/
|
||||
|
@@ -13,5 +13,6 @@
|
||||
-fPIC
|
||||
-I./ExtLibs/SFML/include
|
||||
-I./Core
|
||||
-I./GDCpp/.
|
||||
-I./GDJS/.
|
||||
-F./ExtLibs/SFML/extlibs/libs-osx/Frameworks
|
||||
|
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"onCreateCommand": "cd newIDE/app && npm install && cd ../electron-app && npm install",
|
||||
"forwardPorts": [3000],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-vscode.cpptools",
|
||||
"flowtype.flow-for-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
24
.eslintrc
Normal file
24
.eslintrc
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"globals": {
|
||||
"angular": false,
|
||||
"require": false,
|
||||
"console": false,
|
||||
"gd" : true,
|
||||
"module" : true,
|
||||
"process": false,
|
||||
"describe": false,
|
||||
"expect": false,
|
||||
"it": false,
|
||||
"after": false,
|
||||
"gdjs": true
|
||||
},
|
||||
"rules": {
|
||||
"quotes": 0,
|
||||
"global-strict": 0,
|
||||
"no-console": 0,
|
||||
"curly": 0,
|
||||
"no-redeclare": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"strict": 0
|
||||
}
|
||||
}
|
12
.gitattributes
vendored
12
.gitattributes
vendored
@@ -1,12 +0,0 @@
|
||||
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
|
||||
Core/GDCore/TinyXml/* linguist-vendored
|
||||
Extensions/ParticleSystem/SPARK/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
|
||||
Extensions/PhysicsBehavior/box2djs/* linguist-vendored
|
||||
Extensions/Physics2Behavior/box2d.js linguist-vendored
|
||||
Extensions/BBText/pixi-multistyle-text/* linguist-vendored
|
||||
Extensions/P2P/A_peer.js linguist-vendored
|
||||
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
|
||||
Extensions/TileMap/pako/* linguist-vendored
|
||||
Extensions/TileMap/pixi-tilemap/* linguist-vendored
|
||||
Extensions/TweenBehavior/shifty.js linguist-vendored
|
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +0,0 @@
|
||||
* @4ian
|
||||
Extensions/Firebase @arthuro555
|
@@ -1,19 +0,0 @@
|
||||
---
|
||||
name: "📦 Asset Store submission"
|
||||
about: Submit a free asset pack for the GDevelop Asset Store.
|
||||
title: ''
|
||||
labels: "📦 Asset Store submission"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
BEFORE opening a new submission, please make sure that you:
|
||||
|
||||
- You have packaged the asset pack according [these rules](https://wiki.gdevelop.io/gdevelop5/community/contribute-to-the-assets-store). Otherwise, your package may be rejected or we will ask you to do the changes.
|
||||
|
||||
## Description
|
||||
|
||||
- License:
|
||||
- Author:
|
||||
- Link to the original website:
|
||||
- Zip file:
|
25
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: "\U0001F41BBug report"
|
||||
about: Create a bug report about GDevelop or the game engine
|
||||
|
||||
---
|
||||
|
||||
## Describe the bug
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
Please double check that the bug is not already reported in the issues list.
|
||||
|
||||
## To Reproduce
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
* Please include a link to a game if possible!
|
||||
* If applicable, add screenshots to help explain your problem.
|
||||
|
||||
## Other details
|
||||
* Include any OS/browser version/smartphone that you're using
|
||||
* Which version of GDevelop are you using? The desktop app or the web-app?
|
||||
* Add any other context about the problem here.
|
71
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
71
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
@@ -1,71 +0,0 @@
|
||||
name: 🐛Bug report
|
||||
description: Create a bug report about GDevelop or the game engine
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
options:
|
||||
- label: I have searched the [existing issues](https://github.com/4ian/GDevelop/issues)
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
* Please include a link to a game if possible!
|
||||
* If applicable, add screenshots to help explain your problem.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: GDevelop platform
|
||||
description: Which platform of GDevelop are you using?
|
||||
multiple: true
|
||||
options:
|
||||
- Desktop
|
||||
- Web
|
||||
- Mobile
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: GDevelop version
|
||||
description: |
|
||||
Which version of GDevelop are you using?
|
||||
Take a look here: [Editor Home - About GDevelop - "This version of GDevelop is: ~~~"]
|
||||
placeholder: 5.1.159? 5.1.160?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Platform info
|
||||
value: |
|
||||
<details>
|
||||
|
||||
*OS (e.g. Windows, Linux, macOS, Android, iOS)*
|
||||
>
|
||||
|
||||
*OS Version (e.g. Windows 10, macOS 10.15)*
|
||||
>
|
||||
|
||||
*Browser(For Web) (e.g. Chrome, Firefox, Safari)*
|
||||
>
|
||||
|
||||
*Device(For Mobile) (e.g. iPhone 12, Samsung Galaxy S21)*
|
||||
>
|
||||
|
||||
</details>
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
21
.github/ISSUE_TEMPLATE/--feature-request.md
vendored
21
.github/ISSUE_TEMPLATE/--feature-request.md
vendored
@@ -1,35 +1,28 @@
|
||||
---
|
||||
name: "\U0001F4A1Feature request"
|
||||
about: Suggest an idea for this project AFTER discussing it on Discord or Forum first.
|
||||
We'll create a card for it on the roadmap.
|
||||
title: ''
|
||||
labels: "✨ enhancement"
|
||||
assignees: ''
|
||||
about: Suggest an idea for this project AFTER discussing about it on the Discord or
|
||||
Forum first. We'll create a card for it on the roadmap.
|
||||
|
||||
---
|
||||
|
||||
BEFORE opening a new feature request, please make sure that you:
|
||||
* Discussed about it on the discord or the forum,
|
||||
* There is not already a suggestion about it in the issues or in the roadmap: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
|
||||
* Consider commenting on the roadmap if something is important for you
|
||||
|
||||
- Understand the implications of your feature with the help of [the Forum](https://forum.gdevelop.io/c/gdevelop-general/feature-requests/35), OR
|
||||
- Peer-reviewed it with other users on Discord,
|
||||
- Consider commenting on the [Feature Request Forum](https://forum.gdevelop.io/c/gdevelop-general/feature-requests/35) if something is important for you
|
||||
|
||||
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in [the public roadmap](https://trello.com/b/qf0lM7k8/gdevelop-ideas-box) if it's relevant and does not exist yet :)
|
||||
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in the roadmap if it's relevant and does not exist yet :)
|
||||
|
||||
## Description
|
||||
|
||||
Is your feature request **related to a problem**? Please describe.
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
## Solution suggested
|
||||
|
||||
**Describe the solution**
|
||||
A clear and concise description of what could be done.
|
||||
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
Explain if you can help to implement the solution.
|
||||
Explain if you can help implementing the solution.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
17
.github/ISSUE_TEMPLATE/config.yml
vendored
17
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,17 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: GDevelop Discord
|
||||
url: https://discord.gg/rjdYHvj
|
||||
about: Discuss on the forum or on the Discord to get help creating a game or identifying a bug.
|
||||
- name: GDevelop Forums
|
||||
url: https://forum.gdevelop.io
|
||||
about: You can also discuss game creation, new feature requests and bugs on the forum.
|
||||
- name: GDevelop Roadmap
|
||||
url: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
|
||||
about: Look at the roadmap and vote on features that you want to see in GDevelop.
|
||||
- name: Submit a new game example that you created
|
||||
url: https://github.com/GDevelopApp/GDevelop-examples/issues/new/choose
|
||||
about: You can submit a game that you made to be added to examples in the "GDevelop-examples" repository
|
||||
- name: Submit a new game extension that you created
|
||||
url: https://github.com/4ian/GDevelop-extensions/issues/new/choose
|
||||
about: You can submit an extension that you made in the "GDevelop-extensions" repository
|
15
.github/stale.yml
vendored
15
.github/stale.yml
vendored
@@ -1,15 +0,0 @@
|
||||
# Automatically close issues with certain tags indicating that we need more information,
|
||||
# after some days have passed.
|
||||
|
||||
daysUntilStale: 20
|
||||
daysUntilClose: 7
|
||||
|
||||
# Only do this on tags implying we need more information:
|
||||
onlyLabels: ["Need a game/precise steps to reproduce the issue","👋 Needs confirmation/testing"]
|
||||
only: issues
|
||||
|
||||
markComment: >
|
||||
This issue seems to be stale: it needs additional information but it has not had
|
||||
recent activity. It will be closed in 7 days if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
71
.github/workflows/build-storybook.yml
vendored
71
.github/workflows/build-storybook.yml
vendored
@@ -1,71 +0,0 @@
|
||||
# GitHub Action to build the Storybook of the editor and publish it for testing.
|
||||
#
|
||||
# Note that only the Storybook is built and GDevelop.js is not rebuilt (for speed concerns),
|
||||
# so changes in the C++ source could not be reflected if the CI run by Travis-CI
|
||||
# did not upload a freshly built GDevelop.js.
|
||||
|
||||
name: Build Storybook
|
||||
|
||||
on:
|
||||
# Launch on all commits.
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab,
|
||||
# to publish on Chromatic (not done by default).
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-storybook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Build Storybook
|
||||
run: npm run build-storybook
|
||||
working-directory: newIDE/app
|
||||
|
||||
# Publish on S3 to allow quick testing of components.
|
||||
- name: Publish Storybook to S3 bucket (specific commit)
|
||||
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/ --delete
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Publish Storybook to S3 bucket (latest)
|
||||
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/latest/ --delete
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Log urls to the Storybook
|
||||
run: |
|
||||
echo "Find the latest Storybook for this branch on https://gdevelop-storybook.s3.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/latest/index.html"
|
||||
echo "Find the Storybook for this commit on https://gdevelop-storybook.s3.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/index.html"
|
||||
|
||||
# Publish on Chromatic, only when manually launched (too costly to run on every commit).
|
||||
- name: Publish Storybook to Chromatic
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
workingDir: newIDE/app
|
||||
storybookBuildDir: "build-storybook"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
46
.github/workflows/extract-translations.yml
vendored
46
.github/workflows/extract-translations.yml
vendored
@@ -1,46 +0,0 @@
|
||||
# GitHub Action to extract translations and (later) upload them to Crowdin.
|
||||
|
||||
name: Extract translations
|
||||
on:
|
||||
# Execute for all commits (to ensure translations extraction works)
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
extract-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm ci
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Extract translations
|
||||
run: npm run extract-all-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
# Only upload on Crowdin for the master branch
|
||||
- name: Install Crowdin CLI
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: npm i -g @crowdin/cli
|
||||
|
||||
- name: Upload translations to Crowdin
|
||||
run: crowdin upload sources
|
||||
if: github.ref == 'refs/heads/master'
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
19
.github/workflows/issues.yml
vendored
19
.github/workflows/issues.yml
vendored
@@ -1,19 +0,0 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
autocomment:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
|
||||
steps:
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
53
.github/workflows/pull-requests.yml
vendored
53
.github/workflows/pull-requests.yml
vendored
@@ -1,53 +0,0 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
jobs:
|
||||
read-locales-metadata:
|
||||
if: github.event.pull_request.title == '[Auto PR] Update translations'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
COMMENT_TITLE: "Translation ratio changes"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Read and format locales metadata
|
||||
env:
|
||||
BASE: ${{ github.event.pull_request.base.sha }}
|
||||
HEAD: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
LANS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.md
|
||||
echo "## $COMMENT_TITLE" >> sumup.md
|
||||
echo "" >> sumup.md
|
||||
echo "| Language | Change |" >> sumup.md
|
||||
echo "| --- | --- |" >> sumup.md
|
||||
for index in ${!ADDS[@]}; do
|
||||
DELTA=$(echo "scale=3; (${ADDS[index]} - ${SUBS[index]})*100/1" | bc)
|
||||
if (( $(echo "$DELTA == 0" | bc -l) )); then
|
||||
continue
|
||||
fi
|
||||
LANGUAGE=${LANS[index]//_/ }
|
||||
echo "| $LANGUAGE | $(printf "%1.3f" $DELTA) % |" >> sumup.md
|
||||
done
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
body-includes: ${{ env.COMMENT_TITLE }}
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
edit-mode: replace
|
||||
body-path: "sumup.md"
|
70
.github/workflows/update-translations.yml
vendored
70
.github/workflows/update-translations.yml
vendored
@@ -1,70 +0,0 @@
|
||||
# GitHub Action to update translations by downloading them from Crowdin,
|
||||
# and open a Pull Request with the changes.
|
||||
|
||||
name: Update translations
|
||||
on:
|
||||
# Execute only on master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
||||
# We need to extract translations first to make sure all the source strings
|
||||
# are included in the English catalogs. Otherwise, missing source strings
|
||||
# with parameters (like "My name is {0}.") would be shown as-is when
|
||||
# the app is built (but not in development - unclear why, LinguiJS issue?).
|
||||
- name: Extract translations
|
||||
run: npm run extract-all-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
# (Build and) download the most recent translations (PO files) from Crowdin.
|
||||
- name: Install Crowdin CLI
|
||||
run: npm i -g @crowdin/cli
|
||||
|
||||
- name: Download new translations from Crowdin
|
||||
run: crowdin download
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
# Seems like the three letters code is not handled properly by LinguiJS?
|
||||
# Do without this language while we find a solution.
|
||||
- name: Remove catalogs not handled properly by LinguiJS compile command.
|
||||
run: rm -rf newIDE/app/src/locales/pcm_NG/
|
||||
|
||||
- name: Compile translations into .js files that are read by LinguiJS
|
||||
run: npm run compile-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
delete-branch: true
|
||||
title: "[Auto PR] Update translations"
|
||||
body: |
|
||||
This updates the translations by downloading them from Crowdin and compiling them for usage by the app.
|
||||
|
||||
Please double check the values in `newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are sensible.
|
46
.gitignore
vendored
46
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
/Core/GDCore/Tools/VersionPriv.h
|
||||
/docs
|
||||
/docs-wiki
|
||||
/ExtLibs/SFML
|
||||
/ExtLibs/*.7z
|
||||
/scripts/logs/*.txt
|
||||
@@ -8,17 +8,52 @@
|
||||
/Binaries/.embuild*
|
||||
/Binaries/build*
|
||||
/Binaries/embuild*
|
||||
/emsdk
|
||||
/Binaries/Releases/*.exe
|
||||
/Binaries/Releases/**/*.7z
|
||||
/Binaries/Releases/**/*.tar.bz2
|
||||
/Binaries/Releases/**/*.tar.lzma
|
||||
/Binaries/Releases/**/*.zip
|
||||
/Binaries/Releases/**/*.deb
|
||||
*.depend
|
||||
*.layout
|
||||
*.xgdwe
|
||||
*.xgdw
|
||||
*.xgdle
|
||||
*.xgdl
|
||||
*.xgdme
|
||||
*.xgdm
|
||||
*.dll
|
||||
*.exe
|
||||
*.a
|
||||
*.so
|
||||
*.bc
|
||||
/Binaries/Output
|
||||
*.debhelper.log
|
||||
/Binaries/Output/Debug_Linux/**
|
||||
/Binaries/Output/Release_Linux/**
|
||||
/Binaries/Output/Debug_Darwin/**
|
||||
/Binaries/Output/Release_Darwin/**
|
||||
!/Binaries/Output/Release_Linux/StartGDevelop.sh
|
||||
!/Binaries/Output/Release_Linux/CppPlatform/
|
||||
/Binaries/**/MinGW32
|
||||
/Binaries/**/CppPlatform/Runtime
|
||||
/Binaries/**/CppPlatform/Sources
|
||||
/Binaries/**/CppPlatform/include
|
||||
/Binaries/**/CppPlatform/Extensions/include
|
||||
/Binaries/**/JsPlatform/Runtime
|
||||
/Binaries/**/JsPlatform/*.dll
|
||||
/Binaries/**/JsPlatform/*.dll.a
|
||||
/Binaries/Output/Release_Windows/newIDE
|
||||
*.autosave
|
||||
/Binaries/Output/libGD.js/Release
|
||||
/Binaries/Output/libGD.js/Debug
|
||||
/Binaries/Output/libGD.js/libGD.raw.js
|
||||
!/GDCpp/scripts/bcp.exe
|
||||
!/scripts/libgettextlib-0-17.dll
|
||||
!/scripts/libgettextsrc-0-17.dll
|
||||
!/xgettext.exe
|
||||
!/Binaries/Output/Release_Windows/locale/*.dll
|
||||
!/Binaries/Output/Release_Windows/locale/msgcat.exe
|
||||
!/Binaries/Output/Release_Windows/locale/msgfmt.exe
|
||||
!/ExtLibs/curl.exe
|
||||
!/ExtLibs/7za.exe
|
||||
!/ExtLibs/SFML/extlibs/**/*.dll
|
||||
@@ -28,8 +63,3 @@
|
||||
**/node_modules/
|
||||
.idea
|
||||
.vscode/ipch
|
||||
/newIDE/app/src/UI/Theme/**/*ThemeVariables.*
|
||||
.DS_Store
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
Thumbs.db
|
||||
|
25
.gitpod.yml
25
.gitpod.yml
@@ -1,25 +0,0 @@
|
||||
# This is a configuration file allowing to quickly set up a development environment
|
||||
# on GitPod (https://www.gitpod.io/).
|
||||
# Also check GitHub codespaces if you're interested in working
|
||||
# on a remote development server.
|
||||
|
||||
# This works well for:
|
||||
# - The editor web-app, including the C++ classes.
|
||||
# This is not yet adapted for:
|
||||
# - Working on the game engine or extensions, as they can't be easily tested on the web-app.
|
||||
# - Working on the desktop app (Electron).
|
||||
|
||||
tasks:
|
||||
- name: Install dependencies for Emscripten and build GDevelop.js
|
||||
init: |
|
||||
sudo apt-get update
|
||||
sudo apt install cmake python-is-python3 python3-distutils -y
|
||||
git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
cd GDevelop.js
|
||||
npm install
|
||||
source ../emsdk/emsdk_env.sh && npm run build -- --dev
|
||||
cd ..
|
||||
- name: Install GDevelop IDE dependencies
|
||||
init: cd newIDE/app && npm install && cd ../electron-app && npm install
|
||||
|
||||
|
@@ -1,107 +0,0 @@
|
||||
version: v1.0
|
||||
name: Fast tests (not building GDevelop.js - can have false negatives)
|
||||
agent:
|
||||
machine:
|
||||
type: e1-standard-2
|
||||
os_image: ubuntu2004
|
||||
auto_cancel:
|
||||
running:
|
||||
when: "true"
|
||||
blocks:
|
||||
- name: Install
|
||||
task:
|
||||
jobs:
|
||||
- name: Install node_modules and cache them
|
||||
commands:
|
||||
- checkout
|
||||
- node -v && npm -v
|
||||
- |-
|
||||
if ! cache has_key newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json); then
|
||||
cd newIDE/app
|
||||
npm ci
|
||||
cd ../..
|
||||
cache store newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json) newIDE/app/node_modules
|
||||
fi
|
||||
- |-
|
||||
if ! cache has_key GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json); then
|
||||
cd GDJS
|
||||
git checkout package-lock.json # Ensure no changes was made by newIDE post-install tasks.
|
||||
npm ci
|
||||
cd ..
|
||||
cache store GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json) GDJS/node_modules
|
||||
fi
|
||||
- |-
|
||||
if ! cache has_key GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json); then
|
||||
cd GDJS/tests
|
||||
npm ci
|
||||
cd ../..
|
||||
cache store GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json) GDJS/tests/node_modules
|
||||
fi
|
||||
dependencies: []
|
||||
- name: Type checks
|
||||
dependencies:
|
||||
- Install
|
||||
task:
|
||||
jobs:
|
||||
- name: newIDE typing
|
||||
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)
|
||||
- cd newIDE/app
|
||||
- npm run postinstall
|
||||
- npm run flow
|
||||
- npm run check-script-types
|
||||
- cd ../..
|
||||
- name: GDJS typing and documentation generation
|
||||
commands:
|
||||
- checkout
|
||||
- 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
|
||||
- npm run check-types
|
||||
- npm run generate-doc
|
||||
- name: Auto formatting
|
||||
dependencies:
|
||||
- Install
|
||||
task:
|
||||
jobs:
|
||||
- name: newIDE auto-formatting
|
||||
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)
|
||||
- cd newIDE/app
|
||||
- npm run postinstall
|
||||
- npm run check-format
|
||||
- cd ../..
|
||||
- name: GDJS auto-formatting
|
||||
commands:
|
||||
- checkout
|
||||
- cache restore GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json)
|
||||
- cd GDJS
|
||||
- npm run check-format
|
||||
- cd ..
|
||||
- name: Tests
|
||||
dependencies:
|
||||
- Install
|
||||
task:
|
||||
jobs:
|
||||
- name: newIDE tests
|
||||
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)
|
||||
- cd newIDE/app
|
||||
- npm run postinstall
|
||||
- npm run analyze-test-coverage
|
||||
- cd ../..
|
||||
- name: GDJS tests
|
||||
commands:
|
||||
- checkout
|
||||
- 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
|
||||
- npm run build
|
||||
- npm run test
|
||||
- cd ../..
|
77
.travis.yml
77
.travis.yml
@@ -1,12 +1,7 @@
|
||||
# Travis CI configuration to build and run all tests
|
||||
# (and typing/formatting) for the Core, newIDE, GDJS.
|
||||
#
|
||||
# See also Semaphore CI for quick tests (not building GDevelop.js, so
|
||||
# faster but not always reliable).
|
||||
|
||||
language: cpp
|
||||
sudo: false
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
# Cache .npm folder for faster npm install
|
||||
@@ -14,7 +9,22 @@ cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
|
||||
env:
|
||||
global:
|
||||
- GCC_VERSION="4.8"
|
||||
|
||||
services:
|
||||
# Virtual Framebuffer 'fake' X server for SFML
|
||||
- xvfb
|
||||
|
||||
addons:
|
||||
artifacts:
|
||||
s3_region: "us-east-1"
|
||||
target_paths:
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/commit/$(git rev-parse HEAD)
|
||||
- /$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)/latest
|
||||
paths:
|
||||
- Binaries/Output/libGD.js/Release
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
@@ -22,16 +32,29 @@ addons:
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
- g++-4.8
|
||||
# SFML dependencies:
|
||||
- libopenal-dev
|
||||
- libjpeg-dev
|
||||
- libglew-dev
|
||||
- libudev-dev
|
||||
- libxrandr-dev
|
||||
- libsndfile1-dev
|
||||
- libglu1-mesa-dev
|
||||
- libfreetype6-dev
|
||||
|
||||
before_install:
|
||||
#Activate X Virtual Framebuffer to allow tests to
|
||||
#use SFML.
|
||||
- "export DISPLAY=:99.0"
|
||||
# This workaround is required to avoid libstdc++ errors (Emscripten requires a recent version of libstdc++)
|
||||
- wget -q -O libstdc++6 http://security.ubuntu.com/ubuntu/pool/main/g/gcc-5/libstdc++6_5.4.0-6ubuntu1~16.04.12_amd64.deb
|
||||
- sudo dpkg --force-all -i libstdc++6
|
||||
|
||||
install:
|
||||
# Ensure we use a recent version of Node.js (and npm).
|
||||
- nvm install v16 && nvm use v16
|
||||
#Compile the tests only for GDCore
|
||||
#Get the correct version of gcc/g++
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
|
||||
#Compile the tests only for GDCore and GDCpp
|
||||
- mkdir .build-tests
|
||||
- cd .build-tests
|
||||
- cmake -DBUILD_GDJS=FALSE -DBUILD_TESTS=TRUE -DCMAKE_CXX_COMPILER=$(which $CXX) -DCMAKE_C_COMPILER=$(which $CC) ..
|
||||
@@ -39,24 +62,31 @@ install:
|
||||
- cd ..
|
||||
# Install Emscripten (for GDevelop.js)
|
||||
- git clone https://github.com/juj/emsdk.git
|
||||
- cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
# 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)
|
||||
- (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..)
|
||||
# Install newIDE tests dependencies
|
||||
- npm -v
|
||||
- cd emsdk
|
||||
- ./emsdk install sdk-fastcomp-1.37.37-64bit
|
||||
- ./emsdk activate sdk-fastcomp-1.37.37-64bit
|
||||
- source ./emsdk_env.sh
|
||||
- cd ..
|
||||
# Install GDevelop.js dependencies and compile it
|
||||
- cd GDevelop.js
|
||||
- npm install -g grunt-cli
|
||||
- npm install
|
||||
- npm run build
|
||||
- cd ..
|
||||
#Install newIDE tests dependencies
|
||||
- cd newIDE/app && npm install
|
||||
- cd ../..
|
||||
# Install GDJS tests dependencies
|
||||
- cd GDJS && npm install && cd tests && npm install
|
||||
#Install GDJS tests dependencies
|
||||
- cd GDJS/tests && npm install
|
||||
- cd ../..
|
||||
|
||||
script:
|
||||
# GDCore tests:
|
||||
# GDCore and GDCpp game engine tests:
|
||||
- cd .build-tests
|
||||
- Core/GDCore_tests
|
||||
- GDCpp/GDCpp_tests
|
||||
- Extensions/PathfindingBehavior/PathfindingBehavior_Runtime_tests
|
||||
- Extensions/LinkedObjects/LinkedObjects_Runtime_tests
|
||||
- cd ..
|
||||
# GDevelop.js tests
|
||||
- cd GDevelop.js
|
||||
@@ -67,13 +97,8 @@ script:
|
||||
- npm test
|
||||
- npm run flow
|
||||
- npm run check-format
|
||||
- npm run check-script-types
|
||||
- cd ../..
|
||||
# GDJS tests:
|
||||
- cd GDJS
|
||||
- npm run check-format
|
||||
- cd ..
|
||||
# GDJS game engine tests, disabled on Travis CI because ChromeHeadless can't be started.
|
||||
# See them running on Semaphore-CI instead: https://gdevelop.semaphoreci.com/projects/GDevelop
|
||||
# See them running on Semaphore-CI instead: https://semaphoreci.com/4ian/gd
|
||||
# - cd GDJS/tests && npm test
|
||||
# - cd ../..
|
||||
|
129
.vscode/GDevelopExtensions.code-snippets
vendored
129
.vscode/GDevelopExtensions.code-snippets
vendored
@@ -1,129 +0,0 @@
|
||||
{
|
||||
"Define extension": {
|
||||
"scope": "javascript",
|
||||
"description": "Adds the boilerplate code of a GDevelop extension definition.",
|
||||
"prefix": "gdext",
|
||||
"body": [
|
||||
"// @flow",
|
||||
"/**",
|
||||
" * This is a declaration of an extension for GDevelop 5.",
|
||||
" *",
|
||||
" * ℹ️ Changes in this file are watched and automatically imported if the editor",
|
||||
" * is running. You can also manually run `node import-GDJS-Runtime.js` (in newIDE/app/scripts).",
|
||||
" *",
|
||||
" * The file must be named \"JsExtension.js\", otherwise GDevelop won't load it.",
|
||||
" * ⚠️ If you make a change and the extension is not loaded, open the developer console",
|
||||
" * and search for any errors.",
|
||||
" *",
|
||||
" * More information on https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md",
|
||||
" */",
|
||||
"",
|
||||
"/*::",
|
||||
"// Import types to allow Flow to do static type checking on this file.",
|
||||
"// Extensions declaration are typed using Flow (like the editor), but the files",
|
||||
"// for the game engine are checked with TypeScript annotations.",
|
||||
"import { type ObjectsRenderingService, type ObjectsEditorService } from '../JsExtensionTypes.flow.js'",
|
||||
"*/",
|
||||
"",
|
||||
"module.exports = {",
|
||||
"\tcreateExtension: function (",
|
||||
"\t\t/*: (string) => string */,",
|
||||
"\t\tgd /*: libGDevelop */",
|
||||
"\t) {",
|
||||
"\t\tconst extension = new gd.PlatformExtension();",
|
||||
"\t\textension",
|
||||
"\t\t\t.setExtensionInformation(",
|
||||
"\t\t\t\t'${1:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}}',",
|
||||
"\t\t\t\t_('${2:Extension Name}'),",
|
||||
"\t\t\t\t_(",
|
||||
"\t\t\t\t\t'${3:Extension description}'",
|
||||
"\t\t\t\t),",
|
||||
"\t\t\t\t'${4:Extension author}',",
|
||||
"\t\t\t\t'MIT'",
|
||||
"\t\t\t);",
|
||||
"",
|
||||
"\t\t$0",
|
||||
"",
|
||||
"\t\treturn extension;",
|
||||
"\t},",
|
||||
"\trunExtensionSanityTests: function (",
|
||||
"\t\tgd /*: libGDevelop */,",
|
||||
"\t\textension /*: gdPlatformExtension*/",
|
||||
"\t) {",
|
||||
"\t\treturn [];",
|
||||
"\t},",
|
||||
"};",
|
||||
""
|
||||
]
|
||||
},
|
||||
"Define instruction": {
|
||||
"scope": "javascript",
|
||||
"description": "Define an instruction in a GDevelop extension definition.",
|
||||
"prefix": "gdinstr",
|
||||
"body": [
|
||||
"extension",
|
||||
"\t.add${1|Condition,Action|}(",
|
||||
"\t\t'${2:InstructionInternalName}',",
|
||||
"\t\t_('${3:Instruction full name}'),",
|
||||
"\t\t_(",
|
||||
"\t\t\t'${4:Instruction description}'",
|
||||
"\t\t),",
|
||||
"\t\t_('${5:Event sheet sentence}'),",
|
||||
"\t\t_('${6:Events group}'),",
|
||||
"\t\t'JsPlatform/Extensions/${8:icon}.png',",
|
||||
"\t\t'JsPlatform/Extensions/${8:icon}.png'",
|
||||
"\t)",
|
||||
"\t.getCodeExtraInformation()",
|
||||
"\t.setIncludeFile('Extensions/${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}/${9:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}tools}.js')",
|
||||
"\t.setFunctionName('gdjs.evtTools.${7:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
|
||||
"",
|
||||
"$0"
|
||||
]
|
||||
},
|
||||
"Define expression": {
|
||||
"scope": "javascript",
|
||||
"description": "Define an expression in a GDevelop extension definition.",
|
||||
"prefix": "gdexp",
|
||||
"body": [
|
||||
"extension",
|
||||
"\t.add${1|Expression,StrExpression|}(",
|
||||
"\t\t'${2:ExpressionsInternalName}',",
|
||||
"\t\t_('${3:Expression full name}'),",
|
||||
"\t\t_(",
|
||||
"\t\t\t'${4:Expression description}'",
|
||||
"\t\t),",
|
||||
"\t\t_('${5:Events group}'),",
|
||||
"\t\t'JsPlatform/Extensions/${7:icon}.png'",
|
||||
"\t)",
|
||||
"\t.getCodeExtraInformation()",
|
||||
"\t.setIncludeFile('Extensions/${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}/${8:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}tools}.js')",
|
||||
"\t.setFunctionName('gdjs.evtTools.${6:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
|
||||
"",
|
||||
"$0"
|
||||
]
|
||||
},
|
||||
"Add parameter": {
|
||||
"scope": "javascript",
|
||||
"description": "Define a parameter in a GDevelop extension definition.",
|
||||
"prefix": "gdparam",
|
||||
"body": [
|
||||
".addParameter('${1|string,expression,object,behavior,yesorno,stringWithSelector,scenevar,globalvar,objectvar,objectList,objectListWithoutPicking,color,key,sceneName,file,layer,relationalOperator,operator,trueorfalse,musicfile,soundfile,police,mouse,passwordjoyaxis,camera,objectPtr,forceMultiplier|}', '${2:Parameter description}', '${3:Optional parameter data}', /*parameterIsOptional=*/${4|false,true|})"
|
||||
]
|
||||
},
|
||||
"Add code only parameter": {
|
||||
"scope": "javascript",
|
||||
"description": "Define a parameter in a GDevelop extension definition.",
|
||||
"prefix": "gdcoparam",
|
||||
"body": [
|
||||
".addCodeOnlyParameter('${1|inlineCode,currentScene,objectsContext,eventsFunctionContext,conditionInverted|}', '${2:Inline code (for inlineCode parameter)}')"
|
||||
]
|
||||
},
|
||||
"Add include": {
|
||||
"scope": "javascript",
|
||||
"description": "Define an include file in a GDevelop extension definition.",
|
||||
"prefix": "gdincl",
|
||||
"body": [
|
||||
".addIncludeFile('Extensions/${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}/${1:include}.js')"
|
||||
]
|
||||
}
|
||||
}
|
15
.vscode/c_cpp_properties.json
vendored
15
.vscode/c_cpp_properties.json
vendored
@@ -4,16 +4,18 @@
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/GDCpp",
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"EMSCRIPTEN",
|
||||
"GD_IDE_ONLY",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
@@ -25,6 +27,7 @@
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
|
||||
"/usr/local/include",
|
||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
|
||||
"/usr/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
@@ -42,15 +45,17 @@
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/IDE",
|
||||
"${workspaceRoot}/GDCpp",
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"/usr/include",
|
||||
"/usr/local/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"EMSCRIPTEN",
|
||||
"GD_IDE_ONLY",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
@@ -71,15 +76,18 @@
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceRoot}",
|
||||
"${workspaceRoot}/IDE",
|
||||
"${workspaceRoot}/GDCpp",
|
||||
"${workspaceRoot}/GDJS",
|
||||
"${workspaceRoot}/Extensions",
|
||||
"${workspaceRoot}/Core",
|
||||
"${workspaceRoot}/ExtLibs/SFML/include",
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"EMSCRIPTEN",
|
||||
"GD_IDE_ONLY",
|
||||
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
"GD_API=/* Macro used to export classes on Windows, please ignore */",
|
||||
@@ -88,6 +96,7 @@
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"browse": {
|
||||
"path": [
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*",
|
||||
"${workspaceRoot}"
|
||||
],
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
|
8
.vscode/extensions.json
vendored
8
.vscode/extensions.json
vendored
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"esbenp.prettier-vscode",
|
||||
"xaver.clang-format",
|
||||
"ms-vscode.cpptools",
|
||||
"flowtype.flow-for-vscode"
|
||||
]
|
||||
}
|
53
.vscode/launch.json
vendored
53
.vscode/launch.json
vendored
@@ -1,53 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "GDevelop.js Jest tests (all)",
|
||||
"program": "${workspaceFolder}/GDevelop.js/node_modules/.bin/jest",
|
||||
"args": ["--runInBand"],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/GDevelop.js"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "newIDE/app Jest tests (current file)",
|
||||
"program": "${workspaceFolder}/newIDE/app/node_modules/.bin/react-scripts",
|
||||
"args": [
|
||||
"test", "--env=node",
|
||||
"${fileBasenameNoExtension}"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/newIDE/app"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "GDevelop.js Jest tests (current file)",
|
||||
"program": "${workspaceFolder}/GDevelop.js/node_modules/.bin/jest",
|
||||
"args": [
|
||||
"${fileBasenameNoExtension}"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/GDevelop.js"
|
||||
},
|
||||
{
|
||||
"type": "pwa-chrome",
|
||||
"request": "launch",
|
||||
"name": "Debug with Chrome (web-app, local development server)",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
235
.vscode/settings.json
vendored
235
.vscode/settings.json
vendored
@@ -1,134 +1,109 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"variant": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"Binaries/Packaging/GDevelop.app": true,
|
||||
"ExtLibs/SFML": true,
|
||||
"docs": true,
|
||||
"GDJS/docs": true,
|
||||
"GDCpp/docs": true,
|
||||
"Core/docs": true,
|
||||
"Extensions/CommonDialogs/dlib-18.16": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
}
|
||||
|
100
.vscode/tasks.json
vendored
100
.vscode/tasks.json
vendored
@@ -1,100 +0,0 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"path": "newIDE/app/",
|
||||
"group": "build",
|
||||
"label": "Start development server",
|
||||
"detail": "Starts the GDevelop development server.",
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "cra",
|
||||
"fileLocation": ["relative", "${workspaceFolder}/newIDE/app"],
|
||||
"source": "create-react-app",
|
||||
"applyTo": "allDocuments",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^\\s].*?)$",
|
||||
"file": 1
|
||||
},
|
||||
{
|
||||
"regexp": "^ Line\\s+(\\d+):\\s+(.*)\\s\\s+(.*)$",
|
||||
"line": 1,
|
||||
"message": 2,
|
||||
"code": 3,
|
||||
"loop": true
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "^(?:Compiled with warnings\\.|Compiled successfully!)$",
|
||||
"endsPattern": "^(?:Search for the keywords to learn more about each warning\\.|Note that the development build is not optimized\\.)$"
|
||||
}
|
||||
}
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"isBackground": true,
|
||||
"runOptions": { "instanceLimit": 1, "runOn": "folderOpen" }
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"path": "newIDE/electron-app/",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "Start electron app",
|
||||
"detail": "Starts the development local version of GDevelop."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "build",
|
||||
"path": "GDevelop.js/",
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"label": "Build GDevelop.js",
|
||||
"detail": "Builds GDCore for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "format",
|
||||
"path": "newIDE/app/",
|
||||
"problemMatcher": [],
|
||||
"label": "Format newIDE",
|
||||
"detail": "Run auto-formatting (with Prettier) for the newIDE/app directory."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "newIDE/app/",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"label": "Run newIDE tests",
|
||||
"detail": "Run tests for newIDE."
|
||||
},
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": ["$tsc-watch"],
|
||||
"group": "test",
|
||||
"label": "GDJS TS Check",
|
||||
"detail": "Runs a types check on the GDJS Runtime."
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"path": "GDJS/",
|
||||
"group": "test",
|
||||
"problemMatcher": [],
|
||||
"label": "Run GDJS tests",
|
||||
"detail": "Run tests for GDJS."
|
||||
}
|
||||
]
|
||||
}
|
6
Binaries/.directory
Normal file
6
Binaries/.directory
Normal file
@@ -0,0 +1,6 @@
|
||||
[Dolphin]
|
||||
Timestamp=2015,4,21,21,49,19
|
||||
Version=3
|
||||
|
||||
[Settings]
|
||||
HiddenFilesShown=true
|
@@ -1,3 +1,4 @@
|
||||
This is the directory where native or WebAssembly binaries of the C++ code of GDCore and GDJS are produced.
|
||||
This is the directory where native/WebAssembly binaries from GDCore, GDCpp and GDJS are produced.
|
||||
|
||||
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
|
||||
In particular, the extensions and/or the JS platform files will be
|
||||
created into Output/Release_*OSNAME* with *OSNAME* being Windows, Linux or Darwin.
|
||||
|
140
CMakeLists.txt
140
CMakeLists.txt
@@ -1,100 +1,98 @@
|
||||
# This is the CMake file used to build GDevelop.
|
||||
# For more information, see the README.md file.
|
||||
#This is the CMake file used to build GDevelop.
|
||||
#For more information, see the Readme.md file.
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
|
||||
# Add utility functions
|
||||
include(scripts/CMakeClangUtils.txt) # To add clang-format and clang-tidy support to a target
|
||||
|
||||
# Macro for defining an option
|
||||
macro(gd_set_option var default type docstring)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
endmacro()
|
||||
|
||||
# Set options
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library, FALSE to use the already compiled binaries")
|
||||
gd_set_option(BUILD_GDCPP TRUE BOOL "TRUE to build GDevelop C++ Platform")
|
||||
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS Platform")
|
||||
gd_set_option(BUILD_EXTENSIONS TRUE BOOL "TRUE to build the extensions")
|
||||
gd_set_option(BUILD_TESTS TRUE BOOL "TRUE to build the tests")
|
||||
gd_set_option(BUILD_TESTS FALSE BOOL "TRUE to build the tests")
|
||||
gd_set_option(FULL_VERSION_NUMBER TRUE BOOL "TRUE to build GDevelop with its full version number (lastest tag + commit hash), FALSE to only use the lastest tag (avoid rebulding many source file when developping)")
|
||||
|
||||
# Disable deprecated code
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) # Force disable old GUI related code.
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.
|
||||
|
||||
# Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
if(NOT WIN32)
|
||||
if(NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
else()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
endif()
|
||||
#Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
IF(NOT WIN32)
|
||||
if (NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
ELSE()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
ENDIF()
|
||||
|
||||
# As we embed SFML, prevent it to be installed system-wide
|
||||
#As we embed SFML, prevent it to be installed system-wide
|
||||
set(CMAKE_INSTALL_PREFIX "${GD_INSTALL_PREFIX}/useless")
|
||||
endif()
|
||||
ENDIF()
|
||||
|
||||
project(GDevelop)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE) # Avoid errors when packaging for linux.
|
||||
endif()
|
||||
if(APPLE)
|
||||
IF(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
SET(CMAKE_SKIP_BUILD_RPATH TRUE) #Avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
IF(APPLE)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||
set(CMAKE_INSTALL_RPATH ".")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
add_compile_options(
|
||||
-D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_
|
||||
-Wno-potentially-evaluated-expression)
|
||||
endif()
|
||||
# Sanity checks
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message(STATUS "CMAKE_BUILD_TYPE is empty, assuming build type is Release")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
|
||||
ENDIF()
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-s") # Force stripping to avoid errors when packaging for linux.
|
||||
endif()
|
||||
#Sanity checks
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message( "CMAKE_BUILD_TYPE is empty, assuming build type is Release" )
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
ENDIF()
|
||||
IF (EMSCRIPTEN)
|
||||
set(BUILD_GDCPP FALSE CACHE BOOL "" FORCE) #Force disable GDC++ when compiling with emscripten.
|
||||
ENDIF()
|
||||
|
||||
IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-s") #Force stripping to avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
|
||||
#Activate C++11
|
||||
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 would need to remove usage of bind2nd (should be easy).
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Mark some warnings as errors
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Activate as much warnings as possible to avoid errors like
|
||||
# uninitialized variables or other hard to debug bugs.
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-unknown-warning-option
|
||||
-Wno-reorder-ctor
|
||||
-Wno-reorder
|
||||
-Wno-pessimizing-move
|
||||
-Wno-unused-variable
|
||||
-Wno-unused-private-field
|
||||
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
-Werror=return-stack-address
|
||||
-Werror=return-type)
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_CXX0X)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support (with GNU extensions). Please use a different C++ compiler.")
|
||||
endif()
|
||||
|
||||
# Define common directories:
|
||||
#Define common directories:
|
||||
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# Add all the CMakeLists:
|
||||
add_subdirectory(ExtLibs)
|
||||
if(BUILD_CORE)
|
||||
add_subdirectory(Core)
|
||||
endif()
|
||||
if(BUILD_GDJS)
|
||||
add_subdirectory(GDJS)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
add_subdirectory(GDevelop.js)
|
||||
endif()
|
||||
if(BUILD_EXTENSIONS)
|
||||
add_subdirectory(Extensions)
|
||||
endif()
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(Version)
|
||||
ADD_SUBDIRECTORY(ExtLibs)
|
||||
IF(BUILD_CORE)
|
||||
ADD_SUBDIRECTORY(Core)
|
||||
ENDIF()
|
||||
IF(BUILD_GDJS)
|
||||
ADD_SUBDIRECTORY(GDJS)
|
||||
ENDIF()
|
||||
IF(BUILD_GDCPP)
|
||||
ADD_SUBDIRECTORY(GDCpp)
|
||||
ENDIF()
|
||||
IF(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/GDevelop.js/CMakeLists.txt" AND EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(GDevelop.js)
|
||||
ENDIF()
|
||||
IF(BUILD_EXTENSIONS)
|
||||
ADD_SUBDIRECTORY(Extensions)
|
||||
ENDIF()
|
||||
|
@@ -1,98 +1,88 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
|
||||
project(GDCore)
|
||||
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) # Force use response file: useful for Ninja build system on Windows.
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) #Force use response file: useful for Ninja build system on Windows.
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
|
||||
# Define common directories:
|
||||
#Define common directories:
|
||||
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)
|
||||
|
||||
# Dependencies on external libraries:
|
||||
#
|
||||
#Dependencies on external libraries:
|
||||
###
|
||||
include_directories(${sfml_include_dir})
|
||||
|
||||
# Defines
|
||||
#
|
||||
add_definitions(-DGD_IDE_ONLY)
|
||||
if(EMSCRIPTEN)
|
||||
add_definitions(-DEMSCRIPTEN)
|
||||
endif()
|
||||
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
|
||||
add_definitions(-DDEBUG)
|
||||
else()
|
||||
add_definitions(-DRELEASE)
|
||||
endif()
|
||||
#Defines
|
||||
###
|
||||
add_definitions( -DGD_IDE_ONLY )
|
||||
IF (EMSCRIPTEN)
|
||||
add_definitions( -DEMSCRIPTEN )
|
||||
ENDIF()
|
||||
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
add_definitions( -DDEBUG )
|
||||
ELSE()
|
||||
add_definitions( -DRELEASE )
|
||||
ENDIF()
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWINDOWS)
|
||||
add_definitions("-DGD_CORE_API=__declspec(dllexport)")
|
||||
add_definitions(-D__GNUWIN32__)
|
||||
else()
|
||||
if(APPLE)
|
||||
add_definitions(-DMACOS)
|
||||
else()
|
||||
add_definitions(-DLINUX)
|
||||
endif()
|
||||
add_definitions(-DGD_API=)
|
||||
add_definitions(-DGD_CORE_API=)
|
||||
endif()
|
||||
IF(WIN32)
|
||||
add_definitions( -DWINDOWS )
|
||||
add_definitions( "-DGD_CORE_API=__declspec(dllexport)" )
|
||||
add_definitions( -D__GNUWIN32__ )
|
||||
ELSE()
|
||||
IF(APPLE)
|
||||
add_definitions( -DMACOS )
|
||||
ELSE()
|
||||
add_definitions( -DLINUX )
|
||||
ENDIF()
|
||||
add_definitions( -DGD_API= )
|
||||
add_definitions( -DGD_CORE_API= )
|
||||
ENDIF(WIN32)
|
||||
|
||||
# The target
|
||||
#
|
||||
#The target
|
||||
###
|
||||
include_directories(.)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
source_files
|
||||
GDCore/*)
|
||||
file(GLOB_RECURSE source_files GDCore/*)
|
||||
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
formatted_source_files
|
||||
tests/*
|
||||
GDCore/Events/*
|
||||
GDCore/Extensions/*
|
||||
GDCore/IDE/*
|
||||
GDCore/Project/*
|
||||
GDCore/Serialization/*
|
||||
GDCore/Tools/*)
|
||||
list(
|
||||
REMOVE_ITEM
|
||||
formatted_source_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
file(GLOB_RECURSE formatted_source_files tests/* GDCore/Events/* GDCore/Extensions/* GDCore/IDE/* GDCore/Project/* GDCore/Serialization/* GDCore/Tools/*)
|
||||
list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
gd_add_clang_utils(GDCore "${formatted_source_files}")
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(GDCore STATIC ${source_files})
|
||||
else()
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
add_dependencies(GDCore GDVersion)
|
||||
IF(EMSCRIPTEN)
|
||||
set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
|
||||
elseif(WIN32)
|
||||
ELSEIF(WIN32)
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "")
|
||||
else()
|
||||
ELSE()
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "lib")
|
||||
endif()
|
||||
ENDIF()
|
||||
set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(ARCHIVE_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(RUNTIME_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
|
||||
# Tests
|
||||
#
|
||||
#Linker files
|
||||
###
|
||||
IF(EMSCRIPTEN)
|
||||
#Nothing.
|
||||
ELSE()
|
||||
target_link_libraries(GDCore ${sfml_LIBRARIES})
|
||||
ENDIF()
|
||||
|
||||
#Tests
|
||||
###
|
||||
if(BUILD_TESTS)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*)
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*
|
||||
)
|
||||
|
||||
add_executable(GDCore_tests ${test_source_files})
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) # Allow finding dependencies directly from build path on Mac OS X.
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
|
||||
target_link_libraries(GDCore_tests GDCore)
|
||||
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
|
||||
target_link_libraries(GDCore_tests ${sfml_LIBRARIES})
|
||||
endif()
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Utf8/utf8.h"
|
||||
#include <SFML/System/String.hpp>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define GD_DEPRECATED __attribute__((deprecated))
|
||||
|
@@ -14,8 +14,9 @@
|
||||
*
|
||||
* \section other Other documentations
|
||||
*
|
||||
* GDevelop is architectured around a `Core` (this library), a game engine (`GDJS`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries.
|
||||
* GDevelop is architectured around a `Core` (this library), platforms (`GDJS`, `GDCpp`) and extensions (`Extensions` folder). The editor (`newIDE` folder) is using all of these libraries.
|
||||
*
|
||||
* - [Open GDevelop C++ Platform documentation](../GDCpp Documentation/index.html)
|
||||
* - [Open GDevelop JS Platform documentation](../GDJS Documentation/index.html)
|
||||
* - <a href="https://github.com/4ian/GDevelop/blob/master/newIDE/README.md">Getting started with the editor</a>
|
||||
* - <a href="https://github.com/4ian/GDevelop/blob/master/newIDE/README-extensions.md">Getting started with the extensions</a>
|
||||
|
@@ -1,36 +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 "AsyncEvent.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
AsyncEvent::AsyncEvent() : BaseEvent() {}
|
||||
|
||||
AsyncEvent::~AsyncEvent(){};
|
||||
|
||||
vector<const gd::InstructionsList *> AsyncEvent::GetAllActionsVectors() const {
|
||||
vector<const gd::InstructionsList *> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList *> AsyncEvent::GetAllActionsVectors() {
|
||||
vector<gd::InstructionsList *> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef GDCORE_ASYNCEVENT_H
|
||||
#define GDCORE_ASYNCEVENT_H
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Internal event for asynchronous actions.
|
||||
* This event gets added internally to the events tree when an
|
||||
* asynchronous action is used.
|
||||
*/
|
||||
class GD_CORE_API AsyncEvent : public gd::BaseEvent {
|
||||
public:
|
||||
AsyncEvent();
|
||||
AsyncEvent(const gd::Instruction &asyncAction_,
|
||||
const gd::InstructionsList &actions_,
|
||||
const gd::EventsList &subEvents_)
|
||||
: asyncAction(asyncAction_), actions(actions_), subEvents(subEvents_) {
|
||||
SetType("BuiltinAsync::Async");
|
||||
};
|
||||
virtual ~AsyncEvent();
|
||||
virtual gd::AsyncEvent *Clone() const { return new AsyncEvent(*this); }
|
||||
|
||||
virtual bool IsExecutable() const { return true; }
|
||||
|
||||
virtual bool CanHaveSubEvents() const { return true; }
|
||||
virtual const gd::EventsList &GetSubEvents() const { return subEvents; };
|
||||
virtual gd::EventsList &GetSubEvents() { return subEvents; };
|
||||
|
||||
const gd::InstructionsList &GetActions() const { return actions; };
|
||||
gd::InstructionsList &GetActions() { return actions; };
|
||||
|
||||
const gd::Instruction &GetInstruction() const { return asyncAction; };
|
||||
gd::Instruction &GetInstruction() { return asyncAction; };
|
||||
|
||||
virtual std::vector<const gd::InstructionsList *>
|
||||
GetAllActionsVectors() const;
|
||||
virtual std::vector<gd::InstructionsList *> GetAllActionsVectors();
|
||||
|
||||
private:
|
||||
gd::Instruction asyncAction;
|
||||
gd::InstructionsList actions;
|
||||
EventsList subEvents;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_STANDARDEVENT_H
|
@@ -12,22 +12,6 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
vector<gd::String> CommentEvent::GetAllSearchableStrings() const {
|
||||
vector<gd::String> allSearchableStrings;
|
||||
|
||||
allSearchableStrings.push_back(com1);
|
||||
allSearchableStrings.push_back(com2); ///< Com2 is deprecated
|
||||
|
||||
return allSearchableStrings;
|
||||
}
|
||||
|
||||
bool CommentEvent::ReplaceAllSearchableStrings(
|
||||
std::vector<gd::String> newSearchableString) {
|
||||
if (newSearchableString[0] == com1) return false;
|
||||
SetComment(newSearchableString[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CommentEvent::SerializeTo(SerializerElement &element) const {
|
||||
element.AddChild("color")
|
||||
.SetAttribute("r", r)
|
||||
@@ -38,7 +22,7 @@ void CommentEvent::SerializeTo(SerializerElement &element) const {
|
||||
.SetAttribute("textB", textB);
|
||||
|
||||
element.AddChild("comment").SetValue(com1);
|
||||
if (!com2.empty()) element.AddChild("comment2").SetValue(com2);
|
||||
element.AddChild("comment2").SetValue(com2);
|
||||
}
|
||||
|
||||
void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
@@ -53,9 +37,7 @@ void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
textB = colorElement.GetIntAttribute("textB");
|
||||
|
||||
com1 = element.GetChild("comment", 0, "Com1").GetValue().GetString();
|
||||
if (element.HasChild("comment2")) {
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
}
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -7,11 +7,10 @@
|
||||
#define COMMENTEVENT_H
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
class Project;
|
||||
} // namespace gd
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -46,10 +45,6 @@ class GD_CORE_API CommentEvent : public gd::BaseEvent {
|
||||
const gd::String& GetComment() const { return com1; }
|
||||
void SetComment(const gd::String& comment) { com1 = comment; }
|
||||
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const;
|
||||
virtual bool ReplaceAllSearchableStrings(
|
||||
std::vector<gd::String> newSearchableString);
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "ForEachChildVariableEvent.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
ForEachChildVariableEvent::ForEachChildVariableEvent()
|
||||
: BaseEvent(), valueIteratorVariableName("child"), keyIteratorVariableName(""), iterableVariableName("") {}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllConditionsVectors() {
|
||||
vector<gd::InstructionsList*> allConditions;
|
||||
allConditions.push_back(&conditions);
|
||||
|
||||
return allConditions;
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllActionsVectors() {
|
||||
vector<gd::InstructionsList*> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*>
|
||||
ForEachChildVariableEvent::GetAllConditionsVectors() const {
|
||||
vector<const gd::InstructionsList*> allConditions;
|
||||
allConditions.push_back(&conditions);
|
||||
|
||||
return allConditions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*>
|
||||
ForEachChildVariableEvent::GetAllActionsVectors() const {
|
||||
vector<const gd::InstructionsList*> allActions;
|
||||
allActions.push_back(&actions);
|
||||
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("scenevar");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&iterableVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&valueIteratorVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&keyIteratorVariableName, metadata));
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
}
|
||||
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("scenevar");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&iterableVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&valueIteratorVariableName, metadata));
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&keyIteratorVariableName, metadata));
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
}
|
||||
|
||||
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("iterableVariableName").SetValue(iterableVariableName.GetPlainString());
|
||||
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName.GetPlainString());
|
||||
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName.GetPlainString());
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
iterableVariableName = element.GetChild("iterableVariableName", 0, "").GetValue().GetString();
|
||||
valueIteratorVariableName = element.GetChild("valueIteratorVariableName", 0, "").GetValue().GetString();
|
||||
keyIteratorVariableName = element.GetChild("keyIteratorVariableName", 0, "").GetValue().GetString();
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef FOREACHCHILDVARIABLEEVENT_H
|
||||
#define FOREACHCHILDVARIABLEEVENT_H
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
class Layout;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Event repeated for each every child of a structure variable.
|
||||
*/
|
||||
class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
|
||||
public:
|
||||
ForEachChildVariableEvent();
|
||||
virtual ~ForEachChildVariableEvent(){};
|
||||
virtual gd::ForEachChildVariableEvent* Clone() const {
|
||||
return new ForEachChildVariableEvent(*this);
|
||||
}
|
||||
|
||||
virtual bool IsExecutable() const { return true; }
|
||||
|
||||
virtual bool CanHaveSubEvents() const { return true; }
|
||||
virtual const gd::EventsList& GetSubEvents() const { return events; };
|
||||
virtual gd::EventsList& GetSubEvents() { return events; };
|
||||
|
||||
const gd::InstructionsList& GetConditions() const { return conditions; };
|
||||
gd::InstructionsList& GetConditions() { return conditions; };
|
||||
|
||||
const gd::InstructionsList& GetActions() const { return actions; };
|
||||
gd::InstructionsList& GetActions() { return actions; };
|
||||
|
||||
/**
|
||||
* \brief Get the iterable variable name attached to the event.
|
||||
*
|
||||
* It is the structure variable that will be iterated on.
|
||||
*/
|
||||
const gd::String& GetIterableVariableName() const { return iterableVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the iterable variable name attached to the event.
|
||||
*
|
||||
* It is the structure variable that will be iterated on.
|
||||
*/
|
||||
void SetIterableVariableName(gd::String newName) { iterableVariableName = newName; };
|
||||
|
||||
/**
|
||||
* \brief Get the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the value iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the value of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; };
|
||||
|
||||
/**
|
||||
* \brief Get the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName.GetPlainString(); };
|
||||
|
||||
/**
|
||||
* \brief Set the key iterator variable attached to the event.
|
||||
*
|
||||
* It is the variable that will contain the name of the
|
||||
* iterable's child being iterated on.
|
||||
*/
|
||||
void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; };
|
||||
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
|
||||
const;
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
|
||||
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
|
||||
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const;
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata();
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
||||
private:
|
||||
gd::Expression valueIteratorVariableName;
|
||||
gd::Expression keyIteratorVariableName;
|
||||
gd::Expression iterableVariableName;
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // FOREACHEVENT_H
|
@@ -5,6 +5,10 @@
|
||||
*/
|
||||
|
||||
#include "ForEachEvent.h"
|
||||
#include <iostream>
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -15,7 +19,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
ForEachEvent::ForEachEvent()
|
||||
: BaseEvent(), objectsToPick("") {}
|
||||
: BaseEvent(), objectsToPick(""), objectsToPickSelected(false) {}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors() {
|
||||
vector<gd::InstructionsList*> allConditions;
|
||||
@@ -31,17 +35,12 @@ vector<gd::InstructionsList*> ForEachEvent::GetAllActionsVectors() {
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
ForEachEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&objectsToPick, metadata));
|
||||
vector<gd::Expression*> ForEachEvent::GetAllExpressions() {
|
||||
vector<gd::Expression*> allExpressions;
|
||||
allExpressions.push_back(&objectsToPick);
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
return allExpressions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors()
|
||||
const {
|
||||
vector<const gd::InstructionsList*> allConditions;
|
||||
@@ -57,15 +56,11 @@ vector<const gd::InstructionsList*> ForEachEvent::GetAllActionsVectors() const {
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
ForEachEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("object");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&objectsToPick, metadata));
|
||||
vector<const gd::Expression*> ForEachEvent::GetAllExpressions() const {
|
||||
vector<const gd::Expression*> allExpressions;
|
||||
allExpressions.push_back(&objectsToPick);
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
return allExpressions;
|
||||
}
|
||||
|
||||
void ForEachEvent::SerializeTo(SerializerElement& element) const {
|
||||
@@ -74,10 +69,8 @@ void ForEachEvent::SerializeTo(SerializerElement& element) const {
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void ForEachEvent::UnserializeFrom(gd::Project& project,
|
||||
@@ -88,12 +81,8 @@ void ForEachEvent::UnserializeFrom(gd::Project& project,
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -6,8 +6,6 @@
|
||||
|
||||
#ifndef FOREACHEVENT_H
|
||||
#define FOREACHEVENT_H
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
@@ -52,13 +50,10 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
|
||||
const;
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const;
|
||||
|
||||
virtual std::vector<const gd::Expression*> GetAllExpressions() const;
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata();
|
||||
virtual std::vector<gd::Expression*> GetAllExpressions();
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
@@ -69,6 +64,8 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
|
||||
bool objectsToPickSelected;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -19,21 +19,6 @@ namespace gd {
|
||||
GroupEvent::GroupEvent()
|
||||
: BaseEvent(), creationTime(0), colorR(74), colorG(176), colorB(228) {}
|
||||
|
||||
vector<gd::String> GroupEvent::GetAllSearchableStrings() const {
|
||||
vector<gd::String> allSearchableStrings;
|
||||
|
||||
allSearchableStrings.push_back(name);
|
||||
|
||||
return allSearchableStrings;
|
||||
}
|
||||
|
||||
bool GroupEvent::ReplaceAllSearchableStrings(
|
||||
std::vector<gd::String> newSearchableString) {
|
||||
if (newSearchableString[0] == name) return false;
|
||||
SetName(newSearchableString[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GroupEvent::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("source", source);
|
||||
@@ -76,4 +61,5 @@ void GroupEvent::SetBackgroundColor(unsigned int colorR_,
|
||||
colorB = colorB_;
|
||||
}
|
||||
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -13,7 +13,6 @@
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
class EventVisitor;
|
||||
}
|
||||
class EventsCodeGenerationContext;
|
||||
|
||||
@@ -107,10 +106,6 @@ class GD_CORE_API GroupEvent : public gd::BaseEvent {
|
||||
virtual const gd::EventsList& GetSubEvents() const { return events; };
|
||||
virtual gd::EventsList& GetSubEvents() { return events; };
|
||||
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const;
|
||||
virtual bool ReplaceAllSearchableStrings(
|
||||
std::vector<gd::String> newSearchableString);
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -131,46 +130,30 @@ void LinkEvent::SerializeTo(SerializerElement& element) const {
|
||||
|
||||
void LinkEvent::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
|
||||
SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString());
|
||||
|
||||
// Compatibility with GD <= 5
|
||||
if (element.HasChild("include", "Limites")) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
} else {
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
} else {
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
} else {
|
||||
// Since GDevelop 5, links always include all events.
|
||||
SetIncludeAllEvents();
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
// end of compatibility code
|
||||
}
|
||||
|
||||
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
|
||||
return BaseEvent::AcceptVisitor(eventVisitor) |
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
void LinkEvent::AcceptVisitor(gd::ReadOnlyEventVisitor &eventVisitor) const {
|
||||
BaseEvent::AcceptVisitor(eventVisitor);
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -30,7 +30,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
includeEnd(gd::String::npos),
|
||||
linkWasInvalid(false){};
|
||||
virtual ~LinkEvent();
|
||||
virtual gd::LinkEvent* Clone() const override { return new LinkEvent(*this); }
|
||||
virtual gd::LinkEvent* Clone() const { return new LinkEvent(*this); }
|
||||
|
||||
/**
|
||||
* Get the link target (i.e. the scene or external events the link refers to).
|
||||
@@ -86,7 +86,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
/**
|
||||
* The link event must always be preprocessed.
|
||||
*/
|
||||
virtual bool MustBePreprocessed() override { return true; }
|
||||
virtual bool MustBePreprocessed() { return true; }
|
||||
|
||||
/**
|
||||
* \brief Get a pointer to the list of events that are targeted by the link.
|
||||
@@ -107,14 +107,11 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList);
|
||||
|
||||
virtual bool IsExecutable() const override { return true; };
|
||||
virtual bool IsExecutable() const { return true; };
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const override;
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) override;
|
||||
|
||||
bool AcceptVisitor(gd::EventVisitor& eventVisitor) override;
|
||||
void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const override;
|
||||
const SerializerElement& element);
|
||||
|
||||
private:
|
||||
gd::String
|
||||
|
@@ -5,6 +5,9 @@
|
||||
*/
|
||||
|
||||
#include "RepeatEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
@@ -31,15 +34,11 @@ vector<gd::InstructionsList*> RepeatEvent::GetAllActionsVectors() {
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
RepeatEvent::GetAllExpressionsWithMetadata() {
|
||||
vector<pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("number");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&repeatNumberExpression, metadata));
|
||||
vector<gd::Expression*> RepeatEvent::GetAllExpressions() {
|
||||
vector<gd::Expression*> allExpressions;
|
||||
allExpressions.push_back(&repeatNumberExpression);
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
return allExpressions;
|
||||
}
|
||||
|
||||
vector<const gd::InstructionsList*> RepeatEvent::GetAllConditionsVectors()
|
||||
@@ -57,15 +56,11 @@ vector<const gd::InstructionsList*> RepeatEvent::GetAllActionsVectors() const {
|
||||
return allActions;
|
||||
}
|
||||
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
RepeatEvent::GetAllExpressionsWithMetadata() const {
|
||||
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
allExpressionsWithMetadata;
|
||||
auto metadata = gd::ParameterMetadata().SetType("number");
|
||||
allExpressionsWithMetadata.push_back(
|
||||
std::make_pair(&repeatNumberExpression, metadata));
|
||||
vector<const gd::Expression*> RepeatEvent::GetAllExpressions() const {
|
||||
vector<const gd::Expression*> allExpressions;
|
||||
allExpressions.push_back(&repeatNumberExpression);
|
||||
|
||||
return allExpressionsWithMetadata;
|
||||
return allExpressions;
|
||||
}
|
||||
|
||||
void RepeatEvent::SerializeTo(SerializerElement& element) const {
|
||||
@@ -75,10 +70,8 @@ void RepeatEvent::SerializeTo(SerializerElement& element) const {
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void RepeatEvent::UnserializeFrom(gd::Project& project,
|
||||
@@ -91,12 +84,8 @@ void RepeatEvent::UnserializeFrom(gd::Project& project,
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -45,14 +45,11 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
|
||||
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata();
|
||||
|
||||
virtual std::vector<gd::Expression*> GetAllExpressions();
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
|
||||
const;
|
||||
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
|
||||
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const;
|
||||
virtual std::vector<const gd::Expression*> GetAllExpressions() const;
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
|
@@ -53,10 +53,8 @@ void StandardEvent::SerializeTo(SerializerElement& element) const {
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void StandardEvent::UnserializeFrom(gd::Project& project,
|
||||
@@ -65,12 +63,8 @@ void StandardEvent::UnserializeFrom(gd::Project& project,
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -6,6 +6,9 @@
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "WhileEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
|
||||
@@ -52,10 +55,8 @@ void WhileEvent::SerializeTo(SerializerElement& element) const {
|
||||
conditions, element.AddChild("conditions"));
|
||||
gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
actions, element.AddChild("actions"));
|
||||
|
||||
if (!events.IsEmpty())
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
gd::EventsListSerialization::SerializeEventsTo(events,
|
||||
element.AddChild("events"));
|
||||
}
|
||||
|
||||
void WhileEvent::UnserializeFrom(gd::Project& project,
|
||||
@@ -70,12 +71,8 @@ void WhileEvent::UnserializeFrom(gd::Project& project,
|
||||
project, conditions, element.GetChild("conditions", 0, "Conditions"));
|
||||
gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
project, actions, element.GetChild("actions", 0, "Actions"));
|
||||
|
||||
events.Clear();
|
||||
if (element.HasChild("events", "Events")) {
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
gd::EventsListSerialization::UnserializeEventsFrom(
|
||||
project, events, element.GetChild("events", 0, "Events"));
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,75 +3,56 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EffectsCodeGenerator.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "EffectsCodeGenerator.h"
|
||||
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Project/Effect.h"
|
||||
#include "GDCore/Project/EffectsContainer.h"
|
||||
#include "GDCore/Project/Layer.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void EffectsCodeGenerator::DoVisitObject(gd::Object &object) {
|
||||
auto &effects = object.GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto &effect = effects.GetEffect(e);
|
||||
AddEffectIncludeFiles(effect);
|
||||
}
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::AddEffectIncludeFiles(const gd::Effect &effect) {
|
||||
// TODO: this browse all the extensions every time we're trying to find
|
||||
// a new effect. Might be a good idea to rework MetadataProvider to be
|
||||
// faster (not sure if it is a bottleneck at all though - but could be
|
||||
// for events code generation).
|
||||
const gd::EffectMetadata &effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
|
||||
|
||||
for (auto &includeFile : effectMetadata.GetIncludeFiles())
|
||||
includeFiles.insert(includeFile);
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
const gd::Platform &platform,
|
||||
gd::Project &project,
|
||||
std::set<gd::String> &includeFiles) {
|
||||
// TODO Add unit tests on this function.
|
||||
|
||||
// TODO Merge with UsedExtensionsFinder.
|
||||
// Default lights rely on the fact that UsedExtensionsFinder doesn't find
|
||||
// extension usages for effects. This has the happy side effect of not
|
||||
// including Three.js when no 3D object are in the scenes.
|
||||
// We need to make something explicit to avoid future bugs.
|
||||
|
||||
void ExposeProjectEffects(
|
||||
const gd::Project& project,
|
||||
const std::function<void(const gd::Effect& effect)>& worker) {
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources) and
|
||||
// WholeProjectRefactorer::ExposeProjectEvents.
|
||||
|
||||
EffectsCodeGenerator effectsCodeGenerator(platform, includeFiles);
|
||||
|
||||
// Add layouts effects
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
auto& layout = project.GetLayout(s);
|
||||
|
||||
for (std::size_t l = 0; l < layout.GetLayersCount(); ++l) {
|
||||
auto& effects = layout.GetLayer(l).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
effectsCodeGenerator.AddEffectIncludeFiles(effect);
|
||||
auto& layer = layout.GetLayer(l);
|
||||
|
||||
for (std::size_t e = 0; e < layer.GetEffectsCount(); ++e) {
|
||||
auto& effect = layer.GetEffect(e);
|
||||
worker(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add objects effects
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
|
||||
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
const gd::Platform& platform,
|
||||
const gd::Project& project,
|
||||
std::set<gd::String>& includeFiles) {
|
||||
ExposeProjectEffects(
|
||||
project, [&platform, &includeFiles](const gd::Effect& effect) {
|
||||
// TODO: this browse all the extensions every time we're trying to find
|
||||
// a new effect. Might be a good idea to rework MetadataProvider to be
|
||||
// faster (not sure if it is a bottleneck at all though - but could be
|
||||
// for events code generation).
|
||||
const gd::EffectMetadata& effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform,
|
||||
effect.GetEffectType());
|
||||
|
||||
for (auto& includeFile : effectMetadata.GetIncludeFiles())
|
||||
includeFiles.insert(includeFile);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,18 +3,16 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef GDCORE_EffectsCodeGenerator_H
|
||||
#define GDCORE_EffectsCodeGenerator_H
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Platform;
|
||||
class Effect;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -22,26 +20,16 @@ namespace gd {
|
||||
/**
|
||||
* \brief Internal class used to generate code from events
|
||||
*/
|
||||
class GD_CORE_API EffectsCodeGenerator : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
class GD_CORE_API EffectsCodeGenerator {
|
||||
public:
|
||||
/**
|
||||
* \brief Add all the include files required by the project effects.
|
||||
*/
|
||||
static void GenerateEffectsIncludeFiles(const gd::Platform& platform,
|
||||
gd::Project& project,
|
||||
const gd::Project& project,
|
||||
std::set<gd::String>& includeFiles);
|
||||
|
||||
private:
|
||||
EffectsCodeGenerator(const gd::Platform &platform_,
|
||||
std::set<gd::String> &includeFiles_)
|
||||
: platform(platform_), includeFiles(includeFiles_){};
|
||||
|
||||
void AddEffectIncludeFiles(const gd::Effect& effect);
|
||||
|
||||
void DoVisitObject(gd::Object &object) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
std::set<gd::String> &includeFiles;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EffectsCodeGenerator_H
|
||||
|
@@ -4,9 +4,7 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
@@ -16,7 +14,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void EventsCodeGenerationContext::InheritsFrom(
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
const EventsCodeGenerationContext& parent_) {
|
||||
parent = &parent_;
|
||||
|
||||
// Objects lists declared by parent became "already declared" in the child
|
||||
@@ -26,8 +24,8 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
parent_.objectsListsToBeDeclared.end(),
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
std::copy(parent_.objectsListsOrEmptyToBeDeclared.begin(),
|
||||
parent_.objectsListsOrEmptyToBeDeclared.end(),
|
||||
std::copy(parent_.objectsListsWithoutPickingToBeDeclared.begin(),
|
||||
parent_.objectsListsWithoutPickingToBeDeclared.end(),
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
std::copy(parent_.emptyObjectsListsToBeDeclared.begin(),
|
||||
@@ -35,8 +33,6 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
std::inserter(alreadyDeclaredObjectsLists,
|
||||
alreadyDeclaredObjectsLists.begin()));
|
||||
|
||||
nearestAsyncParent = parent_.IsAsyncCallback() ? &parent_ : parent_.nearestAsyncParent;
|
||||
asyncDepth = parent_.asyncDepth;
|
||||
depthOfLastUse = parent_.depthOfLastUse;
|
||||
customConditionDepth = parent_.customConditionDepth;
|
||||
contextDepth = parent_.GetContextDepth() + 1;
|
||||
@@ -46,59 +42,33 @@ void EventsCodeGenerationContext::InheritsFrom(
|
||||
}
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::InheritsAsAsyncCallbackFrom(
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
// Increasing the async depth is enough to mark the context as an async callback.
|
||||
InheritsFrom(parent_);
|
||||
asyncDepth = parent_.asyncDepth + 1;
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::Reuse(
|
||||
EventsCodeGenerationContext& parent_) {
|
||||
const EventsCodeGenerationContext& parent_) {
|
||||
InheritsFrom(parent_);
|
||||
if (parent_.CanReuse())
|
||||
contextDepth = parent_.GetContextDepth(); // Keep same context depth
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::NotifyAsyncParentsAboutDeclaredObject(const gd::String& objectName) {
|
||||
gd::EventsCodeGenerationContext* asyncContext = IsAsyncCallback() ? this : nearestAsyncParent;
|
||||
for (;
|
||||
asyncContext != nullptr;
|
||||
asyncContext = asyncContext->parent->nearestAsyncParent)
|
||||
asyncContext->allObjectsListToBeDeclaredAcrossChildren.insert(objectName);
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::ObjectsListNeeded(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
if (!IsToBeDeclared(objectName))
|
||||
objectsListsToBeDeclared.insert(objectName);
|
||||
|
||||
if (IsInsideAsync()) {
|
||||
NotifyAsyncParentsAboutDeclaredObject(objectName);
|
||||
}
|
||||
}
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::ObjectsListNeededOrEmptyIfJustDeclared(
|
||||
void EventsCodeGenerationContext::ObjectsListWithoutPickingNeeded(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
objectsListsOrEmptyToBeDeclared.insert(objectName);
|
||||
|
||||
if (IsInsideAsync()) {
|
||||
NotifyAsyncParentsAboutDeclaredObject(objectName);
|
||||
}
|
||||
}
|
||||
if (!IsToBeDeclared(objectName))
|
||||
objectsListsWithoutPickingToBeDeclared.insert(objectName);
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
|
||||
void EventsCodeGenerationContext::EmptyObjectsListNeeded(
|
||||
const gd::String& objectName) {
|
||||
if (!IsToBeDeclared(objectName)) {
|
||||
if (!IsToBeDeclared(objectName))
|
||||
emptyObjectsListsToBeDeclared.insert(objectName);
|
||||
}
|
||||
|
||||
depthOfLastUse[objectName] = GetContextDepth();
|
||||
}
|
||||
@@ -107,8 +77,8 @@ std::set<gd::String> EventsCodeGenerationContext::GetAllObjectsToBeDeclared()
|
||||
const {
|
||||
std::set<gd::String> allObjectListsToBeDeclared(
|
||||
objectsListsToBeDeclared.begin(), objectsListsToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(objectsListsOrEmptyToBeDeclared.begin(),
|
||||
objectsListsOrEmptyToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(objectsListsWithoutPickingToBeDeclared.begin(),
|
||||
objectsListsWithoutPickingToBeDeclared.end());
|
||||
allObjectListsToBeDeclared.insert(emptyObjectsListsToBeDeclared.begin(),
|
||||
emptyObjectsListsToBeDeclared.end());
|
||||
|
||||
@@ -132,21 +102,4 @@ bool EventsCodeGenerationContext::IsSameObjectsList(
|
||||
otherContext.GetLastDepthObjectListWasNeeded(objectName);
|
||||
}
|
||||
|
||||
bool EventsCodeGenerationContext::ShouldUseAsyncObjectsList(
|
||||
const gd::String& objectName) const {
|
||||
if (!IsInsideAsync()) return false;
|
||||
|
||||
// Check if the objects list was used after (or in) the nearest async callback context.
|
||||
const gd::EventsCodeGenerationContext* asyncContext = IsAsyncCallback() ? this : nearestAsyncParent;
|
||||
if (parent->GetLastDepthObjectListWasNeeded(objectName) >= asyncContext->GetContextDepth()) {
|
||||
// The object was used in a context after (or in) the nearest async parent context, so we're not getting it from the
|
||||
// async object lists (it was already gotten from there in this previous context).
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the objects list is declared in a parent of the nearest async context, it means
|
||||
// the async context had to use an async objects list to access it.
|
||||
return asyncContext->ObjectAlreadyDeclaredByParents(objectName);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
@@ -34,7 +33,11 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* updated to contain the maximal scope depth reached.
|
||||
*/
|
||||
EventsCodeGenerationContext(unsigned int* maxDepthLevel_ = nullptr)
|
||||
: maxDepthLevel(maxDepthLevel_){};
|
||||
: contextDepth(0),
|
||||
customConditionDepth(0),
|
||||
maxDepthLevel(maxDepthLevel_),
|
||||
parent(NULL),
|
||||
reuseExplicitlyForbidden(false){};
|
||||
virtual ~EventsCodeGenerationContext(){};
|
||||
|
||||
/**
|
||||
@@ -42,13 +45,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* another one. The child will then for example not declare again objects
|
||||
* already declared by its parent.
|
||||
*/
|
||||
void InheritsFrom(EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* Call this method to make an EventsCodeGenerationContext as a "child" of
|
||||
* another one, but in the context of an async function.
|
||||
*/
|
||||
void InheritsAsAsyncCallbackFrom(EventsCodeGenerationContext& parent);
|
||||
void InheritsFrom(const EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* \brief As InheritsFrom, mark the context as being the child of another one,
|
||||
@@ -56,7 +53,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*
|
||||
* Used for example for optimizing the last event of a list.
|
||||
*/
|
||||
void Reuse(EventsCodeGenerationContext& parent);
|
||||
void Reuse(const EventsCodeGenerationContext& parent);
|
||||
|
||||
/**
|
||||
* \brief Forbid any optimization that would reuse and modify the object list
|
||||
@@ -91,19 +88,19 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
const EventsCodeGenerationContext* GetParentContext() const { return parent; }
|
||||
|
||||
/**
|
||||
* Mark the object as being the object being handled by the instruction.
|
||||
* Mark the object has being the object being handled by the instruction
|
||||
*/
|
||||
void SetCurrentObject(const gd::String& objectName) {
|
||||
currentObject = objectName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set that no particular object is being handled by an instruction.
|
||||
* Set that no particular object is being handled by an instruction
|
||||
*/
|
||||
void SetNoCurrentObject() { currentObject = ""; };
|
||||
|
||||
/**
|
||||
* Get the object being handled by the instruction.
|
||||
* Get the object being handled by the instruction
|
||||
*/
|
||||
const gd::String& GetCurrentObject() const { return currentObject; };
|
||||
|
||||
@@ -112,7 +109,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*
|
||||
* The list will be filled with objects from the scene if it is the first time
|
||||
* it is requested, unless there is already an object list with this name
|
||||
* (i.e. `ObjectAlreadyDeclaredByParents(objectName)` returns true).
|
||||
* (i.e. `ObjectAlreadyDeclared(objectName)` returns true).
|
||||
*/
|
||||
void ObjectsListNeeded(const gd::String& objectName);
|
||||
|
||||
@@ -124,7 +121,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* from the scene. If there is already an objects list with this name, no new
|
||||
* list will be declared again.
|
||||
*/
|
||||
void ObjectsListNeededOrEmptyIfJustDeclared(const gd::String& objectName);
|
||||
void ObjectsListWithoutPickingNeeded(const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* Call this when an instruction in the event needs an empty object list,
|
||||
@@ -137,21 +134,29 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
void EmptyObjectsListNeeded(const gd::String& objectName);
|
||||
|
||||
/**
|
||||
* Return true if an object list has already been declared by the parent contexts.
|
||||
* Return true if an object list has already been declared (or is going to be
|
||||
* declared).
|
||||
*/
|
||||
bool ObjectAlreadyDeclaredByParents(const gd::String& objectName) const {
|
||||
bool ObjectAlreadyDeclared(const gd::String& objectName) const {
|
||||
return (alreadyDeclaredObjectsLists.find(objectName) !=
|
||||
alreadyDeclaredObjectsLists.end());
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Consider that \a objectName is now declared in the context.
|
||||
*/
|
||||
void SetObjectDeclared(const gd::String& objectName) {
|
||||
alreadyDeclaredObjectsLists.insert(objectName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the objects lists which will be declared by the current context
|
||||
* (normal, potentially empty or empty).
|
||||
* ( the non empty as well as the empty objects lists )
|
||||
*/
|
||||
std::set<gd::String> GetAllObjectsToBeDeclared() const;
|
||||
|
||||
/**
|
||||
* Return the objects lists which will be declared by the current context.
|
||||
* Return the objects lists which will be declared by the current context
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsToBeDeclared() const {
|
||||
return objectsListsToBeDeclared;
|
||||
@@ -161,9 +166,9 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* Return the objects lists which will be will be declared, without filling
|
||||
* them with objects from the scene.
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsToBeEmptyIfJustDeclared()
|
||||
const std::set<gd::String>& GetObjectsListsToBeDeclaredWithoutPicking()
|
||||
const {
|
||||
return objectsListsOrEmptyToBeDeclared;
|
||||
return objectsListsWithoutPickingToBeDeclared;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -179,7 +184,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
* Return the objects lists which are already declared and can be used in the
|
||||
* current context without declaration.
|
||||
*/
|
||||
const std::set<gd::String>& GetObjectsListsAlreadyDeclaredByParents() const {
|
||||
const std::set<gd::String>& GetObjectsListsAlreadyDeclared() const {
|
||||
return alreadyDeclaredObjectsLists;
|
||||
};
|
||||
|
||||
@@ -222,55 +227,22 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
*/
|
||||
size_t GetCurrentConditionDepth() const { return customConditionDepth; }
|
||||
|
||||
/**
|
||||
* \brief Returns the list of all objects declared in this context
|
||||
* and subcontexts.
|
||||
* \warning Only works on an async callback's context.
|
||||
*
|
||||
* It is to be used by the Async event code generator to know what objects
|
||||
* lists to backup for the async callback and async callbacks after it.
|
||||
*/
|
||||
const std::set<gd::String>& GetAllDeclaredObjectsAcrossChildren() {
|
||||
return allObjectsListToBeDeclaredAcrossChildren;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if an object list should be gotten from a backed up
|
||||
* objects list instead of the parent context. This can happen inside an
|
||||
* asynchronous callback or a child context of an asynchronous callback (i.e:
|
||||
* the `asyncDepth` is not 0).
|
||||
*/
|
||||
bool ShouldUseAsyncObjectsList(const gd::String& objectName) const;
|
||||
|
||||
/**
|
||||
* Returns true if the code currently being generated is inside an
|
||||
* asynchronous context (either in an asynchronous callback, or in a children of
|
||||
* an asynchronous callback).
|
||||
*/
|
||||
bool IsInsideAsync() const { return asyncDepth != 0; };
|
||||
|
||||
/**
|
||||
* Returns true if the code currently being generated is an asynchronous
|
||||
* callback (but not a child of an asynchronous callback).
|
||||
*/
|
||||
bool IsAsyncCallback() const { return parent != nullptr && parent->asyncDepth != asyncDepth; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Returns true if the given object is already going to be declared
|
||||
* in this context (either as a traditional objects list, or an empty one).
|
||||
* (either as a traditional objects list, or one without picking, or one
|
||||
* empty).
|
||||
*
|
||||
*/
|
||||
bool IsToBeDeclared(const gd::String& objectName) {
|
||||
return objectsListsToBeDeclared.find(objectName) !=
|
||||
objectsListsToBeDeclared.end() ||
|
||||
objectsListsOrEmptyToBeDeclared.find(objectName) !=
|
||||
objectsListsOrEmptyToBeDeclared.end() ||
|
||||
objectsListsWithoutPickingToBeDeclared.find(objectName) !=
|
||||
objectsListsWithoutPickingToBeDeclared.end() ||
|
||||
emptyObjectsListsToBeDeclared.find(objectName) !=
|
||||
emptyObjectsListsToBeDeclared.end();
|
||||
};
|
||||
|
||||
private:
|
||||
void NotifyAsyncParentsAboutDeclaredObject(const gd::String& objectName);
|
||||
|
||||
std::set<gd::String>
|
||||
alreadyDeclaredObjectsLists; ///< Objects lists already needed in a
|
||||
///< parent context.
|
||||
@@ -278,7 +250,7 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
objectsListsToBeDeclared; ///< Objects lists that will be declared in
|
||||
///< this context.
|
||||
std::set<gd::String>
|
||||
objectsListsOrEmptyToBeDeclared; ///< Objects lists that will be
|
||||
objectsListsWithoutPickingToBeDeclared; ///< Objects lists that will be
|
||||
///< declared in this context,
|
||||
///< but not filled with scene's
|
||||
///< objects.
|
||||
@@ -288,40 +260,21 @@ class GD_CORE_API EventsCodeGenerationContext {
|
||||
///< but not filled with scene's
|
||||
///< objects and not filled with any
|
||||
///< previously existing objects list.
|
||||
std::set<gd::String>
|
||||
allObjectsListToBeDeclaredAcrossChildren; ///< This is only to be used by
|
||||
///< the async callback
|
||||
///< contexts to know all
|
||||
///< objects declared across
|
||||
///< all children, so that the
|
||||
///< necessary objects can be
|
||||
///< backed up.
|
||||
|
||||
std::map<gd::String, unsigned int>
|
||||
depthOfLastUse; ///< The context depth when an object was last used.
|
||||
gd::String
|
||||
currentObject; ///< The object being used by an action or condition.
|
||||
unsigned int contextDepth = 0; ///< The depth of the context: 0 for a newly
|
||||
///< created context, n+1 for any context
|
||||
///< inheriting from context with depth n.
|
||||
unsigned int customConditionDepth =
|
||||
0; ///< The depth of the conditions being generated.
|
||||
unsigned int asyncDepth =
|
||||
0; ///< If higher than 0, the current context is an asynchronous callback,
|
||||
///< or a child context of an asynchronous callback:
|
||||
///< - If the parent's async depth != the current context async depth,
|
||||
///< then the current context is an asynchronous callback context.
|
||||
///< - Otherwise, it's a child of an asynchronous callback.
|
||||
unsigned int contextDepth; ///< The depth of the context : 0 for a newly
|
||||
///< created context, n+1 for any context
|
||||
///< inheriting from context with depth n.
|
||||
unsigned int
|
||||
customConditionDepth; ///< The depth of the conditions being generated.
|
||||
unsigned int* maxDepthLevel; ///< A pointer to a unsigned int updated with
|
||||
///< the maximum depth reached.
|
||||
const EventsCodeGenerationContext* parent =
|
||||
nullptr; ///< The parent of the current context. Can be NULL.
|
||||
EventsCodeGenerationContext* nearestAsyncParent =
|
||||
nullptr; ///< The nearest parent context that is an async callback
|
||||
///< context.
|
||||
bool reuseExplicitlyForbidden =
|
||||
false; ///< If set to true, forbid children contexts
|
||||
///< to reuse this one without inheriting.
|
||||
const EventsCodeGenerationContext*
|
||||
parent; ///< The parent of the current context. Can be NULL.
|
||||
bool reuseExplicitlyForbidden; ///< If set to true, forbid children context
|
||||
///< to reuse this one without inheriting.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,8 @@
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
@@ -20,7 +18,6 @@ class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
class ObjectsContainer;
|
||||
class ObjectsContainersList;
|
||||
class ExternalEvents;
|
||||
class ParameterMetadata;
|
||||
class ObjectMetadata;
|
||||
@@ -38,6 +35,10 @@ namespace gd {
|
||||
* \brief Internal class used to generate code from events
|
||||
*/
|
||||
class GD_CORE_API EventsCodeGenerator {
|
||||
// Compatiblity with old ExpressionParser
|
||||
friend class CallbacksForGeneratingExpressionCode;
|
||||
friend class VariableCodeGenerationCallbacks;
|
||||
// end of compatibility code
|
||||
friend class ExpressionCodeGenerator;
|
||||
|
||||
public:
|
||||
@@ -50,7 +51,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \brief Construct a code generator for the specified
|
||||
* platform/project/layout.
|
||||
*/
|
||||
EventsCodeGenerator(const gd::Project& project_,
|
||||
EventsCodeGenerator(gd::Project& project_,
|
||||
const gd::Layout& layout,
|
||||
const gd::Platform& platform_);
|
||||
|
||||
@@ -58,9 +59,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \brief Construct a code generator for the specified
|
||||
* objects/groups and platform
|
||||
*/
|
||||
EventsCodeGenerator(
|
||||
const gd::Platform& platform,
|
||||
const gd::ProjectScopedContainers& projectScopedContainers_);
|
||||
EventsCodeGenerator(const gd::Platform& platform,
|
||||
gd::ObjectsContainer& globalObjectsAndGroups_,
|
||||
const gd::ObjectsContainer& objectsAndGroups_);
|
||||
virtual ~EventsCodeGenerator(){};
|
||||
|
||||
/**
|
||||
@@ -79,7 +80,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \return Code
|
||||
*/
|
||||
virtual gd::String GenerateEventsListCode(
|
||||
gd::EventsList& events, EventsCodeGenerationContext& context);
|
||||
gd::EventsList& events, const EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate code for executing a condition list
|
||||
@@ -126,7 +127,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*
|
||||
*/
|
||||
std::vector<gd::String> GenerateParametersCodes(
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const std::vector<gd::Expression> & parameters,
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfo,
|
||||
EventsCodeGenerationContext& context,
|
||||
std::vector<std::pair<gd::String, gd::String> >*
|
||||
@@ -156,54 +157,8 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \param context Context used for generation
|
||||
* \return Code
|
||||
*/
|
||||
gd::String GenerateActionCode(
|
||||
gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
|
||||
struct CallbackDescriptor {
|
||||
CallbackDescriptor(const gd::String functionName_,
|
||||
const gd::String argumentsList_,
|
||||
const std::set<gd::String> requiredObjects_)
|
||||
: functionName(functionName_),
|
||||
argumentsList(argumentsList_),
|
||||
requiredObjects(requiredObjects_){};
|
||||
/**
|
||||
* The name by which the function can be invoked.
|
||||
*/
|
||||
const gd::String functionName;
|
||||
/**
|
||||
* The comma separated list of arguments that the function takes.
|
||||
*/
|
||||
const gd::String argumentsList;
|
||||
/**
|
||||
* A set of all objects that need to be backed up to be passed to the
|
||||
* callback code.
|
||||
*/
|
||||
const std::set<gd::String> requiredObjects;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Generates actions and events as a callback.
|
||||
*
|
||||
* This is used by asynchronous functions to run the code out of the normal
|
||||
* events flow.
|
||||
*
|
||||
* \returns A set with all objects required by the callback code.
|
||||
* The caller must take care of backing them up in a LongLivedObjectsList,
|
||||
* and to pass it to the callback function as the last argument.
|
||||
*/
|
||||
virtual const CallbackDescriptor GenerateCallback(
|
||||
const gd::String& callbackFunctionName,
|
||||
gd::EventsCodeGenerationContext& parentContext,
|
||||
gd::InstructionsList& actions,
|
||||
gd::EventsList* subEvents = nullptr);
|
||||
|
||||
/**
|
||||
* \brief Generates the parameters list of an event's generated function.
|
||||
*/
|
||||
const gd::String GenerateEventsParameters(
|
||||
const gd::EventsCodeGenerationContext& context);
|
||||
gd::String GenerateActionCode(gd::Instruction& action,
|
||||
EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate code for declaring objects lists.
|
||||
@@ -328,12 +283,18 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
bool ErrorOccurred() const { return errorOccurred; };
|
||||
|
||||
const gd::ObjectsContainersList& GetObjectsContainersList() const {
|
||||
return projectScopedContainers.GetObjectsContainersList();
|
||||
};
|
||||
/**
|
||||
* \brief Get the global objects/groups used for code generation.
|
||||
*/
|
||||
gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
|
||||
return globalObjectsAndGroups;
|
||||
}
|
||||
|
||||
const gd::ProjectScopedContainers& GetProjectScopedContainers() const {
|
||||
return projectScopedContainers;
|
||||
/**
|
||||
* \brief Get the objects/groups used for code generation.
|
||||
*/
|
||||
const gd::ObjectsContainer& GetObjectsAndGroups() const {
|
||||
return objectsAndGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,7 +307,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* \brief Get the project the code is being generated for.
|
||||
* \warning This is only valid if HasProjectAndLayout() is true.
|
||||
*/
|
||||
const gd::Project& GetProject() const { return *project; }
|
||||
gd::Project& GetProject() const { return *project; }
|
||||
|
||||
/**
|
||||
* \brief Get the layout the code is being generated for.
|
||||
@@ -359,6 +320,22 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
*/
|
||||
const gd::Platform& GetPlatform() const { return platform; }
|
||||
|
||||
/**
|
||||
* \brief Convert a group name to the full list of objects contained in the
|
||||
* group.
|
||||
*
|
||||
* Get a list containing the "real" objects name when the events refers to \a
|
||||
* objectName :<br> If \a objectName if really an object, the list will only
|
||||
* contains \a objectName unchanged.<br> If \a objectName is a group, the list
|
||||
* will contains all the objects of the group.<br> If \a objectName is the
|
||||
* "current" object in the context ( i.e: The object being used for launching
|
||||
* an action... ), none of the two rules below apply, and the list will only
|
||||
* contains the context "current" object name.
|
||||
*/
|
||||
std::vector<gd::String> ExpandObjectsName(
|
||||
const gd::String& objectName,
|
||||
const EventsCodeGenerationContext& context) const;
|
||||
|
||||
/**
|
||||
* \brief Get the maximum depth of custom conditions reached during code
|
||||
* generation.
|
||||
@@ -384,18 +361,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the full name for accessing to a boolean variable used for
|
||||
* conditions.
|
||||
*
|
||||
* Default implementation just returns the boolean name passed as argument.
|
||||
*/
|
||||
virtual gd::String GenerateUpperScopeBooleanFullName(
|
||||
const gd::String& boolName,
|
||||
const gd::EventsCodeGenerationContext& context) {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Must create a boolean. Its value must be false.
|
||||
*
|
||||
@@ -450,32 +415,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
|
||||
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
|
||||
|
||||
/**
|
||||
* Generate a single unique number for the specified instruction.
|
||||
*
|
||||
* This is useful for instructions that need to identify themselves in the
|
||||
* generated code like the "Trigger Once" conditions. The id is stable across
|
||||
* code generations if the instructions are the same objects in memory.
|
||||
*
|
||||
* Note that if this function is called multiple times with the same
|
||||
* instruction, the unique number returned will be *different*. This is
|
||||
* because a single instruction might appear at multiple places in events due
|
||||
* to the usage of links.
|
||||
*/
|
||||
size_t GenerateSingleUsageUniqueIdFor(const gd::Instruction* instruction);
|
||||
|
||||
/**
|
||||
* Generate a single unique number for an events list.
|
||||
*
|
||||
* This is useful to create unique function names for events list, that are
|
||||
* stable across code generation given the exact same list of events. They are
|
||||
* *not* stable if events are moved/reorganized.
|
||||
*/
|
||||
size_t GenerateSingleUsageUniqueIdForEventsList();
|
||||
|
||||
virtual const gd::String GenerateRelationalOperatorCodes(
|
||||
const gd::String& operatorString);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Generate the code for a single parameter.
|
||||
@@ -485,9 +424,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* - object : Object name -> string
|
||||
* - expression : Mathematical expression -> number (double)
|
||||
* - string : %Text expression -> string
|
||||
* - layer, color, file, stringWithSelector : Same as string
|
||||
* - layer, color, file, joyaxis : Same as string
|
||||
* - relationalOperator : Used to make a comparison between the function
|
||||
return value and value of the parameter preceding the relationOperator
|
||||
resturn value and value of the parameter preceding the relationOperator
|
||||
parameter -> string
|
||||
* - operator : Used to update a value using a setter and a getter -> string
|
||||
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
|
||||
@@ -503,18 +442,28 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* Other standard parameters type that should be implemented by platforms:
|
||||
* - currentScene: Reference to the current runtime scene.
|
||||
* - objectList : a map containing lists of objects which are specified by the
|
||||
object name in another parameter.
|
||||
* - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick
|
||||
object if they are not already picked.
|
||||
* - objectPtr: Return a reference to the object specified by the object name
|
||||
in another parameter. Example:
|
||||
object name in another parameter. (C++: std::map <gd::String,
|
||||
std::vector<RuntimeObject*> *>). Example:
|
||||
* \code
|
||||
AddExpression("Count", _("Object count"), _("Count the number of picked
|
||||
objects"), _("Objects"), "res/conditions/nbObjet.png")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.SetFunctionName("PickedObjectsCount").SetIncludeFile("GDCpp/Extensions/Builtin/ObjectTools.h");
|
||||
|
||||
* \endcode
|
||||
* - objectListWithoutPicking : Same as objectList but do not pick object if
|
||||
they are not already picked.
|
||||
* - objectPtr : Return a pointer to object specified by the object name in
|
||||
another parameter ( C++: RuntimeObject* ). Example:
|
||||
* \code
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectPtr", _("Target object"))
|
||||
//The called function will be called with this signature on the C++ platform:
|
||||
Function(gd::String, RuntimeObject*)
|
||||
* \endcode
|
||||
*/
|
||||
virtual gd::String GenerateParameterCodes(
|
||||
const gd::Expression& parameter,
|
||||
const gd::String& parameter,
|
||||
const gd::ParameterMetadata& metadata,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& lastObjectName,
|
||||
@@ -546,12 +495,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return ".getChild(" + ConvertToStringExplicit(childName) + ")";
|
||||
};
|
||||
|
||||
virtual gd::String GenerateVariableValueAs(const gd::String& type) {
|
||||
return type == "number|string" ? ".getAsNumberOrString()"
|
||||
: type == "string" ? ".getAsString()"
|
||||
: ".getAsNumber()";
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the code to get the child of a variable,
|
||||
* using generated the expression.
|
||||
@@ -580,17 +523,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return "fakeObjectListOf_" + objectName;
|
||||
}
|
||||
|
||||
virtual gd::String GeneratePropertyGetter(
|
||||
const gd::PropertiesContainer& propertiesContainer,
|
||||
const gd::NamedPropertyDescriptor& property,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateParameterGetter(
|
||||
const gd::ParameterMetadata& parameter,
|
||||
const gd::String& type,
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
/**
|
||||
* \brief Generate the code to reference an object which is
|
||||
* in an empty/null state.
|
||||
@@ -665,16 +597,28 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Must negate a predicate.
|
||||
* \brief Must negate a predicat.
|
||||
*
|
||||
* The default implementation generates C-style code : It wraps the predicate
|
||||
* The default implementation generates C-style code : It wraps the predicat
|
||||
* inside parenthesis and add a !.
|
||||
*/
|
||||
virtual gd::String GenerateNegatedPredicate(
|
||||
const gd::String& predicate) const {
|
||||
return "!(" + predicate + ")";
|
||||
virtual gd::String GenerateNegatedPredicat(const gd::String& predicat) const {
|
||||
return "!(" + predicat + ")";
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Must create a boolean which is a reference to a boolean declared in
|
||||
* the parent scope.
|
||||
*
|
||||
* The default implementation generates C-style code.
|
||||
*/
|
||||
virtual gd::String GenerateReferenceToUpperScopeBoolean(
|
||||
const gd::String& referenceName,
|
||||
const gd::String& referencedBoolean,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
return "bool & " + referenceName + " = " + referencedBoolean + ";\n";
|
||||
}
|
||||
|
||||
virtual gd::String GenerateFreeCondition(
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
@@ -702,30 +646,24 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateFreeAction(
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateObjectAction(
|
||||
const gd::String& objectName,
|
||||
const gd::ObjectMetadata& objInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
virtual gd::String GenerateBehaviorAction(
|
||||
const gd::String& objectName,
|
||||
const gd::String& behaviorName,
|
||||
const gd::BehaviorMetadata& autoInfo,
|
||||
const gd::String& functionCallName,
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
gd::EventsCodeGenerationContext& context,
|
||||
const gd::String& optionalAsyncCallbackName = "");
|
||||
gd::EventsCodeGenerationContext& context);
|
||||
|
||||
gd::String GenerateRelationalOperatorCall(
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
@@ -770,19 +708,19 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
/**
|
||||
* Generate the getter to get the name of the specified behavior.
|
||||
*/
|
||||
virtual gd::String GenerateGetBehaviorNameCode(
|
||||
const gd::String& behaviorName);
|
||||
virtual gd::String GenerateGetBehaviorNameCode(const gd::String& behaviorName);
|
||||
|
||||
const gd::Platform& platform; ///< The platform being used.
|
||||
|
||||
gd::ProjectScopedContainers projectScopedContainers;
|
||||
gd::ObjectsContainer& globalObjectsAndGroups;
|
||||
const gd::ObjectsContainer& objectsAndGroups;
|
||||
|
||||
bool hasProjectAndLayout; ///< true only if project and layout are valid
|
||||
///< references. If false, they should not be used.
|
||||
const gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
|
||||
bool errorOccurred; ///< Must be set to true if an error occurred.
|
||||
bool errorOccurred; ///< Must be set to true if an error occured.
|
||||
bool compilationForRuntime; ///< Is set to true if the code generation is
|
||||
///< made for runtime only.
|
||||
|
||||
@@ -798,11 +736,6 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
size_t maxCustomConditionsDepth; ///< The maximum depth value for all the
|
||||
///< custom conditions created.
|
||||
size_t maxConditionsListsSize; ///< The maximum size of a list of conditions.
|
||||
|
||||
std::set<size_t>
|
||||
instructionUniqueIds; ///< The unique ids generated for instructions.
|
||||
size_t eventsListNextUniqueId; ///< The next identifier to use for an events
|
||||
///< list function name.
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,11 +4,8 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "ExpressionCodeGenerator.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
@@ -26,40 +23,132 @@
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/VariablesContainersList.h"
|
||||
#include "GDCore/Project/ObjectsContainersList.h"
|
||||
#include "GDCore/Project/ProjectScopedContainers.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
|
||||
|
||||
// Compatibility with old ExpressionParser
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/Events/CodeGeneration/VariableParserCallbacks.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
// end of compatibility code
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool ExpressionCodeGenerator::useOldExpressionParser = false;
|
||||
|
||||
gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
EventsCodeGenerator& codeGenerator,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& rootType,
|
||||
const gd::Expression& expression,
|
||||
const gd::String& rootObjectName) {
|
||||
ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context);
|
||||
const gd::String& type,
|
||||
const gd::String& expression,
|
||||
const gd::String& objectName) {
|
||||
// Compatibility with old ExpressionParser
|
||||
if (useOldExpressionParser) {
|
||||
if (type == "number") {
|
||||
gd::String code = "";
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
code, codeGenerator, context);
|
||||
gd::ExpressionParser parser(expression);
|
||||
if (!parser.ParseMathExpression(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
code.empty()) {
|
||||
std::cout << "Error (old ExpressionParser): \""
|
||||
<< parser.GetFirstError() << "\" in: \"" << expression
|
||||
<< "\" (number)" << std::endl;
|
||||
code = "0";
|
||||
}
|
||||
|
||||
auto node = expression.GetRootNode();
|
||||
if (!node) {
|
||||
std::cout << "Error: error while parsing: \"" << expression.GetPlainString()
|
||||
<< "\" (" << rootType << ")" << std::endl;
|
||||
return code;
|
||||
} else if (type == "string") {
|
||||
gd::String code = "";
|
||||
gd::CallbacksForGeneratingExpressionCode callbacks(
|
||||
code, codeGenerator, context);
|
||||
gd::ExpressionParser parser(expression);
|
||||
if (!parser.ParseStringExpression(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
callbacks) ||
|
||||
code.empty()) {
|
||||
std::cout << "Error (old ExpressionParser): \""
|
||||
<< parser.GetFirstError() << "\" in: \"" << expression
|
||||
<< "\" (string)" << std::endl;
|
||||
code = "\"\"";
|
||||
}
|
||||
|
||||
return generator.GenerateDefaultValue(rootType);
|
||||
return code;
|
||||
} else if (type == "scenevar") {
|
||||
gd::String code = "";
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code,
|
||||
codeGenerator,
|
||||
context,
|
||||
gd::EventsCodeGenerator::LAYOUT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
} else if (type == "globalvar") {
|
||||
gd::String code = "";
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code,
|
||||
codeGenerator,
|
||||
context,
|
||||
gd::EventsCodeGenerator::PROJECT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
} else if (type == "objectvar") {
|
||||
gd::String code = "";
|
||||
|
||||
// Object is either the object of the previous parameter or, if it is
|
||||
// empty, the object being picked by the instruction.
|
||||
gd::String object =
|
||||
objectName.empty() ? context.GetCurrentObject() : objectName;
|
||||
|
||||
gd::VariableCodeGenerationCallbacks callbacks(
|
||||
code, codeGenerator, context, object);
|
||||
|
||||
gd::VariableParser parser(expression);
|
||||
if (!parser.Parse(callbacks)) {
|
||||
std::cout << "Error (old VariableParser) :" << parser.GetFirstError()
|
||||
<< " in: " << expression << std::endl;
|
||||
code = codeGenerator.GenerateBadVariable();
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
std::cout << "Type error (old ExpressionParser): type \"" << type
|
||||
<< "\" is not supported" << std::endl;
|
||||
return "/* Error during code generation: type " + type +
|
||||
" is not supported for old ExpressionParser. */ 0";
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType);
|
||||
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups());
|
||||
auto node = parser.ParseExpression(type, expression, objectName);
|
||||
gd::ExpressionValidator validator;
|
||||
node->Visit(validator);
|
||||
if (!validator.GetFatalErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
|
||||
<< "\" in: \"" << expression.GetPlainString() << "\" ("
|
||||
<< rootType << ")" << std::endl;
|
||||
|
||||
return generator.GenerateDefaultValue(rootType);
|
||||
ExpressionCodeGenerator generator(codeGenerator, context);
|
||||
if (!validator.GetErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
|
||||
<< "\" in: \"" << expression << "\" (" << type << ")"
|
||||
<< std::endl;
|
||||
|
||||
return generator.GenerateDefaultValue(type);
|
||||
}
|
||||
|
||||
node->Visit(generator);
|
||||
@@ -102,96 +191,27 @@ void ExpressionCodeGenerator::OnVisitTextNode(TextNode& node) {
|
||||
void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
|
||||
// This "translation" from the type to an enum could be avoided
|
||||
// if all types were moved to an enum.
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
EventsCodeGenerator::VariableScope scope =
|
||||
node.type == "globalvar"
|
||||
? gd::EventsCodeGenerator::PROJECT_VARIABLE
|
||||
: ((node.type == "scenevar")
|
||||
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
|
||||
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
|
||||
|
||||
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 == "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);
|
||||
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.
|
||||
|
||||
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.name, [&](){
|
||||
// Generate the code to access the object variables.
|
||||
|
||||
// Defer generation of the access to the object and variable to the child,
|
||||
// once we know the name of the variable.
|
||||
objectNameToUseForVariableAccessor = node.name;
|
||||
if (node.child) node.child->Visit(*this);
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
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);
|
||||
}, [&]() {
|
||||
// Properties are not supported.
|
||||
output += GenerateDefaultValue(type);
|
||||
}, [&]() {
|
||||
// Parameters are not supported.
|
||||
output += GenerateDefaultValue(type);
|
||||
}, [&]() {
|
||||
// The identifier does not represents a variable (or a child variable), or not at least an existing
|
||||
// one, nor an object variable. It's invalid.
|
||||
output += GenerateDefaultValue(type);
|
||||
});
|
||||
}
|
||||
output += codeGenerator.GenerateGetVariable(
|
||||
node.name, scope, context, node.objectName);
|
||||
if (node.child) node.child->Visit(*this);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// We have accessed an object variable, from now we can continue accessing the child variables
|
||||
// (including using the bracket notation).
|
||||
objectNameToUseForVariableAccessor = "";
|
||||
} else {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.name);
|
||||
}
|
||||
output += codeGenerator.GenerateVariableAccessor(node.name);
|
||||
if (node.child) node.child->Visit(*this);
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) {
|
||||
if (!objectNameToUseForVariableAccessor.empty()) {
|
||||
// Bracket notation can't be used to directly access a variable of an object (`MyObject["MyVariable"]`).
|
||||
// This would be rejected by the ExpressionValidator.
|
||||
output += codeGenerator.GenerateBadVariable();
|
||||
return;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerator generator("number|string", "", codeGenerator, context);
|
||||
ExpressionCodeGenerator generator(codeGenerator, context);
|
||||
node.expression->Visit(generator);
|
||||
output +=
|
||||
codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput());
|
||||
@@ -199,108 +219,39 @@ void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
|
||||
if (gd::ParameterMetadata::IsObject(type)) {
|
||||
if (gd::ParameterMetadata::IsObject(node.type)) {
|
||||
output +=
|
||||
codeGenerator.GenerateObject(node.identifierName, type, context);
|
||||
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
|
||||
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);
|
||||
if (!node.childIdentifierName.empty()) {
|
||||
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
|
||||
}
|
||||
codeGenerator.GenerateObject(node.identifierName, node.type, context);
|
||||
} else {
|
||||
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList();
|
||||
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList();
|
||||
const auto& parametersVectorsList = codeGenerator.GetProjectScopedContainers().GetParametersVectorsList();
|
||||
|
||||
// The node represents a variable, property, parameter or an object.
|
||||
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);
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
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);
|
||||
}
|
||||
output += codeGenerator.GenerateVariableValueAs(type);
|
||||
}, [&]() {
|
||||
const auto& propertiesContainerAndProperty = propertiesContainersList.Get(node.identifierName);
|
||||
|
||||
output += codeGenerator.GeneratePropertyGetter(
|
||||
propertiesContainerAndProperty.first, propertiesContainerAndProperty.second, type, context);
|
||||
}, [&]() {
|
||||
const auto& parameter = gd::ParameterMetadataTools::Get(parametersVectorsList, node.identifierName);
|
||||
output += codeGenerator.GenerateParameterGetter(parameter, type, context);
|
||||
}, [&]() {
|
||||
// The identifier does not represents a variable (or a child variable), or not at least an existing
|
||||
// one, nor an object variable. It's invalid.
|
||||
output += GenerateDefaultValue(type);
|
||||
});
|
||||
output += "/* Error during generation, unrecognized identifier type: " +
|
||||
codeGenerator.ConvertToString(node.type) + " with value " +
|
||||
codeGenerator.ConvertToString(node.identifierName) + " */ " +
|
||||
codeGenerator.ConvertToStringExplicit(node.identifierName);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
|
||||
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
|
||||
codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
node);
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
void ExpressionCodeGenerator::OnVisitFunctionNode(FunctionNode& node) {
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(node.expressionMetadata)) {
|
||||
output += "/* Error during generation, function not found: " +
|
||||
codeGenerator.ConvertToString(node.functionName) + " */ " +
|
||||
GenerateDefaultValue(type);
|
||||
codeGenerator.ConvertToString(node.functionName) + " for type " +
|
||||
node.type + " */ " + GenerateDefaultValue(node.type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node.objectName.empty()) {
|
||||
if (!node.behaviorName.empty()) {
|
||||
output += GenerateBehaviorFunctionCode(type,
|
||||
output += GenerateBehaviorFunctionCode(node.type,
|
||||
node.objectName,
|
||||
node.behaviorName,
|
||||
node.parameters,
|
||||
metadata);
|
||||
node.expressionMetadata);
|
||||
} else {
|
||||
output += GenerateObjectFunctionCode(
|
||||
type, node.objectName, node.parameters, metadata);
|
||||
node.type, node.objectName, node.parameters, node.expressionMetadata);
|
||||
}
|
||||
} else {
|
||||
output +=
|
||||
GenerateFreeFunctionCode(node.parameters, metadata);
|
||||
GenerateFreeFunctionCode(node.parameters, node.expressionMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,10 +259,10 @@ gd::String ExpressionCodeGenerator::GenerateFreeFunctionCode(
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -328,11 +279,16 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
const gd::String& objectName,
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups =
|
||||
codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups =
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -348,22 +304,23 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
codeGenerator.ExpandObjectsName(objectName, context);
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
gd::String objectType = codeGenerator.GetObjectsContainersList().GetTypeOfObject(realObjects[i]);
|
||||
gd::String objectType = gd::GetTypeOfObject(
|
||||
globalObjectsAndGroups, objectsAndGroups, realObjects[i]);
|
||||
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
|
||||
codeGenerator.GetPlatform(), objectType);
|
||||
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
functionOutput = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
objInfo,
|
||||
expressionMetadata.codeExtraInformation,
|
||||
parametersCode,
|
||||
functionOutput,
|
||||
context);
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
functionOutput = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
objInfo,
|
||||
expressionMetadata.codeExtraInformation,
|
||||
parametersCode,
|
||||
functionOutput,
|
||||
context);
|
||||
}
|
||||
|
||||
return functionOutput;
|
||||
@@ -374,11 +331,16 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
|
||||
const gd::String& behaviorName,
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups =
|
||||
codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups =
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -392,11 +354,12 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject());
|
||||
codeGenerator.ExpandObjectsName(objectName, context);
|
||||
|
||||
gd::String functionOutput = GenerateDefaultValue(type);
|
||||
|
||||
gd::String behaviorType = codeGenerator.GetObjectsContainersList().GetTypeOfBehavior(behaviorName);
|
||||
gd::String behaviorType = gd::GetTypeOfBehavior(
|
||||
globalObjectsAndGroups, objectsAndGroups, behaviorName);
|
||||
const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata(
|
||||
codeGenerator.GetPlatform(), behaviorType);
|
||||
|
||||
@@ -430,20 +393,18 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
|
||||
|
||||
auto& parameterMetadata = expressionMetadata.parameters[i];
|
||||
if (!parameterMetadata.IsCodeOnly()) {
|
||||
ExpressionCodeGenerator generator(codeGenerator, context);
|
||||
if (nonCodeOnlyParameterIndex < parameters.size()) {
|
||||
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetObjectsContainersList(),
|
||||
rootObjectName,
|
||||
*parameters[nonCodeOnlyParameterIndex].get());
|
||||
ExpressionCodeGenerator generator(parameterMetadata.GetType(), objectName, codeGenerator, context);
|
||||
parameters[nonCodeOnlyParameterIndex]->Visit(generator);
|
||||
parametersCode += generator.GetOutput();
|
||||
} else if (parameterMetadata.IsOptional()) {
|
||||
ExpressionCodeGenerator generator(parameterMetadata.GetType(), "", codeGenerator, context);
|
||||
// Optional parameters default value were not parsed at the time of the
|
||||
// expression parsing. Parse them now.
|
||||
ExpressionParser2 parser;
|
||||
auto node = parser.ParseExpression(parameterMetadata.GetDefaultValue());
|
||||
ExpressionParser2 parser(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetGlobalObjectsAndGroups(),
|
||||
codeGenerator.GetObjectsAndGroups());
|
||||
auto node = parser.ParseExpression(parameterMetadata.GetType(),
|
||||
parameterMetadata.GetDefaultValue());
|
||||
|
||||
node->Visit(generator);
|
||||
parametersCode += generator.GetOutput();
|
||||
@@ -493,28 +454,12 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
|
||||
if (gd::ParameterMetadata::IsObject(type)) {
|
||||
return codeGenerator.GenerateBadObject();
|
||||
}
|
||||
if (gd::ParameterMetadata::IsExpression("string", type)) {
|
||||
return "\"\"";
|
||||
}
|
||||
|
||||
return "0";
|
||||
return (type == "string") ? "\"\"" : "0";
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
output += GenerateDefaultValue(type);
|
||||
}
|
||||
|
||||
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
|
||||
ObjectFunctionNameNode& node) {
|
||||
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
|
||||
codeGenerator.GetProjectScopedContainers(),
|
||||
rootType,
|
||||
node);
|
||||
output += GenerateDefaultValue(type);
|
||||
output += GenerateDefaultValue(node.type);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -34,11 +35,9 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
public:
|
||||
ExpressionCodeGenerator(const gd::String &rootType_,
|
||||
const gd::String &rootObjectName_,
|
||||
EventsCodeGenerator& codeGenerator_,
|
||||
ExpressionCodeGenerator(EventsCodeGenerator& codeGenerator_,
|
||||
EventsCodeGenerationContext& context_)
|
||||
: rootType(rootType_), rootObjectName(rootObjectName_), codeGenerator(codeGenerator_), context(context_){};
|
||||
: codeGenerator(codeGenerator_), context(context_){};
|
||||
virtual ~ExpressionCodeGenerator(){};
|
||||
|
||||
/**
|
||||
@@ -58,9 +57,14 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
static gd::String GenerateExpressionCode(EventsCodeGenerator& codeGenerator,
|
||||
EventsCodeGenerationContext& context,
|
||||
const gd::String& type,
|
||||
const gd::Expression& expression,
|
||||
const gd::String& expression,
|
||||
const gd::String& objectName = "");
|
||||
|
||||
static void UseOldExpressionParser(bool enable) {
|
||||
useOldExpressionParser = enable;
|
||||
};
|
||||
static bool IsUsingOldExpressionParser() { return useOldExpressionParser; };
|
||||
|
||||
const gd::String& GetOutput() { return output; };
|
||||
|
||||
protected:
|
||||
@@ -74,8 +78,7 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
void OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) override;
|
||||
void OnVisitIdentifierNode(IdentifierNode& node) override;
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override;
|
||||
void OnVisitFunctionCallNode(FunctionCallNode& node) override;
|
||||
void OnVisitFunctionNode(FunctionNode& node) override;
|
||||
void OnVisitEmptyNode(EmptyNode& node) override;
|
||||
|
||||
private:
|
||||
@@ -102,14 +105,13 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters);
|
||||
|
||||
gd::String output;
|
||||
gd::String objectNameToUseForVariableAccessor;
|
||||
EventsCodeGenerator& codeGenerator;
|
||||
EventsCodeGenerationContext& context;
|
||||
const gd::String rootType;
|
||||
const gd::String rootObjectName;
|
||||
|
||||
static bool useOldExpressionParser;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_ExpressionCodeGenerator_H
|
||||
#endif
|
||||
#endif
|
229
Core/GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.cpp
Normal file
229
Core/GDCore/Events/CodeGeneration/ExpressionsCodeGeneration.cpp
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "ExpressionsCodeGeneration.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/Events/Tools/EventsCodeNameMangler.h"
|
||||
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
CallbacksForGeneratingExpressionCode::CallbacksForGeneratingExpressionCode(
|
||||
gd::String& plainExpression_,
|
||||
EventsCodeGenerator& codeGenerator_,
|
||||
EventsCodeGenerationContext& context_)
|
||||
: plainExpression(plainExpression_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_) {}
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnConstantToken(gd::String text) {
|
||||
plainExpression += text;
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnStaticFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Special case: For strings expressions, function without name is a string.
|
||||
if (GetReturnType() == "string" && functionName.empty()) {
|
||||
if (parameters.empty()) return;
|
||||
plainExpression +=
|
||||
codeGenerator.ConvertToStringExplicit(parameters[0].GetPlainString());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 0; i < parametersCode.size(); ++i) {
|
||||
if (i != 0) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
plainExpression += expressionInfo.codeExtraInformation.functionCallName +
|
||||
"(" + parametersStr + ")";
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnObjectFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups = codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups = codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
if (parameters.empty()) return;
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 1; i < parametersCode.size(); ++i) {
|
||||
if (i != 1) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
gd::String output = GetReturnType() == "string" ? "\"\"" : "0";
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(parameters[0].GetPlainString(), context);
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
gd::String objectType = gd::GetTypeOfObject(globalObjectsAndGroups, objectsAndGroups, realObjects[i]);
|
||||
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
|
||||
codeGenerator.GetPlatform(), objectType);
|
||||
|
||||
// Build gd::String to access the object
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
output = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
objInfo,
|
||||
expressionInfo.codeExtraInformation,
|
||||
parametersStr,
|
||||
output,
|
||||
context);
|
||||
}
|
||||
|
||||
plainExpression += output;
|
||||
};
|
||||
|
||||
void CallbacksForGeneratingExpressionCode::OnObjectBehaviorFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo) {
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups = codeGenerator.GetGlobalObjectsAndGroups();
|
||||
const gd::ObjectsContainer& objectsAndGroups = codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionInfo.codeExtraInformation.GetIncludeFiles());
|
||||
if (parameters.size() < 2) return;
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionInfo.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
plainExpression += expressionInfo.codeExtraInformation.customCodeGenerator(
|
||||
parameters, codeGenerator, context);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare parameters
|
||||
std::vector<gd::String> parametersCode =
|
||||
codeGenerator.GenerateParametersCodes(
|
||||
parameters, expressionInfo.parameters, context);
|
||||
gd::String parametersStr;
|
||||
for (std::size_t i = 2; i < parametersCode.size(); ++i) {
|
||||
if (i != 2) parametersStr += ", ";
|
||||
parametersStr += parametersCode[i];
|
||||
}
|
||||
|
||||
// Get object(s) concerned by function call
|
||||
std::vector<gd::String> realObjects =
|
||||
codeGenerator.ExpandObjectsName(parameters[0].GetPlainString(), context);
|
||||
|
||||
gd::String output = GetReturnType() == "string" ? "\"\"" : "0";
|
||||
for (std::size_t i = 0; i < realObjects.size(); ++i) {
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
|
||||
// Cast the object if needed
|
||||
gd::String behaviorType =
|
||||
gd::GetTypeOfBehavior(globalObjectsAndGroups, objectsAndGroups, parameters[1].GetPlainString());
|
||||
const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata(
|
||||
codeGenerator.GetPlatform(), behaviorType);
|
||||
|
||||
// Build gd::String to access the behavior
|
||||
codeGenerator.AddIncludeFiles(autoInfo.includeFiles);
|
||||
output = codeGenerator.GenerateObjectBehaviorFunctionCall(
|
||||
realObjects[i],
|
||||
parameters[1].GetPlainString(),
|
||||
autoInfo,
|
||||
expressionInfo.codeExtraInformation,
|
||||
parametersStr,
|
||||
output,
|
||||
context);
|
||||
}
|
||||
|
||||
plainExpression += output;
|
||||
};
|
||||
|
||||
bool CallbacksForGeneratingExpressionCode::OnSubMathExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups,
|
||||
const gd::ObjectsContainer& objectsAndGroups,
|
||||
gd::Expression& expression) {
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForGeneratingExpressionCode callbacks(
|
||||
newExpression, codeGenerator, context);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseMathExpression(platform, globalObjectsAndGroups, objectsAndGroups, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CallbacksForGeneratingExpressionCode::OnSubTextExpression(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& globalObjectsAndGroups,
|
||||
const gd::ObjectsContainer& objectsAndGroups,
|
||||
gd::Expression& expression) {
|
||||
gd::String newExpression;
|
||||
|
||||
CallbacksForGeneratingExpressionCode callbacks(
|
||||
newExpression, codeGenerator, context);
|
||||
|
||||
gd::ExpressionParser parser(expression.GetPlainString());
|
||||
if (!parser.ParseStringExpression(platform, globalObjectsAndGroups, objectsAndGroups, callbacks)) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
firstErrorStr = callbacks.GetFirstError();
|
||||
firstErrorPos = callbacks.GetFirstErrorPosition();
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EXPRESSIONSCODEGENERATION_H
|
||||
#define EXPRESSIONSCODEGENERATION_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class ExpressionMetadata;
|
||||
class Expression;
|
||||
class Project;
|
||||
class Layout;
|
||||
class Layout;
|
||||
class EventsCodeGenerationContext;
|
||||
class EventsCodeGenerator;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
// TODO: Replace and remove (ExpressionCodeGenerator)
|
||||
|
||||
/**
|
||||
* \brief Used to generate code from expressions.
|
||||
*
|
||||
* Usage example :
|
||||
* \code
|
||||
* gd::String expressionOutputCppCode;
|
||||
*
|
||||
* CallbacksForGeneratingExpressionCode callbacks(expressionOutputCppCode,
|
||||
* codeGenerator, context); gd::ExpressionParser
|
||||
* parser(theOriginalGameDevelopExpression);
|
||||
* parser.ParseStringExpression(platform, project, scene, callbacks);
|
||||
*
|
||||
* if (expressionOutputCppCode.empty()) expressionOutputCppCode = "\"\""; //If
|
||||
* generation failed, we make sure output code is not empty. \endcode \see
|
||||
* EventsCodeGenerator
|
||||
*/
|
||||
class GD_CORE_API CallbacksForGeneratingExpressionCode
|
||||
: public gd::ParserCallbacks {
|
||||
public:
|
||||
CallbacksForGeneratingExpressionCode(gd::String& output,
|
||||
EventsCodeGenerator& codeGenerator_,
|
||||
EventsCodeGenerationContext& context_);
|
||||
virtual ~CallbacksForGeneratingExpressionCode(){};
|
||||
|
||||
void OnConstantToken(gd::String text);
|
||||
void OnStaticFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
void OnObjectFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
void OnObjectBehaviorFunction(gd::String functionName,
|
||||
const std::vector<gd::Expression>& parameters,
|
||||
const gd::ExpressionMetadata& expressionInfo);
|
||||
bool OnSubMathExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
bool OnSubTextExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::Expression& expression);
|
||||
|
||||
private:
|
||||
gd::String& plainExpression;
|
||||
EventsCodeGenerator& codeGenerator;
|
||||
EventsCodeGenerationContext& context;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // EXPRESSIONSCODEGENERATION_H
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* GDevelop C++ Platform
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "VariableParserCallbacks.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/CodeGeneration/ExpressionCodeGenerator.h"
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariableCodeGenerationCallbacks::VariableCodeGenerationCallbacks(
|
||||
gd::String& output_,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::EventsCodeGenerator::VariableScope& scope_)
|
||||
: output(output_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_),
|
||||
scope(scope_) {
|
||||
if (scope == gd::EventsCodeGenerator::OBJECT_VARIABLE) {
|
||||
std::cout << "ERROR: Initializing VariableCodeGenerationCallbacks with "
|
||||
"OBJECT_VARIABLE without object.";
|
||||
}
|
||||
}
|
||||
|
||||
VariableCodeGenerationCallbacks::VariableCodeGenerationCallbacks(
|
||||
gd::String& output_,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::String& object_)
|
||||
: output(output_),
|
||||
codeGenerator(codeGenerator_),
|
||||
context(context_),
|
||||
scope(gd::EventsCodeGenerator::OBJECT_VARIABLE),
|
||||
object(object_) {}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnRootVariable(gd::String variableName) {
|
||||
output += codeGenerator.GenerateGetVariable(variableName, scope, context, object);
|
||||
}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnChildVariable(gd::String variableName) {
|
||||
output += codeGenerator.GenerateVariableAccessor(variableName);
|
||||
}
|
||||
|
||||
void VariableCodeGenerationCallbacks::OnChildSubscript(
|
||||
gd::String stringExpression) {
|
||||
gd::String argumentCode = gd::ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
codeGenerator, context, "string", stringExpression);
|
||||
|
||||
output += codeGenerator.GenerateVariableBracketAccessor(argumentCode);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
97
Core/GDCore/Events/CodeGeneration/VariableParserCallbacks.h
Normal file
97
Core/GDCore/Events/CodeGeneration/VariableParserCallbacks.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* GDevelop C++ Platform
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef VARIABLEPARSERCALLBACKS_H
|
||||
#define VARIABLEPARSERCALLBACKS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "EventsCodeGenerator.h"
|
||||
namespace gd {
|
||||
class EventsCodeGenerationContext;
|
||||
} // namespace gd
|
||||
|
||||
// TODO: Replace and remove (ExpressionCodeGenerator)
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Callbacks called to generate the code for getting a variable.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
VariableCodeGenerationCallbacks callbacks(output, eventsCodeGenerator,
|
||||
context, VariableCodeGenerationCallbacks::LAYOUT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(parameter);
|
||||
if ( !parser.Parse(callbacks) )
|
||||
{
|
||||
//Error during parsing the variable name:
|
||||
output = "runtimeContext->GetSceneVariables().GetBadVariable()";
|
||||
}
|
||||
|
||||
//"output" now contains the C++ code to return the variable.
|
||||
\endcode
|
||||
*/
|
||||
class VariableCodeGenerationCallbacks : public gd::VariableParserCallbacks {
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor for generating code for a layout/global
|
||||
* variable. \param output The string in which the code will be generated.
|
||||
* \param codeGenerator The code generator being used.
|
||||
* \param context The current code generation context.
|
||||
* \param scope The scope of the variable being accessed: LAYOUT_VARIABLE,
|
||||
* PROJECT_VARIABLE.
|
||||
*/
|
||||
VariableCodeGenerationCallbacks(gd::String& output,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::EventsCodeGenerator::VariableScope& scope_);
|
||||
/**
|
||||
|
||||
* \brief Default constructor for generating code for an object variable.
|
||||
* \param output The string in which the code will be generated.
|
||||
* \param codeGenerator The code generator being used.
|
||||
* \param context The current code generation context.
|
||||
* \param object The name of the object
|
||||
*/
|
||||
VariableCodeGenerationCallbacks(gd::String& output,
|
||||
gd::EventsCodeGenerator& codeGenerator_,
|
||||
gd::EventsCodeGenerationContext& context_,
|
||||
const gd::String& object);
|
||||
|
||||
/**
|
||||
* \brief Called when the first variable has been parsed.
|
||||
* \param variableName The variable name.
|
||||
*/
|
||||
virtual void OnRootVariable(gd::String variableName);
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable.
|
||||
* \param variableName The child variable name.
|
||||
*/
|
||||
virtual void OnChildVariable(gd::String variableName);
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable using a
|
||||
* string expression in square brackets. \param variableName The expression
|
||||
* used to access the child variable.
|
||||
*/
|
||||
virtual void OnChildSubscript(gd::String stringExpression);
|
||||
|
||||
private:
|
||||
gd::String& output;
|
||||
gd::EventsCodeGenerator& codeGenerator;
|
||||
gd::EventsCodeGenerationContext& context;
|
||||
gd::EventsCodeGenerator::VariableScope scope;
|
||||
const gd::String object; ///< The object name, when scope == OBJECT_VARIABLE.
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VARIABLEPARSERCALLBACKS_H
|
||||
#endif
|
@@ -5,12 +5,8 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
|
||||
@@ -69,41 +65,10 @@ gd::String BaseEvent::GenerateEventCode(
|
||||
return "";
|
||||
}
|
||||
|
||||
void BaseEvent::PreprocessAsyncActions(const gd::Platform& platform) {
|
||||
if (!CanHaveSubEvents()) return;
|
||||
for (const auto& actionsList : GetAllActionsVectors())
|
||||
for (std::size_t aId = 0; aId < actionsList->size(); ++aId) {
|
||||
const auto& action = actionsList->at(aId);
|
||||
const gd::InstructionMetadata& actionMetadata =
|
||||
gd::MetadataProvider::GetActionMetadata(platform, action.GetType());
|
||||
if (actionMetadata.IsAsync() &&
|
||||
(!actionMetadata.IsOptionallyAsync() || action.IsAwaited())) {
|
||||
gd::InstructionsList remainingActions;
|
||||
remainingActions.InsertInstructions(
|
||||
*actionsList, aId + 1, actionsList->size() - 1);
|
||||
gd::AsyncEvent asyncEvent(action, remainingActions, GetSubEvents());
|
||||
|
||||
// Ensure that the local event no longer has any of the actions/subevent
|
||||
// after the async function
|
||||
actionsList->RemoveAfter(aId);
|
||||
GetSubEvents().Clear();
|
||||
|
||||
GetSubEvents().InsertEvent(asyncEvent);
|
||||
|
||||
// We just moved all the rest, there's nothing left to do in this event.
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList) {
|
||||
if (IsDisabled()) return;
|
||||
|
||||
PreprocessAsyncActions(codeGenerator.GetPlatform());
|
||||
|
||||
if (!MustBePreprocessed()) return;
|
||||
if (IsDisabled() || !MustBePreprocessed()) return;
|
||||
|
||||
try {
|
||||
if (type.empty()) return;
|
||||
@@ -141,14 +106,6 @@ void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseEvent::AcceptVisitor(gd::EventVisitor& eventVisitor) {
|
||||
return eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
void BaseEvent::AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const {
|
||||
eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
BaseEventSPtr GD_CORE_API CloneRememberingOriginalEvent(BaseEventSPtr event) {
|
||||
gd::BaseEventSPtr copy(event->Clone());
|
||||
// Original event is either the original event of the copied event, or the
|
||||
|
@@ -10,13 +10,12 @@
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class EventsList;
|
||||
class MainFrameWrapper;
|
||||
class Project;
|
||||
class Layout;
|
||||
class EventsCodeGenerator;
|
||||
@@ -24,9 +23,7 @@ class EventsCodeGenerationContext;
|
||||
class Platform;
|
||||
class SerializerElement;
|
||||
class Instruction;
|
||||
class EventVisitor;
|
||||
class ReadOnlyEventVisitor;
|
||||
} // namespace gd
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -93,8 +90,8 @@ class GD_CORE_API BaseEvent {
|
||||
bool HasSubEvents() const;
|
||||
|
||||
/**
|
||||
* \brief Return a list of all conditions of the event.
|
||||
* \note Used to preprocess or search in the conditions.
|
||||
* Event must be able to return all conditions std::vector they have.
|
||||
* Used to preprocess the conditions.
|
||||
*/
|
||||
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors() {
|
||||
std::vector<gd::InstructionsList*> noConditions;
|
||||
@@ -107,8 +104,8 @@ class GD_CORE_API BaseEvent {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return a list of all actions of the event.
|
||||
* \note Used to preprocess or search in the actions.
|
||||
* Event must be able to return all actions std::vector they have.
|
||||
* Used to preprocess the actions.
|
||||
*/
|
||||
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors() {
|
||||
std::vector<gd::InstructionsList*> noActions;
|
||||
@@ -121,33 +118,15 @@ class GD_CORE_API BaseEvent {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return a list of all strings of the event.
|
||||
* \note Used to preprocess or search in the event strings.
|
||||
* Event must be able to return all expressions they have.
|
||||
* Used to preprocess the expressions.
|
||||
*/
|
||||
virtual std::vector<gd::String> GetAllSearchableStrings() const {
|
||||
std::vector<gd::String> noSearchableStrings;
|
||||
return noSearchableStrings;
|
||||
};
|
||||
|
||||
virtual bool ReplaceAllSearchableStrings(
|
||||
std::vector<gd::String> newSearchableString) {
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Return a list of all expressions of the event, each with their associated metadata.
|
||||
* \note Used to preprocess or search in the expressions of the event.
|
||||
*/
|
||||
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() {
|
||||
std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> > noExpr;
|
||||
virtual std::vector<gd::Expression*> GetAllExpressions() {
|
||||
std::vector<gd::Expression*> noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
virtual std::vector<
|
||||
std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
GetAllExpressionsWithMetadata() const {
|
||||
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
|
||||
noExpr;
|
||||
virtual std::vector<const gd::Expression*> GetAllExpressions() const {
|
||||
std::vector<const gd::Expression*> noExpr;
|
||||
return noExpr;
|
||||
};
|
||||
|
||||
@@ -211,11 +190,6 @@ class GD_CORE_API BaseEvent {
|
||||
gd::EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList);
|
||||
|
||||
/**
|
||||
* A function that turns all async member actions into an Async subevent for code generation.
|
||||
*/
|
||||
void PreprocessAsyncActions(const gd::Platform& platform);
|
||||
|
||||
/**
|
||||
* \brief If MustBePreprocessed is redefined to return true, the
|
||||
* gd::EventMetadata::preprocessing associated to the event will be called to
|
||||
@@ -240,9 +214,6 @@ class GD_CORE_API BaseEvent {
|
||||
*/
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
virtual bool AcceptVisitor(gd::EventVisitor& eventVisitor);
|
||||
virtual void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const;
|
||||
///@}
|
||||
|
||||
/** \name Common properties
|
||||
@@ -281,6 +252,7 @@ class GD_CORE_API BaseEvent {
|
||||
* \brief True if the event should be folded in the events editor.
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
///@}
|
||||
|
||||
std::weak_ptr<gd::BaseEvent>
|
||||
|
@@ -1,76 +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 <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API EventVisitor {
|
||||
public:
|
||||
virtual ~EventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitEvent(gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitLinkEvent(gd::LinkEvent& linkEvent) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyEventVisitor {
|
||||
public:
|
||||
virtual ~ReadOnlyEventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*/
|
||||
virtual void VisitEvent(const gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*/
|
||||
virtual void VisitLinkEvent(const gd::LinkEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* @brief Abort the iteration on the events.
|
||||
*/
|
||||
virtual void StopAnyEventIteration() = 0;
|
||||
};
|
||||
|
||||
}
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "EventsList.h"
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -100,22 +99,6 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
for (std::size_t i = 0; i < GetEventsCount(); ++i) {
|
||||
if (events[i].get() == &eventToMove) {
|
||||
std::shared_ptr<BaseEvent> event = events[i];
|
||||
events.erase(events.begin() + i);
|
||||
|
||||
newEventsList.InsertEvent(event, newPosition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EventsList::EventsList(const EventsList& other) { Init(other); }
|
||||
|
||||
EventsList& EventsList::operator=(const EventsList& other) {
|
||||
|
@@ -52,8 +52,7 @@ class GD_CORE_API EventsList {
|
||||
* \brief Insert the specified event to the list.
|
||||
* \note The event passed by parameter is not copied.
|
||||
* \param event The smart pointer to the event that must be inserted into the
|
||||
* list
|
||||
* \param position Insertion position. If the position is invalid, the
|
||||
* list \param position Insertion position. If the position is invalid, the
|
||||
* object is inserted at the end of the objects list.
|
||||
*/
|
||||
void InsertEvent(std::shared_ptr<gd::BaseEvent> event,
|
||||
@@ -143,25 +142,6 @@ class GD_CORE_API EventsList {
|
||||
*/
|
||||
bool Contains(const gd::BaseEvent& eventToSearch,
|
||||
bool recursive = true) const;
|
||||
|
||||
/**
|
||||
* Move the specified event, that must be in the events list, to another
|
||||
* events list *without* invalidating the event (i.e: without
|
||||
* destroying/cloning it) in memory.
|
||||
*
|
||||
* \warning newEventsList is supposed not to be contained inside the event
|
||||
* (you should not try
|
||||
* to move an event inside one of its children/grand children events).
|
||||
*
|
||||
* \param eventToMove The event to be moved
|
||||
* \param newEventsList The new events list
|
||||
* \param newPosition The position in the new events list
|
||||
* \return true if the move was made, false otherwise (for example, if
|
||||
* eventToMove is not found in the list)
|
||||
*/
|
||||
bool MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition);
|
||||
///@}
|
||||
|
||||
/** \name std::vector API compatibility
|
||||
|
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#include "GDCore/Events/Expression.h"
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
Expression::Expression() : node(nullptr) {};
|
||||
|
||||
Expression::Expression(gd::String plainString_)
|
||||
: node(nullptr), plainString(plainString_) {};
|
||||
|
||||
Expression::Expression(const char* plainString_)
|
||||
: node(nullptr), plainString(plainString_) {};
|
||||
|
||||
Expression::Expression(const Expression& copy)
|
||||
: node(nullptr), plainString{copy.plainString} {};
|
||||
|
||||
Expression& Expression::operator=(const Expression& expression) {
|
||||
plainString = expression.plainString;
|
||||
node = nullptr;
|
||||
return *this;
|
||||
};
|
||||
|
||||
Expression::~Expression(){};
|
||||
|
||||
ExpressionNode* Expression::GetRootNode() const {
|
||||
if (!node) {
|
||||
gd::ExpressionParser2 parser = ExpressionParser2();
|
||||
node = std::move(parser.ParseExpression(plainString));
|
||||
}
|
||||
return node.get();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -6,15 +6,7 @@
|
||||
|
||||
#ifndef GDCORE_EXPRESSION_H
|
||||
#define GDCORE_EXPRESSION_H
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include <memory>
|
||||
|
||||
namespace gd {
|
||||
class ExpressionParser2;
|
||||
class ObjectsContainer;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -32,49 +24,32 @@ class GD_CORE_API Expression {
|
||||
/**
|
||||
* \brief Construct an empty expression
|
||||
*/
|
||||
Expression();
|
||||
Expression(){};
|
||||
|
||||
/**
|
||||
* \brief Construct an expression from a string
|
||||
*/
|
||||
Expression(gd::String plainString_);
|
||||
Expression(gd::String plainString_) : plainString(plainString_){};
|
||||
|
||||
/**
|
||||
* \brief Construct an expression from a const char *
|
||||
*/
|
||||
Expression(const char* plainString_);
|
||||
|
||||
/**
|
||||
* \brief Copy construct an expression.
|
||||
*/
|
||||
Expression(const Expression& copy);
|
||||
|
||||
/**
|
||||
* \brief Expression affectation overriding.
|
||||
*/
|
||||
Expression& operator=(const Expression& expression);
|
||||
Expression(const char* plainString_) : plainString(plainString_){};
|
||||
|
||||
/**
|
||||
* \brief Get the plain string representing the expression
|
||||
*/
|
||||
inline const gd::String& GetPlainString() const { return plainString; };
|
||||
|
||||
/**
|
||||
* @brief Get the expression node.
|
||||
* @return std::unique_ptr<gd::ExpressionNode>
|
||||
*/
|
||||
gd::ExpressionNode* GetRootNode() const;
|
||||
|
||||
/**
|
||||
* \brief Mimics std::string::c_str
|
||||
*/
|
||||
inline const char* c_str() const { return plainString.c_str(); };
|
||||
|
||||
virtual ~Expression();
|
||||
virtual ~Expression(){};
|
||||
|
||||
private:
|
||||
gd::String plainString; ///< The expression string
|
||||
mutable std::unique_ptr<gd::ExpressionNode> node;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,12 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -18,14 +15,18 @@ namespace gd {
|
||||
|
||||
gd::Expression Instruction::badExpression("");
|
||||
|
||||
Instruction::Instruction(gd::String type_) : type(type_), inverted(false) {
|
||||
Instruction::Instruction(gd::String type_)
|
||||
: type(type_),
|
||||
inverted(false) {
|
||||
parameters.reserve(8);
|
||||
}
|
||||
|
||||
Instruction::Instruction(gd::String type_,
|
||||
const std::vector<gd::Expression>& parameters_,
|
||||
bool inverted_)
|
||||
: type(type_), inverted(inverted_), parameters(parameters_) {
|
||||
: type(type_),
|
||||
inverted(inverted_),
|
||||
parameters(parameters_) {
|
||||
parameters.reserve(8);
|
||||
}
|
||||
|
||||
@@ -55,21 +56,4 @@ void Instruction::SetParameter(std::size_t nb, const gd::Expression& val) {
|
||||
parameters[nb] = val;
|
||||
}
|
||||
|
||||
void Instruction::AddParameter(const gd::Expression& val) {
|
||||
parameters.push_back(val);
|
||||
}
|
||||
|
||||
std::shared_ptr<Instruction> GD_CORE_API
|
||||
CloneRememberingOriginalElement(std::shared_ptr<Instruction> instruction) {
|
||||
std::shared_ptr<Instruction> copy =
|
||||
std::make_shared<Instruction>(*instruction);
|
||||
// Original instruction is either the original instruction of the copied
|
||||
// instruction, or the instruction copied.
|
||||
copy->originalInstruction = instruction->originalInstruction.expired()
|
||||
? instruction
|
||||
: instruction->originalInstruction;
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -5,9 +5,7 @@
|
||||
*/
|
||||
#ifndef INSTRUCTION_H
|
||||
#define INSTRUCTION_H
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -72,22 +70,6 @@ class GD_CORE_API Instruction {
|
||||
*/
|
||||
void SetInverted(bool inverted_) { inverted = inverted_; }
|
||||
|
||||
/**
|
||||
* \brief Return true if the async instruction should be awaited.
|
||||
* This is not relevant if the instruction is not optionally asynchronous.
|
||||
*
|
||||
* \return true if the instruction is to be awaited
|
||||
*/
|
||||
bool IsAwaited() const { return awaitAsync; }
|
||||
|
||||
/**
|
||||
* \brief Set if the async instruction is to be awaited or not.
|
||||
* This is not relevant if the instruction is not optionally asynchronous.
|
||||
*
|
||||
* \param inverted true if the instruction must be awaited
|
||||
*/
|
||||
void SetAwaited(bool awaited) { awaitAsync = awaited; }
|
||||
|
||||
/**
|
||||
* \brief Return the number of parameters of the instruction.
|
||||
*/
|
||||
@@ -123,11 +105,6 @@ class GD_CORE_API Instruction {
|
||||
*/
|
||||
void SetParameter(std::size_t nb, const gd::Expression& val);
|
||||
|
||||
/** Add a parameter at the end
|
||||
* \param val The new value of the parameter
|
||||
*/
|
||||
void AddParameter(const gd::Expression& val);
|
||||
|
||||
/** \brief Get a reference to the std::vector containing the parameters.
|
||||
* \return A std::vector containing the parameters
|
||||
*/
|
||||
@@ -154,47 +131,17 @@ class GD_CORE_API Instruction {
|
||||
*/
|
||||
inline gd::InstructionsList& GetSubInstructions() { return subInstructions; };
|
||||
|
||||
/**
|
||||
* \brief Return the original instruction this instruction was copied from.
|
||||
*
|
||||
* Useful to get reference to the original instruction in memory during code
|
||||
* generation, to ensure stable unique identifiers.
|
||||
*/
|
||||
std::weak_ptr<Instruction> GetOriginalInstruction() {
|
||||
return originalInstruction;
|
||||
};
|
||||
|
||||
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
|
||||
std::shared_ptr<Instruction> instruction);
|
||||
|
||||
private:
|
||||
gd::String type; ///< Instruction type
|
||||
bool inverted; ///< True if the instruction if inverted. Only applicable for
|
||||
///< instruction used as conditions by events
|
||||
bool awaitAsync =
|
||||
false; ///< Tells the code generator whether the optionally asynchronous
|
||||
///< instruction should be generated as asynchronous (awaited) or not.
|
||||
mutable std::vector<gd::Expression>
|
||||
parameters; ///< Vector containing the parameters
|
||||
gd::InstructionsList subInstructions; ///< Sub instructions, if applicable.
|
||||
|
||||
std::weak_ptr<Instruction>
|
||||
originalInstruction; ///< Pointer used to remember which gd::Instruction
|
||||
///< this instruction was copied from. Useful to
|
||||
///< ensure the stability of code generation (as
|
||||
///< some part of code generation uses the pointer
|
||||
///< to the instruction as a unique identifier).
|
||||
|
||||
static gd::Expression badExpression;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone the given instruction, returning an instruction for which
|
||||
* `GetOriginalInstruction()` returns the originally copied instruction.
|
||||
*/
|
||||
std::shared_ptr<Instruction> GD_CORE_API
|
||||
CloneRememberingOriginalElement(std::shared_ptr<Instruction> instruction);
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // INSTRUCTION_H
|
||||
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include "InstructionsList.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "Serialization.h"
|
||||
@@ -32,10 +31,6 @@ void InstructionsList::InsertInstructions(const InstructionsList& list,
|
||||
}
|
||||
}
|
||||
|
||||
void InstructionsList::RemoveAfter(const size_t position) {
|
||||
elements.resize(position);
|
||||
}
|
||||
|
||||
void InstructionsList::SerializeTo(SerializerElement& element) const {
|
||||
EventsListSerialization::SerializeInstructionsTo(*this, element);
|
||||
}
|
||||
|
@@ -6,10 +6,9 @@
|
||||
|
||||
#ifndef GDCORE_INSTRUCTIONSLIST_H
|
||||
#define GDCORE_INSTRUCTIONSLIST_H
|
||||
#include "GDCore/Tools/SPtrList.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Tools/SPtrList.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
}
|
||||
@@ -23,11 +22,11 @@ class SerializerElement;
|
||||
namespace gd {
|
||||
|
||||
class InstructionsList : public SPtrList<gd::Instruction> {
|
||||
public:
|
||||
void InsertInstructions(const InstructionsList &list, size_t begin,
|
||||
size_t end, size_t position = (size_t)-1);
|
||||
|
||||
void RemoveAfter(size_t position);
|
||||
public:
|
||||
void InsertInstructions(const InstructionsList& list,
|
||||
size_t begin,
|
||||
size_t end,
|
||||
size_t position = (size_t)-1);
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
@@ -36,17 +35,17 @@ public:
|
||||
* \brief Serialize the instructions to the specified element
|
||||
* \see EventsListSerialization
|
||||
*/
|
||||
void SerializeTo(gd::SerializerElement &element) const;
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Load the instructions from the specified element
|
||||
* \see EventsListSerialization
|
||||
*/
|
||||
void UnserializeFrom(gd::Project &project,
|
||||
const gd::SerializerElement &element);
|
||||
void UnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element);
|
||||
///@}
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
|
897
Core/GDCore/Events/Parsers/ExpressionParser.cpp
Normal file
897
Core/GDCore/Events/Parsers/ExpressionParser.cpp
Normal file
@@ -0,0 +1,897 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/ExpressionParser.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::String ExpressionParser::parserSeparators = " ,+-*/%.<>=&|;()#^![]{}";
|
||||
|
||||
size_t ExpressionParser::GetMinimalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfos) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = 0; i < parametersInfos.size(); ++i) {
|
||||
if (!parametersInfos[i].optional && !parametersInfos[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
size_t ExpressionParser::GetMaximalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfos) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = 0; i < parametersInfos.size(); ++i) {
|
||||
if (!parametersInfos[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add blank parameters when code-only parameters are expected.
|
||||
* \param Parameters information
|
||||
* \param vector of parameters without code only parameters.
|
||||
*/
|
||||
std::vector<gd::Expression> CompleteParameters(
|
||||
const std::vector<gd::ParameterMetadata>& parametersInfo,
|
||||
const std::vector<gd::Expression>& parameters) {
|
||||
std::vector<gd::Expression> completeParameters = parameters;
|
||||
for (std::size_t i = 0; i < parametersInfo.size();
|
||||
++i) // Code only parameters are not included in expressions parameters.
|
||||
{
|
||||
if (parametersInfo[i].codeOnly) {
|
||||
if (i > completeParameters.size()) {
|
||||
cout << "Bad parameter count in expression.";
|
||||
}
|
||||
|
||||
if (i >= completeParameters.size())
|
||||
completeParameters.push_back(gd::Expression(""));
|
||||
else
|
||||
completeParameters.insert(completeParameters.begin() + i,
|
||||
gd::Expression(""));
|
||||
} else {
|
||||
if (i >= completeParameters.size()) {
|
||||
completeParameters.push_back(gd::Expression(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
return completeParameters;
|
||||
}
|
||||
|
||||
bool ExpressionParser::ValidSyntax(const gd::String& str) {
|
||||
static const gd::String numerics = "0123456789.e";
|
||||
static const gd::String operators = "+/*-%";
|
||||
|
||||
size_t parenthesisLevel = 0;
|
||||
gd::String lastOperator;
|
||||
|
||||
bool parsingNumber = false;
|
||||
bool parsingScientificNotationNumber = false;
|
||||
bool parsingDecimalNumber = false;
|
||||
bool requestNumber = false;
|
||||
gd::String lastNumber;
|
||||
bool numberWasParsedLast = false;
|
||||
|
||||
for (auto it = str.begin(); it != str.end(); ++it) {
|
||||
char32_t currentChar = *it;
|
||||
if (currentChar == U' ' || currentChar == U'\n') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
requestNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
} else if (numerics.find(currentChar) != gd::String::npos) {
|
||||
requestNumber = false;
|
||||
|
||||
if (currentChar == U'.') {
|
||||
if (!parsingNumber) {
|
||||
firstErrorStr = _("Syntax error");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingDecimalNumber) {
|
||||
firstErrorStr = _("Syntax error in a number.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingDecimalNumber = true;
|
||||
}
|
||||
|
||||
if (currentChar == U'e') {
|
||||
if (parsingScientificNotationNumber) {
|
||||
firstErrorStr = _("Syntax error in a number.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingScientificNotationNumber = true;
|
||||
requestNumber = true;
|
||||
}
|
||||
|
||||
if (numberWasParsedLast) {
|
||||
firstErrorStr = _("Operator missing before a number");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsingNumber = true;
|
||||
lastNumber += currentChar;
|
||||
} else if (currentChar == U')') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (!numberWasParsedLast) {
|
||||
firstErrorStr = _("Superfluous operator before a paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parenthesisLevel > 0)
|
||||
parenthesisLevel--;
|
||||
else {
|
||||
firstErrorStr = _("Bad closing paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto previousIt = it;
|
||||
--previousIt;
|
||||
if (*previousIt == U'(') {
|
||||
firstErrorStr = _("Empty paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
} else if (currentChar == U'(') {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (numberWasParsedLast) {
|
||||
firstErrorStr = _("Operator missing before a paranthesis");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parenthesisLevel++;
|
||||
numberWasParsedLast = false;
|
||||
} else if (operators.find(currentChar) != gd::String::npos) {
|
||||
if (currentChar == U'-' && parsingNumber &&
|
||||
parsingScientificNotationNumber) {
|
||||
lastNumber += currentChar;
|
||||
requestNumber = true;
|
||||
} else {
|
||||
if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
}
|
||||
|
||||
if (currentChar != U'-' && currentChar != U'+' &&
|
||||
!numberWasParsedLast) {
|
||||
firstErrorStr = _("Operators without any number between them");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
numberWasParsedLast = false;
|
||||
}
|
||||
} else {
|
||||
firstErrorStr = _("Syntax error");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (parsingNumber) {
|
||||
parsingNumber = false;
|
||||
parsingScientificNotationNumber = false;
|
||||
parsingDecimalNumber = false;
|
||||
lastNumber.clear();
|
||||
numberWasParsedLast = true;
|
||||
} else if (requestNumber) {
|
||||
firstErrorStr = _("Number expected");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parenthesisLevel != 0) {
|
||||
firstErrorStr = _("Paranthesis mismatch");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!numberWasParsedLast) {
|
||||
firstErrorStr = _("Alone operator at the end of the expression");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpressionParser::ParseMathExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::ParserCallbacks& callbacks) {
|
||||
callbacks.SetReturnType("expression");
|
||||
gd::String expression = expressionPlainString;
|
||||
|
||||
size_t parsePosition = 0;
|
||||
|
||||
size_t firstPointPos = expression.find(".");
|
||||
size_t firstParPos = expression.find("(");
|
||||
|
||||
gd::String expressionWithoutFunctions;
|
||||
gd::String nonFunctionToken;
|
||||
size_t nonFunctionTokenStartPos = gd::String::npos;
|
||||
|
||||
while (firstPointPos != string::npos || firstParPos != string::npos) {
|
||||
// Identify name
|
||||
size_t nameEnd = firstPointPos < firstParPos ? firstPointPos : firstParPos;
|
||||
size_t nameStart = expression.find_last_of(parserSeparators, nameEnd - 1);
|
||||
nameStart++;
|
||||
|
||||
gd::String nameBefore = expression.substr(nameStart, nameEnd - nameStart);
|
||||
gd::String objectName = nameBefore.FindAndReplace("~", " ");
|
||||
|
||||
// Identify function name
|
||||
gd::String functionName = nameBefore;
|
||||
size_t functionNameEnd = nameEnd;
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
bool nameIsFunction = firstPointPos > firstParPos;
|
||||
if (!nameIsFunction) {
|
||||
parameters.push_back(gd::Expression(objectName));
|
||||
functionNameEnd = expression.find_first_of(" (", nameEnd);
|
||||
if (nameEnd + 1 < expression.length())
|
||||
functionName =
|
||||
expression.substr(nameEnd + 1, functionNameEnd - (nameEnd + 1));
|
||||
if (functionNameEnd == string::npos) {
|
||||
functionName = "";
|
||||
functionNameEnd = expression.length() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we're going to identify the expression
|
||||
gd::ExpressionMetadata instructionInfos;
|
||||
|
||||
if (functionName.substr(0, functionName.length() - 1)
|
||||
.find_first_of(parserSeparators) == string::npos) {
|
||||
bool functionFound = false;
|
||||
bool staticFunctionFound = false;
|
||||
bool objectFunctionFound = false;
|
||||
bool behaviorFunctionFound = false;
|
||||
|
||||
// First try to bind to a static expression
|
||||
if (nameIsFunction &&
|
||||
MetadataProvider::HasExpression(platform, functionName)) {
|
||||
functionFound = true;
|
||||
staticFunctionFound = true;
|
||||
instructionInfos =
|
||||
MetadataProvider::GetExpressionMetadata(platform, functionName);
|
||||
}
|
||||
// Then search in object expression
|
||||
else if (!nameIsFunction &&
|
||||
MetadataProvider::HasObjectExpression(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName)) {
|
||||
functionFound = true;
|
||||
objectFunctionFound = true;
|
||||
instructionInfos = MetadataProvider::GetObjectExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName);
|
||||
}
|
||||
// And in behaviors expressions
|
||||
else if (!nameIsFunction) {
|
||||
size_t firstDoublePoints = functionName.find("::");
|
||||
if (firstDoublePoints != string::npos) {
|
||||
gd::String autoName = functionName.substr(0, firstDoublePoints);
|
||||
if (firstDoublePoints + 2 < functionName.length())
|
||||
functionName = functionName.substr(firstDoublePoints + 2,
|
||||
functionName.length());
|
||||
else
|
||||
functionName = "";
|
||||
|
||||
if (MetadataProvider::HasBehaviorExpression(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName)) {
|
||||
parameters.push_back(gd::Expression(autoName));
|
||||
functionFound = true;
|
||||
behaviorFunctionFound = true;
|
||||
|
||||
instructionInfos = MetadataProvider::GetBehaviorExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName);
|
||||
|
||||
// Verify that object has behavior.
|
||||
vector<gd::String> behaviors =
|
||||
gd::GetBehaviorsOfObject(project, layout, objectName);
|
||||
if (find(behaviors.begin(), behaviors.end(), autoName) ==
|
||||
behaviors.end()) {
|
||||
cout << "Bad behavior requested" << endl;
|
||||
functionFound = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (functionFound) // Add the function
|
||||
{
|
||||
// Identify parameters
|
||||
size_t parametersEnd = expression.find_first_of("(", functionNameEnd);
|
||||
gd::String currentParameterStr;
|
||||
char32_t previousChar = '(';
|
||||
bool takeSymbolsInAccount = true;
|
||||
if (parametersEnd != string::npos) {
|
||||
size_t level = 0;
|
||||
parametersEnd++;
|
||||
|
||||
while (parametersEnd < expression.length() &&
|
||||
!(expression[parametersEnd] == ')' && level == 0)) {
|
||||
// Be sure we are not in quotes
|
||||
if (expression[parametersEnd] == U'\"' && previousChar != U'\\')
|
||||
takeSymbolsInAccount = !takeSymbolsInAccount;
|
||||
|
||||
// So as to be sure paranthesis don't belong to a parameter
|
||||
if (expression[parametersEnd] == U'(' && takeSymbolsInAccount)
|
||||
level++;
|
||||
if (expression[parametersEnd] == U')' && takeSymbolsInAccount)
|
||||
level--;
|
||||
|
||||
// Add the character to the current parameter or terminate the
|
||||
// latter
|
||||
if ((expression[parametersEnd] == U',' && level == 0) &&
|
||||
takeSymbolsInAccount) {
|
||||
parameters.push_back(currentParameterStr);
|
||||
currentParameterStr.clear();
|
||||
} else
|
||||
currentParameterStr += expression[parametersEnd];
|
||||
|
||||
previousChar = expression[parametersEnd];
|
||||
parametersEnd++;
|
||||
}
|
||||
if (currentParameterStr.find_first_not_of(" ") !=
|
||||
string::npos) // Add last parameter if needed
|
||||
{
|
||||
parameters.push_back(currentParameterStr);
|
||||
}
|
||||
|
||||
// Testing function call is properly closed
|
||||
if (parametersEnd == expression.length() ||
|
||||
expression[parametersEnd] != U')') {
|
||||
firstErrorStr = _("Paranthesis not closed");
|
||||
firstErrorPos = parametersEnd - 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(instructionInfos.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(instructionInfos.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
firstErrorStr += " ";
|
||||
firstErrorStr += _("Expected (maximum) :");
|
||||
firstErrorStr += gd::String::From(
|
||||
GetMaximalParametersNumber(instructionInfos.parameters));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters =
|
||||
CompleteParameters(instructionInfos.parameters, parameters);
|
||||
for (std::size_t i = 0; i < instructionInfos.parameters.size(); ++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
instructionInfos.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Parameters' parenthesis missing");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnConstantToken(
|
||||
nonFunctionToken +
|
||||
expression.substr(parsePosition, nameStart - parsePosition));
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, nameStart - parsePosition);
|
||||
nonFunctionToken.clear();
|
||||
nonFunctionTokenStartPos = gd::String::npos;
|
||||
|
||||
if (objectFunctionFound)
|
||||
callbacks.OnObjectFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
else if (behaviorFunctionFound)
|
||||
callbacks.OnObjectBehaviorFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
else if (staticFunctionFound)
|
||||
callbacks.OnStaticFunction(
|
||||
functionName, parameters, instructionInfos);
|
||||
|
||||
if (objectFunctionFound || behaviorFunctionFound || staticFunctionFound)
|
||||
expressionWithoutFunctions += "0";
|
||||
|
||||
parsePosition = parametersEnd + 1;
|
||||
firstPointPos = expression.find(".", parametersEnd + 1);
|
||||
firstParPos = expression.find("(", parametersEnd + 1);
|
||||
} else // Math function or math constant : Pass it.
|
||||
{
|
||||
nonFunctionToken += expression.substr(
|
||||
parsePosition, functionNameEnd + 1 - parsePosition);
|
||||
expressionWithoutFunctions += expression.substr(
|
||||
parsePosition, functionNameEnd + 1 - parsePosition);
|
||||
nonFunctionTokenStartPos = (nonFunctionTokenStartPos != gd::String::npos
|
||||
? nonFunctionTokenStartPos
|
||||
: parsePosition);
|
||||
parsePosition = functionNameEnd + 1;
|
||||
firstPointPos = expression.find(".", functionNameEnd + 1);
|
||||
firstParPos = expression.find("(", functionNameEnd + 1);
|
||||
}
|
||||
} else // Not a function call : Pass it
|
||||
{
|
||||
nonFunctionToken +=
|
||||
expression.substr(parsePosition, nameEnd + 1 - parsePosition);
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, nameEnd + 1 - parsePosition);
|
||||
nonFunctionTokenStartPos = (nonFunctionTokenStartPos != gd::String::npos
|
||||
? nonFunctionTokenStartPos
|
||||
: parsePosition);
|
||||
parsePosition = nameEnd + 1;
|
||||
firstPointPos = expression.find(".", nameEnd + 1);
|
||||
firstParPos = expression.find("(", nameEnd + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsePosition < expression.length() || !nonFunctionToken.empty())
|
||||
callbacks.OnConstantToken(
|
||||
nonFunctionToken +
|
||||
expression.substr(parsePosition, expression.length()));
|
||||
|
||||
expressionWithoutFunctions +=
|
||||
expression.substr(parsePosition, expression.length());
|
||||
|
||||
return ValidSyntax(expressionWithoutFunctions);
|
||||
}
|
||||
|
||||
bool ExpressionParser::ParseStringExpression(const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
gd::ParserCallbacks& callbacks) {
|
||||
callbacks.SetReturnType("string");
|
||||
gd::String expression = expressionPlainString;
|
||||
|
||||
size_t parsePosition = 0;
|
||||
|
||||
// Searching for first token.
|
||||
size_t firstPointPos = expression.find(".");
|
||||
size_t firstParPos = expression.find("(");
|
||||
size_t firstQuotePos = expression.find("\"");
|
||||
|
||||
if (firstPointPos == string::npos && firstParPos == string::npos &&
|
||||
firstQuotePos == string::npos) {
|
||||
firstErrorPos = 0;
|
||||
firstErrorStr =
|
||||
_("The expression is invalid or empty. Enter a text ( surrounded by "
|
||||
"quotes ) or a function.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
while (firstPointPos != string::npos || firstParPos != string::npos ||
|
||||
firstQuotePos != string::npos) {
|
||||
if (firstQuotePos < firstPointPos &&
|
||||
firstQuotePos < firstParPos) // Adding a constant text
|
||||
{
|
||||
callbacks.OnConstantToken(
|
||||
expression.substr(parsePosition, firstQuotePos - parsePosition));
|
||||
|
||||
// Finding start and end of quotes
|
||||
size_t finalQuotePosition = expression.find("\"", firstQuotePos + 1);
|
||||
while (finalQuotePosition ==
|
||||
expression.find("\\\"", finalQuotePosition - 1) + 1)
|
||||
finalQuotePosition = expression.find("\"", finalQuotePosition + 1);
|
||||
|
||||
if (finalQuotePosition == string::npos) {
|
||||
firstErrorPos = firstQuotePos;
|
||||
firstErrorStr = _("Quotes not closed.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generating final text, by replacing \" by quotes
|
||||
gd::String finalText = expression.substr(
|
||||
firstQuotePos + 1, finalQuotePosition - (firstQuotePos + 1));
|
||||
|
||||
size_t foundPos = finalText.find("\\\"");
|
||||
while (foundPos != string::npos) {
|
||||
if (foundPos != string::npos) finalText.replace(foundPos, 2, "\"");
|
||||
foundPos = finalText.find("\\\"", foundPos);
|
||||
}
|
||||
|
||||
// Adding constant text instruction
|
||||
//(Function without name is considered as a constant text)
|
||||
vector<gd::Expression> parameters;
|
||||
parameters.push_back(finalText);
|
||||
gd::ExpressionMetadata noParametersInfo;
|
||||
|
||||
callbacks.OnStaticFunction("", parameters, noParametersInfo);
|
||||
|
||||
parsePosition = finalQuotePosition + 1;
|
||||
} else // Adding a function
|
||||
{
|
||||
// Identify name
|
||||
size_t nameEnd =
|
||||
firstPointPos < firstParPos ? firstPointPos : firstParPos;
|
||||
size_t nameStart = expression.find_last_of(parserSeparators, nameEnd - 1);
|
||||
nameStart++;
|
||||
|
||||
callbacks.OnConstantToken(
|
||||
expression.substr(parsePosition, nameStart - parsePosition));
|
||||
|
||||
gd::String nameBefore = expression.substr(nameStart, nameEnd - nameStart);
|
||||
gd::String objectName = nameBefore.FindAndReplace("~", " ");
|
||||
|
||||
// Identify function name
|
||||
gd::String functionName = nameBefore;
|
||||
size_t functionNameEnd = nameEnd;
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
bool nameIsFunction = firstPointPos > firstParPos;
|
||||
if (!nameIsFunction) {
|
||||
parameters.push_back(gd::Expression(objectName));
|
||||
functionNameEnd = expression.find_first_of("( ", nameEnd);
|
||||
if (nameEnd + 1 < expression.length())
|
||||
functionName =
|
||||
expression.substr(nameEnd + 1, functionNameEnd - (nameEnd + 1));
|
||||
}
|
||||
|
||||
// Identify parameters
|
||||
size_t parametersEnd = expression.find_first_of("(", functionNameEnd) + 1;
|
||||
char32_t previousChar = U'(';
|
||||
bool takeSymbolsInAccount = true;
|
||||
size_t level = 0;
|
||||
gd::String currentParameterStr;
|
||||
while (parametersEnd < expression.length() &&
|
||||
!(expression[parametersEnd] == U')' && level == 0)) {
|
||||
// Be sure we are not in quotes
|
||||
if (expression[parametersEnd] == U'\"' && previousChar != U'\\')
|
||||
takeSymbolsInAccount = !takeSymbolsInAccount;
|
||||
|
||||
// So as to be sure paranthesis don't belong to a parameter
|
||||
if (expression[parametersEnd] == U'(' && takeSymbolsInAccount) level++;
|
||||
if (expression[parametersEnd] == U')' && takeSymbolsInAccount) level--;
|
||||
|
||||
// Add the character to the current parameter or terminate the latter
|
||||
if ((expression[parametersEnd] == ',' && level == 0) &&
|
||||
takeSymbolsInAccount) {
|
||||
gd::Expression currentParameter(currentParameterStr);
|
||||
parameters.push_back(currentParameter);
|
||||
|
||||
currentParameterStr.clear();
|
||||
} else
|
||||
currentParameterStr += expression[parametersEnd];
|
||||
|
||||
previousChar = expression[parametersEnd];
|
||||
parametersEnd++;
|
||||
}
|
||||
|
||||
if (parametersEnd == expression.length() ||
|
||||
expression[parametersEnd] != U')') {
|
||||
firstErrorPos = parametersEnd - 1;
|
||||
firstErrorStr = _("Paranthesis not closed");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentParameterStr.find_first_not_of(" ") !=
|
||||
string::npos) // Add last parameter if needed
|
||||
{
|
||||
gd::Expression lastParameter(currentParameterStr);
|
||||
parameters.push_back(lastParameter);
|
||||
}
|
||||
|
||||
bool functionFound = false;
|
||||
|
||||
// First try to bind to a static str expression
|
||||
if (nameIsFunction &&
|
||||
MetadataProvider::HasStrExpression(platform, functionName)) {
|
||||
functionFound = true;
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetStrExpressionMetadata(platform, functionName);
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters = CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0;
|
||||
i < parameters.size() && i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnStaticFunction(functionName, parameters, expressionInfo);
|
||||
}
|
||||
// Then an object member expression
|
||||
else if (!nameIsFunction &&
|
||||
MetadataProvider::HasObjectStrExpression(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, objectName),
|
||||
functionName)) {
|
||||
functionFound = true;
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetObjectStrExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfObject(project, layout, nameBefore),
|
||||
functionName);
|
||||
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters = CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0;
|
||||
i < parameters.size() && i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnObjectFunction(functionName, parameters, expressionInfo);
|
||||
}
|
||||
// And search behaviors expressions
|
||||
else {
|
||||
size_t firstDoublePoints = functionName.find("::");
|
||||
if (firstDoublePoints != string::npos) {
|
||||
gd::String autoName = functionName.substr(0, firstDoublePoints);
|
||||
if (firstDoublePoints + 2 < functionName.length())
|
||||
functionName = functionName.substr(firstDoublePoints + 2,
|
||||
functionName.length());
|
||||
else
|
||||
functionName = "";
|
||||
|
||||
if (MetadataProvider::HasBehaviorStrExpression(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName)) {
|
||||
parameters.push_back(gd::Expression(autoName));
|
||||
functionFound = true;
|
||||
|
||||
const gd::ExpressionMetadata& expressionInfo =
|
||||
MetadataProvider::GetBehaviorStrExpressionMetadata(
|
||||
platform,
|
||||
gd::GetTypeOfBehavior(project, layout, autoName),
|
||||
functionName);
|
||||
|
||||
// Verify that object has behavior.
|
||||
vector<gd::String> behaviors =
|
||||
gd::GetBehaviorsOfObject(project, layout, objectName);
|
||||
if (find(behaviors.begin(), behaviors.end(), autoName) ==
|
||||
behaviors.end()) {
|
||||
cout << "Bad behavior requested" << endl;
|
||||
functionFound = false;
|
||||
} else {
|
||||
// Testing the number of parameters
|
||||
if (parameters.size() >
|
||||
GetMaximalParametersNumber(expressionInfo.parameters) ||
|
||||
parameters.size() <
|
||||
GetMinimalParametersNumber(expressionInfo.parameters)) {
|
||||
firstErrorPos = functionNameEnd;
|
||||
firstErrorStr = _("Incorrect number of parameters");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preparing parameters
|
||||
parameters =
|
||||
CompleteParameters(expressionInfo.parameters, parameters);
|
||||
for (std::size_t i = 0; i < parameters.size() &&
|
||||
i < expressionInfo.parameters.size();
|
||||
++i) {
|
||||
if (!PrepareParameter(platform,
|
||||
project,
|
||||
layout,
|
||||
callbacks,
|
||||
parameters[i],
|
||||
expressionInfo.parameters[i],
|
||||
functionNameEnd))
|
||||
return false;
|
||||
}
|
||||
|
||||
callbacks.OnObjectBehaviorFunction(
|
||||
functionName, parameters, expressionInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note : _No_ support for implicit conversion from math result to string
|
||||
|
||||
if (!functionFound) // Function was not found
|
||||
{
|
||||
firstErrorPos = nameStart;
|
||||
firstErrorStr = _("Function not recognized.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parsePosition = parametersEnd + 1;
|
||||
}
|
||||
|
||||
// Searching for next token
|
||||
size_t firstPlusPos = expression.find("+", parsePosition);
|
||||
firstPointPos = expression.find(".", parsePosition);
|
||||
firstParPos = expression.find("(", parsePosition);
|
||||
firstQuotePos = expression.find("\"", parsePosition);
|
||||
|
||||
// Checking for a + between token
|
||||
if ((firstPointPos != string::npos || firstParPos != string::npos ||
|
||||
firstQuotePos != string::npos)) {
|
||||
size_t nextTokenPos = firstPointPos;
|
||||
if (firstParPos < nextTokenPos) nextTokenPos = firstParPos;
|
||||
if (firstQuotePos < nextTokenPos) nextTokenPos = firstQuotePos;
|
||||
|
||||
if (nextTokenPos < firstPlusPos) {
|
||||
firstErrorPos = nextTokenPos;
|
||||
firstErrorStr = _("Symbol missing between two +.");
|
||||
|
||||
return false;
|
||||
} else if (expression.find("+", firstPlusPos + 1) < nextTokenPos) {
|
||||
firstErrorPos = firstPlusPos;
|
||||
firstErrorStr = _("Symbol missing between two +.");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (expression.substr(parsePosition, expression.length())
|
||||
.find_first_not_of(" \n") != gd::String::npos) {
|
||||
firstErrorPos = parsePosition;
|
||||
firstErrorStr = _("Bad symbol at the end of the expression.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExpressionParser::PrepareParameter(
|
||||
const gd::Platform& platform,
|
||||
const gd::ObjectsContainer& project,
|
||||
const gd::ObjectsContainer& layout,
|
||||
ParserCallbacks& callbacks,
|
||||
gd::Expression& parameter,
|
||||
const gd::ParameterMetadata& parametersInfo,
|
||||
const size_t positionInExpression) {
|
||||
if (ParameterMetadata::IsExpression("number", parametersInfo.type)) {
|
||||
if (parametersInfo.optional && parameter.GetPlainString().empty())
|
||||
parameter = parametersInfo.GetDefaultValue().empty()
|
||||
? gd::Expression("0")
|
||||
: gd::Expression(parametersInfo.GetDefaultValue());
|
||||
|
||||
if (!callbacks.OnSubMathExpression(platform, project, layout, parameter)) {
|
||||
firstErrorStr = callbacks.firstErrorStr;
|
||||
firstErrorPos = callbacks.firstErrorPos + positionInExpression;
|
||||
|
||||
return false;
|
||||
}
|
||||
} else if (ParameterMetadata::IsExpression("string", parametersInfo.type)) {
|
||||
if (parametersInfo.optional && parameter.GetPlainString().empty())
|
||||
parameter = parametersInfo.GetDefaultValue().empty()
|
||||
? gd::Expression("\"\"")
|
||||
: gd::Expression(parametersInfo.GetDefaultValue());
|
||||
|
||||
if (!callbacks.OnSubTextExpression(platform, project, layout, parameter)) {
|
||||
firstErrorStr = callbacks.firstErrorStr;
|
||||
firstErrorPos = callbacks.firstErrorPos + positionInExpression;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ExpressionParser::ExpressionParser(const gd::String& expressionPlainString_)
|
||||
: expressionPlainString(expressionPlainString_) {}
|
||||
|
||||
} // namespace gd
|
179
Core/GDCore/Events/Parsers/ExpressionParser.h
Normal file
179
Core/GDCore/Events/Parsers/ExpressionParser.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EXPRESSIONPARSER_H
|
||||
#define GDCORE_EXPRESSIONPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Expression;
|
||||
class ParserCallbacks;
|
||||
class ObjectsContainer;
|
||||
class Platform;
|
||||
class ParameterMetadata;
|
||||
class ExpressionMetadata;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/** \brief Parse an expression
|
||||
*
|
||||
* Parse an expression, calling callbacks when a token is reached
|
||||
* \see gd::ParserCallbacks
|
||||
*/
|
||||
class GD_CORE_API ExpressionParser {
|
||||
public:
|
||||
ExpressionParser(const gd::String &expressionPlainString_);
|
||||
virtual ~ExpressionParser(){};
|
||||
|
||||
/**
|
||||
* \brief Parse the expression, calling each functor when necessary
|
||||
* \return True if expression was correctly parsed.
|
||||
*/
|
||||
bool ParseMathExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::ParserCallbacks &callbacks);
|
||||
|
||||
/**
|
||||
* \brief Parse the expression, calling each functor when necessary
|
||||
* \return True if expression was correctly parsed.
|
||||
*/
|
||||
bool ParseStringExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::ParserCallbacks &callbacks);
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String &GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
private:
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
/**
|
||||
* Tool function to add a parameter
|
||||
*/
|
||||
bool AddParameterToList(const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
ParserCallbacks &,
|
||||
std::vector<gd::Expression> ¶meters,
|
||||
gd::String parameterStr,
|
||||
std::vector<gd::ParameterMetadata> parametersInfos,
|
||||
const size_t positionInExpression);
|
||||
|
||||
/**
|
||||
* Tool function to prepare a parameter
|
||||
*/
|
||||
bool PrepareParameter(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
ParserCallbacks &,
|
||||
gd::Expression ¶meter,
|
||||
const gd::ParameterMetadata ¶metersInfo,
|
||||
const size_t positionInExpression);
|
||||
|
||||
/**
|
||||
* Return the minimal number of parameters which can be used when calling an
|
||||
* expression ( i.e. ParametersCount-OptionalParameters-CodeOnlyParameters )
|
||||
*/
|
||||
size_t GetMinimalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata> ¶metersInfos);
|
||||
|
||||
/**
|
||||
* Return the maximal number of parameters which can be used when calling an
|
||||
* expression ( i.e. ParametersCount-CodeOnlyParameters )
|
||||
*/
|
||||
size_t GetMaximalParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata> ¶metersInfos);
|
||||
|
||||
bool ValidSyntax(const gd::String &str);
|
||||
|
||||
gd::String expressionPlainString;
|
||||
static gd::String parserSeparators;
|
||||
};
|
||||
|
||||
/** \brief Callbacks called by parser during parsing
|
||||
*
|
||||
* Parser will call the appropriate functions during parsing, allowing to do
|
||||
* special works. \see gd::ExpressionParser
|
||||
*/
|
||||
class GD_CORE_API ParserCallbacks {
|
||||
friend class ExpressionParser;
|
||||
|
||||
public:
|
||||
ParserCallbacks() : returnType("expression"){};
|
||||
virtual ~ParserCallbacks(){};
|
||||
|
||||
/**
|
||||
* \brief Get the type of the expression for which callbacks are used:
|
||||
* "expression" or "string".
|
||||
*/
|
||||
const gd::String &GetReturnType() { return returnType; }
|
||||
|
||||
virtual void OnConstantToken(gd::String text) = 0;
|
||||
|
||||
virtual void OnStaticFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual void OnObjectFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual void OnObjectBehaviorFunction(
|
||||
gd::String functionName,
|
||||
const std::vector<gd::Expression> ¶meters,
|
||||
const gd::ExpressionMetadata &expressionInfo) = 0;
|
||||
|
||||
virtual bool OnSubMathExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::Expression &expression) = 0;
|
||||
virtual bool OnSubTextExpression(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &project,
|
||||
const gd::ObjectsContainer &layout,
|
||||
gd::Expression &expression) = 0;
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String &GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
protected:
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
private:
|
||||
/**
|
||||
* \brief Set the return type of the expression: Done by ExpressionParser
|
||||
* according to which Parse* method is called. \see gd::ExpressionParser
|
||||
*/
|
||||
void SetReturnType(gd::String type) { returnType = type; }
|
||||
|
||||
gd::String returnType; // The type of the expression ("expression" (default),
|
||||
// "string"...)
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDEXPRESSIONPARSER_H
|
@@ -4,11 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
@@ -19,29 +17,112 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GrammarTerminals.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gd::GrammarTerminals;
|
||||
|
||||
namespace gd {
|
||||
|
||||
gd::String ExpressionParser2::NUMBER_FIRST_CHAR = ".0123456789";
|
||||
gd::String ExpressionParser2::DOT = ".";
|
||||
gd::String ExpressionParser2::PARAMETERS_SEPARATOR = ",";
|
||||
gd::String ExpressionParser2::QUOTE = "\"";
|
||||
gd::String ExpressionParser2::BRACKETS = "()[]{}";
|
||||
gd::String ExpressionParser2::EXPRESSION_OPERATORS = "+-<>?^=\\:!";
|
||||
gd::String ExpressionParser2::TERM_OPERATORS = "/*";
|
||||
gd::String ExpressionParser2::UNARY_OPERATORS = "+-";
|
||||
gd::String ExpressionParser2::WHITESPACES = " \n\r";
|
||||
gd::String ExpressionParser2::NAMESPACE_SEPARATOR = "::";
|
||||
|
||||
ExpressionParser2::ExpressionParser2()
|
||||
ExpressionParser2::ExpressionParser2(
|
||||
const gd::Platform& platform_,
|
||||
const gd::ObjectsContainer& globalObjectsContainer_,
|
||||
const gd::ObjectsContainer& objectsContainer_)
|
||||
: expression(""),
|
||||
currentPosition(0) {}
|
||||
currentPosition(0),
|
||||
platform(platform_),
|
||||
globalObjectsContainer(globalObjectsContainer_),
|
||||
objectsContainer(objectsContainer_) {}
|
||||
|
||||
namespace {
|
||||
/**
|
||||
* Return the minimum number of parameters, starting from a given parameter
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMinimumParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].optional && !parameters[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of parameters, starting from a given parameter
|
||||
* (by convention, 1 for object functions and 2 for behavior functions).
|
||||
*/
|
||||
size_t GetMaximumParametersNumber(
|
||||
const std::vector<gd::ParameterMetadata>& parameters,
|
||||
size_t initialParameterIndex) {
|
||||
size_t nb = 0;
|
||||
for (std::size_t i = initialParameterIndex; i < parameters.size(); ++i) {
|
||||
if (!parameters[i].codeOnly) nb++;
|
||||
}
|
||||
|
||||
return nb;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ExpressionParserDiagnostic> ExpressionParser2::ValidateFunction(
|
||||
const gd::FunctionNode& function, size_t functionStartPosition) {
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(
|
||||
function.expressionMetadata)) {
|
||||
return gd::make_unique<ExpressionParserError>(
|
||||
"invalid_function_name",
|
||||
_("Cannot find an expression with this name: ") +
|
||||
function.functionName + "\n" +
|
||||
_("Double check that you've not made any typo in the name."),
|
||||
functionStartPosition,
|
||||
GetCurrentPosition());
|
||||
}
|
||||
|
||||
size_t minParametersCount = GetMinimumParametersNumber(
|
||||
function.expressionMetadata.parameters,
|
||||
WrittenParametersFirstIndex(function.objectName, function.behaviorName));
|
||||
size_t maxParametersCount = GetMaximumParametersNumber(
|
||||
function.expressionMetadata.parameters,
|
||||
WrittenParametersFirstIndex(function.objectName, function.behaviorName));
|
||||
if (function.parameters.size() < minParametersCount ||
|
||||
function.parameters.size() > maxParametersCount) {
|
||||
gd::String expectedCountMessage =
|
||||
minParametersCount == maxParametersCount
|
||||
? _("The number of parameters must be exactly ") +
|
||||
gd::String::From(minParametersCount)
|
||||
: _("The number of parameters must be: ") +
|
||||
gd::String::From(minParametersCount) + "-" +
|
||||
gd::String::From(maxParametersCount);
|
||||
|
||||
if (function.parameters.size() < minParametersCount) {
|
||||
return gd::make_unique<ExpressionParserError>(
|
||||
"too_few_parameters",
|
||||
"You have not entered enough parameters for the expression. " +
|
||||
expectedCountMessage,
|
||||
functionStartPosition,
|
||||
GetCurrentPosition());
|
||||
}
|
||||
}
|
||||
|
||||
return gd::make_unique<ExpressionParserDiagnostic>();
|
||||
}
|
||||
|
||||
std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
|
||||
size_t textStartPosition = GetCurrentPosition();
|
||||
SkipAllWhitespaces();
|
||||
if (!CheckIfChar(IsQuote)) {
|
||||
SkipWhitespace();
|
||||
if (!IsAnyChar("\"")) {
|
||||
auto text = gd::make_unique<TextNode>("");
|
||||
// It can't happen.
|
||||
text->diagnostic =
|
||||
RaiseSyntaxError(_("A text must start with a double quote (\")."));
|
||||
text->location =
|
||||
ExpressionParserLocation(textStartPosition, GetCurrentPosition());
|
||||
return text;
|
||||
}
|
||||
SkipChar();
|
||||
@@ -76,8 +157,6 @@ std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
|
||||
}
|
||||
|
||||
auto text = gd::make_unique<TextNode>(parsedText);
|
||||
text->location =
|
||||
ExpressionParserLocation(textStartPosition, GetCurrentPosition());
|
||||
if (!textParsingHasEnded) {
|
||||
text->diagnostic =
|
||||
RaiseSyntaxError(_("A text must end with a double quote (\"). Add a "
|
||||
@@ -88,30 +167,28 @@ std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
|
||||
}
|
||||
|
||||
std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
|
||||
size_t numberStartPosition = GetCurrentPosition();
|
||||
SkipAllWhitespaces();
|
||||
SkipWhitespace();
|
||||
gd::String parsedNumber;
|
||||
|
||||
bool numberHasStarted = false;
|
||||
bool digitFound = false;
|
||||
bool dotFound = false;
|
||||
while (!IsEndReached()) {
|
||||
if (CheckIfChar(IsZeroDigit)) {
|
||||
if (IsAnyChar("0")) {
|
||||
numberHasStarted = true;
|
||||
digitFound = true;
|
||||
if (!parsedNumber.empty()) { // Ignore leading 0s.
|
||||
if (!parsedNumber.empty()) { // Ignore leading 0s.
|
||||
parsedNumber += GetCurrentChar();
|
||||
}
|
||||
} else if (CheckIfChar(IsNonZeroDigit)) {
|
||||
} else if (IsAnyChar("123456789")) {
|
||||
numberHasStarted = true;
|
||||
digitFound = true;
|
||||
parsedNumber += GetCurrentChar();
|
||||
} else if (CheckIfChar(IsDot) && !dotFound) {
|
||||
} else if (IsAnyChar(".") && !dotFound) {
|
||||
numberHasStarted = true;
|
||||
dotFound = true;
|
||||
if (parsedNumber == "") {
|
||||
parsedNumber +=
|
||||
"0."; // Normalize by adding a leading 0, only in this case.
|
||||
parsedNumber += "0."; //Normalize by adding a leading 0, only in this case.
|
||||
} else {
|
||||
parsedNumber += ".";
|
||||
}
|
||||
@@ -132,8 +209,6 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
|
||||
// valid in most languages so we allow this.
|
||||
|
||||
auto number = gd::make_unique<NumberNode>(parsedNumber);
|
||||
number->location =
|
||||
ExpressionParserLocation(numberStartPosition, GetCurrentPosition());
|
||||
if (!numberHasStarted || !digitFound) {
|
||||
number->diagnostic = RaiseSyntaxError(
|
||||
_("A number was expected. You must enter a number here."));
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -17,34 +16,14 @@ class ObjectsContainer;
|
||||
class Platform;
|
||||
class ParameterMetadata;
|
||||
class ExpressionMetadata;
|
||||
struct FunctionCallNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
struct GD_CORE_API ExpressionParserLocation {
|
||||
ExpressionParserLocation() : isValid(false){};
|
||||
ExpressionParserLocation(size_t position)
|
||||
: isValid(true), startPosition(position), endPosition(position){};
|
||||
ExpressionParserLocation(size_t startPosition_, size_t endPosition_)
|
||||
: isValid(true),
|
||||
startPosition(startPosition_),
|
||||
endPosition(endPosition_){};
|
||||
size_t GetStartPosition() const { return startPosition; }
|
||||
size_t GetEndPosition() const { return endPosition; }
|
||||
bool IsValid() const { return isValid; }
|
||||
|
||||
private:
|
||||
bool isValid;
|
||||
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;
|
||||
struct ExpressionParserDiagnostic {
|
||||
virtual bool IsError() { return false; }
|
||||
virtual const gd::String &GetMessage() { return noMessage; }
|
||||
virtual size_t GetStartPosition() { return 0; }
|
||||
@@ -57,57 +36,50 @@ struct GD_CORE_API ExpressionParserDiagnostic {
|
||||
/**
|
||||
* \brief An error that can be attached to a gd::ExpressionNode.
|
||||
*/
|
||||
struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
const ExpressionParserLocation &location_)
|
||||
: type(type_), message(message_), location(location_){};
|
||||
struct ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
size_t position_)
|
||||
: type(type_), message(message_), location(position_){};
|
||||
: type(type_),
|
||||
message(message_),
|
||||
startPosition(position_),
|
||||
endPosition(position_){};
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
size_t startPosition_,
|
||||
size_t endPosition_)
|
||||
: type(type_),
|
||||
message(message_),
|
||||
location(startPosition_, endPosition_){};
|
||||
startPosition(startPosition_),
|
||||
endPosition(endPosition_){};
|
||||
virtual ~ExpressionParserError(){};
|
||||
|
||||
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(); }
|
||||
size_t GetStartPosition() override { return startPosition; }
|
||||
size_t GetEndPosition() override { return endPosition; }
|
||||
|
||||
private:
|
||||
gd::String type;
|
||||
gd::String message;
|
||||
ExpressionParserLocation location;
|
||||
size_t startPosition;
|
||||
size_t endPosition;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The base node, from which all nodes in the tree of
|
||||
* an expression inherits from.
|
||||
*/
|
||||
struct GD_CORE_API ExpressionNode {
|
||||
ExpressionNode() : parent(nullptr) {};
|
||||
struct ExpressionNode {
|
||||
virtual ~ExpressionNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker){};
|
||||
|
||||
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
|
||||
/// function can store the position of the
|
||||
/// object name, the dot, the function
|
||||
/// name, etc...
|
||||
ExpressionNode *parent;
|
||||
};
|
||||
|
||||
struct GD_CORE_API SubExpressionNode : public ExpressionNode {
|
||||
struct SubExpressionNode : public ExpressionNode {
|
||||
SubExpressionNode(std::unique_ptr<ExpressionNode> expression_)
|
||||
: ExpressionNode(), expression(std::move(expression_)){};
|
||||
: expression(std::move(expression_)){};
|
||||
virtual ~SubExpressionNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitSubExpressionNode(*this);
|
||||
@@ -119,9 +91,7 @@ struct GD_CORE_API SubExpressionNode : public ExpressionNode {
|
||||
/**
|
||||
* \brief An operator node. For example: "lhs + rhs".
|
||||
*/
|
||||
struct GD_CORE_API OperatorNode : public ExpressionNode {
|
||||
OperatorNode(gd::String::value_type op_)
|
||||
: ExpressionNode(), op(op_){};
|
||||
struct OperatorNode : public ExpressionNode {
|
||||
virtual ~OperatorNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitOperatorNode(*this);
|
||||
@@ -135,9 +105,8 @@ struct GD_CORE_API OperatorNode : public ExpressionNode {
|
||||
/**
|
||||
* \brief A unary operator node. For example: "-2".
|
||||
*/
|
||||
struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
|
||||
UnaryOperatorNode(gd::String::value_type op_)
|
||||
: ExpressionNode(), op(op_){};
|
||||
struct UnaryOperatorNode : public ExpressionNode {
|
||||
UnaryOperatorNode(gd::String::value_type op_) : op(op_){};
|
||||
virtual ~UnaryOperatorNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitUnaryOperatorNode(*this);
|
||||
@@ -149,26 +118,22 @@ struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
|
||||
|
||||
/**
|
||||
* \brief A number node. For example: "123".
|
||||
* Its `type` is always "number".
|
||||
*/
|
||||
struct GD_CORE_API NumberNode : public ExpressionNode {
|
||||
NumberNode(const gd::String &number_)
|
||||
: ExpressionNode(), number(number_){};
|
||||
struct NumberNode : public ExpressionNode {
|
||||
NumberNode(const gd::String &number_) : number(number_){};
|
||||
virtual ~NumberNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitNumberNode(*this);
|
||||
};
|
||||
|
||||
//
|
||||
gd::String number;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A text node. For example: "Hello World".
|
||||
* Its `type` is always "string".
|
||||
*/
|
||||
struct GD_CORE_API TextNode : public ExpressionNode {
|
||||
TextNode(const gd::String &text_) : ExpressionNode(), text(text_){};
|
||||
struct TextNode : public ExpressionNode {
|
||||
TextNode(const gd::String &text_) : text(text_){};
|
||||
virtual ~TextNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitTextNode(*this);
|
||||
@@ -177,122 +142,59 @@ struct GD_CORE_API TextNode : public ExpressionNode {
|
||||
gd::String text;
|
||||
};
|
||||
|
||||
struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
: public ExpressionNode {
|
||||
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode()
|
||||
: ExpressionNode(){};
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief An identifier node, usually representing an object or a variable
|
||||
* with an optional function name or child variable name respectively.
|
||||
*
|
||||
* The name of a function to call on an object or the behavior,
|
||||
* for example: "MyObject.Function" or "MyObject.Physics".
|
||||
*
|
||||
* A variable, potentially with accessor to its child,
|
||||
* for example: MyVariable or MyVariable.MyChild
|
||||
*/
|
||||
struct GD_CORE_API IdentifierNode
|
||||
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
IdentifierNode(
|
||||
const gd::String &identifierName_)
|
||||
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
identifierName(identifierName_),
|
||||
childIdentifierName(""){};
|
||||
IdentifierNode(
|
||||
const gd::String &identifierName_,
|
||||
const gd::String &childIdentifierName_)
|
||||
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
identifierName(identifierName_),
|
||||
childIdentifierName(childIdentifierName_){};
|
||||
virtual ~IdentifierNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitIdentifierNode(*this);
|
||||
};
|
||||
|
||||
gd::String identifierName; ///< The object or variable name.
|
||||
gd::String childIdentifierName; ///< The object function or variable child name.
|
||||
|
||||
|
||||
ExpressionParserLocation
|
||||
identifierNameLocation; ///< Location of the object or variable name.
|
||||
ExpressionParserLocation
|
||||
identifierNameDotLocation; ///< Location of the "." after the object or variable name.
|
||||
ExpressionParserLocation childIdentifierNameLocation; ///< Location of object
|
||||
/// function, behavior or
|
||||
/// child variable name.
|
||||
};
|
||||
|
||||
struct GD_CORE_API FunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
FunctionCallOrObjectFunctionNameOrEmptyNode()
|
||||
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(){};
|
||||
virtual ~FunctionCallOrObjectFunctionNameOrEmptyNode(){};
|
||||
void Visit(ExpressionParser2NodeWorker &worker) override{};
|
||||
};
|
||||
|
||||
struct GD_CORE_API VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
|
||||
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(){};
|
||||
|
||||
struct VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
|
||||
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A variable, or object variable, with bracket accessor or at least 2 "dot" accessors.
|
||||
* \brief A variable, potentially with accessor to its children.
|
||||
*
|
||||
* Example: `MyVariable["MyChildren"]` or `MyVariable.MyChildren.MyGrandChildren`.
|
||||
* Example: `MyObject["MyVariable"]` or `MyObject.MyVariable.MyChildren`.
|
||||
* Example: MyVariable or MyVariable.MyChildren
|
||||
*
|
||||
* Other cases like "MyVariable" or "MyVariable.MyChildren" are IdentifierNode
|
||||
* to allow handling ambiguities.
|
||||
*
|
||||
* \see gd::IdentifierNode
|
||||
* \see gd::VariableAccessorNode
|
||||
* \see gd::VariableBracketAccessorNode
|
||||
*/
|
||||
struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
VariableNode(const gd::String &name_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(), name(name_){};
|
||||
struct VariableNode : public ExpressionNode {
|
||||
VariableNode(const gd::String &type_,
|
||||
const gd::String &name_,
|
||||
const gd::String &objectName_)
|
||||
: type(type_), name(name_), objectName(objectName_){};
|
||||
virtual ~VariableNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitVariableNode(*this);
|
||||
};
|
||||
|
||||
gd::String type;
|
||||
gd::String name;
|
||||
gd::String objectName;
|
||||
|
||||
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>
|
||||
child; // Can be nullptr if no accessor
|
||||
|
||||
ExpressionParserLocation nameLocation;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A direct accessor to a child variable. Example: MyChild
|
||||
* \brief A bracket accessor of a variable. Example: MyChild
|
||||
* in MyVariable.MyChild
|
||||
*/
|
||||
struct GD_CORE_API VariableAccessorNode
|
||||
struct VariableAccessorNode
|
||||
: public VariableAccessorOrVariableBracketAccessorNode {
|
||||
VariableAccessorNode(const gd::String &name_)
|
||||
: VariableAccessorOrVariableBracketAccessorNode(), name(name_){};
|
||||
VariableAccessorNode(const gd::String &name_) : name(name_){};
|
||||
virtual ~VariableAccessorNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitVariableAccessorNode(*this);
|
||||
};
|
||||
|
||||
gd::String name;
|
||||
ExpressionParserLocation nameLocation;
|
||||
ExpressionParserLocation dotLocation;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A bracket accessor to a child variable. Example: ["MyChild"]
|
||||
* \brief A bracket accessor of a variable. Example: ["MyChild"]
|
||||
* (in MyVariable["MyChild"]).
|
||||
*/
|
||||
struct GD_CORE_API VariableBracketAccessorNode
|
||||
struct VariableBracketAccessorNode
|
||||
: public VariableAccessorOrVariableBracketAccessorNode {
|
||||
VariableBracketAccessorNode(std::unique_ptr<ExpressionNode> expression_)
|
||||
: VariableAccessorOrVariableBracketAccessorNode(), expression(std::move(expression_)){};
|
||||
: expression(std::move(expression_)){};
|
||||
virtual ~VariableBracketAccessorNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitVariableBracketAccessorNode(*this);
|
||||
@@ -301,129 +203,92 @@ struct GD_CORE_API VariableBracketAccessorNode
|
||||
std::unique_ptr<ExpressionNode> expression;
|
||||
};
|
||||
|
||||
struct IdentifierOrFunctionOrEmptyNode : public ExpressionNode {};
|
||||
|
||||
/**
|
||||
* \brief The name of a function to call on an object or the behavior
|
||||
* For example: "MyObject.Physics::LinearVelocity".
|
||||
*
|
||||
* Other cases like "MyObject.Function" or "MyObject.Physics" are IdentifierNode
|
||||
* to allow handling ambiguities.
|
||||
*
|
||||
* \see gd::IdentifierNode
|
||||
* \brief An identifier node, usually representing an object.
|
||||
*/
|
||||
struct GD_CORE_API ObjectFunctionNameNode
|
||||
: public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
ObjectFunctionNameNode(const gd::String &objectName_,
|
||||
const gd::String &objectFunctionOrBehaviorName_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
objectName(objectName_),
|
||||
objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {}
|
||||
ObjectFunctionNameNode(const gd::String &objectName_,
|
||||
const gd::String &behaviorName_,
|
||||
const gd::String &behaviorFunctionName_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
objectName(objectName_),
|
||||
objectFunctionOrBehaviorName(behaviorName_),
|
||||
behaviorFunctionName(behaviorFunctionName_) {}
|
||||
virtual ~ObjectFunctionNameNode(){};
|
||||
struct IdentifierNode : public IdentifierOrFunctionOrEmptyNode {
|
||||
IdentifierNode(const gd::String &identifierName_, const gd::String &type_)
|
||||
: identifierName(identifierName_), type(type_){};
|
||||
virtual ~IdentifierNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitObjectFunctionNameNode(*this);
|
||||
worker.OnVisitIdentifierNode(*this);
|
||||
};
|
||||
|
||||
gd::String objectName;
|
||||
gd::String objectFunctionOrBehaviorName; ///< Behavior name if
|
||||
///`behaviorFunctionName` is not
|
||||
/// empty.
|
||||
gd::String behaviorFunctionName; ///< If empty, then
|
||||
/// objectFunctionOrBehaviorName is filled
|
||||
/// with the behavior name.
|
||||
gd::String identifierName;
|
||||
gd::String type;
|
||||
};
|
||||
|
||||
ExpressionParserLocation
|
||||
objectNameLocation; ///< Location of the object name.
|
||||
ExpressionParserLocation
|
||||
objectNameDotLocation; ///< Location of the "." after the object name.
|
||||
ExpressionParserLocation objectFunctionOrBehaviorNameLocation; ///< Location
|
||||
/// of object
|
||||
/// function
|
||||
/// name or
|
||||
/// behavior
|
||||
/// name.
|
||||
ExpressionParserLocation
|
||||
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
|
||||
/// separator, if any.
|
||||
ExpressionParserLocation behaviorFunctionNameLocation; ///< Location of the
|
||||
/// behavior function
|
||||
/// name, if any.
|
||||
struct FunctionOrEmptyNode : public IdentifierOrFunctionOrEmptyNode {
|
||||
virtual ~FunctionOrEmptyNode(){};
|
||||
void Visit(ExpressionParser2NodeWorker &worker) override{};
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief A function call node (either free function, object function or object
|
||||
* behavior function).
|
||||
* For example: "MyExtension::MyFunction(1, 2)", "MyObject.Function()" or
|
||||
* "MyObject.Physics::LinearVelocity()".
|
||||
* \brief A function node. For example: "MyExtension::MyFunction(1, 2)".
|
||||
*/
|
||||
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
/** \brief Construct a free function call node. */
|
||||
FunctionCallNode(const gd::String &functionName_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
struct FunctionNode : public FunctionOrEmptyNode {
|
||||
FunctionNode(const gd::String &type_,
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
|
||||
const ExpressionMetadata &expressionMetadata_,
|
||||
const gd::String &functionName_)
|
||||
: type(type_),
|
||||
parameters(std::move(parameters_)),
|
||||
expressionMetadata(expressionMetadata_),
|
||||
functionName(functionName_){};
|
||||
|
||||
/** \brief Construct an object function call node. */
|
||||
FunctionCallNode(const gd::String &objectName_,
|
||||
const gd::String &functionName_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
FunctionNode(const gd::String &type_,
|
||||
const gd::String &objectName_,
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
|
||||
const ExpressionMetadata &expressionMetadata_,
|
||||
const gd::String &functionName_)
|
||||
: type(type_),
|
||||
objectName(objectName_),
|
||||
parameters(std::move(parameters_)),
|
||||
expressionMetadata(expressionMetadata_),
|
||||
functionName(functionName_){};
|
||||
|
||||
/** \brief Construct a behavior function call node. */
|
||||
FunctionCallNode(const gd::String &objectName_,
|
||||
const gd::String &behaviorName_,
|
||||
const gd::String &functionName_)
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
|
||||
FunctionNode(const gd::String &type_,
|
||||
const gd::String &objectName_,
|
||||
const gd::String &behaviorName_,
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
|
||||
const ExpressionMetadata &expressionMetadata_,
|
||||
const gd::String &functionName_)
|
||||
: type(type_),
|
||||
objectName(objectName_),
|
||||
behaviorName(behaviorName_),
|
||||
parameters(std::move(parameters_)),
|
||||
expressionMetadata(expressionMetadata_),
|
||||
functionName(functionName_){};
|
||||
virtual ~FunctionCallNode(){};
|
||||
virtual ~FunctionNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitFunctionCallNode(*this);
|
||||
worker.OnVisitFunctionNode(*this);
|
||||
};
|
||||
|
||||
gd::String type; // This could be removed if the type ("string" or "number")
|
||||
// was stored in ExpressionMetadata.
|
||||
gd::String objectName;
|
||||
gd::String behaviorName;
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters;
|
||||
const ExpressionMetadata &expressionMetadata;
|
||||
gd::String functionName;
|
||||
|
||||
ExpressionParserLocation
|
||||
functionNameLocation; ///< Location of the function name.
|
||||
ExpressionParserLocation
|
||||
objectNameLocation; ///< Location of the object name, if any.
|
||||
ExpressionParserLocation
|
||||
objectNameDotLocation; ///< Location of the "." after the object name.
|
||||
ExpressionParserLocation
|
||||
behaviorNameLocation; ///< Location of the behavior name, if any.
|
||||
ExpressionParserLocation
|
||||
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
|
||||
/// separator, if any.
|
||||
ExpressionParserLocation
|
||||
openingParenthesisLocation; ///< Location of the "(".
|
||||
ExpressionParserLocation
|
||||
closingParenthesisLocation; ///< Location of the ")".
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief An empty node, used when parsing failed/a syntax error was
|
||||
* encountered and any other node could not make sense.
|
||||
*/
|
||||
struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
EmptyNode(const gd::String &text_ = "")
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(), text(text_){};
|
||||
struct EmptyNode : public FunctionOrEmptyNode {
|
||||
EmptyNode(const gd::String &type_, const gd::String &text_ = "")
|
||||
: type(type_), text(text_){};
|
||||
virtual ~EmptyNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
worker.OnVisitEmptyNode(*this);
|
||||
};
|
||||
|
||||
gd::String type;
|
||||
gd::String text;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
#endif
|
@@ -91,19 +91,8 @@ class GD_CORE_API ExpressionParser2NodePrinter
|
||||
}
|
||||
void OnVisitIdentifierNode(IdentifierNode& node) override {
|
||||
output += node.identifierName;
|
||||
if (!node.childIdentifierName.empty()) {
|
||||
output += "." + node.childIdentifierName;
|
||||
}
|
||||
}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
|
||||
if (!node.behaviorFunctionName.empty()) {
|
||||
output +=
|
||||
node.objectName + "." + node.objectFunctionOrBehaviorName + "::" + node.behaviorFunctionName;
|
||||
} else {
|
||||
output += node.objectName + "." + node.objectFunctionOrBehaviorName;
|
||||
}
|
||||
};
|
||||
void OnVisitFunctionCallNode(FunctionCallNode& node) override {
|
||||
void OnVisitFunctionNode(FunctionNode& node) override {
|
||||
if (!node.behaviorName.empty()) {
|
||||
output +=
|
||||
node.objectName + "." + node.behaviorName + "::" + node.functionName;
|
||||
|
@@ -7,21 +7,20 @@
|
||||
#define GDCORE_EXPRESSIONPARSER2NODEWORKER_H
|
||||
|
||||
namespace gd {
|
||||
struct ExpressionNode;
|
||||
struct SubExpressionNode;
|
||||
struct OperatorNode;
|
||||
struct UnaryOperatorNode;
|
||||
struct NumberNode;
|
||||
struct TextNode;
|
||||
struct VariableNode;
|
||||
struct VariableAccessorNode;
|
||||
struct VariableBracketAccessorNode;
|
||||
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
struct IdentifierNode;
|
||||
struct FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
struct ObjectFunctionNameNode;
|
||||
struct FunctionCallNode;
|
||||
struct EmptyNode;
|
||||
class ExpressionNode;
|
||||
class SubExpressionNode;
|
||||
class OperatorNode;
|
||||
class UnaryOperatorNode;
|
||||
class NumberNode;
|
||||
class TextNode;
|
||||
class VariableNode;
|
||||
class VariableAccessorNode;
|
||||
class VariableBracketAccessorNode;
|
||||
class IdentifierOrFunctionOrEmptyNode;
|
||||
class IdentifierNode;
|
||||
class FunctionOrEmptyNode;
|
||||
class FunctionNode;
|
||||
class EmptyNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -34,21 +33,20 @@ namespace gd {
|
||||
* \see gd::ExpressionNode
|
||||
*/
|
||||
class GD_CORE_API ExpressionParser2NodeWorker {
|
||||
friend struct ExpressionNode;
|
||||
friend struct SubExpressionNode;
|
||||
friend struct OperatorNode;
|
||||
friend struct UnaryOperatorNode;
|
||||
friend struct NumberNode;
|
||||
friend struct TextNode;
|
||||
friend struct VariableNode;
|
||||
friend struct VariableAccessorNode;
|
||||
friend struct VariableBracketAccessorNode;
|
||||
friend struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend struct IdentifierNode;
|
||||
friend struct FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend struct ObjectFunctionNameNode;
|
||||
friend struct FunctionCallNode;
|
||||
friend struct EmptyNode;
|
||||
friend class ExpressionNode;
|
||||
friend class SubExpressionNode;
|
||||
friend class OperatorNode;
|
||||
friend class UnaryOperatorNode;
|
||||
friend class NumberNode;
|
||||
friend class TextNode;
|
||||
friend class VariableNode;
|
||||
friend class VariableAccessorNode;
|
||||
friend class VariableBracketAccessorNode;
|
||||
friend class IdentifierOrFunctionOrEmptyNode;
|
||||
friend class IdentifierNode;
|
||||
friend class FunctionOrEmptyNode;
|
||||
friend class FunctionNode;
|
||||
friend class EmptyNode;
|
||||
|
||||
public:
|
||||
virtual ~ExpressionParser2NodeWorker();
|
||||
@@ -64,11 +62,10 @@ class GD_CORE_API ExpressionParser2NodeWorker {
|
||||
virtual void OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode& node) = 0;
|
||||
virtual void OnVisitIdentifierNode(IdentifierNode& node) = 0;
|
||||
virtual void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) = 0;
|
||||
virtual void OnVisitFunctionCallNode(FunctionCallNode& node) = 0;
|
||||
virtual void OnVisitFunctionNode(FunctionNode& node) = 0;
|
||||
virtual void OnVisitEmptyNode(EmptyNode& node) = 0;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
#endif
|
@@ -1,118 +0,0 @@
|
||||
#pragma once
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* Contains functions to handle the grammar of the expressions accepted by GDevelop.
|
||||
*/
|
||||
namespace GrammarTerminals {
|
||||
|
||||
inline bool IsWhitespace(gd::String::value_type character) {
|
||||
return character == ' ' || character == '\n' || character == '\r';
|
||||
}
|
||||
|
||||
inline bool IsParameterSeparator(gd::String::value_type character) {
|
||||
return character == ',';
|
||||
}
|
||||
|
||||
inline bool IsDot(gd::String::value_type character) { return character == '.'; }
|
||||
|
||||
inline bool IsQuote(gd::String::value_type character) {
|
||||
return character == '"';
|
||||
}
|
||||
|
||||
inline bool IsBracket(gd::String::value_type character) {
|
||||
return character == '(' || character == ')' || character == '[' ||
|
||||
character == ']' || character == '{' || character == '}';
|
||||
}
|
||||
|
||||
inline bool IsOpeningParenthesis(gd::String::value_type character) {
|
||||
return character == '(';
|
||||
}
|
||||
|
||||
inline bool IsClosingParenthesis(gd::String::value_type character) {
|
||||
return character == ')';
|
||||
}
|
||||
|
||||
inline bool IsOpeningSquareBracket(gd::String::value_type character) {
|
||||
return character == '[';
|
||||
}
|
||||
|
||||
inline bool IsClosingSquareBracket(gd::String::value_type character) {
|
||||
return character == ']';
|
||||
}
|
||||
|
||||
inline bool IsExpressionEndingChar(gd::String::value_type character) {
|
||||
return character == ',' || IsClosingParenthesis(character) ||
|
||||
IsClosingSquareBracket(character);
|
||||
}
|
||||
|
||||
inline bool IsExpressionOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-' || character == '<' ||
|
||||
character == '>' || character == '?' || character == '^' ||
|
||||
character == '=' || character == '\\' || character == ':' ||
|
||||
character == '!';
|
||||
}
|
||||
|
||||
inline bool IsUnaryOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-';
|
||||
}
|
||||
|
||||
inline bool IsTermOperator(gd::String::value_type character) {
|
||||
return character == '/' || character == '*';
|
||||
}
|
||||
|
||||
inline bool IsNumberFirstChar(gd::String::value_type character) {
|
||||
return character == '.' || (character >= '0' && character <= '9');
|
||||
}
|
||||
|
||||
inline bool IsNonZeroDigit(gd::String::value_type character) {
|
||||
return (character >= '1' && character <= '9');
|
||||
}
|
||||
|
||||
inline bool IsZeroDigit(gd::String::value_type character) {
|
||||
return character == '0';
|
||||
}
|
||||
|
||||
inline bool IsAdditionalReservedCharacter(gd::String::value_type character) {
|
||||
// These characters are not part of the grammar - but are often used in programming language
|
||||
// and could become operators or part of the grammar one day.
|
||||
return character == '~' || character == '\'' || character == '%' ||
|
||||
character == '#' || character == '@' || character == '|' ||
|
||||
character == '&' || character == '`' || character == '$' ||
|
||||
character == ';';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given character can be used in an identifier. This is
|
||||
* any unicode character, except for:
|
||||
* `, . " () [] {} + - < > ? ^ = \ : ! / * ~ ' % # @ | & $ ;`
|
||||
* and backtick and whitespaces (space, line break, carriage return).
|
||||
*
|
||||
* This is loosely based on what is allowed in languages like JavaScript
|
||||
* (see https://mathiasbynens.be/notes/javascript-properties), without support
|
||||
* for unicode escape syntax, and allowing all unicode ranges. The only
|
||||
* disallowed characters are the one used for the grammar.
|
||||
*/
|
||||
inline bool IsAllowedInIdentifier(gd::String::value_type character) {
|
||||
// Quickly compare if the character is a number or ASCII character.
|
||||
if ((character >= '0' && character <= '9') ||
|
||||
(character >= 'A' && character <= 'Z') ||
|
||||
(character >= 'a' && character <= 'z'))
|
||||
return true;
|
||||
|
||||
// Otherwise do the full check against separators forbidden in identifiers.
|
||||
if (!IsParameterSeparator(character) && !IsDot(character) &&
|
||||
!IsQuote(character) && !IsBracket(character) &&
|
||||
!IsExpressionOperator(character) && !IsTermOperator(character) &&
|
||||
!IsWhitespace(character) && !IsAdditionalReservedCharacter(character)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace GrammarTerminals
|
||||
} // namespace gd
|
141
Core/GDCore/Events/Parsers/VariableParser.cpp
Normal file
141
Core/GDCore/Events/Parsers/VariableParser.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Parsers/VariableParser.h"
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Platform;
|
||||
}
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
VariableParser::~VariableParser() {}
|
||||
|
||||
bool VariableParser::Parse(VariableParserCallbacks& callbacks_) {
|
||||
callbacks = &callbacks_;
|
||||
rootVariableParsed = false;
|
||||
firstErrorStr.clear();
|
||||
firstErrorPos = 0;
|
||||
currentPositionIt = expression.begin();
|
||||
currentTokenType = TS_INVALID;
|
||||
currentToken.clear();
|
||||
S();
|
||||
|
||||
return firstErrorStr == "";
|
||||
}
|
||||
|
||||
void VariableParser::ReadToken() {
|
||||
currentTokenType = TS_INVALID;
|
||||
currentToken.clear();
|
||||
while (currentPositionIt != expression.end()) {
|
||||
char32_t currentChar = *currentPositionIt;
|
||||
if (currentChar == U'[' || currentChar == U']' || currentChar == U'.') {
|
||||
if (currentTokenType == TS_VARNAME)
|
||||
return; // We've parsed a variable name.
|
||||
}
|
||||
|
||||
if (currentChar == U'[') {
|
||||
currentTokenType = TS_OPENING_BRACKET;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
} else if (currentChar == U']') {
|
||||
currentTokenType = TS_CLOSING_BRACKET;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
} else if (currentChar == U'.') {
|
||||
currentTokenType = TS_PERIOD;
|
||||
currentToken.clear();
|
||||
++currentPositionIt;
|
||||
return;
|
||||
}
|
||||
|
||||
currentTokenType = TS_VARNAME; // We're parsing a variable name.
|
||||
currentToken.push_back(currentChar);
|
||||
++currentPositionIt;
|
||||
}
|
||||
|
||||
// Can be reached if we are at the end of the expression. In this case,
|
||||
// currentTokenType will be either TS_VARNAME or TS_INVALID.
|
||||
}
|
||||
|
||||
void VariableParser::S() {
|
||||
ReadToken();
|
||||
if (currentTokenType != TS_VARNAME) {
|
||||
firstErrorStr = _("Expecting a variable name.");
|
||||
firstErrorPos = std::distance<gd::String::const_iterator>(
|
||||
expression.begin(), currentPositionIt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rootVariableParsed) {
|
||||
rootVariableParsed = true;
|
||||
if (callbacks) callbacks->OnRootVariable(currentToken);
|
||||
} else if (callbacks)
|
||||
callbacks->OnChildVariable(currentToken);
|
||||
|
||||
X();
|
||||
}
|
||||
|
||||
void VariableParser::X() {
|
||||
ReadToken();
|
||||
if (currentTokenType == TS_INVALID)
|
||||
return; // Ended parsing.
|
||||
else if (currentTokenType == TS_PERIOD)
|
||||
S();
|
||||
else if (currentTokenType == TS_OPENING_BRACKET) {
|
||||
gd::String strExpr = SkipStringExpression();
|
||||
|
||||
ReadToken();
|
||||
if (currentTokenType != TS_CLOSING_BRACKET) {
|
||||
firstErrorStr = _("Expecting ]");
|
||||
firstErrorPos = std::distance<gd::String::const_iterator>(
|
||||
expression.begin(), currentPositionIt);
|
||||
return;
|
||||
}
|
||||
if (callbacks) callbacks->OnChildSubscript(strExpr);
|
||||
X();
|
||||
}
|
||||
}
|
||||
|
||||
gd::String VariableParser::SkipStringExpression() {
|
||||
gd::String stringExpression;
|
||||
bool insideStringLiteral = false;
|
||||
bool lastCharacterWasBackslash = false;
|
||||
unsigned int nestedBracket = 0;
|
||||
while (currentPositionIt != expression.end()) {
|
||||
char32_t currentChar = *currentPositionIt;
|
||||
if (currentChar == U'\"') {
|
||||
if (!insideStringLiteral)
|
||||
insideStringLiteral = true;
|
||||
else if (!lastCharacterWasBackslash)
|
||||
insideStringLiteral = false;
|
||||
} else if (currentChar == U'[' && !insideStringLiteral) {
|
||||
nestedBracket++;
|
||||
} else if (currentChar == U']' && !insideStringLiteral) {
|
||||
if (nestedBracket == 0)
|
||||
return stringExpression; // Found the end of the string litteral.
|
||||
nestedBracket--;
|
||||
}
|
||||
|
||||
lastCharacterWasBackslash = currentChar == U'\\';
|
||||
stringExpression.push_back(currentChar);
|
||||
++currentPositionIt;
|
||||
}
|
||||
|
||||
// End of the expression reached (so expression is invalid by the way)
|
||||
return stringExpression;
|
||||
}
|
||||
|
||||
} // namespace gd
|
148
Core/GDCore/Events/Parsers/VariableParser.h
Normal file
148
Core/GDCore/Events/Parsers/VariableParser.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_VARIABLEPARSER_H
|
||||
#define GDCORE_VARIABLEPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Layout;
|
||||
}
|
||||
namespace gd {
|
||||
class Project;
|
||||
}
|
||||
namespace gd {
|
||||
class Platform;
|
||||
}
|
||||
namespace gd {
|
||||
class VariableParserCallbacks;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/** \brief Parse a variable expression.
|
||||
*
|
||||
* Parse an variable expression ( like
|
||||
myVariable.child["subchild"+ToString(i)].subsubchild ),
|
||||
* calling callbacks when a token is reached.
|
||||
*
|
||||
* Usage example:
|
||||
\code
|
||||
//...
|
||||
|
||||
//VariableCodeGenerationCallbacks is a class inheriting from
|
||||
gd::VariableParserCallbacks VariableCodeGenerationCallbacks callbacks(output,
|
||||
*this, context, VariableCodeGenerationCallbacks::PROJECT_VARIABLE);
|
||||
|
||||
gd::VariableParser parser(parameter);
|
||||
if ( !parser.Parse(callbacks) )
|
||||
cout << "Error :" << parser.GetFirstError() << " in: "<< parameter <<
|
||||
endl;
|
||||
\endcode
|
||||
*
|
||||
* Here is the parsed grammar: <br>
|
||||
* S -> VarName X <br>
|
||||
* X -> e | . S | [StringExpression] X <br>
|
||||
*
|
||||
* where e = nothing (end of expression), StringExpression = A valid string
|
||||
expression and
|
||||
* S is the start.
|
||||
*
|
||||
* \see gd::VariableParserCallbacks
|
||||
*/
|
||||
class GD_CORE_API VariableParser {
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor
|
||||
* \param expressionPlainString The string representing the expression to be
|
||||
* parsed.
|
||||
*/
|
||||
VariableParser(const gd::String& expressionPlainString_)
|
||||
: currentPositionIt(), expression(expressionPlainString_){};
|
||||
virtual ~VariableParser();
|
||||
|
||||
/**
|
||||
* Parse the expression, calling each callback when necessary.
|
||||
* \param callbacks The callbacks to be called.
|
||||
* \return true if expression was correctly parsed.
|
||||
* \see gd::VariableParserCallbacks
|
||||
*/
|
||||
bool Parse(VariableParserCallbacks& callbacks);
|
||||
|
||||
/**
|
||||
* \brief Return the description of the error that was found
|
||||
*/
|
||||
const gd::String& GetFirstError() { return firstErrorStr; }
|
||||
|
||||
/**
|
||||
* \brief Return the position of the error that was found
|
||||
* \return The position, or gd::String::npos if no error is found
|
||||
*/
|
||||
size_t GetFirstErrorPosition() { return firstErrorPos; }
|
||||
|
||||
gd::String firstErrorStr;
|
||||
size_t firstErrorPos;
|
||||
|
||||
private:
|
||||
void S();
|
||||
void X();
|
||||
|
||||
/**
|
||||
* \brief Skip the string expression, starting from the current position.
|
||||
* \return The string expression skipped. currentPosition is now put on the
|
||||
* closing bracket.
|
||||
*/
|
||||
gd::String SkipStringExpression();
|
||||
|
||||
void ReadToken();
|
||||
|
||||
enum TokenType {
|
||||
TS_PERIOD,
|
||||
TS_OPENING_BRACKET,
|
||||
TS_CLOSING_BRACKET,
|
||||
TS_VARNAME,
|
||||
TS_INVALID
|
||||
};
|
||||
|
||||
TokenType currentTokenType;
|
||||
gd::String currentToken;
|
||||
gd::String::const_iterator currentPositionIt;
|
||||
gd::String expression;
|
||||
|
||||
VariableParserCallbacks* callbacks;
|
||||
bool rootVariableParsed;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Callbacks called by VariableParser when parsing a variable expression.
|
||||
*/
|
||||
class GD_CORE_API VariableParserCallbacks {
|
||||
public:
|
||||
/**
|
||||
* \brief Called when the first variable has been parsed. ( varName1 in
|
||||
* varName1.child for example. ) \param variableName The variable name.
|
||||
*/
|
||||
virtual void OnRootVariable(gd::String variableName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable. ( child in
|
||||
* varName1.child for example. ) \param variableName The child variable name.
|
||||
*/
|
||||
virtual void OnChildVariable(gd::String variableName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Called when accessing the child of a structure variable using a
|
||||
* string expression in square brackets. ( "subscript" in
|
||||
* varName1["subscript"] for example. )
|
||||
*
|
||||
* \param variableName The expression used to access the child variable.
|
||||
*/
|
||||
virtual void OnChildSubscript(gd::String stringExpression) = 0;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDEXPRESSIONPARSER_H
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
@@ -184,8 +183,8 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
|
||||
for (std::size_t j = 0;
|
||||
j < parameters.size() && j < metadata.parameters.size();
|
||||
++j) {
|
||||
if (metadata.parameters[j].GetType() == "relationalOperator" ||
|
||||
metadata.parameters[j].GetType() == "operator") {
|
||||
if (metadata.parameters[j].type == "relationalOperator" ||
|
||||
metadata.parameters[j].type == "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";
|
||||
@@ -219,8 +218,8 @@ void EventsListSerialization::UnserializeEventsFrom(
|
||||
event = std::make_shared<EmptyEvent>();
|
||||
}
|
||||
|
||||
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
|
||||
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
|
||||
event->SetDisabled(eventElem.GetBoolAttribute("disabled"));
|
||||
event->SetFolded(eventElem.GetBoolAttribute("folded"));
|
||||
|
||||
list.InsertEvent(event, list.GetEventsCount());
|
||||
}
|
||||
@@ -233,9 +232,8 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
|
||||
const gd::BaseEvent& event = list.GetEvent(j);
|
||||
SerializerElement& eventElem = events.AddChild("event");
|
||||
|
||||
if (event.IsDisabled())
|
||||
eventElem.SetAttribute("disabled", event.IsDisabled());
|
||||
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
|
||||
eventElem.SetAttribute("disabled", event.IsDisabled());
|
||||
eventElem.SetAttribute("folded", event.IsFolded());
|
||||
eventElem.AddChild("type").SetValue(event.GetType());
|
||||
|
||||
event.SerializeTo(eventElem);
|
||||
@@ -269,9 +267,6 @@ void gd::EventsListSerialization::UnserializeInstructionsFrom(
|
||||
instrElement.GetChild("type", 0, "Type")
|
||||
.GetBoolAttribute("inverted", false, "Contraire"));
|
||||
|
||||
instruction.SetAwaited(
|
||||
instrElement.GetChild("type", 0, "Type").GetBoolAttribute("await"));
|
||||
|
||||
// Read parameters
|
||||
vector<gd::Expression> parameters;
|
||||
|
||||
@@ -345,12 +340,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
instructions.ConsiderAsArrayOf("instruction");
|
||||
for (std::size_t k = 0; k < list.size(); k++) {
|
||||
SerializerElement& instruction = instructions.AddChild("instruction");
|
||||
instruction.AddChild("type").SetAttribute("value", list[k].GetType());
|
||||
|
||||
if (list[k].IsInverted())
|
||||
instruction.GetChild("type").SetAttribute("inverted", true);
|
||||
if (list[k].IsAwaited())
|
||||
instruction.GetChild("type").SetAttribute("await", true);
|
||||
instruction.AddChild("type")
|
||||
.SetAttribute("value", list[k].GetType())
|
||||
.SetAttribute("inverted", list[k].IsInverted());
|
||||
|
||||
// Parameters
|
||||
SerializerElement& parameters = instruction.AddChild("parameters");
|
||||
@@ -360,10 +352,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
|
||||
.SetValue(list[k].GetParameter(l).GetPlainString());
|
||||
|
||||
// Sub instructions
|
||||
if (!list[k].GetSubInstructions().empty()) {
|
||||
SerializeInstructionsTo(list[k].GetSubInstructions(),
|
||||
instruction.AddChild("subInstructions"));
|
||||
}
|
||||
SerializerElement& subInstructions =
|
||||
instruction.AddChild("subInstructions");
|
||||
SerializeInstructionsTo(list[k].GetSubInstructions(), subInstructions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,16 +8,11 @@
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::_singleton = nullptr;
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::_singleton = NULL;
|
||||
|
||||
const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
gd::String EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
const gd::String &originalObjectName) {
|
||||
auto it = mangledObjectNames.find(originalObjectName);
|
||||
if (it != mangledObjectNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(originalObjectName);
|
||||
gd::String partiallyMangledName = originalObjectName;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -32,26 +27,12 @@ const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
}
|
||||
}
|
||||
|
||||
mangledObjectNames[originalObjectName] = "GD" + partiallyMangledName + "Objects";
|
||||
return mangledObjectNames[originalObjectName];
|
||||
return "GD" + partiallyMangledName + "Objects";
|
||||
}
|
||||
|
||||
const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
gd::String EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName) {
|
||||
auto it = mangledExternalEventsNames.find(externalEventsName);
|
||||
if (it != mangledExternalEventsNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(externalEventsName);
|
||||
|
||||
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
|
||||
return mangledExternalEventsNames[externalEventsName];
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledNameWithForbiddenUnderscore(
|
||||
const gd::String &name) {
|
||||
gd::String partiallyMangledName = name;
|
||||
gd::String partiallyMangledName = externalEventsName;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -65,44 +46,24 @@ gd::String EventsCodeNameMangler::GetMangledNameWithForbiddenUnderscore(
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
return partiallyMangledName;
|
||||
|
||||
return "GDExternalEvents" + partiallyMangledName;
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledName(
|
||||
const gd::String &name) {
|
||||
gd::String partiallyMangledName = name;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
for (size_t i = 0; i < partiallyMangledName.size();
|
||||
++i) // Replace all unallowed letter by an underscore and the ascii
|
||||
// number of the letter
|
||||
{
|
||||
if (allowedCharacters.find_first_of(
|
||||
std::u32string(1, partiallyMangledName[i])) == gd::String::npos) {
|
||||
char32_t unallowedChar = partiallyMangledName[i];
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
return partiallyMangledName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const gd::String& ManObjListName(const gd::String &objectName) {
|
||||
gd::String ManObjListName(const gd::String &objectName) {
|
||||
return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName);
|
||||
}
|
||||
|
||||
EventsCodeNameMangler *EventsCodeNameMangler::Get() {
|
||||
if (nullptr == _singleton) _singleton = new EventsCodeNameMangler;
|
||||
if (NULL == _singleton) _singleton = new EventsCodeNameMangler;
|
||||
|
||||
return (static_cast<EventsCodeNameMangler *>(_singleton));
|
||||
}
|
||||
|
||||
void EventsCodeNameMangler::DestroySingleton() {
|
||||
if (nullptr != _singleton) {
|
||||
if (NULL != _singleton) {
|
||||
delete _singleton;
|
||||
_singleton = nullptr;
|
||||
_singleton = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,38 +6,28 @@
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef EVENTSCODENAMEMANGLER_H
|
||||
#define EVENTSCODENAMEMANGLER_H
|
||||
#include <unordered_map>
|
||||
#include "GDCore/String.h"
|
||||
|
||||
/**
|
||||
* \brief Mangle object names, so as to ensure all names used in code are valid.
|
||||
* Manage name mangling, so as to ensure all names used in code are valid.
|
||||
*
|
||||
* \see ManObjListName
|
||||
*/
|
||||
class GD_CORE_API EventsCodeNameMangler {
|
||||
public:
|
||||
/**
|
||||
* Get the mangled name from a name: All characters that are not 0-9, a-z,
|
||||
* Get the mangled name from a name : All characters that are not 0-9, a-z,
|
||||
* A-Z or _ are replaced by "_"+AsciiCodeOfTheCharacter.
|
||||
*
|
||||
* The mangled name is memoized as this is intensively used during project
|
||||
* export and events code generation.
|
||||
*/
|
||||
const gd::String &GetMangledObjectsListName(
|
||||
const gd::String &originalObjectName);
|
||||
gd::String GetMangledObjectsListName(const gd::String &originalObjectName);
|
||||
|
||||
/**
|
||||
* Get the mangled function name to be used to call external events named \a
|
||||
* externalEventsName.
|
||||
*
|
||||
* The mangled name is memoized as this is intensively used during project
|
||||
* export and events code generation.
|
||||
*/
|
||||
const gd::String &GetExternalEventsFunctionMangledName(
|
||||
gd::String GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName);
|
||||
|
||||
static gd::String GetMangledName(const gd::String &name);
|
||||
|
||||
static EventsCodeNameMangler *Get();
|
||||
static void DestroySingleton();
|
||||
|
||||
@@ -45,25 +35,14 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
EventsCodeNameMangler(){};
|
||||
virtual ~EventsCodeNameMangler(){};
|
||||
static EventsCodeNameMangler *_singleton;
|
||||
|
||||
// This method is inlined to avoid to copy the returned string.
|
||||
static inline gd::String GetMangledNameWithForbiddenUnderscore(const gd::String &name);
|
||||
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledObjectNames; ///< Memoized results of mangling for objects
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledExternalEventsNames; ///< Memoized results of mangling for
|
||||
/// external events
|
||||
};
|
||||
|
||||
/**
|
||||
* Shortcut for
|
||||
* `EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName)`.
|
||||
*
|
||||
* \see EventsCodeNameMangler
|
||||
* \return Mangled object name
|
||||
* Shortcut to
|
||||
* EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName). \see
|
||||
* EventsCodeNameMangler \return Mangled object name
|
||||
*/
|
||||
const gd::String &GD_CORE_API ManObjListName(const gd::String &objectName);
|
||||
gd::String GD_CORE_API ManObjListName(const gd::String &objectName);
|
||||
|
||||
#endif // EVENTSCODENAMEMANGLER_H
|
||||
#endif
|
||||
|
@@ -11,16 +11,26 @@ namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension.SetExtensionInformation(
|
||||
"BuiltinAdvanced",
|
||||
_("Advanced control features"),
|
||||
_("Built-in extension providing advanced control features."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinAdvanced",
|
||||
_("Event functions"),
|
||||
_("Advanced control features for functions made with events."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetCategory("Advanced");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Event functions"))
|
||||
.SetIcon("res/function32.png");
|
||||
.AddCondition("Toujours",
|
||||
_("Always"),
|
||||
_("This condition always returns true (or always false, if "
|
||||
"the condition is inverted)."),
|
||||
_("Always"),
|
||||
_("Other"),
|
||||
"res/conditions/toujours24.png",
|
||||
"res/conditions/toujours.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
@@ -29,12 +39,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Set the return value of the events function to the specified "
|
||||
"number (to be used with \"Expression\" functions)."),
|
||||
_("Set return value to number _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("expression", _("The number to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.AddParameter("expression", "The number to be returned")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -44,12 +53,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Set the return value of the events function to the specified text "
|
||||
"(to be used with \"String Expression\" functions)."),
|
||||
_("Set return value to text _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("string", _("The text to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.AddParameter("string", "The text to be returned")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -58,106 +66,31 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Set the return value of the Condition events function to "
|
||||
"either true (condition will pass) or false."),
|
||||
_("Set return value of the condition to _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("trueorfalse", _("Should the condition be true or false?"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyArgumentToVariable",
|
||||
_("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("scenevar", _("Scene variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CopyVariableToArgument",
|
||||
_("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("scenevar", _("Scene variable"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("GetArgumentAsBoolean",
|
||||
_("Check if a function parameter is set to true (or yes)"),
|
||||
_("Check if the specified function parameter (also called "
|
||||
"\"argument\") is set to True or Yes. If the argument is "
|
||||
"a string, an empty string is considered as \"false\". "
|
||||
"If it's a number, 0 is considered as \"false\"."),
|
||||
_("Parameter _PARAM0_ is true"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.AddParameter("trueorfalse", "Should the condition be true or false?")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"GetArgumentAsNumber",
|
||||
_("Get function parameter value"),
|
||||
_("Get function parameter (also called \"argument\") value."),
|
||||
"",
|
||||
_("Get function parameter (also called \"argument\") value"),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.AddParameter("string", "Parameter name");
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
"GetArgumentAsString",
|
||||
_("Get function parameter text"),
|
||||
_("Get function parameter (also called \"argument\") text."),
|
||||
"",
|
||||
_("Get function parameter (also called \"argument\") text "),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"CompareArgumentAsNumber",
|
||||
_("Compare function parameter value"),
|
||||
_("Compare function parameter (also called \"argument\") value."),
|
||||
_("Parameter _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"CompareArgumentAsString",
|
||||
_("Compare function parameter text"),
|
||||
_("Compare function parameter (also called \"argument\") text."),
|
||||
_("Parameter _PARAM0_"),
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
.AddParameter("string", "Parameter name");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -15,6 +15,8 @@ namespace gd {
|
||||
* so that it provides standards events, objects or instructions of an
|
||||
* extension.
|
||||
*
|
||||
* TOOD: Usage example.
|
||||
*
|
||||
* \ingroup BuiltinExtensions
|
||||
*/
|
||||
class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
@@ -30,6 +32,7 @@ class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
static void ImplementsExternalLayoutsExtension(
|
||||
gd::PlatformExtension& extension);
|
||||
static void ImplementsFileExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsJoystickExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsKeyboardExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsMathematicalToolsExtension(
|
||||
gd::PlatformExtension& extension);
|
||||
@@ -42,13 +45,6 @@ class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
static void ImplementsTimeExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsVariablesExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsWindowExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAsyncExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsResizableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsScalableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsFlippableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAnimatableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsEffectExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsOpacityExtension(gd::PlatformExtension& extension);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -1,47 +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 "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAsyncExtension(
|
||||
gd::PlatformExtension &extension) {
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinAsync",
|
||||
_("Asynchronous functions"),
|
||||
_("Functions that defer the execution of the events after it."),
|
||||
"Arthur Pacaud (arthuro555)",
|
||||
"Open source (MIT License)")
|
||||
.SetCategory("Advanced");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Asynchronous functions"))
|
||||
.SetIcon("res/function32.png");
|
||||
|
||||
extension.AddEvent("Async",
|
||||
_("Async event"),
|
||||
_("Internal event for asynchronous actions"),
|
||||
"",
|
||||
"res/eventaddicon.png",
|
||||
std::make_shared<gd::AsyncEvent>());
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"ResolveAsyncEventsFunction",
|
||||
_("End asynchronous function"),
|
||||
_("Mark an asynchronous function as finished. This will allow the "
|
||||
"actions and subevents following it to be run."),
|
||||
"Mark asynchronous function as ended",
|
||||
"",
|
||||
"res/actions/quit24.png",
|
||||
"res/actions/quit.png")
|
||||
.AddCodeOnlyParameter("eventsFunctionContext", "")
|
||||
.SetRelevantForAsynchronousFunctionEventsOnly();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -12,20 +12,14 @@ namespace gd {
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinAudio",
|
||||
_("Sounds and music"),
|
||||
_("GDevelop provides several conditions and actions to play audio "
|
||||
"files. They can be either long music or short sound effects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/audio")
|
||||
.SetCategory("Audio");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and music"))
|
||||
.SetIcon("res/actions/music24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds on channels"))
|
||||
.SetIcon("res/actions/son24.png");
|
||||
.SetExtensionInformation("BuiltinAudio",
|
||||
_("Audio"),
|
||||
_("Builtin audio extension"),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/audio");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction("PlaySoundCanal",
|
||||
_("Play a sound on a channel"),
|
||||
@@ -33,7 +27,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"you'll be able to manipulate it."),
|
||||
_("Play the sound _PARAM1_ on the channel _PARAM2_, vol.: "
|
||||
"_PARAM4_, loop: _PARAM3_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -54,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Stop the sound of a channel"),
|
||||
_("Stop the sound on the specified channel."),
|
||||
_("Stop the sound of channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -66,7 +60,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Pause the sound of a channel"),
|
||||
_("Pause the sound played on the specified channel."),
|
||||
_("Pause the sound of channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -75,10 +69,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
|
||||
extension
|
||||
.AddAction("RePlaySoundCanal",
|
||||
_("Resume playing a sound on a channel"),
|
||||
_("Resume playing a sound on a channel that was paused."),
|
||||
_("Resume the sound of channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Play the sound of a channel"),
|
||||
_("Play the sound of the channel."),
|
||||
_("Play the sound of channel _PARAM1_"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -92,7 +86,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"able to interact with it later."),
|
||||
_("Play the music _PARAM1_ on channel _PARAM2_, vol.: "
|
||||
"_PARAM4_, loop: _PARAM3_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -113,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Stop the music on a channel"),
|
||||
_("Stop the music on the specified channel"),
|
||||
_("Stop the music of channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -125,7 +119,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Pause the music of a channel"),
|
||||
_("Pause the music on the specified channel."),
|
||||
_("Pause the music of channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -134,10 +128,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
|
||||
extension
|
||||
.AddAction("RePlayMusicCanal",
|
||||
_("Resume playing a music on a channel"),
|
||||
_("Resume playing a music on a channel that was paused."),
|
||||
_("Resume the music of channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Play the music of a channel"),
|
||||
_("Play the music of the channel."),
|
||||
_("Play the music of channel _PARAM1_"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -148,83 +142,69 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
.AddAction("ModVolumeSoundCanal",
|
||||
_("Volume of the sound on a channel"),
|
||||
_("This action modifies the volume of the sound on the "
|
||||
"specified channel."),
|
||||
"specified channel. The volume is between 0 and 100."),
|
||||
_("the volume of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/sonVolume24.png",
|
||||
"res/actions/sonVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume (0-100)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("ModVolumeMusicCanal",
|
||||
_("Volume of the music on a channel"),
|
||||
_("This action modifies the volume of the music on the "
|
||||
"specified channel."),
|
||||
"specified channel. The volume is between 0 and 100."),
|
||||
_("the volume of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/musicVolume24.png",
|
||||
"res/actions/musicVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume (0-100)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("ModGlobalVolume",
|
||||
_("Game global volume"),
|
||||
_("This action modifies the global volume of the game."),
|
||||
_("This action modifies the global volume of the game. The "
|
||||
"volume is between 0 and 100."),
|
||||
_("the global sound level"),
|
||||
"",
|
||||
_("Audio"),
|
||||
"res/actions/volume24.png",
|
||||
"res/actions/volume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume (0-100)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddAction("ModPitchSoundChannel",
|
||||
_("Pitch of the sound of a channel"),
|
||||
_("This action modifies the pitch (speed) of the sound on a "
|
||||
"channel."),
|
||||
"channel.\n1 is the default pitch."),
|
||||
_("the pitch of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Pitch (1 by default)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("ModPitchMusicChannel",
|
||||
_("Pitch of the music on a channel"),
|
||||
_("This action modifies the pitch of the music on the "
|
||||
"specified channel."),
|
||||
"specified channel. 1 is the default pitch"),
|
||||
_("the pitch of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Pitch (1 by default)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -233,15 +213,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("This action modifies the playing offset of the sound on a "
|
||||
"channel"),
|
||||
_("the playing offset of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Position (in seconds)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -250,15 +227,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("This action modifies the playing offset of the music on "
|
||||
"the specified channel"),
|
||||
_("the playing offset of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Position (in seconds)")))
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -266,7 +240,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Play a sound"),
|
||||
_("Play a sound."),
|
||||
_("Play the sound _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
|
||||
"",
|
||||
_("Audio"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -286,7 +260,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Play a music file"),
|
||||
_("Play a music file."),
|
||||
_("Play the music _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
|
||||
"",
|
||||
_("Audio"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -301,105 +275,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
.SetDefaultValue("1")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddAction("PreloadMusic",
|
||||
_("Preload a music file"),
|
||||
_("Preload a music file in memory."),
|
||||
_("Preload the music file _PARAM1_"),
|
||||
_("Loading"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("musicfile", _("Audio file (or audio resource name)"))
|
||||
.MarkAsComplex();
|
||||
|
||||
extension
|
||||
.AddAction("PreloadSound",
|
||||
_("Preload a sound file"),
|
||||
_("Preload a sound file in memory."),
|
||||
_("Preload the sound file _PARAM1_"),
|
||||
_("Loading"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("soundfile", _("Sound file (or sound resource name)"))
|
||||
.MarkAsComplex();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"UnloadMusic",
|
||||
_("Unload a music file"),
|
||||
_("Unload a music file from memory. "
|
||||
"Unloading a music file will cause any music playing it to stop."),
|
||||
_("Unload the music file _PARAM1_"),
|
||||
_("Loading"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("musicfile", _("Audio file (or audio resource name)"))
|
||||
.MarkAsComplex();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"UnloadSound",
|
||||
_("Unload a sound file"),
|
||||
_("Unload a sound file from memory. "
|
||||
"Unloading a sound file will cause any sounds playing it to stop."),
|
||||
_("Unload the sound file _PARAM1_"),
|
||||
_("Loading"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("soundfile", _("Sound file (or sound resource name)"))
|
||||
.MarkAsComplex();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"UnloadAllAudio",
|
||||
_("Unload all audio"),
|
||||
_("Unload all the audio in memory. "
|
||||
"This will cause every sound and music of the game to stop."),
|
||||
_("Unload all audio files"),
|
||||
_("Loading"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsComplex();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeSoundVolume",
|
||||
_("Fade the volume of a sound played on a channel."),
|
||||
_("Fade the volume of a sound played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the sound on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Sounds on channels"),
|
||||
"res/actions/son24.png",
|
||||
"res/actions/son.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
extension
|
||||
.AddAction(
|
||||
"FadeMusicVolume",
|
||||
_("Fade the volume of a music played on a channel."),
|
||||
_("Fade the volume of a music played on a channel to the specified volume within the specified duration."),
|
||||
_("Fade the music on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
|
||||
_("Music on channels"),
|
||||
"res/actions/music24.png",
|
||||
"res/actions/music.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.AddParameter("expression", _("Final volume (0-100)"))
|
||||
.AddParameter("expression", _("Fading time in seconds"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("MusicPlaying",
|
||||
_("A music file is being played"),
|
||||
_("Test if the music on a channel is being played"),
|
||||
_("Music on channel _PARAM1_ is being played"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicplaying24.png",
|
||||
"res/conditions/musicplaying.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -411,7 +292,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("A music file is paused"),
|
||||
_("Test if the music on the specified channel is paused."),
|
||||
_("Music on channel _PARAM1_ is paused"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicpaused24.png",
|
||||
"res/conditions/musicpaused.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -423,7 +304,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("A music file is stopped"),
|
||||
_("Test if the music on the specified channel is stopped."),
|
||||
_("Music on channel _PARAM1_ is stopped"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicstopped24.png",
|
||||
"res/conditions/musicstopped.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -435,7 +316,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("A sound is being played"),
|
||||
_("Test if the sound on a channel is being played."),
|
||||
_("Sound on channel _PARAM1_ is being played"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonplaying24.png",
|
||||
"res/conditions/sonplaying.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -447,7 +328,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("A sound is paused"),
|
||||
_("Test if the sound on the specified channel is paused."),
|
||||
_("Sound on channel _PARAM1_ is paused"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonpaused24.png",
|
||||
"res/conditions/sonpaused.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -459,7 +340,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("A sound is stopped"),
|
||||
_("Test if the sound on the specified channel is stopped."),
|
||||
_("Sound on channel _PARAM1_ is stopped"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonstopped24.png",
|
||||
"res/conditions/sonstopped.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -470,17 +351,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
.AddCondition(
|
||||
"SoundCanalVolume",
|
||||
_("Volume of the sound on a channel"),
|
||||
_("Test the volume of the sound on the specified channel."),
|
||||
_("Test the volume of the sound on the specified channel. The volume "
|
||||
"is between 0 and 100."),
|
||||
_("the volume of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonVolume24.png",
|
||||
"res/conditions/sonVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume to compare to (0-100)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -490,15 +369,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Test the volume of the music on a specified channel. The volume "
|
||||
"is between 0 and 100."),
|
||||
_("the volume of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicVolume24.png",
|
||||
"res/conditions/musicVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume to compare to (0-100)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -507,14 +383,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Global volume"),
|
||||
_("Test the global sound level. The volume is between 0 and 100."),
|
||||
_("the global game volume"),
|
||||
"",
|
||||
_("Audio"),
|
||||
"res/conditions/volume24.png",
|
||||
"res/conditions/volume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Volume to compare to (0-100)")));
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
@@ -523,32 +396,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Test the pitch of the sound on the specified channel. 1 is the "
|
||||
"default pitch."),
|
||||
_("the pitch of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonVolume24.png",
|
||||
"res/conditions/sonVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Pitch to compare to (1 by default)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"MusicChannelPitch",
|
||||
_("Pitch of the music on a channel"),
|
||||
_("Test the pitch (speed) of the music on a specified channel."),
|
||||
_("Test the pitch (speed) of the music on a specified channel. 1 is "
|
||||
"the default pitch."),
|
||||
_("the pitch of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicVolume24.png",
|
||||
"res/conditions/musicVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Pitch to compare to (1 by default)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -557,15 +425,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Playing offset of the sound on a channel"),
|
||||
_("Test the playing offset of the sound on the specified channel."),
|
||||
_("the playing offset of the sound on channel _PARAM1_"),
|
||||
_("Sounds on channels"),
|
||||
_("Audio/Sounds on channels"),
|
||||
"res/conditions/sonVolume24.png",
|
||||
"res/conditions/sonVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Position to compare to (in seconds)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -574,15 +439,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Playing offset of the music on a channel"),
|
||||
_("Test the playing offset of the music on the specified channel."),
|
||||
_("the playing offset of the music on channel _PARAM1_"),
|
||||
_("Music on channels"),
|
||||
_("Audio/Music on channels"),
|
||||
"res/conditions/musicVolume24.png",
|
||||
"res/conditions/musicVolume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Channel identifier"))
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Position to compare to (in seconds)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -646,6 +508,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
_("Sound level"),
|
||||
"res/conditions/volume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -13,218 +12,152 @@ namespace gd {
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinCamera",
|
||||
_("Layers and cameras"),
|
||||
"Each scene can be composed of multiple layers. These conditions "
|
||||
"and actions allow to manipulate them during the game. In "
|
||||
"particular, you can move the camera of a layer to center it on an "
|
||||
"object or a position.",
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetCategory("Camera")
|
||||
.SetExtensionInformation("BuiltinCamera",
|
||||
_("Cameras and layers features"),
|
||||
_("Built-in camera extension"),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
|
||||
.SetIcon("res/conditions/camera24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("CameraX",
|
||||
_("Camera center X position"),
|
||||
_("Compare the X position of the center of a camera."),
|
||||
_("the x position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"CameraCenterX",
|
||||
.AddCondition("CameraY",
|
||||
_("Camera center Y position"),
|
||||
_("Compare the Y position of the center of a camera."),
|
||||
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"))
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"CameraX",
|
||||
_("Camera center X position"),
|
||||
_("the X position of the center of a camera"),
|
||||
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
_("Change the X position of the center of the specified camera."),
|
||||
_("the x position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.UseStandardOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Compatibility with GD <= 5.0.135
|
||||
extension.AddDuplicatedCondition("CameraX", "CameraCenterX")
|
||||
.SetHidden(); // Deprecated
|
||||
extension.AddDuplicatedExpression("CameraX", "CameraCenterX")
|
||||
.SetHidden(); // Deprecated
|
||||
extension.AddDuplicatedAction("SetCameraX", "SetCameraCenterX")
|
||||
.SetHidden(); // Deprecated
|
||||
|
||||
extension.AddDuplicatedAction("CameraX", "SetCameraX")
|
||||
.SetHidden(); // Deprecated
|
||||
|
||||
extension.AddDuplicatedExpression("VueX", "CameraX")
|
||||
.SetHidden(); // Deprecated
|
||||
// end of compatibility code
|
||||
|
||||
extension
|
||||
.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"CameraCenterY",
|
||||
.AddAction(
|
||||
"CameraY",
|
||||
_("Camera center Y position"),
|
||||
_("the Y position of the center of a camera"),
|
||||
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
_("Change the Y position of the center of the specified camera."),
|
||||
_("the y position of camera _PARAM4_ (layer: _PARAM3_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.UseStandardOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Compatibility with GD <= 5.0.135
|
||||
extension.AddDuplicatedCondition("CameraY", "CameraCenterY")
|
||||
.SetHidden(); // Deprecated
|
||||
extension.AddDuplicatedExpression("CameraY", "CameraCenterY")
|
||||
.SetHidden(); // Deprecated
|
||||
extension.AddDuplicatedAction("SetCameraY", "SetCameraCenterY")
|
||||
.SetHidden(); // Deprecated
|
||||
|
||||
extension.AddDuplicatedAction("CameraY", "SetCameraY")
|
||||
.SetHidden(); // Deprecated
|
||||
|
||||
extension.AddDuplicatedExpression("VueY", "CameraY")
|
||||
.SetHidden(); // Deprecated
|
||||
// end of compatibility code
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraWidth",
|
||||
_("Width of a camera"),
|
||||
_("the width of a camera of a layer"),
|
||||
_("the width of camera _PARAM2_ of layer _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCondition("CameraWidth",
|
||||
_("Width of a camera"),
|
||||
_("Test the width of a camera of a layer"),
|
||||
_("the width of camera _PARAM2_ of layer _PARAM1_"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraHeight",
|
||||
_("Height of a camera"),
|
||||
_("the height of a camera of a layer"),
|
||||
_("the height of camera _PARAM2_ of layer _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCondition("CameraHeight",
|
||||
_("Height of a camera"),
|
||||
_("Test the height of a camera of a layer"),
|
||||
_("the height of camera _PARAM2_ of layer _PARAM1_"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraBorderLeft",
|
||||
_("Camera left border position"),
|
||||
_("the position of the left border of a camera"),
|
||||
_("the position of the left border of camera _PARAM2_ of layer "
|
||||
"_PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCondition("CameraAngle",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Test a camera angle."),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraBorderRight",
|
||||
_("Camera right border position"),
|
||||
_("the position of the right border of a camera"),
|
||||
_("the position of the right border of camera _PARAM2_ of layer "
|
||||
"_PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraBorderTop",
|
||||
_("Camera top border position"),
|
||||
_("the position of the top border of a camera"),
|
||||
_("the position of the top border of camera _PARAM2_ of layer "
|
||||
"_PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition(
|
||||
"number",
|
||||
"CameraBorderBottom",
|
||||
_("Camera bottom border position"),
|
||||
_("the position of the bottom border of a camera"),
|
||||
_("the position of the bottom border of camera _PARAM2_ of layer "
|
||||
"_PARAM1_"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"CameraAngle",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("the angle of rotation of a camera (in degrees)"),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension.AddDuplicatedAction("RotateCamera", "SetCameraAngle").SetHidden();
|
||||
extension.AddDuplicatedExpression("CameraRotation", "CameraAngle")
|
||||
.SetHidden();
|
||||
extension.AddDuplicatedExpression("VueRotation", "CameraAngle").SetHidden();
|
||||
extension
|
||||
.AddAction("RotateCamera",
|
||||
_("Change camera angle"),
|
||||
_("This action modifies the angle of a camera in the "
|
||||
"specified layer."),
|
||||
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardOperatorParameters("number")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddAction("AddCamera",
|
||||
_("Add a camera to a layer"),
|
||||
_("This action adds a camera to a layer"),
|
||||
_("Add a camera to layer _PARAM1_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Width"), "", true)
|
||||
.AddParameter("expression", _("Height"), "", true)
|
||||
@@ -255,11 +188,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Delete a camera of a layer"),
|
||||
_("Remove the specified camera from a layer"),
|
||||
_("Delete camera _PARAM2_ from layer _PARAM1_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.MarkAsComplex();
|
||||
@@ -271,11 +204,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"layer. The zoom will be reset."),
|
||||
_("Change the size of camera _PARAM2_ of _PARAM1_ to "
|
||||
"_PARAM3_*_PARAM4_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.AddParameter("expression", _("Width"))
|
||||
@@ -289,11 +222,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"specified layer."),
|
||||
_("Set the render zone of camera _PARAM2_ from layer _PARAM1_ "
|
||||
"to _PARAM3_;_PARAM4_ _PARAM5_;_PARAM6_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"))
|
||||
.AddParameter(
|
||||
@@ -312,22 +245,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
|
||||
extension
|
||||
.AddAction("ZoomCamera",
|
||||
_("Camera zoom"),
|
||||
_("Change camera zoom."),
|
||||
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
|
||||
_("Change camera zoom."),
|
||||
_("Change camera zoom to _PARAM1_ (layer : _PARAM2_, camera : "
|
||||
"_PARAM3_)"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression",
|
||||
_("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)"))
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
// TODO Deprecated: hide this action in a future release.
|
||||
extension
|
||||
.AddAction(
|
||||
"FixCamera",
|
||||
@@ -336,7 +268,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"specified limits."),
|
||||
_("Center the camera on _PARAM1_ (limit : from _PARAM2_;_PARAM3_ to "
|
||||
"_PARAM4_;_PARAM5_) (layer: _PARAM7_, camera: _PARAM8_)"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -354,41 +286,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("ClampCamera",
|
||||
_("Enforce camera boundaries"),
|
||||
_("Enforce camera boundaries by moving the camera back inside "
|
||||
"specified boundaries."),
|
||||
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
|
||||
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Left bound X Position"))
|
||||
.AddParameter("expression", _("Top bound Y Position"))
|
||||
.AddParameter("expression", _("Right bound X Position"))
|
||||
.AddParameter("expression", _("Bottom bound Y Position"))
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddAction(
|
||||
"CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_, camera: _PARAM4_)"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("yesorno",
|
||||
@@ -396,7 +308,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -407,11 +319,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Show a layer"),
|
||||
_("Show a layer."),
|
||||
_("Show layer _PARAM1_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -420,11 +332,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Hide a layer"),
|
||||
_("Hide a layer."),
|
||||
_("Hide layer _PARAM1_"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -433,69 +345,69 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Visibility of a layer"),
|
||||
_("Test if a layer is set as visible."),
|
||||
_("Layer _PARAM1_ is visible"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"))
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectParameter",
|
||||
_("Effect property (number)"),
|
||||
_("Change the value of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
_("Effect parameter (number)"),
|
||||
_("Change the value of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
_("Layers and cameras/Effects"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectStringParameter",
|
||||
_("Effect property (string)"),
|
||||
_("Change the value (string) of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
_("Effect parameter (string)"),
|
||||
_("Change the value (string) of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
_("Layers and cameras/Effects"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerEffectBooleanParameter",
|
||||
_("Effect property (enable or disable)"),
|
||||
_("Enable or disable a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
_("Effect parameter (enable or disable)"),
|
||||
_("Enable or disable a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
_("Layers and cameras/Effects"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Property name"))
|
||||
.AddParameter("yesorno", _("Enable this property"))
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable this parameter"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -503,13 +415,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Layer effect is enabled"),
|
||||
_("The effect on a layer is enabled"),
|
||||
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
|
||||
_(""),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
_("Layers and cameras/Effects"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("string", _("Effect"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -517,13 +429,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Enable layer effect"),
|
||||
_("Enable an effect on a layer"),
|
||||
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
_("Layers and cameras/Effects"),
|
||||
"res/conditions/camera24.png",
|
||||
"res/conditions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("yesorno", _("Enable"), "", true)
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -533,16 +445,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Layer time scale"),
|
||||
_("Compare the time scale applied to the objects of the layer."),
|
||||
_("the time scale of layer _PARAM1_"),
|
||||
"",
|
||||
_("Layers and cameras/Time"),
|
||||
"res/conditions/time24.png",
|
||||
"res/conditions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Time scale (1 by default)")))
|
||||
.UseStandardRelationalOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -550,69 +459,44 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"ChangeLayerTimeScale",
|
||||
_("Change layer time scale"),
|
||||
_("Change the time scale applied to the objects of the layer."),
|
||||
_("Set the time scale of layer _PARAM1_ to _PARAM2_"),
|
||||
"",
|
||||
_("Set time scale of layer _PARAM1_ to _PARAM2_"),
|
||||
_("Layers and cameras/Time"),
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
|
||||
extension
|
||||
.AddCondition("LayerDefaultZOrder",
|
||||
_("Layer default Z order"),
|
||||
_("Compare the default Z order set to objects when they "
|
||||
"are created on a layer."),
|
||||
_("the default Z order of objects created on _PARAM1_"),
|
||||
"",
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddExpression("CameraWidth",
|
||||
_("Width of a camera of a layer"),
|
||||
_("Width of a camera of a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("expression", _("Camera number (default : 0)"))
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddAction("SetLayerDefaultZOrder",
|
||||
_("Layer default Z order"),
|
||||
_("Change the default Z order set to objects when they are "
|
||||
"created on a layer."),
|
||||
_("Set the default Z order of objects created on _PARAM1_ to "
|
||||
"_PARAM2_"),
|
||||
"",
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddExpression("CameraHeight",
|
||||
_("Height of a camera of a layer"),
|
||||
_("Height of a camera of a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("New default Z order"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"SetLayerAmbientLightColor",
|
||||
_("Set the ambient light color"),
|
||||
_("Set the ambient light color of the lighting layer in format "
|
||||
"\"R;G;B\" string."),
|
||||
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
|
||||
_(""),
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"Lighting\"")
|
||||
.AddParameter("color", _("Color"))
|
||||
.MarkAsAdvanced();
|
||||
.AddParameter("layer", _("Layer"))
|
||||
.AddParameter("expression", _("Camera number (default : 0)"))
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression(
|
||||
"CameraViewportLeft",
|
||||
_("X position of the top left side point of a render zone"),
|
||||
_("X position of the top left side point of a render zone"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
@@ -624,7 +508,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"CameraViewportTop",
|
||||
_("Y position of the top left side point of a render zone"),
|
||||
_("Y position of the top left side point of a render zone"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
@@ -636,7 +520,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"CameraViewportRight",
|
||||
_("X position of the bottom right side point of a render zone"),
|
||||
_("X position of the bottom right side point of a render zone"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
@@ -648,7 +532,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"CameraViewportBottom",
|
||||
_("Y position of the bottom right side point of a render zone"),
|
||||
_("Y position of the bottom right side point of a render zone"),
|
||||
"",
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"))
|
||||
@@ -656,10 +540,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("CameraZoom",
|
||||
_("Zoom of a camera of a layer"),
|
||||
_("Zoom of a camera of a layer"),
|
||||
"",
|
||||
.AddExpression("CameraX",
|
||||
_("Camera X position"),
|
||||
_("Camera X position"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
@@ -667,23 +551,78 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("VueX",
|
||||
_("Camera X position"),
|
||||
_("Camera X position"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("CameraY",
|
||||
_("Camera Y position"),
|
||||
_("Camera Y position"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("VueY",
|
||||
_("Camera Y position"),
|
||||
_("Camera Y position"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("CameraRotation",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("VueRotation",
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Angle of a camera of a layer"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/camera.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
||||
extension
|
||||
.AddExpression("LayerTimeScale",
|
||||
_("Layer time scale"),
|
||||
_("Returns the time scale of the specified layer."),
|
||||
"",
|
||||
_("Time scale"),
|
||||
_("Time scale"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
|
||||
extension
|
||||
.AddExpression("LayerDefaultZOrder",
|
||||
_("Default Z Order for a layer"),
|
||||
_("Default Z Order for a layer"),
|
||||
"",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("AnimatableCapability",
|
||||
_("Animatable capability"),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"AnimatableBehavior",
|
||||
_("Animatable capability"),
|
||||
"Animation",
|
||||
_("Animate objects."),
|
||||
"",
|
||||
"res/actions/animation24.png",
|
||||
"AnimatableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Index",
|
||||
_("Animation (by number)"),
|
||||
_("the number of the animation played by the object (the number from "
|
||||
"the animations list)"),
|
||||
_("the number of the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation index")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"string",
|
||||
"Name",
|
||||
_("Animation (by name)"),
|
||||
_("the animation played by the object using the name of the "
|
||||
"animation"),
|
||||
_("the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation name")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("PauseAnimation",
|
||||
_("Pause the animation"),
|
||||
_("Pause the animation of the object."),
|
||||
_("Pause the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("PlayAnimation",
|
||||
_("Resume the animation"),
|
||||
_("Resume the animation of the object."),
|
||||
_("Resume the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"SpeedScale",
|
||||
_("Animation speed scale"),
|
||||
_("the animation speed scale (1 = the default speed, >1 = faster and "
|
||||
"<1 = slower)"),
|
||||
_("the animation speed scale"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Speed scale")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("IsAnimationPaused",
|
||||
_("Animation paused"),
|
||||
_("Check if the animation of an object is paused."),
|
||||
_("The animation of _PARAM0_ is paused"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("HasAnimationEnded",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
"is finished."),
|
||||
_("The animation of _PARAM0_ is finished"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("EffectCapability",
|
||||
_("Effect capability"),
|
||||
_("Apply visual effects to objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Effect capability"),
|
||||
"Effect",
|
||||
_("Apply visual effects to objects."),
|
||||
"",
|
||||
"res/actions/effect24.png",
|
||||
"EffectBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("EnableEffect",
|
||||
_("Enable an object effect"),
|
||||
_("Enable an effect on the object"),
|
||||
_("Enable effect _PARAM2_ on _PARAM0_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectDoubleParameter",
|
||||
_("Effect property (number)"),
|
||||
_("Change the value of a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectStringParameter",
|
||||
_("Effect property (string)"),
|
||||
_("Change the value (string) of a property of an effect.") +
|
||||
"\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectBooleanParameter",
|
||||
_("Effect property (enable or disable)"),
|
||||
_("Enable or disable a property of an effect.") + "\n" +
|
||||
_("You can find the property names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM3_ for effect _PARAM2_ of _PARAM0_: _PARAM4_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Property name"))
|
||||
.AddParameter("yesorno", _("Enable this property"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("IsEffectEnabled",
|
||||
_("Effect is enabled"),
|
||||
_("Check if the effect on an object is enabled."),
|
||||
_("Effect _PARAM2_ of _PARAM0_ is enabled"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("FlippableCapability",
|
||||
_("Flippable capability"),
|
||||
_("Flip objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"FlippableBehavior",
|
||||
_("Flippable capability"),
|
||||
"Flippable",
|
||||
_("Flip objects."),
|
||||
"",
|
||||
"res/actions/flipX24.png",
|
||||
"FlippableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("FlipX",
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip horizontally _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("FlipY",
|
||||
_("Flip the object vertically"),
|
||||
_("Flip the object vertically"),
|
||||
_("Flip vertically _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("FlippedX",
|
||||
_("Horizontally flipped"),
|
||||
_("Check if the object is horizontally flipped"),
|
||||
_("_PARAM0_ is horizontally flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
|
||||
aut.AddScopedCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
_("Check if the object is vertically flipped"),
|
||||
_("_PARAM0_ is vertically flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("OpacityCapability",
|
||||
_("Opacity capability"),
|
||||
_("Change the object opacity."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"OpacityBehavior",
|
||||
_("Opacity capability"),
|
||||
"Opacity",
|
||||
_("Change the object opacity."),
|
||||
"",
|
||||
"res/actions/opacity24.png",
|
||||
"OpacityBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Opacity"),
|
||||
_("the opacity of an object, between 0 (fully transparent) to 255 "
|
||||
"(opaque)"),
|
||||
_("the opacity"),
|
||||
_("Visibility"),
|
||||
"res/actions/opacity24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "OpacityBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0-255)")))
|
||||
.SetFunctionName("setOpacity")
|
||||
.SetGetter("getOpacity");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
|
||||
gd::PlatformExtension &extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ResizableCapability",
|
||||
_("Resizable capability"),
|
||||
_("Change the object dimensions."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
|
||||
"res/actions/scale24_black.png");
|
||||
|
||||
gd::BehaviorMetadata &aut =
|
||||
extension
|
||||
.AddBehavior("ResizableBehavior",
|
||||
_("Resizable capability"),
|
||||
"Resizable",
|
||||
_("Change the object dimensions."),
|
||||
"",
|
||||
"res/actions/scale24_black.png",
|
||||
"ResizableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("SetWidth",
|
||||
_("Width"),
|
||||
_("Change the width of the object."),
|
||||
_("the width"),
|
||||
_("Size"),
|
||||
"res/actions/scaleWidth24_black.png",
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedCondition("Width",
|
||||
_("Width"),
|
||||
_("Compare the width of the object."),
|
||||
_("the width"),
|
||||
_("Size"),
|
||||
"res/conditions/scaleWidth24_black.png",
|
||||
"res/conditions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedAction("SetHeight",
|
||||
_("Height"),
|
||||
_("Change the height of the object."),
|
||||
_("the height"),
|
||||
_("Size"),
|
||||
"res/actions/scaleHeight24_black.png",
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedCondition("Height",
|
||||
_("Height"),
|
||||
_("Compare the height of the object."),
|
||||
_("the height"),
|
||||
_("Size"),
|
||||
"res/conditions/scaleHeight24_black.png",
|
||||
"res/conditions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddScopedAction(
|
||||
"SetSize",
|
||||
_("Size"),
|
||||
_("Change the size of an object."),
|
||||
_("Change the size of _PARAM0_: set to _PARAM2_ x _PARAM3_"),
|
||||
_("Size"),
|
||||
"res/actions/scale24_black.png",
|
||||
"res/actions/scale_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
|
||||
.AddParameter("expression", _("Width"))
|
||||
.AddParameter("expression", _("Height"))
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ScalableCapability",
|
||||
_("Scalable capability"),
|
||||
_("Change the object scale."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"ScalableBehavior",
|
||||
_("Scalable capability"),
|
||||
"Scale",
|
||||
_("Change the object scale."),
|
||||
"",
|
||||
"res/actions/scale24_black.png",
|
||||
"ResizableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Scale"),
|
||||
_("the scale of the object (default scale is 1)"),
|
||||
_("the scale"),
|
||||
_("Scale"),
|
||||
"res/actions/scale24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"X",
|
||||
_("Scale on X axis"),
|
||||
_("the scale on X axis of the object (default scale is 1)"),
|
||||
_("the scale on X axis"),
|
||||
_("Scale"),
|
||||
"res/actions/scaleWidth24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Y",
|
||||
_("Scale on Y axis"),
|
||||
_("the scale on Y axis of the object (default scale is 1)"),
|
||||
_("the scale on Y axis"),
|
||||
_("Scale"),
|
||||
"res/actions/scaleHeight24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -15,28 +15,28 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinCommonConversions",
|
||||
_("Conversion"),
|
||||
"Expressions to convert number, texts and quantities.",
|
||||
_("Standard Conversions"),
|
||||
_("Built-in extension providing standard conversions expressions."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/common-conversions");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Conversion"))
|
||||
.SetIcon("res/conditions/toujours24_black.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
extension
|
||||
.AddExpression("ToNumber",
|
||||
_("Text > Number"),
|
||||
_("Convert the text to a number"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("string", _("Text to convert to a number"));
|
||||
|
||||
extension
|
||||
.AddStrExpression("ToString",
|
||||
_("Number > Text"),
|
||||
_("Convert the result of the expression to text"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("expression", _("Expression to be converted to text"));
|
||||
|
||||
extension
|
||||
@@ -44,8 +44,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
_("Number > Text ( without scientific notation )"),
|
||||
_("Convert the result of the expression to text, "
|
||||
"without using the scientific notation"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("expression", _("Expression to be converted to text"));
|
||||
|
||||
extension
|
||||
@@ -53,8 +53,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
"ToRad",
|
||||
_("Degrees > Radians"),
|
||||
_("Converts the angle, expressed in degrees, into radians"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("expression", _("Angle, in degrees"));
|
||||
|
||||
extension
|
||||
@@ -62,76 +62,10 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
"ToDeg",
|
||||
_("Radians > Degrees"),
|
||||
_("Converts the angle, expressed in radians, into degrees"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("expression", _("Angle, in radians"));
|
||||
|
||||
extension
|
||||
.AddStrExpression("ToJSON",
|
||||
_("Convert scene variable to JSON"),
|
||||
_("Convert a scene variable to JSON"),
|
||||
_("JSON"),
|
||||
"res/conditions/toujours24_black.png")
|
||||
.AddParameter("scenevar", _("Scene variable to be stringified"));
|
||||
|
||||
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"));
|
||||
|
||||
extension
|
||||
.AddStrExpression("ObjectVarToJSON",
|
||||
_("Convert object variable to JSON"),
|
||||
_("Convert an object variable to JSON"),
|
||||
_("JSON"),
|
||||
"res/conditions/toujours24_black.png")
|
||||
.AddParameter("objectPtr", _("The object with the variable"))
|
||||
.AddParameter("objectvar", _("The object variable to be stringified"));
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"JSONToVariableStructure",
|
||||
_("Convert JSON to a scene variable"),
|
||||
_("Parse a JSON object and store it into a scene variable"),
|
||||
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"),
|
||||
"",
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("scenevar", _("Variable where store the JSON object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("JSONToGlobalVariableStructure",
|
||||
_("Convert JSON to global variable"),
|
||||
_("Parse a JSON object and store it into a global variable"),
|
||||
_("Convert JSON string _PARAM0_ and store it into global "
|
||||
"variable _PARAM1_"),
|
||||
"",
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("globalvar",
|
||||
_("Global variable where store the JSON object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction("JSONToObjectVariableStructure",
|
||||
_("Convert JSON to object variable"),
|
||||
_("Parse a JSON object and store it into an object variable"),
|
||||
_("Parse JSON string _PARAM0_ and store it into variable "
|
||||
"_PARAM2_ of _PARAM1_"),
|
||||
"",
|
||||
"res/actions/net24.png",
|
||||
"res/actions/net.png")
|
||||
.AddParameter("string", _("JSON string"))
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("objectvar",
|
||||
_("Object variable where store the JSON object"))
|
||||
.MarkAsAdvanced();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,8 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Events/Builtin/CommentEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachChildVariableEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachEvent.h"
|
||||
#include "GDCore/Events/Builtin/GroupEvent.h"
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
@@ -13,7 +14,7 @@
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Builtin/WhileEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
@@ -24,59 +25,32 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
extension
|
||||
.SetExtensionInformation(
|
||||
"BuiltinCommonInstructions",
|
||||
_("Events and control flow"),
|
||||
"GDevelop comes with a set of events and conditions that allow to "
|
||||
"express the game logic and rules.",
|
||||
_("Standard events"),
|
||||
_("Built-in extension providing standard events."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetCategory("Advanced")
|
||||
.SetExtensionHelpPath("/all-features/advanced-conditions");
|
||||
extension
|
||||
.AddInstructionOrExpressionGroupMetadata(_("Events and control flow"))
|
||||
.SetIcon("res/conditions/toujours24_black.png");
|
||||
|
||||
// This condition is deprecated as this does not bring anything new
|
||||
// and can be confusing or misleading for beginners.
|
||||
extension
|
||||
.AddCondition("Always",
|
||||
_("Always"),
|
||||
_("This condition always returns true (or always false, if "
|
||||
"the condition is inverted)."),
|
||||
_("Always"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png",
|
||||
"res/conditions/toujours_black.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
.AddDuplicatedCondition(
|
||||
"Toujours", "BuiltinCommonInstructions::Always", {.unscoped = true})
|
||||
.SetHidden();
|
||||
// end of compatibility code
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("Or",
|
||||
_("Or"),
|
||||
_("Check if one of the sub conditions is true"),
|
||||
_("Return true 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")
|
||||
_("Advanced"),
|
||||
"res/conditions/or24.png",
|
||||
"res/conditions/or.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("And",
|
||||
_("And"),
|
||||
_("Check if all sub conditions are true"),
|
||||
_("Return true if all sub conditions are true"),
|
||||
_("If all of these conditions are true:"),
|
||||
"",
|
||||
"res/conditions/and24_black.png",
|
||||
"res/conditions/and_black.png")
|
||||
_("Advanced"),
|
||||
"res/conditions/and24.png",
|
||||
"res/conditions/and.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -86,9 +60,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
_("Not"),
|
||||
_("Return the contrary of the result of the sub conditions"),
|
||||
_("Invert the logical result of these conditions:"),
|
||||
"",
|
||||
"res/conditions/not24_black.png",
|
||||
"res/conditions/not_black.png")
|
||||
_("Advanced"),
|
||||
"res/conditions/not24.png",
|
||||
"res/conditions/not.png")
|
||||
.SetCanHaveSubInstructions()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -97,54 +71,10 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
_("Trigger once while true"),
|
||||
_("Run actions only once, for each time the conditions have been met."),
|
||||
_("Trigger once"),
|
||||
"",
|
||||
_("Advanced"),
|
||||
"res/conditions/once24.png",
|
||||
"res/conditions/once.png");
|
||||
|
||||
extension
|
||||
.AddCondition("CompareNumbers",
|
||||
_("Compare two numbers"),
|
||||
_("Compare the two numbers."),
|
||||
_("_PARAM0_ _PARAM1_ _PARAM2_"),
|
||||
"",
|
||||
"res/conditions/egal24_black.png",
|
||||
"res/conditions/egal_black.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddParameter("expression", _("First expression"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.AddParameter("expression", _("Second expression"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
.AddDuplicatedCondition("Egal",
|
||||
"BuiltinCommonInstructions::CompareNumbers",
|
||||
{.unscoped = true})
|
||||
.SetHidden();
|
||||
// end of compatibility code
|
||||
|
||||
extension
|
||||
.AddCondition("CompareStrings",
|
||||
_("Compare two strings"),
|
||||
_("Compare the two strings."),
|
||||
_("_PARAM0_ _PARAM1_ _PARAM2_"),
|
||||
"",
|
||||
"res/conditions/egal24_black.png",
|
||||
"res/conditions/egal_black.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddParameter("string", _("First string expression"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "string")
|
||||
.AddParameter("string", _("Second string expression"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Compatibility with GD <= 5.0.127
|
||||
extension
|
||||
.AddDuplicatedCondition("StrEqual",
|
||||
"BuiltinCommonInstructions::CompareStrings",
|
||||
{.unscoped = true})
|
||||
.SetHidden();
|
||||
// end of compatibility code
|
||||
|
||||
extension.AddEvent(
|
||||
"Standard",
|
||||
_("Standard event"),
|
||||
@@ -154,29 +84,29 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
std::make_shared<gd::StandardEvent>());
|
||||
|
||||
extension.AddEvent("Link",
|
||||
_("Link external events"),
|
||||
_("Link to external events."),
|
||||
_("Link"),
|
||||
_("Link to some external events"),
|
||||
"",
|
||||
"res/lienaddicon.png",
|
||||
std::make_shared<gd::LinkEvent>());
|
||||
|
||||
extension.AddEvent("Comment",
|
||||
_("Comment"),
|
||||
_("Event displaying a text in the events editor."),
|
||||
_("Event displaying a text in the events editor"),
|
||||
"",
|
||||
"res/comment.png",
|
||||
std::make_shared<gd::CommentEvent>());
|
||||
|
||||
extension.AddEvent("While",
|
||||
_("While"),
|
||||
_("Repeat the event while the conditions are true."),
|
||||
_("The event is repeated while the conditions are true"),
|
||||
"",
|
||||
"res/while.png",
|
||||
std::make_shared<gd::WhileEvent>());
|
||||
|
||||
extension.AddEvent("Repeat",
|
||||
_("Repeat"),
|
||||
_("Repeat the event for a specified number of times."),
|
||||
_("Event repeated a number of times"),
|
||||
"",
|
||||
"res/repeat.png",
|
||||
std::make_shared<gd::RepeatEvent>());
|
||||
@@ -188,20 +118,13 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::ForEachEvent>());
|
||||
|
||||
extension.AddEvent(
|
||||
"ForEachChildVariable",
|
||||
_("For each child variable (of a structure or array)"),
|
||||
_("Repeat the event for each child variable of a structure or array."),
|
||||
"",
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::ForEachChildVariableEvent>());
|
||||
|
||||
extension.AddEvent("Group",
|
||||
_("Event group"),
|
||||
_("Group containing events."),
|
||||
_("Group"),
|
||||
_("Group containing events"),
|
||||
"",
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::GroupEvent>());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -13,34 +13,32 @@ void GD_CORE_API
|
||||
BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("BuiltinExternalLayouts",
|
||||
_("External layouts"),
|
||||
"Provides actions and conditions related to "
|
||||
"external layouts.",
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/interface/scene-editor/external-layouts")
|
||||
.SetCategory("Advanced");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("External layouts"))
|
||||
.SetIcon("res/ribbon_default/externallayout32.png");
|
||||
.SetExtensionInformation(
|
||||
"BuiltinExternalLayouts",
|
||||
_("External layouts"),
|
||||
_("Built-in extension providing actions and conditions related to "
|
||||
"external layouts"),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/interface/scene-editor/external-layouts");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction("CreateObjectsFromExternalLayout",
|
||||
_("Create objects from an external layout"),
|
||||
_("Create objects from an external layout."),
|
||||
_("Create objects from the external layout named _PARAM1_"),
|
||||
"",
|
||||
"res/ribbon_default/externallayout32.png",
|
||||
"res/ribbon_default/externallayout32.png")
|
||||
_("External layouts"),
|
||||
"res/conditions/fichier24.png",
|
||||
"res/conditions/fichier.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("externalLayoutName", _("Name of the external layout"))
|
||||
.AddParameter("string", _("Name of the external layout"))
|
||||
.AddParameter("expression", _("X position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Y position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.AddParameter("expression", _("Z position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user