Compare commits

..

1 Commits

Author SHA1 Message Date
Florian Rival
2b60377820 Remove deprecated/unused/unmaintained GDCpp code
* This also includes extensions code.

Only show in developer changelog
2021-08-16 23:23:09 +02:00
3721 changed files with 695030 additions and 346415 deletions

View File

@@ -2,17 +2,8 @@
# on the Electron runtime (newIDE/electron-app) for macOS and Linux.
# For Windows, see the appveyor.yml file.
# 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
jobs:
# Build the **entire** app for macOS.
build-macos:
macos:
xcode: 12.5.1
@@ -21,12 +12,8 @@ jobs:
# 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 /
name: Install dependencies for Emscripten and AWS S3 upload
command: brew install cmake && brew install awscli
- run:
name: Install Emscripten (for GDevelop.js)
@@ -40,7 +27,7 @@ jobs:
- gd-macos-nodejs-dependencies---
- run:
name: Install GDevelop.js dependencies
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)
@@ -68,7 +55,7 @@ jobs:
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app" && rm -rf "newIDE/electron-app/dist/mac-arm64/GDevelop 5.app"
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
# Upload artifacts (CircleCI)
- store_artifacts:
@@ -77,33 +64,27 @@ jobs:
# 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)/
command: 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/
command: 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
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
- 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 ..
@@ -143,11 +124,11 @@ jobs:
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
name: Build GDevelop IDE
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux --publish=never
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --linux AppImage --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.
command: rm -rf newIDE/electron-app/dist/linux-unpacked && rm -rf newIDE/electron-app/dist/linux-arm64-unpacked
command: rm -rf newIDE/electron-app/dist/linux-unpacked
# Upload artifacts (CircleCI)
- store_artifacts:
@@ -161,67 +142,10 @@ jobs:
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:

6
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
# 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

16
.devcontainer/README.md Normal file
View File

@@ -0,0 +1,16 @@
# 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

@@ -0,0 +1,51 @@
// 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.'"
}

View File

@@ -1,19 +0,0 @@
---
name: "📦 Asset Store submission"
about: Submit a free asset pack for the GDevelop Asset Store.
title: ''
labels: "📦 Asset Store submission"
assignees: ''
---
BEFORE opening a new submission, please make sure that you:
- You have packaged the asset pack according [these rules](https://wiki.gdevelop.io/gdevelop5/community/contribute-to-the-assets-store). Otherwise, your package may be rejected or we will ask you to do the changes.
## Description
- License:
- Author:
- Link to the original website:
- Zip file:

28
.github/ISSUE_TEMPLATE/--bug-report.md vendored Normal file
View File

@@ -0,0 +1,28 @@
---
name: "\U0001F41BBug report"
about: Create a bug report about GDevelop or the game engine
title: ''
labels: ''
assignees: ''
---
## Describe the bug
A clear and concise description of what the bug is.
Please double check that the bug is not already reported in the issues list.
## To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
* Please include a link to a game if possible!
* If applicable, add screenshots to help explain your problem.
## Other details
* Include any OS/browser version/smartphone that you're using
* Which version of GDevelop are you using? The desktop app or the web-app?
* Add any other context about the problem here.

View File

@@ -1,71 +0,0 @@
name: 🐛Bug report
description: Create a bug report about GDevelop or the game engine
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
options:
- label: I have searched the [existing issues](https://github.com/4ian/GDevelop/issues)
required: true
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
* Please include a link to a game if possible!
* If applicable, add screenshots to help explain your problem.
placeholder: |
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
validations:
required: true
- type: dropdown
attributes:
label: GDevelop platform
description: Which platform of GDevelop are you using?
multiple: true
options:
- Desktop
- Web
- Mobile
validations:
required: true
- type: input
attributes:
label: GDevelop version
description: |
Which version of GDevelop are you using?
Take a look here: [Editor Home - About GDevelop - "This version of GDevelop is: ~~~"]
placeholder: 5.1.159? 5.1.160?
validations:
required: true
- type: textarea
attributes:
label: Platform info
value: |
<details>
*OS (e.g. Windows, Linux, macOS, Android, iOS)*
>
*OS Version (e.g. Windows 10, macOS 10.15)*
>
*Browser(For Web) (e.g. Chrome, Firefox, Safari)*
>
*Device(For Mobile) (e.g. iPhone 12, Samsung Galaxy S21)*
>
</details>
- type: textarea
attributes:
label: Additional context
description: Add any other context about the problem here.

View File

@@ -10,11 +10,11 @@ assignees: ''
BEFORE opening a new feature request, please make sure that 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
- Discussed 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
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

View File

@@ -4,14 +4,14 @@ contact_links:
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
url: https://forum.gdevelop-app.com
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
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
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,67 +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:
- uses: actions/checkout@v3
with:
fetch-depth: 50
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: 'newIDE/app/package-lock.json'
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Install newIDE dependencies
run: npm install
working-directory: newIDE/app
- name: Build Storybook
run: npm run build-storybook
working-directory: newIDE/app
# Publish on S3 to allow quick testing of components.
- name: Publish Storybook to S3 bucket (specific commit)
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/ --delete
working-directory: newIDE/app
- name: Publish Storybook to S3 bucket (latest)
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/latest/ --delete
working-directory: newIDE/app
- name: Log urls to the Storybook
run: |
echo "Find the latest Storybook for this branch on https://gdevelop-storybook.s3.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/latest/index.html"
echo "Find the Storybook for this commit on https://gdevelop-storybook.s3.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/index.html"
# Publish on Chromatic, only when manually launched (too costly to run on every commit).
- name: Publish Storybook to Chromatic
if: github.event_name == 'workflow_dispatch'
uses: chromaui/action@v1
with:
workingDir: newIDE/app
storybookBuildDir: "build-storybook"
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View File

@@ -1,42 +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@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: 'newIDE/app/package-lock.json'
- name: Install gettext
run: sudo apt update && sudo apt install gettext -y
- name: Install newIDE dependencies
run: npm install
working-directory: newIDE/app
- 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,19 +1,28 @@
name: GDevelop Issues automatic workflow
on:
issues:
types: [opened]
on: [issues]
jobs:
autocomment:
autoclose:
runs-on: ubuntu-latest
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
steps:
- name: Autocomment indications on bug if it looks like #3453
uses: peter-evans/create-or-update-comment@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hi @${{ github.actor }}!
Thank you for taking the time to open an issue.
- 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-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/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."
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.

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 "sumupFileContent=$(cat sumup.txt)" >> $GITHUB_OUTPUT
- name: Autocomment pull request with sumup
uses: peter-evans/create-or-update-comment@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.number }}
body: ${{ steps.sumup.outputs.sumupFileContent }}

View File

