Compare commits

..

9 Commits

Author SHA1 Message Date
Florian Rival
cba3a4e87a Add Video tutorials and hints about these tutorials in the editor 2020-07-21 00:24:23 +01:00
Florian Rival
15dc2fcdd0 Fix hot-reloading of Anchor behavior and BBText and Text objects width
Don't show in changelog
2020-07-20 22:34:38 +01:00
Florian Rival
b21fdc1ac2 Don't reload fonts already loaded during a hot-reload
Also only issue a single request when multiple audio resources are pointing to the same file.

Don't show in changelog
2020-07-19 23:23:17 +01:00
Florian Rival
ad4c53898a Ensure events generated code is stable across code generation.
This is done by given unique identifiers to "Trigger Once" conditions (stable given the same object in memory) and events list function names (stable given events with same content).

This avoids useless hot-reloading and re-triggering Trigger Once conditions after a hot-reloading.

Don't show in changelog
2020-07-19 23:23:16 +01:00
Florian Rival
7a0745a977 Update icons and fix stale icons in Debugger Toolbar when selecting game
Don't show in changelog
2020-07-19 23:13:05 +01:00
Florian Rival
69b3c23f1d Add support for "hot reloading" of previews (apply changes to preview without restarting) 2020-07-19 23:13:04 +01:00
Florian Rival
5f52b6d7e3 Refactor changes cancelling of GDevelop.js objects
* Use a typed hook (shorter and type-safe to use)
* Avoid the necessity of providing a function to create an object.
* Only unserialize back to the object if cancelling changes (instead of when applying).
2020-07-19 22:52:55 +01:00
Florian Rival
dfdbd5c5a0 Add hot reloader (electron app only) 2020-07-19 22:52:55 +01:00
Florian Rival
958f89fb49 Add persistentUuid to gd::InitialInstance 2020-07-19 22:52:53 +01:00
5999 changed files with 940832 additions and 395079 deletions

View File

@@ -1,113 +1,30 @@
# 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: 12.5.1
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).
- run:
name: Build GDevelop IDE
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf "newIDE/electron-app/dist/mac/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 ..
- 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
command: sudo apt install icnsutils && sudo apt install graphicsmagick && sudo apt install rsync
@@ -115,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 ..
@@ -138,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 AppImage zip deb --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
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:
@@ -160,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.*/

View File

@@ -13,5 +13,6 @@
-fPIC
-I./ExtLibs/SFML/include
-I./Core
-I./GDCpp/.
-I./GDJS/.
-F./ExtLibs/SFML/extlibs/libs-osx/Frameworks

View File

@@ -1,6 +0,0 @@
# This is the Dockerfile to create a "devcontainer".
# This is a way to quickly create a development environment,
# that can be used with GitHub workspaces.
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux/.devcontainer/base.Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/universal:1-focal

View File

@@ -1,16 +0,0 @@
# Devcontainer (development environment in the cloud) for GDevelop (beta)
A devcontainer is the configuration to run a cloud development environment, available remotely.
This is notably used to run a **[GitHub Codespace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces)**. The advantage is that you can quickly experiment and do changes without installing anything on your computer.
> ⚠️ This development environment is in beta, and not everything is supported. This is useful for playing a bit with GDevelop codebase or to make quick changes. **In particular, it's not possible to test your changes on GDJS** because only the web-app can be launched.
It's recommended that you follow the usual [README](../newIDE/README.md) to get started, with development tools installed on your computer.
## Start a GitHub workspace to work on GDevelop (beta)
- Subscribe to the [beta edition of GitHub workspace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces#joining-the-beta).
- In the repository GitHub page, click **Code** and then choose **Open with Codespaces**.
- Wait for the Codespace to load and Visual Studio Code to open.
- When it's ready, open a terminal in Visual Studio Code.
- Follow the usual [README in `newIDE`](../newIDE/README.md) to get started, like you would do on your own computer.

View File

@@ -1,51 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux
{
"name": "GitHub Codespaces for GDevelop",
"build": {
"dockerfile": "Dockerfile"
},
"settings": {
"terminal.integrated.shell.linux": "/bin/zsh",
"go.toolsManagement.checkForUpdates": "off",
"go.useLanguageServer": true,
"go.gopath": "/go",
"go.goroot": "/usr/local/go",
"python.pythonPath": "/opt/python/latest/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"lldb.executable": "/usr/bin/lldb",
"files.watcherExclude": {
"**/target/**": true
}
},
"remoteUser": "codespace",
"overrideCommand": false,
"workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached",
"workspaceFolder": "/home/codespace/workspace",
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--privileged", "--init" ],
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"GitHub.vscode-pull-request-github",
"esbenp.prettier-vscode",
"ms-vscode.cpptools",
"xaver.clang-format",
"flowtype.flow-for-vscode"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// "oryx build" will automatically install your dependencies and attempt to build your project
"postCreateCommand": "oryx build -p virtualenv_name=.venv || echo 'Could not auto-build. Skipping.'"
}

24
.eslintrc Normal file
View 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
View File

@@ -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
View File

@@ -1,2 +0,0 @@
* @4ian
Extensions/Firebase @arthuro555

View File

@@ -1,9 +1,6 @@
---
name: "\U0001F41BBug report"
about: Create a bug report about GDevelop or the game engine
title: ''
labels: ''
assignees: ''
---

View File

@@ -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.

View File

@@ -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
View File

@@ -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.

View File

@@ -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:
# 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:
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
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
- uses: actions/checkout@v2
with:
fetch-depth: 50
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
- 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 http://gdevelop-storybook.s3-website-us-east-1.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/latest/index.html"
echo "Find the Storybook for this commit on http://gdevelop-storybook.s3-website-us-east-1.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 }}

View File

@@ -1,47 +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:
# Allows to run this workflow manually from the Actions tab.
workflow_dispatch:
jobs:
extract-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('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
- 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 }}

View File

@@ -1,43 +0,0 @@
name: GDevelop Issues automatic workflow
on:
issues:
types: [opened]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Autoclose issues about adding a bug without changing the bug report template
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop.io/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/gdevelop5/start) to learn more about GDevelop. Thanks!"
- name: Autoclose known beta 105 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*_instance.getRawFloatProperty is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
- name: Autoclose known beta 114 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*getAssociatedSettings is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
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@v1
with:
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.
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,29 +0,0 @@
name: GDevelop Issues automatic workflow
on:
pull_request:
types: [opened]
jobs:
read-locales-metadata:
if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
runs-on: ubuntu-latest
steps:
- name: Read and format locales metadata
run: |
LANS=($(git diff HEAD^ HEAD --unified=5 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
touch sumup.txt
for index in ${!ADDS[@]}; do
echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
echo $DELTA % >> sumup.txt
done
- name: Store sumup in outputs
id: sumup
run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
- name: Autocomment pull request with sumup
uses: peter-evans/create-or-update-comment@v1
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.sumup.outputs.sumupFileContent}}
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,73 +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
# Allows to run this workflow manually from the Actions tab.
workflow_dispatch:
jobs:
update-translations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('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@v3.10.1
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.

43
.gitignore vendored
View File

@@ -1,5 +1,5 @@
/Core/GDCore/Tools/VersionPriv.h
/docs
/docs-wiki
/ExtLibs/SFML
/ExtLibs/*.7z
/scripts/logs/*.txt
@@ -8,17 +8,49 @@
/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
!/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 +60,3 @@
**/node_modules/
.idea
.vscode/ipch
/newIDE/app/src/UI/Theme/**/*ThemeVariables.*
.DS_Store
.Spotlight-V100
.Trashes
Thumbs.db

View File

@@ -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

View File

@@ -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 ../..

View File

@@ -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/embuild/GDevelop.js
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 1.39.6
- ./emsdk activate 1.39.6
- 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 ../..

View File

@@ -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')"
]
}
}

View File

@@ -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,

View File

@@ -1,8 +0,0 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"xaver.clang-format",
"ms-vscode.cpptools",
"flowtype.flow-for-vscode"
]
}

53
.vscode/launch.json vendored
View File

@@ -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}"
}
]
}

34
.vscode/settings.json vendored
View File

@@ -85,38 +85,18 @@
"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"
"__memory": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,
"Binaries/Output": true,
"GDJS/Runtime-dist": 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,

100
.vscode/tasks.json vendored
View File

@@ -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
View File

@@ -0,0 +1,6 @@
[Dolphin]
Timestamp=2015,4,21,21,49,19
Version=3
[Settings]
HiddenFilesShown=true

View File

@@ -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.

View File

@@ -14,10 +14,12 @@ macro(gd_set_option var default type docstring)
endif()
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
endmacro()
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.
@@ -47,11 +49,15 @@ IF(APPLE)
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()
#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.
@@ -71,13 +77,6 @@ endif()
# 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.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -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).
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
endif()
@@ -85,6 +84,7 @@ endif()
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})
#Add all the CMakeLists:
ADD_SUBDIRECTORY(Version)
ADD_SUBDIRECTORY(ExtLibs)
IF(BUILD_CORE)
ADD_SUBDIRECTORY(Core)
@@ -92,7 +92,10 @@ ENDIF()
IF(BUILD_GDJS)
ADD_SUBDIRECTORY(GDJS)
ENDIF()
IF(EMSCRIPTEN)
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)

View File

@@ -14,6 +14,7 @@ set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SY
#Dependencies on external libraries:
###
include_directories(${sfml_include_dir})
#Defines
###
@@ -56,6 +57,7 @@ IF(EMSCRIPTEN)
ELSE()
add_library(GDCore SHARED ${source_files})
ENDIF()
add_dependencies(GDCore GDVersion)
IF(EMSCRIPTEN)
set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
ELSEIF(WIN32)
@@ -67,6 +69,14 @@ set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMA
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})
#Linker files
###
IF(EMSCRIPTEN)
#Nothing.
ELSE()
target_link_libraries(GDCore ${sfml_LIBRARIES})
ENDIF()
#Tests
###
if(BUILD_TESTS)
@@ -79,5 +89,5 @@ if(BUILD_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.
target_link_libraries(GDCore_tests GDCore)
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
target_link_libraries(GDCore_tests ${sfml_LIBRARIES})
endif()

View File

@@ -13,6 +13,7 @@
#include <string>
#include <vector>
#include "Utf8/utf8.h"
#include <SFML/System/String.hpp>
#ifdef __GNUC__
#define GD_DEPRECATED __attribute__((deprecated))

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -21,13 +21,6 @@ vector<gd::String> CommentEvent::GetAllSearchableStrings() const {
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)

View File

@@ -47,8 +47,6 @@ class GD_CORE_API CommentEvent : public gd::BaseEvent {
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,

View File

@@ -1,79 +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;
}
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
element.AddChild("iterableVariableName").SetValue(iterableVariableName);
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName);
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName);
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

View File

@@ -1,110 +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"
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; };
/**
* \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; };
/**
* \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; };
/**
* \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 void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element);
private:
gd::String valueIteratorVariableName;
gd::String keyIteratorVariableName;
gd::String iterableVariableName;
gd::InstructionsList conditions;
gd::InstructionsList actions;
gd::EventsList events;
};
} // namespace gd
#endif // FOREACHEVENT_H

View File

@@ -74,10 +74,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 +86,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

View File

@@ -27,13 +27,6 @@ vector<gd::String> GroupEvent::GetAllSearchableStrings() const {
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 +69,5 @@ void GroupEvent::SetBackgroundColor(unsigned int colorR_,
colorB = colorB_;
}
} // namespace gd

View File

@@ -107,8 +107,6 @@ class GD_CORE_API GroupEvent : public gd::BaseEvent {
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,

View File

@@ -75,10 +75,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 +89,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

View File

@@ -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

View File

@@ -52,10 +52,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 +68,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

View File

@@ -3,17 +3,13 @@
* 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"
namespace gd {
@@ -30,30 +26,13 @@ void ExposeProjectEffects(
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);
auto& layer = layout.GetLayer(l);
for (std::size_t e = 0; e < layer.GetEffectsCount(); ++e) {
auto& effect = layer.GetEffect(e);
worker(effect);
}
}
for (std::size_t i = 0; i < layout.GetObjectsCount(); i++) {
auto& object = layout.GetObject(i);
auto& effects = object.GetEffects();
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
auto& effect = effects.GetEffect(e);
worker(effect);
}
}
}
// Add global object effects
for (std::size_t s = 0; s < project.GetObjectsCount(); s++) {
auto& effects = project.GetObject(s).GetEffects();
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
auto& effect = effects.GetEffect(e);
worker(effect);
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -261,11 +261,8 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
EventsCodeGenerationContext& context) {
gd::String conditionCode;
const gd::InstructionMetadata& instrInfos =
gd::InstructionMetadata instrInfos =
MetadataProvider::GetConditionMetadata(platform, condition.GetType());
if (MetadataProvider::IsBadInstructionMetadata(instrInfos)) {
return "/* Unknown instruction - skipped. */";
}
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
maxConditionsListsSize =
@@ -291,7 +288,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.SetParameters(parameters);
}
// Verify that there are no mismatchs between object type in parameters.
// Verify that there are not mismatch between object type in parameters
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter =
@@ -302,87 +299,22 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
condition.SetParameter(pNb, gd::Expression(""));
condition.SetType("");
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
condition.SetParameter(pNb, gd::Expression(""));
condition.SetType("");
}
}
}
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
if (!objectName.empty() && !instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
conditionCode +=
"/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
condition.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole condition code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateBehaviorCondition(
realObjects[i],
condition.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
} else {
// Generate static condition if available
if (MetadataProvider::HasCondition(platform, condition.GetType())) {
// Prepare arguments
std::vector<std::pair<gd::String, gd::String> >
supplementaryParametersTypes;
supplementaryParametersTypes.push_back(std::make_pair(
@@ -397,6 +329,78 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
arguments, instrInfos, returnBoolean, condition.IsInverted(), context);
}
// Generate object condition if available
gd::String objectName = condition.GetParameters().empty()
? ""
: condition.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!objectName.empty() &&
MetadataProvider::HasObjectCondition(
platform, objectType, condition.GetType()) &&
!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
// Generate behavior condition if available
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
condition.GetParameters().size() < 2
? ""
: condition.GetParameter(1).GetPlainString());
if (MetadataProvider::HasBehaviorCondition(
platform, behaviorType, condition.GetType()) &&
instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole condition code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode +=
GenerateBehaviorCondition(realObjects[i],
condition.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
return conditionCode;
}
@@ -413,6 +417,9 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
"condition" + gd::String::From(i) + "IsTrue", context);
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
gd::InstructionMetadata instrInfos = MetadataProvider::GetConditionMetadata(
platform, conditions[cId].GetType());
gd::String conditionCode =
GenerateConditionCode(conditions[cId],
"condition" + gd::String::From(cId) + "IsTrue",
@@ -433,11 +440,6 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
outputCode += "{\n";
outputCode += conditionCode;
outputCode += "}";
} else {
// Deprecated way to cancel code generation - but still honor it.
// Can be removed once condition is passed by const reference to
// GenerateConditionCode.
outputCode += "/* Skipped condition (empty type) */";
}
}
@@ -450,16 +452,11 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
* Generate code for an action.
*/
gd::String EventsCodeGenerator::GenerateActionCode(
gd::Instruction& action,
EventsCodeGenerationContext& context,
const gd::String& optionalAsyncCallbackName) {
gd::Instruction& action, EventsCodeGenerationContext& context) {
gd::String actionCode;
const gd::InstructionMetadata& instrInfos =
gd::InstructionMetadata instrInfos =
MetadataProvider::GetActionMetadata(platform, action.GetType());
if (MetadataProvider::IsBadInstructionMetadata(instrInfos)) {
return "/* Unknown instruction - skipped. */";
}
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
@@ -468,14 +465,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action, *this, context);
}
// Get the correct function name depending on whether it should be async or
// not.
const gd::String& functionCallName =
instrInfos.IsAsync() &&
(!instrInfos.IsOptionallyAsync() || action.IsAwaited())
? instrInfos.codeExtraInformation.asyncFunctionCallName
: instrInfos.codeExtraInformation.functionCallName;
// Be sure there is no lack of parameter.
while (action.GetParameters().size() < instrInfos.parameters.size()) {
vector<gd::Expression> parameters = action.GetParameters();
@@ -483,7 +472,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.SetParameters(parameters);
}
// Verify that there are no mismatchs between object type in parameters.
// Verify that there are not mismatch between object type in parameters
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
@@ -492,160 +481,94 @@ gd::String EventsCodeGenerator::GenerateActionCode(
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
action.SetParameter(pNb, gd::Expression(""));
action.SetType("");
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
action.SetParameter(pNb, gd::Expression(""));
action.SetType("");
}
}
}
// Call free function first if available
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
if (!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
actionCode += "/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(realObjects[i],
objInfo,
functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
context.SetNoCurrentObject();
}
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
action.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode +=
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
context.SetNoCurrentObject();
}
}
} else {
if (MetadataProvider::HasAction(platform, action.GetType())) {
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateFreeAction(functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
actionCode += GenerateFreeAction(arguments, instrInfos, context);
}
// Call object function if available
gd::String objectName = action.GetParameters().empty()
? ""
: action.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (MetadataProvider::HasObjectAction(
platform, objectType, action.GetType()) &&
!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(
realObjects[i], objInfo, arguments, instrInfos, context);
context.SetNoCurrentObject();
}
}
// Assign to a behavior member function if found
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
action.GetParameters().size() < 2
? ""
: action.GetParameter(1).GetPlainString());
if (MetadataProvider::HasBehaviorAction(
platform, behaviorType, action.GetType()) &&
instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode +=
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
context);
context.SetNoCurrentObject();
}
}
return actionCode;
}
const EventsCodeGenerator::CallbackDescriptor
EventsCodeGenerator::GenerateCallback(
const gd::String& callbackID,
gd::EventsCodeGenerationContext& parentContext,
gd::InstructionsList& actions,
gd::EventsList* subEvents) {
gd::EventsCodeGenerationContext callbackContext;
callbackContext.InheritsAsAsyncCallbackFrom(parentContext);
const gd::String callbackFunctionName =
GetCodeNamespaceAccessor() + "asyncCallback" + callbackID;
const gd::String callbackFunctionArguments =
GenerateEventsParameters(callbackContext);
// Generate actions
gd::String actionsCode = GenerateActionsListCode(actions, callbackContext);
// Generate subevents
if (subEvents != nullptr) // Sub events
{
actionsCode += "\n{ //Subevents\n";
actionsCode += GenerateEventsListCode(*subEvents, callbackContext);
actionsCode += "} //End of subevents\n";
}
// Compose the callback function and add outside main
const gd::String actionsDeclarationsCode =
GenerateObjectsDeclarationCode(callbackContext);
const gd::String callbackCode = callbackFunctionName + " = function (" +
GenerateEventsParameters(callbackContext) +
") {\n" + actionsDeclarationsCode +
actionsCode + "}\n";
AddCustomCodeOutsideMain(callbackCode);
std::set<gd::String> requiredObjects;
// Build the list of all objects required by the callback. Any object that has
// already been declared could have gone through previous object picking, so
// if such an object is used by the actions or subevents of this callback, we
// must ask the caller to pass the already existing objects lists through a
// `LongLivedObjectsList` to the callback function.
for (const auto& objectUsedInSubTree :
callbackContext.GetAllDeclaredObjectsAcrossChildren()) {
if (callbackContext.ObjectAlreadyDeclaredByParents(objectUsedInSubTree))
requiredObjects.insert(objectUsedInSubTree);
};
return CallbackDescriptor(
callbackFunctionName, callbackFunctionArguments, requiredObjects);
};
const gd::String EventsCodeGenerator::GenerateEventsParameters(
const gd::EventsCodeGenerationContext& context) {
gd::String parameters = "runtimeScene";
if (!HasProjectAndLayout()) parameters += ", eventsFunctionContext";
if (context.IsInsideAsync()) parameters += ", asyncObjectsList";
return parameters;
};
/**
* Generate actions code.
*/
@@ -653,17 +576,13 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
gd::InstructionsList& actions, EventsCodeGenerationContext& context) {
gd::String outputCode;
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
gd::InstructionMetadata instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
gd::String actionCode = GenerateActionCode(actions[aId], context);
outputCode += "{";
if (actions[aId].GetType().empty()) {
// Deprecated way to cancel code generation - but still honor it.
// Can be removed once action is passed by const reference to
// GenerateActionCode.
outputCode += "/* Skipped action (empty type) */";
} else {
outputCode += actionCode;
}
if (!actions[aId].GetType().empty()) outputCode += actionCode;
outputCode += "}";
}
@@ -671,7 +590,7 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
}
gd::String EventsCodeGenerator::GenerateParameterCodes(
const gd::Expression& parameter,
const gd::String& parameter,
const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName,
@@ -681,21 +600,19 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
if (ParameterMetadata::IsExpression("number", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "number", parameter, lastObjectName);
*this, context, "number", parameter);
} else if (ParameterMetadata::IsExpression("string", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "string", parameter, lastObjectName);
*this, context, "string", parameter);
} else if (ParameterMetadata::IsExpression("variable", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, metadata.type, parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.type)) {
// It would be possible to run a gd::ExpressionCodeGenerator if later
// objects can have nested objects, or function returning objects.
argOutput =
GenerateObject(parameter.GetPlainString(), metadata.type, context);
argOutput = GenerateObject(parameter, metadata.type, context);
} else if (metadata.type == "relationalOperator") {
auto parameterString = parameter.GetPlainString();
argOutput += parameterString == "=" ? "==" : parameterString;
argOutput += parameter == "=" ? "==" : parameter;
if (argOutput != "==" && argOutput != "<" && argOutput != ">" &&
argOutput != "<=" && argOutput != ">=" && argOutput != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
@@ -704,7 +621,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
argOutput = "\"" + argOutput + "\"";
} else if (metadata.type == "operator") {
argOutput += parameter.GetPlainString();
argOutput += parameter;
if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
argOutput != "/" && argOutput != "*") {
cout << "Warning: Bad operator: Set to = by default." << endl;
@@ -713,32 +630,21 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
argOutput = "\"" + argOutput + "\"";
} else if (ParameterMetadata::IsBehavior(metadata.type)) {
argOutput = GenerateGetBehaviorNameCode(parameter.GetPlainString());
argOutput = GenerateGetBehaviorNameCode(parameter);
} else if (metadata.type == "key") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.type == "audioResource" ||
metadata.type == "bitmapFontResource" ||
metadata.type == "fontResource" ||
metadata.type == "imageResource" ||
metadata.type == "jsonResource" ||
metadata.type == "videoResource" ||
// Deprecated, old parameter names:
metadata.type == "password" || metadata.type == "musicfile" ||
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "password" || metadata.type == "musicfile" ||
metadata.type == "soundfile" || metadata.type == "police") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "mouse") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "yesorno") {
auto parameterString = parameter.GetPlainString();
argOutput += (parameterString == "yes" || parameterString == "oui")
? GenerateTrue()
: GenerateFalse();
argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
: GenerateFalse();
} else if (metadata.type == "trueorfalse") {
auto parameterString = parameter.GetPlainString();
// This is duplicated in AdvancedExtension.cpp for GDJS
argOutput += (parameterString == "True" || parameterString == "Vrai")
? GenerateTrue()
: GenerateFalse();
argOutput += (parameter == "True" || parameter == "Vrai") ? GenerateTrue()
: GenerateFalse();
}
// Code only parameter type
else if (metadata.type == "inlineCode") {
@@ -757,7 +663,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
if (!metadata.type.empty())
cout << "Warning: Unknown type of parameter \"" << metadata.type
<< "\"." << std::endl;
argOutput += "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
argOutput += "\"" + ConvertToString(parameter) + "\"";
}
}
@@ -777,7 +683,7 @@ vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
parametersInfo,
[this, &context, &supplementaryParametersTypes, &arguments](
const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue,
const gd::String& parameterValue,
const gd::String& lastObjectName) {
gd::String argOutput =
GenerateParameterCodes(parameterValue,
@@ -829,21 +735,23 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
gd::String declarationsCode;
for (auto object : context.GetObjectsListsToBeDeclared()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(object)) {
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) +
" = runtimeContext->GetObjectsRawPointers(\"" +
ConvertToString(object) + "\");\n";
context.SetObjectDeclared(object);
} else
objectListDeclaration = declareObjectList(object, context);
declarationsCode += objectListDeclaration + "\n";
}
for (auto object : context.GetObjectsListsToBeEmptyIfJustDeclared()) {
for (auto object : context.GetObjectsListsToBeDeclaredWithoutPicking()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(object)) {
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
context.SetObjectDeclared(object);
} else
objectListDeclaration = declareObjectList(object, context);
@@ -851,9 +759,10 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
}
for (auto object : context.GetObjectsListsToBeDeclaredEmpty()) {
gd::String objectListDeclaration = "";
if (!context.ObjectAlreadyDeclaredByParents(object)) {
if (!context.ObjectAlreadyDeclared(object)) {
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
context.SetObjectDeclared(object);
} else
objectListDeclaration = "std::vector<RuntimeObject*> " +
GetObjectListName(object, context) + ";\n";
@@ -868,7 +777,7 @@ gd::String EventsCodeGenerator::GenerateObjectsDeclarationCode(
* Generate events list code.
*/
gd::String EventsCodeGenerator::GenerateEventsListCode(
gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
gd::EventsList& events, const EventsCodeGenerationContext& parentContext) {
gd::String output;
for (std::size_t eId = 0; eId < events.size(); ++eId) {
// Each event has its own context : Objects picked in an event are totally
@@ -884,8 +793,6 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
// operation.
bool reuseParentContext =
parentContext.CanReuse() && eId == events.size() - 1;
// TODO: avoid creating if useless.
gd::EventsCodeGenerationContext reusedContext;
reusedContext.Reuse(parentContext);
@@ -1098,11 +1005,9 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
}
gd::String EventsCodeGenerator::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) {
// Generate call
gd::String call;
if (instrInfos.codeExtraInformation.type == "number" ||
@@ -1112,39 +1017,32 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction);
else if (instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::Mutators)
call =
GenerateMutatorCall(instrInfos,
arguments,
functionCallName);
instrInfos.codeExtraInformation.functionCallName);
else
call = GenerateCompoundOperatorCall(
instrInfos,
arguments,
functionCallName);
instrInfos.codeExtraInformation.functionCallName);
} else {
call = functionCallName + "(" +
call = instrInfos.codeExtraInformation.functionCallName + "(" +
GenerateArgumentsList(arguments) + ")";
}
if (!optionalAsyncCallbackName.empty())
call = "runtimeScene.getAsyncTasksManager().addTask(" + call + ", " +
optionalAsyncCallbackName + ")";
return call + ";\n";
}
gd::String EventsCodeGenerator::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) {
// Create call
gd::String call;
if ((instrInfos.codeExtraInformation.type == "number" ||
@@ -1154,26 +1052,25 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2);
else
call = GenerateCompoundOperatorCall(
instrInfos, arguments, functionCallName, 2);
instrInfos,
arguments,
instrInfos.codeExtraInformation.functionCallName,
2);
return "For each picked object \"" + objectName + "\", call " + call +
".\n";
} else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 1);
call = functionCallName + "(" + argumentsStr + ")";
call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" +
(optionalAsyncCallbackName.empty()
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n";
argumentsStr + ").\n";
}
}
@@ -1181,11 +1078,9 @@ gd::String EventsCodeGenerator::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) {
// Create call
gd::String call;
if ((instrInfos.codeExtraInformation.type == "number" ||
@@ -1195,29 +1090,24 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
call = GenerateOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2);
else
call = GenerateCompoundOperatorCall(
instrInfos,
arguments,
functionCallName,
instrInfos.codeExtraInformation.functionCallName,
2);
return "For each picked object \"" + objectName + "\", call " + call +
" for behavior \"" + behaviorName + "\".\n";
} else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 2);
call = functionCallName + "(" +
call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" +
(optionalAsyncCallbackName.empty()
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n";
argumentsStr + ")" + " for behavior \"" + behaviorName + "\".\n";
}
}
@@ -1237,11 +1127,10 @@ size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
// in memory will get the same id across different code generations.
size_t uniqueId = (size_t)instruction;
// While in most case this function is called a single time for each
// instruction, it's possible for an instruction to be appearing more than
// once in the events, if we used links. In this case, simply increment the
// unique id to be sure that ids are effectively uniques, and stay stable
// (given the same order of links).
// While in most case this function is called a single time for each instruction,
// it's possible for an instruction to be appearing more than once in the events,
// if we used links. In this case, simply increment the unique id to be sure that
// ids are effectively uniques, and stay stable (given the same order of links).
while (instructionUniqueIds.find(uniqueId) != instructionUniqueIds.end()) {
uniqueId++;
}
@@ -1265,7 +1154,7 @@ gd::String EventsCodeGenerator::GenerateArgumentsList(
return argumentsStr;
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator::EventsCodeGenerator(gd::Project& project_,
const gd::Layout& layout,
const gd::Platform& platform_)
: platform(platform_),
@@ -1282,7 +1171,7 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator::EventsCodeGenerator(
const gd::Platform& platform_,
const gd::ObjectsContainer& globalObjectsAndGroups_,
gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ObjectsContainer& objectsAndGroups_)
: platform(platform_),
globalObjectsAndGroups(globalObjectsAndGroups_),

View File

@@ -48,7 +48,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_);
@@ -57,7 +57,7 @@ class GD_CORE_API EventsCodeGenerator {
* objects/groups and platform
*/
EventsCodeGenerator(const gd::Platform& platform,
const gd::ObjectsContainer& globalObjectsAndGroups_,
gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ObjectsContainer& objectsAndGroups_);
virtual ~EventsCodeGenerator(){};
@@ -77,7 +77,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
@@ -154,54 +154,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.
@@ -329,7 +283,7 @@ class GD_CORE_API EventsCodeGenerator {
/**
* \brief Get the global objects/groups used for code generation.
*/
const gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
return globalObjectsAndGroups;
}
@@ -350,7 +304,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.
@@ -368,7 +322,7 @@ class GD_CORE_API EventsCodeGenerator {
* group.
*
* Get a list containing the "real" objects name when the events refers to \a
* objectName :<br> If \a objectName is really an object, the list will only
* 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
@@ -508,18 +462,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,
@@ -702,30 +666,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,
@@ -775,13 +733,13 @@ class GD_CORE_API EventsCodeGenerator {
const gd::Platform& platform; ///< The platform being used.
const gd::ObjectsContainer& globalObjectsAndGroups;
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 occured.
bool compilationForRuntime; ///< Is set to true if the code generation is

View File

@@ -4,10 +4,8 @@
* reserved. This project is released under the MIT License.
*/
#include "ExpressionCodeGenerator.h"
#include <memory>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
@@ -25,38 +23,29 @@
#include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
namespace gd {
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);
auto node = expression.GetRootNode();
if (!node) {
std::cout << "Error: error while parsing: \"" << expression.GetPlainString()
<< "\" (" << rootType << ")" << std::endl;
return generator.GenerateDefaultValue(rootType);
}
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType);
const gd::String& type,
const gd::String& expression,
const gd::String& objectName) {
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
auto node = parser.ParseExpression(type, expression, objectName);
gd::ExpressionValidator validator;
node->Visit(validator);
ExpressionCodeGenerator generator(codeGenerator, context);
if (!validator.GetErrors().empty()) {
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
<< "\" in: \"" << expression.GetPlainString() << "\" ("
<< rootType << ")" << std::endl;
<< "\" in: \"" << expression << "\" (" << type << ")"
<< std::endl;
return generator.GenerateDefaultValue(rootType);
return generator.GenerateDefaultValue(type);
}
node->Visit(generator);
@@ -99,24 +88,15 @@ 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.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
EventsCodeGenerator::VariableScope scope =
type == "globalvar"
node.type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: ((type == "scenevar")
: ((node.type == "scenevar")
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName);
node.name, scope, context, node.objectName);
if (node.child) node.child->Visit(*this);
}
@@ -128,7 +108,7 @@ void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) {
ExpressionCodeGenerator generator("string", "", codeGenerator, context);
ExpressionCodeGenerator generator(codeGenerator, context);
node.expression->Visit(generator);
output +=
codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput());
@@ -136,79 +116,39 @@ void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
}
void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
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.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
} else if (node.childIdentifierName.empty()) {
codeGenerator.GenerateObject(node.identifierName, node.type, context);
} else {
output += "/* Error during generation, unrecognized identifier type: " +
codeGenerator.ConvertToString(type) + " with value " +
codeGenerator.ConvertToString(node.type) + " with value " +
codeGenerator.ConvertToString(node.identifierName) + " */ " +
codeGenerator.ConvertToStringExplicit(node.identifierName);
}
else {
// This is for function names that are put in IdentifierNode
// because the type is needed to tell them appart from variables.
output += GenerateDefaultValue(type);
}
}
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
node);
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
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);
}
}
@@ -270,20 +210,14 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
codeGenerator.GetPlatform(), objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
expressionMetadata.GetRequiredBaseObjectCapability())) {
// Do nothing, skipping objects not supporting the capability required by
// this expression.
} else {
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;
@@ -356,21 +290,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.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
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();
@@ -420,30 +351,16 @@ 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.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
output += GenerateDefaultValue(type);
output += GenerateDefaultValue(node.type);
}
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType,
node);
output += GenerateDefaultValue(type);
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) {
output += GenerateDefaultValue(node.type);
}
} // namespace gd

View File

@@ -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,7 +57,7 @@ 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 = "");
const gd::String& GetOutput() { return output; };
@@ -104,8 +103,6 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
gd::String output;
EventsCodeGenerator& codeGenerator;
EventsCodeGenerationContext& context;
const gd::String rootType;
const gd::String rootObjectName;
};
} // namespace gd

View File

@@ -5,11 +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/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
@@ -68,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;

View File