@@ -1,68 +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@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'npm'
cache-dependency-path: 'newIDE/app/package-lock.json'
- name: Install gettext
run: sudo apt update && sudo apt install gettext -y
- name: Install newIDE dependencies
run: npm install
working-directory: newIDE/app
# We need to extract translations first to make sure all the source strings
# are included in the English catalogs. Otherwise, missing source strings
# with parameters (like "My name is {0}.") would be shown as-is when
# the app is built (but not in development - unclear why, LinguiJS issue?).
- name: Extract translations
run: npm run extract-all-translations
working-directory: newIDE/app
# (Build and) download the most recent translations (PO files) from Crowdin.
- name: Install Crowdin CLI
run: npm i -g @crowdin/cli
- name: Download new translations from Crowdin
run: crowdin download
env:
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
# Seems like the three letters code is not handled properly by LinguiJS?
# Do without this language while we find a solution.
- name: Remove catalogs not handled properly by LinguiJS compile command.
run: rm -rf newIDE/app/src/locales/pcm_NG/
- name: Compile translations into .js files that are read by LinguiJS
run: npm run compile-translations
working-directory: newIDE/app
- name: Create a Pull Request with the changes
uses: peter-evans/create-pull-request@v5
with:
commit-message: Update translations [skip ci]
branch: chore/update-translations
delete-branch: true
title: "[Auto PR] Update translations"
body: |
This updates the translations by downloading them from Crowdin and compiling them for usage by the app.
Please double check the values in `newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are sensible.

2
.gitignore vendored
View File

@@ -1,3 +1,4 @@
/Core/GDCore/Tools/VersionPriv.h
/docs
/docs-wiki
/ExtLibs/SFML
@@ -8,7 +9,6 @@
/Binaries/.embuild*
/Binaries/build*
/Binaries/embuild*
/emsdk
*.dll
*.exe
*.a

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,6 +1,9 @@
# Travis CI configuration to build and run all tests
# (and typing/formatting) for the Core, newIDE, GDJS.
#
# This builds GDevelop.js and store it on a S3 so it can be used to run
# GDevelop without building it.
#
# See also Semaphore CI for quick tests (not building GDevelop.js, so
# faster but not always reliable).
@@ -14,7 +17,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,15 +40,28 @@ 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
#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
- mkdir .build-tests
- cd .build-tests
@@ -39,17 +70,21 @@ 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
#Install GDJS tests dependencies
- cd GDJS && npm install && cd tests && npm install
- cd ../..
@@ -67,13 +102,12 @@ 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,99 +1,95 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"/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",
"${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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/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",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"/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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceRoot}",
"${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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/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,
"databaseFilename": ""
},
"macFrameworkPath": ["/System/Library/Frameworks", "/Library/Frameworks"],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": ["/usr/include", "/usr/local/include", "${workspaceRoot}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/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 */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": ["${workspaceRoot}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
}

43
.vscode/launch.json vendored
View File

@@ -4,50 +4,13 @@
// 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)",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
"webRoot": "${workspaceFolder}",
"preLaunchTask": "Start development server"
}
]
}

View File

@@ -108,13 +108,12 @@
"xtree": "cpp",
"xutility": "cpp",
"xlocbuf": "cpp",
"xlocmes": "cpp",
"xmemory0": "cpp",
"memory_resource": "cpp"
"xlocmes": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,
"Binaries/Output": true,
"ExtLibs/SFML": true,
"GDJS/Runtime-dist": true,
"docs": true,
"newIDE/electron-app/dist": true,

2
.vscode/tasks.json vendored
View File

@@ -80,7 +80,7 @@
},
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"tsconfig": "GDJS/tsconfig.json",
"option": "watch",
"problemMatcher": ["$tsc-watch"],
"group": "test",

View File

@@ -1,3 +1,3 @@
This is the directory where native or WebAssembly binaries of the C++ code of GDCore and GDJS are produced.
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
See GDevelop.js README for the instructions to compile after a change in the C++ source code.

View File

@@ -1,5 +1,5 @@
#This is the CMake file used to build GDevelop.
#For more information, see the README.md file.
#For more information, see the Readme.md file.
cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0011 NEW)
@@ -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,7 @@ ENDIF()
IF(BUILD_GDJS)
ADD_SUBDIRECTORY(GDJS)
ENDIF()
IF(EMSCRIPTEN)
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

@@ -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)
@@ -38,7 +31,7 @@ void CommentEvent::SerializeTo(SerializerElement &element) const {
.SetAttribute("textB", textB);
element.AddChild("comment").SetValue(com1);
if (!com2.empty()) element.AddChild("comment2").SetValue(com2);
element.AddChild("comment2").SetValue(com2);
}
void CommentEvent::UnserializeFrom(gd::Project &project,
@@ -53,9 +46,7 @@ void CommentEvent::UnserializeFrom(gd::Project &project,
textB = colorElement.GetIntAttribute("textB");
com1 = element.GetChild("comment", 0, "Com1").GetValue().GetString();
if (element.HasChild("comment2")) {
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
}
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
}
} // namespace gd

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

@@ -53,10 +53,8 @@ void ForEachChildVariableEvent::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 ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
@@ -68,12 +66,8 @@ void ForEachChildVariableEvent::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

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

@@ -13,7 +13,6 @@
namespace gd {
class Instruction;
class Project;
class EventVisitor;
}
class EventsCodeGenerationContext;
@@ -108,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

@@ -16,7 +16,6 @@
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Events/EventVisitor.h"
using namespace std;
@@ -157,14 +156,4 @@ void LinkEvent::UnserializeFrom(gd::Project& project,
}
}
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
return BaseEvent::AcceptVisitor(eventVisitor) |
eventVisitor.VisitLinkEvent(*this);
}
void LinkEvent::AcceptVisitor(gd::ReadOnlyEventVisitor &eventVisitor) const {
BaseEvent::AcceptVisitor(eventVisitor);
eventVisitor.VisitLinkEvent(*this);
}
} // namespace gd

View File

@@ -30,7 +30,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
includeEnd(gd::String::npos),
linkWasInvalid(false){};
virtual ~LinkEvent();
virtual gd::LinkEvent* Clone() const override { return new LinkEvent(*this); }
virtual gd::LinkEvent* Clone() const { return new LinkEvent(*this); }
/**
* Get the link target (i.e. the scene or external events the link refers to).
@@ -86,7 +86,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
/**
* The link event must always be preprocessed.
*/
virtual bool MustBePreprocessed() override { return true; }
virtual bool MustBePreprocessed() { return true; }
/**
* \brief Get a pointer to the list of events that are targeted by the link.
@@ -107,14 +107,11 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
EventsList& eventList,
std::size_t indexOfTheEventInThisList);
virtual bool IsExecutable() const override { return true; };
virtual bool IsExecutable() const { return true; };
virtual void SerializeTo(SerializerElement& element) const override;
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element) override;
bool AcceptVisitor(gd::EventVisitor& eventVisitor) override;
void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const override;
const SerializerElement& element);
private:
gd::String

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,14 @@
* 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/EffectsContainer.h"
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
@@ -36,24 +33,6 @@ void ExposeProjectEffects(
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

@@ -43,7 +43,7 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
std::size_t relationalOperatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "relationalOperator")
if (instrInfos.parameters[i].type == "relationalOperator")
relationalOperatorIndex = i;
}
// Ensure that there is at least one parameter after the relational operator
@@ -95,7 +95,7 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -164,7 +164,7 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -215,7 +215,7 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) {
if (instrInfos.parameters[i].GetType() == "operator") operatorIndex = i;
if (instrInfos.parameters[i].type == "operator") operatorIndex = i;
}
// Ensure that there is at least one parameter after the operator
@@ -273,6 +273,8 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
context.EnterCustomCondition();
conditionCode += GenerateReferenceToUpperScopeBoolean(
"conditionTrue", returnBoolean, context);
conditionCode += instrInfos.codeExtraInformation.customCodeGenerator(
condition, *this, context);
maxCustomConditionsDepth =
@@ -289,9 +291,9 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.SetParameters(parameters);
}
// Verify that there are no mismatches between object type in parameters.
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter =
condition.GetParameter(pNb).GetPlainString();
@@ -301,11 +303,11 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].GetExtraInfo()) {
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
}
}
@@ -313,38 +315,31 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
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);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
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);
// 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();
}
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
@@ -448,9 +443,7 @@ 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 =
@@ -466,14 +459,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();
@@ -481,9 +466,9 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.SetParameters(parameters);
}
// Verify that there are no mismatches between object type in parameters.
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
@@ -491,11 +476,11 @@ gd::String EventsCodeGenerator::GenerateActionCode(
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() &&
} else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].GetExtraInfo()) {
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */";
}
}
@@ -504,38 +489,27 @@ gd::String EventsCodeGenerator::GenerateActionCode(
// Call free function first if available
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
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);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
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, arguments, instrInfos, context);
// 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();
}
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
@@ -563,11 +537,9 @@ gd::String EventsCodeGenerator::GenerateActionCode(
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
context);
context.SetNoCurrentObject();
}
@@ -575,75 +547,12 @@ gd::String EventsCodeGenerator::GenerateActionCode(
} else {
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateFreeAction(functionCallName,
arguments,
instrInfos,
context,
optionalAsyncCallbackName);
actionCode += GenerateFreeAction(arguments, instrInfos, context);
}
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.
*/
@@ -668,20 +577,8 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
return outputCode;
}
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
if (operatorString == "=") {
return "==";
}
if (operatorString != "<" && operatorString != ">" &&
operatorString != "<=" && operatorString != ">=" && operatorString != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
return "==";
}
return operatorString;
}
gd::String EventsCodeGenerator::GenerateParameterCodes(
const gd::Expression& parameter,
const gd::String& parameter,
const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName,
@@ -689,25 +586,30 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
supplementaryParametersTypes) {
gd::String argOutput;
if (ParameterMetadata::IsExpression("number", metadata.GetType())) {
if (ParameterMetadata::IsExpression("number", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "number", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("string", metadata.GetType())) {
*this, context, "number", parameter);
} else if (ParameterMetadata::IsExpression("string", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "string", parameter, lastObjectName);
} else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) {
*this, context, "string", parameter);
} else if (ParameterMetadata::IsExpression("variable", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, metadata.GetType(), parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.GetType())) {
*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.GetType(), context);
} else if (metadata.GetType() == "relationalOperator") {
argOutput += GenerateRelationalOperatorCodes(parameter.GetPlainString());
argOutput = GenerateObject(parameter, metadata.type, context);
} else if (metadata.type == "relationalOperator") {
argOutput += parameter == "=" ? "==" : parameter;
if (argOutput != "==" && argOutput != "<" && argOutput != ">" &&
argOutput != "<=" && argOutput != ">=" && argOutput != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
argOutput = "==";
}
argOutput = "\"" + argOutput + "\"";
} else if (metadata.GetType() == "operator") {
argOutput += parameter.GetPlainString();
} else if (metadata.type == "operator") {
argOutput += parameter;
if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
argOutput != "/" && argOutput != "*") {
cout << "Warning: Bad operator: Set to = by default." << endl;
@@ -715,55 +617,41 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
}
argOutput = "\"" + argOutput + "\"";
} else if (ParameterMetadata::IsBehavior(metadata.GetType())) {
argOutput = GenerateGetBehaviorNameCode(parameter.GetPlainString());
} else if (metadata.GetType() == "key") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "audioResource" ||
metadata.GetType() == "bitmapFontResource" ||
metadata.GetType() == "fontResource" ||
metadata.GetType() == "imageResource" ||
metadata.GetType() == "jsonResource" ||
metadata.GetType() == "tilemapResource" ||
metadata.GetType() == "tilesetResource" ||
metadata.GetType() == "videoResource" ||
metadata.GetType() == "model3DResource" ||
// Deprecated, old parameter names:
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "mouse") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
} else if (metadata.GetType() == "yesorno") {
auto parameterString = parameter.GetPlainString();
argOutput += (parameterString == "yes" || parameterString == "oui")
? GenerateTrue()
: GenerateFalse();
} else if (metadata.GetType() == "trueorfalse") {
auto parameterString = parameter.GetPlainString();
} else if (ParameterMetadata::IsBehavior(metadata.type)) {
argOutput = GenerateGetBehaviorNameCode(parameter);
} else if (metadata.type == "key") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "password" || metadata.type == "musicfile" ||
metadata.type == "soundfile" || metadata.type == "police") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "mouse") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "yesorno") {
argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
: GenerateFalse();
} else if (metadata.type == "trueorfalse") {
// 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.GetType() == "inlineCode") {
argOutput += metadata.GetExtraInfo();
else if (metadata.type == "inlineCode") {
argOutput += metadata.supplementaryInformation;
} else {
// Try supplementary types if provided
if (supplementaryParametersTypes) {
for (std::size_t i = 0; i < supplementaryParametersTypes->size(); ++i) {
if ((*supplementaryParametersTypes)[i].first == metadata.GetType())
if ((*supplementaryParametersTypes)[i].first == metadata.type)
argOutput += (*supplementaryParametersTypes)[i].second;
}
}
// Type unknown
if (argOutput.empty()) {
if (!metadata.GetType().empty())
cout << "Warning: Unknown type of parameter \"" << metadata.GetType()
if (!metadata.type.empty())
cout << "Warning: Unknown type of parameter \"" << metadata.type
<< "\"." << std::endl;
argOutput += "\"" + ConvertToString(parameter.GetPlainString()) + "\"";
argOutput += "\"" + ConvertToString(parameter) + "\"";
}
}
@@ -783,7 +671,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,
@@ -835,21 +723,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);
@@ -857,9 +747,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";
@@ -874,7 +765,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
@@ -890,8 +781,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);
@@ -1036,7 +925,7 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
for (std::size_t i = 0; i < instrInfos.parameters.size();
++i) // Some conditions already have a "conditionInverted" parameter
{
if (instrInfos.parameters[i].GetType() == "conditionInverted")
if (instrInfos.parameters[i].type == "conditionInverted")
conditionAlreadyTakeCareOfInversion = true;
}
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
@@ -1057,7 +946,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
// Prepare call
// Add a static_cast if necessary
gd::String objectFunctionCallNamePart =
(!instrInfos.parameters[0].GetExtraInfo().empty())
(!instrInfos.parameters[0].supplementaryInformation.empty())
? "static_cast<" + objInfo.className + "*>(" +
GetObjectListName(objectName, context) + "[i])->" +
instrInfos.codeExtraInformation.functionCallName
@@ -1104,11 +993,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" ||
@@ -1118,39 +1005,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" ||
@@ -1160,26 +1040,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";
}
}
@@ -1187,11 +1066,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" ||
@@ -1201,29 +1078,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";
}
}
@@ -1239,7 +1111,7 @@ size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
<< std::endl;
}
// Base the unique id on the address in memory so that the same instruction
// Base the unique id on the adress in memory so that the same instruction
// in memory will get the same id across different code generations.
size_t uniqueId = (size_t)instruction;
@@ -1271,7 +1143,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_),
@@ -1288,7 +1160,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.
@@ -404,18 +358,6 @@ class GD_CORE_API EventsCodeGenerator {
return boolName;
}
/**
* \brief Generate the full name for accessing to a boolean variable used for
* conditions.
*
* Default implementation just returns the boolean name passed as argument.
*/
virtual gd::String GenerateUpperScopeBooleanFullName(
const gd::String& boolName,
const gd::EventsCodeGenerationContext& context) {
return boolName;
}
/**
* \brief Must create a boolean. Its value must be false.
*
@@ -493,9 +435,6 @@ class GD_CORE_API EventsCodeGenerator {
*/
size_t GenerateSingleUsageUniqueIdForEventsList();
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
protected:
/**
* \brief Generate the code for a single parameter.
@@ -505,9 +444,9 @@ class GD_CORE_API EventsCodeGenerator {
* - object : Object name -> string
* - expression : Mathematical expression -> number (double)
* - string : %Text expression -> string
* - layer, color, file, stringWithSelector : Same as string
* - layer, color, file, joyaxis : Same as string
* - relationalOperator : Used to make a comparison between the function
return value and value of the parameter preceding the relationOperator
resturn value and value of the parameter preceding the relationOperator
parameter -> string
* - operator : Used to update a value using a setter and a getter -> string
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
@@ -523,18 +462,25 @@ 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. Example:
* \code
AddExpression("Count", _("Object count"), _("Count the number of picked
objects"), _("Objects"), "res/conditions/nbObjet.png")
.AddParameter("objectList", _("Object"))
.SetFunctionName("getPickedObjectsCount");
* \endcode
* - objectListWithoutPicking : 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:
* \code
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target object"))
* \endcode
*/
virtual gd::String GenerateParameterCodes(
const gd::Expression& parameter,
const gd::String& parameter,
const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName,
@@ -677,6 +623,19 @@ class GD_CORE_API EventsCodeGenerator {
return "!(" + predicat + ")";
};
/**
* \brief Must create a boolean which is a reference to a boolean declared in
* the parent scope.
*
* The default implementation generates C-style code.
*/
virtual gd::String GenerateReferenceToUpperScopeBoolean(
const gd::String& referenceName,
const gd::String& referencedBoolean,
gd::EventsCodeGenerationContext& context) {
return "bool & " + referenceName + " = " + referencedBoolean + ";\n";
}
virtual gd::String GenerateFreeCondition(
const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos,
@@ -704,30 +663,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,
@@ -777,15 +730,15 @@ 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 occurred.
bool errorOccurred; ///< Must be set to true if an error occured.
bool compilationForRuntime; ///< Is set to true if the code generation is
///< made for runtime only.

View File

@@ -25,38 +25,36 @@
#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);
const gd::String& type,
const gd::String& expression,
const gd::String& objectName) {
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
ExpressionCodeGenerator generator(codeGenerator, context);
auto node = expression.GetRootNode();
auto node = parser.ParseExpression(type, expression, objectName);
if (!node) {
std::cout << "Error: error while parsing: \"" << expression.GetPlainString()
<< "\" (" << rootType << ")" << std::endl;
std::cout << "Error: error while parsing: \"" << expression << "\" ("
<< type << ")" << std::endl;
return generator.GenerateDefaultValue(rootType);
return generator.GenerateDefaultValue(type);
}
gd::ExpressionValidator validator(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups(),
rootType);
gd::ExpressionValidator validator;
node->Visit(validator);
if (!validator.GetFatalErrors().empty()) {
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
<< "\" in: \"" << expression.GetPlainString() << "\" ("
<< rootType << ")" << std::endl;
if (!validator.GetErrors().empty()) {
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
<< "\" in: \"" << expression << "\" (" << type << ")"
<< std::endl;
return generator.GenerateDefaultValue(rootType);
return generator.GenerateDefaultValue(type);
}
node->Visit(generator);
@@ -99,24 +97,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 +117,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 +125,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 apart 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);
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 +219,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 +299,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();
@@ -428,22 +368,12 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
}
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);
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,12 +5,8 @@
*/
#include "GDCore/Events/Event.h"
#include "GDCore/Events/Builtin/AsyncEvent.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Events/EventVisitor.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
@@ -69,41 +65,10 @@ gd::String BaseEvent::GenerateEventCode(
return "";
}
void BaseEvent::PreprocessAsyncActions(const gd::Platform& platform) {
if (!CanHaveSubEvents()) return;
for (const auto& actionsList : GetAllActionsVectors())
for (std::size_t aId = 0; aId < actionsList->size(); ++aId) {
const auto& action = actionsList->at(aId);
const gd::InstructionMetadata& actionMetadata =
gd::MetadataProvider::GetActionMetadata(platform, action.GetType());
if (actionMetadata.IsAsync() &&
(!actionMetadata.IsOptionallyAsync() || action.IsAwaited())) {
gd::InstructionsList remainingActions;
remainingActions.InsertInstructions(
*actionsList, aId + 1, actionsList->size() - 1);
gd::AsyncEvent asyncEvent(action, remainingActions, GetSubEvents());
// Ensure that the local event no longer has any of the actions/subevent
// after the async function
actionsList->RemoveAfter(aId);
GetSubEvents().Clear();
GetSubEvents().InsertEvent(asyncEvent);
// We just moved all the rest, there's nothing left to do in this event.
return;
}
}
};
void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
gd::EventsList& eventList,
std::size_t indexOfTheEventInThisList) {
if (IsDisabled()) return;
PreprocessAsyncActions(codeGenerator.GetPlatform());
if (!MustBePreprocessed()) return;
if (IsDisabled() || !MustBePreprocessed()) return;
try {
if (type.empty()) return;
@@ -141,14 +106,6 @@ void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
}
}
bool BaseEvent::AcceptVisitor(gd::EventVisitor& eventVisitor) {
return eventVisitor.VisitEvent(*this);
}
void BaseEvent::AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const {
eventVisitor.VisitEvent(*this);
}
BaseEventSPtr GD_CORE_API CloneRememberingOriginalEvent(BaseEventSPtr event) {
gd::BaseEventSPtr copy(event->Clone());
// Original event is either the original event of the copied event, or the

View File

@@ -10,7 +10,6 @@
#include <iostream>
#include <memory>
#include <vector>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
@@ -24,9 +23,7 @@ class EventsCodeGenerationContext;
class Platform;
class SerializerElement;
class Instruction;
class EventVisitor;
class ReadOnlyEventVisitor;
} // namespace gd
}
namespace gd {
@@ -129,25 +126,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;
};
@@ -211,11 +201,6 @@ class GD_CORE_API BaseEvent {
gd::EventsList& eventList,
std::size_t indexOfTheEventInThisList);
/**
* A function that turns all async member actions into an Async subevent for code generation.
*/
void PreprocessAsyncActions(const gd::Platform& platform);
/**
* \brief If MustBePreprocessed is redefined to return true, the
* gd::EventMetadata::preprocessing associated to the event will be called to
@@ -240,9 +225,6 @@ class GD_CORE_API BaseEvent {
*/
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element){};
virtual bool AcceptVisitor(gd::EventVisitor& eventVisitor);
virtual void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const;
///@}
/** \name Common properties

View File

@@ -1,76 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <iostream>
#include <memory>
#include <vector>
#include "GDCore/String.h"
namespace gd {
class BaseEvent;
class LinkEvent;
} // namespace gd
namespace gd {
/**
* \brief Visitor of any kind of event.
*
* \ingroup Events
*/
class GD_CORE_API EventVisitor {
public:
virtual ~EventVisitor(){};
/**
* Called to do some work on an event.
*
* \return true if the event must be deleted from the events list, false
* otherwise.
*/
virtual bool VisitEvent(gd::BaseEvent& linkEvent) = 0;
/**
* Called to do some work on a link event.
*
* Note that VisitEvent is also called with this event.
*
* \return true if the event must be deleted from the events list, false
* otherwise.
*/
virtual bool VisitLinkEvent(gd::LinkEvent& linkEvent) = 0;
};
/**
* \brief Visitor of any kind of event.
*
* \ingroup Events
*/
class GD_CORE_API ReadOnlyEventVisitor {
public:
virtual ~ReadOnlyEventVisitor(){};
/**
* Called to do some work on an event.
*/
virtual void VisitEvent(const gd::BaseEvent& linkEvent) = 0;
/**
* Called to do some work on a link event.
*
* Note that VisitEvent is also called with this event.
*/
virtual void VisitLinkEvent(const gd::LinkEvent& linkEvent) = 0;
/**
* @brief Abort the iteration on the events.
*/
virtual void StopAnyEventIteration() = 0;
};
}

View File

@@ -5,7 +5,6 @@
*/
#include "EventsList.h"
#include "GDCore/Events/Event.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Tools/Log.h"
@@ -101,8 +100,9 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
}
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
gd::EventsList& newEventsList,
std::size_t newPosition) {
gd::EventsList& newEventsList,
std::size_t newPosition) {
for (std::size_t i = 0; i < GetEventsCount(); ++i) {
if (events[i].get() == &eventToMove) {
std::shared_ptr<BaseEvent> event = events[i];

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

@@ -55,10 +55,6 @@ void Instruction::SetParameter(std::size_t nb, const gd::Expression& val) {
parameters[nb] = val;
}
void Instruction::AddParameter(const gd::Expression& val) {
parameters.push_back(val);
}
std::shared_ptr<Instruction> GD_CORE_API
CloneRememberingOriginalElement(std::shared_ptr<Instruction> instruction) {
std::shared_ptr<Instruction> copy =

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.
*/
@@ -123,11 +107,6 @@ class GD_CORE_API Instruction {
*/
void SetParameter(std::size_t nb, const gd::Expression& val);
/** Add a parameter at the end
* \param val The new value of the parameter
*/
void AddParameter(const gd::Expression& val);
/** \brief Get a reference to the std::vector containing the parameters.
* \return A std::vector containing the parameters
*/
@@ -160,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);
@@ -171,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

@@ -26,16 +26,132 @@ 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::String& type,
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());
}
// Validate the type of the function
const gd::String& returnType = function.expressionMetadata.GetReturnType();
if (returnType == "number") {
if (type == "string")
return RaiseTypeError(
_("You tried to use an expression that returns a number, but a "
"string is expected. Use `ToString` if you need to convert a "
"number to a string."),
functionStartPosition);
else if (type != "number" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"number, but another type is expected:") +
" " + type,
functionStartPosition);
} else if (returnType == "string") {
if (type == "number")
return RaiseTypeError(
_("You tried to use an expression that returns a string, but a "
"number is expected. Use `ToNumber` if you need to convert a "
"string to a number."),
functionStartPosition);
else if (type != "string" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"string, but another type is expected:") +
" " + type,
functionStartPosition);
} else {
if (type != returnType)
return RaiseTypeError(
_("You tried to use an expression with the wrong return type:") + " " +
returnType,
functionStartPosition);
}
// Validate parameters count
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 =

View File

@@ -13,7 +13,6 @@
#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 +39,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,21 +57,23 @@ 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();
return Start(type, objectName);
}
/**
* 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).
* 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) {
@@ -84,16 +87,18 @@ 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);
const gd::String &inferredType = expression->type;
// Check for extra characters at the end of the expression
if (!IsEndReached()) {
auto op = gd::make_unique<OperatorNode>(' ');
auto op = gd::make_unique<OperatorNode>(inferredType, ' ');
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 +112,61 @@ 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);
const gd::String &inferredType = leftHandSide->type;
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>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(inferredType, 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 (inferredType == "string") {
leftHandSide->diagnostic = RaiseSyntaxError(
"You must add the operator + between texts or expressions. For "
"example: \"Your name: \" + VariableString(PlayerName).");
} else if (inferredType == "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>(inferredType, ' ');
op->leftHandSide = std::move(leftHandSide);
op->leftHandSide->parent = op.get();
op->rightHandSide = Expression();
op->rightHandSide->parent = op.get();
op->rightHandSide = Expression(inferredType, 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);
const gd::String &inferredType = factor->type;
SkipAllWhitespaces();
@@ -157,13 +174,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>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(factor);
op->leftHandSide->parent = op.get();
op->diagnostic = ValidateOperator(GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Factor();
op->rightHandSide->parent = op.get();
op->rightHandSide = Factor(inferredType, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
SkipAllWhitespaces();
@@ -174,35 +189,54 @@ 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();
if (CheckIfChar(IsQuote)) {
std::unique_ptr<ExpressionNode> factor = ReadText();
if (type == "number")
factor->diagnostic =
RaiseTypeError(_("You entered a text, but a number was expected."),
expressionStartPosition);
else if (type != "string" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a text, but this type was expected:") + type,
expressionStartPosition);
return factor;
} else if (CheckIfChar(IsUnaryOperator)) {
auto unaryOperatorCharacter = GetCurrentChar();
SkipChar();
auto operatorOperand = Factor();
auto operatorOperand = Factor(type, objectName);
const gd::String &inferredType = operatorOperand->type;
auto unaryOperator = gd::make_unique<UnaryOperatorNode>(
unaryOperatorCharacter);
inferredType, unaryOperatorCharacter);
unaryOperator->diagnostic = ValidateUnaryOperator(
unaryOperatorCharacter, expressionStartPosition);
inferredType, unaryOperatorCharacter, expressionStartPosition);
unaryOperator->factor = std::move(operatorOperand);
unaryOperator->factor->parent = unaryOperator.get();
unaryOperator->location = ExpressionParserLocation(
expressionStartPosition, GetCurrentPosition());
return std::move(unaryOperator);
} else if (CheckIfChar(IsNumberFirstChar)) {
std::unique_ptr<ExpressionNode> factor = ReadNumber();
if (type == "string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but a text was expected (in quotes)."),
expressionStartPosition);
else if (type != "number" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but this type was expected:") + type,
expressionStartPosition);
return factor;
} else if (CheckIfChar(IsOpeningParenthesis)) {
SkipChar();
std::unique_ptr<ExpressionNode> factor = SubExpression();
std::unique_ptr<ExpressionNode> factor = SubExpression(type, objectName);
if (!CheckIfChar(IsClosingParenthesis)) {
factor->diagnostic =
@@ -212,20 +246,29 @@ class GD_CORE_API ExpressionParser2 {
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)) {
return Variable(type, objectName);
} else {
return Identifier(type);
}
}
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace();
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace(type);
factor->diagnostic = RaiseEmptyError(type, expressionStartPosition);
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 expression = Expression(type, objectName);
const gd::String &inferredType = expression->type;
auto subExpression =
gd::make_unique<SubExpressionNode>(std::move(expression));
gd::make_unique<SubExpressionNode>(inferredType, std::move(expression));
subExpression->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
@@ -233,7 +276,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 +303,47 @@ 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 (type == "number|string") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number or a text, wrapped inside double quotes "
"(example: \"Hello world\")."),
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 +358,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("number|string"));
if (!CheckIfChar(IsClosingSquareBracket)) {
child->diagnostic =
@@ -306,7 +368,6 @@ class GD_CORE_API ExpressionParser2 {
}
SkipIfChar(IsClosingSquareBracket);
child->child = VariableAccessorOrVariableBracketAccessor();
child->child->parent = child.get();
child->location =
ExpressionParserLocation(childStartPosition, GetCurrentPosition());
@@ -319,7 +380,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 +388,31 @@ 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
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetAnyExpressionMetadata(platform, functionFullName);
auto parametersNode = Parameters(metadata.parameters);
auto function =
gd::make_unique<FunctionCallNode>(functionFullName);
auto parametersNode = Parameters(function.get());
function->parameters = std::move(parametersNode.parameters);
gd::make_unique<FunctionCallNode>(metadata.GetReturnType(),
std::move(parametersNode.parameters),
metadata,
functionFullName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, identifierLocation.GetStartPosition());
function->location = ExpressionParserLocation(
identifierLocation.GetStartPosition(), GetCurrentPosition());
@@ -354,15 +424,16 @@ class GD_CORE_API ExpressionParser2 {
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 +441,63 @@ 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);
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetObjectAnyExpressionMetadata(
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),
metadata.GetReturnType(),
objectName,
std::move(parametersNode.parameters),
metadata,
objectFunctionOrBehaviorName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *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 +513,26 @@ class GD_CORE_API ExpressionParser2 {
if (CheckIfChar(IsOpeningParenthesis)) {
ExpressionParserLocation openingParenthesisLocation = SkipChar();
gd::String behaviorType = GetTypeOfBehavior(
globalObjectsContainer, objectsContainer, behaviorName);
const gd::ExpressionMetadata &metadata =
MetadataProvider::GetBehaviorAnyExpressionMetadata(
platform, behaviorType, functionName);
auto parametersNode =
Parameters(metadata.parameters, objectName, behaviorName);
auto function = gd::make_unique<FunctionCallNode>(
metadata.GetReturnType(),
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) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
objectNameLocation.GetStartPosition(), GetCurrentPosition());
@@ -470,7 +548,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,7 +572,7 @@ 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;
@@ -505,25 +583,77 @@ class GD_CORE_API ExpressionParser2 {
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, lastObjectName.empty() ? objectName : lastObjectName));
} else if (gd::ParameterMetadata::IsObject(type)) {
size_t parameterStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> objectExpression = Expression(type);
SkipAllWhitespaces();
previousCharacterIsParameterSeparator = CheckIfChar(IsParameterSeparator);
SkipIfChar(IsParameterSeparator);
parameterIndex++;
// Memorize the last object name. By convention, parameters that
// require an object (mainly, "objectvar" and "behavior") should be
// placed after the object in the list of parameters (if possible,
// just after). Search "lastObjectName" in the codebase for other
// place where this convention is enforced.
if (auto identifierNode =
dynamic_cast<IdentifierNode *>(objectExpression.get())) {
lastObjectName = identifierNode->identifierName;
} else {
objectExpression->diagnostic =
gd::make_unique<ExpressionParserError>(
"malformed_object_parameter",
_("An object name was expected but something else was "
"written. Enter just the name of the object for this "
"parameter."),
parameterStartPosition,
GetCurrentPosition());
}
parameters.push_back(std::move(objectExpression));
} 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();
SkipIfChar(IsParameterSeparator);
parameterIndex++;
}
}
ExpressionParserLocation invalidClosingParenthesisLocation;
@@ -535,32 +665,92 @@ class GD_CORE_API ExpressionParser2 {
}
///@}
/** \name Validators
* Return a diagnostic if any error is found
*/
///@{
std::unique_ptr<ExpressionParserDiagnostic> ValidateFunction(
const gd::String &type,
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(
const gd::String &type,
gd::String::value_type operatorChar,
size_t position) {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
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 -."),
position);
} 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)."),
position);
} 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."),
position);
} 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."),
position);
}
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>();
}
///@}
@@ -748,7 +938,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 +947,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 +961,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 +994,34 @@ 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));
}
///@}
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

@@ -17,12 +17,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 +42,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 +55,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,8 +84,8 @@ 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 {
ExpressionNode(const gd::String &type_) : type(type_){};
virtual ~ExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker){};
@@ -102,12 +96,17 @@ struct GD_CORE_API ExpressionNode {
/// function can store the position of the
/// object name, the dot, the function
/// name, etc...
ExpressionNode *parent;
gd::String type; // Actual type of the node.
// "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
};
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_)
: ExpressionNode(type_), expression(std::move(expression_)){};
virtual ~SubExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitSubExpressionNode(*this);
@@ -119,9 +118,9 @@ struct GD_CORE_API SubExpressionNode : public ExpressionNode {
/**
* \brief An operator node. For example: "lhs + rhs".
*/
struct GD_CORE_API OperatorNode : public ExpressionNode {
OperatorNode(gd::String::value_type op_)
: ExpressionNode(), op(op_){};
struct OperatorNode : public ExpressionNode {
OperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(type_), op(op_){};
virtual ~OperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitOperatorNode(*this);
@@ -135,9 +134,9 @@ struct GD_CORE_API OperatorNode : public ExpressionNode {
/**
* \brief A unary operator node. For example: "-2".
*/
struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
UnaryOperatorNode(gd::String::value_type op_)
: ExpressionNode(), op(op_){};
struct UnaryOperatorNode : public ExpressionNode {
UnaryOperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(type_), op(op_){};
virtual ~UnaryOperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitUnaryOperatorNode(*this);
@@ -151,9 +150,9 @@ struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
* \brief A number node. For example: "123".
* Its `type` is always "number".
*/
struct GD_CORE_API NumberNode : public ExpressionNode {
struct NumberNode : public ExpressionNode {
NumberNode(const gd::String &number_)
: ExpressionNode(), number(number_){};
: ExpressionNode("number"), number(number_){};
virtual ~NumberNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitNumberNode(*this);
@@ -167,8 +166,8 @@ struct GD_CORE_API NumberNode : public ExpressionNode {
* \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_) : ExpressionNode("string"), text(text_){};
virtual ~TextNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitTextNode(*this);
@@ -177,88 +176,32 @@ 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 {
VariableAccessorOrVariableBracketAccessorNode() : 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_)
: ExpressionNode(type_), name(name_), objectName(objectName_){};
virtual ~VariableNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableNode(*this);
};
gd::String name;
gd::String objectName;
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>
child; // Can be nullptr if no accessor
@@ -270,10 +213,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 +230,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 +242,55 @@ struct GD_CORE_API VariableBracketAccessorNode
std::unique_ptr<ExpressionNode> expression;
};
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(
const gd::String &type)
: ExpressionNode(type){};
};
/**
* \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_)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type_),
identifierName(identifierName_){};
virtual ~IdentifierNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitIdentifierNode(*this);
};
gd::String identifierName;
};
struct FunctionCallOrObjectFunctionNameOrEmptyNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
FunctionCallOrObjectFunctionNameOrEmptyNode(const gd::String &type)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type){};
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(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(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(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(behaviorName_),
behaviorFunctionName(behaviorFunctionName_) {}
@@ -360,26 +331,41 @@ struct GD_CORE_API ObjectFunctionNameNode
* For example: "MyExtension::MyFunction(1, 2)", "MyObject.Function()" or
* "MyObject.Physics::LinearVelocity()".
*/
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
/** \brief Construct a free function call node. */
FunctionCallNode(const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
FunctionCallNode(const gd::String &type_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
/** \brief Construct an object function call node. */
FunctionCallNode(const gd::String &objectName_,
FunctionCallNode(const gd::String &type_,
const gd::String &objectName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(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(),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
behaviorName(behaviorName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
virtual ~FunctionCallNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
@@ -389,6 +375,7 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
gd::String objectName;
gd::String behaviorName;
std::vector<std::unique_ptr<ExpressionNode>> parameters;
const ExpressionMetadata &expressionMetadata;
gd::String functionName;
ExpressionParserLocation
@@ -412,9 +399,9 @@ 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_ = "")
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_), text(text_){};
virtual ~EmptyNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitEmptyNode(*this);

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"
@@ -184,8 +183,8 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
for (std::size_t j = 0;
j < parameters.size() && j < metadata.parameters.size();
++j) {
if (metadata.parameters[j].GetType() == "relationalOperator" ||
metadata.parameters[j].GetType() == "operator") {
if (metadata.parameters[j].type == "relationalOperator" ||
metadata.parameters[j].type == "operator") {
if (j == parameters.size() - 1) {
std::cout << "ERROR: No more parameters after a [relational]operator "
"when trying to update an instruction from GD2.x";
@@ -219,8 +218,8 @@ void EventsListSerialization::UnserializeEventsFrom(
event = std::make_shared<EmptyEvent>();
}
event->SetDisabled(eventElem.GetBoolAttribute("disabled", false));
event->SetFolded(eventElem.GetBoolAttribute("folded", false));
event->SetDisabled(eventElem.GetBoolAttribute("disabled"));
event->SetFolded(eventElem.GetBoolAttribute("folded"));
list.InsertEvent(event, list.GetEventsCount());
}
@@ -233,9 +232,8 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
const gd::BaseEvent& event = list.GetEvent(j);
SerializerElement& eventElem = events.AddChild("event");
if (event.IsDisabled())
eventElem.SetAttribute("disabled", event.IsDisabled());
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
eventElem.SetAttribute("disabled", event.IsDisabled());
eventElem.SetAttribute("folded", event.IsFolded());
eventElem.AddChild("type").SetValue(event.GetType());
event.SerializeTo(eventElem);
@@ -269,9 +267,6 @@ void gd::EventsListSerialization::UnserializeInstructionsFrom(
instrElement.GetChild("type", 0, "Type")
.GetBoolAttribute("inverted", false, "Contraire"));
instruction.SetAwaited(
instrElement.GetChild("type", 0, "Type").GetBoolAttribute("await"));
// Read parameters
vector<gd::Expression> parameters;
@@ -345,12 +340,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
instructions.ConsiderAsArrayOf("instruction");
for (std::size_t k = 0; k < list.size(); k++) {
SerializerElement& instruction = instructions.AddChild("instruction");
instruction.AddChild("type").SetAttribute("value", list[k].GetType());
if (list[k].IsInverted())
instruction.GetChild("type").SetAttribute("inverted", true);
if (list[k].IsAwaited())
instruction.GetChild("type").SetAttribute("await", true);
instruction.AddChild("type")
.SetAttribute("value", list[k].GetType())
.SetAttribute("inverted", list[k].IsInverted());
// Parameters
SerializerElement& parameters = instruction.AddChild("parameters");
@@ -360,10 +352,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
.SetValue(list[k].GetParameter(l).GetPlainString());
// Sub instructions
if (!list[k].GetSubInstructions().empty()) {
SerializeInstructionsTo(list[k].GetSubInstructions(),
instruction.AddChild("subInstructions"));
}
SerializerElement& subInstructions =
instruction.AddChild("subInstructions");
SerializeInstructionsTo(list[k].GetSubInstructions(), subInstructions);
}
}

View File

@@ -11,16 +11,26 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
gd::PlatformExtension& extension) {
extension.SetExtensionInformation(
"BuiltinAdvanced",
_("Advanced control features"),
_("Advanced control features to be used in events."),
"Florian Rival",
"Open source (MIT License)");
#if defined(GD_IDE_ONLY)
extension
.SetExtensionInformation(
"BuiltinAdvanced",
_("Event functions"),
_("Advanced control features for functions made with events."),
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Event functions"))
.SetIcon("res/function32.png");
.AddCondition("Toujours",
_("Always"),
_("This condition always returns true (or always false, if "
"the condition is inverted)."),
_("Always"),
_("Other"),
"res/conditions/toujours24.png",
"res/conditions/toujours.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
extension
.AddAction(
@@ -29,12 +39,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the events function to the specified "
"number (to be used with \"Expression\" functions)."),
_("Set return value to number _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("expression", _("The number to be returned"))
.SetRelevantForFunctionEventsOnly()
.AddParameter("expression", "The number to be returned")
.MarkAsAdvanced();
extension
@@ -44,12 +53,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the events function to the specified text "
"(to be used with \"String Expression\" functions)."),
_("Set return value to text _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("string", _("The text to be returned"))
.SetRelevantForFunctionEventsOnly()
.AddParameter("string", "The text to be returned")
.MarkAsAdvanced();
extension
@@ -58,42 +66,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Set the return value of the Condition events function to "
"either true (condition will pass) or false."),
_("Set return value of the condition to _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
_("Functions"),
"res/function24.png",
"res/function16.png")
.SetHelpPath("/events/functions/return")
.AddParameter("trueorfalse", _("Should the condition be true or false?"))
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
extension
.AddAction("CopyArgumentToVariable",
_("Copy function parameter to variable"),
_("Copy a function parameter (also called \"argument\") to a variable. "
"The parameter type must be a variable."),
_("Copy the parameter _PARAM0_ into the variable _PARAM1_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable"))
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
extension
.AddAction("CopyVariableToArgument",
_("Copy variable to function parameter"),
_("Copy a variable to function parameter (also called \"argument\"). "
"The parameter type must be a variable."),
_("Copy the variable _PARAM1_ into the parameter _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable"))
.SetRelevantForFunctionEventsOnly()
.AddParameter("trueorfalse", "Should the condition be true or false?")
.MarkAsAdvanced();
extension
@@ -104,60 +81,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"a string, an empty string is considered as \"false\". "
"If it's a number, 0 is considered as \"false\"."),
_("Parameter _PARAM0_ is true"),
"",
"res/function32.png",
"res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly()
_("Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("string", "Parameter name")
.MarkAsAdvanced();
extension
.AddExpression(
"GetArgumentAsNumber",
_("Get function parameter value"),
_("Get function parameter (also called \"argument\") value."),
"",
_("Get function parameter (also called \"argument\") value"),
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly();
.AddParameter("string", "Parameter name");
extension
.AddStrExpression(
"GetArgumentAsString",
_("Get function parameter text"),
_("Get function parameter (also called \"argument\") text."),
"",
_("Get function parameter (also called \"argument\") text "),
_("Functions"),
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly();
extension
.AddCondition(
"CompareArgumentAsNumber",
_("Compare function parameter value"),
_("Compare function parameter (also called \"argument\") value."),
_("Parameter _PARAM0_"),
"",
"res/function32.png",
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
extension
.AddCondition(
"CompareArgumentAsString",
_("Compare function parameter text"),
_("Compare function parameter (also called \"argument\") text."),
_("Parameter _PARAM0_"),
"",
"res/function32.png",
"res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.AddParameter("string", "Parameter name");
#endif
}
} // namespace gd

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,47 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Events/Builtin/AsyncEvent.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAsyncExtension(
gd::PlatformExtension &extension) {
extension
.SetExtensionInformation(
"BuiltinAsync",
_("Asynchronous functions"),
_("Functions that defer the execution of the events after it."),
"Arthur Pacaud (arthuro555)",
"Open source (MIT License)")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Asynchronous functions"))
.SetIcon("res/function32.png");
extension.AddEvent("Async",
_("Async event"),
_("Internal event for asynchronous actions"),
"",
"res/eventaddicon.png",
std::make_shared<gd::AsyncEvent>());
extension
.AddAction(
"ResolveAsyncEventsFunction",
_("End asynchronous function"),
_("Mark an asynchronous function as finished. This will allow the "
"actions and subevents following it to be run."),
"Mark asynchronous function as ended",
"",
"res/actions/quit24.png",
"res/actions/quit.png")
.AddCodeOnlyParameter("eventsFunctionContext", "")
.SetRelevantForAsynchronousFunctionEventsOnly();
}
} // namespace gd

View File

@@ -14,18 +14,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.SetExtensionInformation(
"BuiltinAudio",
_("Sounds and music"),
_("Audio"),
_("GDevelop provides several conditions and actions to play audio "
"files. They can be either long music or short sound effects."),
"files. They can be either long musics or short sound effects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/audio")
.SetCategory("Audio");
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and music"))
.SetIcon("res/actions/music24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds on channels"))
.SetIcon("res/actions/son24.png");
.SetExtensionHelpPath("/all-features/audio");
#if defined(GD_IDE_ONLY)
extension
.AddAction("PlaySoundCanal",
_("Play a sound on a channel"),
@@ -33,7 +29,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"you'll be able to manipulate it."),
_("Play the sound _PARAM1_ on the channel _PARAM2_, vol.: "
"_PARAM4_, loop: _PARAM3_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -54,7 +50,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Stop the sound of a channel"),
_("Stop the sound on the specified channel."),
_("Stop the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -66,7 +62,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Pause the sound of a channel"),
_("Pause the sound played on the specified channel."),
_("Pause the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -75,10 +71,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.AddAction("RePlaySoundCanal",
_("Resume playing a sound on a channel"),
_("Resume playing a sound on a channel that was paused."),
_("Resume the sound of channel _PARAM1_"),
_("Sounds on channels"),
_("Play the sound of a channel"),
_("Play the sound of the channel."),
_("Play the sound of channel _PARAM1_"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -92,7 +88,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"able to interact with it later."),
_("Play the music _PARAM1_ on channel _PARAM2_, vol.: "
"_PARAM4_, loop: _PARAM3_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -113,7 +109,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Stop the music on a channel"),
_("Stop the music on the specified channel"),
_("Stop the music of channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -125,7 +121,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Pause the music of a channel"),
_("Pause the music on the specified channel."),
_("Pause the music of channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -134,10 +130,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension
.AddAction("RePlayMusicCanal",
_("Resume playing a music on a channel"),
_("Resume playing a music on a channel that was paused."),
_("Resume the music of channel _PARAM1_"),
_("Music on channels"),
_("Play the music of a channel"),
_("Play the music of the channel."),
_("Play the music of channel _PARAM1_"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -148,83 +144,69 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.AddAction("ModVolumeSoundCanal",
_("Volume of the sound on a channel"),
_("This action modifies the volume of the sound on the "
"specified channel."),
"specified channel. The volume is between 0 and 100."),
_("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/sonVolume24.png",
"res/actions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddAction("ModVolumeMusicCanal",
_("Volume of the music on a channel"),
_("This action modifies the volume of the music on the "
"specified channel."),
"specified channel. The volume is between 0 and 100."),
_("the volume of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/musicVolume24.png",
"res/actions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddAction("ModGlobalVolume",
_("Game global volume"),
_("This action modifies the global volume of the game."),
_("This action modifies the global volume of the game. The "
"volume is between 0 and 100."),
_("the global sound level"),
"",
_("Audio"),
"res/actions/volume24.png",
"res/actions/volume.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.UseStandardOperatorParameters("number")
.MarkAsSimple();
extension
.AddAction("ModPitchSoundChannel",
_("Pitch of the sound of a channel"),
_("This action modifies the pitch (speed) of the sound on a "
"channel."),
"channel.\n1 is the default pitch."),
_("the pitch of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch (1 by default)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddAction("ModPitchMusicChannel",
_("Pitch of the music on a channel"),
_("This action modifies the pitch of the music on the "
"specified channel."),
"specified channel. 1 is the default pitch"),
_("the pitch of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch (1 by default)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -233,15 +215,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the playing offset of the sound on a "
"channel"),
_("the playing offset of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position (in seconds)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -250,15 +229,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("This action modifies the playing offset of the music on "
"the specified channel"),
_("the playing offset of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position (in seconds)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -266,7 +242,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Play a sound"),
_("Play a sound."),
_("Play the sound _PARAM1_, vol.: _PARAM3_, loop: _PARAM2_"),
"",
_("Audio"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -286,7 +262,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", "")
@@ -306,7 +282,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Preload a music file"),
_("Preload a music file in memory."),
_("Preload the music file _PARAM1_"),
_("Loading"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -318,7 +294,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Preload a sound file"),
_("Preload a sound file in memory."),
_("Preload the sound file _PARAM1_"),
_("Loading"),
_("Audio/Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -326,80 +302,55 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.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")
.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_"),
_("Audio/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")
.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_"),
_("Audio/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")
.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"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsComplex();
extension
.AddAction(
"FadeSoundVolume",
_("Fade the volume of a sound played on a channel."),
_("Fade the volume of a sound played on a channel to the specified volume within the specified duration."),
_("Fade the sound on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
_("Sounds on channels"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.AddParameter("expression", _("Final volume (0-100)"))
.AddParameter("expression", _("Fading time in seconds"))
.MarkAsAdvanced();
extension
.AddAction(
"FadeMusicVolume",
_("Fade the volume of a music played on a channel."),
_("Fade the volume of a music played on a channel to the specified volume within the specified duration."),
_("Fade the music on channel _PARAM1_ to volume _PARAM2_ within _PARAM3_ seconds"),
_("Music on channels"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.AddParameter("expression", _("Final volume (0-100)"))
.AddParameter("expression", _("Fading time in seconds"))
.MarkAsAdvanced();
extension
.AddCondition("MusicPlaying",
_("A music file is being played"),
_("Test if the music on a channel is being played"),
_("Music on channel _PARAM1_ is being played"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicplaying24.png",
"res/conditions/musicplaying.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -411,7 +362,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A music file is paused"),
_("Test if the music on the specified channel is paused."),
_("Music on channel _PARAM1_ is paused"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicpaused24.png",
"res/conditions/musicpaused.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -423,7 +374,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A music file is stopped"),
_("Test if the music on the specified channel is stopped."),
_("Music on channel _PARAM1_ is stopped"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicstopped24.png",
"res/conditions/musicstopped.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -435,7 +386,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is being played"),
_("Test if the sound on a channel is being played."),
_("Sound on channel _PARAM1_ is being played"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonplaying24.png",
"res/conditions/sonplaying.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -447,7 +398,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is paused"),
_("Test if the sound on the specified channel is paused."),
_("Sound on channel _PARAM1_ is paused"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonpaused24.png",
"res/conditions/sonpaused.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -459,7 +410,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("A sound is stopped"),
_("Test if the sound on the specified channel is stopped."),
_("Sound on channel _PARAM1_ is stopped"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonstopped24.png",
"res/conditions/sonstopped.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -470,17 +421,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.AddCondition(
"SoundCanalVolume",
_("Volume of the sound on a channel"),
_("Test the volume of the sound on the specified channel."),
_("Test the volume of the sound on the specified channel. The volume "
"is between 0 and 100."),
_("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -490,15 +439,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the volume of the music on a specified channel. The volume "
"is between 0 and 100."),
_("the volume of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -507,14 +453,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Global volume"),
_("Test the global sound level. The volume is between 0 and 100."),
_("the global game volume"),
"",
_("Audio"),
"res/conditions/volume24.png",
"res/conditions/volume.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")));
.UseStandardRelationalOperatorParameters("number");
extension
.AddCondition(
@@ -523,32 +466,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Test the pitch of the sound on the specified channel. 1 is the "
"default pitch."),
_("the pitch of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch to compare to (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddCondition(
"MusicChannelPitch",
_("Pitch of the music on a channel"),
_("Test the pitch (speed) of the music on a specified channel."),
_("Test the pitch (speed) of the music on a specified channel. 1 is "
"the default pitch."),
_("the pitch of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch to compare to (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -557,15 +495,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Playing offset of the sound on a channel"),
_("Test the playing offset of the sound on the specified channel."),
_("the playing offset of the sound on channel _PARAM1_"),
_("Sounds on channels"),
_("Audio/Sounds on channels"),
"res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position to compare to (in seconds)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -574,15 +509,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
_("Playing offset of the music on a channel"),
_("Test the playing offset of the music on the specified channel."),
_("the playing offset of the music on channel _PARAM1_"),
_("Music on channels"),
_("Audio/Music on channels"),
"res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position to compare to (in seconds)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -646,6 +578,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

@@ -15,83 +15,59 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.SetExtensionInformation(
"BuiltinCamera",
_("Layers and cameras"),
_("Cameras and layers features"),
"Each scene can be composed of multiple layers. These conditions "
"and actions allow to manipulate them during the game. In "
"particular, you can move the camera of a layer to center it on an "
"object or a position.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Camera")
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
.SetIcon("res/conditions/camera24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect24.png");
#if defined(GD_IDE_ONLY)
extension
.AddExpressionAndConditionAndAction(
"number",
"CameraCenterX",
"CameraX",
_("Camera center X position"),
_("the X position of the center of a camera"),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.UseStandardParameters("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",
"CameraY",
_("Camera center Y position"),
_("the Y position of the center of a camera"),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.UseStandardParameters("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(
@@ -100,13 +76,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Width of a camera"),
_("the width of a camera of a layer"),
_("the width of camera _PARAM2_ of layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("expression", _("Camera number"))
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
@@ -116,81 +92,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Height of a camera"),
_("the height of a camera of a layer"),
_("the height of camera _PARAM2_ of layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.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")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderRight",
_("Camera right border position"),
_("the position of the right border of a camera"),
_("the position of the right border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderTop",
_("Camera top border position"),
_("the position of the top border of a camera"),
_("the position of the top border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderBottom",
_("Camera bottom border position"),
_("the position of the bottom border of a camera"),
_("the position of the bottom border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("expression", _("Camera number"))
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
@@ -198,13 +106,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"number",
"CameraAngle",
_("Angle of a camera of a layer"),
_("the angle of rotation of a camera (in degrees)"),
_("the angle of rotation of a camera"),
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
"",
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
@@ -220,11 +128,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Add a camera to a layer"),
_("This action adds a camera to a layer"),
_("Add a camera to layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Width"), "", true)
.AddParameter("expression", _("Height"), "", true)
@@ -255,11 +163,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Delete a camera of a layer"),
_("Remove the specified camera from a layer"),
_("Delete camera _PARAM2_ from layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.MarkAsComplex();
@@ -271,11 +179,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"layer. The zoom will be reset."),
_("Change the size of camera _PARAM2_ of _PARAM1_ to "
"_PARAM3_*_PARAM4_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.AddParameter("expression", _("Width"))
@@ -289,11 +197,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"specified layer."),
_("Set the render zone of camera _PARAM2_ from layer _PARAM1_ "
"to _PARAM3_;_PARAM4_ _PARAM5_;_PARAM6_"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.AddParameter(
@@ -312,22 +220,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.AddAction("ZoomCamera",
_("Camera zoom"),
_("Change camera zoom"),
_("Change camera zoom."),
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
"_PARAM3_)"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression",
_("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)"))
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// TODO Deprecated: hide this action in a future release.
extension
.AddAction(
"FixCamera",
@@ -336,7 +243,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"specified limits."),
_("Center the camera on _PARAM1_ (limit : from _PARAM2_;_PARAM3_ to "
"_PARAM4_;_PARAM5_) (layer: _PARAM7_, camera: _PARAM8_)"),
"",
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -354,41 +261,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"",
true)
.SetDefaultValue("yes")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction("ClampCamera",
_("Enforce camera boundaries"),
_("Enforce camera boundaries by moving the camera back inside "
"specified boundaries."),
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
"",
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Left bound X Position"))
.AddParameter("expression", _("Top bound Y Position"))
.AddParameter("expression", _("Right bound X Position"))
.AddParameter("expression", _("Bottom bound Y Position"))
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction("CentreCamera",
_("Center the camera on an object"),
_("Center the camera on the specified object."),
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
"",
"res/actions/camera24.png",
"res/actions/camera.png")
.AddAction(
"CentreCamera",
_("Center the camera on an object"),
_("Center the camera on the specified object."),
_("Center camera on _PARAM1_ (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("objectPtr", _("Object"))
.AddParameter("yesorno",
@@ -396,7 +283,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"",
true)
.SetDefaultValue("yes")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
@@ -407,11 +294,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Show a layer"),
_("Show a layer."),
_("Show layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -420,11 +307,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Hide a layer"),
_("Hide a layer."),
_("Hide layer _PARAM1_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -433,11 +320,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Visibility of a layer"),
_("Test if a layer is set as visible."),
_("Layer _PARAM1_ is visible"),
"",
_("Layers and cameras"),
"res/conditions/layer24.png",
"res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.MarkAsAdvanced();
@@ -449,14 +336,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"),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("expression", _("New value"))
.MarkAsAdvanced();
@@ -468,14 +355,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"),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("string", _("New value"))
.MarkAsAdvanced();
@@ -487,14 +374,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"),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("Effect"))
.AddParameter("string", _("Parameter name"))
.AddParameter("yesorno", _("Enable this parameter"))
.MarkAsAdvanced();
@@ -503,13 +390,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Layer effect is enabled"),
_("The effect on a layer is enabled"),
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
_(""),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("string", _("Effect"))
.MarkAsAdvanced();
extension
@@ -517,13 +404,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Enable layer effect"),
_("Enable an effect on a layer"),
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
_("Effects"),
"res/actions/effect24.png",
"res/actions/effect.png")
_("Layers and cameras/Effects"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name"))
.AddParameter("string", _("Effect"))
.AddParameter("yesorno", _("Enable"), "", true)
.MarkAsAdvanced();
@@ -533,16 +420,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Layer time scale"),
_("Compare the time scale applied to the objects of the layer."),
_("the time scale of layer _PARAM1_"),
"",
_("Layers and cameras/Time"),
"res/conditions/time24.png",
"res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters(
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Time scale (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -550,12 +434,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"ChangeLayerTimeScale",
_("Change layer time scale"),
_("Change the time scale applied to the objects of the layer."),
_("Set the time scale of layer _PARAM1_ to _PARAM2_"),
"",
_("Set time scale of layer _PARAM1_ to _PARAM2_"),
_("Layers and cameras/Time"),
"res/actions/time24.png",
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression",
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
@@ -566,28 +450,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Compare the default Z order set to objects when they "
"are created on a layer."),
_("the default Z order of objects created on _PARAM1_"),
"",
_("Layers and cameras"),
"res/conditions/layer24.png",
"res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddAction("SetLayerDefaultZOrder",
_("Layer default Z order"),
_("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_"),
"",
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("New default Z order"));
@@ -598,11 +481,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("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_"),
_(""),
_("Layers and cameras/Lighting"),
"res/actions/color24.png",
"res/actions/color.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"Lighting\"")
.AddParameter("color", _("Color"))
.MarkAsAdvanced();
@@ -612,7 +495,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportLeft",
_("X position of the top left side point of a render zone"),
_("X position of the top left side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -624,7 +507,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportTop",
_("Y position of the top left side point of a render zone"),
_("Y position of the top left side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -636,7 +519,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"CameraViewportRight",
_("X position of the bottom right side point of a render zone"),
_("X position of the bottom right side point of a render zone"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
@@ -648,7 +531,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"))
@@ -659,7 +542,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddExpression("CameraZoom",
_("Zoom of a camera of a layer"),
_("Zoom of a camera of a layer"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
@@ -669,9 +552,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
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"));
@@ -680,10 +563,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddExpression("LayerDefaultZOrder",
_("Default Z Order for a layer"),
_("Default Z Order for a layer"),
"",
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));
#endif
}
} // namespace gd

View File

@@ -15,28 +15,28 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
extension
.SetExtensionInformation(
"BuiltinCommonConversions",
_("Conversion"),
_("Standard Conversions"),
"Expressions to convert number, texts and quantities.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/common-conversions");
extension.AddInstructionOrExpressionGroupMetadata(_("Conversion"))
.SetIcon("res/conditions/toujours24_black.png");
#if defined(GD_IDE_ONLY)
extension
.AddExpression("ToNumber",
_("Text > Number"),
_("Convert the text to a number"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to convert to a number"));
extension
.AddStrExpression("ToString",
_("Number > Text"),
_("Convert the result of the expression to text"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
extension
@@ -44,8 +44,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Number > Text ( without scientific notation )"),
_("Convert the result of the expression to text, "
"without using the scientific notation"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text"));
extension
@@ -53,8 +53,8 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToRad",
_("Degrees > Radians"),
_("Converts the angle, expressed in degrees, into radians"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in degrees"));
extension
@@ -62,76 +62,10 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"ToDeg",
_("Radians > Degrees"),
_("Converts the angle, expressed in radians, into degrees"),
"",
"res/conditions/toujours24_black.png")
_("Conversion"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in radians"));
extension
.AddStrExpression("ToJSON",
_("Convert scene variable to JSON"),
_("Convert a scene variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("scenevar", _("Scene variable to be stringified"));
extension
.AddStrExpression("GlobalVarToJSON",
_("Convert global variable to JSON"),
_("Convert a global variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("globalvar", _("The global variable to be stringified"));
extension
.AddStrExpression("ObjectVarToJSON",
_("Convert object variable to JSON"),
_("Convert an object variable to JSON"),
_("JSON"),
"res/conditions/toujours24_black.png")
.AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified"));
extension
.AddAction(
"JSONToVariableStructure",
_("Convert JSON to a scene variable"),
_("Parse a JSON object and store it into a scene variable"),
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("scenevar", _("Variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToGlobalVariableStructure",
_("Convert JSON to global variable"),
_("Parse a JSON object and store it into a global variable"),
_("Convert JSON string _PARAM0_ and store it into global "
"variable _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("globalvar",
_("Global variable where store the JSON object"))
.MarkAsAdvanced();
extension
.AddAction("JSONToObjectVariableStructure",
_("Convert JSON to object variable"),
_("Parse a JSON object and store it into an object variable"),
_("Parse JSON string _PARAM0_ and store it into variable "
"_PARAM2_ of _PARAM1_"),
"",
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("JSON string"))
.AddParameter("objectPtr", _("Object"))
.AddParameter("objectvar",
_("Object variable where store the JSON object"))
.MarkAsAdvanced();
#endif
}
} // namespace gd

View File

@@ -4,6 +4,8 @@
* 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"
@@ -13,7 +15,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,45 +26,22 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
extension
.SetExtensionInformation(
"BuiltinCommonInstructions",
_("Events and control flow"),
_("Builtin events"),
"GDevelop comes with a set of events and conditions that allow to "
"express the game logic and rules.",
"Florian Rival",
"Open source (MIT License)")
.SetCategory("Advanced")
.SetExtensionHelpPath("/all-features/advanced-conditions");
extension
.AddInstructionOrExpressionGroupMetadata(_("Events and control flow"))
.SetIcon("res/conditions/toujours24_black.png");
extension
.AddCondition("Always",
_("Always"),
_("This condition always returns true (or always false, if "
"the condition is inverted)."),
_("Always"),
"",
"res/conditions/toujours24_black.png",
"res/conditions/toujours_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();
// 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"),
_("If one of these conditions is true:"),
"",
"res/conditions/or24_black.png",
"res/conditions/or_black.png")
_("Advanced"),
"res/conditions/or24.png",
"res/conditions/or.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -71,9 +50,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("And"),
_("Check if all sub conditions are true"),
_("If all of these conditions are true:"),
"",
"res/conditions/and24_black.png",
"res/conditions/and_black.png")
_("Advanced"),
"res/conditions/and24.png",
"res/conditions/and.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -83,9 +62,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Not"),
_("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"),
"",
"res/conditions/not24_black.png",
"res/conditions/not_black.png")
_("Advanced"),
"res/conditions/not24.png",
"res/conditions/not.png")
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
@@ -94,52 +73,10 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Trigger once while true"),
_("Run actions only once, for each time the conditions have been met."),
_("Trigger once"),
"",
_("Advanced"),
"res/conditions/once24.png",
"res/conditions/once.png");
extension
.AddCondition("CompareNumbers",
_("Compare two numbers"),
_("Compare the two numbers."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
"",
"res/conditions/egal24_black.png",
"res/conditions/egal_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("expression", _("First expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "number")
.AddParameter("expression", _("Second expression"))
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.127
extension
.AddDuplicatedCondition(
"Egal", "BuiltinCommonInstructions::CompareNumbers", {.unscoped = true})
.SetHidden();
// end of compatibility code
extension
.AddCondition("CompareStrings",
_("Compare two strings"),
_("Compare the two strings."),
_("_PARAM0_ _PARAM1_ _PARAM2_"),
"",
"res/conditions/egal24_black.png",
"res/conditions/egal_black.png")
.SetHelpPath("/all-features/advanced-conditions")
.AddParameter("string", _("First string expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "string")
.AddParameter("string", _("Second string expression"))
.MarkAsAdvanced();
// Compatibility with GD <= 5.0.127
extension
.AddDuplicatedCondition(
"StrEqual", "BuiltinCommonInstructions::CompareStrings", {.unscoped = true})
.SetHidden();
// end of compatibility code
extension.AddEvent(
"Standard",
_("Standard event"),
@@ -149,29 +86,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>());
@@ -192,11 +129,12 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
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

@@ -19,26 +19,25 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
"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");
.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

@@ -20,11 +20,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"stored on the device and erased when the game is uninstalled.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage")
.SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Storage"))
.SetIcon("res/conditions/fichier24.png");
.SetExtensionHelpPath("/all-features/storage");
#if defined(GD_IDE_ONLY)
extension
.AddCondition(
"GroupExists",
@@ -32,7 +30,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 +46,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 +58,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 +73,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 +89,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"))
@@ -108,7 +106,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"(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"))
@@ -127,7 +125,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"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 +141,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 +154,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 +164,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,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.SetExtensionInformation(
"BuiltinKeyboard",
_("Keyboard"),
_("Keyboard features"),
_("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."),
"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 +38,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,35 +49,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"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -87,9 +85,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
extension
.AddCondition("AnyKeyReleased",
_("Any key released"),
_("Check if any key is released"),
_("Test if any key is released"),
_("Any key is released"),
"",
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -99,9 +97,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

@@ -18,63 +18,14 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"A set of mathematical functions that can be used in expressions.",
"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"));
#if defined(GD_IDE_ONLY)
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Remap a value between 0 and 1."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
@@ -84,7 +35,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.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,16 +45,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"));
.AddParameter("expression", _("First angle"))
.AddParameter("expression", _("Second angle"));
extension
.AddExpression("AngleBetweenPositions",
_("Angle between two positions"),
_("Compute the angle between two positions (in degrees)."),
"",
_("Compute the angle between two positions."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
@@ -114,7 +65,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("DistanceBetweenPositions",
_("Distance between two positions"),
_("Compute the distance between two positions."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
@@ -125,7 +76,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.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 +85,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 +94,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 +103,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 +119,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 +135,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 +151,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 +160,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("atanh",
_("Hyperbolic arctangent"),
_("Hyperbolic arctangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -220,7 +168,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cbrt",
_("Cube root"),
_("Cube root"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -228,42 +176,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 +200,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cosh",
_("Hyperbolic cosine"),
_("Hyperbolic cosine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -279,7 +208,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("cot",
_("Cotangent"),
_("Cotangent of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -287,7 +216,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("csc",
_("Cosecant"),
_("Cosecant of a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -295,7 +224,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("int",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -304,7 +233,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("rint",
_("Round"),
_("Round a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -313,24 +242,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 +258,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -346,7 +266,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("ln",
_("Logarithm"),
_("Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.SetHidden()
.AddParameter("expression", _("Expression"));
@@ -355,7 +275,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log2",
_("Base-2 logarithm"),
_("Base 2 Logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -363,7 +283,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("log10",
_("Base-10 logarithm"),
_("Base-10 logarithm"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -371,7 +291,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 +300,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 +309,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sec",
_("Secant"),
_("Secant"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -397,16 +317,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 +333,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("sinh",
_("Hyperbolic sine"),
_("Hyperbolic sine"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -422,16 +341,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 +357,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("tanh",
_("Hyperbolic tangent"),
_("Hyperbolic tangent"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -447,7 +365,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddExpression("trunc",
_("Truncation"),
_("Truncate a number"),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));
@@ -455,7 +373,7 @@ 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)"))
@@ -468,7 +386,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
@@ -480,28 +398,12 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
"",
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression("Pi",
_("Number Pi (3.1415...)"),
_("The number Pi (3.1415...)"),
"",
"res/mathfunction.png")
.SetHelpPath("/all-features/expressions");
extension
.AddExpression("lerpAngle",
_("Lerp (Linear interpolation) between two angles"),
_("Linearly interpolates between two angles (in degrees) by taking the shortest direction around the circle."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Starting angle, in degrees"))
.AddParameter("expression", _("Destination angle, in degrees"))
.AddParameter("expression", _("Interpolation value between 0 and 1."));
#endif
}
} // namespace gd

View File

@@ -23,13 +23,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"separately in different events.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/mouse-touch")
.SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Mouse and touch"))
.SetIcon("res/actions/mouse24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Multitouch"))
.SetIcon("res/conditions/touch24.png");
.SetExtensionHelpPath("/all-features/mouse-touch");
#if defined(GD_IDE_ONLY)
extension
.AddCondition(
"IsMouseWheelScrollingUp",
@@ -37,7 +33,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")
@@ -51,7 +47,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")
@@ -69,7 +65,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")
@@ -84,7 +80,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")
@@ -96,7 +92,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")
@@ -108,7 +104,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", "")
@@ -119,7 +115,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")
@@ -131,7 +127,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")
@@ -145,7 +141,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")
@@ -155,91 +151,42 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
extension
.AddExpressionAndCondition(
"number",
"CursorX",
"MouseX",
_("Cursor X position"),
_("the X position of the cursor or of a touch"),
_("the cursor (or touch) X position"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.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("MouseX", "CursorX").SetHidden();
extension.AddDuplicatedExpression("MouseX", "CursorX").SetHidden();
extension.AddDuplicatedCondition("SourisX", "CursorX").SetHidden();
extension.AddDuplicatedExpression("SourisX", "CursorX").SetHidden();
extension.AddDuplicatedCondition("SourisX", "MouseX").SetHidden();
extension.AddDuplicatedExpression("SourisX", "MouseX").SetHidden();
extension
.AddExpressionAndCondition(
"number",
"CursorY",
"MouseY",
_("Cursor Y position"),
_("the Y position of the cursor or of a touch"),
_("the cursor (or touch) Y position"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.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("MouseY", "CursorY").SetHidden();
extension.AddDuplicatedExpression("MouseY", "CursorY").SetHidden();
extension.AddDuplicatedCondition("SourisY", "CursorY").SetHidden();
extension.AddDuplicatedExpression("SourisY", "CursorY").SetHidden();
extension
.AddExpressionAndCondition("number",
"MouseOnlyCursorX",
_("Mouse cursor X position"),
_("the X position of the mouse cursor"),
_("the mouse cursor X position"),
"",
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
// It's only useful for extensions as they can't use TouchSimulateMouse.
.SetHidden();
extension
.AddExpressionAndCondition("number",
"MouseOnlyCursorY",
_("Mouse cursor Y position"),
_("the Y position of the mouse cursor"),
_("the mouse cursor Y position"),
"",
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
// It's only useful for extensions as they can't use TouchSimulateMouse.
.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"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsAdvanced();
extension.AddDuplicatedCondition("SourisY", "MouseY").SetHidden();
extension.AddDuplicatedExpression("SourisY", "MouseY").SetHidden();
extension
.AddCondition("MouseButtonPressed",
@@ -247,7 +194,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Check if the specified mouse button is pressed or "
"if a touch is in contact with the screen."),
_("Touch or _PARAM1_ mouse button is down"),
"",
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -263,61 +210,25 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Mouse button released"),
_("Check 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("mouse", _("Button to check"))
.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"),
"",
"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
.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"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
@@ -328,12 +239,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
_("Touch Y position"),
_("the Y position of a specific touch"),
_("the touch #_PARAM1_ Y position"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.AddParameter("layer", _("Layer"), "", true)
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
@@ -348,11 +259,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"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(
@@ -364,98 +274,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"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"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.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", "")
.SetHidden();
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", "")
.SetHidden();
extension
.AddExpression("StartedTouchId",
_("Started touch identifier"),
_("The identifier of the touch that has just started on "
"this frame. The number of touches can be "
"accessed using StartedTouchCount()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch index"))
.SetHidden();
extension
.AddCondition(
"HasAnyTouchOrMouseStarted",
_("A new touch has started"),
_("Check if a touch has just started or the mouse left button has "
"been pressed on this frame. The touch identifiers can be "
"accessed using StartedTouchOrMouseId() and "
"StartedTouchOrMouseCount()."),
_("A new touch has started"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchOrMouseCount",
_("Started touch count"),
_("The number of touches (including the mouse) that have just "
"started on this frame. The touch identifiers can be "
"accessed using StartedTouchOrMouseId()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression(
"StartedTouchOrMouseId",
_("Started touch identifier"),
_("The identifier of the touch or mouse that has just started on "
"this frame. The number of touches can be "
"accessed using StartedTouchOrMouseCount()."),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch index"));
extension
.AddCondition("HasTouchEnded",
_("A touch has ended"),
_("Check if a touch has ended or a mouse left button has "
"been released."),
_("The touch with identifier _PARAM1_ has ended"),
_("Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"));
extension
.AddExpression("MouseWheelDelta",
_("Mouse wheel: Displacement"),
@@ -468,19 +291,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddExpression("LastTouchId",
_("Identifier of the last touch"),
_("Identifier of the last touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("LastEndedTouchId",
_("Identifier of the last ended touch"),
_("Identifier of the last ended touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden();
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

@@ -14,16 +14,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
extension
.SetExtensionInformation(
"BuiltinNetwork",
_("Network"),
_("Basic internet features"),
_("Features to send web requests, communicate with external \"APIs\" "
"and other network related tasks."),
"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",
@@ -33,7 +31,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"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_",
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", "Host, with protocol")
@@ -48,7 +46,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
.AddParameter("string", "Content type", "", true)
.SetParameterLongDescription(
"If empty, \"application/x-www-form-urlencoded\" will be used.")
.AddParameter("scenevar", "Response scene variable", "", 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 "
@@ -68,7 +66,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"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)"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (API or web-page address)"))
@@ -95,37 +93,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"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\"."))
.SetParameterLongDescription(
_("Optional, only used if an error occurs. This will contain the "
"error message (if request could not be sent) or the [\"status "
"code\"](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), "
"if the server returns a status >= 400."))
.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)"))
@@ -143,11 +124,79 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"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_"),
"",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Enable the metrics?"));
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_"),
_("Network"),
"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_"),
_("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"),
_("Scene management features"),
_("Actions and conditions to manipulate the scenes during the game."),
"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,32 +96,19 @@ 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")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple();
extension
.AddCondition("DoesSceneExist",
_("Does scene exist"),
_("Check if scene exists."),
_("Scene _PARAM1_ exists"),
"",
"res/actions/texte.png",
"res/actions/texte.png")
.SetHelpPath("/interface/scene-editor/events")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Name of the scene to check"))
.MarkAsSimple();
extension
.AddAction("Scene",
_("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")
@@ -89,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")
@@ -104,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")
@@ -116,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")
@@ -125,10 +161,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
extension
.AddAction("SceneBackground",
_("Background color"),
_("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")
@@ -142,7 +178,7 @@ 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")
@@ -151,18 +187,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.MarkAsAdvanced();
extension
.AddCondition(
"HasGameJustResumed",
_("Game has just resumed"),
_("Check if the game has just resumed from being hidden. It "
"happens when the game tab is selected, a minimized window is "
"restored or the application is put back on front."),
_("Game has just resumed"),
"",
"res/actions/window24.png",
"res/actions/window.png")
.SetHelpPath("/interface/scene-editor/events")
.AddCodeOnlyParameter("currentScene", "");
.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"
@@ -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

@@ -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.
std::vector<Sprite> sprites; ///< The sprites of the direction.
#if defined(GD_IDE_ONLY)
gd::String metadata;
#endif
};
} // namespace gd

View File

@@ -31,7 +31,7 @@ class GD_CORE_API Point {
/**
* Change point position.
*/
void SetXY(double x_, double y_) {
void SetXY(float x_, float y_) {
x = x_;
y = y_;
}
@@ -39,27 +39,27 @@ class GD_CORE_API Point {
/**
* Change point X position.
*/
void SetX(double x_) { x = x_; }
void SetX(float x_) { x = x_; }
/**
* Change point Y position.
*/
void SetY(double y_) { y = y_; }
void SetY(float y_) { y = y_; }
/**
* Get point X position.
*/
double GetX() const { return x; }
float GetX() const { return x; }
/**
* Get point Y position.
*/
double GetY() const { return y; }
float GetY() const { return y; }
private:
gd::String name;
double x;
double y;
float x;
float y;
};
#endif // GDCORE_POINT_H

View File

@@ -4,15 +4,13 @@
* reserved. This project is released under the MIT License.
*/
#include "Polygon2d.h"
#include <SFML/System/Vector2.hpp>
#include <cmath>
#include <iostream>
#include "GDCore/Vector2.h"
void Polygon2d::Rotate(double angle) {
double t, cosa = cos(-angle),
sina = sin(-angle); // We want a clockwise rotation
void Polygon2d::Rotate(float angle) {
float t, cosa = cos(-angle),
sina = sin(-angle); // We want a clockwise rotation
for (std::size_t i = 0; i < vertices.size(); ++i) {
t = vertices[i].x;
@@ -21,7 +19,7 @@ void Polygon2d::Rotate(double angle) {
}
}
void Polygon2d::Move(double x, double y) {
void Polygon2d::Move(float x, float y) {
for (std::size_t i = 0; i < vertices.size(); i++) {
vertices[i].x += x;
vertices[i].y += y;
@@ -30,7 +28,7 @@ void Polygon2d::Move(double x, double 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++) {
@@ -52,20 +50,20 @@ bool Polygon2d::IsConvex() const {
(edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x) > 0;
for (std::size_t i = 1; i < edges.size() - 1; ++i) {
double zCrossProduct =
float zCrossProduct =
edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x;
if ((zCrossProduct > 0) != zProductIsPositive) return false;
}
double lastZCrossProduct = edges[edges.size() - 1].x * edges[0].y -
edges[edges.size() - 1].y * edges[0].x;
float lastZCrossProduct = edges[edges.size() - 1].x * edges[0].y -
edges[edges.size() - 1].y * edges[0].x;
if ((lastZCrossProduct > 0) != zProductIsPositive) return false;
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,12 +75,12 @@ gd::Vector2f Polygon2d::ComputeCenter() const {
return center;
}
Polygon2d Polygon2d::CreateRectangle(double width, double height) {
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,10 +5,9 @@
*/
#ifndef GDCORE_POLYGON_H
#define GDCORE_POLYGON_H
#include <SFML/System/Vector2.hpp>
#include <vector>
#include "GDCore/Vector2.h"
/**
* \brief Represents a polygon. Usually used for collisions masks.
*
@@ -23,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.
@@ -43,7 +42,7 @@ class GD_CORE_API Polygon2d {
* \note Edges are updated, there is no need to call ComputeEdges after
* calling Move.
*/
void Move(double x, double y);
void Move(float x, float y);
/**
* \brief Rotate the polygon.
@@ -53,7 +52,7 @@ class GD_CORE_API Polygon2d {
* \warning edges vector is not updated, you have to call ComputeEdges if
* needed.
*/
void Rotate(double angle);
void Rotate(float angle);
/**
* \brief Automatically fill edges vector using vertices.
@@ -69,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
@@ -78,7 +77,7 @@ class GD_CORE_API Polygon2d {
/**
* \brief Create a rectangle
*/
static Polygon2d CreateRectangle(double width, double height);
static Polygon2d CreateRectangle(float width, float height);
///@}
};

View File

@@ -4,6 +4,7 @@
* 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"

View File

@@ -6,6 +6,7 @@
#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"

View File

@@ -22,20 +22,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects/sprite");
extension.AddInstructionOrExpressionGroupMetadata(_("Sprite"))
.SetIcon("CppPlatform/Extensions/spriteicon.png");
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",
_("Sprite opacity"),
_("Change sprite opacity"),
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
"is opaque (default)."),
_("the opacity"),
@@ -44,10 +40,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/opacity.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity (0-255)")))
.UseStandardOperatorParameters("number")
.MarkAsSimple();
obj.AddAction("ChangeAnimation",
@@ -60,8 +53,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("number")
.MarkAsSimple();
obj.AddAction("SetAnimationName",
@@ -85,13 +77,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"is in 8 directions mode, the valid directions are 0..7"),
_("the direction"),
_("Direction"),
"res/actions/direction24_black.png",
"res/actions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeSprite",
@@ -103,8 +93,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("PauseAnimation",
@@ -140,9 +129,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Speed scale")))
.UseStandardOperatorParameters("number")
.MarkAsSimple();
obj.AddAction("TourneVersPos",
@@ -150,8 +137,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Rotate an object towards a position.",
"Rotate _PARAM0_ towards _PARAM1_;_PARAM2_",
_("Direction"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object to be rotated"), "Sprite")
.AddParameter("expression", _("X position"))
@@ -166,14 +153,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the specified object."),
_("the scale"),
_("Size"),
"res/actions/scale24_black.png",
"res/actions/scale_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeScaleWidth",
@@ -181,14 +165,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the width of an object."),
_("the width's scale"),
_("Size"),
"res/actions/scaleWidth24_black.png",
"res/actions/scaleWidth_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeScaleHeight",
@@ -196,14 +177,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Modify the scale of the height of an object."),
_("the height's scale"),
_("Size"),
"res/actions/scaleHeight24_black.png",
"res/actions/scaleHeight_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeWidth",
@@ -211,25 +189,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Change the width of a Sprite object."),
_("the width"),
_("Size"),
"res/actions/scaleWidth24_black.png",
"res/actions/scaleWidth_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
obj.AddCondition("Width",
_("Width"),
_("Compare the width of a Sprite object."),
_("the width"),
_("Size"),
"res/conditions/scaleWidth24_black.png",
"res/conditions/scaleWidth_black.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeHeight",
@@ -237,38 +201,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Change the height of a Sprite object."),
_("the height"),
_("Size"),
"res/actions/scaleHeight24_black.png",
"res/actions/scaleHeight_black.png")
"res/actions/scale24.png",
"res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
obj.AddCondition("Height",
_("Height"),
_("Compare the height of a Sprite object."),
_("the height"),
_("Size"),
"res/conditions/scaleHeight24_black.png",
"res/conditions/scaleHeight_black.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.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_black.png",
"res/actions/scale_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Width"))
.AddParameter("expression", _("Height"))
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition(
@@ -281,8 +218,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("AnimationName",
@@ -305,13 +241,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"from 0 to 7. Otherwise, the direction is in degrees."),
_("the direction"),
_("Direction"),
"res/conditions/direction24_black.png",
"res/conditions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/conditions/direction24.png",
"res/conditions/direction.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions());
.UseStandardRelationalOperatorParameters("number");
obj.AddCondition("Sprite",
_("Current frame"),
@@ -324,8 +258,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/sprite.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("AnimStopped",
@@ -348,19 +281,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.MarkAsSimple()
.SetHidden();
obj.AddCondition("AnimationEnded2",
_("Animation finished"),
_("Check if the animation being played by the Sprite object "
"is finished."),
_("The animation of _PARAM0_ is finished"),
_("Animations and images"),
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.MarkAsSimple();
@@ -369,14 +289,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Compare the scale of the width of an object."),
_("the width's scale"),
_("Size"),
"res/conditions/scaleWidth24_black.png",
"res/conditions/scaleWidth_black.png")
"res/conditions/scaleWidth24.png",
"res/conditions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("ScaleHeight",
@@ -384,14 +301,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Compare the scale of the height of an object."),
_("the height's scale"),
_("Size"),
"res/conditions/scaleHeight24_black.png",
"res/conditions/scaleHeight_black.png")
"res/conditions/scaleHeight24.png",
"res/conditions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddCondition("Opacity",
@@ -404,10 +318,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/opacity.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity to compare to (0-255)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsSimple();
obj.AddCondition(
@@ -420,8 +331,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/opacity.png")
.AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
obj.AddAction("ChangeColor",
@@ -452,7 +362,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")
@@ -464,7 +374,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")
@@ -498,8 +408,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Rotate an object towards another.",
"Rotate _PARAM0_ towards _PARAM1_",
_("Direction"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPtr", "Rotate toward this object")
@@ -510,7 +420,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("X position of a point"),
_("X position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -519,7 +429,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"),
_("Y position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -528,7 +438,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("X position of a point"),
_("X position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
@@ -537,7 +447,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"),
_("Y position of a point"),
_("Position"),
"res/actions/position_black.png")
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"));
@@ -546,7 +456,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
_("Direction of the object"),
_("Direction"),
"res/actions/direction_black.png")
"res/actions/direction.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite");
@@ -554,9 +464,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Direction"),
_("Direction of the object"),
_("Direction"),
"res/actions/direction_black.png")
.SetHidden() // Hide as 8 direction is not supported officially in the
// interface.
"res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Anim",
@@ -583,14 +491,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddExpression("Sprite",
_("Image"),
_("Current frame of the animation of the object"),
_("Animations and images"),
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("AnimationFrameCount",
_("Number of frames"),
_("Number of frames in the current animation of the object"),
_("Animation frame of the object"),
_("Animations and images"),
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite");
@@ -606,14 +507,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Scale of the width of an object"),
_("Scale of the width of an object"),
_("Size"),
"res/actions/scaleWidth_black.png")
"res/actions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("ScaleY",
_("Scale of the height of an object"),
_("Scale of the height of an object"),
_("Size"),
"res/actions/scaleHeight_black.png")
"res/actions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Opacity",
@@ -635,6 +536,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,28 +4,31 @@
* 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/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;
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
SpriteObject::SpriteObject(gd::String name_)
: Object(name_), updateIfNotVisible(false) {}
SpriteObject::~SpriteObject(){};
@@ -78,6 +81,7 @@ void SpriteObject::DoUnserializeFrom(gd::Project& project,
}
}
#if defined(GD_IDE_ONLY)
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
@@ -102,8 +106,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")
@@ -135,33 +138,26 @@ 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")] = gd::String::From(position.GetRawDoubleProperty("animation"));
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.SetRawDoubleProperty("animation", value.To<int>());
return true;
}
#endif
const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
if (nb >= animations.size()) return badAnimation;

View File

@@ -36,14 +36,15 @@ namespace gd {
* \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension
* \ingroup SpriteObjectExtension
*/
class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
class GD_CORE_API SpriteObject : public gd::Object {
public:
SpriteObject();
SpriteObject(gd::String name_);
virtual ~SpriteObject();
std::unique_ptr<gd::ObjectConfiguration> Clone() const override {
std::unique_ptr<gd::Object> Clone() const override {
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 +60,7 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
const gd::String& value,
gd::Project& project,
gd::Layout& scene) override;
#endif
/** \name Animations
* Methods related to animations management
@@ -116,24 +118,14 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
* 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

@@ -20,21 +20,20 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Text manipulation"))
.SetIcon("res/actions/text24_black.png");
#if defined(GD_IDE_ONLY)
extension.AddStrExpression("NewLine",
_("Insert a new line"),
_("Insert a new line"),
"",
"res/conditions/toujours24_black.png");
_("Manipulation of text"),
"res/conditions/toujours24.png");
extension
.AddStrExpression("FromCodePoint",
_("Get character from code point"),
_("Get character from code point"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("expression", _("Code point"));
@@ -42,8 +41,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToUpperCase",
_("Uppercase a text"),
_("Uppercase a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -51,8 +50,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("ToLowerCase",
_("Lowercase a text"),
_("Lowercase a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -60,8 +59,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("SubStr",
_("Get a portion of a text"),
_("Get a portion of a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("expression",
@@ -73,8 +72,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrAt",
_("Get a character from a text"),
_("Get a character from a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter(
@@ -85,8 +84,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddStrExpression("StrRepeat",
_("Repeat a text"),
_("Repeat a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text to repeat"))
.AddParameter("expression", _("Repetition count"));
@@ -95,8 +94,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.AddExpression("StrLength",
_("Length of a text"),
_("Length of a text"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"));
@@ -105,8 +104,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text"),
_("Search in a text (return the position of the result or "
"-1 if not found)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -116,8 +115,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"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)",
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -126,12 +125,12 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression(
"StrFindLast",
_("Search the last occurrence in a text"),
_("Search the last occurrence in a string (return the position of "
_("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_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -141,8 +140,8 @@ 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)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -156,8 +155,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"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)",
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -169,13 +168,13 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression(
"StrFindLastFrom",
_("Search the last occurrence in a text, starting from a position"),
_("Search in a text the last occurrence, starting from a position "
_("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)"),
"",
"res/conditions/toujours24_black.png")
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
@@ -183,26 +182,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Position of the last character in the string to be "
"considered in the search"));
extension
.AddStrExpression("StrReplaceOne",
_("Replace the first occurrence of a text by another."),
_("Replace the first occurrence of a text by another."),
"",
"res/conditions/toujours24_black.png")
.AddParameter("string", _("Text in which the replacement must be done"))
.AddParameter("string", _("Text to find inside the first text"))
.AddParameter("string", _("Replacement to put instead of the text to find"));
extension
.AddStrExpression("StrReplaceAll",
_("Replace all occurrences of a text by another."),
_("Replace all occurrences of a text by another."),
"",
"res/conditions/toujours24_black.png")
.AddParameter("string", _("Text in which the replacement(s) must be done"))
.AddParameter("string", _("Text to find inside the first text"))
.AddParameter("string", _("Replacement to put instead of the text to find"));
#endif
}
} // namespace gd

View File

@@ -14,61 +14,38 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension
.SetExtensionInformation(
"BuiltinTime",
_("Timers and time"),
_("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");
.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("identifier", _("Timer's name"), "sceneTimer")
.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("identifier", _("Timer's name"), "sceneTimer")
.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", "")
.UseStandardRelationalOperatorParameters(
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Time scale (1 by default)")))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
@@ -76,12 +53,11 @@ 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", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -90,25 +66,23 @@ 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", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer");
.AddParameter("string", _("Timer's name"));
extension
.AddAction("PauseTimer",
_("Pause a scene timer"),
_("Pause a scene timer."),
_("Pause timer _PARAM1_"),
"",
_("Timers and time"),
"res/actions/pauseTimer24.png",
"res/actions/pauseTimer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -116,12 +90,11 @@ 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", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
@@ -129,43 +102,30 @@ 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", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer")
.AddParameter("string", _("Timer's name"))
.MarkAsAdvanced();
extension
.AddAction("ChangeTimeScale",
_("Time scale"),
_("Change the time scale of the scene."),
_("Set the time scale of the scene to _PARAM1_"),
"",
_("Change time scale"),
_("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"),
_("Waits a number of seconds before running "
"the next actions (and sub-events)."),
_("Wait _PARAM0_ seconds"),
"",
"res/timer_black.svg",
"res/timer_black.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", "");
@@ -173,7 +133,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", "");
@@ -182,7 +142,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", "");
@@ -191,16 +151,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
.AddExpression("TimerElapsedTime",
_("Scene timer value"),
_("Value of a scene timer"),
"",
_("Time"),
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer");
.AddParameter("string", _("Timer's name"));
extension
.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", "");
@@ -208,7 +168,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", "");
@@ -216,16 +176,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(
@@ -236,6 +205,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"timestamp\""),
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
"\"yday\", \"timestamp\"]");
#endif
}
} // namespace gd

View File

@@ -14,7 +14,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.SetExtensionInformation(
"BuiltinVariables",
_("Variables"),
_("Variable features"),
"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 "
@@ -22,40 +22,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"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",
_("Number variable"),
_("Compare the number value of a scene variable."),
_("The number of scene variable _PARAM0_"),
_("Scene variables"),
_("Value of a scene variable"),
_("Compare the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions());
.UseStandardRelationalOperatorParameters("number");
extension
.AddCondition("VarSceneTxt",
_("Text variable"),
_("Compare the text (string) of a scene variable."),
_("The text of scene variable _PARAM0_"),
_("Scene variables"),
_("Text of a scene variable"),
_("Compare the text of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions());
.UseStandardRelationalOperatorParameters("string");
extension
.AddCondition(
"SceneVariableAsBoolean",
_("Boolean variable"),
_("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"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -63,14 +60,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetDefaultValue("true");
extension
.AddCondition("VariableChildExists",
_("Child existence"),
_("Check if the specified child of the scene structure "
"variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("Scene variables/Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCondition(
"VariableChildExists",
_("Child existence"),
_("Check if the specified child of the scene variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("Variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("string", _("Name of the child"))
.MarkAsAdvanced();
@@ -78,10 +75,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("GlobalVariableChildExists",
_("Child existence"),
_("Check if the specified child of the global structure "
_("Check if the specified child of the global "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("Global variables/Arrays and structures"),
_("Variables/Global variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -90,49 +87,47 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("VarSceneDef",
"Variable defined",
"Test if a scene variable is defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("Scene variables"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Variable"))
.SetHidden(); // Deprecated.
.SetHidden();
extension
.AddCondition("VarGlobal",
_("Number variable"),
_("Compare the number value of a global variable."),
_("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"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddCondition("VarGlobalTxt",
_("Text variable"),
_("Compare the text (string) of a global variable."),
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.UseStandardRelationalOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddCondition(
"GlobalVariableAsBoolean",
_("Boolean variable"),
_("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"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -141,48 +136,46 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("VarGlobalDef",
"Variable defined",
"Test if a global variable exists.",
"Test if a global variable is defined",
"Test if a global variable exists",
"Global variable _PARAM0_ is defined",
_("Global variables"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Variable"))
.MarkAsAdvanced()
.SetHidden(); // Deprecated.
.SetHidden();
extension
.AddAction("ModVarScene",
_("Change number variable"),
_("Modify the number value of a scene variable."),
_("Value of a scene variable"),
_("Change the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Scene variables"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions());
.UseStandardOperatorParameters("number");
extension
.AddAction("ModVarSceneTxt",
_("Change text variable"),
_("Modify the text (string) of a scene variable."),
_("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",
ParameterOptions::MakeNewOptions());
.UseStandardOperatorParameters("string");
extension
.AddAction(
"SetSceneVariableAsBoolean",
_("Change boolean variable"),
_("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"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -190,49 +183,47 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddAction("ToggleSceneVariableAsBoolean",
_("Toggle boolean variable"),
_("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"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"));
extension
.AddAction("ModVarGlobal",
_("Change number variable"),
_("Modify the number value of a global variable."),
_("Value of a global variable"),
_("Change 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"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddAction("ModVarGlobalTxt",
_("Change text variable"),
_("Modify the text (string) of a global variable."),
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Global variables"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.UseStandardOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddAction(
"SetGlobalVariableAsBoolean",
_("Change boolean variable"),
_("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"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -240,355 +231,234 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddAction("ToggleGlobalVariableAsBoolean",
_("Toggle boolean variable"),
_("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"),
_("Variables/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 structure variable."),
_("Remove child _PARAM1_ from scene structure variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure variable"))
.AddAction("VariableRemoveChild",
_("Remove a child"),
_("Remove a child from a scene variable."),
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
_("Variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("string", _("Child's name"))
.MarkAsAdvanced();
extension
.AddAction(
"GlobalVariableRemoveChild",
_("Remove a child"),
_("Remove a child from a global structure variable."),
_("Remove child _PARAM1_ from global structure variable _PARAM0_"),
_("Global variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure variable"))
.AddAction("GlobalVariableRemoveChild",
_("Remove a child"),
_("Remove a child from a global variable."),
_("Remove child _PARAM1_ from global variable _PARAM0_"),
_("Variables/Global variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("string", _("Child's name"))
.MarkAsAdvanced();
extension
.AddAction("VariableClearChildren",
_("Clear children"),
_("Remove all the children from the scene structure or array "
"variable."),
_("Clear scene variable"),
_("Remove all the children from the scene variable."),
_("Clear children from scene variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
_("Variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure or array variable"))
.AddParameter("scenevar", _("Variable"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariableClearChildren",
_("Clear children"),
_("Remove all the children from the global structure or array "
"variable."),
_("Clear global variable"),
_("Remove all the children from the global variable."),
_("Clear children from global variable _PARAM0_"),
_("Global variables/Arrays and structures"),
_("Variables/Global variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure or array variable"))
.AddParameter("globalvar", _("Variable"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePush",
_("Add existing variable"),
_("Adds an existing variable at the end of a scene array "
"variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
_("Append variable to a scene array"),
_("Appends a variable at the end of a scene array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to add"))
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.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",
_("Add text variable"),
_("Adds a text (string) at the end of a scene array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.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_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushNumber",
_("Add number variable"),
_("Adds a number at the end of a scene array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
_("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_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushBool",
_("Add boolean variable"),
_("Adds a boolean at the end of a scene array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
_("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_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariableRemoveAt",
_("Remove variable 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/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
extension
.AddCondition(
"SceneVariableChildCount",
_("Number of children"),
_("Compare the number of children in a scene array variable."),
_("The number of children in the array variable _PARAM0_"),
_("Scene variables/Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddStrExpression(
"SceneVariableFirstString",
_("First text child"),
_("Get the value of the first element of a scene array variable, if "
"it is a text (string)."),
_("Scene variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"));
extension
.AddExpression(
"SceneVariableFirstNumber",
_("First number child"),
_("Get the value of the first element of a scene array variable, if "
"it is a number."),
_("Scene variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"));
extension
.AddStrExpression(
"SceneVariableLastString",
_("Last text child"),
_("Get the value of the last element of a scene array variable, if "
"it is a text (string)."),
_("Scene variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"));
extension
.AddExpression(
"SceneVariableLastNumber",
_("Last number child"),
_("Get the value of the last element of a scene array variable, if "
"it is a number."),
_("Scene variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"));
extension
.AddAction(
"GlobalVariablePush",
_("Add existing variable"),
_("Adds an existing variable at the end of a global array variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to add"))
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariableRemoveAt",
_("Remove variable 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/Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddAction(
"GlobalVariablePushString",
_("Add text variable"),
_("Adds a text (string) at the end of a global array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Arrays and structures"),
"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_"),
_("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_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.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_"),
_("Variables/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_"),
_("Variables/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",
_("Add number variable"),
_("Adds a number at the end of a global array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Arrays and structures"),
_("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_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushBool",
_("Add boolean variable"),
_("Adds a boolean at the end of a global array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("Global variables/Arrays and structures"),
_("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_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddCondition(
"GlobalVariableChildCount",
_("Number of children"),
_("Compare the number of children in a global array variable."),
_("The number of children of the array variable _PARAM0_"),
_("Global variables/Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddStrExpression("GlobalVariableFirstString",
_("First text child"),
_("Value of the first element of a global array "
"variable, if it is a text (string) variable."),
_("Global variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"));
extension
.AddExpression("GlobalVariableFirstNumber",
_("First number child"),
_("Value of the first element of a global array "
"variable, if it is a number variable"),
_("Global variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"));
extension
.AddStrExpression(
"GlobalVariableLastString",
_("Last text child"),
_("Value of the last element of a global array variable, if "
"it is a text (string) variable."),
_("Global variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"));
extension
.AddExpression(
"GlobalVariableLastNumber",
_("Last number child"),
_("Value of the last element of a global array variable, if "
"it is a number variable"),
_("Global variables/Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"));
extension
.AddExpression("GlobalVariableChildCount",
_("Number of children"),
_("Number of children in a global array or "
"structure variable"),
_("Global variables/Arrays and structures"),
_("Number of children of a global variable"),
_("Number of children of a global variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array or structure variable"));
.AddParameter("globalvar", _("Variable"));
extension
.AddExpression("VariableChildCount",
_("Number of children"),
_("Number of children in a scene array or "
"structure variable"),
_("Scene variables/Arrays and structures"),
_("Number of children of a scene variable"),
_("Number of children of a scene variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array or structure variable"));
.AddParameter("scenevar", _("Variable"));
extension
.AddExpression("Variable",
_("Number variable"),
_("Number value of a scene variable"),
_("Scene variables"),
_("Value of a scene variable"),
_("Value of a scene variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
extension
.AddStrExpression("VariableString",
_("Text variable"),
_("Text of a scene variable"),
_("Scene variables"),
_("Text of a scene variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));
extension
.AddExpression("GlobalVariable",
_("Number variable"),
_("Number value of a global variable"),
_("Global variables"),
_("Value of a global variable"),
_("Value of a global variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable"));
extension
.AddStrExpression("GlobalVariableString",
_("Text variable"),
_("Text of a global variable"),
_("Global variables"),
_("Text of a global variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
#endif
}
} // namespace gd

View File

@@ -14,26 +14,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.SetExtensionInformation(
"BuiltinWindow",
_("Game window and resolution"),
_("Window features"),
"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)")
.SetCategory("User interface")
.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", "")
@@ -49,19 +45,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
_("Fullscreen activated?"),
_("Check if the game is currently in fullscreen."),
_("The game is in fullscreen"),
"",
_("Game's window and resolution"),
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetWindowMargins",
_("Window's margins"),
_("Change the window's margins"),
_("This action changes the margins, in pixels, between the "
"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", "")
@@ -72,12 +68,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetGameResolutionSize",
_("Game resolution"),
_("Change the resolution of the game"),
_("Changes the resolution of the game, effectively changing "
"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", "")
@@ -94,7 +90,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", "")
@@ -111,19 +107,19 @@ 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", "");
extension
.AddAction("SetGameResolutionResizeMode",
_("Game resolution resize mode"),
_("Change the game resolution resize mode"),
_("Set if the width or the height of the game resolution "
"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", "")
@@ -144,7 +140,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", "")
@@ -154,10 +150,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetWindowIcon",
_("Window's icon"),
_("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", "")
@@ -165,10 +161,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension
.AddAction("SetWindowTitle",
_("Window's title"),
_("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", "")
@@ -179,7 +175,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", "");
@@ -188,7 +184,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", "");
@@ -196,29 +192,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

@@ -14,14 +14,12 @@
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/MakeUnique.h"
#include "GDCore/Tools/Log.h"
namespace gd {
BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace_,
const gd::String& nameWithNamespace,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
@@ -31,50 +29,21 @@ BehaviorMetadata::BehaviorMetadata(
std::shared_ptr<gd::Behavior> instance_,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance_)
: extensionNamespace(extensionNamespace_),
className(className_),
iconFilename(icon24x24),
instance(instance_),
sharedDatasInstance(sharedDatasInstance_),
isEventBased(false) {
sharedDatasInstance(sharedDatasInstance_) {
#if defined(GD_IDE_ONLY)
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
SetDefaultName(gd::String(defaultName_));
SetGroup(group_);
className = className_;
iconFilename = icon24x24;
#endif
if (!instance) {
gd::LogFatalError(
"Trying to create a BehaviorMetadata that has no "
"behavior. This will crash - please double check that the "
"BehaviorMetadata is valid for: " + nameWithNamespace);
}
if (instance) instance->SetTypeName(nameWithNamespace);
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
if (instance) instance->SetTypeName(name_);
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(name_);
}
BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon24x24_): BehaviorMetadata(
extensionNamespace,
nameWithNamespace,
fullname_,
defaultName_,
description_,
group_,
icon24x24_,
// Class name is the name, actually unused
defaultName_,
// It is only used to get the name for GetName.
gd::make_unique<gd::Behavior>("", nameWithNamespace),
nullptr){
isEventBased = true;
};
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
const gd::String& name,
const gd::String& fullname,
@@ -83,6 +52,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -96,6 +66,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddAction(
@@ -106,6 +77,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -119,6 +91,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
@@ -129,6 +102,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -142,6 +116,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
@@ -152,6 +127,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -165,6 +141,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
.SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace];
#endif
}
gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
@@ -173,6 +150,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
const gd::String& description,
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",
@@ -184,6 +162,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
smallicon)
.SetHelpPath(GetHelpPath());
return expressionsInfos[name];
#endif
}
gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
@@ -192,6 +171,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
const gd::String& description,
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",
@@ -203,6 +183,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
smallicon)
.SetHelpPath(GetHelpPath());
return strExpressionsInfos[name];
#endif
}
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
@@ -253,40 +234,6 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
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"
@@ -303,10 +250,32 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
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;
@@ -374,44 +343,49 @@ gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
return strExpressionsInfos[newNameWithNamespace];
}
#endif
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetDefaultName(
const gd::String& defaultName_) {
#if defined(GD_IDE_ONLY)
defaultName = defaultName_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetDescription(
const gd::String& description_) {
#if defined(GD_IDE_ONLY)
description = description_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetGroup(const gd::String& group_) {
#if defined(GD_IDE_ONLY)
group = group_;
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::SetIncludeFile(
const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
includeFiles.clear();
includeFiles.push_back(includeFile);
#endif
return *this;
}
BehaviorMetadata& BehaviorMetadata::AddIncludeFile(
const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
includeFiles.end())
includeFiles.push_back(includeFile);
return *this;
}
BehaviorMetadata& BehaviorMetadata::AddRequiredFile(
const gd::String& requiredFile) {
if (std::find(requiredFiles.begin(), requiredFiles.end(), requiredFile) ==
requiredFiles.end())
requiredFiles.push_back(requiredFile);
#endif
return *this;
}
@@ -419,26 +393,4 @@ const gd::String& BehaviorMetadata::GetName() const {
return instance->GetTypeName();
}
gd::Behavior& BehaviorMetadata::Get() const {
if (isEventBased) {
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
"This method should not never be called.");
}
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 for: " + className);
}
return *instance;
}
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
if (isEventBased) {
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
"This method should not never be called.");
}
return sharedDatasInstance.get();
}
} // namespace gd

View File

@@ -29,7 +29,7 @@ class GD_CORE_API BehaviorMetadata {
public:
BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
@@ -38,21 +38,6 @@ class GD_CORE_API BehaviorMetadata {
const gd::String& className_,
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
/**
* \brief Construct a behavior metadata, without "blueprint" behavior.
*
* \note This is used by events based behaviors.
*/
BehaviorMetadata(
const gd::String& extensionNamespace,
const gd::String& nameWithNamespace,
const gd::String& fullname_,
const gd::String& defaultName_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon24x24_);
BehaviorMetadata(){};
virtual ~BehaviorMetadata(){};
@@ -210,13 +195,6 @@ class GD_CORE_API BehaviorMetadata {
*/
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* \brief Add a file to the already existing required files.
* \note These files are required for the behavior to work,
* but they are not executable.
*/
BehaviorMetadata& AddRequiredFile(const gd::String& requiredFile);
/**
* Get the help path of the behavior, relative to the GDevelop documentation
* root.
@@ -236,6 +214,7 @@ class GD_CORE_API BehaviorMetadata {
}
const gd::String& GetName() const;
#if defined(GD_IDE_ONLY)
const gd::String& GetFullName() const { return fullname; }
const gd::String& GetDefaultName() const { return defaultName; }
const gd::String& GetDescription() const { return description; }
@@ -256,84 +235,45 @@ class GD_CORE_API BehaviorMetadata {
* \note An empty string means the base object, so any object.
*/
const gd::String& GetObjectType() const { return objectType; }
/**
* Check if the behavior is private - it can't be used outside of its
* extension.
*/
bool IsPrivate() const { return isPrivate; }
/**
* Set that the behavior is private - it can't be used outside of its
* extension.
*/
BehaviorMetadata &SetPrivate() {
isPrivate = true;
return *this;
}
#endif
/**
* \brief Return the associated gd::Behavior, handling behavior contents.
*
* \note Returns a dumb Behavior for events based behaviors as CustomBehavior
* are using EventBasedBehavior.
*/
gd::Behavior& Get() const;
gd::Behavior& Get() const { return *instance; }
/**
* \brief Return the associated gd::BehaviorsSharedData, handling behavior
* shared data, if any (nullptr if none).
*
* \note Returns nullptr for events based behaviors as they don't declare
* shared data yet.
*/
gd::BehaviorsSharedData* GetSharedDataInstance() const;
/**
* \brief 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; };
gd::BehaviorsSharedData* GetSharedDataInstance() const {
return sharedDatasInstance.get();
}
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::String> includeFiles;
std::vector<gd::String> requiredFiles;
gd::String className;
#endif
private:
gd::String extensionNamespace;
gd::String helpPath;
#if defined(GD_IDE_ONLY)
gd::String fullname;
gd::String defaultName;
gd::String description;
gd::String group;
gd::String iconFilename;
gd::String objectType;
bool isPrivate = false;
#endif
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
std::shared_ptr<gd::Behavior> instance;
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
bool isEventBased;
};
} // namespace gd

View File

@@ -62,7 +62,7 @@ class GD_CORE_API DependencyMetadata {
};
/**
* \brief Sets the type of dependency (what will be used to install it)
* \brief Sets the type of dependecy (what will be used to install it)
*
* This can either be "npm" or "cordova" for now.
*/

View File

@@ -7,6 +7,8 @@
namespace gd {
EffectMetadata::EffectMetadata(const gd::String& type_) : type(type_) {}
EffectMetadata& EffectMetadata::SetIncludeFile(const gd::String& includeFile) {
includeFiles.clear();
includeFiles.push_back(includeFile);

View File

@@ -3,13 +3,11 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#ifndef EFFECTMETADATA_H
#define EFFECTMETADATA_H
#include <functional>
#include <map>
#include <memory>
#include <algorithm>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
@@ -25,25 +23,21 @@ class GD_CORE_API EffectMetadata {
/**
* \brief Construct an effect metadata, with the given type
*/
EffectMetadata(const gd::String &type_)
: type(type_), isMarkedAsNotWorkingForObjects(false),
isMarkedAsOnlyWorkingFor2D(false), isMarkedAsOnlyWorkingFor3D(false),
isMarkedAsUnique(false) {}
EffectMetadata(const gd::String& type_);
/**
* \brief Default constructor, only used for initializing
* `badEffectMetadata`.
*/
EffectMetadata() {}
/**
* \brief Default constructor, only used for initializing `badEffectMetadata`.
*/
EffectMetadata() {}
virtual ~EffectMetadata(){};
virtual ~EffectMetadata(){};
/**
* \brief Set the name shown to the user.
*/
EffectMetadata &SetFullName(const gd::String &fullname_) {
fullname = fullname_;
return *this;
/**
* \brief Set the name shown to the user.
*/
EffectMetadata& SetFullName(const gd::String& fullname_) {
fullname = fullname_;
return *this;
};
/**
@@ -55,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 GDevelop documentation root.
*/
EffectMetadata& SetHelpPath(const gd::String& path) {
helpPath = path;
@@ -88,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 GDevelop 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; }
@@ -116,66 +107,6 @@ class GD_CORE_API EffectMetadata {
return includeFiles;
}
/**
* \brief Mark the effect as not working as an object effect.
*/
EffectMetadata& MarkAsNotWorkingForObjects() {
isMarkedAsNotWorkingForObjects = true;
return *this;
}
/**
* \brief Mark the effect as only working for the 2D renderer.
*/
EffectMetadata& MarkAsOnlyWorkingFor2D() {
isMarkedAsOnlyWorkingFor2D = true;
return *this;
}
/**
* \brief Mark the effect as only working for the 3D renderer.
*/
EffectMetadata& MarkAsOnlyWorkingFor3D() {
isMarkedAsOnlyWorkingFor3D = true;
return *this;
}
/**
* \brief Mark the effect as only addable once.
*/
EffectMetadata& MarkAsUnique() {
isMarkedAsUnique = true;
return *this;
}
/**
* \brief Check if the effect is marked as not working as an object effect.
*/
bool IsMarkedAsNotWorkingForObjects() const {
return isMarkedAsNotWorkingForObjects;
};
/**
* \brief Check if the effect is marked as only working for the 2D renderer.
*/
bool IsMarkedAsOnlyWorkingFor2D() const {
return isMarkedAsOnlyWorkingFor2D;
};
/**
* \brief Check if the effect is marked as only working for the 3D renderer.
*/
bool IsMarkedAsOnlyWorkingFor3D() const {
return isMarkedAsOnlyWorkingFor3D;
};
/**
* \brief Check if the effect can only be added once.
*/
bool IsMarkedAsUnique() const {
return isMarkedAsUnique;
};
private:
gd::String extensionNamespace;
gd::String type;
@@ -183,11 +114,8 @@ class GD_CORE_API EffectMetadata {
gd::String fullname;
gd::String description;
std::vector<gd::String> includeFiles;
bool isMarkedAsNotWorkingForObjects;
bool isMarkedAsOnlyWorkingFor2D;
bool isMarkedAsOnlyWorkingFor3D;
bool isMarkedAsUnique;
std::map<gd::String, gd::PropertyDescriptor> properties;
};
} // namespace gd
#endif // EFFECTMETADATA_H

View File

@@ -23,8 +23,7 @@ ExpressionMetadata::ExpressionMetadata(const gd::String& returnType_,
shown(true),
smallIconFilename(smallicon_),
extensionNamespace(extensionNamespace_),
isPrivate(false),
relevantContext("Any") {
isPrivate(false) {
}
ExpressionMetadata& ExpressionMetadata::SetHidden() {
@@ -35,29 +34,27 @@ 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.SetType(type);
info.type = type;
info.description = description;
info.codeOnly = false;
info.SetOptional(parameterIsOptional);
info.SetExtraInfo(
info.optional = parameterIsOptional;
info.supplementaryInformation =
// For objects/behavior, the supplementary information
// parameter is an object/behavior type...
((gd::ParameterMetadata::IsObject(type) ||
(gd::ParameterMetadata::IsObject(type) ||
gd::ParameterMetadata::IsBehavior(type))
// Prefix with the namespace if it's not already there.
&& !(supplementaryInformation.rfind(extensionNamespace, 0) == 0))
? (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);
@@ -67,19 +64,12 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
gd::ExpressionMetadata& ExpressionMetadata::AddCodeOnlyParameter(
const gd::String& type, const gd::String& supplementaryInformation) {
gd::ParameterMetadata info;
info.SetType(type);
info.type = type;
info.codeOnly = true;
info.SetExtraInfo(supplementaryInformation);
info.supplementaryInformation = supplementaryInformation;
parameters.push_back(info);
return *this;
}
gd::ExpressionMetadata& ExpressionMetadata::SetRequiresBaseObjectCapability(
const gd::String& capability) {
requiredBaseObjectCapability = capability;
return *this;
}
} // namespace gd

View File

@@ -137,7 +137,7 @@ class GD_CORE_API ExpressionMetadata {
* to fulfill std::map requirements.
*/
ExpressionMetadata()
: returnType("unknown"), shown(false), isPrivate(false), relevantContext("Any"){};
: returnType("unknown"), shown(false), isPrivate(false){};
virtual ~ExpressionMetadata(){};
@@ -184,74 +184,13 @@ class GD_CORE_API ExpressionMetadata {
return *this;
}
/**
* Check if the instruction can be used in layouts or external events.
*/
bool IsRelevantForLayoutEvents() const {
return relevantContext == "Any" || relevantContext == "Layout";
}
/**
* Check if the instruction can be used in function events.
*/
bool IsRelevantForFunctionEvents() const {
return relevantContext == "Any" || relevantContext == "Function";
}
/**
* Check if the instruction can be used in asynchronous function events.
*/
bool IsRelevantForAsynchronousFunctionEvents() const {
return relevantContext == "Any" || relevantContext == "Function" ||
relevantContext == "AsynchronousFunction";
}
/**
* Check if the instruction can be used in custom object events.
*/
bool IsRelevantForCustomObjectEvents() const {
return relevantContext == "Any" || relevantContext == "Object";
}
/**
* Set that the instruction can be used in layouts or external events.
*/
ExpressionMetadata &SetRelevantForLayoutEventsOnly() {
relevantContext = "Layout";
return *this;
}
/**
* Set that the instruction can be used in function events.
*/
ExpressionMetadata &SetRelevantForFunctionEventsOnly() {
relevantContext = "Function";
return *this;
}
/**
* Set that the instruction can be used in asynchronous function events.
*/
ExpressionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() {
relevantContext = "AsynchronousFunction";
return *this;
}
/**
* Set that the instruction can be used in custom object events.
*/
ExpressionMetadata &SetRelevantForCustomObjectEventsOnly() {
relevantContext = "Object";
return *this;
}
/**
* \see gd::InstructionMetadata::AddParameter
*/
gd::ExpressionMetadata& AddParameter(
const gd::String& type,
const gd::String& description,
const gd::String& supplementaryInformation = "",
const gd::String& optionalObjectType = "",
bool parameterIsOptional = false);
/**
@@ -283,35 +222,6 @@ class GD_CORE_API ExpressionMetadata {
return *this;
};
/**
* \brief Set the additional information, used for some parameters
* with special type (for example, it can contains the type of object accepted
* by the parameter), for the last added parameter.
*
* \see AddParameter
*/
ExpressionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
return *this;
}
/**
* \brief Mark this (object) expression as requiring the specified capability,
* offered by the base object.
* This is useful for some objects that don't support this capability, so that
* the editor can hide the expression as it does not apply to them.
*/
ExpressionMetadata& SetRequiresBaseObjectCapability(
const gd::String& capability);
/**
* \brief Get the required specified capability for this (object) expression,
* or an empty string if there is nothing specific required.
*/
const gd::String& GetRequiredBaseObjectCapability() const {
return requiredBaseObjectCapability;
};
/**
* \brief Set the function that should be called when generating the source
* code from events.
@@ -329,30 +239,7 @@ class GD_CORE_API ExpressionMetadata {
*/
ExpressionCodeGenerationInformation& GetCodeExtraInformation() {
return codeExtraInformation;
}
/**
* \brief Erase any existing include file and add the specified include.
*/
ExpressionMetadata &SetIncludeFile(const gd::String &includeFile) {
codeExtraInformation.SetIncludeFile(includeFile);
return *this;
}
/**
* \brief Add a file to the already existing include files.
*/
ExpressionMetadata &AddIncludeFile(const gd::String &includeFile) {
codeExtraInformation.AddIncludeFile(includeFile);
return *this;
}
/**
* \brief Get the files that must be included to use the instruction.
*/
const std::vector<gd::String>& GetIncludeFiles() const {
return codeExtraInformation.GetIncludeFiles();
}
};
ExpressionCodeGenerationInformation codeExtraInformation;
@@ -386,8 +273,6 @@ class GD_CORE_API ExpressionMetadata {
gd::String smallIconFilename;
gd::String extensionNamespace;
bool isPrivate;
gd::String requiredBaseObjectCapability;
gd::String relevantContext;
};
} // namespace gd

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