@@ -10,13 +10,13 @@
#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,7 +24,7 @@ class EventsCodeGenerationContext;
class Platform;
class SerializerElement;
class Instruction;
} // namespace gd
}
namespace gd {
@@ -127,25 +127,18 @@ class GD_CORE_API BaseEvent {
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() {
GetAllExpressionsWithMetadata() {
std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> > 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<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() const {
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> > noExpr;
return noExpr;
};
@@ -209,11 +202,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

View File

@@ -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

View File

@@ -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

View File

@@ -72,22 +72,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.
*/
@@ -155,9 +139,7 @@ class GD_CORE_API Instruction {
* 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;
};
std::weak_ptr<Instruction> GetOriginalInstruction() { return originalInstruction; };
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
std::shared_ptr<Instruction> instruction);
@@ -166,9 +148,6 @@ class GD_CORE_API Instruction {
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.

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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"
@@ -26,20 +24,98 @@ namespace gd {
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::FunctionCallNode& 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)) {
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());
text->location = ExpressionParserLocation(textStartPosition, GetCurrentPosition());
return text;
}
SkipChar();
@@ -74,8 +150,7 @@ std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
}
auto text = gd::make_unique<TextNode>(parsedText);
text->location =
ExpressionParserLocation(textStartPosition, GetCurrentPosition());
text->location = ExpressionParserLocation(textStartPosition, GetCurrentPosition());
if (!textParsingHasEnded) {
text->diagnostic =
RaiseSyntaxError(_("A text must end with a double quote (\"). Add a "
@@ -97,7 +172,7 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
if (CheckIfChar(IsZeroDigit)) {
numberHasStarted = true;
digitFound = true;
if (!parsedNumber.empty()) { // Ignore leading 0s.
if (!parsedNumber.empty()) { // Ignore leading 0s.
parsedNumber += GetCurrentChar();
}
} else if (CheckIfChar(IsNonZeroDigit)) {
@@ -108,8 +183,7 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
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 += ".";
}
@@ -130,8 +204,7 @@ 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());
number->location = ExpressionParserLocation(numberStartPosition, GetCurrentPosition());
if (!numberHasStarted || !digitFound) {
number->diagnostic = RaiseSyntaxError(
_("A number was expected. You must enter a number here."));

View File

@@ -9,11 +9,9 @@
#include <memory>
#include <utility>
#include <vector>
#include "ExpressionParser2Node.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Project/Layout.h" // For GetTypeOfObject and GetTypeOfBehavior
#include "GDCore/String.h"
#include "GDCore/Tools/Localization.h"
@@ -40,7 +38,9 @@ namespace gd {
*/
class GD_CORE_API ExpressionParser2 {
public:
ExpressionParser2();
ExpressionParser2(const gd::Platform &platform_,
const gd::ObjectsContainer &globalObjectsContainer_,
const gd::ObjectsContainer &objectsContainer_);
virtual ~ExpressionParser2(){};
/**
@@ -56,27 +56,13 @@ class GD_CORE_API ExpressionParser2 {
* \return The node representing the expression as a parsed tree.
*/
std::unique_ptr<ExpressionNode> ParseExpression(
const gd::String &expression_) {
const gd::String &type,
const gd::String &expression_,
const gd::String &objectName = "") {
expression = expression_;
currentPosition = 0;
return Start();
}
/**
* Given an object name (or empty if none) and a behavior name (or empty if
* none), return the index of the first parameter that is inside the
* parenthesis: 0, 1 or 2.
*
* For example, in an expression like `Object.MyBehavior::Method("hello")`,
* the parameter "hello" is the second parameter (the first being by
* convention Object, and the second MyBehavior, also by convention).
*/
static size_t WrittenParametersFirstIndex(const gd::String &objectName,
const gd::String &behaviorName) {
// By convention, object is always the first parameter, and behavior the
// second one.
return !behaviorName.empty() ? 2 : (!objectName.empty() ? 1 : 0);
return Start(type, objectName);
}
private:
@@ -84,16 +70,16 @@ class GD_CORE_API ExpressionParser2 {
* Each method is a part of the grammar.
*/
///@{
std::unique_ptr<ExpressionNode> Start() {
std::unique_ptr<ExpressionNode> Start(const gd::String &type,
const gd::String &objectName = "") {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression();
auto expression = Expression(type, objectName);
// Check for extra characters at the end of the expression
if (!IsEndReached()) {
auto op = gd::make_unique<OperatorNode>(' ');
auto op = gd::make_unique<OperatorNode>(type, ' ');
op->leftHandSide = std::move(expression);
op->rightHandSide = ReadUntilEnd();
op->rightHandSide->parent = op.get();
op->rightHandSide = ReadUntilEnd("unknown");
op->rightHandSide->diagnostic = RaiseSyntaxError(
_("The expression has extra character at the end that should be "
@@ -107,49 +93,57 @@ class GD_CORE_API ExpressionParser2 {
return expression;
}
std::unique_ptr<ExpressionNode> Expression() {
std::unique_ptr<ExpressionNode> Expression(
const gd::String &type, const gd::String &objectName = "") {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> leftHandSide = Term();
std::unique_ptr<ExpressionNode> leftHandSide = Term(type, objectName);
SkipAllWhitespaces();
if (IsEndReached()) return leftHandSide;
if (CheckIfChar(IsExpressionEndingChar)) return leftHandSide;
if (CheckIfChar(IsExpressionOperator)) {
auto op = gd::make_unique<OperatorNode>(GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(type, GetCurrentChar());
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(type, GetCurrentChar());
SkipChar();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(type, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
return std::move(op);
}
leftHandSide->diagnostic = RaiseSyntaxError(
"More than one term was found. Verify that your expression is "
"properly written.");
if (type == "string") {
leftHandSide->diagnostic = RaiseSyntaxError(
"You must add the operator + between texts or expressions. For "
"example: \"Your name: \" + VariableString(PlayerName).");
} else if (type == "number") {
leftHandSide->diagnostic = RaiseSyntaxError(
"No operator found. Did you forget to enter an operator (like +, -, "
"* or /) between numbers or expressions?");
} else {
leftHandSide->diagnostic = RaiseSyntaxError(
"More than one term was found. Verify that your expression is "
"properly written.");
}
auto op = gd::make_unique<OperatorNode>(' ');
auto op = gd::make_unique<OperatorNode>(type, ' ');
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(type, objectName);
op->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
return std::move(op);
}
std::unique_ptr<ExpressionNode> Term() {
std::unique_ptr<ExpressionNode> Term(const gd::String &type,
const gd::String &objectName) {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> factor = Factor();
std::unique_ptr<ExpressionNode> factor = Factor(type, objectName);
SkipAllWhitespaces();
@@ -157,13 +151,11 @@ class GD_CORE_API ExpressionParser2 {
// to guarantee the proper operator precedence. (Expression could also
// be reworked to use a while loop).
while (CheckIfChar(IsTermOperator)) {
auto op = gd::make_unique<OperatorNode>(GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(type, GetCurrentChar());
op->leftHandSide = std::move(factor);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(type, GetCurrentChar());
SkipChar();
op->rightHandSide = Factor();
op->rightHandSide->parent = op.get();
op->rightHandSide = Factor(type, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
SkipAllWhitespaces();
@@ -174,35 +166,46 @@ class GD_CORE_API ExpressionParser2 {
return factor;
};
std::unique_ptr<ExpressionNode> Factor() {
std::unique_ptr<ExpressionNode> Factor(const gd::String &type,
const gd::String &objectName) {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> factor;
if (CheckIfChar(IsQuote)) {
std::unique_ptr<ExpressionNode> factor = ReadText();
return factor;
factor = ReadText();
if (type == "number")
factor->diagnostic =
RaiseTypeError(_("You entered a text, but a number was expected."),
expressionStartPosition);
else if (type != "string")
factor->diagnostic = RaiseTypeError(
_("You entered a text, but this type was expected:") + type,
expressionStartPosition);
} else if (CheckIfChar(IsUnaryOperator)) {
auto unaryOperatorCharacter = GetCurrentChar();
auto unaryOperator =
gd::make_unique<UnaryOperatorNode>(type, GetCurrentChar());
unaryOperator->diagnostic = ValidateUnaryOperator(type, GetCurrentChar());
SkipChar();
unaryOperator->factor = Factor(type, objectName);
auto operatorOperand = Factor();
auto unaryOperator = gd::make_unique<UnaryOperatorNode>(
unaryOperatorCharacter);
unaryOperator->diagnostic = ValidateUnaryOperator(
unaryOperatorCharacter, expressionStartPosition);
unaryOperator->factor = std::move(operatorOperand);
unaryOperator->factor->parent = unaryOperator.get();
unaryOperator->location = ExpressionParserLocation(
expressionStartPosition, GetCurrentPosition());
return std::move(unaryOperator);
factor = std::move(unaryOperator);
} else if (CheckIfChar(IsNumberFirstChar)) {
std::unique_ptr<ExpressionNode> factor = ReadNumber();
return factor;
factor = ReadNumber();
if (type == "string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but a text was expected (in quotes)."),
expressionStartPosition);
else if (type != "number")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but this type was expected:") + type,
expressionStartPosition);
} else if (CheckIfChar(IsOpeningParenthesis)) {
SkipChar();
std::unique_ptr<ExpressionNode> factor = SubExpression();
factor = SubExpression(type, objectName);
if (!CheckIfChar(IsClosingParenthesis)) {
factor->diagnostic =
@@ -210,22 +213,27 @@ class GD_CORE_API ExpressionParser2 {
"parenthesis for each opening parenthesis."));
}
SkipIfChar(IsClosingParenthesis);
return factor;
} else if (IsIdentifierAllowedChar()) {
return Identifier();
// This is a place where the grammar differs according to the
// type being expected.
if (gd::ParameterMetadata::IsExpression("variable", type)) {
factor = Variable(type, objectName);
} else {
factor = Identifier(type);
}
} else {
factor = ReadUntilWhitespace(type);
factor->diagnostic = RaiseEmptyError(type, expressionStartPosition);
}
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace();
return factor;
}
std::unique_ptr<SubExpressionNode> SubExpression() {
std::unique_ptr<SubExpressionNode> SubExpression(
const gd::String &type, const gd::String &objectName) {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression();
auto subExpression =
gd::make_unique<SubExpressionNode>(std::move(expression));
gd::make_unique<SubExpressionNode>(type, Expression(type, objectName));
subExpression->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
@@ -233,7 +241,7 @@ class GD_CORE_API ExpressionParser2 {
};
std::unique_ptr<IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode>
Identifier() {
Identifier(const gd::String &type) {
auto identifierAndLocation = ReadIdentifierName();
gd::String name = identifierAndLocation.name;
auto nameLocation = identifierAndLocation.location;
@@ -260,28 +268,42 @@ class GD_CORE_API ExpressionParser2 {
if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
return FreeFunction(name, nameLocation, openingParenthesisLocation);
return FreeFunction(type, name, nameLocation, openingParenthesisLocation);
} else if (CheckIfChar(IsDot)) {
ExpressionParserLocation dotLocation = SkipChar();
SkipAllWhitespaces();
return ObjectFunctionOrBehaviorFunction(
name, nameLocation, dotLocation);
} else if (CheckIfChar(IsOpeningSquareBracket)) {
return Variable(name, nameLocation);
}
else {
auto identifier = gd::make_unique<IdentifierNode>(name);
type, name, nameLocation, dotLocation);
} else {
auto identifier = gd::make_unique<IdentifierNode>(name, type);
if (type == "string") {
identifier->diagnostic =
RaiseTypeError(_("You must wrap your text inside double quotes "
"(example: \"Hello world\")."),
nameLocation.GetStartPosition());
} else if (type == "number") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number."), nameLocation.GetStartPosition());
} else if (!gd::ParameterMetadata::IsObject(type)) {
identifier->diagnostic = RaiseTypeError(
_("You've entered a name, but this type was expected:") + type,
nameLocation.GetStartPosition());
}
identifier->location = ExpressionParserLocation(
nameLocation.GetStartPosition(), GetCurrentPosition());
identifier->identifierNameLocation = identifier->location;
return std::move(identifier);
}
}
std::unique_ptr<VariableNode> Variable(const gd::String &name, gd::ExpressionParserLocation nameLocation) {
auto variable = gd::make_unique<VariableNode>(name);
std::unique_ptr<VariableNode> Variable(const gd::String &type,
const gd::String &objectName) {
auto identifierAndLocation = ReadIdentifierName();
const gd::String &name = identifierAndLocation.name;
const auto &nameLocation = identifierAndLocation.location;
auto variable = gd::make_unique<VariableNode>(type, name, objectName);
variable->child = VariableAccessorOrVariableBracketAccessor();
variable->child->parent = variable.get();
variable->location = ExpressionParserLocation(
nameLocation.GetStartPosition(), GetCurrentPosition());
@@ -296,8 +318,8 @@ class GD_CORE_API ExpressionParser2 {
SkipAllWhitespaces();
if (CheckIfChar(IsOpeningSquareBracket)) {
SkipChar();
auto child = gd::make_unique<VariableBracketAccessorNode>(Expression());
child->expression->parent = child.get();
auto child =
gd::make_unique<VariableBracketAccessorNode>(Expression("string"));
if (!CheckIfChar(IsClosingSquareBracket)) {
child->diagnostic =
@@ -306,7 +328,6 @@ class GD_CORE_API ExpressionParser2 {
}
SkipIfChar(IsClosingSquareBracket);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->location =
ExpressionParserLocation(childStartPosition, GetCurrentPosition());
@@ -319,7 +340,6 @@ class GD_CORE_API ExpressionParser2 {
auto child =
gd::make_unique<VariableAccessorNode>(identifierAndLocation.name);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->nameLocation = identifierAndLocation.location;
child->dotLocation = dotLocation;
child->location =
@@ -328,21 +348,33 @@ class GD_CORE_API ExpressionParser2 {
return std::move(child);
}
return std::move(gd::make_unique<VariableAccessorOrVariableBracketAccessorNode>());
return std::move(
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>());
}
std::unique_ptr<FunctionCallNode> FreeFunction(
const gd::String &type,
const gd::String &functionFullName,
const ExpressionParserLocation &identifierLocation,
const ExpressionParserLocation &openingParenthesisLocation) {
// TODO: error if trying to use function for type != "number" && != "string"
// + Test for it
auto function =
gd::make_unique<FunctionCallNode>(functionFullName);
auto parametersNode = Parameters(function.get());
function->parameters = std::move(parametersNode.parameters);
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number" ? MetadataProvider::GetExpressionMetadata(
platform, functionFullName)
: MetadataProvider::GetStrExpressionMetadata(
platform, functionFullName);
auto parametersNode = Parameters(metadata.parameters);
auto function = gd::make_unique<FunctionCallNode>(
type, std::move(parametersNode.parameters), metadata, functionFullName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, identifierLocation.GetStartPosition());
function->location = ExpressionParserLocation(
identifierLocation.GetStartPosition(), GetCurrentPosition());
@@ -350,19 +382,19 @@ class GD_CORE_API ExpressionParser2 {
function->openingParenthesisLocation = openingParenthesisLocation;
function->closingParenthesisLocation =
parametersNode.closingParenthesisLocation;
return std::move(function);
}
std::unique_ptr<IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode>
std::unique_ptr<FunctionCallOrObjectFunctionNameOrEmptyNode>
ObjectFunctionOrBehaviorFunction(
const gd::String &parentIdentifier,
const ExpressionParserLocation &parentIdentifierLocation,
const ExpressionParserLocation &parentIdentifierDotLocation) {
auto childIdentifierAndLocation = ReadIdentifierName();
const gd::String &childIdentifierName = childIdentifierAndLocation.name;
const auto &childIdentifierNameLocation =
childIdentifierAndLocation.location;
const gd::String &type,
const gd::String &objectName,
const ExpressionParserLocation &objectNameLocation,
const ExpressionParserLocation &objectNameDotLocation) {
auto identifierAndLocation = ReadIdentifierName();
const gd::String &objectFunctionOrBehaviorName = identifierAndLocation.name;
const auto &objectFunctionOrBehaviorNameLocation =
identifierAndLocation.location;
SkipAllWhitespaces();
@@ -370,68 +402,68 @@ class GD_CORE_API ExpressionParser2 {
ExpressionParserLocation namespaceSeparatorLocation =
SkipNamespaceSeparator();
SkipAllWhitespaces();
return BehaviorFunction(parentIdentifier,
childIdentifierName,
parentIdentifierLocation,
parentIdentifierDotLocation,
childIdentifierNameLocation,
return BehaviorFunction(type,
objectName,
objectFunctionOrBehaviorName,
objectNameLocation,
objectNameDotLocation,
objectFunctionOrBehaviorNameLocation,
namespaceSeparatorLocation);
} else if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
gd::String objectType =
GetTypeOfObject(globalObjectsContainer, objectsContainer, objectName);
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number"
? MetadataProvider::GetObjectExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName)
: MetadataProvider::GetObjectStrExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName);
auto parametersNode = Parameters(metadata.parameters, objectName);
auto function = gd::make_unique<FunctionCallNode>(
parentIdentifier,
childIdentifierName);
auto parametersNode = Parameters(function.get(), parentIdentifier);
function->parameters = std::move(parametersNode.parameters),
type,
objectName,
std::move(parametersNode.parameters),
metadata,
objectFunctionOrBehaviorName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
function->objectNameLocation = parentIdentifierLocation;
function->objectNameDotLocation = parentIdentifierDotLocation;
function->functionNameLocation = childIdentifierNameLocation;
objectNameLocation.GetStartPosition(), GetCurrentPosition());
function->objectNameLocation = objectNameLocation;
function->objectNameDotLocation = objectNameDotLocation;
function->functionNameLocation = objectFunctionOrBehaviorNameLocation;
function->openingParenthesisLocation = openingParenthesisLocation;
function->closingParenthesisLocation =
parametersNode.closingParenthesisLocation;
return std::move(function);
} else if (CheckIfChar(IsDot) || CheckIfChar(IsOpeningSquareBracket)) {
auto variable = gd::make_unique<VariableNode>(parentIdentifier);
auto child =
gd::make_unique<VariableAccessorNode>(childIdentifierName);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->nameLocation = childIdentifierNameLocation;
child->dotLocation = parentIdentifierDotLocation;
child->location = ExpressionParserLocation(
parentIdentifierDotLocation.GetStartPosition(), GetCurrentPosition());
variable->child = std::move(child);
variable->child->parent = variable.get();
variable->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
variable->nameLocation = parentIdentifierLocation;
return std::move(variable);
}
auto node = gd::make_unique<IdentifierNode>(
parentIdentifier, childIdentifierName);
if (!CheckIfChar(IsParameterSeparator) && !CheckIfChar(IsClosingParenthesis) && !IsEndReached()) {
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis (for an object expression), a double colon "
"(:: for a behavior expression), a dot or an opening bracket (for "
"a child variable) where expected."));
}
auto node = gd::make_unique<ObjectFunctionNameNode>(
type, objectName, objectFunctionOrBehaviorName);
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis (for an object expression), or double colon "
"(::) was expected (for a behavior expression)."));
node->location = ExpressionParserLocation(
parentIdentifierLocation.GetStartPosition(), GetCurrentPosition());
node->identifierNameLocation = parentIdentifierLocation;
node->identifierNameDotLocation = parentIdentifierDotLocation;
node->childIdentifierNameLocation = childIdentifierNameLocation;
objectNameLocation.GetStartPosition(), GetCurrentPosition());
node->objectNameLocation = objectNameLocation;
node->objectNameDotLocation = objectNameDotLocation;
node->objectFunctionOrBehaviorNameLocation =
objectFunctionOrBehaviorNameLocation;
return std::move(node);
}
std::unique_ptr<FunctionCallOrObjectFunctionNameOrEmptyNode> BehaviorFunction(
const gd::String &type,
const gd::String &objectName,
const gd::String &behaviorName,
const ExpressionParserLocation &objectNameLocation,
@@ -447,14 +479,30 @@ class GD_CORE_API ExpressionParser2 {
if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
gd::String behaviorType = GetTypeOfBehavior(
globalObjectsContainer, objectsContainer, behaviorName);
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number" ? MetadataProvider::GetBehaviorExpressionMetadata(
platform, behaviorType, functionName)
: MetadataProvider::GetBehaviorStrExpressionMetadata(
platform, behaviorType, functionName);
auto parametersNode =
Parameters(metadata.parameters, objectName, behaviorName);
auto function = gd::make_unique<FunctionCallNode>(
type,
objectName,
behaviorName,
std::move(parametersNode.parameters),
metadata,
functionName);
auto parametersNode =
Parameters(function.get(), objectName, behaviorName);
function->parameters = std::move(parametersNode.parameters);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
objectNameLocation.GetStartPosition(), GetCurrentPosition());
@@ -470,7 +518,7 @@ class GD_CORE_API ExpressionParser2 {
return std::move(function);
} else {
auto node = gd::make_unique<ObjectFunctionNameNode>(
objectName, behaviorName, functionName);
type, objectName, behaviorName, functionName);
node->diagnostic = RaiseSyntaxError(
_("An opening parenthesis was expected here to call a function."));
@@ -494,36 +542,64 @@ class GD_CORE_API ExpressionParser2 {
};
ParametersNode Parameters(
FunctionCallNode *functionCallNode,
std::vector<gd::ParameterMetadata> parameterMetadata,
const gd::String &objectName = "",
const gd::String &behaviorName = "") {
std::vector<std::unique_ptr<ExpressionNode>> parameters;
gd::String lastObjectName = "";
// By convention, object is always the first parameter, and behavior the
// second one.
size_t parameterIndex =
WrittenParametersFirstIndex(objectName, behaviorName);
bool previousCharacterIsParameterSeparator = false;
while (!IsEndReached()) {
SkipAllWhitespaces();
if (CheckIfChar(IsClosingParenthesis) && !previousCharacterIsParameterSeparator) {
if (CheckIfChar(IsClosingParenthesis)) {
auto closingParenthesisLocation = SkipChar();
return ParametersNode{
std::move(parameters), nullptr, closingParenthesisLocation};
}
bool isEmptyParameter = CheckIfChar(IsParameterSeparator)
|| (CheckIfChar(IsClosingParenthesis) && previousCharacterIsParameterSeparator);
auto parameter = isEmptyParameter ? gd::make_unique<EmptyNode>() : Expression();
parameter->parent = functionCallNode;
parameters.push_back(std::move(parameter));
} else {
if (parameterIndex < parameterMetadata.size()) {
const gd::String &type = parameterMetadata[parameterIndex].GetType();
if (parameterMetadata[parameterIndex].IsCodeOnly()) {
// Do nothing, code only parameters are not written in expressions.
} else if (gd::ParameterMetadata::IsExpression("number", type)) {
parameters.push_back(Expression("number"));
} else if (gd::ParameterMetadata::IsExpression("string", type)) {
parameters.push_back(Expression("string"));
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
parameters.push_back(Expression(type, objectName));
} else if (gd::ParameterMetadata::IsObject(type)) {
parameters.push_back(Expression(type));
} else {
size_t parameterStartPosition = GetCurrentPosition();
parameters.push_back(Expression("unknown"));
parameters.back()->diagnostic =
gd::make_unique<ExpressionParserError>(
"unknown_parameter_type",
_("This function is improperly set up. Reach out to the "
"extension developer or a GDevelop maintainer to fix "
"this issue"),
parameterStartPosition,
GetCurrentPosition());
}
} else {
size_t parameterStartPosition = GetCurrentPosition();
parameters.push_back(Expression("unknown"));
parameters.back()
->diagnostic = gd::make_unique<ExpressionParserError>(
"extra_parameter",
_("This parameter was not expected by this expression. Remove it "
"or verify that you've entered the proper expression name."),
parameterStartPosition,
GetCurrentPosition());
}
SkipAllWhitespaces();
previousCharacterIsParameterSeparator = CheckIfChar(IsParameterSeparator);
SkipIfChar(IsParameterSeparator);
parameterIndex++;
SkipAllWhitespaces();
SkipIfChar(IsParameterSeparator);
parameterIndex++;
}
}
ExpressionParserLocation invalidClosingParenthesisLocation;
@@ -535,32 +611,88 @@ class GD_CORE_API ExpressionParser2 {
}
///@}
/** \name Validators
* Return a diagnostic if any error is found
*/
///@{
std::unique_ptr<ExpressionParserDiagnostic> ValidateFunction(
const gd::FunctionCallNode &function, size_t functionStartPosition);
std::unique_ptr<ExpressionParserDiagnostic> ValidateOperator(
gd::String::value_type operatorChar) {
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
operatorChar == '*') {
return gd::make_unique<ExpressionParserDiagnostic>();
const gd::String &type, gd::String::value_type operatorChar) {
if (type == "number") {
if (operatorChar == '+' || operatorChar == '-' || operatorChar == '/' ||
operatorChar == '*') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Operator should be "
"either +, -, / or *."),
GetCurrentPosition());
} else if (type == "string") {
if (operatorChar == '+') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Only + can be used "
"to concatenate texts."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsObject(type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -, /, *) can't be used with an object name. Remove "
"the operator."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -, /, *) can't be used in variable names. Remove "
"the operator from the variable name."),
GetCurrentPosition());
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Operator should be "
"either +, -, / or *."),
GetCurrentPosition());
return gd::make_unique<ExpressionParserDiagnostic>();
}
std::unique_ptr<ExpressionParserDiagnostic> ValidateUnaryOperator(
gd::String::value_type operatorChar,
size_t position) {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
const gd::String &type, gd::String::value_type operatorChar) {
if (type == "number") {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an \"unary\" operator that is not supported. Operator "
"should be "
"either + or -."),
GetCurrentPosition());
} else if (type == "string") {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Only + can be used "
"to concatenate texts, and must be placed between two texts (or "
"expressions)."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsObject(type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used with an object name. Remove the "
"operator."),
GetCurrentPosition());
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used in variable names. Remove "
"the operator from the variable name."),
GetCurrentPosition());
}
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an \"unary\" operator that is not supported. Operator "
"should be "
"either + or -."),
position);
return gd::make_unique<ExpressionParserDiagnostic>();
}
///@}
@@ -717,7 +849,8 @@ class GD_CORE_API ExpressionParser2 {
while (currentPosition < expression.size() &&
(IsIdentifierAllowedChar()
// Allow whitespace in identifier name for compatibility
|| expression[currentPosition] == ' ')) {
||
expression[currentPosition] == ' ')) {
name += expression[currentPosition];
currentPosition++;
}
@@ -748,7 +881,7 @@ class GD_CORE_API ExpressionParser2 {
std::unique_ptr<NumberNode> ReadNumber();
std::unique_ptr<EmptyNode> ReadUntilWhitespace() {
std::unique_ptr<EmptyNode> ReadUntilWhitespace(gd::String type) {
size_t startPosition = GetCurrentPosition();
gd::String text;
while (currentPosition < expression.size() &&
@@ -757,13 +890,13 @@ class GD_CORE_API ExpressionParser2 {
currentPosition++;
}
auto node = gd::make_unique<EmptyNode>(text);
auto node = gd::make_unique<EmptyNode>(type, text);
node->location =
ExpressionParserLocation(startPosition, GetCurrentPosition());
return node;
}
std::unique_ptr<EmptyNode> ReadUntilEnd() {
std::unique_ptr<EmptyNode> ReadUntilEnd(gd::String type) {
size_t startPosition = GetCurrentPosition();
gd::String text;
while (currentPosition < expression.size()) {
@@ -771,7 +904,7 @@ class GD_CORE_API ExpressionParser2 {
currentPosition++;
}
auto node = gd::make_unique<EmptyNode>(text);
auto node = gd::make_unique<EmptyNode>(type, text);
node->location =
ExpressionParserLocation(startPosition, GetCurrentPosition());
return node;
@@ -804,11 +937,41 @@ class GD_CORE_API ExpressionParser2 {
return std::move(gd::make_unique<ExpressionParserError>(
"type_error", message, beginningPosition, GetCurrentPosition()));
}
std::unique_ptr<ExpressionParserError> RaiseEmptyError(
const gd::String &type, size_t beginningPosition) {
gd::String message;
if (type == "number") {
message = _("You must enter a number or a valid expression call.");
} else if (type == "string") {
message = _(
"You must enter a text (between quotes) or a valid expression call.");
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
message = _("You must enter a variable name.");
} else if (gd::ParameterMetadata::IsObject(type)) {
message = _("You must enter a valid object name.");
} else {
message = _("You must enter a valid expression.");
}
return std::move(RaiseTypeError(message, beginningPosition));
}
///@}
static size_t WrittenParametersFirstIndex(const gd::String &objectName,
const gd::String &behaviorName) {
// By convention, object is always the first parameter, and behavior the
// second one.
return !behaviorName.empty() ? 2 : (!objectName.empty() ? 1 : 0);
}
gd::String expression;
std::size_t currentPosition;
const gd::Platform &platform;
const gd::ObjectsContainer &globalObjectsContainer;
const gd::ObjectsContainer &objectsContainer;
static gd::String NAMESPACE_SEPARATOR;
};

View File

@@ -8,7 +8,6 @@
#include <memory>
#include <vector>
#include "ExpressionParser2NodeWorker.h"
#include "GDCore/String.h"
namespace gd {
@@ -17,12 +16,11 @@ class ObjectsContainer;
class Platform;
class ParameterMetadata;
class ExpressionMetadata;
struct FunctionCallNode;
} // namespace gd
namespace gd {
struct GD_CORE_API ExpressionParserLocation {
struct ExpressionParserLocation {
ExpressionParserLocation() : isValid(false){};
ExpressionParserLocation(size_t position)
: isValid(true), startPosition(position), endPosition(position){};
@@ -43,8 +41,7 @@ struct GD_CORE_API ExpressionParserLocation {
/**
* \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,11 +54,7 @@ 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_)
@@ -90,38 +83,40 @@ struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
* \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;
///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...
};
struct GD_CORE_API SubExpressionNode : public ExpressionNode {
SubExpressionNode(std::unique_ptr<ExpressionNode> expression_)
: ExpressionNode(), expression(std::move(expression_)){};
struct SubExpressionNode : public ExpressionNode {
SubExpressionNode(const gd::String &type_,
std::unique_ptr<ExpressionNode> expression_)
: type(type_), expression(std::move(expression_)){};
virtual ~SubExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitSubExpressionNode(*this);
};
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
std::unique_ptr<ExpressionNode> expression;
};
/**
* \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 {
OperatorNode(const gd::String &type_, gd::String::value_type op_)
: type(type_), op(op_){};
virtual ~OperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitOperatorNode(*this);
@@ -129,46 +124,48 @@ struct GD_CORE_API OperatorNode : public ExpressionNode {
std::unique_ptr<ExpressionNode> leftHandSide;
std::unique_ptr<ExpressionNode> rightHandSide;
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String::value_type op;
};
/**
* \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(const gd::String &type_, gd::String::value_type op_)
: type(type_), op(op_){};
virtual ~UnaryOperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitUnaryOperatorNode(*this);
};
std::unique_ptr<ExpressionNode> factor;
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String::value_type op;
};
/**
* \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,88 +174,31 @@ 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 with bracket accessor or at least 2 "dot" accessors.
* \brief A variable, potentially with accessor to its children.
*
* Example: MyVariable or MyVariable.MyChildren
*
* Example: MyVariable[MyChildren] or MyVariable.MyChildren.MyGranChildren.
*
* 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
@@ -270,10 +210,9 @@ struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmpty
* \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);
@@ -288,10 +227,10 @@ struct GD_CORE_API VariableAccessorNode
* \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);
@@ -300,26 +239,49 @@ struct GD_CORE_API VariableBracketAccessorNode
std::unique_ptr<ExpressionNode> expression;
};
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {};
/**
* \brief An identifier node, usually representing an object or a function name.
*/
struct IdentifierNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
IdentifierNode(const gd::String &identifierName_, const gd::String &type_)
: identifierName(identifierName_), type(type_){};
virtual ~IdentifierNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitIdentifierNode(*this);
};
gd::String identifierName;
gd::String type;
};
struct FunctionCallOrObjectFunctionNameOrEmptyNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
virtual ~FunctionCallOrObjectFunctionNameOrEmptyNode(){};
void Visit(ExpressionParser2NodeWorker &worker) override{};
};
/**
* \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
* For example: "MyObject.Function" or "MyObject.Physics" or
* "MyObject.Physics::LinearVelocity".
*/
struct GD_CORE_API ObjectFunctionNameNode
struct ObjectFunctionNameNode
: public FunctionCallOrObjectFunctionNameOrEmptyNode {
ObjectFunctionNameNode(const gd::String &objectName_,
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &objectFunctionOrBehaviorName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: type(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {}
ObjectFunctionNameNode(const gd::String &objectName_,
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_,
const gd::String &behaviorFunctionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: type(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(behaviorName_),
behaviorFunctionName(behaviorFunctionName_) {}
@@ -328,30 +290,34 @@ struct GD_CORE_API ObjectFunctionNameNode
worker.OnVisitObjectFunctionNameNode(*this);
};
gd::String type; // This could be removed if the type ("string", "number",
// type supported by gd::ParameterMetadata::IsObject, types
// supported by gd::ParameterMetadata::IsExpression or
// "unknown") was stored in ExpressionMetadata.
gd::String objectName;
gd::String objectFunctionOrBehaviorName; ///< Behavior name if
///`behaviorFunctionName` is not
/// empty.
///empty.
gd::String behaviorFunctionName; ///< If empty, then
/// objectFunctionOrBehaviorName is filled
/// with the behavior name.
///objectFunctionOrBehaviorName is filled
///with the behavior name.
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.
///of object
///function
///name or
///behavior
///name.
ExpressionParserLocation
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
/// separator, if any.
///separator, if any.
ExpressionParserLocation behaviorFunctionNameLocation; ///< Location of the
/// behavior function
/// name, if any.
///behavior function
///name, if any.
};
/**
@@ -360,35 +326,50 @@ struct GD_CORE_API ObjectFunctionNameNode
* For example: "MyExtension::MyFunction(1, 2)", "MyObject.Function()" or
* "MyObject.Physics::LinearVelocity()".
*/
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
/** \brief Construct a free function call node. */
FunctionCallNode(const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
functionName(functionName_){};
/** \brief Construct an object function call node. */
FunctionCallNode(const gd::String &objectName_,
struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
FunctionCallNode(const gd::String &type_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: type(type_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
FunctionCallNode(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_,
FunctionCallNode(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_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: type(type_),
objectName(objectName_),
behaviorName(behaviorName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
virtual ~FunctionCallNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitFunctionCallNode(*this);
};
gd::String type; // This could be removed if the type ("string", "number",
// type supported by gd::ParameterMetadata::IsObject, types
// supported by gd::ParameterMetadata::IsExpression or
// "unknown") was stored in ExpressionMetadata.
gd::String objectName;
gd::String behaviorName;
std::vector<std::unique_ptr<ExpressionNode>> parameters;
const ExpressionMetadata &expressionMetadata;
gd::String functionName;
ExpressionParserLocation
@@ -401,7 +382,7 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
behaviorNameLocation; ///< Location of the behavior name, if any.
ExpressionParserLocation
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
/// separator, if any.
///separator, if any.
ExpressionParserLocation
openingParenthesisLocation; ///< Location of the "(".
ExpressionParserLocation
@@ -412,14 +393,17 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
* \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 FunctionCallOrObjectFunctionNameOrEmptyNode {
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; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String text;
};

View File

@@ -91,9 +91,6 @@ 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()) {

View File

@@ -7,21 +7,21 @@
#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 IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
class IdentifierNode;
class FunctionCallOrObjectFunctionNameOrEmptyNode;
class ObjectFunctionNameNode;
class FunctionCallNode;
class EmptyNode;
} // namespace gd
namespace gd {
@@ -34,21 +34,21 @@ 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 IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
friend class IdentifierNode;
friend class FunctionCallOrObjectFunctionNameOrEmptyNode;
friend class ObjectFunctionNameNode;
friend class FunctionCallNode;
friend class EmptyNode;
public:
virtual ~ExpressionParser2NodeWorker();

View File

@@ -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"
@@ -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);
}
}

View File

@@ -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,9 +39,9 @@ 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")
.MarkAsAdvanced();
@@ -43,9 +53,9 @@ 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")
.MarkAsAdvanced();
@@ -56,44 +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?")
.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")
.MarkAsAdvanced();
extension
.AddExpression(
"GetArgumentAsNumber",
_("Get function parameter value"),
_("Get function parameter (also called \"argument\") value"),
"",
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name");
.AddParameter("string", "Parameter name");
extension
.AddStrExpression(
"GetArgumentAsString",
_("Get function parameter text"),
_("Get function parameter (also called \"argument\") text "),
"",
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", "Parameter name");
.AddParameter("string", "Parameter name");
#endif
}
} // namespace gd

View File

@@ -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,7 +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);
};
} // namespace gd

View File

@@ -1,32 +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",
_("Async functions"),
_("Functions that defer the execution of the events after it."),
"Arthur Pacaud (arthuro555)",
"Open source (MIT License)")
.SetCategory("Advanced");
extension.AddEvent("Async",
_("Async event"),
_("Internal event for asynchronous actions"),
"",
"res/eventaddicon.png",
std::make_shared<gd::AsyncEvent>());
}
} // namespace gd

View File

@@ -12,18 +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");
.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"),
@@ -31,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", "")
@@ -52,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", "")
@@ -64,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", "")
@@ -76,7 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Play the sound of a channel"),
_("Play the sound of the channel."),
_("Play the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -90,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", "")
@@ -111,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", "")
@@ -123,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", "")
@@ -135,7 +131,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Play the music of a channel"),
_("Play the music of the channel."),
_("Play the music of channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -148,7 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies 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/actions/sonVolume24.png",
"res/actions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -162,7 +158,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the volume of the music on the "
"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", "")
@@ -176,7 +172,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("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", "")
@@ -189,7 +185,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the pitch (speed) of the sound on a "
"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", "")
@@ -203,7 +199,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the pitch of the music on the "
"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", "")
@@ -217,7 +213,7 @@ 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", "")
@@ -231,7 +227,7 @@ 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", "")
@@ -244,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", "")
@@ -264,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", "")
@@ -279,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", "")
@@ -389,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", "")
@@ -401,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", "")
@@ -413,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", "")
@@ -425,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", "")
@@ -437,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", "")
@@ -451,7 +354,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("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", "")
@@ -466,7 +369,7 @@ 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", "")
@@ -480,7 +383,7 @@ 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", "")
@@ -493,7 +396,7 @@ 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", "")
@@ -508,7 +411,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("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", "")
@@ -522,7 +425,7 @@ 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", "")
@@ -536,7 +439,7 @@ 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", "")
@@ -605,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

View File

@@ -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,211 +12,148 @@ 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)")
.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");
#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"),
_("Change the X position of the center of the specified camera."),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
"res/conditions/camera24.png")
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
.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"),
_("Change the Y position of the center of the specified camera."),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
"res/conditions/camera24.png")
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.AddParameter("layer", _("Layer"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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 (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number")
.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")
.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", "")
@@ -252,7 +188,7 @@ 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", "")
@@ -268,7 +204,7 @@ 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", "")
@@ -286,7 +222,7 @@ 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", "")
@@ -309,11 +245,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.AddAction("ZoomCamera",
_("Change 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", "")
@@ -324,7 +260,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// TODO Deprecated: hide this action in a future release.
extension
.AddAction(
"FixCamera",
@@ -333,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", "")
@@ -357,38 +292,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.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 (base layer if empty)"), "", 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_)"),
"",
_("Center camera on _PARAM1_ (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -409,7 +319,7 @@ 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", "")
@@ -422,7 +332,7 @@ 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", "")
@@ -435,7 +345,7 @@ 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", "")
@@ -451,14 +361,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("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"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("expression", _("New value"))
.MarkAsAdvanced();
@@ -470,14 +380,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("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"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("string", _("New value"))
.MarkAsAdvanced();
@@ -489,14 +399,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("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"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("yesorno", _("Enable this parameter"))
.MarkAsAdvanced();
@@ -505,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"),
_("Effects"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("string", _("Effect"))
.MarkAsAdvanced();
extension
@@ -519,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"),
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("string", _("Effect"))
.AddParameter("yesorno", _("Enable"), "", true)
.MarkAsAdvanced();
@@ -535,7 +445,7 @@ 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", "")
@@ -549,8 +459,8 @@ 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", "")
@@ -560,57 +470,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("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 (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
.AddParameter("layer", _("Layer"))
.AddParameter("expression", _("Camera number (default : 0)"))
.SetDefaultValue("0");
extension
.AddAction("SetLayerDefaultZOrder",
_("Change 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 (base layer if empty)"), "", 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_"),
_("Lighting"),
"res/actions/color24.png",
"res/actions/color.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", 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"))
@@ -622,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"))
@@ -634,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"))
@@ -646,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"))
@@ -654,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)
@@ -665,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

View File

@@ -15,19 +15,19 @@ 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.png");
#if defined(GD_IDE_ONLY)
extension
.AddExpression("ToNumber",
_("Text > Number"),
_("Convert the text to a number"),
"",
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to convert to a number"));
@@ -35,7 +35,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.AddStrExpression("ToString",
_("Number > Text"),
_("Convert the result of the expression to text"),
"",
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
@@ -44,7 +44,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Number > Text ( without scientific notation )"),
_("Convert the result of the expression to text, "
"without using the scientific notation"),
"",
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
@@ -53,7 +53,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToRad",
_("Degrees > Radians"),
_("Converts the angle, expressed in degrees, into radians"),
"",
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in degrees"));
@@ -62,76 +62,10 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToDeg",
_("Radians > Degrees"),
_("Converts the angle, expressed in radians, into degrees"),
"",
_("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.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.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.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"),
_("Parse 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"),
_("Parse 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

View File

@@ -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,43 +25,19 @@ 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.png");
extension
.AddCondition("Always",
_("Always"),
_("This condition always returns true (or always false, if "
"the condition is inverted)."),
_("Always"),
"",
"res/conditions/toujours24.png",
"res/conditions/toujours.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
// 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:"),
"",
_("Advanced"),
"res/conditions/or24.png",
"res/conditions/or.png")
.SetCanHaveSubInstructions()
@@ -69,9 +46,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
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:"),
"",
_("Advanced"),
"res/conditions/and24.png",
"res/conditions/and.png")
.SetCanHaveSubInstructions()
@@ -83,7 +60,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Not"),
_("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"),
"",
_("Advanced"),
"res/conditions/not24.png",
"res/conditions/not.png")
.SetCanHaveSubInstructions()
@@ -94,52 +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.png",
"res/conditions/egal.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.png",
"res/conditions/egal.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"),
@@ -149,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>());
@@ -183,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

View File

@@ -13,32 +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")
.MarkAsAdvanced();
#endif
}
} // namespace gd

View File

@@ -12,19 +12,15 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation(
"BuiltinFile",
_("Storage"),
"Actions and conditions to store data (like the player progress or "
"anything else to be persisted across game sessions). Data are "
"stored on the device and erased when the game is uninstalled.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage")
.SetCategory("Device");
extension.AddInstructionOrExpressionGroupMetadata(_("Storage"))
.SetIcon("res/conditions/fichier24.png");
.SetExtensionInformation("BuiltinFile",
_("Storage"),
_("Built-in extension providing functions "
"to store data."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage");
#if defined(GD_IDE_ONLY)
extension
.AddCondition(
"GroupExists",
@@ -32,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("Check if an element (example : PlayerState/CurrentLevel) exists "
"in the stored data.\nSpaces are forbidden in element names."),
_("_PARAM1_ exists in storage _PARAM0_"),
"",
_("Storage"),
"res/conditions/fichier24.png",
"res/conditions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -48,7 +44,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"action, but it will be slower.\nIf you use this action, do not "
"forget to unload the storage from memory."),
_("Load storage _PARAM0_ in memory"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -60,7 +56,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("This action closes the structured data previously loaded "
"in memory, saving all changes made."),
_("Close structured data _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -75,7 +71,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"element using / (example : Root/Level/Current)\nSpaces are "
"forbidden in element names."),
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -91,7 +87,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"the structure leading to the element using / (example : "
"Root/Level/Current)\nSpaces are forbidden in element names."),
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -102,13 +98,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddAction(
"LireFichierExp",
_("Read a value"),
_("Read the value saved in the specified element and store it in a "
"scene "
_("Read the value saved in the specified element and store it in a scene"
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
_("Read _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -120,14 +115,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddAction(
"LireFichierTxt",
_("Read a text"),
_("Read the text saved in the specified element and store it in a "
"scene "
_("Read the text saved in the specified element and store it in a scene "
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
_("Read _PARAM1_ from storage _PARAM0_ and store as text in "
"_PARAM3_"),
"",
_("Storage"),
"res/actions/fichier24.png",
"res/actions/fichier.png")
.AddParameter("string", _("Storage name"))
@@ -143,7 +137,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"element using / (example : Root/Level/Current)\nSpaces are "
"forbidden in element names."),
_("Delete _PARAM1_ from storage _PARAM0_"),
"",
_("Storage"),
"res/actions/delete24.png",
"res/actions/delete.png")
.AddParameter("string", _("Storage name"))
@@ -156,7 +150,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("Clear a storage"),
_("Clear the specified storage, removing all data saved in it."),
_("Delete storage _PARAM0_"),
"",
_("Storage"),
"res/actions/delete24.png",
"res/actions/delete.png")
.AddParameter("string", _("Storage name"));
@@ -166,22 +160,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
_("A storage exists"),
_("Test if the specified storage exists."),
_("Storage _PARAM0_ exists"),
"",
_("Storage"),
"res/conditions/fichier24.png",
"res/conditions/fichier.png")
.AddParameter("string", _("Storage name"))
.MarkAsAdvanced();
extension
.AddAction("LaunchFile",
_("Open a URL or a file"),
_("This action launches the specified file or URL, in a "
"browser (or in a new tab if the game is using the Web "
"platform and is launched inside a browser)."),
_("Open URL (or file) _PARAM0_"),
_("Files"),
"res/actions/launchFile24.png",
"res/actions/launchFile.png")
.AddParameter("string", _("URL (or filename)"))
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
.AddAction("ExecuteCmd",
_("Execute a command"),
_("This action executes the specified command."),
_("Execute _PARAM0_"),
_("Network"),
_("Files"),
"res/actions/launchFile24.png",
"res/actions/launchFile.png")
.AddParameter("string", _("Command"))
.MarkAsAdvanced();
#endif
}
} // namespace gd

View File

@@ -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.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsJoystickExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation(
"BuiltinJoystick",
_("Joysticks features"),
_("Built-in extension that enables the use of joysticks"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
#if defined(GD_IDE_ONLY)
extension
.AddCondition("JoystickButtonDown",
_("A button on a joystick is pressed"),
_("Test if a button on a joystick is pressed."),
_("The button _PARAM2_ of joystick _PARAM1_ is pressed"),
_("Joystick"),
"res/conditions/joystick24.png",
"res/conditions/joystick.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Joystick number (first joystick: 0)"))
.AddParameter("expression", _("Button"));
extension
.AddCondition("JoystickAxis",
_("Value of an axis of a joystick"),
_("Test the value of an axis of a joystick."),
_("the value of the axis _PARAM2_ of joystick _PARAM1_"),
_("Joystick"),
"res/conditions/joystick24.png",
"res/conditions/joystick.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Joystick number (first joystick: 0)"))
.AddParameter("joyaxis", _("Axis"))
.UseStandardRelationalOperatorParameters("number");
extension
.AddAction(
"GetJoystickAxis",
_("Get the value of the axis of a joystick"),
_("Save the value of the axis of the joystick (from -100 to 100)."),
_("Save in _PARAM3_ the value of axis _PARAM2_ of joystick _PARAM1_"),
_("Joystick"),
"res/actions/joystick24.png",
"res/actions/joystick.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Joystick number (first joystick: 0)"))
.AddParameter("joyaxis", _("Axis"))
.AddParameter("scenevar", _("Save the result to the scene variable"))
.SetManipulatedType("number");
extension
.AddExpression("GetJoystickAxis",
_("Joystick axis"),
_("Value of an axis of a joystick"),
_("Joystick"),
"res/conditions/joystick.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Joystick number (first joystick: 0)"))
.AddParameter("joyaxis", _("Axis"));
#endif
}
} // namespace gd

View File

@@ -14,24 +14,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.SetExtensionInformation(
"BuiltinKeyboard",
_("Keyboard"),
_("Allows your game to respond to keyboard input. Note that this "
"does not work with on-screen keyboard on touch devices: use "
"instead conditions related to touch when making a game for "
"mobile/touchscreen devices."),
_("Keyboard features"),
_("Built-in extension that enables the use of a keyboard"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/keyboard")
.SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Keyboard"))
.SetIcon("res/conditions/keyboard24.png");
.SetExtensionHelpPath("/all-features/keyboard");
#if defined(GD_IDE_ONLY)
extension
.AddCondition("KeyPressed",
_("Key pressed"),
_("Check if a key is pressed"),
_("Test if a key is pressed"),
_("_PARAM1_ key is pressed"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -40,9 +35,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.AddCondition("KeyReleased",
_("Key released"),
_("Check if a key was just released"),
_("Test if a key was just released"),
_("_PARAM1_ key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -51,45 +46,35 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.AddCondition("KeyFromTextPressed",
_("Key pressed (text expression)"),
_("Check if a key, retrieved from the result of the "
_("Test if a key, retrieved from the result of the "
"expression, is pressed"),
_("_PARAM1_ key is pressed"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.AddParameter("string", _("Expression generating the key to test"))
.MarkAsAdvanced();
extension
.AddCondition("KeyFromTextReleased",
_("Key released (text expression)"),
_("Check if a key, retrieved from the result of the "
_("Test if a key, retrieved from the result of the "
"expression, was just released"),
_("_PARAM1_ key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.AddParameter("string", _("Expression generating the key to test"))
.MarkAsAdvanced();
extension
.AddCondition("AnyKeyPressed",
_("Any key pressed"),
_("Check if any key is pressed"),
_("Test if any key is pressed"),
_("Any key is pressed"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddCondition("AnyKeyReleased",
_("Any key released"),
_("Check if any key is released"),
_("Any key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -99,9 +84,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"LastPressedKey",
_("Last pressed key"),
_("Get the name of the latest key pressed on the keyboard"),
"",
_("Keyboard"),
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

@@ -15,76 +15,17 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension.SetExtensionInformation(
"BuiltinMathematicalTools",
_("Mathematical tools"),
"A set of mathematical functions that can be used in expressions.",
_("Built-in extension providing mathematical tools"),
"Florian Rival",
"Open source (MIT License)");
extension.AddInstructionOrExpressionGroupMetadata(_("Mathematical tools"))
.SetIcon("res/mathfunction.png");
extension
.AddExpression("Random",
_("Random integer"),
_("Random integer"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomInRange",
_("Random integer in range"),
_("Random integer in range"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloat",
_("Random float"),
_("Random float"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloatInRange",
_("Random float in range"),
_("Random float in range"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomWithStep",
_("Random value in steps"),
_("Random value in steps"),
"",
"res/dice-6.svg")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"))
.AddParameter("expression", _("Step"));
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Remap a value between 0 and 1."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
.AddParameter("expression", _("Max"));
#if defined(GD_IDE_ONLY)
extension
.AddExpression("clamp",
_("Clamp (restrict a value to a given range)"),
_("Restrict a value to a given range"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
@@ -94,38 +35,16 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("AngleDifference",
_("Difference between two angles"),
_("Difference between two angles"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First angle, in degrees"))
.AddParameter("expression", _("Second angle, in degrees"));
extension
.AddExpression("AngleBetweenPositions",
_("Angle between two positions"),
_("Compute the angle between two positions (in degrees)."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
.AddParameter("expression", _("Second point X position"))
.AddParameter("expression", _("Second point Y position"));
extension
.AddExpression("DistanceBetweenPositions",
_("Distance between two positions"),
_("Compute the distance between two positions."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
.AddParameter("expression", _("Second point X position"))
.AddParameter("expression", _("Second point Y position"));
.AddParameter("expression", _("First angle"))
.AddParameter("expression", _("Second angle"));
extension
.AddExpression("mod",
_("Modulo"),
_("x mod y"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("x (as in x mod y)"))
.AddParameter("expression", _("y (as in x mod y)"));
@@ -134,7 +53,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("min",
_("Minimum of two numbers"),
_("Minimum of two numbers"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First expression"))
.AddParameter("expression", _("Second expression"));
@@ -143,7 +62,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("max",
_("Maximum of two numbers"),
_("Maximum of two numbers"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First expression"))
.AddParameter("expression", _("Second expression"));
@@ -152,16 +71,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("abs",
_("Absolute value"),
_("Absolute value"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("acos",
_("Arccosine"),
_("Arccosine, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arccosine"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -169,16 +87,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("acosh",
_("Hyperbolic arccosine"),
_("Hyperbolic arccosine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("asin",
_("Arcsine"),
_("Arcsine, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arcsine"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -186,16 +103,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("asinh",
_("Arcsine"),
_("Arcsine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("atan",
_("Arctangent"),
_("Arctangent, return an angle (in radian). "
"`ToDeg` allows to convert it to degrees."),
"",
_("Arctangent"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -203,7 +119,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("atan2",
_("2 argument arctangent"),
_("2 argument arctangent (atan2)"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Y"))
.AddParameter("expression", _("X"));
@@ -212,7 +128,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("atanh",
_("Hyperbolic arctangent"),
_("Hyperbolic arctangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -220,7 +136,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cbrt",
_("Cube root"),
_("Cube root"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -228,42 +144,23 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("ceil",
_("Ceil (round up)"),
_("Round number up to an integer"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("ceilTo",
_("Ceil (round up) to a decimal point"),
_("Round number up to the Nth decimal place"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"))
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression("floor",
_("Floor (round down)"),
_("Round number down to an integer"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("floorTo",
_("Floor (round down) to a decimal point"),
_("Round number down to the Nth decimal place"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"))
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression("cos",
_("Cosine"),
_("Cosine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
_("Cosine of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -271,7 +168,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cosh",
_("Hyperbolic cosine"),
_("Hyperbolic cosine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -279,7 +176,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cot",
_("Cotangent"),
_("Cotangent of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -287,7 +184,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("csc",
_("Cosecant"),
_("Cosecant of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -295,7 +192,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("int",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -304,7 +201,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("rint",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -313,24 +210,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("round",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("roundTo",
_("Round to a decimal point"),
_("Round a number to the Nth decimal place"),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"))
.AddParameter("expression", _("Expression"), "", true);
extension
.AddExpression("exp",
_("Exponential"),
_("Exponential of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -338,7 +226,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -346,7 +234,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("ln",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -355,7 +243,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log2",
_("Base-2 logarithm"),
_("Base 2 Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -363,7 +251,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log10",
_("Base-10 logarithm"),
_("Base-10 logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -371,7 +259,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("nthroot",
_("Nth root"),
_("Nth root of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Number"))
.AddParameter("expression", _("N"));
@@ -380,7 +268,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("pow",
_("Power"),
_("Raise a number to power n"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Number"))
.AddParameter("expression", _("The exponent (n in x^n)"));
@@ -389,7 +277,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sec",
_("Secant"),
_("Secant"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -397,16 +285,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sign",
_("Sign of a number"),
_("Return the sign of a number (1,-1 or 0)"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("sin",
_("Sine"),
_("Sine of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"",
_("Sine of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -414,7 +301,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sinh",
_("Hyperbolic sine"),
_("Hyperbolic sine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -422,16 +309,15 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sqrt",
_("Square root"),
_("Square root of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
extension
.AddExpression("tan",
_("Tangent"),
_("Tangent of an angle (in radian). "
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"",
_("Tangent of a number"),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -439,7 +325,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("tanh",
_("Hyperbolic tangent"),
_("Hyperbolic tangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -447,7 +333,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("trunc",
_("Truncation"),
_("Truncate a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -455,36 +341,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("lerp",
_("Lerp (Linear interpolation)"),
_("Linearly interpolate a to b by x"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("a (in a+(b-a)*x)"))
.AddParameter("expression", _("b (in a+(b-a)*x)"))
.AddParameter("expression", _("x (in a+(b-a)*x)"));
extension
.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
#endif
}
} // namespace gd

View File

@@ -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;
@@ -15,19 +14,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
extension
.SetExtensionInformation(
"BuiltinMouse",
_("Mouse and touch"),
"Conditions and actions to handle either the mouse or touches on "
"touchscreen. By default, conditions related to the mouse will also "
"handle the touches - so that it's easier to handle both in your "
"game. You can disable this behavior if you want to handle them "
"separately in different events.",
_("Mouse features"),
_("Built-in extension that enables the use of a mouse"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/mouse-touch")
.SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Mouse and touch"))
.SetIcon("res/actions/mouse24.png");
.SetExtensionHelpPath("/all-features/mouse-touch");
#if defined(GD_IDE_ONLY)
extension
.AddCondition(
"IsMouseWheelScrollingUp",
@@ -35,7 +28,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if the mouse wheel is scrolling up. Use MouseWheelDelta "
"expression if you want to know the amount that was scrolled."),
_("The mouse wheel is scrolling up"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -49,7 +42,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if the mouse wheel is scrolling down. Use MouseWheelDelta "
"expression if you want to know the amount that was scrolled."),
_("The mouse wheel is scrolling down"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -67,7 +60,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"touchscreens. If you want to have multitouch and differentiate "
"mouse movement and touches, just deactivate it with this action."),
_("Move mouse cursor when touching screen: _PARAM1_"),
"",
_("Mouse and touch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
@@ -82,7 +75,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center cursor horizontally"),
_("Put the cursor in the middle of the screen horizontally."),
_("Center cursor horizontally"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -94,7 +87,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center cursor vertically"),
_("Put the cursor in the middle of the screen vertically."),
_("Center cursor vertically"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -106,7 +99,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Hide the cursor"),
_("Hide the cursor."),
_("Hide the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -117,7 +110,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Show the cursor"),
_("Show the cursor."),
_("Show the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -129,7 +122,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Position the cursor of the mouse"),
_("Position the cursor at the given coordinates."),
_("Position cursor at _PARAM1_;_PARAM2_"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -143,7 +136,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Center the cursor"),
_("Center the cursor on the screen."),
_("Center the cursor"),
"",
_("Mouse and touch"),
"res/actions/mouse24.png",
"res/actions/mouse.png")
@@ -151,148 +144,88 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"MouseX",
_("Cursor X position"),
_("the X position of the cursor or of a touch"),
_("the cursor (or touch) X position"),
"",
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisX", "MouseX").SetHidden();
extension.AddDuplicatedExpression("SourisX", "MouseX").SetHidden();
extension
.AddExpressionAndCondition(
"number",
"MouseY",
_("Cursor Y position"),
_("the Y position of the cursor or of a touch"),
_("the cursor (or touch) Y position"),
"",
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisY", "MouseY").SetHidden();
extension.AddDuplicatedExpression("SourisY", "MouseY").SetHidden();
extension
.AddCondition("IsMouseInsideCanvas",
_("Mouse cursor is inside the window"),
_("Check if the mouse cursor is inside the window."),
_("The mouse cursor is inside the window"),
"",
.AddCondition("SourisX",
_("Cursor X position"),
_("Compare the X position of the cursor or of a touch."),
_("the cursor X position"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddCondition("MouseButtonPressed",
.AddCondition("SourisY",
_("Cursor Y position"),
_("Compare the Y position of the cursor or of a touch."),
_("the cursor Y position"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddCondition("SourisBouton",
_("Mouse button pressed or touch held"),
_("Check if the specified mouse button is pressed or "
_("Return true if the specified mouse button is pressed or "
"if a touch is in contact with the screen."),
_("Touch or _PARAM1_ mouse button is down"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed")
.SetHidden();
extension
.AddCondition("MouseButtonReleased",
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.AddParameter("mouse", _("Button to test"))
.MarkAsSimple();
extension
.AddCondition(
"MouseButtonFromTextPressed",
_("Mouse button pressed or touch held (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, is pressed."),
_("_PARAM1_ mouse button is pressed"),
"",
"MouseButtonReleased",
_("Mouse button released"),
_("Return true if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
.AddParameter("mouse", _("Button to test"))
.MarkAsSimple();
extension
.AddCondition(
"MouseButtonFromTextReleased",
_("Mouse button released (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, was just released."),
_("_PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
extension
.AddExpressionAndCondition("number",
"TouchX",
_("Touch X position"),
_("the X position of a specific touch"),
_("the touch #_PARAM1_ X position"),
_("Multitouch"),
"res/conditions/touch24.png")
.AddCondition("TouchX",
_("Touch X position"),
_("Compare the X position of a specific touch."),
_("the touch #_PARAM1_ X position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpressionAndCondition("number",
"TouchY",
_("Touch Y position"),
_("the Y position of a specific touch"),
_("the touch #_PARAM1_ Y position"),
_("Multitouch"),
"res/conditions/touch24.png")
.AddCondition("TouchY",
_("Touch Y position"),
_("Compare the Y position of a specific touch."),
_("the touch #_PARAM1_ Y position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
@@ -302,95 +235,123 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition(
"PopStartedTouch",
_("A new touch has started"),
_("Check if a touch has started. The touch identifier can be "
_("Return true if a touch has started. The touch identifier can be "
"accessed using LastTouchId().\nAs more than one touch can be "
"started, this condition is only true once for each touch: the "
"next time you use it, it will be for a new touch, or it will "
"return false if no more touches have just started."),
_("A new touch has started"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
extension
.AddCondition(
"PopEndedTouch",
_("A touch has ended"),
_("Check if a touch has ended. The touch identifier can be "
_("Return true if a touch has ended. The touch identifier can be "
"accessed using LastEndedTouchId().\nAs more than one touch can be "
"ended, this condition is only true once for each touch: the next "
"time you use it, it will be for a new touch, or it will return "
"false if no more touches have just ended."),
_("A touch has ended"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("MouseX",
_("Cursor X position"),
_("Cursor X position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("SourisX",
_("Cursor X position"),
_("Cursor X position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0")
.SetHidden();
extension
.AddCondition(
"HasAnyTouchStarted",
_("A new touch has started"),
_("Check if a touch has just started on this frame. The touch identifiers can be "
"accessed using StartedTouchId() and StartedTouchCount()."),
_("A new touch has started"),
_("Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchCount",
_("Started touch count"),
_("The number of touches that have just started on this frame. The touch identifiers can be "
"accessed using StartedTouchId()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchId",
_("Started touch identifier"),
_("The identifier of the touch that has just started on this frame. The touch number of touches can be "
"accessed using StartedTouchCount()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddExpression("MouseY",
_("Cursor Y position"),
_("Cursor Y position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch index"));
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddCondition(
"HasTouchEnded",
_("A touch has ended"),
_("Check if a touch has ended."),
_("The touch with identifier _PARAM1_ has ended"),
_("Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddExpression("SourisY",
_("Cursor Y position"),
_("Cursor Y position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"));
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0")
.SetHidden();
extension
.AddExpression("MouseWheelDelta",
_("Mouse wheel: Displacement"),
_("Mouse wheel displacement"),
_("Mouse and touch"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("TouchX",
_("Touch X position"),
_("Touch X position"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("TouchY",
_("Touch Y position"),
_("Touch Y position"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("LastTouchId",
_("Identifier of the last touch"),
_("Identifier of the last touch"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("LastEndedTouchId",
@@ -398,8 +359,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Identifier of the last ended touch"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

@@ -14,118 +14,52 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
extension
.SetExtensionInformation(
"BuiltinNetwork",
_("Network"),
_("Features to send web requests, communicate with external \"APIs\" "
"and other network related tasks."),
_("Basic internet features"),
_("Built-in extension providing network features."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/network")
.SetCategory("Network");
extension.AddInstructionOrExpressionGroupMetadata(_("Network"))
.SetIcon("res/actions/net24.png");
.SetExtensionHelpPath("/all-features/network");
#if defined(GD_IDE_ONLY)
extension
.AddAction(
"SendRequest",
"Send a request to a web page",
"Send a request to the specified web page.\n\nPlease note that for "
"the web games, the game must be hosted on the same host "
"as specified below, except if the server is configured to answer "
"to all requests (cross-domain requests).",
"Send _PARAM3_ request to _PARAM0__PARAM1_ with body: _PARAM2_",
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", "Host, with protocol")
.SetParameterLongDescription("Example: \"http://example.com/\".")
.AddParameter("string", "Path")
.SetParameterLongDescription(
"Example: \"/user/123\" or \"/some-page.php\".")
.AddParameter("string", "Request body content")
.AddParameter("string", "Method: \"POST\" or \"GET\"", "", true)
.SetParameterLongDescription("If empty, \"GET\" will be used.")
.SetDefaultValue("\"GET\"")
.AddParameter("string", "Content type", "", true)
.SetParameterLongDescription(
"If empty, \"application/x-www-form-urlencoded\" will be used.")
.AddParameter("scenevar", "Reponse scene variable", "", true)
.SetParameterLongDescription(
"The response of the server will be stored, as a string, in this "
"variable. If the server returns *JSON*, you may want to use the "
"action \"Convert JSON to a scene variable\" afterwards, to "
"explore the results with a *structure variable*.")
.MarkAsComplex()
.SetHidden();
extension
.AddAction(
"SendAsyncRequest",
_("Send a request to a web page"),
_("Send an asynchronous request to the specified web page.\n\nPlease "
"note that for "
_("Send a request to the specified web page.\n\nPlease note that for "
"the web games, the game must be hosted on the same host "
"as specified below, except if the server is configured to answer "
"to all requests (cross-domain requests)."),
_("Send a _PARAM2_ request to _PARAM0_ with body: _PARAM1_, and "
"store the result in _PARAM4_ (or in _PARAM5_ in case of error)"),
"",
_("Send _PARAM3_ request to _PARAM0__PARAM1_ with body: _PARAM2_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (API or web-page address)"))
.AddParameter("string", _("Host, with protocol"))
.SetParameterLongDescription(
_("Example: \"https://example.com/user/123\". Using *https* is "
"highly recommended."))
_("Example: \"http://example.com/\"."))
.AddParameter("string", _("Path"))
.SetParameterLongDescription(_("Example: \"/user/123\" or \"/some-page.php\"."))
.AddParameter("string", _("Request body content"))
.AddParameter("stringWithSelector",
_("Request method"),
"[\"GET\", \"POST\", \"PUT\", \"HEAD\", \"DELETE\", "
"\"PATCH\", \"OPTIONS\"]",
false)
.AddParameter("string", _("Method: \"POST\" or \"GET\""), "", true)
.SetParameterLongDescription(_("If empty, \"GET\" will be used."))
.SetDefaultValue("\"GET\"")
.AddParameter("string", _("Content type"), "", true)
.SetParameterLongDescription(
_("If empty, \"application/x-www-form-urlencoded\" will be used."))
.AddParameter(
"scenevar", _("Variable where to store the response"), "", true)
.AddParameter("scenevar", _("Reponse scene variable"), "", true)
.SetParameterLongDescription(
_("The response of the server will be stored, as a string, in this "
"variable. If the server returns *JSON*, you may want to use the "
"action \"Convert JSON to a scene variable\" afterwards, to "
"explore the results with a *structure variable*."))
.AddParameter(
"scenevar", _("Variable where to store the error message"), "", true)
.SetParameterLongDescription(_(
"Optional, only used if an error occurs. This will contain the "
"[\"status "
"code\"](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) "
"if the server returns a status >= 400. If the request was not sent "
"at all (e.g. no internet or CORS issues), the variable will be set "
"to "
"\"REQUEST_NOT_SENT\"."))
.MarkAsComplex();
extension
.AddAction("LaunchFile",
_("Open a URL (web page) or a file"),
_("This action launches the specified file or URL, in a "
"browser (or in a new tab if the game is using the Web "
"platform and is launched inside a browser)."),
_("Open URL _PARAM0_ in a browser (or new tab)"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (or filename)"))
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension
.AddAction(
"DownloadFile",
_("Download a file"),
_("Download a file from a web site"),
_("Download file _PARAM1_ from _PARAM0_ under the name of _PARAM2_"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("Host (for example : http://www.website.com)"))
@@ -135,19 +69,71 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
extension
.AddAction(
"EnableMetrics",
_("Enable (or disable) metrics collection"),
_("Enable, or disable, the sending of anonymous data used to compute "
"the number of sessions and other metrics from your game "
"players.\nBe sure to only send metrics if in accordance with the "
"terms of service of your game and if they player gave their "
"consent, depending on how your game/company handles this."),
_("Enable analytics metrics: _PARAM1_"),
"",
"JSONToVariableStructure",
_("Convert JSON to a scene variable"),
_("Parse a JSON object and store it into a scene variable"),
_("Parse JSON string _PARAM0_ and store it into variable _PARAM1_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Enable the metrics?"));
.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"),
_("Parse JSON string _PARAM0_ and store it into global "
"variable _PARAM1_"),
_("Network"),
"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_"),
_("Network"),
"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();
extension
.AddStrExpression("ToJSON",
_("Convert scene variable to JSON"),
_("Convert a scene variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("scenevar", _("Scene variable to be stringified"));
extension
.AddStrExpression("GlobalVarToJSON",
_("Convert global variable to JSON"),
_("Convert a global variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("globalvar", _("The global variable to be stringified"));
extension
.AddStrExpression("ObjectVarToJSON",
_("Convert object variable to JSON"),
_("Convert an object variable to JSON"),
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified"));
#endif
}
} // namespace gd

View File

@@ -14,19 +14,68 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
extension
.SetExtensionInformation(
"BuiltinScene",
_("Scene"),
_("Actions and conditions to manipulate the scenes during the game."),
_("Scene management features"),
_("Built-in extension allowing to manipulate scenes and providing common features"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Scene"))
.SetIcon("res/conditions/depart24.png");
#if defined(GD_IDE_ONLY)
extension
.AddExpression("Random",
_("Random integer"),
_("Random integer"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomInRange",
_("Random integer in range"),
_("Random integer in range"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloat",
_("Random float"),
_("Random float"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomFloatInRange",
_("Random float in range"),
_("Random float in range"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"));
extension
.AddExpression("RandomWithStep",
_("Random value in steps"),
_("Random value in steps"),
_("Random"),
"res/actions/position.png")
.SetHelpPath("/all-features/expressions")
.AddParameter("expression", _("Minimum value"))
.AddParameter("expression", _("Maximum value"))
.AddParameter("expression", _("Step"));
extension
.AddStrExpression("CurrentSceneName",
_("Current scene name"),
_("Name of the current scene"),
"",
_("Scene"),
"res/actions/texte.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -35,7 +84,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("At the beginning of the scene"),
_("Is true only when scene just begins."),
_("At the beginning of the scene"),
"",
_("Scene"),
"res/conditions/depart24.png",
"res/conditions/depart.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -47,7 +96,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Scene just resumed"),
_("The scene has just resumed after being paused."),
_("Scene just resumed"),
"",
_("Scene"),
"res/conditions/depart24.png",
"res/conditions/depart.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -59,7 +108,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Change the scene"),
_("Stop this scene and start the specified one instead."),
_("Change to scene _PARAM1_"),
"",
_("Scene"),
"res/actions/replaceScene24.png",
"res/actions/replaceScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -76,7 +125,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
"can use the \"Stop and go back to previous scene\" action "
"to go back to this scene."),
_("Pause the scene and start _PARAM1_"),
"",
_("Scene"),
"res/actions/pushScene24.png",
"res/actions/pushScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -91,7 +140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Stop this scene and go back to the previous paused one.\nTo pause "
"a scene, use the \"Pause and start a new scene\" action."),
_("Stop the scene and go back to the previous paused one"),
"",
_("Scene"),
"res/actions/popScene24.png",
"res/actions/popScene.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -103,7 +152,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Quit the game"),
_("Quit the game"),
_("Quit the game"),
"",
_("Scene"),
"res/actions/quit24.png",
"res/actions/quit.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -115,7 +164,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("Change background color"),
_("Change the background color of the scene."),
_("Set background color to _PARAM1_"),
"",
_("Scene"),
"res/actions/background24.png",
"res/actions/background.png")
.SetHelpPath("/interface/scene-editor/events")
@@ -129,13 +178,42 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
_("mouse buttons must be taken "
"into account even\nif the window is not active."),
_("Disable input when focus is lost: _PARAM1_"),
"",
_("Scene"),
"res/actions/window24.png",
"res/actions/window.png")
.SetHelpPath("/interface/scene-editor/events")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Deactivate input when focus is lost"))
.MarkAsAdvanced();
extension
.AddCondition("Egal",
_("Compare two numbers"),
_("Compare the two numbers."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
_("Other"),
"res/conditions/egal24.png",
"res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("expression", _("First expression"))
.AddParameter("relationalOperator", _("Sign of the test"))
.AddParameter("expression", _("Second expression"))
.MarkAsAdvanced();
extension
.AddCondition("StrEqual",
_("Compare two strings"),
_("Compare the two strings."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
_("Other"),
"res/conditions/egal24.png",
"res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("string", _("First string expression"))
.AddParameter("relationalOperator", _("Sign of the test"))
.AddParameter("string", _("Second string expression"))
.MarkAsAdvanced();
#endif
}
} // namespace gd

View File

@@ -4,10 +4,8 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include <iostream>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Serialization/SerializerElement.h"
@@ -23,7 +21,7 @@ Direction::~Direction(){};
void Direction::SetLoop(bool loop_) { loop = loop_; }
void Direction::SetTimeBetweenFrames(double time) { timeBetweenFrame = time; }
void Direction::SetTimeBetweenFrames(float time) { timeBetweenFrame = time; }
void Direction::AddSprite(const Sprite& sprite) { sprites.push_back(sprite); }
@@ -31,15 +29,6 @@ const Sprite& Direction::GetSprite(std::size_t nb) const { return sprites[nb]; }
Sprite& Direction::GetSprite(std::size_t nb) { return sprites[nb]; }
const std::vector<gd::String>& Direction::GetSpriteNames() const {
static std::vector<gd::String> spriteNames;
spriteNames.clear();
for (std::size_t i = 0; i < sprites.size(); ++i) {
spriteNames.push_back(sprites[i].GetImageName());
}
return spriteNames;
}
void Direction::RemoveSprite(std::size_t index) {
if (index < sprites.size()) sprites.erase(sprites.begin() + index);
}
@@ -86,9 +75,11 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
SetTimeBetweenFrames(
element.GetDoubleAttribute("timeBetweenFrames", 1, "tempsEntre"));
SetLoop(element.GetBoolAttribute("looping", false, "boucle"));
#if defined(GD_IDE_ONLY)
SetMetadata(element.HasAttribute("metadata") || element.HasChild("metadata")
? element.GetStringAttribute("metadata")
: "");
#endif
const gd::SerializerElement& spritesElement =
element.GetChild("sprites", 0, "Sprites");
@@ -132,7 +123,7 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
polygonElement.GetChild(k);
polygon.vertices.push_back(
gd::Vector2f(verticeElement.GetDoubleAttribute("x"),
sf::Vector2f(verticeElement.GetDoubleAttribute("x"),
verticeElement.GetDoubleAttribute("y")));
}
@@ -144,6 +135,7 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
}
};
#if defined(GD_IDE_ONLY)
void SavePoint(const Point& point, gd::SerializerElement& element) {
element.SetAttribute("name", point.GetName());
element.SetAttribute("x", point.GetX());
@@ -198,5 +190,6 @@ void Direction::SerializeTo(gd::SerializerElement& element) const {
if (!GetMetadata().empty()) element.SetAttribute("metadata", GetMetadata());
SaveSpritesDirection(sprites, element.AddChild("sprites"));
}
#endif
} // namespace gd

View File

@@ -43,14 +43,14 @@ class GD_CORE_API Direction {
/**
* \brief Get the time between each sprite
*/
inline double GetTimeBetweenFrames() const { return timeBetweenFrame; }
inline float GetTimeBetweenFrames() const { return timeBetweenFrame; }
/**
* \brief Set the time between each sprite
*
* \param time Time between each sprite, in seconds.
*/
void SetTimeBetweenFrames(double time);
void SetTimeBetweenFrames(float time);
/**
* \brief Return a reference to a sprite of the direction.
@@ -72,13 +72,6 @@ class GD_CORE_API Direction {
*/
Sprite& GetSprite(std::size_t nb);
/**
* \brief Return a vector of references to sprite names.
*
* \return A vector of all sprite names references.
*/
const std::vector<gd::String>& GetSpriteNames() const;
/**
* \brief Check if the direction contains sprites.
*
@@ -120,6 +113,7 @@ class GD_CORE_API Direction {
*/
void MoveSprite(std::size_t oldIndex, std::size_t newIndex);
#if defined(GD_IDE_ONLY)
/**
* \brief Set the metadata (any string) associated to the Direction.
* \note Can be used by external editors to store extra information.
@@ -130,15 +124,20 @@ class GD_CORE_API Direction {
* \brief Return the (optional) metadata associated to the Direction.
*/
virtual const gd::String& GetMetadata() const { return metadata; }
#endif
void UnserializeFrom(const gd::SerializerElement& element);
#if defined(GD_IDE_ONLY)
void SerializeTo(gd::SerializerElement& element) const;
#endif
private:
bool loop; ///< true if the animation must loop.
double timeBetweenFrame; ///< The time between each sprite of the animation.
float timeBetweenFrame; ///< The time between each sprite of the animation.
std::vector<Sprite> sprites; ///< The sprites of the direction.
#if defined(GD_IDE_ONLY)
gd::String metadata;
#endif
};
} // namespace gd

View File

@@ -4,7 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "Polygon2d.h"
#include "GDCore/Vector2.h"
#include <SFML/System/Vector2.hpp>
#include <cmath>
#include <iostream>
@@ -28,7 +28,7 @@ void Polygon2d::Move(float x, float y) {
}
void Polygon2d::ComputeEdges() const {
gd::Vector2f v1, v2;
sf::Vector2f v1, v2;
edges.clear();
for (std::size_t i = 0; i < vertices.size(); i++) {
@@ -62,8 +62,8 @@ bool Polygon2d::IsConvex() const {
return true;
}
gd::Vector2f Polygon2d::ComputeCenter() const {
gd::Vector2f center;
sf::Vector2f Polygon2d::ComputeCenter() const {
sf::Vector2f center;
for (std::size_t i = 0; i < vertices.size(); i++) {
center.x += vertices[i].x;
@@ -77,10 +77,10 @@ gd::Vector2f Polygon2d::ComputeCenter() const {
Polygon2d Polygon2d::CreateRectangle(float width, float height) {
Polygon2d rect;
rect.vertices.push_back(gd::Vector2f(-width / 2.0f, -height / 2.0f));
rect.vertices.push_back(gd::Vector2f(+width / 2.0f, -height / 2.0f));
rect.vertices.push_back(gd::Vector2f(+width / 2.0f, +height / 2.0f));
rect.vertices.push_back(gd::Vector2f(-width / 2.0f, +height / 2.0f));
rect.vertices.push_back(sf::Vector2f(-width / 2.0f, -height / 2.0f));
rect.vertices.push_back(sf::Vector2f(+width / 2.0f, -height / 2.0f));
rect.vertices.push_back(sf::Vector2f(+width / 2.0f, +height / 2.0f));
rect.vertices.push_back(sf::Vector2f(-width / 2.0f, +height / 2.0f));
return rect;
}

View File

@@ -5,7 +5,7 @@
*/
#ifndef GDCORE_POLYGON_H
#define GDCORE_POLYGON_H
#include "GDCore/Vector2.h"
#include <SFML/System/Vector2.hpp>
#include <vector>
/**
@@ -22,19 +22,19 @@ class GD_CORE_API Polygon2d {
Polygon2d(){};
virtual ~Polygon2d(){};
std::vector<gd::Vector2f> vertices; ///< The vertices composing the polygon
mutable std::vector<gd::Vector2f>
std::vector<sf::Vector2f> vertices; ///< The vertices composing the polygon
mutable std::vector<sf::Vector2f>
edges; ///< Edges. Can be computed from vertices using ComputeEdges()
/**
* \brief Get the vertices composing the polygon.
*/
std::vector<gd::Vector2f>& GetVertices() { return vertices; }
std::vector<sf::Vector2f>& GetVertices() { return vertices; }
/**
* \brief Get the vertices composing the polygon.
*/
const std::vector<gd::Vector2f>& GetVertices() const { return vertices; }
const std::vector<sf::Vector2f>& GetVertices() const { return vertices; }
/**
* \brief Moves each vertices from the given amount.
@@ -68,7 +68,7 @@ class GD_CORE_API Polygon2d {
/**
* \brief Return the position of the center of the polygon
*/
gd::Vector2f ComputeCenter() const;
sf::Vector2f ComputeCenter() const;
/** \name Tools
* Tool functions

View File

@@ -4,8 +4,10 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include <SFML/Graphics/Sprite.hpp>
#include <iostream>
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
#include "GDCore/Project/ImageManager.h"
using namespace std;
@@ -14,7 +16,11 @@ namespace gd {
Point Sprite::badPoint("");
Sprite::Sprite()
: automaticCollisionMask(true),
:
#if !defined(EMSCRIPTEN)
hasItsOwnImage(false),
#endif
automaticCollisionMask(true),
origine("origine"),
centre("centre"),
automaticCentre(true) {
@@ -67,10 +73,36 @@ Point& Sprite::GetPoint(const gd::String& name) {
bool Sprite::SetDefaultCenterPoint(bool enabled) {
automaticCentre = enabled;
#if !defined(EMSCRIPTEN)
if (automaticCentre)
centre.SetXY(sfmlSprite.getLocalBounds().width / 2,
sfmlSprite.getLocalBounds().height / 2);
#endif
return true;
}
std::vector<Polygon2d> Sprite::GetCollisionMask() const {
// TODO(perf): Cache to avoid re-creating a mask at every call
#if !defined(EMSCRIPTEN)
if (automaticCollisionMask) {
std::vector<Polygon2d> mask;
Polygon2d rectangle;
rectangle.vertices.push_back(sf::Vector2f(0, 0));
rectangle.vertices.push_back(
sf::Vector2f(sfmlSprite.getLocalBounds().width, 0));
rectangle.vertices.push_back(sf::Vector2f(
sfmlSprite.getLocalBounds().width, sfmlSprite.getLocalBounds().height));
rectangle.vertices.push_back(
sf::Vector2f(0, sfmlSprite.getLocalBounds().height));
mask.push_back(rectangle);
return mask;
}
#endif
return customCollisionMask;
}
@@ -79,4 +111,25 @@ void Sprite::SetCustomCollisionMask(
customCollisionMask = collisionMask;
}
#if !defined(EMSCRIPTEN)
void Sprite::LoadImage(std::shared_ptr<SFMLTextureWrapper> image_) {
sfmlImage = image_;
sfmlSprite.setTexture(sfmlImage->texture, true);
hasItsOwnImage = false;
if (automaticCentre)
centre.SetXY(sfmlSprite.getLocalBounds().width / 2,
sfmlSprite.getLocalBounds().height / 2);
}
void Sprite::MakeSpriteOwnsItsImage() {
if (!hasItsOwnImage || sfmlImage == std::shared_ptr<SFMLTextureWrapper>()) {
sfmlImage = std::make_shared<SFMLTextureWrapper>(
sfmlImage->texture); // Copy the texture.
sfmlSprite.setTexture(sfmlImage->texture);
hasItsOwnImage = true;
}
}
#endif
} // namespace gd

View File

@@ -6,10 +6,12 @@
#ifndef SPRITE_H
#define SPRITE_H
#include <SFML/Graphics/Sprite.hpp>
#include <memory>
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
#include "GDCore/String.h"
class SFMLTextureWrapper;
#undef LoadImage // prevent windows.h to be polluting everything
namespace gd {
@@ -17,6 +19,9 @@ namespace gd {
/**
* \brief Represents a sprite to be displayed on the screen.
*
* A sprite contains a SFML sprite to be displayed, some points,
* and can also have its own texture (rather than a texture from ImageManager).
*
* \see Direction
* \see SpriteObject
* \ingroup SpriteObjectExtension
@@ -158,7 +163,53 @@ class GD_CORE_API Sprite {
*/
bool SetDefaultCenterPoint(bool enabled);
#if !defined(EMSCRIPTEN)
/** \name Sprite runtime management
* Functions used by the C++ game engine.
*/
///@{
/**
* \brief Get the SFML sprite associated with the sprite
*/
inline const sf::Sprite& GetSFMLSprite() const { return sfmlSprite; }
/**
* \brief Get the SFML sprite associated with the sprite
*/
inline sf::Sprite& GetSFMLSprite() { return sfmlSprite; }
/**
* \brief Set the SFML texture of the sprite
*/
void LoadImage(std::shared_ptr<SFMLTextureWrapper> image);
/**
* \brief Get SFML texture used by the sprite
*/
std::shared_ptr<SFMLTextureWrapper> GetSFMLTexture() { return sfmlImage; };
/**
* \brief Get SFML texture used by the sprite
*/
const std::shared_ptr<SFMLTextureWrapper> GetSFMLTexture() const {
return sfmlImage;
};
/**
* \brief Make the sprite, if it uses a texture from ImageManager,
* copy this texture and take ownership of it.
*/
void MakeSpriteOwnsItsImage();
///@}
#endif
private:
#if !defined(EMSCRIPTEN)
sf::Sprite sfmlSprite; ///< Displayed SFML sprite
std::shared_ptr<SFMLTextureWrapper>
sfmlImage; ///< Pointer to the image displayed by the sprite.
bool hasItsOwnImage; ///< True if sfmlImage is only owned by this Sprite.
#endif
gd::String image; ///< Name of the image to be loaded in Image Manager.
bool automaticCollisionMask; ///< True to use the custom collision mask.

View File

@@ -23,15 +23,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Open source (MIT License)")
.SetExtensionHelpPath("/objects/sprite");
gd::ObjectMetadata& obj =
extension
.AddObject<SpriteObject>("Sprite",
_("Sprite"),
_("Animated object which can be used for "
"most elements of a game"),
"CppPlatform/Extensions/spriteicon.png")
.SetCategoryFullName(_("General"));
gd::ObjectMetadata& obj = extension.AddObject<SpriteObject>(
"Sprite",
_("Sprite"),
_("Animated object which can be used for most elements of a game"),
"CppPlatform/Extensions/spriteicon.png");
#if defined(GD_IDE_ONLY)
obj.AddAction("Opacity",
_("Change sprite opacity"),
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
@@ -68,7 +66,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectAnimationName", _("Animation name"))
.AddParameter("string", _("Animation name"))
.MarkAsAdvanced();
obj.AddAction(
@@ -81,8 +79,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
"res/actions/direction24.png",
"res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
@@ -136,9 +133,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.MarkAsSimple();
obj.AddAction("TourneVersPos",
"Rotate an object toward a position",
"Rotate an object towards a position.",
"Rotate _PARAM0_ towards _PARAM1_;_PARAM2_",
_("Rotate an object toward a position"),
_("Rotate an object towards a position."),
_("Rotate _PARAM0_ towards _PARAM1_;_PARAM2_"),
_("Direction"),
"res/actions/direction24.png",
"res/actions/direction.png")
@@ -199,18 +196,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("Width",
_("Width"),
_("Compare the width of a Sprite object."),
_("the width"),
_("Size"),
"res/conditions/scaleWidth24.png",
"res/conditions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeHeight",
_("Height"),
_("Change the height of a Sprite object."),
@@ -223,31 +208,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("Height",
_("Height"),
_("Compare the height of a Sprite object."),
_("the height"),
_("Size"),
"res/conditions/scaleHeight24.png",
"res/conditions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("SetSize",
_("Size"),
_("Change the size of an object."),
_("Change the size of _PARAM0_: set to _PARAM1_x_PARAM2_"),
_("Size"),
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Width"))
.AddParameter("expression", _("Height"))
.MarkAsAdvanced();
obj.AddCondition(
"Animation",
_("Current animation"),
@@ -270,7 +230,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectAnimationName", _("Animation name"))
.AddParameter("string", _("Animation name"))
.MarkAsAdvanced();
obj.AddCondition(
@@ -283,16 +243,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
"res/conditions/direction24.png",
"res/conditions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters("number");
obj.AddCondition("Sprite",
_("Current frame"),
_("Compare the index of the current frame in the animation "
"displayed by the specified object. The first frame in an "
"animation starts at index 0."),
_("Compare the index of the current frame in the animation displayed by the specified object. The first frame in an animation starts at index 0."),
_("the animation frame"),
_("Animations and images"),
"res/conditions/sprite24.png",
@@ -375,16 +332,50 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeColor",
_("Tint color"),
_("Change the tint of an object. The default color is white."),
_("Change tint of _PARAM0_ to _PARAM1_"),
obj.AddAction("CopyImageOnImageOfSprite",
_("Copy an image on the current one of an object"),
_("Copy an image on the current image of an object.\nNote that "
"the source image must be preferably kept loaded in memory."),
_("Copy image _PARAM2_ on the current of _PARAM0_ at "
"_PARAM3_;_PARAM4_"),
_("Effects"),
"res/actions/color24.png",
"res/actions/color.png")
"res/copy24.png",
"res/copyicon.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Tint"));
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Name of the source image"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter(
"yesorno",
_("Should the copy take in account the source transparency\?"));
obj.AddAction(
"CreateMaskFromColorOnActualImage", // Actual is indeed a mistake :
// Current should have been
// chosen.
_("Make a color of the image of an object transparent"),
_("Make a color of the image of an object transparent."),
_("Make color _PARAM1_ of the current image of _PARAM0_ transparent"),
_("Effects"),
"res/actions/opacity24.png",
"res/actions/opacity.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Color to make transparent"));
obj.AddAction(
"ChangeColor",
_("Global color"),
_("Change the global color of an object. The default color is white."),
_("Change color of _PARAM0_ to _PARAM1_"),
_("Effects"),
"res/actions/color24.png",
"res/actions/color.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Color"));
obj.AddAction("ChangeBlendMode",
_("Blend mode"),
@@ -403,7 +394,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddAction("FlipX",
_("Flip the object horizontally"),
_("Flip the object horizontally"),
_("Flip horizontally _PARAM0_: _PARAM1_"),
_("Flip horizontally _PARAM0_ : _PARAM1_"),
_("Effects"),
"res/actions/flipX24.png",
"res/actions/flipX.png")
@@ -415,7 +406,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddAction("FlipY",
_("Flip the object vertically"),
_("Flip the object vertically"),
_("Flip vertically _PARAM0_: _PARAM1_"),
_("Flip vertically _PARAM0_ : _PARAM1_"),
_("Effects"),
"res/actions/flipY24.png",
"res/actions/flipY.png")
@@ -426,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddCondition("FlippedX",
_("Horizontally flipped"),
_("Check if the object is horizontally flipped"),
_("Return true if the object is horizontally flipped"),
_("_PARAM0_ is horizontally flipped"),
_("Effects"),
"res/actions/flipX24.png",
@@ -436,7 +427,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddCondition("FlippedY",
_("Vertically flipped"),
_("Check if the object is vertically flipped"),
_("Return true if the object is vertically flipped"),
_("_PARAM0_ is vertically flipped"),
_("Effects"),
"res/actions/flipY24.png",
@@ -445,15 +436,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("object", _("Object"), "Sprite");
obj.AddAction("TourneVers",
"Rotate an object toward another",
"Rotate an object towards another.",
"Rotate _PARAM0_ towards _PARAM1_",
_("Rotate an object toward another"),
_("Rotate an object towards another."),
_("Rotate _PARAM0_ towards _PARAM1_"),
_("Direction"),
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPtr", "Rotate toward this object")
.AddParameter("object", _("Object to be rotated"), "Sprite")
.AddParameter("objectPtr", _("Rotate toward this object"))
.AddCodeOnlyParameter("currentScene", "")
.SetHidden(); // Deprecated
@@ -464,7 +455,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
.AddParameter("string", _("Name of the point"), "", true);
obj.AddExpression("Y",
_("Y position of a point"),
@@ -473,7 +464,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
.AddParameter("string", _("Name of the point"), "", true);
obj.AddExpression("PointX",
_("X position of a point"),
@@ -482,7 +473,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
.AddParameter("string", _("Name of the point"));
obj.AddExpression("PointY",
_("Y position of a point"),
@@ -491,7 +482,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
.AddParameter("string", _("Name of the point"));
obj.AddExpression("Direc",
_("Direction"),
@@ -506,8 +497,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction of the object"),
_("Direction"),
"res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Anim",
@@ -579,6 +568,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("objectList", _("Object 1"), "Sprite")
.AddParameter("objectList", _("Object 2"), "Sprite")
.AddCodeOnlyParameter("conditionInverted", "");
#endif
}
} // namespace gd

View File

@@ -4,23 +4,26 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include <algorithm>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
#include "GDCore/Project/ImageManager.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
#if defined(GD_IDE_ONLY)
#include <SFML/Graphics.hpp>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#endif
namespace gd {
Animation SpriteObject::badAnimation;
@@ -79,6 +82,7 @@ void SpriteObject::DoUnserializeFrom(gd::Project& project,
}
}
#if defined(GD_IDE_ONLY)
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
@@ -103,8 +107,7 @@ void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
}
}
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
const {
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties() const {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Animate even if hidden or far from the screen")]
.SetValue(updateIfNotVisible ? "true" : "false")
@@ -136,33 +139,29 @@ void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
}
std::map<gd::String, gd::PropertyDescriptor>
SpriteObject::GetInitialInstanceProperties(
const gd::InitialInstance& initialInstance,
gd::Project& project,
gd::Layout& scene) {
SpriteObject::GetInitialInstanceProperties(const gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties["animation"] =
gd::PropertyDescriptor(
gd::String::From(initialInstance.GetRawDoubleProperty("animation")))
.SetLabel(_("Animation"))
.SetType("number");
properties[_("Animation")] =
position.floatInfos.find("animation") != position.floatInfos.end()
? gd::String::From(position.floatInfos.find("animation")->second)
: gd::String("0");
return properties;
}
bool SpriteObject::UpdateInitialInstanceProperty(
gd::InitialInstance& initialInstance,
const gd::String& name,
const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == "animation") {
initialInstance.SetRawDoubleProperty(
"animation", std::max(0, value.empty() ? 0 : value.To<int>()));
}
bool SpriteObject::UpdateInitialInstanceProperty(gd::InitialInstance& position,
const gd::String& name,
const gd::String& value,
gd::Project& project,
gd::Layout& scene) {
if (name == _("Animation"))
position.floatInfos["animation"] = value.To<int>();
return true;
}
#endif
const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
if (nb >= animations.size()) return badAnimation;

View File

@@ -16,6 +16,7 @@ class Object;
class Layout;
class Sprite;
class Animation;
class MainFrameWrapper;
class SerializerElement;
class PropertyDescriptor;
} // namespace gd
@@ -44,6 +45,7 @@ class GD_CORE_API SpriteObject : public gd::Object {
return gd::make_unique<SpriteObject>(*this);
}
#if defined(GD_IDE_ONLY)
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
@@ -59,6 +61,7 @@ class GD_CORE_API SpriteObject : public gd::Object {
const gd::String& value,
gd::Project& project,
gd::Layout& scene) override;
#endif
/** \name Animations
* Methods related to animations management
@@ -116,24 +119,14 @@ class GD_CORE_API SpriteObject : public gd::Object {
* animation of the object.
*/
const std::vector<Animation>& GetAllAnimations() const { return animations; }
/**
* \brief Set if the object animation should be played even if the object is hidden
* or far from the camera.
*/
void SetUpdateIfNotVisible(bool updateIfNotVisible_) { updateIfNotVisible = updateIfNotVisible_; }
/**
* \brief Check if the object animation should be played even if the object is hidden
* or far from the camera (false by default).
*/
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
///@}
private:
void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) override;
#if defined(GD_IDE_ONLY)
void DoSerializeTo(gd::SerializerElement& element) const override;
#endif
mutable std::vector<Animation> animations;
bool updateIfNotVisible; ///< If set to true, ask the game engine to play

View File

@@ -16,24 +16,24 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.SetExtensionInformation(
"BuiltinStringInstructions",
_("Text manipulation"),
"Provides expressions to manipulate strings (also called texts).",
_("Built-in extension providing expressions for manipulating text "
"objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Text manipulation"))
.SetIcon("res/actions/text24.png");
#if defined(GD_IDE_ONLY)
extension.AddStrExpression("NewLine",
_("Insert a new line"),
_("Insert a new line"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png");
extension
.AddStrExpression("FromCodePoint",
_("Get character from code point"),
_("Get character from code point"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Code point"));
@@ -42,7 +42,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToUpperCase",
_("Uppercase a text"),
_("Uppercase a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -51,7 +51,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToLowerCase",
_("Lowercase a text"),
_("Lowercase a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -60,7 +60,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("SubStr",
_("Get a portion of a text"),
_("Get a portion of a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
@@ -73,7 +73,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrAt",
_("Get a character from a text"),
_("Get a character from a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
@@ -85,7 +85,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrRepeat",
_("Repeat a text"),
_("Repeat a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to repeat"))
@@ -95,7 +95,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddExpression("StrLength",
_("Length of a text"),
_("Length of a text"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -105,7 +105,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text"),
_("Search in a text (return the position of the result or "
"-1 if not found)"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
@@ -113,25 +113,23 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression("StrRFind",
"Search in a text from the end",
"Search in a text from the end (return the position of "
"the result or -1 if not found)",
"",
_("Search in a text from the end"),
_("Search in a text from the end (return the position of "
"the result or -1 if not found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
.SetHidden(); // Deprecated, see StrFindLast instead.
.SetHidden(); // Deprecated, see StrFindLast instead.
extension
.AddExpression(
"StrFindLast",
_("Search the last occurence in a text"),
_("Search the last occurence in a string (return the position of "
"the result, from the beginning of the string, or -1 if not "
"found)"),
"",
"res/conditions/toujours24.png")
.AddExpression("StrFindLast",
_("Search the last occurence in a text"),
_("Search the last occurence in a string (return the position of "
"the result, from the beginning of the string, or -1 if not found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -141,7 +139,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text, starting from a position"),
_("Search in a text, starting from a position (return the "
"position of the result or -1 if not found)"),
"",
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
@@ -153,28 +151,26 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression(
"StrRFindFrom",
"Search in a text from the end, starting from a position",
"Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)",
"",
_("Search in a text from the end, starting from a position"),
_("Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
.AddParameter("expression",
"Position of the last character in the string to be "
"considered in the search")
.SetHidden(); // Deprecated, see StrFindLastFrom instead.
_("Position of the last character in the string to be "
"considered in the search"))
.SetHidden(); // Deprecated, see StrFindLastFrom instead.
extension
.AddExpression(
"StrFindLastFrom",
_("Search the last occurence in a text, starting from a position"),
_("Search in a text the last occurence, starting from a position "
"(return "
" the position of the result, from the beginning of the string, or "
"-1 if not found)"),
"",
_("Search in a text the last occurence, starting from a position (return "
" the position of the result, from the beginning of the string, or -1 if not found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
@@ -183,6 +179,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Position of the last character in the string to be "
"considered in the search"));
#endif
}
} // namespace gd

View File

@@ -12,56 +12,34 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation(
"BuiltinTime",
_("Timers and time"),
"Actions and conditions to run timers, get the current time or "
"modify the time scale (speed at which the game is running - useful "
"for slow motion effects).",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers-and-time");
extension.AddInstructionOrExpressionGroupMetadata(_("Timers and time"))
.SetIcon("res/conditions/timer24.png");
.SetExtensionInformation("BuiltinTime",
_("Time"),
_("Built-in extension providing actions and "
"conditions related to time."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers");
#if defined(GD_IDE_ONLY)
// Deprecated and replaced by CompareTimer
extension
.AddCondition("Timer",
_("Value of a scene timer"),
_("Test the elapsed time of a scene timer."),
_("The timer _PARAM2_ is greater than _PARAM1_ seconds"),
"",
_("Timers and time"),
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Time in seconds"))
.AddParameter("string", _("Timer's name"))
.SetHidden();
extension
.AddCondition("CompareTimer",
_("Value of a scene timer"),
_("Compare the elapsed time of a scene timer. This "
"condition doesn't start the timer."),
_("The timer _PARAM1_ _PARAM2_ _PARAM3_ seconds"),
"",
"res/conditions/timer24.png",
"res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Timer's name"))
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetManipulatedType("number");
.AddParameter("string", _("Timer's name"));
extension
.AddCondition("TimeScale",
_("Time scale"),
_("Compare the time scale of the scene."),
_("the time scale of the scene"),
"",
_("Test the time scale."),
_("the time scale"),
_("Timers and time"),
"res/conditions/time24.png",
"res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -73,8 +51,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Scene timer paused"),
_("Test if the specified scene timer is paused."),
_("The timer _PARAM1_ is paused"),
"",
_("Timers and time"),
"res/conditions/timerPaused24.png",
"res/conditions/timerPaused.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -87,9 +64,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Start (or reset) a scene timer"),
_("Reset the specified scene timer, if the timer doesn't exist "
"it's created and started."),
_("Start (or reset) the timer _PARAM1_"),
"",
_("Reset the timer _PARAM1_"),
_("Timers and time"),
"res/actions/timer24.png",
"res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -100,8 +76,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Pause a scene timer"),
_("Pause a scene timer."),
_("Pause timer _PARAM1_"),
"",
_("Timers and time"),
"res/actions/pauseTimer24.png",
"res/actions/pauseTimer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -113,8 +88,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Unpause a scene timer"),
_("Unpause a scene timer."),
_("Unpause timer _PARAM1_"),
"",
_("Timers and time"),
"res/actions/unPauseTimer24.png",
"res/actions/unPauseTimer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -126,8 +100,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
_("Delete a scene timer"),
_("Delete a scene timer from memory."),
_("Delete timer _PARAM1_ from memory"),
"",
_("Timers and time"),
"res/actions/timer24.png",
"res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -137,32 +110,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.AddAction("ChangeTimeScale",
_("Change time scale"),
_("Change the time scale of the scene."),
_("Set the time scale of the scene to _PARAM1_"),
"",
_("Change the time scale of the game."),
_("Set time scale to _PARAM1_"),
_("Timers and time"),
"res/actions/time24.png",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression",
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
extension
.AddAction("Wait",
_("Wait X seconds (experimental)"),
_("Waits a number of seconds before running "
"the next actions (and sub-events)."),
_("Wait _PARAM0_ seconds"),
"",
"res/timer.svg",
"res/timer.svg")
.AddParameter("expression", "Time to wait in seconds")
.SetHelpPath("/all-features/timers-and-time/wait-action");
extension
.AddExpression("TimeDelta",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -170,7 +131,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TempsFrame",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -179,7 +140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("ElapsedTime",
_("Time elapsed since the last frame"),
_("Time elapsed since the last frame rendered on screen"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -188,7 +149,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TimerElapsedTime",
_("Scene timer value"),
_("Value of a scene timer"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Timer's name"));
@@ -197,7 +158,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TimeFromStart",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -205,7 +166,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TempsDebut",
_("Time elapsed since the beginning of the scene"),
_("Time elapsed since the beginning of the scene"),
"",
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
@@ -213,16 +174,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.AddExpression("TimeScale",
_("Time scale"),
_("Returns the time scale of the scene."),
"",
_("Time scale"),
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("TimeScale",
_("Time scale"),
_("Time scale"),
_("Time"),
"res/actions/time.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("Time",
_("Current time"),
_("Current time"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter(
@@ -233,6 +203,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"timestamp\""),
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
"\"yday\", \"timestamp\"]");
#endif
}
} // namespace gd

View File

@@ -14,23 +14,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.SetExtensionInformation(
"BuiltinVariables",
_("Variables"),
"Actions, conditions and expressions to handle variables, from "
"simple variables like the player score, the number of remaining "
"lives to complex variables containing arbitrary data like an "
"inventory or the result of a web request.",
_("Variable features"),
_("Built-in extension allowing to manipulate variables"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/variables");
extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
.SetIcon("res/conditions/var24.png");
#if defined(GD_IDE_ONLY)
extension
.AddCondition("VarScene",
_("Value of a scene variable"),
_("Compare the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Scene variables"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -41,32 +37,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text of a scene variable"),
_("Compare the text of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("Scene variables"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters("string");
extension
.AddCondition(
"SceneVariableAsBoolean",
_("Boolean value of a scene variable"),
_("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true");
extension
.AddCondition(
"VariableChildExists",
_("Child existence"),
_("Check if the specified child of the scene variable exists."),
_("Return true if the specified child of the scene variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("Scene variables/Collections/Structures"),
_("Variables/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -76,10 +59,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("GlobalVariableChildExists",
_("Child existence"),
_("Check if the specified child of the global "
_("Return true if the specified child of the global "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("Global variables/Collections/Structures"),
_("Variables/Global variables/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -88,10 +71,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("VarSceneDef",
"Test if a scene variable is defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("Scene variables"),
_("Test if a scene variable is defined"),
_("Test if the scene variable exists."),
_("Scene variable _PARAM0_ is defined"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -103,7 +86,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Value of a global variable"),
_("Compare the value of a global variable."),
_("the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -111,36 +94,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.MarkAsAdvanced();
extension
.AddCondition("VarGlobalTxt",
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
_("Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCondition(
"VarGlobalTxt",
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddCondition(
"GlobalVariableAsBoolean",
_("Boolean value of a global variable"),
_("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true");
extension
.AddCondition("VarGlobalDef",
"Test if a global variable is defined",
"Test if a global variable exists",
"Global variable _PARAM0_ is defined",
_("Global variables"),
_("Test if a global variable is defined"),
_("Test if a global variable exists"),
_("Global variable _PARAM0_ is defined"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -151,9 +122,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddAction("ModVarScene",
_("Value of a scene variable"),
_("Change the value of a scene variable."),
_("Modify the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Scene variables"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -164,42 +135,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("String of a scene variable"),
_("Modify the text of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("Scene variables"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("string");
extension
.AddAction(
"SetSceneVariableAsBoolean",
_("Boolean value of a scene variable"),
_("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"));
extension
.AddAction("ToggleSceneVariableAsBoolean",
_("Toggle boolean value of a scene variable"),
_("Toggle the boolean value of a scene variable.") + "\n" +
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"),
_("Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"));
extension
.AddAction("ModVarGlobal",
_("Value of a global variable"),
_("Change the value of a global variable"),
_("Modify the value of a global variable"),
_("the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -207,47 +154,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.MarkAsAdvanced();
extension
.AddAction("ModVarGlobalTxt",
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddAction(
"ModVarGlobalTxt",
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddAction(
"SetGlobalVariableAsBoolean",
_("Boolean value of a global variable"),
_("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"));
extension
.AddAction("ToggleGlobalVariableAsBoolean",
_("Toggle boolean value of a global variable"),
_("Toggle the boolean value of a global variable.") + "\n" +
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of global variable _PARAM0_"),
_("Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"));
extension
.AddAction("VariableRemoveChild",
_("Remove a child"),
_("Remove a child from a scene variable."),
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
_("Scene variables/Collections/Structures"),
_("Variables/Structure"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -259,7 +183,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a global variable."),
_("Remove child _PARAM1_ from global variable _PARAM0_"),
_("Global variables/Collections/Structures"),
_("Variables/Global variables/Structure"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -271,7 +195,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear scene variable"),
_("Remove all the children from the scene variable."),
_("Clear children from scene variable _PARAM0_"),
_("Scene variables/Collections"),
_("Variables/Structure"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -282,149 +206,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear global variable"),
_("Remove all the children from the global variable."),
_("Clear children from global variable _PARAM0_"),
_("Global variables/Collections"),
_("Variables/Global variables/Structure"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePush",
_("Append variable to a scene array"),
_("Appends a variable at the end of a scene array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to append"))
.SetParameterLongDescription(_("The content of the variable will *be copied* and appended at the end of the array."))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushString",
_("Append a string to a scene array"),
_("Appends a string at the end of a scene array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushNumber",
_("Append a number to a scene array"),
_("Appends a number at the end of a scene array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushBool",
_("Append a boolean to a scene array"),
_("Appends a boolean at the end of a scene array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddAction(
"SceneVariableRemoveAt",
_("Remove variable from a scene array (by index)"),
_("Removes a variable at the specified index of a scene array variable."),
_("Remove variable at index _PARAM1_ from scene array variable _PARAM0_"),
_("Scene variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePush",
_("Append variable to a global array"),
_("Appends a variable at the end of a global array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to append"))
.SetParameterLongDescription(_("The content of the variable will *be copied* and appended at the end of the array."))
.MarkAsAdvanced();
extension
.AddAction(
"GlobalVariableRemoveAt",
_("Remove variable from a global array (by index)"),
_("Removes a variable at the specified index of a global array variable."),
_("Remove variable at index _PARAM1_ from global array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushString",
_("Append a string to a global array"),
_("Appends a string at the end of a global array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushNumber",
_("Append a number to a global array"),
_("Appends a number at the end of a global array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushBool",
_("Append a boolean to a global array"),
_("Appends a boolean at the end of a global array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddExpression("GlobalVariableChildCount",
_("Number of children of a global variable"),
_("Number of children of a global variable"),
_("Global variables"),
_("Get the number of children of a global variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
extension
.AddExpression("VariableChildCount",
_("Number of children of a scene variable"),
_("Number of children of a scene variable"),
_("Scene variables"),
_("Get the number of children of a scene variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -432,7 +232,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("Variable",
_("Value of a scene variable"),
_("Value of a scene variable"),
_("Scene variables"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -440,7 +240,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddStrExpression("VariableString",
_("Text of a scene variable"),
_("Text of a scene variable"),
_("Scene variables"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
@@ -448,7 +248,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddExpression("GlobalVariable",
_("Value of a global variable"),
_("Value of a global variable"),
_("Global variables"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable"));
@@ -456,9 +256,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddStrExpression("GlobalVariableString",
_("Text of a global variable"),
_("Text of a global variable"),
_("Global variables"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
#endif
}
} // namespace gd

View File

@@ -12,27 +12,22 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation(
"BuiltinWindow",
_("Game window and resolution"),
"Provides actions and conditions to manipulate the game window. "
"Depending on the platform on which the game is running, not all of "
"these features can be applied.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation("BuiltinWindow",
_("Window features"),
_("Built-in extension allowing to manipulate "
"the game window and canvas"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/window");
extension
.AddInstructionOrExpressionGroupMetadata(
_("Game window and resolution"))
.SetIcon("res/actions/window24.png");
#if defined(GD_IDE_ONLY)
extension
.AddAction(
"SetFullScreen",
_("De/activate fullscreen"),
_("This action activates or deactivates fullscreen."),
_("Activate fullscreen: _PARAM1_ (keep aspect ratio: _PARAM2_)"),
"",
_("Game's window and resolution"),
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -43,16 +38,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
true)
.SetDefaultValue("yes");
extension
.AddCondition("IsFullScreen",
_("Fullscreen activated?"),
_("Check if the game is currently in fullscreen."),
_("The game is in fullscreen"),
"",
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetWindowMargins",
_("Change the window's margins"),
@@ -60,7 +45,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"game frame and the window borders."),
_("Set margins of game window to "
"_PARAM1_;_PARAM2_;_PARAM3_;_PARAM4_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -76,7 +61,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"the game area size. This won't change the size of the "
"window in which the game is running."),
_("Set game resolution to _PARAM1_x_PARAM2_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -93,7 +78,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"window size. Game resolution can still be updated."),
_("Set game window size to _PARAM1_x_PARAM2_ (also update game "
"resolution: _PARAM3_)"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -110,7 +95,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"only works on Windows, macOS and Linux (not when the game "
"is executed in a web-browser or on iOS/Android)."),
_("Center the game window"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -122,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"should be changed to fit the game window - or if the game "
"resolution should not be updated automatically."),
_("Set game resolution resize mode to _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -143,7 +128,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"be the case if the game resolution resize mode is "
"configured to adapt the width or the height of the game."),
_("Automatically adapt the game resolution: _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -156,7 +141,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("Change the window's icon"),
_("This action changes the icon of the game's window."),
_("Use _PARAM1_ as the icon for the game's window."),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -167,7 +152,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("Change the window's title"),
_("This action changes the title of the game's window."),
_("Change window title to _PARAM1_"),
"",
_("Game's window and resolution"),
"res/actions/window24.png",
"res/actions/window.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -178,7 +163,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"SceneWindowWidth",
_("Width of the scene window"),
_("Width of the scene window (or scene canvas for HTML5 games)"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -187,7 +172,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"SceneWindowHeight",
_("Height of the scene window"),
_("Height of the scene window (or scene canvas for HTML5 games)"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -195,29 +180,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"ScreenWidth",
_("Width of the screen/page"),
_("Width of the screen (or the page for HTML5 games in browser)"),
"",
_("Screen"),
"res/display16.png");
extension.AddExpression(
"ScreenHeight",
_("Height of the screen/page"),
_("Height of the screen (or the page for HTML5 games in browser)"),
"",
_("Screen"),
"res/display16.png");
extension.AddExpression("ColorDepth",
_("Color depth"),
_("Color depth"),
"",
_("Screen"),
"res/display16.png");
extension
.AddStrExpression("WindowTitle",
_("Window's title"),
_("Window's title"),
"",
_("Screen"),
"res/window.png")
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

@@ -4,16 +4,12 @@
* reserved. This project is released under the MIT License.
*/
#include "BehaviorMetadata.h"
#include <iostream>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
@@ -151,16 +147,12 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
expressionsInfos[name] = ExpressionMetadata("number",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, behaviors expression do not have namespace ( not necessary as
// we refer to the auomatism name in the expression )
expressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
return expressionsInfos[name];
#endif
}
@@ -172,192 +164,16 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
strExpressionsInfos[name] = ExpressionMetadata("string",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, behaviors expression do not have namespace ( not necessary as
// we refer to the auomatism name in the expression )
strExpressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
return strExpressionsInfos[name];
#endif
}
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndCondition(expression,
condition);
}
gd::MultipleInstructionMetadata
BehaviorMetadata::AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
if (type != "number" && type != "string" && type != "boolean") {
gd::LogError(
"Unrecognised type passed to AddExpressionAndConditionAndAction: " +
type + ". Verify this type is valid and supported.");
}
gd::String conditionDescriptionTemplate =
type == "boolean" ? _("Check if <subject>.") : _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = type == "boolean"
? _("Set (or unset) if <subject>.")
: _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
if (type == "boolean") {
return MultipleInstructionMetadata::WithConditionAndAction(condition, action);
}
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
}
#if defined(GD_IDE_ONLY)
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName) {
gd::String newNameWithNamespace = extensionNamespace + newActionName;
gd::String copiedNameWithNamespace = extensionNamespace + copiedActionName;
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) {
gd::LogWarning("Could not find an action with name " +
copiedNameWithNamespace + " to copy.");
} else {
actionsInfos[newNameWithNamespace] = copiedAction->second;
}
return actionsInfos[newNameWithNamespace];
}
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedCondition(
const gd::String& newConditionName, const gd::String& copiedConditionName) {
gd::String newNameWithNamespace = extensionNamespace + newConditionName;
gd::String copiedNameWithNamespace = extensionNamespace + copiedConditionName;
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) {
gd::LogWarning("Could not find a condition with name " +
copiedNameWithNamespace + " to copy.");
} else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
}
return conditionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
gd::String copiedNameWithNamespace =
extensionNamespace + copiedExpressionName;
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) {
gd::LogWarning("Could not find an expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return expressionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = extensionNamespace + newExpressionName;
gd::String copiedNameWithNamespace =
extensionNamespace + copiedExpressionName;
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) {
gd::LogWarning("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return strExpressionsInfos[newNameWithNamespace];
}
#endif
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;
@@ -406,14 +222,4 @@ const gd::String& BehaviorMetadata::GetName() const {
return instance->GetTypeName();
}
gd::Behavior& BehaviorMetadata::Get() const {
if (!instance)
gd::LogFatalError(
"Trying to get a behavior from a BehaviorMetadata that has no "
"behavior. This will crash - please double check that the "
"BehaviorMetadata is valid.");
return *instance;
}
} // namespace gd

View File

@@ -6,14 +6,12 @@
#ifndef BEHAVIORMETADATA_H
#define BEHAVIORMETADATA_H
#include <map>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
namespace gd {
class Behavior;
class BehaviorsSharedData;
class MultipleInstructionMetadata;
class InstructionMetadata;
class ExpressionMetadata;
} // namespace gd
@@ -43,8 +41,7 @@ class GD_CORE_API BehaviorMetadata {
/**
* Declare a new condition as being part of the behavior.
* \deprecated Prefer using `AddScopedCondition`, to properly namespace
* the condition.
* \deprecated Prefer using `AddScopedCondition`.
*/
gd::InstructionMetadata& AddCondition(const gd::String& name_,
const gd::String& fullname_,
@@ -56,8 +53,7 @@ class GD_CORE_API BehaviorMetadata {
/**
* Declare a new action as being part of the behavior.
* \deprecated Prefer using `AddScopedAction`, to properly namespace
* the action.
* \deprecated Prefer using `AddScopedAction`.
*/
gd::InstructionMetadata& AddAction(const gd::String& name_,
const gd::String& fullname_,
@@ -71,23 +67,23 @@ class GD_CORE_API BehaviorMetadata {
* Declare a new condition as being part of the behavior.
*/
gd::InstructionMetadata& AddScopedCondition(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new action as being part of the behavior.
*/
gd::InstructionMetadata& AddScopedAction(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new action as being part of the extension.
*/
@@ -106,78 +102,6 @@ class GD_CORE_API BehaviorMetadata {
const gd::String& group_,
const gd::String& smallicon_);
/**
* \brief Declare a new expression and condition as being part of the
* behavior.
* \note It's recommended to use this function to avoid declaring twice a
* similar expression/condition.
*/
gd::MultipleInstructionMetadata AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Declare a new expression, condition and action as being part of the
* behavior.
* \note The action name is prefixed by "Set" (and the namespace, as the
* condition).
* \note It's recommended to use this function to avoid declaring 3 times a
* similar expression/condition/action.
*/
gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Create a new action which is the duplicate of the specified one.
*
* Useful for handling a deprecated action that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName);
/**
* \brief Create a new condition which is the duplicate of the specified one.
*
* Useful for handling a deprecated condition that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedCondition(
const gd::String& newConditionName,
const gd::String& copiedConditionName);
/**
* \brief Create a new expression which is the duplicate of the specified one.
*
* Useful for handling a deprecated expression that is just a "copy" of the
* new one.
*/
gd::ExpressionMetadata& AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
/**
* \brief Create a new string expression which is the duplicate of the
* specified one.
*
* Useful for handling a deprecated string expression that is just a "copy" of
* the new one.
*/
gd::ExpressionMetadata& AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
BehaviorMetadata& SetFullName(const gd::String& fullname_);
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
BehaviorMetadata& SetDescription(const gd::String& description_);
@@ -196,14 +120,12 @@ class GD_CORE_API BehaviorMetadata {
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* Get the help path of the behavior, relative to the GDevelop documentation
* root.
* Get the help path of the behavior, relative to the documentation root.
*/
const gd::String& GetHelpPath() const { return helpPath; }
/**
* Set the help path of the behavior, relative to the GDevelop documentation
* root.
* Set the help path of the behavior, relative to the documentation root.
*
* The behavior instructions will have this help path set by
* default, unless you call SetHelpPath on them.
@@ -240,7 +162,7 @@ class GD_CORE_API BehaviorMetadata {
/**
* \brief Return the associated gd::Behavior, handling behavior contents.
*/
gd::Behavior& Get() const;
gd::Behavior& Get() const { return *instance; }
/**
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
@@ -250,27 +172,6 @@ class GD_CORE_API BehaviorMetadata {
return sharedDatasInstance.get();
}
/**
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
/**
* \see gd::PlatformExtension::GetAllActions
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos;

View File

@@ -1,155 +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 DEPENDENCYMETADATA_H
#define DEPENDENCYMETADATA_H
#include <map>
#include <set>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
namespace gd {
/**
* \brief Contains information about a dependency (library, npm/cordova
* package, or other according to the export) of an extension.
*/
class GD_CORE_API DependencyMetadata {
public:
/**
* Construct a new dependency metadata, though you probably want to call
* `AddDependency` on gd::PlatformExtension.
*
* \see gd::PlatformExtension
*/
DependencyMetadata() : onlyIfSomeExtraSettingsNonEmpty(false){};
/**
* \brief Sets the name shown to users.
*/
DependencyMetadata& SetName(const gd::String& name_) {
name = name_;
return *this;
};
/**
* \brief Sets the name written by the exporter.
* Typically, this is what is used by the dependency manager
* to find the dependency.
*
* \example
* \code
* // For depending upon the NPM package is-thirteen
* gd::DependencyMetadata dependencyMetadata = gd::DependencyMetadata();
* dependencyMetadata.setExporterName("is-thirteen");
* \endcode
*/
DependencyMetadata& SetExportName(const gd::String& exportName_) {
exportName = exportName_;
return *this;
};
/**
* \brief Set the version of the dependency to install.
* Use an empty string to use the latest version.
*/
DependencyMetadata& SetVersion(const gd::String& version_) {
version = version_;
return *this;
};
/**
* \brief Sets the type of dependecy (what will be used to install it)
*
* This can either be "npm" or "cordova" for now.
*/
DependencyMetadata& SetDependencyType(const gd::String& dependencyType_) {
dependencyType = dependencyType_;
if (dependencyType != "npm" && dependencyType != "cordova") {
gd::LogWarning("Invalid dependency type: " + dependencyType);
}
return *this;
};
/**
* \brief Sets a dependency type specific setting.
*/
DependencyMetadata& SetExtraSetting(
const gd::String& settingName,
const gd::PropertyDescriptor& settingValue) {
extraData[settingName] = settingValue;
return *this;
};
/**
* \brief Mark the dependency to be included in the export only if at least
* one of the extra settings is set.
*/
DependencyMetadata& OnlyIfSomeExtraSettingsNonEmpty() {
onlyIfSomeExtraSettingsNonEmpty = true;
return *this;
};
/**
* \brief Check if at least one of the extra settings must be set for the
* dependency to be included in the export.
*/
bool IsOnlyIfSomeExtraSettingsNonEmpty() const {
return onlyIfSomeExtraSettingsNonEmpty;
};
/**
* \brief Mark the dependency to be included in the export only if one other
* dependency is included in the export.
*/
DependencyMetadata& OnlyIfOtherDependencyIsExported(
const gd::String& otherDependency) {
onlyIfOtherDependencyIsExported = otherDependency;
return *this;
};
/**
* \brief Get the name of another dependency that must be exported to have
* this one also exported.
*/
const gd::String& GetOtherDependencyThatMustBeExported() const {
return onlyIfOtherDependencyIsExported;
};
const gd::String& GetName() const { return name; };
const gd::String& GetExportName() const { return exportName; };
const gd::String& GetVersion() const { return version; };
const gd::String& GetDependencyType() const {
if (dependencyType == "")
gd::LogWarning("Dependency has no type, it won't be exported.");
return dependencyType;
};
const std::map<gd::String, gd::PropertyDescriptor>& GetAllExtraSettings()
const {
return extraData;
}
void CopyFrom(const DependencyMetadata& dependencyMetadata) {
*this = dependencyMetadata;
}
private:
gd::String name; ///< The name of the dependency.
gd::String exportName; ///< The name used to install the package (example:
///< npm package name for npm dependency type).
gd::String version; ///< The version of the dependency
gd::String dependencyType; ///< The tool used to install the dependency.
std::map<gd::String, gd::PropertyDescriptor>
extraData; ///< Contains dependency type specific additional parameters
///< for the dependency.
bool onlyIfSomeExtraSettingsNonEmpty; ///< If true, only use this dependency
///< if at least one of the extra
///< settings is set.
gd::String onlyIfOtherDependencyIsExported;
};
} // namespace gd
#endif // DEPENDENCYMETADATA_H

View File

@@ -7,8 +7,7 @@
namespace gd {
EffectMetadata::EffectMetadata(const gd::String& type_)
: type(type_), isMarkedAsNotWorkingForObjects(false) {}
EffectMetadata::EffectMetadata(const gd::String& type_) : type(type_) {}
EffectMetadata& EffectMetadata::SetIncludeFile(const gd::String& includeFile) {
includeFiles.clear();
@@ -23,9 +22,4 @@ EffectMetadata& EffectMetadata::AddIncludeFile(const gd::String& includeFile) {
return *this;
}
EffectMetadata& EffectMetadata::MarkAsNotWorkingForObjects() {
isMarkedAsNotWorkingForObjects = true;
return *this;
}
} // namespace gd

View File

@@ -8,8 +8,6 @@
#include <functional>
#include <map>
#include <memory>
#include <algorithm>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
@@ -51,8 +49,7 @@ class GD_CORE_API EffectMetadata {
};
/**
* Set the help path of the effect, relative to the GDevelop documentation
* root.
* Set the help path of the effect, relative to the documentation root.
*/
EffectMetadata& SetHelpPath(const gd::String& path) {
helpPath = path;
@@ -69,11 +66,6 @@ class GD_CORE_API EffectMetadata {
*/
EffectMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* \brief Mark the effect as not working as an object effect.
*/
EffectMetadata& MarkAsNotWorkingForObjects();
/**
* \brief Return a reference to the properties of this effect.
*/
@@ -89,14 +81,12 @@ class GD_CORE_API EffectMetadata {
}
/**
* \brief Get the help path of the effect, relative to the GDevelop
* documentation root.
* \brief Get the help path of the effect, relative to the documentation root.
*/
const gd::String& GetHelpPath() const { return helpPath; }
/**
* \brief Get the type of the effect (its internal name, like
* "BlackAndWhite").
* \brief Get the type of the effect (its internal name, like "BlackAndWhite").
*/
const gd::String& GetType() const { return type; }
@@ -117,11 +107,6 @@ class GD_CORE_API EffectMetadata {
return includeFiles;
}
/**
* \brief Check if the effect is marked as not working as an object effect.
*/
bool IsMarkedAsNotWorkingForObjects() const { return isMarkedAsNotWorkingForObjects; };
private:
gd::String extensionNamespace;
gd::String type;
@@ -129,7 +114,6 @@ class GD_CORE_API EffectMetadata {
gd::String fullname;
gd::String description;
std::vector<gd::String> includeFiles;
bool isMarkedAsNotWorkingForObjects;
std::map<gd::String, gd::PropertyDescriptor> properties;
};

View File

@@ -9,15 +9,13 @@
namespace gd {
ExpressionMetadata::ExpressionMetadata(const gd::String& returnType_,
const gd::String& extensionNamespace_,
ExpressionMetadata::ExpressionMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& group_,
const gd::String& smallicon_)
: returnType(returnType_),
fullname(fullname_),
: fullname(fullname_),
description(description_),
group(group_),
shown(true),
@@ -34,7 +32,7 @@ ExpressionMetadata& ExpressionMetadata::SetHidden() {
gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
const gd::String& type,
const gd::String& description,
const gd::String& supplementaryInformation,
const gd::String& optionalObjectType,
bool parameterIsOptional) {
gd::ParameterMetadata info;
info.type = type;
@@ -46,15 +44,15 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
// parameter is an object/behavior type...
(gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
? (supplementaryInformation.empty()
? (optionalObjectType.empty()
? ""
: extensionNamespace +
supplementaryInformation //... so prefix it with the extension
optionalObjectType //... so prefix it with the extension
// namespace.
)
: supplementaryInformation; // Otherwise don't change anything
: optionalObjectType; // Otherwise don't change anything
// TODO: Assert against supplementaryInformation === "emsc" (when running with
// TODO: Assert against optionalObjectType === "emsc" (when running with
// Emscripten), and warn about a missing argument when calling addParameter.
parameters.push_back(info);
@@ -72,11 +70,4 @@ gd::ExpressionMetadata& ExpressionMetadata::AddCodeOnlyParameter(
return *this;
}
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
const gd::String& capability) {
requiredBaseObjectCapability = capability;
return *this;
}
} // namespace gd

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