Compare commits

..

2 Commits

Author SHA1 Message Date
Florian Rival
32587bd13f Add patch-package 2022-05-21 23:19:03 +00:00
Florian Rival
a6ea94846d Speed up IDE JS transpilation by avoiding to process locale files
These files don't need to be processed by Babel and they are huge. Patch create-react-app to avoid running Babel on them.
2022-05-21 15:32:33 +00:00
4065 changed files with 263038 additions and 412548 deletions

View File

@@ -15,7 +15,7 @@ jobs:
# Build the **entire** app for macOS. # Build the **entire** app for macOS.
build-macos: build-macos:
macos: macos:
xcode: 14.2.0 xcode: 12.5.1
steps: steps:
- checkout - checkout
@@ -30,7 +30,7 @@ jobs:
- run: - run:
name: Install Emscripten (for GDevelop.js) name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. 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 # GDevelop.js dependencies
- restore_cache: - restore_cache:
@@ -62,14 +62,13 @@ jobs:
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual) # Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing). # Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
# To test signing the code in the CI, add "export CSC_FOR_PULL_REQUEST=true && " before the command.
- run: - run:
name: Build GDevelop IDE name: Build GDevelop IDE
command: export CSC_FOR_PULL_REQUEST=true && export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && CI=false npm run build -- --mac --publish=never command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
- run: - run:
name: Clean dist folder to keep only installers/binaries. name: Clean dist folder to keep only installers/binaries.
command: rm -rf "newIDE/electron-app/dist/mac-universal/GDevelop 5.app" command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app"
# Upload artifacts (CircleCI) # Upload artifacts (CircleCI)
- store_artifacts: - store_artifacts:
@@ -102,12 +101,12 @@ jobs:
command: sudo apt-get update && sudo apt install cmake command: sudo apt-get update && sudo apt install cmake
- run: - run:
name: Install Python3 dependencies for Emscripten name: Install Python3 dependencies for Emscripten
command: sudo apt install python-is-python3 python3-distutils -y command: sudo apt install python-is-python3 python3-distutils -y
- run: - run:
name: Install Emscripten (for GDevelop.js) name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
- run: - run:
name: Install system dependencies for Electron builder name: Install system dependencies for Electron builder
@@ -127,8 +126,7 @@ jobs:
# Build GDevelop.js (and run tests to ensure it works) # Build GDevelop.js (and run tests to ensure it works)
- run: - run:
name: Build GDevelop.js name: Build GDevelop.js
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number). command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
# GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version) # GDevelop IDE dependencies (after building GDevelop.js to avoid downloading a pre-built version)
- run: - run:
@@ -145,11 +143,11 @@ jobs:
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual) # Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run: - run:
name: Build GDevelop IDE 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 zip deb --publish=never
- run: - run:
name: Clean dist folder to keep only installers/binaries. 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) # Upload artifacts (CircleCI)
- store_artifacts: - store_artifacts:
@@ -180,12 +178,12 @@ jobs:
command: sudo apt-get update && sudo apt install cmake command: sudo apt-get update && sudo apt install cmake
- run: - run:
name: Install Python3 dependencies for Emscripten name: Install Python3 dependencies for Emscripten
command: sudo apt install python-is-python3 python3-distutils -y command: sudo apt install python-is-python3 python3-distutils -y
- run: - run:
name: Install Emscripten (for GDevelop.js) name: Install Emscripten (for GDevelop.js)
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. 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 # GDevelop.js dependencies
- restore_cache: - restore_cache:
@@ -201,8 +199,7 @@ jobs:
# Build GDevelop.js (and run tests to ensure it works) # Build GDevelop.js (and run tests to ensure it works)
- run: - run:
name: Build GDevelop.js name: Build GDevelop.js
# Use "--runInBand" as it's faster and avoid deadlocks on CircleCI Linux machines (probably because limited in processes number). command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test && cd ..
command: cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && npm test -- --runInBand && cd ..
- save_cache: - save_cache:
paths: paths:

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

@@ -1,14 +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
{ {
"image": "mcr.microsoft.com/devcontainers/universal:2", "name": "GitHub Codespaces for GDevelop",
"onCreateCommand": "cd newIDE/app && npm install && cd ../electron-app && npm install", "build": {
"forwardPorts": [3000], "dockerfile": "Dockerfile"
"customizations": { },
"vscode": { "settings": {
"extensions": [ "terminal.integrated.shell.linux": "/bin/zsh",
"esbenp.prettier-vscode", "go.toolsManagement.checkForUpdates": "off",
"ms-vscode.cpptools", "go.useLanguageServer": true,
"flowtype.flow-for-vscode" "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:

View File

@@ -1,37 +0,0 @@
name: 💥 Automatic crash report
description: Do not use this template for bug reports. This template is only for automatic crash reports.
body:
- type: textarea
id: description
attributes:
label: Describe what you were doing when the crash happened
description: If applicable, add screenshots to help explain your problem.
placeholder: |
1. Went to '...'
2. Clicked on '...'
3. Scrolled down to '...'
4. Saw error
- type: input
id: gdevelop_version
attributes:
label: GDevelop version
description: |
The version of GDevelop used. Leave the prefilled value.
validations:
required: true
- type: textarea
id: platform_info
attributes:
label: Platform info
description: |
The platform you are using GDevelop on. Leave the prefilled value.
- type: textarea
id: error_stack
attributes:
label: Additional error context
description: Additonal context about the problem. Leave the prefilled value.
- type: textarea
id: component_stack
attributes:
label: Additional component context
description: Additonal context about the problem. Leave the prefilled value.

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,78 +0,0 @@
name: 🐛Bug report
description: Create a bug report about GDevelop or the game engine
body:
- type: checkboxes
id: searched_issues
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
id: description
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
id: reproduction_steps
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
id: platform
attributes:
label: GDevelop platform
description: Which platform of GDevelop are you using?
multiple: true
options:
- Desktop
- Web
- Mobile
validations:
required: true
- type: input
id: gdevelop_version
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
id: platform_info
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
id: additional_context
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: 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 - Discussed it on the discord or the forum,
- Peer-reviewed it with other users on Discord, - 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 [Feature Request Forum](https://forum.gdevelop.io/c/gdevelop-general/feature-requests/35) if something is important for you - 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 ## Description

View File

@@ -4,14 +4,14 @@ contact_links:
url: https://discord.gg/rjdYHvj url: https://discord.gg/rjdYHvj
about: Discuss on the forum or on the Discord to get help creating a game or identifying a bug. about: Discuss on the forum or on the Discord to get help creating a game or identifying a bug.
- name: GDevelop Forums - 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. about: You can also discuss game creation, new feature requests and bugs on the forum.
- name: GDevelop Roadmap - name: GDevelop Roadmap
url: https://trello.com/b/qf0lM7k8/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. 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 - name: Submit a new game example that you created
url: https://github.com/GDevelopApp/GDevelop-examples/issues/new/choose 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 - name: Submit a new game extension that you created
url: https://github.com/4ian/GDevelop-extensions/issues/new/choose 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

View File

@@ -9,10 +9,6 @@ name: Build Storybook
on: on:
# Launch on all commits. # Launch on all commits.
push: push:
branches:
- "**"
tags-ignore:
- "**" # Don't run on new tags
# Allows to run this workflow manually from the Actions tab, # Allows to run this workflow manually from the Actions tab,
# to publish on Chromatic (not done by default). # to publish on Chromatic (not done by default).
workflow_dispatch: workflow_dispatch:
@@ -21,23 +17,27 @@ jobs:
build-storybook: build-storybook:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: 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 - name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2 uses: aws-actions/configure-aws-credentials@v1
with: with:
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }} aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1 aws-region: us-east-1
- uses: actions/checkout@v2
with:
fetch-depth: 50
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
- name: Install newIDE dependencies - name: Install newIDE dependencies
run: npm install run: npm install
working-directory: newIDE/app working-directory: newIDE/app
@@ -57,8 +57,8 @@ jobs:
- name: Log urls to the Storybook - name: Log urls to the Storybook
run: | 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 latest Storybook for this branch on http://gdevelop-storybook.s3-website-us-east-1.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/latest/index.html"
echo "Find the Storybook for this commit on https://gdevelop-storybook.s3.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/index.html" echo "Find the Storybook for this commit on http://gdevelop-storybook.s3-website-us-east-1.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/index.html"
# Publish on Chromatic, only when manually launched (too costly to run on every commit). # Publish on Chromatic, only when manually launched (too costly to run on every commit).
- name: Publish Storybook to Chromatic - name: Publish Storybook to Chromatic

View File

@@ -4,10 +4,6 @@ name: Extract translations
on: on:
# Execute for all commits (to ensure translations extraction works) # Execute for all commits (to ensure translations extraction works)
push: push:
branches:
- "**"
tags-ignore:
- "**" # Don't run on new tags
# Allows to run this workflow manually from the Actions tab. # Allows to run this workflow manually from the Actions tab.
workflow_dispatch: workflow_dispatch:
@@ -15,18 +11,23 @@ jobs:
extract-translations: extract-translations:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with: with:
node-version: 16 # npm cache files are stored in `~/.npm` on Linux/macOS
cache: "npm" path: ~/.npm
cache-dependency-path: "newIDE/app/package-lock.json" key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
- name: Install gettext - name: Install gettext
run: sudo apt update && sudo apt install gettext -y run: sudo apt update && sudo apt install gettext -y
- name: Install newIDE dependencies - name: Install newIDE dependencies
run: npm ci run: npm install
working-directory: newIDE/app working-directory: newIDE/app
- name: Extract translations - name: Extract translations
@@ -37,7 +38,7 @@ jobs:
- name: Install Crowdin CLI - name: Install Crowdin CLI
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master'
run: npm i -g @crowdin/cli run: npm i -g @crowdin/cli
- name: Upload translations to Crowdin - name: Upload translations to Crowdin
run: crowdin upload sources run: crowdin upload sources
if: github.ref == 'refs/heads/master' if: github.ref == 'refs/heads/master'

View File

@@ -3,17 +3,41 @@ on:
issues: issues:
types: [opened] types: [opened]
jobs: jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Autoclose issues about adding a bug without changing the bug report template
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/gdevelop5/start) to learn more about GDevelop. Thanks!"
- name: Autoclose known beta 105 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*_instance.getRawFloatProperty is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
- name: Autoclose known beta 114 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*getAssociatedSettings is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
autocomment: autocomment:
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node') if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
steps: steps:
- name: Autocomment indications on bug if it looks like #3453 - name: Autocomment indications on bug if it looks like #3453
uses: peter-evans/create-or-update-comment@v3 uses: peter-evans/create-or-update-comment@v1
with: with:
token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }}
issue-number: ${{ github.event.issue.number }} body: |
body: | Hi @${{ github.actor }}!
Hi @${{ github.actor }}! Thank you for taking the time to open an issue.
Thank you for taking the time to open an issue.
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue. The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,53 +1,29 @@
name: GDevelop Issues automatic workflow name: GDevelop Issues automatic workflow
on: on:
pull_request: pull_request:
types: types: [opened]
- opened
- reopened
- synchronize
jobs: jobs:
read-locales-metadata: read-locales-metadata:
if: github.event.pull_request.title == '[Auto PR] Update translations' if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
runs-on: ubuntu-latest runs-on: ubuntu-latest
env:
COMMENT_TITLE: "Translation ratio changes"
steps: steps:
- uses: actions/checkout@v3 - name: Read and format locales metadata
with: run: |
fetch-depth: 0 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"))
- name: Read and format locales metadata ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
env: SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
BASE: ${{ github.event.pull_request.base.sha }} touch sumup.txt
HEAD: ${{ github.event.pull_request.head.sha }} for index in ${!ADDS[@]}; do
run: | echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
LANS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g")) DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
ADDS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g")) echo $DELTA % >> sumup.txt
SUBS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g")) done
touch sumup.md - name: Store sumup in outputs
echo "## $COMMENT_TITLE" >> sumup.md id: sumup
echo "" >> sumup.md run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
echo "| Language | Change |" >> sumup.md - name: Autocomment pull request with sumup
echo "| --- | --- |" >> sumup.md uses: peter-evans/create-or-update-comment@v1
for index in ${!ADDS[@]}; do with:
DELTA=$(echo "scale=3; (${ADDS[index]} - ${SUBS[index]})*100/1" | bc) issue-number: ${{ github.event.number }}
if (( $(echo "$DELTA == 0" | bc -l) )); then body: ${{ steps.sumup.outputs.sumupFileContent}}
continue token: ${{ secrets.GITHUB_TOKEN }}
fi
LANGUAGE=${LANS[index]//_/ }
echo "| $LANGUAGE | $(printf "%1.3f" $DELTA) % |" >> sumup.md
done
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.number }}
body-includes: ${{ env.COMMENT_TITLE }}
- name: Autocomment pull request with sumup
uses: peter-evans/create-or-update-comment@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.number }}
comment-id: ${{ steps.fc.outputs.comment-id }}
edit-mode: replace
body-path: "sumup.md"

View File

@@ -7,8 +7,6 @@ on:
push: push:
branches: branches:
- master - master
tags-ignore:
- "**" # Don't run on new tags
# Allows to run this workflow manually from the Actions tab. # Allows to run this workflow manually from the Actions tab.
workflow_dispatch: workflow_dispatch:
@@ -16,12 +14,17 @@ jobs:
update-translations: update-translations:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3
# Cache npm dependencies to speed up the workflow
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-newIDE-app-node_modules
with: with:
node-version: 20 # npm cache files are stored in `~/.npm` on Linux/macOS
cache: "npm" path: ~/.npm
cache-dependency-path: "newIDE/app/package-lock.json" key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
- name: Install gettext - name: Install gettext
run: sudo apt update && sudo apt install gettext -y run: sudo apt update && sudo apt install gettext -y
@@ -41,7 +44,7 @@ jobs:
# (Build and) download the most recent translations (PO files) from Crowdin. # (Build and) download the most recent translations (PO files) from Crowdin.
- name: Install Crowdin CLI - name: Install Crowdin CLI
run: npm i -g @crowdin/cli run: npm i -g @crowdin/cli
- name: Download new translations from Crowdin - name: Download new translations from Crowdin
run: crowdin download run: crowdin download
env: env:
@@ -58,13 +61,13 @@ jobs:
working-directory: newIDE/app working-directory: newIDE/app
- name: Create a Pull Request with the changes - name: Create a Pull Request with the changes
uses: peter-evans/create-pull-request@v6 uses: peter-evans/create-pull-request@v3.10.1
with: with:
commit-message: Update translations [skip ci] commit-message: Update translations [skip ci]
branch: chore/update-translations branch: chore/update-translations
delete-branch: true delete-branch: true
title: "[Auto PR] Update translations" title: '[Auto PR] Update translations'
body: | body: |
This updates the translations by downloading them from Crowdin and compiling them for usage by the app. 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. Please double check the values in `newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are sensible.

View File

@@ -14,7 +14,7 @@ tasks:
init: | init: |
sudo apt-get update sudo apt-get update
sudo apt install cmake python-is-python3 python3-distutils -y sudo apt install cmake python-is-python3 python3-distutils -y
git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
cd GDevelop.js cd GDevelop.js
npm install npm install
source ../emsdk/emsdk_env.sh && npm run build -- --dev source ../emsdk/emsdk_env.sh && npm run build -- --dev

View File

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

View File

@@ -39,7 +39,7 @@ install:
- cd .. - cd ..
# Install Emscripten (for GDevelop.js) # Install Emscripten (for GDevelop.js)
- git clone https://github.com/juj/emsdk.git - git clone https://github.com/juj/emsdk.git
- cd emsdk && ./emsdk install 3.1.21 && ./emsdk activate 3.1.21 && cd .. - cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
# Install GDevelop.js dependencies # Install GDevelop.js dependencies
- cd GDevelop.js && npm install && cd .. - cd GDevelop.js && npm install && cd ..
# Build GDevelop.js # Build GDevelop.js

258
.vscode/settings.json vendored
View File

@@ -1,135 +1,131 @@
// Place your settings in this file to overwrite default and user settings. // Place your settings in this file to overwrite default and user settings.
{ {
"files.associations": { "files.associations": {
"*.idl": "java", "*.idl": "java",
"Fastfile": "ruby", "Fastfile": "ruby",
"iosfwd": "cpp", "iosfwd": "cpp",
"functional": "cpp", "functional": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"utility": "cpp", "utility": "cpp",
"algorithm": "cpp", "algorithm": "cpp",
"random": "cpp", "random": "cpp",
"__config": "cpp", "__config": "cpp",
"cstddef": "cpp", "cstddef": "cpp",
"exception": "cpp", "exception": "cpp",
"initializer_list": "cpp", "initializer_list": "cpp",
"new": "cpp", "new": "cpp",
"stdexcept": "cpp", "stdexcept": "cpp",
"typeinfo": "cpp", "typeinfo": "cpp",
"*.tcc": "cpp", "*.tcc": "cpp",
"cctype": "cpp", "cctype": "cpp",
"clocale": "cpp", "clocale": "cpp",
"cmath": "cpp", "cmath": "cpp",
"complex": "cpp", "complex": "cpp",
"cstdarg": "cpp", "cstdarg": "cpp",
"cstdio": "cpp", "cstdio": "cpp",
"cstdlib": "cpp", "cstdlib": "cpp",
"ctime": "cpp", "ctime": "cpp",
"cwchar": "cpp", "cwchar": "cpp",
"cwctype": "cpp", "cwctype": "cpp",
"istream": "cpp", "istream": "cpp",
"limits": "cpp", "limits": "cpp",
"memory": "cpp", "memory": "cpp",
"ostream": "cpp", "ostream": "cpp",
"sstream": "cpp", "sstream": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"hashtable": "cpp", "hashtable": "cpp",
"tuple": "cpp", "tuple": "cpp",
"unordered_map": "cpp", "unordered_map": "cpp",
"unordered_set": "cpp", "unordered_set": "cpp",
"__split_buffer": "cpp", "__split_buffer": "cpp",
"deque": "cpp", "deque": "cpp",
"iterator": "cpp", "iterator": "cpp",
"list": "cpp", "list": "cpp",
"map": "cpp", "map": "cpp",
"queue": "cpp", "queue": "cpp",
"regex": "cpp", "regex": "cpp",
"set": "cpp", "set": "cpp",
"stack": "cpp", "stack": "cpp",
"string": "cpp", "string": "cpp",
"vector": "cpp", "vector": "cpp",
"iostream": "cpp", "iostream": "cpp",
"__functional_03": "cpp", "__functional_03": "cpp",
"__hash_table": "cpp", "__hash_table": "cpp",
"__tree": "cpp", "__tree": "cpp",
"bitset": "cpp", "bitset": "cpp",
"__bit_reference": "cpp", "__bit_reference": "cpp",
"__mutex_base": "cpp", "__mutex_base": "cpp",
"fstream": "cpp", "fstream": "cpp",
"ios": "cpp", "ios": "cpp",
"__locale": "cpp", "__locale": "cpp",
"valarray": "cpp", "valarray": "cpp",
"freeglut_spaceball.c": "cpp", "freeglut_spaceball.c": "cpp",
"__tuple": "cpp", "__tuple": "cpp",
"hash_map": "cpp", "hash_map": "cpp",
"hash_set": "cpp", "hash_set": "cpp",
"system_error": "cpp", "system_error": "cpp",
"__nullptr": "cpp", "__nullptr": "cpp",
"__functional_base": "cpp", "__functional_base": "cpp",
"__functional_base_03": "cpp", "__functional_base_03": "cpp",
"chrono": "cpp", "chrono": "cpp",
"ratio": "cpp", "ratio": "cpp",
"atomic": "cpp", "atomic": "cpp",
"locale": "cpp", "locale": "cpp",
"string_view": "cpp", "string_view": "cpp",
"__string": "cpp", "__string": "cpp",
"cstring": "cpp", "cstring": "cpp",
"iomanip": "cpp", "iomanip": "cpp",
"cstdint": "cpp", "cstdint": "cpp",
"forward_list": "cpp", "forward_list": "cpp",
"mutex": "cpp", "mutex": "cpp",
"__hash": "cpp", "__hash": "cpp",
"__debug": "cpp", "__debug": "cpp",
"__threading_support": "cpp", "__threading_support": "cpp",
"any": "cpp", "any": "cpp",
"array": "cpp", "array": "cpp",
"cinttypes": "cpp", "cinttypes": "cpp",
"numeric": "cpp", "numeric": "cpp",
"__memory": "cpp", "__memory": "cpp",
"__errc": "cpp", "__errc": "cpp",
"__node_handle": "cpp", "__node_handle": "cpp",
"bit": "cpp", "bit": "cpp",
"optional": "cpp", "optional": "cpp",
"filesystem": "cpp", "filesystem": "cpp",
"compare": "cpp", "compare": "cpp",
"concepts": "cpp", "concepts": "cpp",
"xfacet": "cpp", "xfacet": "cpp",
"xhash": "cpp", "xhash": "cpp",
"xiosbase": "cpp", "xiosbase": "cpp",
"xlocale": "cpp", "xlocale": "cpp",
"xlocinfo": "cpp", "xlocinfo": "cpp",
"xlocmon": "cpp", "xlocmon": "cpp",
"xlocnum": "cpp", "xlocnum": "cpp",
"xloctime": "cpp", "xloctime": "cpp",
"xmemory": "cpp", "xmemory": "cpp",
"xstddef": "cpp", "xstddef": "cpp",
"xstring": "cpp", "xstring": "cpp",
"xtr1common": "cpp", "xtr1common": "cpp",
"xtree": "cpp", "xtree": "cpp",
"xutility": "cpp", "xutility": "cpp",
"xlocbuf": "cpp", "xlocbuf": "cpp",
"xlocmes": "cpp", "xlocmes": "cpp",
"xmemory0": "cpp", "xmemory0": "cpp",
"memory_resource": "cpp", "memory_resource": "cpp"
"__bits": "cpp", },
"__verbose_abort": "cpp", "files.exclude": {
"variant": "cpp", "Binaries/*build*": true,
"charconv": "cpp" "Binaries/Output": true,
}, "GDJS/Runtime-dist": true,
"files.exclude": { "docs": true,
"Binaries/*build*": true, "newIDE/electron-app/dist": true,
"Binaries/Output": true, "newIDE/app/build": true,
"GDJS/Runtime-dist": true, "newIDE/app/resources/GDJS": true,
"docs": true, "newIDE/electron-app/app/www": true
"newIDE/electron-app/dist": true, },
"newIDE/app/build": true, // Support for Flowtype (for newIDE):
"newIDE/app/resources/GDJS": true, "javascript.validate.enable": false,
"newIDE/electron-app/app/www": true "flow.useNPMPackagedFlow": true,
},
// Support for Flowtype (for newIDE):
"javascript.validate.enable": false,
"flow.useNPMPackagedFlow": true,
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt) // Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}" "C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
} }

1
.vscode/tasks.json vendored
View File

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

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. 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,100 +1,100 @@
# This is the CMake file used to build GDevelop. #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 3.5) cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0011 NEW)
# Add utility functions # Add utility functions
include(scripts/CMakeClangUtils.txt) # To add clang-format and clang-tidy support to a target include(scripts/CMakeClangUtils.txt) # To add clang-format and clang-tidy support to a target
# Macro for defining an option # Macro for defining an option
macro(gd_set_option var default type docstring) macro(gd_set_option var default type docstring)
if(NOT DEFINED ${var}) if(NOT DEFINED ${var})
set(${var} ${default}) set(${var} ${default})
endif() endif()
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE) set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
endmacro() endmacro()
# Set options
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library") gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS 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_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 TRUE BOOL "TRUE to build the tests")
# Disable deprecated code # Disable deprecated code
set(NO_GUI TRUE CACHE BOOL "" FORCE) # Force disable old GUI related code. set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.
# Setting up installation directory, for Linux (has to be done before "project" command). #Setting up installation directory, for Linux (has to be done before "project" command).
if(NOT WIN32) IF(NOT WIN32)
if(NOT APPLE) if (NOT APPLE)
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed") gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
else() ELSE()
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed") gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
endif() ENDIF()
# As we embed SFML, prevent it to be installed system-wide #As we embed SFML, prevent it to be installed system-wide
set(CMAKE_INSTALL_PREFIX "${GD_INSTALL_PREFIX}/useless") set(CMAKE_INSTALL_PREFIX "${GD_INSTALL_PREFIX}/useless")
endif() ENDIF()
project(GDevelop) project(GDevelop)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS) IF(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
set(CMAKE_SKIP_BUILD_RPATH TRUE) # Avoid errors when packaging for linux. SET(CMAKE_SKIP_BUILD_RPATH TRUE) #Avoid errors when packaging for linux.
endif() ENDIF()
if(APPLE) IF(APPLE)
set(CMAKE_MACOSX_RPATH 1) set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
set(CMAKE_INSTALL_RPATH ".") set(CMAKE_INSTALL_RPATH ".")
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
add_compile_options( set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_")
-D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
-Wno-potentially-evaluated-expression) ENDIF()
endif() #Sanity checks
# Sanity checks IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
if("${CMAKE_BUILD_TYPE}" STREQUAL "") message( "CMAKE_BUILD_TYPE is empty, assuming build type is Release" )
message(STATUS "CMAKE_BUILD_TYPE is empty, assuming build type is Release")
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif() ENDIF()
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX) 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. SET(CMAKE_SHARED_LINKER_FLAGS "-s") #Force stripping to avoid errors when packaging for linux.
endif() ENDIF()
#Activate C++11 #Activate C++11
set(CMAKE_CXX_STANDARD 11) # Upgrading to C++17 would need to remove usage of bind2nd (should be easy). include(CheckCXXCompilerFlag)
set(CMAKE_CXX_STANDARD_REQUIRED ON) CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support (with GNU extensions). Please use a different C++ compiler.")
endif()
# Mark some warnings as errors # Mark some warnings as errors
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Activate as much warnings as possible to avoid errors like # Activate as much warnings as possible to avoid errors like
# uninitialized variables or other hard to debug bugs. # uninitialized variables or other hard to debug bugs.
add_compile_options( set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
-Wall set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
-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")
-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). # Make as much warnings considered as errors as possible (only one for now).
-Werror=return-stack-address set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
-Werror=return-type)
endif() endif()
# Define common directories: #Define common directories:
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR}) set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})
# Add all the CMakeLists: #Add all the CMakeLists:
add_subdirectory(ExtLibs) ADD_SUBDIRECTORY(ExtLibs)
if(BUILD_CORE) IF(BUILD_CORE)
add_subdirectory(Core) ADD_SUBDIRECTORY(Core)
endif() ENDIF()
if(BUILD_GDJS) IF(BUILD_GDJS)
add_subdirectory(GDJS) ADD_SUBDIRECTORY(GDJS)
endif() ENDIF()
if(EMSCRIPTEN) IF(EMSCRIPTEN)
add_subdirectory(GDevelop.js) ADD_SUBDIRECTORY(GDevelop.js)
endif() ENDIF()
if(BUILD_EXTENSIONS) IF(BUILD_EXTENSIONS)
add_subdirectory(Extensions) ADD_SUBDIRECTORY(Extensions)
endif() ENDIF()

View File

@@ -1,98 +1,83 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0015 NEW)
project(GDCore) project(GDCore)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) # Force use response file: useful for Ninja build system on Windows. SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) #Force use response file: useful for Ninja build system on Windows.
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1) SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1) SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1) SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
# Define common directories: #Define common directories:
set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE) set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE)
set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE) set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
# Dependencies on external libraries: #Dependencies on external libraries:
# ###
# Defines #Defines
# ###
add_definitions(-DGD_IDE_ONLY) add_definitions( -DGD_IDE_ONLY )
if(EMSCRIPTEN) IF (EMSCRIPTEN)
add_definitions(-DEMSCRIPTEN) add_definitions( -DEMSCRIPTEN )
endif() ENDIF()
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug") IF(CMAKE_BUILD_TYPE MATCHES "Debug")
add_definitions(-DDEBUG) add_definitions( -DDEBUG )
else() ELSE()
add_definitions(-DRELEASE) add_definitions( -DRELEASE )
endif() ENDIF()
if(WIN32) IF(WIN32)
add_definitions(-DWINDOWS) add_definitions( -DWINDOWS )
add_definitions("-DGD_CORE_API=__declspec(dllexport)") add_definitions( "-DGD_CORE_API=__declspec(dllexport)" )
add_definitions(-D__GNUWIN32__) add_definitions( -D__GNUWIN32__ )
else() ELSE()
if(APPLE) IF(APPLE)
add_definitions(-DMACOS) add_definitions( -DMACOS )
else() ELSE()
add_definitions(-DLINUX) add_definitions( -DLINUX )
endif() ENDIF()
add_definitions(-DGD_API=) add_definitions( -DGD_API= )
add_definitions(-DGD_CORE_API=) add_definitions( -DGD_CORE_API= )
endif() ENDIF(WIN32)
# The target #The target
# ###
include_directories(.) include_directories(.)
file( file(GLOB_RECURSE source_files GDCore/*)
GLOB_RECURSE
source_files
GDCore/*)
file( file(GLOB_RECURSE formatted_source_files tests/* GDCore/Events/* GDCore/Extensions/* GDCore/IDE/* GDCore/Project/* GDCore/Serialization/* GDCore/Tools/*)
GLOB_RECURSE list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
formatted_source_files
tests/*
GDCore/Events/*
GDCore/Extensions/*
GDCore/IDE/*
GDCore/Project/*
GDCore/Serialization/*
GDCore/Tools/*)
list(
REMOVE_ITEM
formatted_source_files
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h"
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
gd_add_clang_utils(GDCore "${formatted_source_files}") gd_add_clang_utils(GDCore "${formatted_source_files}")
if(EMSCRIPTEN) IF(EMSCRIPTEN)
# Emscripten treats all libraries as static libraries # Emscripten treats all libraries as static libraries
add_library(GDCore STATIC ${source_files}) add_library(GDCore STATIC ${source_files})
else() ELSE()
add_library(GDCore SHARED ${source_files}) add_library(GDCore SHARED ${source_files})
endif() ENDIF()
if(EMSCRIPTEN) IF(EMSCRIPTEN)
set_target_properties(GDCore PROPERTIES SUFFIX ".bc") set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
elseif(WIN32) ELSEIF(WIN32)
set_target_properties(GDCore PROPERTIES PREFIX "") set_target_properties(GDCore PROPERTIES PREFIX "")
else() ELSE()
set_target_properties(GDCore PROPERTIES PREFIX "lib") set_target_properties(GDCore PROPERTIES PREFIX "lib")
endif() ENDIF()
set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}) set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
set(ARCHIVE_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME}) set(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}) set(RUNTIME_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
# Tests #Tests
# ###
if(BUILD_TESTS) if(BUILD_TESTS)
file( file(
GLOB_RECURSE GLOB_RECURSE
test_source_files test_source_files
tests/*) tests/*
)
add_executable(GDCore_tests ${test_source_files}) add_executable(GDCore_tests ${test_source_files})
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) # Allow finding dependencies directly from build path on Mac OS X. set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
target_link_libraries(GDCore_tests GDCore) target_link_libraries(GDCore_tests GDCore)
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS}) target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
endif() endif()

View File

@@ -23,9 +23,8 @@ vector<gd::String> CommentEvent::GetAllSearchableStrings() const {
bool CommentEvent::ReplaceAllSearchableStrings( bool CommentEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) { std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == com1) return false;
SetComment(newSearchableString[0]); SetComment(newSearchableString[0]);
return true; return newSearchableString[0] == com1;
} }
void CommentEvent::SerializeTo(SerializerElement &element) const { void CommentEvent::SerializeTo(SerializerElement &element) const {
@@ -38,7 +37,7 @@ void CommentEvent::SerializeTo(SerializerElement &element) const {
.SetAttribute("textB", textB); .SetAttribute("textB", textB);
element.AddChild("comment").SetValue(com1); element.AddChild("comment").SetValue(com1);
if (!com2.empty()) element.AddChild("comment2").SetValue(com2); element.AddChild("comment2").SetValue(com2);
} }
void CommentEvent::UnserializeFrom(gd::Project &project, void CommentEvent::UnserializeFrom(gd::Project &project,
@@ -53,9 +52,7 @@ void CommentEvent::UnserializeFrom(gd::Project &project,
textB = colorElement.GetIntAttribute("textB"); textB = colorElement.GetIntAttribute("textB");
com1 = element.GetChild("comment", 0, "Com1").GetValue().GetString(); 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 } // namespace gd

View File

@@ -45,47 +45,16 @@ ForEachChildVariableEvent::GetAllActionsVectors() const {
return allActions; return allActions;
} }
vector<pair<gd::Expression*, gd::ParameterMetadata> >
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() {
vector<pair<gd::Expression*, gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("scenevar");
allExpressionsWithMetadata.push_back(
std::make_pair(&iterableVariableName, metadata));
allExpressionsWithMetadata.push_back(
std::make_pair(&valueIteratorVariableName, metadata));
allExpressionsWithMetadata.push_back(
std::make_pair(&keyIteratorVariableName, metadata));
return allExpressionsWithMetadata;
}
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
ForEachChildVariableEvent::GetAllExpressionsWithMetadata() const {
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("scenevar");
allExpressionsWithMetadata.push_back(
std::make_pair(&iterableVariableName, metadata));
allExpressionsWithMetadata.push_back(
std::make_pair(&valueIteratorVariableName, metadata));
allExpressionsWithMetadata.push_back(
std::make_pair(&keyIteratorVariableName, metadata));
return allExpressionsWithMetadata;
}
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const { void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
element.AddChild("iterableVariableName").SetValue(iterableVariableName.GetPlainString()); element.AddChild("iterableVariableName").SetValue(iterableVariableName);
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName.GetPlainString()); element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName);
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName.GetPlainString()); element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName);
gd::EventsListSerialization::SerializeInstructionsTo( gd::EventsListSerialization::SerializeInstructionsTo(
conditions, element.AddChild("conditions")); conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo( gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions")); actions, element.AddChild("actions"));
gd::EventsListSerialization::SerializeEventsTo(events,
if (!events.IsEmpty()) element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
} }
void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project, void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
@@ -97,12 +66,8 @@ void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions")); project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom( gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions")); project, actions, element.GetChild("actions", 0, "Actions"));
gd::EventsListSerialization::UnserializeEventsFrom(
events.Clear(); project, events, element.GetChild("events", 0, "Events"));
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} }
} // namespace gd } // namespace gd

View File

@@ -8,7 +8,6 @@
#define FOREACHCHILDVARIABLEEVENT_H #define FOREACHCHILDVARIABLEEVENT_H
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
#include "GDCore/Events/Expression.h"
namespace gd { namespace gd {
class Instruction; class Instruction;
class Project; class Project;
@@ -45,7 +44,7 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
* *
* It is the structure variable that will be iterated on. * It is the structure variable that will be iterated on.
*/ */
const gd::String& GetIterableVariableName() const { return iterableVariableName.GetPlainString(); }; const gd::String& GetIterableVariableName() const { return iterableVariableName; };
/** /**
* \brief Set the iterable variable name attached to the event. * \brief Set the iterable variable name attached to the event.
@@ -57,15 +56,15 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
/** /**
* \brief Get the value iterator variable attached to the event. * \brief Get the value iterator variable attached to the event.
* *
* It is the variable that will contain the value of the * It is the variable that will contain the value of the
* iterable's child being iterated on. * iterable's child being iterated on.
*/ */
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName.GetPlainString(); }; const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName; };
/** /**
* \brief Set the value iterator variable attached to the event. * \brief Set the value iterator variable attached to the event.
* *
* It is the variable that will contain the value of the * It is the variable that will contain the value of the
* iterable's child being iterated on. * iterable's child being iterated on.
*/ */
void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; }; void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; };
@@ -73,15 +72,15 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
/** /**
* \brief Get the key iterator variable attached to the event. * \brief Get the key iterator variable attached to the event.
* *
* It is the variable that will contain the name of the * It is the variable that will contain the name of the
* iterable's child being iterated on. * iterable's child being iterated on.
*/ */
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName.GetPlainString(); }; const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName; };
/** /**
* \brief Set the key iterator variable attached to the event. * \brief Set the key iterator variable attached to the event.
* *
* It is the variable that will contain the name of the * It is the variable that will contain the name of the
* iterable's child being iterated on. * iterable's child being iterated on.
*/ */
void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; }; void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; };
@@ -93,19 +92,14 @@ class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors(); virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors(); virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() const;
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
GetAllExpressionsWithMetadata();
virtual void SerializeTo(SerializerElement& element) const; virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project, virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element); const SerializerElement& element);
private: private:
gd::Expression valueIteratorVariableName; gd::String valueIteratorVariableName;
gd::Expression keyIteratorVariableName; gd::String keyIteratorVariableName;
gd::Expression iterableVariableName; gd::String iterableVariableName;
gd::InstructionsList conditions; gd::InstructionsList conditions;
gd::InstructionsList actions; gd::InstructionsList actions;
gd::EventsList events; gd::EventsList events;

View File

@@ -15,7 +15,7 @@ using namespace std;
namespace gd { namespace gd {
ForEachEvent::ForEachEvent() ForEachEvent::ForEachEvent()
: BaseEvent(), objectsToPick("") {} : BaseEvent(), objectsToPick(""), objectsToPickSelected(false) {}
vector<gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors() { vector<gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors() {
vector<gd::InstructionsList*> allConditions; vector<gd::InstructionsList*> allConditions;
@@ -74,10 +74,8 @@ void ForEachEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions")); conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo( gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions")); actions, element.AddChild("actions"));
gd::EventsListSerialization::SerializeEventsTo(events,
if (!events.IsEmpty()) element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
} }
void ForEachEvent::UnserializeFrom(gd::Project& project, void ForEachEvent::UnserializeFrom(gd::Project& project,
@@ -88,12 +86,8 @@ void ForEachEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions")); project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom( gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions")); project, actions, element.GetChild("actions", 0, "Actions"));
gd::EventsListSerialization::UnserializeEventsFrom(
events.Clear(); project, events, element.GetChild("events", 0, "Events"));
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} }
} // namespace gd } // namespace gd

View File

@@ -6,8 +6,6 @@
#ifndef FOREACHEVENT_H #ifndef FOREACHEVENT_H
#define FOREACHEVENT_H #define FOREACHEVENT_H
#include <vector>
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
namespace gd { namespace gd {
@@ -69,6 +67,8 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
gd::InstructionsList conditions; gd::InstructionsList conditions;
gd::InstructionsList actions; gd::InstructionsList actions;
gd::EventsList events; gd::EventsList events;
bool objectsToPickSelected;
}; };
} // namespace gd } // namespace gd

View File

@@ -29,9 +29,8 @@ vector<gd::String> GroupEvent::GetAllSearchableStrings() const {
bool GroupEvent::ReplaceAllSearchableStrings( bool GroupEvent::ReplaceAllSearchableStrings(
std::vector<gd::String> newSearchableString) { std::vector<gd::String> newSearchableString) {
if (newSearchableString[0] == name) return false;
SetName(newSearchableString[0]); SetName(newSearchableString[0]);
return true; return newSearchableString[0] == name;
} }
void GroupEvent::SerializeTo(SerializerElement& element) const { void GroupEvent::SerializeTo(SerializerElement& element) const {

View File

@@ -13,7 +13,6 @@
namespace gd { namespace gd {
class Instruction; class Instruction;
class Project; class Project;
class EventVisitor;
} }
class EventsCodeGenerationContext; class EventsCodeGenerationContext;

View File

@@ -16,7 +16,6 @@
#include "GDCore/Project/Object.h" #include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Events/EventVisitor.h"
using namespace std; using namespace std;
@@ -131,46 +130,30 @@ void LinkEvent::SerializeTo(SerializerElement& element) const {
void LinkEvent::UnserializeFrom(gd::Project& project, void LinkEvent::UnserializeFrom(gd::Project& project,
const SerializerElement& element) { const SerializerElement& element) {
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString()); SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString());
// Compatibility with GD <= 5 if (includeElement.HasAttribute("includeAll")) {
if (element.HasChild("include", "Limites")) { // Compatibility with GDevelop <= 4.0.92
SerializerElement& includeElement = element.GetChild("include", 0, "Limites"); if (includeElement.GetBoolAttribute("includeAll", true)) {
if (includeElement.HasAttribute("includeAll")) { SetIncludeAllEvents();
// Compatibility with GDevelop <= 4.0.92
if (includeElement.GetBoolAttribute("includeAll", true)) {
SetIncludeAllEvents();
} else {
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
includeElement.GetIntAttribute("end"));
}
} else { } else {
// GDevelop > 4.0.92 SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
IncludeConfig config = static_cast<IncludeConfig>( includeElement.GetIntAttribute("end"));
includeElement.GetIntAttribute("includeConfig", 0));
if (config == INCLUDE_ALL)
SetIncludeAllEvents();
else if (config == INCLUDE_EVENTS_GROUP)
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
else if (config == INCLUDE_BY_INDEX)
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
includeElement.GetIntAttribute("end"));
} }
} else { } else {
// Since GDevelop 5, links always include all events. // GDevelop > 4.0.92
SetIncludeAllEvents(); IncludeConfig config = static_cast<IncludeConfig>(
includeElement.GetIntAttribute("includeConfig", 0));
if (config == INCLUDE_ALL)
SetIncludeAllEvents();
else if (config == INCLUDE_EVENTS_GROUP)
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
else if (config == INCLUDE_BY_INDEX)
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
includeElement.GetIntAttribute("end"));
} }
// end of compatibility code
}
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
return BaseEvent::AcceptVisitor(eventVisitor) ||
eventVisitor.VisitLinkEvent(*this);
}
void LinkEvent::AcceptVisitor(gd::ReadOnlyEventVisitor &eventVisitor) const {
BaseEvent::AcceptVisitor(eventVisitor);
eventVisitor.VisitLinkEvent(*this);
} }
} // namespace gd } // namespace gd

View File

@@ -30,7 +30,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
includeEnd(gd::String::npos), includeEnd(gd::String::npos),
linkWasInvalid(false){}; linkWasInvalid(false){};
virtual ~LinkEvent(); 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). * 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. * 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. * \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, EventsList& eventList,
std::size_t indexOfTheEventInThisList); 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, virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element) override; const SerializerElement& element);
bool AcceptVisitor(gd::EventVisitor& eventVisitor) override;
void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const override;
private: private:
gd::String gd::String

View File

@@ -35,7 +35,7 @@ vector<pair<gd::Expression*, gd::ParameterMetadata> >
RepeatEvent::GetAllExpressionsWithMetadata() { RepeatEvent::GetAllExpressionsWithMetadata() {
vector<pair<gd::Expression*, gd::ParameterMetadata> > vector<pair<gd::Expression*, gd::ParameterMetadata> >
allExpressionsWithMetadata; allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("number"); auto metadata = gd::ParameterMetadata().SetType("expression");
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(
std::make_pair(&repeatNumberExpression, metadata)); std::make_pair(&repeatNumberExpression, metadata));
@@ -61,7 +61,7 @@ vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
RepeatEvent::GetAllExpressionsWithMetadata() const { RepeatEvent::GetAllExpressionsWithMetadata() const {
vector<pair<const gd::Expression*, const gd::ParameterMetadata> > vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
allExpressionsWithMetadata; allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("number"); auto metadata = gd::ParameterMetadata().SetType("expression");
allExpressionsWithMetadata.push_back( allExpressionsWithMetadata.push_back(
std::make_pair(&repeatNumberExpression, metadata)); std::make_pair(&repeatNumberExpression, metadata));
@@ -75,10 +75,8 @@ void RepeatEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions")); conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo( gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions")); actions, element.AddChild("actions"));
gd::EventsListSerialization::SerializeEventsTo(events,
if (!events.IsEmpty()) element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
} }
void RepeatEvent::UnserializeFrom(gd::Project& project, void RepeatEvent::UnserializeFrom(gd::Project& project,
@@ -91,12 +89,8 @@ void RepeatEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions")); project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom( gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions")); project, actions, element.GetChild("actions", 0, "Actions"));
gd::EventsListSerialization::UnserializeEventsFrom(
events.Clear(); project, events, element.GetChild("events", 0, "Events"));
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} }
} // namespace gd } // namespace gd

View File

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

View File

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

View File

@@ -52,10 +52,8 @@ void WhileEvent::SerializeTo(SerializerElement& element) const {
conditions, element.AddChild("conditions")); conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo( gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions")); actions, element.AddChild("actions"));
gd::EventsListSerialization::SerializeEventsTo(events,
if (!events.IsEmpty()) element.AddChild("events"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
} }
void WhileEvent::UnserializeFrom(gd::Project& project, void WhileEvent::UnserializeFrom(gd::Project& project,
@@ -70,12 +68,8 @@ void WhileEvent::UnserializeFrom(gd::Project& project,
project, conditions, element.GetChild("conditions", 0, "Conditions")); project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom( gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions")); project, actions, element.GetChild("actions", 0, "Actions"));
gd::EventsListSerialization::UnserializeEventsFrom(
events.Clear(); project, events, element.GetChild("events", 0, "Events"));
if (element.HasChild("events", "Events")) {
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} }
} // namespace gd } // namespace gd

View File

@@ -15,44 +15,16 @@
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h" #include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
namespace gd { namespace gd {
void EffectsCodeGenerator::DoVisitObject(gd::Object &object) { void ExposeProjectEffects(
auto &effects = object.GetEffects(); const gd::Project& project,
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) { const std::function<void(const gd::Effect& effect)>& worker) {
auto &effect = effects.GetEffect(e);
AddEffectIncludeFiles(effect);
}
};
void EffectsCodeGenerator::AddEffectIncludeFiles(const gd::Effect &effect) {
// TODO: this browse all the extensions every time we're trying to find
// a new effect. Might be a good idea to rework MetadataProvider to be
// faster (not sure if it is a bottleneck at all though - but could be
// for events code generation).
const gd::EffectMetadata &effectMetadata =
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
for (auto &includeFile : effectMetadata.GetIncludeFiles())
includeFiles.insert(includeFile);
};
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
const gd::Platform &platform,
gd::Project &project,
std::set<gd::String> &includeFiles) {
// TODO Add unit tests on this function.
// TODO Merge with UsedExtensionsFinder.
// See also gd::Project::ExposeResources for a method that traverse the whole // See also gd::Project::ExposeResources for a method that traverse the whole
// project (this time for resources) and // project (this time for resources) and
// WholeProjectRefactorer::ExposeProjectEvents. // WholeProjectRefactorer::ExposeProjectEvents.
EffectsCodeGenerator effectsCodeGenerator(platform, includeFiles);
// Add layouts effects // Add layouts effects
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) { for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
auto& layout = project.GetLayout(s); auto& layout = project.GetLayout(s);
@@ -61,13 +33,47 @@ void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
auto& effects = layout.GetLayer(l).GetEffects(); auto& effects = layout.GetLayer(l).GetEffects();
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) { for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
auto& effect = effects.GetEffect(e); auto& effect = effects.GetEffect(e);
effectsCodeGenerator.AddEffectIncludeFiles(effect); 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 objects effects // Add global object effects
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator); 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);
}
}
}
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
const gd::Platform& platform,
const gd::Project& project,
std::set<gd::String>& includeFiles) {
ExposeProjectEffects(
project, [&platform, &includeFiles](const gd::Effect& effect) {
// TODO: this browse all the extensions every time we're trying to find
// a new effect. Might be a good idea to rework MetadataProvider to be
// faster (not sure if it is a bottleneck at all though - but could be
// for events code generation).
const gd::EffectMetadata& effectMetadata =
MetadataProvider::GetEffectMetadata(platform,
effect.GetEffectType());
for (auto& includeFile : effectMetadata.GetIncludeFiles())
includeFiles.insert(includeFile);
});
} }
} // namespace gd } // namespace gd

View File

@@ -3,18 +3,16 @@
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_EffectsCodeGenerator_H
#define GDCORE_EffectsCodeGenerator_H
#include <set> #include <set>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "GDCore/String.h" #include "GDCore/String.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
namespace gd { namespace gd {
class Project; class Project;
class Platform; class Platform;
class Effect;
} // namespace gd } // namespace gd
namespace gd { namespace gd {
@@ -22,26 +20,16 @@ namespace gd {
/** /**
* \brief Internal class used to generate code from events * \brief Internal class used to generate code from events
*/ */
class GD_CORE_API EffectsCodeGenerator : public ArbitraryObjectsWorker { class GD_CORE_API EffectsCodeGenerator {
public: public:
/** /**
* \brief Add all the include files required by the project effects. * \brief Add all the include files required by the project effects.
*/ */
static void GenerateEffectsIncludeFiles(const gd::Platform& platform, static void GenerateEffectsIncludeFiles(const gd::Platform& platform,
gd::Project& project, const gd::Project& project,
std::set<gd::String>& includeFiles); std::set<gd::String>& includeFiles);
private:
EffectsCodeGenerator(const gd::Platform &platform_,
std::set<gd::String> &includeFiles_)
: platform(platform_), includeFiles(includeFiles_){};
void AddEffectIncludeFiles(const gd::Effect& effect);
void DoVisitObject(gd::Object &object) override;
const gd::Platform &platform;
std::set<gd::String> &includeFiles;
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_EffectsCodeGenerator_H

View File

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

View File

@@ -16,7 +16,6 @@
#include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/ObjectsContainer.h" #include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainersList.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
using namespace std; using namespace std;
@@ -44,7 +43,7 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
std::size_t relationalOperatorIndex = instrInfos.parameters.size(); std::size_t relationalOperatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++i) {
if (instrInfos.parameters[i].GetType() == "relationalOperator") if (instrInfos.parameters[i].type == "relationalOperator")
relationalOperatorIndex = i; relationalOperatorIndex = i;
} }
// Ensure that there is at least one parameter after the relational operator // Ensure that there is at least one parameter after the relational operator
@@ -69,36 +68,8 @@ gd::String EventsCodeGenerator::GenerateRelationalOperatorCall(
} }
} }
auto lhs = callStartString + "(" + argumentsStr + ")"; return callStartString + "(" + argumentsStr + ") " + relationalOperator +
return GenerateRelationalOperation(relationalOperator, lhs, rhs); " " + rhs;
}
/**
* @brief Generate a relational operation
*
* @param relationalOperator the operator
* @param lhs the left hand operand
* @param rhs the right hand operand
* @return gd::String
*/
gd::String EventsCodeGenerator::GenerateRelationalOperation(
const gd::String& relationalOperator,
const gd::String& lhs,
const gd::String& rhs) {
return lhs + " " + GenerateRelationalOperatorCodes(relationalOperator) + " " + rhs;
}
const gd::String EventsCodeGenerator::GenerateRelationalOperatorCodes(const gd::String &operatorString) {
if (operatorString == "=") {
return "==";
}
if (operatorString != "<" && operatorString != ">" &&
operatorString != "<=" && operatorString != ">=" && operatorString != "!=" &&
operatorString != "startsWith" && operatorString != "endsWith" && operatorString != "contains") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
return "==";
}
return operatorString;
} }
/** /**
@@ -124,7 +95,7 @@ gd::String EventsCodeGenerator::GenerateOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++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 // Ensure that there is at least one parameter after the operator
@@ -193,7 +164,7 @@ gd::String EventsCodeGenerator::GenerateCompoundOperatorCall(
std::size_t operatorIndex = instrInfos.parameters.size(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++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 // Ensure that there is at least one parameter after the operator
@@ -244,7 +215,7 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
std::size_t operatorIndex = instrInfos.parameters.size(); std::size_t operatorIndex = instrInfos.parameters.size();
for (std::size_t i = startFromArgument; i < instrInfos.parameters.size(); for (std::size_t i = startFromArgument; i < instrInfos.parameters.size();
++i) { ++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 // Ensure that there is at least one parameter after the operator
@@ -254,12 +225,12 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
} }
gd::String operatorStr = arguments[operatorIndex]; gd::String operatorStr = arguments[operatorIndex];
if (operatorStr.size() > 2 && operatorStr[0] == '\"') { if (operatorStr.size() > 2)
operatorStr = operatorStr.substr( operatorStr = operatorStr.substr(
1, 1,
operatorStr.length() - 1 - operatorStr.length() - 1 -
1); // Operator contains quote which must be removed. 1); // Operator contains quote which must be removed.
}
auto mutators = instrInfos.codeExtraInformation.optionalMutators; auto mutators = instrInfos.codeExtraInformation.optionalMutators;
auto mutator = mutators.find(operatorStr); auto mutator = mutators.find(operatorStr);
if (mutator == mutators.end()) { if (mutator == mutators.end()) {
@@ -279,9 +250,6 @@ gd::String EventsCodeGenerator::GenerateMutatorCall(
argumentsStr += arguments[i]; argumentsStr += arguments[i];
} }
} }
if (instrInfos.GetManipulatedType() == "boolean") {
return callStartString + "(" + argumentsStr + ")." + mutator->second;
}
return callStartString + "(" + argumentsStr + ")." + mutator->second + "(" + return callStartString + "(" + argumentsStr + ")." + mutator->second + "(" +
rhs + ")"; rhs + ")";
@@ -299,12 +267,14 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
return "/* Unknown instruction - skipped. */"; return "/* Unknown instruction - skipped. */";
} }
AddIncludeFiles(instrInfos.GetIncludeFiles()); AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
maxConditionsListsSize = maxConditionsListsSize =
std::max(maxConditionsListsSize, condition.GetSubInstructions().size()); std::max(maxConditionsListsSize, condition.GetSubInstructions().size());
if (instrInfos.HasCustomCodeGenerator()) { if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
context.EnterCustomCondition(); context.EnterCustomCondition();
conditionCode += GenerateReferenceToUpperScopeBoolean(
"conditionTrue", returnBoolean, context);
conditionCode += instrInfos.codeExtraInformation.customCodeGenerator( conditionCode += instrInfos.codeExtraInformation.customCodeGenerator(
condition, *this, context); condition, *this, context);
maxCustomConditionsDepth = maxCustomConditionsDepth =
@@ -321,17 +291,23 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.SetParameters(parameters); 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) { 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 = gd::String objectInParameter =
condition.GetParameter(pNb).GetPlainString(); condition.GetParameter(pNb).GetPlainString();
if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) { if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */"; return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() && } else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
GetObjectsContainersList().GetTypeOfObject(objectInParameter) != gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
instrInfos.parameters[pNb].GetExtraInfo()) { GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */"; return "/* Mismatched object type - skipped. */";
} }
} }
@@ -341,13 +317,19 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
gd::String objectName = condition.GetParameter(0).GetPlainString(); gd::String objectName = condition.GetParameter(0).GetPlainString();
if (!objectName.empty() && !instrInfos.parameters.empty()) { if (!objectName.empty() && !instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context // Set up the context
gd::String objectType = GetObjectsContainersList().GetTypeOfObject(realObjects[i]); gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo = const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType); MetadataProvider::GetObjectMetadata(platform, objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
conditionCode +=
"/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles); AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]); context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]); context.ObjectsListNeeded(realObjects[i]);
@@ -364,14 +346,18 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
context); context);
context.SetNoCurrentObject(); context.SetNoCurrentObject();
}
} }
} }
} else if (instrInfos.IsBehaviorInstruction()) { } else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString(); gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(condition.GetParameter(1).GetPlainString()); gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
condition.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) { if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context // Setup context
const BehaviorMetadata& autoInfo = const BehaviorMetadata& autoInfo =
@@ -475,21 +461,13 @@ gd::String EventsCodeGenerator::GenerateActionCode(
return "/* Unknown instruction - skipped. */"; return "/* Unknown instruction - skipped. */";
} }
AddIncludeFiles(instrInfos.GetIncludeFiles()); AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
if (instrInfos.HasCustomCodeGenerator()) { if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
return instrInfos.codeExtraInformation.customCodeGenerator( return instrInfos.codeExtraInformation.customCodeGenerator(
action, *this, context); 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. // Be sure there is no lack of parameter.
while (action.GetParameters().size() < instrInfos.parameters.size()) { while (action.GetParameters().size() < instrInfos.parameters.size()) {
vector<gd::Expression> parameters = action.GetParameters(); vector<gd::Expression> parameters = action.GetParameters();
@@ -497,15 +475,21 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.SetParameters(parameters); 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) { 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(); gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
if (!GetObjectsContainersList().HasObjectOrGroupNamed(objectInParameter)) { if (!GetObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetGlobalObjectsAndGroups().HasObjectNamed(objectInParameter) &&
!GetObjectsAndGroups().GetObjectGroups().Has(objectInParameter) &&
!GetGlobalObjectsAndGroups().GetObjectGroups().Has(
objectInParameter)) {
return "/* Unknown object - skipped. */"; return "/* Unknown object - skipped. */";
} else if (!instrInfos.parameters[pNb].GetExtraInfo().empty() && } else if (!instrInfos.parameters[pNb].supplementaryInformation.empty() &&
GetObjectsContainersList().GetTypeOfObject(objectInParameter) != gd::GetTypeOfObject(GetGlobalObjectsAndGroups(),
instrInfos.parameters[pNb].GetExtraInfo()) { GetObjectsAndGroups(),
objectInParameter) !=
instrInfos.parameters[pNb].supplementaryInformation) {
return "/* Mismatched object type - skipped. */"; return "/* Mismatched object type - skipped. */";
} }
} }
@@ -517,13 +501,18 @@ gd::String EventsCodeGenerator::GenerateActionCode(
if (!instrInfos.parameters.empty()) { if (!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context // Setup context
gd::String objectType = GetObjectsContainersList().GetTypeOfObject(realObjects[i]); gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), realObjects[i]);
const ObjectMetadata& objInfo = const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType); MetadataProvider::GetObjectMetadata(platform, objectType);
if (objInfo.IsUnsupportedBaseObjectCapability(
instrInfos.GetRequiredBaseObjectCapability())) {
actionCode += "/* Object with unsupported capability - skipped. */\n";
} else {
AddIncludeFiles(objInfo.includeFiles); AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]); context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]); context.ObjectsListNeeded(realObjects[i]);
@@ -533,22 +522,25 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.GetParameters(), instrInfos.parameters, context); action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(realObjects[i], actionCode += GenerateObjectAction(realObjects[i],
objInfo, objInfo,
functionCallName,
arguments, arguments,
instrInfos, instrInfos,
context, context,
optionalAsyncCallbackName); optionalAsyncCallbackName);
context.SetNoCurrentObject(); context.SetNoCurrentObject();
}
} }
} }
} else if (instrInfos.IsBehaviorInstruction()) { } else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString(); gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String behaviorType = GetObjectsContainersList().GetTypeOfBehavior(action.GetParameter(1).GetPlainString()); gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
action.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) { if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context // Setup context
const BehaviorMetadata& autoInfo = const BehaviorMetadata& autoInfo =
@@ -564,7 +556,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
GenerateBehaviorAction(realObjects[i], GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(), action.GetParameter(1).GetPlainString(),
autoInfo, autoInfo,
functionCallName,
arguments, arguments,
instrInfos, instrInfos,
context, context,
@@ -576,22 +567,13 @@ gd::String EventsCodeGenerator::GenerateActionCode(
} else { } else {
vector<gd::String> arguments = GenerateParametersCodes( vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context); action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateFreeAction(functionCallName, actionCode +=
arguments, GenerateFreeAction(arguments, instrInfos, context, optionalAsyncCallbackName);
instrInfos,
context,
optionalAsyncCallbackName);
} }
return actionCode; return actionCode;
} }
gd::String EventsCodeGenerator::GenerateLocalVariablesStackAccessor() {
return (HasProjectAndLayout() ? GetCodeNamespace()
: "eventsFunctionContext") +
".localVariables";
}
const EventsCodeGenerator::CallbackDescriptor const EventsCodeGenerator::CallbackDescriptor
EventsCodeGenerator::GenerateCallback( EventsCodeGenerator::GenerateCallback(
const gd::String& callbackID, const gd::String& callbackID,
@@ -616,20 +598,14 @@ EventsCodeGenerator::GenerateCallback(
actionsCode += "} //End of subevents\n"; actionsCode += "} //End of subevents\n";
} }
gd::String restoreLocalVariablesCode;
restoreLocalVariablesCode +=
"asyncObjectsList.restoreLocalVariablesContainers(" +
GenerateLocalVariablesStackAccessor() + ");\n";
// Compose the callback function and add outside main // Compose the callback function and add outside main
const gd::String actionsDeclarationsCode = const gd::String actionsDeclarationsCode =
GenerateObjectsDeclarationCode(callbackContext); GenerateObjectsDeclarationCode(callbackContext);
const gd::String callbackCode = const gd::String callbackCode = callbackFunctionName + " = function (" +
callbackFunctionName + " = function (" + GenerateEventsParameters(callbackContext) +
GenerateEventsParameters(callbackContext) + ") {\n" + ") {\n" + actionsDeclarationsCode +
restoreLocalVariablesCode + actionsCode + "}\n";
actionsDeclarationsCode + actionsCode + "}\n";
AddCustomCodeOutsideMain(callbackCode); AddCustomCodeOutsideMain(callbackCode);
@@ -682,7 +658,7 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
} }
gd::String EventsCodeGenerator::GenerateParameterCodes( gd::String EventsCodeGenerator::GenerateParameterCodes(
const gd::Expression& parameter, const gd::String& parameter,
const gd::ParameterMetadata& metadata, const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName, const gd::String& lastObjectName,
@@ -690,84 +666,79 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
supplementaryParametersTypes) { supplementaryParametersTypes) {
gd::String argOutput; gd::String argOutput;
if (ParameterMetadata::IsExpression("number", metadata.GetType())) { if (ParameterMetadata::IsExpression("number", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "number", parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, "number", parameter);
} else if (ParameterMetadata::IsExpression("string", metadata.GetType())) { } else if (ParameterMetadata::IsExpression("string", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, "string", parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, "string", parameter);
} else if (ParameterMetadata::IsExpression("variable", metadata.GetType())) { } else if (ParameterMetadata::IsExpression("variable", metadata.type)) {
argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode( argOutput = gd::ExpressionCodeGenerator::GenerateExpressionCode(
*this, context, metadata.GetType(), parameter, lastObjectName, metadata.GetExtraInfo()); *this, context, metadata.type, parameter, lastObjectName);
} else if (ParameterMetadata::IsObject(metadata.GetType())) { } else if (ParameterMetadata::IsObject(metadata.type)) {
// It would be possible to run a gd::ExpressionCodeGenerator if later // It would be possible to run a gd::ExpressionCodeGenerator if later
// objects can have nested objects, or function returning objects. // objects can have nested objects, or function returning objects.
argOutput = argOutput = GenerateObject(parameter, metadata.type, context);
GenerateObject(parameter.GetPlainString(), metadata.GetType(), context); } else if (metadata.type == "relationalOperator") {
} else if (metadata.GetType() == "relationalOperator") { argOutput += parameter == "=" ? "==" : parameter;
argOutput += parameter.GetPlainString(); if (argOutput != "==" && argOutput != "<" && argOutput != ">" &&
argOutput != "<=" && argOutput != ">=" && argOutput != "!=") {
cout << "Warning: Bad relational operator: Set to == by default." << endl;
argOutput = "==";
}
argOutput = "\"" + argOutput + "\""; argOutput = "\"" + argOutput + "\"";
} else if (metadata.GetType() == "operator") { } else if (metadata.type == "operator") {
argOutput += parameter.GetPlainString(); argOutput += parameter;
if (argOutput != "=" && argOutput != "+" && argOutput != "-" && if (argOutput != "=" && argOutput != "+" && argOutput != "-" &&
argOutput != "/" && argOutput != "*" && argOutput != "True" && argOutput != "/" && argOutput != "*") {
argOutput != "False" && argOutput != "Toggle") {
cout << "Warning: Bad operator: Set to = by default." << endl; cout << "Warning: Bad operator: Set to = by default." << endl;
argOutput = "="; argOutput = "=";
} }
argOutput = "\"" + argOutput + "\""; argOutput = "\"" + argOutput + "\"";
} else if (ParameterMetadata::IsBehavior(metadata.GetType())) { } else if (ParameterMetadata::IsBehavior(metadata.type)) {
argOutput = GenerateGetBehaviorNameCode(parameter.GetPlainString()); argOutput = GenerateGetBehaviorNameCode(parameter);
} else if (metadata.GetType() == "key") { } else if (metadata.type == "key") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.GetType() == "audioResource" || } else if (metadata.type == "audioResource" ||
metadata.GetType() == "bitmapFontResource" || metadata.type == "bitmapFontResource" ||
metadata.GetType() == "fontResource" || metadata.type == "fontResource" ||
metadata.GetType() == "imageResource" || metadata.type == "imageResource" ||
metadata.GetType() == "jsonResource" || metadata.type == "jsonResource" ||
metadata.GetType() == "tilemapResource" || metadata.type == "videoResource" ||
metadata.GetType() == "tilesetResource" ||
metadata.GetType() == "videoResource" ||
metadata.GetType() == "model3DResource" ||
metadata.GetType() == "atlasResource" ||
metadata.GetType() == "spineResource" ||
// Deprecated, old parameter names: // Deprecated, old parameter names:
metadata.GetType() == "password" || metadata.GetType() == "musicfile" || metadata.type == "password" || metadata.type == "musicfile" ||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") { metadata.type == "soundfile" || metadata.type == "police") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.GetType() == "mouse") { } else if (metadata.type == "mouse") {
argOutput = "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.GetType() == "yesorno") { } else if (metadata.type == "yesorno") {
auto parameterString = parameter.GetPlainString(); argOutput += (parameter == "yes" || parameter == "oui") ? GenerateTrue()
argOutput += (parameterString == "yes" || parameterString == "oui") : GenerateFalse();
? GenerateTrue() } else if (metadata.type == "trueorfalse") {
: GenerateFalse();
} else if (metadata.GetType() == "trueorfalse") {
auto parameterString = parameter.GetPlainString();
// This is duplicated in AdvancedExtension.cpp for GDJS // This is duplicated in AdvancedExtension.cpp for GDJS
argOutput += (parameterString == "True" || parameterString == "Vrai") argOutput += (parameter == "True" || parameter == "Vrai") ? GenerateTrue()
? GenerateTrue() : GenerateFalse();
: GenerateFalse();
} }
// Code only parameter type // Code only parameter type
else if (metadata.GetType() == "inlineCode") { else if (metadata.type == "inlineCode") {
argOutput += metadata.GetExtraInfo(); argOutput += metadata.supplementaryInformation;
} else { } else {
// Try supplementary types if provided // Try supplementary types if provided
if (supplementaryParametersTypes) { if (supplementaryParametersTypes) {
for (std::size_t i = 0; i < supplementaryParametersTypes->size(); ++i) { 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; argOutput += (*supplementaryParametersTypes)[i].second;
} }
} }
// Type unknown // Type unknown
if (argOutput.empty()) { if (argOutput.empty()) {
if (!metadata.GetType().empty()) if (!metadata.type.empty())
cout << "Warning: Unknown type of parameter \"" << metadata.GetType() cout << "Warning: Unknown type of parameter \"" << metadata.type
<< "\"." << std::endl; << "\"." << std::endl;
argOutput += "\"" + ConvertToString(parameter.GetPlainString()) + "\""; argOutput += "\"" + ConvertToString(parameter) + "\"";
} }
} }
@@ -787,7 +758,7 @@ vector<gd::String> EventsCodeGenerator::GenerateParametersCodes(
parametersInfo, parametersInfo,
[this, &context, &supplementaryParametersTypes, &arguments]( [this, &context, &supplementaryParametersTypes, &arguments](
const gd::ParameterMetadata& parameterMetadata, const gd::ParameterMetadata& parameterMetadata,
const gd::Expression& parameterValue, const gd::String& parameterValue,
const gd::String& lastObjectName) { const gd::String& lastObjectName) {
gd::String argOutput = gd::String argOutput =
GenerateParameterCodes(parameterValue, GenerateParameterCodes(parameterValue,
@@ -881,11 +852,6 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
gd::EventsList& events, EventsCodeGenerationContext& parentContext) { gd::EventsList& events, EventsCodeGenerationContext& parentContext) {
gd::String output; gd::String output;
for (std::size_t eId = 0; eId < events.size(); ++eId) { for (std::size_t eId = 0; eId < events.size(); ++eId) {
auto& event = events[eId];
if (event.HasVariables()) {
GetProjectScopedContainers().GetVariablesContainersList().Push(event.GetVariables());
}
// Each event has its own context : Objects picked in an event are totally // Each event has its own context : Objects picked in an event are totally
// different than the one picked in another. // different than the one picked in another.
gd::EventsCodeGenerationContext newContext; gd::EventsCodeGenerationContext newContext;
@@ -906,17 +872,13 @@ gd::String EventsCodeGenerator::GenerateEventsListCode(
auto& context = reuseParentContext ? reusedContext : newContext; auto& context = reuseParentContext ? reusedContext : newContext;
gd::String eventCoreCode = event.GenerateEventCode(*this, context); gd::String eventCoreCode = events[eId].GenerateEventCode(*this, context);
gd::String scopeBegin = GenerateScopeBegin(context); gd::String scopeBegin = GenerateScopeBegin(context);
gd::String scopeEnd = GenerateScopeEnd(context); gd::String scopeEnd = GenerateScopeEnd(context);
gd::String declarationsCode = GenerateObjectsDeclarationCode(context); gd::String declarationsCode = GenerateObjectsDeclarationCode(context);
output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" + output += "\n" + scopeBegin + "\n" + declarationsCode + "\n" +
eventCoreCode + "\n" + scopeEnd + "\n"; eventCoreCode + "\n" + scopeEnd + "\n";
if (event.HasVariables()) {
GetProjectScopedContainers().GetVariablesContainersList().Pop();
}
} }
return output; return output;
@@ -936,6 +898,41 @@ gd::String EventsCodeGenerator::ConvertToStringExplicit(
return "\"" + ConvertToString(plainString) + "\""; return "\"" + ConvertToString(plainString) + "\"";
} }
std::vector<gd::String> EventsCodeGenerator::ExpandObjectsName(
const gd::String& objectName,
const EventsCodeGenerationContext& context) const {
// Note: this logic is duplicated in EventsContextAnalyzer::ExpandObjectsName
std::vector<gd::String> realObjects;
if (globalObjectsAndGroups.GetObjectGroups().Has(objectName))
realObjects = globalObjectsAndGroups.GetObjectGroups()
.Get(objectName)
.GetAllObjectsNames();
else if (objectsAndGroups.GetObjectGroups().Has(objectName))
realObjects =
objectsAndGroups.GetObjectGroups().Get(objectName).GetAllObjectsNames();
else
realObjects.push_back(objectName);
// If current object is present, use it and only it.
if (find(realObjects.begin(),
realObjects.end(),
context.GetCurrentObject()) != realObjects.end()) {
realObjects.clear();
realObjects.push_back(context.GetCurrentObject());
}
// Ensure that all returned objects actually exists.
for (std::size_t i = 0; i < realObjects.size();) {
if (!objectsAndGroups.HasObjectNamed(realObjects[i]) &&
!globalObjectsAndGroups.HasObjectNamed(realObjects[i]))
realObjects.erase(realObjects.begin() + i);
else
++i;
}
return realObjects;
}
void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) { void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) {
for (std::size_t eId = events.size() - 1; eId < events.size(); --eId) { for (std::size_t eId = events.size() - 1; eId < events.size(); --eId) {
if (events[eId].CanHaveSubEvents()) // Process sub events, if any if (events[eId].CanHaveSubEvents()) // Process sub events, if any
@@ -952,8 +949,6 @@ void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) {
*/ */
void EventsCodeGenerator::PreprocessEventList(gd::EventsList& listEvent) { void EventsCodeGenerator::PreprocessEventList(gd::EventsList& listEvent) {
for (std::size_t i = 0; i < listEvent.GetEventsCount(); ++i) { for (std::size_t i = 0; i < listEvent.GetEventsCount(); ++i) {
if (listEvent[i].IsDisabled()) continue;
listEvent[i].Preprocess(*this, listEvent, i); listEvent[i].Preprocess(*this, listEvent, i);
if (i < if (i <
listEvent.GetEventsCount()) { // Be sure that that there is still an listEvent.GetEventsCount()) { // Be sure that that there is still an
@@ -999,15 +994,15 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
bool conditionInverted, bool conditionInverted,
gd::EventsCodeGenerationContext& context) { gd::EventsCodeGenerationContext& context) {
// Generate call // Generate call
gd::String predicate; gd::String predicat;
if (instrInfos.codeExtraInformation.type == "number" || if (instrInfos.codeExtraInformation.type == "number" ||
instrInfos.codeExtraInformation.type == "string") { instrInfos.codeExtraInformation.type == "string") {
predicate = GenerateRelationalOperatorCall( predicat = GenerateRelationalOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
instrInfos.codeExtraInformation.functionCallName); instrInfos.codeExtraInformation.functionCallName);
} else { } else {
predicate = instrInfos.codeExtraInformation.functionCallName + "(" + predicat = instrInfos.codeExtraInformation.functionCallName + "(" +
GenerateArgumentsList(arguments, 0) + ")"; GenerateArgumentsList(arguments, 0) + ")";
} }
@@ -1016,14 +1011,14 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
for (std::size_t i = 0; i < instrInfos.parameters.size(); for (std::size_t i = 0; i < instrInfos.parameters.size();
++i) // Some conditions already have a "conditionInverted" parameter ++i) // Some conditions already have a "conditionInverted" parameter
{ {
if (instrInfos.parameters[i].GetType() == "conditionInverted") if (instrInfos.parameters[i].type == "conditionInverted")
conditionAlreadyTakeCareOfInversion = true; conditionAlreadyTakeCareOfInversion = true;
} }
if (!conditionAlreadyTakeCareOfInversion && conditionInverted) if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
predicate = GenerateNegatedPredicate(predicate); predicat = GenerateNegatedPredicat(predicat);
// Generate condition code // Generate condition code
return returnBoolean + " = " + predicate + ";\n"; return returnBoolean + " = " + predicat + ";\n";
} }
gd::String EventsCodeGenerator::GenerateObjectCondition( gd::String EventsCodeGenerator::GenerateObjectCondition(
@@ -1037,7 +1032,7 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
// Prepare call // Prepare call
// Add a static_cast if necessary // Add a static_cast if necessary
gd::String objectFunctionCallNamePart = gd::String objectFunctionCallNamePart =
(!instrInfos.parameters[0].GetExtraInfo().empty()) (!instrInfos.parameters[0].supplementaryInformation.empty())
? "static_cast<" + objInfo.className + "*>(" + ? "static_cast<" + objInfo.className + "*>(" +
GetObjectListName(objectName, context) + "[i])->" + GetObjectListName(objectName, context) + "[i])->" +
instrInfos.codeExtraInformation.functionCallName instrInfos.codeExtraInformation.functionCallName
@@ -1045,18 +1040,18 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
instrInfos.codeExtraInformation.functionCallName; instrInfos.codeExtraInformation.functionCallName;
// Create call // Create call
gd::String predicate; gd::String predicat;
if ((instrInfos.codeExtraInformation.type == "number" || if ((instrInfos.codeExtraInformation.type == "number" ||
instrInfos.codeExtraInformation.type == "string")) { instrInfos.codeExtraInformation.type == "string")) {
predicate = GenerateRelationalOperatorCall( predicat = GenerateRelationalOperatorCall(
instrInfos, arguments, objectFunctionCallNamePart, 1); instrInfos, arguments, objectFunctionCallNamePart, 1);
} else { } else {
predicate = objectFunctionCallNamePart + "(" + predicat = objectFunctionCallNamePart + "(" +
GenerateArgumentsList(arguments, 1) + ")"; GenerateArgumentsList(arguments, 1) + ")";
} }
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate); if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
return "For each picked object \"" + objectName + "\", check " + predicate + return "For each picked object \"" + objectName + "\", check " + predicat +
".\n"; ".\n";
} }
@@ -1070,21 +1065,20 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
bool conditionInverted, bool conditionInverted,
gd::EventsCodeGenerationContext& context) { gd::EventsCodeGenerationContext& context) {
// Create call // Create call
gd::String predicate; gd::String predicat;
if ((instrInfos.codeExtraInformation.type == "number" || if ((instrInfos.codeExtraInformation.type == "number" ||
instrInfos.codeExtraInformation.type == "string")) { instrInfos.codeExtraInformation.type == "string")) {
predicate = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2); predicat = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2);
} else { } else {
predicate = "(" + GenerateArgumentsList(arguments, 2) + ")"; predicat = "(" + GenerateArgumentsList(arguments, 2) + ")";
} }
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate); if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
return "For each picked object \"" + objectName + "\", check " + predicate + return "For each picked object \"" + objectName + "\", check " + predicat +
" for behavior \"" + behaviorName + "\".\n"; " for behavior \"" + behaviorName + "\".\n";
} }
gd::String EventsCodeGenerator::GenerateFreeAction( gd::String EventsCodeGenerator::GenerateFreeAction(
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -1092,28 +1086,27 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
// Generate call // Generate call
gd::String call; gd::String call;
if (instrInfos.codeExtraInformation.type == "number" || if (instrInfos.codeExtraInformation.type == "number" ||
instrInfos.codeExtraInformation.type == "string" || instrInfos.codeExtraInformation.type == "string") {
instrInfos.codeExtraInformation.type == "boolean") {
if (instrInfos.codeExtraInformation.accessType == if (instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor) gd::InstructionMetadata::ExtraInformation::MutatorAndOrAccessor)
call = GenerateOperatorCall( call = GenerateOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
functionCallName, instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction); instrInfos.codeExtraInformation.optionalAssociatedInstruction);
else if (instrInfos.codeExtraInformation.accessType == else if (instrInfos.codeExtraInformation.accessType ==
gd::InstructionMetadata::ExtraInformation::Mutators) gd::InstructionMetadata::ExtraInformation::Mutators)
call = call =
GenerateMutatorCall(instrInfos, GenerateMutatorCall(instrInfos,
arguments, arguments,
functionCallName); instrInfos.codeExtraInformation.functionCallName);
else else
call = GenerateCompoundOperatorCall( call = GenerateCompoundOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
functionCallName); instrInfos.codeExtraInformation.functionCallName);
} else { } else {
call = functionCallName + "(" + call = instrInfos.codeExtraInformation.functionCallName + "(" +
GenerateArgumentsList(arguments) + ")"; GenerateArgumentsList(arguments) + ")";
} }
@@ -1127,7 +1120,6 @@ gd::String EventsCodeGenerator::GenerateFreeAction(
gd::String EventsCodeGenerator::GenerateObjectAction( gd::String EventsCodeGenerator::GenerateObjectAction(
const gd::String& objectName, const gd::String& objectName,
const gd::ObjectMetadata& objInfo, const gd::ObjectMetadata& objInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -1141,25 +1133,27 @@ gd::String EventsCodeGenerator::GenerateObjectAction(
call = GenerateOperatorCall( call = GenerateOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
functionCallName, instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction, instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2); 2);
else else
call = GenerateCompoundOperatorCall( call = GenerateCompoundOperatorCall(
instrInfos, arguments, functionCallName, 2); instrInfos,
arguments,
instrInfos.codeExtraInformation.functionCallName,
2);
return "For each picked object \"" + objectName + "\", call " + call + return "For each picked object \"" + objectName + "\", call " + call +
".\n"; ".\n";
} else { } else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 1); gd::String argumentsStr = GenerateArgumentsList(arguments, 1);
call = functionCallName + "(" + argumentsStr + ")"; call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" + return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" + argumentsStr + ")" +
(optionalAsyncCallbackName.empty() (optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n"; ".\n";
} }
} }
@@ -1168,7 +1162,6 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
const gd::String& objectName, const gd::String& objectName,
const gd::String& behaviorName, const gd::String& behaviorName,
const gd::BehaviorMetadata& autoInfo, const gd::BehaviorMetadata& autoInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -1182,28 +1175,26 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
call = GenerateOperatorCall( call = GenerateOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
functionCallName, instrInfos.codeExtraInformation.functionCallName,
instrInfos.codeExtraInformation.optionalAssociatedInstruction, instrInfos.codeExtraInformation.optionalAssociatedInstruction,
2); 2);
else else
call = GenerateCompoundOperatorCall( call = GenerateCompoundOperatorCall(
instrInfos, instrInfos,
arguments, arguments,
functionCallName, instrInfos.codeExtraInformation.functionCallName,
2); 2);
return "For each picked object \"" + objectName + "\", call " + call + return "For each picked object \"" + objectName + "\", call " + call +
" for behavior \"" + behaviorName + "\".\n"; " for behavior \"" + behaviorName + "\".\n";
} else { } else {
gd::String argumentsStr = GenerateArgumentsList(arguments, 2); gd::String argumentsStr = GenerateArgumentsList(arguments, 2);
call = functionCallName + "(" + call = instrInfos.codeExtraInformation.functionCallName + "(" +
argumentsStr + ")"; argumentsStr + ")";
return "For each picked object \"" + objectName + "\", call " + call + "(" + return "For each picked object \"" + objectName + "\", call " + call + "(" +
argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" + argumentsStr + ")" + " for behavior \"" + behaviorName + "\"" +
(optionalAsyncCallbackName.empty() (optionalAsyncCallbackName.empty() ? "" : (", then call" + optionalAsyncCallbackName)) +
? ""
: (", then call" + optionalAsyncCallbackName)) +
".\n"; ".\n";
} }
} }
@@ -1220,7 +1211,7 @@ size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
<< std::endl; << 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. // in memory will get the same id across different code generations.
size_t uniqueId = (size_t)instruction; size_t uniqueId = (size_t)instruction;
@@ -1252,24 +1243,12 @@ gd::String EventsCodeGenerator::GenerateArgumentsList(
return argumentsStr; return argumentsStr;
} }
gd::String EventsCodeGenerator::GeneratePropertyGetter(const gd::PropertiesContainer& propertiesContainer, EventsCodeGenerator::EventsCodeGenerator(gd::Project& project_,
const gd::NamedPropertyDescriptor& property,
const gd::String& type,
gd::EventsCodeGenerationContext& context) {
return "getProperty" + property.GetName() + "As" + type + "()";
}
gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context) {
return "getParameter" + parameter.GetName() + "As" + type + "()";
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
const gd::Layout& layout, const gd::Layout& layout,
const gd::Platform& platform_) const gd::Platform& platform_)
: platform(platform_), : platform(platform_),
projectScopedContainers(gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project_, layout)), globalObjectsAndGroups(project_),
objectsAndGroups(layout),
hasProjectAndLayout(true), hasProjectAndLayout(true),
project(&project_), project(&project_),
scene(&layout), scene(&layout),
@@ -1281,9 +1260,11 @@ EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
EventsCodeGenerator::EventsCodeGenerator( EventsCodeGenerator::EventsCodeGenerator(
const gd::Platform& platform_, const gd::Platform& platform_,
const gd::ProjectScopedContainers& projectScopedContainers_) gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ObjectsContainer& objectsAndGroups_)
: platform(platform_), : platform(platform_),
projectScopedContainers(projectScopedContainers_), globalObjectsAndGroups(globalObjectsAndGroups_),
objectsAndGroups(objectsAndGroups_),
hasProjectAndLayout(false), hasProjectAndLayout(false),
project(nullptr), project(nullptr),
scene(nullptr), scene(nullptr),

View File

@@ -12,7 +12,6 @@
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/Instruction.h" #include "GDCore/Events/Instruction.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/String.h" #include "GDCore/String.h"
namespace gd { namespace gd {
class EventsList; class EventsList;
@@ -20,7 +19,6 @@ class Expression;
class Project; class Project;
class Layout; class Layout;
class ObjectsContainer; class ObjectsContainer;
class ObjectsContainersList;
class ExternalEvents; class ExternalEvents;
class ParameterMetadata; class ParameterMetadata;
class ObjectMetadata; class ObjectMetadata;
@@ -50,7 +48,7 @@ class GD_CORE_API EventsCodeGenerator {
* \brief Construct a code generator for the specified * \brief Construct a code generator for the specified
* platform/project/layout. * platform/project/layout.
*/ */
EventsCodeGenerator(const gd::Project& project_, EventsCodeGenerator(gd::Project& project_,
const gd::Layout& layout, const gd::Layout& layout,
const gd::Platform& platform_); const gd::Platform& platform_);
@@ -58,9 +56,9 @@ class GD_CORE_API EventsCodeGenerator {
* \brief Construct a code generator for the specified * \brief Construct a code generator for the specified
* objects/groups and platform * objects/groups and platform
*/ */
EventsCodeGenerator( EventsCodeGenerator(const gd::Platform& platform,
const gd::Platform& platform, gd::ObjectsContainer& globalObjectsAndGroups_,
const gd::ProjectScopedContainers& projectScopedContainers_); const gd::ObjectsContainer& objectsAndGroups_);
virtual ~EventsCodeGenerator(){}; virtual ~EventsCodeGenerator(){};
/** /**
@@ -156,10 +154,9 @@ class GD_CORE_API EventsCodeGenerator {
* \param context Context used for generation * \param context Context used for generation
* \return Code * \return Code
*/ */
gd::String GenerateActionCode( gd::String GenerateActionCode(gd::Instruction& action,
gd::Instruction& action, EventsCodeGenerationContext& context,
EventsCodeGenerationContext& context, const gd::String& optionalAsyncCallbackName = "");
const gd::String& optionalAsyncCallbackName = "");
struct CallbackDescriptor { struct CallbackDescriptor {
CallbackDescriptor(const gd::String functionName_, CallbackDescriptor(const gd::String functionName_,
@@ -177,8 +174,7 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
const gd::String argumentsList; const gd::String argumentsList;
/** /**
* A set of all objects that need to be backed up to be passed to the * A set of all objects that need to be backed up to be passed to the callback code.
* callback code.
*/ */
const std::set<gd::String> requiredObjects; const std::set<gd::String> requiredObjects;
}; };
@@ -328,22 +324,18 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
bool ErrorOccurred() const { return errorOccurred; }; bool ErrorOccurred() const { return errorOccurred; };
const gd::ObjectsContainersList& GetObjectsContainersList() const { /**
return projectScopedContainers.GetObjectsContainersList(); * \brief Get the global objects/groups used for code generation.
}; */
gd::ObjectsContainer& GetGlobalObjectsAndGroups() const {
const gd::ProjectScopedContainers& GetProjectScopedContainers() const { return globalObjectsAndGroups;
return projectScopedContainers;
} }
/** /**
* @brief Give access to the project scoped containers as code generation might * \brief Get the objects/groups used for code generation.
* push and pop variable containers (for local variables).
* This could be passed as a parameter recursively in code generation, but this requires
* heavy refactoring. Instead, we use this single instance.
*/ */
gd::ProjectScopedContainers& GetProjectScopedContainers() { const gd::ObjectsContainer& GetObjectsAndGroups() const {
return projectScopedContainers; return objectsAndGroups;
} }
/** /**
@@ -356,7 +348,7 @@ class GD_CORE_API EventsCodeGenerator {
* \brief Get the project the code is being generated for. * \brief Get the project the code is being generated for.
* \warning This is only valid if HasProjectAndLayout() is true. * \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. * \brief Get the layout the code is being generated for.
@@ -369,6 +361,22 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
const gd::Platform& GetPlatform() const { return platform; } const gd::Platform& GetPlatform() const { return platform; }
/**
* \brief Convert a group name to the full list of objects contained in the
* group.
*
* Get a list containing the "real" objects name when the events refers to \a
* objectName :<br> If \a objectName is really an object, the list will only
* contains \a objectName unchanged.<br> If \a objectName is a group, the list
* will contains all the objects of the group.<br> If \a objectName is the
* "current" object in the context ( i.e: The object being used for launching
* an action... ), none of the two rules below apply, and the list will only
* contains the context "current" object name.
*/
std::vector<gd::String> ExpandObjectsName(
const gd::String& objectName,
const EventsCodeGenerationContext& context) const;
/** /**
* \brief Get the maximum depth of custom conditions reached during code * \brief Get the maximum depth of custom conditions reached during code
* generation. * generation.
@@ -394,18 +402,6 @@ class GD_CORE_API EventsCodeGenerator {
return boolName; 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. * \brief Must create a boolean. Its value must be false.
* *
@@ -458,7 +454,7 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
virtual gd::String GetCodeNamespace() { return ""; }; virtual gd::String GetCodeNamespace() { return ""; };
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE, ANY_VARIABLE }; enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
/** /**
* Generate a single unique number for the specified instruction. * Generate a single unique number for the specified instruction.
@@ -483,20 +479,7 @@ class GD_CORE_API EventsCodeGenerator {
*/ */
size_t GenerateSingleUsageUniqueIdForEventsList(); size_t GenerateSingleUsageUniqueIdForEventsList();
virtual gd::String GenerateRelationalOperation(
const gd::String& relationalOperator,
const gd::String& lhs,
const gd::String& rhs);
/**
* \brief Generate the code to access the local variables stack.
*/
virtual gd::String GenerateLocalVariablesStackAccessor();
protected: protected:
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
/** /**
* \brief Generate the code for a single parameter. * \brief Generate the code for a single parameter.
* *
@@ -505,9 +488,9 @@ class GD_CORE_API EventsCodeGenerator {
* - object : Object name -> string * - object : Object name -> string
* - expression : Mathematical expression -> number (double) * - expression : Mathematical expression -> number (double)
* - string : %Text expression -> string * - 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 * - 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 parameter -> string
* - operator : Used to update a value using a setter and a getter -> string * - operator : Used to update a value using a setter and a getter -> string
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile, * - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
@@ -524,17 +507,17 @@ class GD_CORE_API EventsCodeGenerator {
* - currentScene: Reference to the current runtime scene. * - currentScene: Reference to the current runtime scene.
* - objectList : a map containing lists of objects which are specified by the * - objectList : a map containing lists of objects which are specified by the
object name in another parameter. object name in another parameter.
* - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick * - objectListOrEmptyIfJustDeclared : Same as `objectList` but do not pick object if
object if they are not already picked. they are not already picked.
* - objectPtr: Return a reference to the object specified by the object name * - objectPtr: Return a reference to the object specified by the object name in
in another parameter. Example: another parameter. Example:
* \code * \code
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target object")) .AddParameter("objectPtr", _("Target object"))
* \endcode * \endcode
*/ */
virtual gd::String GenerateParameterCodes( virtual gd::String GenerateParameterCodes(
const gd::Expression& parameter, const gd::String& parameter,
const gd::ParameterMetadata& metadata, const gd::ParameterMetadata& metadata,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
const gd::String& lastObjectName, const gd::String& lastObjectName,
@@ -549,15 +532,11 @@ class GD_CORE_API EventsCodeGenerator {
const VariableScope& scope, const VariableScope& scope,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
const gd::String& objectName) { const gd::String& objectName) {
// This code is only used as a mock.
// See the real implementation in GDJS.
if (scope == LAYOUT_VARIABLE) { if (scope == LAYOUT_VARIABLE) {
return "getLayoutVariable(" + variableName + ")"; return "getLayoutVariable(" + variableName + ")";
} else if (scope == PROJECT_VARIABLE) { } else if (scope == PROJECT_VARIABLE) {
return "getProjectVariable(" + variableName + ")"; return "getProjectVariable(" + variableName + ")";
} else if (scope == ANY_VARIABLE) {
return "getAnyVariable(" + variableName + ")";
} }
return "getVariableForObject(" + objectName + ", " + variableName + ")"; return "getVariableForObject(" + objectName + ", " + variableName + ")";
@@ -570,12 +549,6 @@ class GD_CORE_API EventsCodeGenerator {
return ".getChild(" + ConvertToStringExplicit(childName) + ")"; return ".getChild(" + ConvertToStringExplicit(childName) + ")";
}; };
virtual gd::String GenerateVariableValueAs(const gd::String& type) {
return type == "number|string" ? ".getAsNumberOrString()"
: type == "string" ? ".getAsString()"
: ".getAsNumber()";
}
/** /**
* \brief Generate the code to get the child of a variable, * \brief Generate the code to get the child of a variable,
* using generated the expression. * using generated the expression.
@@ -604,17 +577,6 @@ class GD_CORE_API EventsCodeGenerator {
return "fakeObjectListOf_" + objectName; return "fakeObjectListOf_" + objectName;
} }
virtual gd::String GeneratePropertyGetter(
const gd::PropertiesContainer& propertiesContainer,
const gd::NamedPropertyDescriptor& property,
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String GenerateParameterGetter(
const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context);
/** /**
* \brief Generate the code to reference an object which is * \brief Generate the code to reference an object which is
* in an empty/null state. * in an empty/null state.
@@ -689,16 +651,28 @@ class GD_CORE_API EventsCodeGenerator {
}; };
/** /**
* \brief Must negate a predicate. * \brief Must negate a predicat.
* *
* The default implementation generates C-style code : It wraps the predicate * The default implementation generates C-style code : It wraps the predicat
* inside parenthesis and add a !. * inside parenthesis and add a !.
*/ */
virtual gd::String GenerateNegatedPredicate( virtual gd::String GenerateNegatedPredicat(const gd::String& predicat) const {
const gd::String& predicate) const { return "!(" + predicat + ")";
return "!(" + predicate + ")";
}; };
/**
* \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( virtual gd::String GenerateFreeCondition(
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
@@ -726,7 +700,6 @@ class GD_CORE_API EventsCodeGenerator {
gd::EventsCodeGenerationContext& context); gd::EventsCodeGenerationContext& context);
virtual gd::String GenerateFreeAction( virtual gd::String GenerateFreeAction(
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -735,7 +708,6 @@ class GD_CORE_API EventsCodeGenerator {
virtual gd::String GenerateObjectAction( virtual gd::String GenerateObjectAction(
const gd::String& objectName, const gd::String& objectName,
const gd::ObjectMetadata& objInfo, const gd::ObjectMetadata& objInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -745,7 +717,6 @@ class GD_CORE_API EventsCodeGenerator {
const gd::String& objectName, const gd::String& objectName,
const gd::String& behaviorName, const gd::String& behaviorName,
const gd::BehaviorMetadata& autoInfo, const gd::BehaviorMetadata& autoInfo,
const gd::String& functionCallName,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::InstructionMetadata& instrInfos, const gd::InstructionMetadata& instrInfos,
gd::EventsCodeGenerationContext& context, gd::EventsCodeGenerationContext& context,
@@ -756,7 +727,6 @@ class GD_CORE_API EventsCodeGenerator {
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::String& callStartString, const gd::String& callStartString,
std::size_t startFromArgument = 0); std::size_t startFromArgument = 0);
gd::String GenerateOperatorCall(const gd::InstructionMetadata& instrInfos, gd::String GenerateOperatorCall(const gd::InstructionMetadata& instrInfos,
const std::vector<gd::String>& arguments, const std::vector<gd::String>& arguments,
const gd::String& callStartString, const gd::String& callStartString,
@@ -800,14 +770,15 @@ class GD_CORE_API EventsCodeGenerator {
const gd::Platform& platform; ///< The platform being used. const gd::Platform& platform; ///< The platform being used.
gd::ProjectScopedContainers projectScopedContainers; gd::ObjectsContainer& globalObjectsAndGroups;
const gd::ObjectsContainer& objectsAndGroups;
bool hasProjectAndLayout; ///< true only if project and layout are valid bool hasProjectAndLayout; ///< true only if project and layout are valid
///< references. If false, they should not be used. ///< references. If false, they should not be used.
const gd::Project* project; ///< The project being used. gd::Project* project; ///< The project being used.
const gd::Layout* scene; ///< The scene being generated. 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 bool compilationForRuntime; ///< Is set to true if the code generation is
///< made for runtime only. ///< made for runtime only.

View File

@@ -7,7 +7,6 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <vector>
#include "GDCore/CommonTools.h" #include "GDCore/CommonTools.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h" #include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
@@ -26,42 +25,36 @@
#include "GDCore/IDE/Events/ExpressionValidator.h" #include "GDCore/IDE/Events/ExpressionValidator.h"
#include "GDCore/Project/Layout.h" #include "GDCore/Project/Layout.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Project/VariablesContainersList.h"
#include "GDCore/Project/ObjectsContainersList.h"
#include "GDCore/Project/ProjectScopedContainers.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/Events/ExpressionVariableOwnerFinder.h"
namespace gd { namespace gd {
gd::String ExpressionCodeGenerator::GenerateExpressionCode( gd::String ExpressionCodeGenerator::GenerateExpressionCode(
EventsCodeGenerator& codeGenerator, EventsCodeGenerator& codeGenerator,
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
const gd::String& rootType, const gd::String& type,
const gd::Expression& expression, const gd::String& expression,
const gd::String& rootObjectName, const gd::String& objectName) {
const gd::String& extraInfo) { gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
ExpressionCodeGenerator generator(rootType, rootObjectName, codeGenerator, context); codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
ExpressionCodeGenerator generator(codeGenerator, context);
auto node = expression.GetRootNode(); auto node = parser.ParseExpression(type, expression, objectName);
if (!node) { if (!node) {
std::cout << "Error: error while parsing: \"" << expression.GetPlainString() std::cout << "Error: error while parsing: \"" << expression << "\" ("
<< "\" (" << rootType << ")" << std::endl; << type << ")" << std::endl;
return generator.GenerateDefaultValue(rootType); return generator.GenerateDefaultValue(type);
} }
gd::ExpressionValidator validator(codeGenerator.GetPlatform(), gd::ExpressionValidator validator;
codeGenerator.GetProjectScopedContainers(),
rootType,
extraInfo);
node->Visit(validator); node->Visit(validator);
if (!validator.GetFatalErrors().empty()) { if (!validator.GetErrors().empty()) {
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage() std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
<< "\" in: \"" << expression.GetPlainString() << "\" (" << "\" in: \"" << expression << "\" (" << type << ")"
<< rootType << ")" << std::endl; << std::endl;
return generator.GenerateDefaultValue(rootType); return generator.GenerateDefaultValue(type);
} }
node->Visit(generator); node->Visit(generator);
@@ -104,87 +97,27 @@ void ExpressionCodeGenerator::OnVisitTextNode(TextNode& node) {
void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) { void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
// This "translation" from the type to an enum could be avoided // This "translation" from the type to an enum could be avoided
// if all types were moved to an enum. // if all types were moved to an enum.
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(), EventsCodeGenerator::VariableScope scope =
codeGenerator.GetProjectScopedContainers(), node.type == "globalvar"
rootType, ? gd::EventsCodeGenerator::PROJECT_VARIABLE
node); : ((node.type == "scenevar")
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE);
if (gd::ParameterMetadata::IsExpression("variable", type)) { output += codeGenerator.GenerateGetVariable(
// The node is a variable inside an expression waiting for a *variable* to be returned, not its value. node.name, scope, context, node.objectName);
EventsCodeGenerator::VariableScope scope = if (node.child) node.child->Visit(*this);
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName);
if (node.child) node.child->Visit(*this);
} else {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.name, [&](){
// Generate the code to access the object variables.
// Defer generation of the access to the object and variable to the child,
// once we know the name of the variable.
objectNameToUseForVariableAccessor = node.name;
if (node.child) node.child->Visit(*this);
objectNameToUseForVariableAccessor = "";
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "");
if (node.child) node.child->Visit(*this);
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
// Properties are not supported.
output += GenerateDefaultValue(type);
}, [&]() {
// Parameters are not supported.
output += GenerateDefaultValue(type);
}, [&]() {
// The identifier does not represents a variable (or a child variable), or not at least an existing
// one, nor an object variable. It's invalid.
output += GenerateDefaultValue(type);
});
}
} }
void ExpressionCodeGenerator::OnVisitVariableAccessorNode( void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
VariableAccessorNode& node) { VariableAccessorNode& node) {
if (!objectNameToUseForVariableAccessor.empty()) { output += codeGenerator.GenerateVariableAccessor(node.name);
// Use the name of the object passed by the parent, as we need both to access an object variable.
output += codeGenerator.GenerateGetVariable(node.name,
gd::EventsCodeGenerator::OBJECT_VARIABLE, context, objectNameToUseForVariableAccessor);
// We have accessed an object variable, from now we can continue accessing the child variables
// (including using the bracket notation).
objectNameToUseForVariableAccessor = "";
} else {
output += codeGenerator.GenerateVariableAccessor(node.name);
}
if (node.child) node.child->Visit(*this); if (node.child) node.child->Visit(*this);
} }
void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode( void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) { VariableBracketAccessorNode& node) {
if (!objectNameToUseForVariableAccessor.empty()) { ExpressionCodeGenerator generator(codeGenerator, context);
// Bracket notation can't be used to directly access a variable of an object (`MyObject["MyVariable"]`).
// This would be rejected by the ExpressionValidator.
output += codeGenerator.GenerateBadVariable();
return;
}
ExpressionCodeGenerator generator("number|string", "", codeGenerator, context);
node.expression->Visit(generator); node.expression->Visit(generator);
output += output +=
codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput()); codeGenerator.GenerateVariableBracketAccessor(generator.GetOutput());
@@ -192,100 +125,39 @@ void ExpressionCodeGenerator::OnVisitVariableBracketAccessorNode(
} }
void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) { void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(), if (gd::ParameterMetadata::IsObject(node.type)) {
codeGenerator.GetProjectScopedContainers(),
rootType,
node);
if (gd::ParameterMetadata::IsObject(type)) {
output += output +=
codeGenerator.GenerateObject(node.identifierName, type, context); codeGenerator.GenerateObject(node.identifierName, node.type, context);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
EventsCodeGenerator::VariableScope scope =
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
} else { } else {
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList(); output += "/* Error during generation, unrecognized identifier type: " +
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList(); codeGenerator.ConvertToString(node.type) + " with value " +
const auto& parametersVectorsList = codeGenerator.GetProjectScopedContainers().GetParametersVectorsList(); codeGenerator.ConvertToString(node.identifierName) + " */ " +
codeGenerator.ConvertToStringExplicit(node.identifierName);
// The node represents a variable, property, parameter or an object.
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() {
// Generate the code to access the object variable.
output += codeGenerator.GenerateGetVariable(
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, node.identifierName);
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.identifierName, gd::EventsCodeGenerator::ANY_VARIABLE, context,
"");
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
const auto& propertiesContainerAndProperty = propertiesContainersList.Get(node.identifierName);
output += codeGenerator.GeneratePropertyGetter(
propertiesContainerAndProperty.first, propertiesContainerAndProperty.second, type, context);
}, [&]() {
const auto& parameter = gd::ParameterMetadataTools::Get(parametersVectorsList, node.identifierName);
output += codeGenerator.GenerateParameterGetter(parameter, type, context);
}, [&]() {
// The identifier does not represents a variable (or a child variable), or not at least an existing
// one, nor an object variable. It's invalid.
output += GenerateDefaultValue(type);
});
} }
} }
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) { void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(), if (gd::MetadataProvider::IsBadExpressionMetadata(node.expressionMetadata)) {
codeGenerator.GetProjectScopedContainers(),
rootType,
node);
const gd::ExpressionMetadata &metadata = MetadataProvider::GetFunctionCallMetadata(
codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
node);
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
output += "/* Error during generation, function not found: " + output += "/* Error during generation, function not found: " +
codeGenerator.ConvertToString(node.functionName) + " */ " + codeGenerator.ConvertToString(node.functionName) + " */ " +
GenerateDefaultValue(type); GenerateDefaultValue(node.type);
return; return;
} }
if (!node.objectName.empty()) { if (!node.objectName.empty()) {
if (!node.behaviorName.empty()) { if (!node.behaviorName.empty()) {
output += GenerateBehaviorFunctionCode(type, output += GenerateBehaviorFunctionCode(node.type,
node.objectName, node.objectName,
node.behaviorName, node.behaviorName,
node.parameters, node.parameters,
metadata); node.expressionMetadata);
} else { } else {
output += GenerateObjectFunctionCode( output += GenerateObjectFunctionCode(
type, node.objectName, node.parameters, metadata); node.type, node.objectName, node.parameters, node.expressionMetadata);
} }
} else { } else {
output += output +=
GenerateFreeFunctionCode(node.parameters, metadata); GenerateFreeFunctionCode(node.parameters, node.expressionMetadata);
} }
} }
@@ -293,10 +165,10 @@ gd::String ExpressionCodeGenerator::GenerateFreeFunctionCode(
const std::vector<std::unique_ptr<ExpressionNode>>& parameters, const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
const ExpressionMetadata& expressionMetadata) { const ExpressionMetadata& expressionMetadata) {
codeGenerator.AddIncludeFiles( codeGenerator.AddIncludeFiles(
expressionMetadata.GetIncludeFiles()); expressionMetadata.codeExtraInformation.GetIncludeFiles());
// Launch custom code generator if needed // Launch custom code generator if needed
if (expressionMetadata.HasCustomCodeGenerator()) { if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
return expressionMetadata.codeExtraInformation.customCodeGenerator( return expressionMetadata.codeExtraInformation.customCodeGenerator(
PrintParameters(parameters), codeGenerator, context); PrintParameters(parameters), codeGenerator, context);
} }
@@ -313,11 +185,16 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
const gd::String& objectName, const gd::String& objectName,
const std::vector<std::unique_ptr<ExpressionNode>>& parameters, const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
const ExpressionMetadata& expressionMetadata) { const ExpressionMetadata& expressionMetadata) {
const gd::ObjectsContainer& globalObjectsAndGroups =
codeGenerator.GetGlobalObjectsAndGroups();
const gd::ObjectsContainer& objectsAndGroups =
codeGenerator.GetObjectsAndGroups();
codeGenerator.AddIncludeFiles( codeGenerator.AddIncludeFiles(
expressionMetadata.GetIncludeFiles()); expressionMetadata.codeExtraInformation.GetIncludeFiles());
// Launch custom code generator if needed // Launch custom code generator if needed
if (expressionMetadata.HasCustomCodeGenerator()) { if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
return expressionMetadata.codeExtraInformation.customCodeGenerator( return expressionMetadata.codeExtraInformation.customCodeGenerator(
PrintParameters(parameters), codeGenerator, context); PrintParameters(parameters), codeGenerator, context);
} }
@@ -333,14 +210,20 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
// Get object(s) concerned by function call // Get object(s) concerned by function call
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); codeGenerator.ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) { for (std::size_t i = 0; i < realObjects.size(); ++i) {
context.ObjectsListNeeded(realObjects[i]); context.ObjectsListNeeded(realObjects[i]);
gd::String objectType = codeGenerator.GetObjectsContainersList().GetTypeOfObject(realObjects[i]); gd::String objectType = gd::GetTypeOfObject(
globalObjectsAndGroups, objectsAndGroups, realObjects[i]);
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata( const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
codeGenerator.GetPlatform(), objectType); 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); codeGenerator.AddIncludeFiles(objInfo.includeFiles);
functionOutput = codeGenerator.GenerateObjectFunctionCall( functionOutput = codeGenerator.GenerateObjectFunctionCall(
realObjects[i], realObjects[i],
@@ -349,6 +232,7 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
parametersCode, parametersCode,
functionOutput, functionOutput,
context); context);
}
} }
return functionOutput; return functionOutput;
@@ -359,11 +243,16 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
const gd::String& behaviorName, const gd::String& behaviorName,
const std::vector<std::unique_ptr<ExpressionNode>>& parameters, const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
const ExpressionMetadata& expressionMetadata) { const ExpressionMetadata& expressionMetadata) {
const gd::ObjectsContainer& globalObjectsAndGroups =
codeGenerator.GetGlobalObjectsAndGroups();
const gd::ObjectsContainer& objectsAndGroups =
codeGenerator.GetObjectsAndGroups();
codeGenerator.AddIncludeFiles( codeGenerator.AddIncludeFiles(
expressionMetadata.GetIncludeFiles()); expressionMetadata.codeExtraInformation.GetIncludeFiles());
// Launch custom code generator if needed // Launch custom code generator if needed
if (expressionMetadata.HasCustomCodeGenerator()) { if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
return expressionMetadata.codeExtraInformation.customCodeGenerator( return expressionMetadata.codeExtraInformation.customCodeGenerator(
PrintParameters(parameters), codeGenerator, context); PrintParameters(parameters), codeGenerator, context);
} }
@@ -377,11 +266,12 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
// Get object(s) concerned by function call // Get object(s) concerned by function call
std::vector<gd::String> realObjects = std::vector<gd::String> realObjects =
codeGenerator.GetObjectsContainersList().ExpandObjectName(objectName, context.GetCurrentObject()); codeGenerator.ExpandObjectsName(objectName, context);
gd::String functionOutput = GenerateDefaultValue(type); gd::String functionOutput = GenerateDefaultValue(type);
gd::String behaviorType = codeGenerator.GetObjectsContainersList().GetTypeOfBehavior(behaviorName); gd::String behaviorType = gd::GetTypeOfBehavior(
globalObjectsAndGroups, objectsAndGroups, behaviorName);
const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata( const BehaviorMetadata& autoInfo = MetadataProvider::GetBehaviorMetadata(
codeGenerator.GetPlatform(), behaviorType); codeGenerator.GetPlatform(), behaviorType);
@@ -415,20 +305,18 @@ gd::String ExpressionCodeGenerator::GenerateParametersCodes(
auto& parameterMetadata = expressionMetadata.parameters[i]; auto& parameterMetadata = expressionMetadata.parameters[i];
if (!parameterMetadata.IsCodeOnly()) { if (!parameterMetadata.IsCodeOnly()) {
ExpressionCodeGenerator generator(codeGenerator, context);
if (nonCodeOnlyParameterIndex < parameters.size()) { if (nonCodeOnlyParameterIndex < parameters.size()) {
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
*parameters[nonCodeOnlyParameterIndex].get());
ExpressionCodeGenerator generator(parameterMetadata.GetType(), objectName, codeGenerator, context);
parameters[nonCodeOnlyParameterIndex]->Visit(generator); parameters[nonCodeOnlyParameterIndex]->Visit(generator);
parametersCode += generator.GetOutput(); parametersCode += generator.GetOutput();
} else if (parameterMetadata.IsOptional()) { } else if (parameterMetadata.IsOptional()) {
ExpressionCodeGenerator generator(parameterMetadata.GetType(), "", codeGenerator, context);
// Optional parameters default value were not parsed at the time of the // Optional parameters default value were not parsed at the time of the
// expression parsing. Parse them now. // expression parsing. Parse them now.
ExpressionParser2 parser; ExpressionParser2 parser(codeGenerator.GetPlatform(),
auto node = parser.ParseExpression(parameterMetadata.GetDefaultValue()); codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
auto node = parser.ParseExpression(parameterMetadata.GetType(),
parameterMetadata.GetDefaultValue());
node->Visit(generator); node->Visit(generator);
parametersCode += generator.GetOutput(); parametersCode += generator.GetOutput();
@@ -486,20 +374,12 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
} }
void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) { void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(), output += GenerateDefaultValue(node.type);
codeGenerator.GetProjectScopedContainers(),
rootType,
node);
output += GenerateDefaultValue(type);
} }
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode( void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode& node) { ObjectFunctionNameNode& node) {
auto type = gd::ExpressionTypeFinder::GetType(codeGenerator.GetPlatform(), output += GenerateDefaultValue(node.type);
codeGenerator.GetProjectScopedContainers(),
rootType,
node);
output += GenerateDefaultValue(type);
} }
} // namespace gd } // namespace gd

View File

@@ -9,6 +9,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Events/Parsers/ExpressionParser2Node.h" #include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h" #include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/String.h" #include "GDCore/String.h"
@@ -34,11 +35,9 @@ namespace gd {
*/ */
class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker { class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
public: public:
ExpressionCodeGenerator(const gd::String &rootType_, ExpressionCodeGenerator(EventsCodeGenerator& codeGenerator_,
const gd::String &rootObjectName_,
EventsCodeGenerator& codeGenerator_,
EventsCodeGenerationContext& context_) EventsCodeGenerationContext& context_)
: rootType(rootType_), rootObjectName(rootObjectName_), codeGenerator(codeGenerator_), context(context_){}; : codeGenerator(codeGenerator_), context(context_){};
virtual ~ExpressionCodeGenerator(){}; virtual ~ExpressionCodeGenerator(){};
/** /**
@@ -58,9 +57,8 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
static gd::String GenerateExpressionCode(EventsCodeGenerator& codeGenerator, static gd::String GenerateExpressionCode(EventsCodeGenerator& codeGenerator,
EventsCodeGenerationContext& context, EventsCodeGenerationContext& context,
const gd::String& type, const gd::String& type,
const gd::Expression& expression, const gd::String& expression,
const gd::String& objectName = "", const gd::String& objectName = "");
const gd::String& extraInfo = "");
const gd::String& GetOutput() { return output; }; const gd::String& GetOutput() { return output; };
@@ -103,11 +101,8 @@ class GD_CORE_API ExpressionCodeGenerator : public ExpressionParser2NodeWorker {
const std::vector<std::unique_ptr<ExpressionNode>>& parameters); const std::vector<std::unique_ptr<ExpressionNode>>& parameters);
gd::String output; gd::String output;
gd::String objectNameToUseForVariableAccessor;
EventsCodeGenerator& codeGenerator; EventsCodeGenerator& codeGenerator;
EventsCodeGenerationContext& context; EventsCodeGenerationContext& context;
const gd::String rootType;
const gd::String rootObjectName;
}; };
} // namespace gd } // namespace gd

View File

@@ -9,7 +9,6 @@
#include "GDCore/Events/Builtin/AsyncEvent.h" #include "GDCore/Events/Builtin/AsyncEvent.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h" #include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
#include "GDCore/Events/EventVisitor.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h" #include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h" #include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Extensions/PlatformExtension.h"
@@ -17,7 +16,6 @@
namespace gd { namespace gd {
EventsList BaseEvent::badSubEvents; EventsList BaseEvent::badSubEvents;
VariablesContainer BaseEvent::badLocalVariables;
std::vector<gd::String> BaseEvent::emptyDependencies; std::vector<gd::String> BaseEvent::emptyDependencies;
gd::String BaseEvent::emptySourceFile; gd::String BaseEvent::emptySourceFile;
@@ -29,8 +27,6 @@ BaseEvent::BaseEvent()
bool BaseEvent::HasSubEvents() const { return !GetSubEvents().IsEmpty(); } bool BaseEvent::HasSubEvents() const { return !GetSubEvents().IsEmpty(); }
bool BaseEvent::HasVariables() const { return GetVariables().Count() > 0; }
gd::String BaseEvent::GenerateEventCode( gd::String BaseEvent::GenerateEventCode(
gd::EventsCodeGenerator& codeGenerator, gd::EventsCodeGenerator& codeGenerator,
gd::EventsCodeGenerationContext& context) { gd::EventsCodeGenerationContext& context) {
@@ -79,8 +75,7 @@ void BaseEvent::PreprocessAsyncActions(const gd::Platform& platform) {
const auto& action = actionsList->at(aId); const auto& action = actionsList->at(aId);
const gd::InstructionMetadata& actionMetadata = const gd::InstructionMetadata& actionMetadata =
gd::MetadataProvider::GetActionMetadata(platform, action.GetType()); gd::MetadataProvider::GetActionMetadata(platform, action.GetType());
if (actionMetadata.IsAsync() && if (actionMetadata.IsAsync()) {
(!actionMetadata.IsOptionallyAsync() || action.IsAwaited())) {
gd::InstructionsList remainingActions; gd::InstructionsList remainingActions;
remainingActions.InsertInstructions( remainingActions.InsertInstructions(
*actionsList, aId + 1, actionsList->size() - 1); *actionsList, aId + 1, actionsList->size() - 1);
@@ -144,14 +139,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) { BaseEventSPtr GD_CORE_API CloneRememberingOriginalEvent(BaseEventSPtr event) {
gd::BaseEventSPtr copy(event->Clone()); gd::BaseEventSPtr copy(event->Clone());
// Original event is either the original event of the copied event, or the // Original event is either the original event of the copied event, or the

View File

@@ -3,7 +3,9 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #if defined(GD_IDE_ONLY)
#ifndef GDCORE_EVENT_H
#define GDCORE_EVENT_H
#include <iostream> #include <iostream>
#include <memory> #include <memory>
@@ -22,9 +24,6 @@ class EventsCodeGenerationContext;
class Platform; class Platform;
class SerializerElement; class SerializerElement;
class Instruction; class Instruction;
class EventVisitor;
class ReadOnlyEventVisitor;
class VariablesContainer;
} // namespace gd } // namespace gd
namespace gd { namespace gd {
@@ -91,32 +90,6 @@ class GD_CORE_API BaseEvent {
*/ */
bool HasSubEvents() const; bool HasSubEvents() const;
/**
* Derived class have to redefine this function, so as to return true, if they
* can have local variables.
*/
virtual bool CanHaveVariables() const { return false; }
/**
* Return the local variables, if applicable.
*/
virtual const gd::VariablesContainer& GetVariables() const {
return badLocalVariables;
};
/**
* Return the local variables, if applicable.
*/
virtual gd::VariablesContainer& GetVariables() {
return badLocalVariables;
};
/**
* \brief Return true if the events has local variables.
* \warning This is only applicable when CanHaveVariables() return true.
*/
bool HasVariables() const;
/** /**
* \brief Return a list of all conditions of the event. * \brief Return a list of all conditions of the event.
* \note Used to preprocess or search in the conditions. * \note Used to preprocess or search in the conditions.
@@ -265,9 +238,6 @@ class GD_CORE_API BaseEvent {
*/ */
virtual void UnserializeFrom(gd::Project& project, virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element){}; const SerializerElement& element){};
virtual bool AcceptVisitor(gd::EventVisitor& eventVisitor);
virtual void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const;
///@} ///@}
/** \name Common properties /** \name Common properties
@@ -306,6 +276,7 @@ class GD_CORE_API BaseEvent {
* \brief True if the event should be folded in the events editor. * \brief True if the event should be folded in the events editor.
*/ */
bool IsFolded() const { return folded; } bool IsFolded() const { return folded; }
///@} ///@}
std::weak_ptr<gd::BaseEvent> std::weak_ptr<gd::BaseEvent>
@@ -326,7 +297,6 @@ class GD_CORE_API BaseEvent {
///< Used for saving the event for instance. ///< Used for saving the event for instance.
static gd::EventsList badSubEvents; static gd::EventsList badSubEvents;
static gd::VariablesContainer badLocalVariables;
static std::vector<gd::String> emptyDependencies; static std::vector<gd::String> emptyDependencies;
static gd::String emptySourceFile; static gd::String emptySourceFile;
}; };
@@ -351,3 +321,6 @@ class EmptyEvent : public BaseEvent {
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_EVENT_H
#endif

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 "EventsList.h"
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Tools/Log.h" #include "GDCore/Tools/Log.h"
@@ -101,8 +100,9 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
} }
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove, bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
gd::EventsList& newEventsList, gd::EventsList& newEventsList,
std::size_t newPosition) { std::size_t newPosition) {
for (std::size_t i = 0; i < GetEventsCount(); ++i) { for (std::size_t i = 0; i < GetEventsCount(); ++i) {
if (events[i].get() == &eventToMove) { if (events[i].get() == &eventToMove) {
std::shared_ptr<BaseEvent> event = events[i]; 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 #ifndef GDCORE_EXPRESSION_H
#define GDCORE_EXPRESSION_H #define GDCORE_EXPRESSION_H
#include "GDCore/String.h" #include "GDCore/String.h"
#include <memory>
namespace gd {
class ExpressionParser2;
class ObjectsContainer;
struct ExpressionNode;
} // namespace gd
namespace gd { namespace gd {
@@ -32,49 +24,32 @@ class GD_CORE_API Expression {
/** /**
* \brief Construct an empty expression * \brief Construct an empty expression
*/ */
Expression(); Expression(){};
/** /**
* \brief Construct an expression from a string * \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 * * \brief Construct an expression from a const char *
*/ */
Expression(const char* plainString_); Expression(const char* plainString_) : plainString(plainString_){};
/**
* \brief Copy construct an expression.
*/
Expression(const Expression& copy);
/**
* \brief Expression affectation overriding.
*/
Expression& operator=(const Expression& expression);
/** /**
* \brief Get the plain string representing the expression * \brief Get the plain string representing the expression
*/ */
inline const gd::String& GetPlainString() const { return plainString; }; 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 * \brief Mimics std::string::c_str
*/ */
inline const char* c_str() const { return plainString.c_str(); }; inline const char* c_str() const { return plainString.c_str(); };
virtual ~Expression(); virtual ~Expression(){};
private: private:
gd::String plainString; ///< The expression string gd::String plainString; ///< The expression string
mutable std::unique_ptr<gd::ExpressionNode> node;
}; };
} // namespace gd } // namespace gd

View File

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

View File

@@ -72,22 +72,6 @@ class GD_CORE_API Instruction {
*/ */
void SetInverted(bool inverted_) { inverted = inverted_; } 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. * \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); 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. /** \brief Get a reference to the std::vector containing the parameters.
* \return A 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 * Useful to get reference to the original instruction in memory during code
* generation, to ensure stable unique identifiers. * generation, to ensure stable unique identifiers.
*/ */
std::weak_ptr<Instruction> GetOriginalInstruction() { std::weak_ptr<Instruction> GetOriginalInstruction() { return originalInstruction; };
return originalInstruction;
};
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement( friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
std::shared_ptr<Instruction> instruction); std::shared_ptr<Instruction> instruction);
@@ -171,9 +148,6 @@ class GD_CORE_API Instruction {
gd::String type; ///< Instruction type gd::String type; ///< Instruction type
bool inverted; ///< True if the instruction if inverted. Only applicable for bool inverted; ///< True if the instruction if inverted. Only applicable for
///< instruction used as conditions by events ///< 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> mutable std::vector<gd::Expression>
parameters; ///< Vector containing the parameters parameters; ///< Vector containing the parameters
gd::InstructionsList subInstructions; ///< Sub instructions, if applicable. gd::InstructionsList subInstructions; ///< Sub instructions, if applicable.

View File

@@ -19,25 +19,139 @@
#include "GDCore/Project/Project.h" #include "GDCore/Project/Project.h"
#include "GDCore/Tools/Localization.h" #include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/MakeUnique.h" #include "GDCore/Tools/MakeUnique.h"
#include "GrammarTerminals.h"
using namespace std; using namespace std;
using namespace gd::GrammarTerminals;
namespace gd { namespace gd {
gd::String ExpressionParser2::NAMESPACE_SEPARATOR = "::"; gd::String ExpressionParser2::NAMESPACE_SEPARATOR = "::";
ExpressionParser2::ExpressionParser2() ExpressionParser2::ExpressionParser2(
const gd::Platform& platform_,
const gd::ObjectsContainer& globalObjectsContainer_,
const gd::ObjectsContainer& objectsContainer_)
: expression(""), : 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() { std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
size_t textStartPosition = GetCurrentPosition(); size_t textStartPosition = GetCurrentPosition();
SkipAllWhitespaces(); SkipAllWhitespaces();
if (!CheckIfChar(IsQuote)) { if (!CheckIfChar(IsQuote)) {
auto text = gd::make_unique<TextNode>(""); auto text = gd::make_unique<TextNode>("");
// It can't happen.
text->diagnostic = text->diagnostic =
RaiseSyntaxError(_("A text must start with a double quote (\").")); RaiseSyntaxError(_("A text must start with a double quote (\")."));
text->location = text->location =

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,6 @@ class ObjectsContainer;
class Platform; class Platform;
class ParameterMetadata; class ParameterMetadata;
class ExpressionMetadata; class ExpressionMetadata;
struct FunctionCallNode;
} // namespace gd } // namespace gd
namespace gd { namespace gd {
@@ -58,10 +57,6 @@ struct GD_CORE_API ExpressionParserDiagnostic {
* \brief An error that can be attached to a gd::ExpressionNode. * \brief An error that can be attached to a gd::ExpressionNode.
*/ */
struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic { 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_){};
ExpressionParserError(const gd::String &type_, ExpressionParserError(const gd::String &type_,
const gd::String &message_, const gd::String &message_,
size_t position_) size_t position_)
@@ -91,7 +86,7 @@ struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
* an expression inherits from. * an expression inherits from.
*/ */
struct GD_CORE_API ExpressionNode { struct GD_CORE_API ExpressionNode {
ExpressionNode() : parent(nullptr) {}; ExpressionNode(const gd::String &type_) : type(type_){};
virtual ~ExpressionNode(){}; virtual ~ExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker){}; virtual void Visit(ExpressionParser2NodeWorker &worker){};
@@ -102,12 +97,17 @@ struct GD_CORE_API ExpressionNode {
/// function can store the position of the /// function can store the position of the
/// object name, the dot, the function /// object name, the dot, the function
/// name, etc... /// 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 { struct GD_CORE_API SubExpressionNode : public ExpressionNode {
SubExpressionNode(std::unique_ptr<ExpressionNode> expression_) SubExpressionNode(const gd::String &type_,
: ExpressionNode(), expression(std::move(expression_)){}; std::unique_ptr<ExpressionNode> expression_)
: ExpressionNode(type_), expression(std::move(expression_)){};
virtual ~SubExpressionNode(){}; virtual ~SubExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitSubExpressionNode(*this); worker.OnVisitSubExpressionNode(*this);
@@ -120,8 +120,8 @@ struct GD_CORE_API SubExpressionNode : public ExpressionNode {
* \brief An operator node. For example: "lhs + rhs". * \brief An operator node. For example: "lhs + rhs".
*/ */
struct GD_CORE_API OperatorNode : public ExpressionNode { struct GD_CORE_API OperatorNode : public ExpressionNode {
OperatorNode(gd::String::value_type op_) OperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(), op(op_){}; : ExpressionNode(type_), op(op_){};
virtual ~OperatorNode(){}; virtual ~OperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitOperatorNode(*this); worker.OnVisitOperatorNode(*this);
@@ -136,8 +136,8 @@ struct GD_CORE_API OperatorNode : public ExpressionNode {
* \brief A unary operator node. For example: "-2". * \brief A unary operator node. For example: "-2".
*/ */
struct GD_CORE_API UnaryOperatorNode : public ExpressionNode { struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
UnaryOperatorNode(gd::String::value_type op_) UnaryOperatorNode(const gd::String &type_, gd::String::value_type op_)
: ExpressionNode(), op(op_){}; : ExpressionNode(type_), op(op_){};
virtual ~UnaryOperatorNode(){}; virtual ~UnaryOperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitUnaryOperatorNode(*this); worker.OnVisitUnaryOperatorNode(*this);
@@ -153,7 +153,7 @@ struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
*/ */
struct GD_CORE_API NumberNode : public ExpressionNode { struct GD_CORE_API NumberNode : public ExpressionNode {
NumberNode(const gd::String &number_) NumberNode(const gd::String &number_)
: ExpressionNode(), number(number_){}; : ExpressionNode("number"), number(number_){};
virtual ~NumberNode(){}; virtual ~NumberNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitNumberNode(*this); worker.OnVisitNumberNode(*this);
@@ -168,7 +168,7 @@ struct GD_CORE_API NumberNode : public ExpressionNode {
* Its `type` is always "string". * Its `type` is always "string".
*/ */
struct GD_CORE_API TextNode : public ExpressionNode { struct GD_CORE_API TextNode : public ExpressionNode {
TextNode(const gd::String &text_) : ExpressionNode(), text(text_){}; TextNode(const gd::String &text_) : ExpressionNode("string"), text(text_){};
virtual ~TextNode(){}; virtual ~TextNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitTextNode(*this); worker.OnVisitTextNode(*this);
@@ -177,89 +177,32 @@ struct GD_CORE_API TextNode : public ExpressionNode {
gd::String text; 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 { struct GD_CORE_API VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(){}; VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(""){};
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child; std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child;
}; };
/** /**
* \brief A variable, or object variable, with bracket accessor or at least 2 "dot" accessors. * \brief A variable, potentially with accessor to its children.
* *
* Example: `MyVariable["MyChildren"]` or `MyVariable.MyChildren.MyGrandChildren`. * Example: MyVariable or MyVariable.MyChildren
* Example: `MyObject["MyVariable"]` or `MyObject.MyVariable.MyChildren`.
* *
* Other cases like "MyVariable" or "MyVariable.MyChildren" are IdentifierNode
* to allow handling ambiguities.
*
* \see gd::IdentifierNode
* \see gd::VariableAccessorNode * \see gd::VariableAccessorNode
* \see gd::VariableBracketAccessorNode * \see gd::VariableBracketAccessorNode
*/ */
struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmptyNode { struct GD_CORE_API VariableNode : public ExpressionNode {
VariableNode(const gd::String &name_) VariableNode(const gd::String &type_,
: FunctionCallOrObjectFunctionNameOrEmptyNode(), name(name_){}; const gd::String &name_,
const gd::String &objectName_)
: ExpressionNode(type_), name(name_), objectName(objectName_){};
virtual ~VariableNode(){}; virtual ~VariableNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableNode(*this); worker.OnVisitVariableNode(*this);
}; };
gd::String name; gd::String name;
gd::String objectName;
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode>
child; // Can be nullptr if no accessor child; // Can be nullptr if no accessor
@@ -268,13 +211,12 @@ struct GD_CORE_API VariableNode : public FunctionCallOrObjectFunctionNameOrEmpty
}; };
/** /**
* \brief A direct accessor to a child variable. Example: MyChild * \brief A bracket accessor of a variable. Example: MyChild
* in MyVariable.MyChild * in MyVariable.MyChild
*/ */
struct GD_CORE_API VariableAccessorNode struct GD_CORE_API VariableAccessorNode
: public VariableAccessorOrVariableBracketAccessorNode { : public VariableAccessorOrVariableBracketAccessorNode {
VariableAccessorNode(const gd::String &name_) VariableAccessorNode(const gd::String &name_) : name(name_){};
: VariableAccessorOrVariableBracketAccessorNode(), name(name_){};
virtual ~VariableAccessorNode(){}; virtual ~VariableAccessorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableAccessorNode(*this); worker.OnVisitVariableAccessorNode(*this);
@@ -286,13 +228,13 @@ struct GD_CORE_API VariableAccessorNode
}; };
/** /**
* \brief A bracket accessor to a child variable. Example: ["MyChild"] * \brief A bracket accessor of a variable. Example: ["MyChild"]
* (in MyVariable["MyChild"]). * (in MyVariable["MyChild"]).
*/ */
struct GD_CORE_API VariableBracketAccessorNode struct GD_CORE_API VariableBracketAccessorNode
: public VariableAccessorOrVariableBracketAccessorNode { : public VariableAccessorOrVariableBracketAccessorNode {
VariableBracketAccessorNode(std::unique_ptr<ExpressionNode> expression_) VariableBracketAccessorNode(std::unique_ptr<ExpressionNode> expression_)
: VariableAccessorOrVariableBracketAccessorNode(), expression(std::move(expression_)){}; : expression(std::move(expression_)){};
virtual ~VariableBracketAccessorNode(){}; virtual ~VariableBracketAccessorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableBracketAccessorNode(*this); worker.OnVisitVariableBracketAccessorNode(*this);
@@ -301,26 +243,55 @@ struct GD_CORE_API VariableBracketAccessorNode
std::unique_ptr<ExpressionNode> expression; std::unique_ptr<ExpressionNode> expression;
}; };
struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(
const gd::String &type)
: ExpressionNode(type){};
};
/**
* \brief An identifier node, usually representing an object or a function name.
*/
struct GD_CORE_API 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 GD_CORE_API 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 * \brief The name of a function to call on an object or the behavior
* For example: "MyObject.Physics::LinearVelocity". * For example: "MyObject.Function" or "MyObject.Physics" or
* * "MyObject.Physics::LinearVelocity".
* Other cases like "MyObject.Function" or "MyObject.Physics" are IdentifierNode
* to allow handling ambiguities.
*
* \see gd::IdentifierNode
*/ */
struct GD_CORE_API ObjectFunctionNameNode struct GD_CORE_API ObjectFunctionNameNode
: public FunctionCallOrObjectFunctionNameOrEmptyNode { : public FunctionCallOrObjectFunctionNameOrEmptyNode {
ObjectFunctionNameNode(const gd::String &objectName_, ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &objectFunctionOrBehaviorName_) const gd::String &objectFunctionOrBehaviorName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(), : FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_), objectName(objectName_),
objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {} objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {}
ObjectFunctionNameNode(const gd::String &objectName_, ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_, const gd::String &behaviorName_,
const gd::String &behaviorFunctionName_) const gd::String &behaviorFunctionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(), : FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_), objectName(objectName_),
objectFunctionOrBehaviorName(behaviorName_), objectFunctionOrBehaviorName(behaviorName_),
behaviorFunctionName(behaviorFunctionName_) {} behaviorFunctionName(behaviorFunctionName_) {}
@@ -363,24 +334,39 @@ struct GD_CORE_API ObjectFunctionNameNode
*/ */
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode { struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
/** \brief Construct a free function call node. */ /** \brief Construct a free function call node. */
FunctionCallNode(const gd::String &functionName_) FunctionCallNode(const gd::String &type_,
: FunctionCallOrObjectFunctionNameOrEmptyNode(), std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){}; functionName(functionName_){};
/** \brief Construct an object function call node. */ /** \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_) const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(), : FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_), objectName(objectName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){}; functionName(functionName_){};
/** \brief Construct a behavior function call node. */ /** \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_, const gd::String &behaviorName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_) const gd::String &functionName_)
: FunctionCallOrObjectFunctionNameOrEmptyNode(), : FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_), objectName(objectName_),
behaviorName(behaviorName_), behaviorName(behaviorName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){}; functionName(functionName_){};
virtual ~FunctionCallNode(){}; virtual ~FunctionCallNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
@@ -390,6 +376,7 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
gd::String objectName; gd::String objectName;
gd::String behaviorName; gd::String behaviorName;
std::vector<std::unique_ptr<ExpressionNode>> parameters; std::vector<std::unique_ptr<ExpressionNode>> parameters;
const ExpressionMetadata &expressionMetadata;
gd::String functionName; gd::String functionName;
ExpressionParserLocation ExpressionParserLocation
@@ -414,8 +401,8 @@ struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrE
* encountered and any other node could not make sense. * encountered and any other node could not make sense.
*/ */
struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode { struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
EmptyNode(const gd::String &text_ = "") EmptyNode(const gd::String &type_, const gd::String &text_ = "")
: FunctionCallOrObjectFunctionNameOrEmptyNode(), text(text_){}; : FunctionCallOrObjectFunctionNameOrEmptyNode(type_), text(text_){};
virtual ~EmptyNode(){}; virtual ~EmptyNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) { virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitEmptyNode(*this); worker.OnVisitEmptyNode(*this);

View File

@@ -8,7 +8,6 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2Node.h" #include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h" #include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
namespace gd { namespace gd {
@@ -44,11 +43,6 @@ class GD_CORE_API ExpressionParser2NodePrinter
*/ */
const gd::String& GetOutput() { return output; }; const gd::String& GetOutput() { return output; };
static gd::String PrintStringLiteral(const gd::String& str) {
return "\"" +
str.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") + "\"";
}
protected: protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override { void OnVisitSubExpressionNode(SubExpressionNode& node) override {
output += "("; output += "(";
@@ -75,7 +69,10 @@ class GD_CORE_API ExpressionParser2NodePrinter
} }
void OnVisitNumberNode(NumberNode& node) override { output += node.number; } void OnVisitNumberNode(NumberNode& node) override { output += node.number; }
void OnVisitTextNode(TextNode& node) override { void OnVisitTextNode(TextNode& node) override {
output += PrintStringLiteral(node.text); output +=
"\"" +
node.text.FindAndReplace("\\", "\\\\").FindAndReplace("\"", "\\\"") +
"\"";
} }
void OnVisitVariableNode(VariableNode& node) override { void OnVisitVariableNode(VariableNode& node) override {
output += node.name; output += node.name;
@@ -94,14 +91,11 @@ class GD_CORE_API ExpressionParser2NodePrinter
} }
void OnVisitIdentifierNode(IdentifierNode& node) override { void OnVisitIdentifierNode(IdentifierNode& node) override {
output += node.identifierName; output += node.identifierName;
if (!node.childIdentifierName.empty()) {
output += "." + node.childIdentifierName;
}
} }
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override { void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
if (!node.behaviorFunctionName.empty()) { if (!node.behaviorFunctionName.empty()) {
output += node.objectName + "." + node.objectFunctionOrBehaviorName + output +=
"::" + node.behaviorFunctionName; node.objectName + "." + node.objectFunctionOrBehaviorName + "::" + node.behaviorFunctionName;
} else { } else {
output += node.objectName + "." + node.objectFunctionOrBehaviorName; output += node.objectName + "." + node.objectFunctionOrBehaviorName;
} }

View File

@@ -1,118 +0,0 @@
#pragma once
#include "GDCore/String.h"
namespace gd {
/**
* Contains functions to handle the grammar of the expressions accepted by GDevelop.
*/
namespace GrammarTerminals {
inline bool IsWhitespace(gd::String::value_type character) {
return character == ' ' || character == '\n' || character == '\r';
}
inline bool IsParameterSeparator(gd::String::value_type character) {
return character == ',';
}
inline bool IsDot(gd::String::value_type character) { return character == '.'; }
inline bool IsQuote(gd::String::value_type character) {
return character == '"';
}
inline bool IsBracket(gd::String::value_type character) {
return character == '(' || character == ')' || character == '[' ||
character == ']' || character == '{' || character == '}';
}
inline bool IsOpeningParenthesis(gd::String::value_type character) {
return character == '(';
}
inline bool IsClosingParenthesis(gd::String::value_type character) {
return character == ')';
}
inline bool IsOpeningSquareBracket(gd::String::value_type character) {
return character == '[';
}
inline bool IsClosingSquareBracket(gd::String::value_type character) {
return character == ']';
}
inline bool IsExpressionEndingChar(gd::String::value_type character) {
return character == ',' || IsClosingParenthesis(character) ||
IsClosingSquareBracket(character);
}
inline bool IsExpressionOperator(gd::String::value_type character) {
return character == '+' || character == '-' || character == '<' ||
character == '>' || character == '?' || character == '^' ||
character == '=' || character == '\\' || character == ':' ||
character == '!';
}
inline bool IsUnaryOperator(gd::String::value_type character) {
return character == '+' || character == '-';
}
inline bool IsTermOperator(gd::String::value_type character) {
return character == '/' || character == '*';
}
inline bool IsNumberFirstChar(gd::String::value_type character) {
return character == '.' || (character >= '0' && character <= '9');
}
inline bool IsNonZeroDigit(gd::String::value_type character) {
return (character >= '1' && character <= '9');
}
inline bool IsZeroDigit(gd::String::value_type character) {
return character == '0';
}
inline bool IsAdditionalReservedCharacter(gd::String::value_type character) {
// These characters are not part of the grammar - but are often used in programming language
// and could become operators or part of the grammar one day.
return character == '~' || character == '\'' || character == '%' ||
character == '#' || character == '@' || character == '|' ||
character == '&' || character == '`' || character == '$' ||
character == ';';
}
/**
* Check if the given character can be used in an identifier. This is
* any unicode character, except for:
* `, . " () [] {} + - < > ? ^ = \ : ! / * ~ ' % # @ | & $ ;`
* and backtick and whitespaces (space, line break, carriage return).
*
* This is loosely based on what is allowed in languages like JavaScript
* (see https://mathiasbynens.be/notes/javascript-properties), without support
* for unicode escape syntax, and allowing all unicode ranges. The only
* disallowed characters are the one used for the grammar.
*/
inline bool IsAllowedInIdentifier(gd::String::value_type character) {
// Quickly compare if the character is a number or ASCII character.
if ((character >= '0' && character <= '9') ||
(character >= 'A' && character <= 'Z') ||
(character >= 'a' && character <= 'z'))
return true;
// Otherwise do the full check against separators forbidden in identifiers.
if (!IsParameterSeparator(character) && !IsDot(character) &&
!IsQuote(character) && !IsBracket(character) &&
!IsExpressionOperator(character) && !IsTermOperator(character) &&
!IsWhitespace(character) && !IsAdditionalReservedCharacter(character)) {
return true;
}
return false;
}
} // namespace GrammarTerminals
} // namespace gd

View File

@@ -4,7 +4,6 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#include "GDCore/Events/Serialization.h" #include "GDCore/Events/Serialization.h"
#include "GDCore/CommonTools.h" #include "GDCore/CommonTools.h"
#include "GDCore/Events/Event.h" #include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h" #include "GDCore/Events/EventsList.h"
@@ -184,8 +183,8 @@ void EventsListSerialization::UpdateInstructionsFromGD2x(
for (std::size_t j = 0; for (std::size_t j = 0;
j < parameters.size() && j < metadata.parameters.size(); j < parameters.size() && j < metadata.parameters.size();
++j) { ++j) {
if (metadata.parameters[j].GetType() == "relationalOperator" || if (metadata.parameters[j].type == "relationalOperator" ||
metadata.parameters[j].GetType() == "operator") { metadata.parameters[j].type == "operator") {
if (j == parameters.size() - 1) { if (j == parameters.size() - 1) {
std::cout << "ERROR: No more parameters after a [relational]operator " std::cout << "ERROR: No more parameters after a [relational]operator "
"when trying to update an instruction from GD2.x"; "when trying to update an instruction from GD2.x";
@@ -233,8 +232,7 @@ void EventsListSerialization::SerializeEventsTo(const EventsList& list,
const gd::BaseEvent& event = list.GetEvent(j); const gd::BaseEvent& event = list.GetEvent(j);
SerializerElement& eventElem = events.AddChild("event"); SerializerElement& eventElem = events.AddChild("event");
if (event.IsDisabled()) if (event.IsDisabled()) eventElem.SetAttribute("disabled", event.IsDisabled());
eventElem.SetAttribute("disabled", event.IsDisabled());
if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded()); if (event.IsFolded()) eventElem.SetAttribute("folded", event.IsFolded());
eventElem.AddChild("type").SetValue(event.GetType()); eventElem.AddChild("type").SetValue(event.GetType());
@@ -269,9 +267,6 @@ void gd::EventsListSerialization::UnserializeInstructionsFrom(
instrElement.GetChild("type", 0, "Type") instrElement.GetChild("type", 0, "Type")
.GetBoolAttribute("inverted", false, "Contraire")); .GetBoolAttribute("inverted", false, "Contraire"));
instruction.SetAwaited(
instrElement.GetChild("type", 0, "Type").GetBoolAttribute("await"));
// Read parameters // Read parameters
vector<gd::Expression> parameters; vector<gd::Expression> parameters;
@@ -345,12 +340,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
instructions.ConsiderAsArrayOf("instruction"); instructions.ConsiderAsArrayOf("instruction");
for (std::size_t k = 0; k < list.size(); k++) { for (std::size_t k = 0; k < list.size(); k++) {
SerializerElement& instruction = instructions.AddChild("instruction"); SerializerElement& instruction = instructions.AddChild("instruction");
instruction.AddChild("type").SetAttribute("value", list[k].GetType()); instruction.AddChild("type")
.SetAttribute("value", list[k].GetType())
if (list[k].IsInverted()) .SetAttribute("inverted", list[k].IsInverted());
instruction.GetChild("type").SetAttribute("inverted", true);
if (list[k].IsAwaited())
instruction.GetChild("type").SetAttribute("await", true);
// Parameters // Parameters
SerializerElement& parameters = instruction.AddChild("parameters"); SerializerElement& parameters = instruction.AddChild("parameters");
@@ -360,10 +352,9 @@ void gd::EventsListSerialization::SerializeInstructionsTo(
.SetValue(list[k].GetParameter(l).GetPlainString()); .SetValue(list[k].GetParameter(l).GetPlainString());
// Sub instructions // Sub instructions
if (!list[k].GetSubInstructions().empty()) { SerializerElement& subInstructions =
SerializeInstructionsTo(list[k].GetSubInstructions(), instruction.AddChild("subInstructions");
instruction.AddChild("subInstructions")); SerializeInstructionsTo(list[k].GetSubInstructions(), subInstructions);
}
} }
} }

View File

@@ -17,7 +17,7 @@ const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
return it->second; return it->second;
} }
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(originalObjectName); gd::String partiallyMangledName = originalObjectName;
static const gd::String allowedCharacters = static const gd::String allowedCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
@@ -43,15 +43,7 @@ const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
return it->second; return it->second;
} }
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(externalEventsName); gd::String partiallyMangledName = externalEventsName;
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
return mangledExternalEventsNames[externalEventsName];
}
gd::String EventsCodeNameMangler::GetMangledNameWithForbiddenUnderscore(
const gd::String &name) {
gd::String partiallyMangledName = name;
static const gd::String allowedCharacters = static const gd::String allowedCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
@@ -65,30 +57,11 @@ gd::String EventsCodeNameMangler::GetMangledNameWithForbiddenUnderscore(
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar)); partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
} }
} }
return partiallyMangledName;
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
return mangledExternalEventsNames[externalEventsName];
} }
gd::String EventsCodeNameMangler::GetMangledName(
const gd::String &name) {
gd::String partiallyMangledName = name;
static const gd::String allowedCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
for (size_t i = 0; i < partiallyMangledName.size();
++i) // Replace all unallowed letter by an underscore and the ascii
// number of the letter
{
if (allowedCharacters.find_first_of(
std::u32string(1, partiallyMangledName[i])) == gd::String::npos) {
char32_t unallowedChar = partiallyMangledName[i];
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
}
}
return partiallyMangledName;
}
const gd::String& ManObjListName(const gd::String &objectName) { const gd::String& ManObjListName(const gd::String &objectName) {
return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName); return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName);
} }

View File

@@ -36,8 +36,6 @@ class GD_CORE_API EventsCodeNameMangler {
const gd::String &GetExternalEventsFunctionMangledName( const gd::String &GetExternalEventsFunctionMangledName(
const gd::String &externalEventsName); const gd::String &externalEventsName);
static gd::String GetMangledName(const gd::String &name);
static EventsCodeNameMangler *Get(); static EventsCodeNameMangler *Get();
static void DestroySingleton(); static void DestroySingleton();
@@ -46,9 +44,6 @@ class GD_CORE_API EventsCodeNameMangler {
virtual ~EventsCodeNameMangler(){}; virtual ~EventsCodeNameMangler(){};
static EventsCodeNameMangler *_singleton; static EventsCodeNameMangler *_singleton;
// This method is inlined to avoid to copy the returned string.
static inline gd::String GetMangledNameWithForbiddenUnderscore(const gd::String &name);
std::unordered_map<gd::String, gd::String> std::unordered_map<gd::String, gd::String>
mangledObjectNames; ///< Memoized results of mangling for objects mangledObjectNames; ///< Memoized results of mangling for objects
std::unordered_map<gd::String, gd::String> std::unordered_map<gd::String, gd::String>

View File

@@ -33,8 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png", "res/function32.png",
"res/function32.png") "res/function32.png")
.SetHelpPath("/events/functions/return") .SetHelpPath("/events/functions/return")
.AddParameter("expression", _("The number to be returned")) .AddParameter("expression", "The number to be returned")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -48,8 +47,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png", "res/function32.png",
"res/function32.png") "res/function32.png")
.SetHelpPath("/events/functions/return") .SetHelpPath("/events/functions/return")
.AddParameter("string", _("The text to be returned")) .AddParameter("string", "The text to be returned")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -62,38 +60,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png", "res/function32.png",
"res/function32.png") "res/function32.png")
.SetHelpPath("/events/functions/return") .SetHelpPath("/events/functions/return")
.AddParameter("trueorfalse", _("Should the condition be true or false?")) .AddParameter("trueorfalse", "Should the condition be true or false?")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
extension
.AddAction("CopyArgumentToVariable",
_("Copy function parameter to variable"),
_("Copy a function parameter (also called \"argument\") to a variable. "
"The parameter type must be a variable."),
_("Copy the parameter _PARAM0_ into the variable _PARAM1_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable"))
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
extension
.AddAction("CopyVariableToArgument",
_("Copy variable to function parameter"),
_("Copy a variable to function parameter (also called \"argument\"). "
"The parameter type must be a variable."),
_("Copy the variable _PARAM1_ into the parameter _PARAM0_"),
"",
"res/function32.png",
"res/function32.png")
.SetHelpPath("/events/functions/return")
.AddParameter("functionParameterName", _("Parameter name"), "variable")
.AddParameter("scenevar", _("Scene variable"))
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -107,59 +74,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"", "",
"res/function32.png", "res/function32.png",
"res/function32.png") "res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", "Parameter name")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddExpression( .AddExpression(
"GetArgumentAsNumber", "GetArgumentAsNumber",
_("Get function parameter value"), _("Get function parameter value"),
_("Get function parameter (also called \"argument\") value. You don't need this most of the time as you can simply write the parameter name in an expression."), _("Get function parameter (also called \"argument\") value"),
"", "",
"res/function16.png") "res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", "Parameter name");
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension extension
.AddStrExpression( .AddStrExpression(
"GetArgumentAsString", "GetArgumentAsString",
_("Get function parameter text"), _("Get function parameter text"),
_("Get function parameter (also called \"argument\") text. You don't need this most of the time as you can simply write the parameter name in an expression."), _("Get function parameter (also called \"argument\") text "),
"", "",
"res/function16.png") "res/function16.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean") .AddParameter("functionParameterName", "Parameter name");
.SetRelevantForFunctionEventsOnly()
.SetHidden();
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();
} }
} // namespace gd } // namespace gd

View File

@@ -43,13 +43,6 @@ class GD_CORE_API BuiltinExtensionsImplementer {
static void ImplementsVariablesExtension(gd::PlatformExtension& extension); static void ImplementsVariablesExtension(gd::PlatformExtension& extension);
static void ImplementsWindowExtension(gd::PlatformExtension& extension); static void ImplementsWindowExtension(gd::PlatformExtension& extension);
static void ImplementsAsyncExtension(gd::PlatformExtension& extension); static void ImplementsAsyncExtension(gd::PlatformExtension& extension);
static void ImplementsResizableExtension(gd::PlatformExtension& extension);
static void ImplementsScalableExtension(gd::PlatformExtension& extension);
static void ImplementsFlippableExtension(gd::PlatformExtension& extension);
static void ImplementsAnimatableExtension(gd::PlatformExtension& extension);
static void ImplementsEffectExtension(gd::PlatformExtension& extension);
static void ImplementsOpacityExtension(gd::PlatformExtension& extension);
static void ImplementsTextContainerExtension(gd::PlatformExtension& extension);
}; };
} // namespace gd } // namespace gd

View File

@@ -15,13 +15,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAsyncExtension(
extension extension
.SetExtensionInformation( .SetExtensionInformation(
"BuiltinAsync", "BuiltinAsync",
_("Asynchronous functions"), _("Async functions"),
_("Functions that defer the execution of the events after it."), _("Functions that defer the execution of the events after it."),
"Arthur Pacaud (arthuro555)", "Arthur Pacaud (arthuro555)",
"Open source (MIT License)") "Open source (MIT License)")
.SetCategory("Advanced"); .SetCategory("Advanced");
extension.AddInstructionOrExpressionGroupMetadata(_("Asynchronous functions"))
.SetIcon("res/function32.png");
extension.AddEvent("Async", extension.AddEvent("Async",
_("Async event"), _("Async event"),
@@ -29,19 +27,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAsyncExtension(
"", "",
"res/eventaddicon.png", "res/eventaddicon.png",
std::make_shared<gd::AsyncEvent>()); 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 } // namespace gd

View File

@@ -14,17 +14,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension extension
.SetExtensionInformation( .SetExtensionInformation(
"BuiltinAudio", "BuiltinAudio",
_("Sounds and music"), _("Sounds and musics"),
_("GDevelop provides several conditions and actions to play 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", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("/all-features/audio") .SetExtensionHelpPath("/all-features/audio")
.SetCategory("Audio"); .SetCategory("Audio");
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and music")) extension.AddInstructionOrExpressionGroupMetadata(_("Sounds and musics"))
.SetIcon("res/actions/music24.png"); .SetIcon("res/actions/music24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Sounds on channels"))
.SetIcon("res/actions/son24.png");
extension extension
.AddAction("PlaySoundCanal", .AddAction("PlaySoundCanal",
@@ -75,9 +73,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension extension
.AddAction("RePlaySoundCanal", .AddAction("RePlaySoundCanal",
_("Resume playing a sound on a channel"), _("Play the sound of a channel"),
_("Resume playing a sound on a channel that was paused."), _("Play the sound of the channel."),
_("Resume the sound of channel _PARAM1_"), _("Play the sound of channel _PARAM1_"),
_("Sounds on channels"), _("Sounds on channels"),
"res/actions/son24.png", "res/actions/son24.png",
"res/actions/son.png") "res/actions/son.png")
@@ -134,9 +132,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
extension extension
.AddAction("RePlayMusicCanal", .AddAction("RePlayMusicCanal",
_("Resume playing a music on a channel"), _("Play the music of a channel"),
_("Resume playing a music on a channel that was paused."), _("Play the music of the channel."),
_("Resume the music of channel _PARAM1_"), _("Play the music of channel _PARAM1_"),
_("Music on channels"), _("Music on channels"),
"res/actions/music24.png", "res/actions/music24.png",
"res/actions/music.png") "res/actions/music.png")
@@ -148,83 +146,69 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.AddAction("ModVolumeSoundCanal", .AddAction("ModVolumeSoundCanal",
_("Volume of the sound on a channel"), _("Volume of the sound on a channel"),
_("This action modifies the volume of the sound on the " _("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_"), _("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"), _("Sounds on channels"),
"res/actions/sonVolume24.png", "res/actions/sonVolume24.png",
"res/actions/sonVolume.png") "res/actions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("ModVolumeMusicCanal", .AddAction("ModVolumeMusicCanal",
_("Volume of the music on a channel"), _("Volume of the music on a channel"),
_("This action modifies the volume of the music on the " _("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_"), _("the volume of the music on channel _PARAM1_"),
_("Music on channels"), _("Music on channels"),
"res/actions/musicVolume24.png", "res/actions/musicVolume24.png",
"res/actions/musicVolume.png") "res/actions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("ModGlobalVolume", .AddAction("ModGlobalVolume",
_("Game global volume"), _("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"), _("the global sound level"),
"", "",
"res/actions/volume24.png", "res/actions/volume24.png",
"res/actions/volume.png") "res/actions/volume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume (0-100)")))
.MarkAsSimple(); .MarkAsSimple();
extension extension
.AddAction("ModPitchSoundChannel", .AddAction("ModPitchSoundChannel",
_("Pitch of the sound of a channel"), _("Pitch of the sound of a channel"),
_("This action modifies the pitch (speed) of the sound on a " _("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_"), _("the pitch of the sound on channel _PARAM1_"),
_("Sounds on channels"), _("Sounds on channels"),
"res/actions/son24.png", "res/actions/son24.png",
"res/actions/son.png") "res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("ModPitchMusicChannel", .AddAction("ModPitchMusicChannel",
_("Pitch of the music on a channel"), _("Pitch of the music on a channel"),
_("This action modifies the pitch of the music on the " _("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_"), _("the pitch of the music on channel _PARAM1_"),
_("Music on channels"), _("Music on channels"),
"res/actions/music24.png", "res/actions/music24.png",
"res/actions/music.png") "res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -238,10 +222,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/actions/son.png") "res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position (in seconds)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -255,10 +236,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/actions/music.png") "res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position (in seconds)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -470,17 +448,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.AddCondition( .AddCondition(
"SoundCanalVolume", "SoundCanalVolume",
_("Volume of the sound on a channel"), _("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_"), _("the volume of the sound on channel _PARAM1_"),
_("Sounds on channels"), _("Sounds on channels"),
"res/conditions/sonVolume24.png", "res/conditions/sonVolume24.png",
"res/conditions/sonVolume.png") "res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -495,10 +471,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/conditions/musicVolume.png") "res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -511,10 +484,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/conditions/volume24.png", "res/conditions/volume24.png",
"res/conditions/volume.png") "res/conditions/volume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number");
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Volume to compare to (0-100)")));
extension extension
.AddCondition( .AddCondition(
@@ -528,27 +498,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/conditions/sonVolume.png") "res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch to compare to (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddCondition( .AddCondition(
"MusicChannelPitch", "MusicChannelPitch",
_("Pitch of the music on a channel"), _("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_"), _("the pitch of the music on channel _PARAM1_"),
_("Music on channels"), _("Music on channels"),
"res/conditions/musicVolume24.png", "res/conditions/musicVolume24.png",
"res/conditions/musicVolume.png") "res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Pitch to compare to (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -562,10 +527,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/conditions/sonVolume.png") "res/conditions/sonVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position to compare to (in seconds)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -579,10 +541,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
"res/conditions/musicVolume.png") "res/conditions/musicVolume.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Channel identifier")) .AddParameter("expression", _("Channel identifier"))
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Position to compare to (in seconds)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension

File diff suppressed because it is too large Load Diff

View File

@@ -22,76 +22,53 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"object or a position.", "object or a position.",
"Florian Rival", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetCategory("Camera")
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras"); .SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras")) extension.AddInstructionOrExpressionGroupMetadata(_("Layers and cameras"))
.SetIcon("res/conditions/camera24.png"); .SetIcon("res/conditions/camera24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
extension extension
.AddExpressionAndConditionAndAction( .AddExpressionAndConditionAndAction(
"number", "number",
"CameraCenterX", "CameraX",
_("Camera center X position"), _("Camera center X position"),
_("the X position of the center of a camera"), _("the X position of the center of a camera"),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"), _("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
"", "",
"res/conditions/camera24.png") "res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.MarkAsAdvanced(); .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") extension.AddDuplicatedAction("CameraX", "SetCameraX")
.SetHidden(); // Deprecated .SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueX", "CameraX") extension.AddDuplicatedExpression("VueX", "CameraX")
.SetHidden(); // Deprecated .SetHidden(); // Deprecated
// end of compatibility code
extension extension
.AddExpressionAndConditionAndAction( .AddExpressionAndConditionAndAction(
"number", "number",
"CameraCenterY", "CameraY",
_("Camera center Y position"), _("Camera center Y position"),
_("the Y position of the center of a camera"), _("the Y position of the center of a camera"),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"), _("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
"", "",
"res/conditions/camera24.png") "res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.MarkAsAdvanced(); .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") extension.AddDuplicatedAction("CameraY", "SetCameraY")
.SetHidden(); // Deprecated .SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueY", "CameraY") extension.AddDuplicatedExpression("VueY", "CameraY")
.SetHidden(); // Deprecated .SetHidden(); // Deprecated
// end of compatibility code
extension extension
.AddExpressionAndCondition( .AddExpressionAndCondition(
@@ -103,10 +80,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"", "",
"res/conditions/camera24.png") "res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true) .AddParameter("expression", _("Camera number"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -119,78 +96,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"", "",
"res/conditions/camera24.png") "res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true) .AddParameter("expression", _("Camera number"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderLeft",
_("Camera left border position"),
_("the position of the left border of a camera"),
_("the position of the left border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderRight",
_("Camera right border position"),
_("the position of the right border of a camera"),
_("the position of the right border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderTop",
_("Camera top border position"),
_("the position of the top border of a camera"),
_("the position of the top border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddExpressionAndCondition(
"number",
"CameraBorderBottom",
_("Camera bottom border position"),
_("the position of the bottom border of a camera"),
_("the position of the bottom border of camera _PARAM2_ of layer "
"_PARAM1_"),
"",
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"), "", true)
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -198,13 +107,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"number", "number",
"CameraAngle", "CameraAngle",
_("Angle of a camera of a layer"), _("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_)"), _("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
"", "",
"res/conditions/camera24.png") "res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
@@ -224,7 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Width"), "", true) .AddParameter("expression", _("Width"), "", true)
.AddParameter("expression", _("Height"), "", true) .AddParameter("expression", _("Height"), "", true)
@@ -259,7 +168,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number")) .AddParameter("expression", _("Camera number"))
.MarkAsComplex(); .MarkAsComplex();
@@ -275,7 +184,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number")) .AddParameter("expression", _("Camera number"))
.AddParameter("expression", _("Width")) .AddParameter("expression", _("Width"))
@@ -293,7 +202,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number")) .AddParameter("expression", _("Camera number"))
.AddParameter( .AddParameter(
@@ -312,7 +221,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension extension
.AddAction("ZoomCamera", .AddAction("ZoomCamera",
_("Camera zoom"), _("Change camera zoom"),
_("Change camera zoom."), _("Change camera zoom."),
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: " _("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
"_PARAM3_)"), "_PARAM3_)"),
@@ -322,11 +231,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", .AddParameter("expression",
_("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)")) _("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)"))
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
// TODO Deprecated: hide this action in a future release.
extension extension
.AddAction( .AddAction(
"FixCamera", "FixCamera",
@@ -338,7 +248,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"", "",
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("objectPtr", _("Object")) .AddParameter("objectPtr", _("Object"))
.AddParameter("expression", .AddParameter("expression",
@@ -354,41 +263,46 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"", "",
true) true)
.SetDefaultValue("yes") .SetDefaultValue("yes")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("ClampCamera", .AddAction(
_("Enforce camera boundaries"), "ClampCamera",
_("Enforce camera boundaries by moving the camera back inside " _("Enforce camera boundaries"),
"specified boundaries."), _("Enforce camera boundaries by moving the camera back inside specified boundaries."),
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ " _("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"), "right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
"", "",
"res/actions/camera24.png", "res/actions/camera24.png",
"res/actions/camera.png") "res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Left bound X Position")) .AddParameter("expression",
.AddParameter("expression", _("Top bound Y Position")) _("Left bound X Position"))
.AddParameter("expression", _("Right bound X Position")) .AddParameter("expression",
.AddParameter("expression", _("Bottom bound Y Position")) _("Top bound Y Position"))
.AddParameter("layer", _("Layer"), "", true) .AddParameter("expression",
_("Right bound X Position"))
.AddParameter("expression",
_("Bottom bound Y Position"))
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("CentreCamera", .AddAction(
_("Center the camera on an object"), "CentreCamera",
_("Center the camera on the specified object."), _("Center the camera on an object"),
_("Center camera on _PARAM1_ (layer: _PARAM3_)"), _("Center the camera on the specified object."),
_("Layers and cameras"), _("Center camera on _PARAM1_ (layer: _PARAM3_)"),
"res/actions/camera24.png", "",
"res/actions/camera.png") "res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("objectPtr", _("Object")) .AddParameter("objectPtr", _("Object"))
.AddParameter("yesorno", .AddParameter("yesorno",
@@ -396,7 +310,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"", "",
true) true)
.SetDefaultValue("yes") .SetDefaultValue("yes")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
@@ -411,7 +325,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/layer24.png", "res/actions/layer24.png",
"res/actions/layer.png") "res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -424,7 +338,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/layer24.png", "res/actions/layer24.png",
"res/actions/layer.png") "res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -437,65 +351,65 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/conditions/layer24.png", "res/conditions/layer24.png",
"res/conditions/layer.png") "res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer")) .AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction( .AddAction(
"SetLayerEffectParameter", "SetLayerEffectParameter",
_("Effect property (number)"), _("Effect parameter (number)"),
_("Change the value of a property of an effect.") + "\n" + _("Change the value of a parameter of an effect.") + "\n" +
_("You can find the property names (and change the effect " _("You can find the parameter names (and change the effect "
"names) in the effects window."), "names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"), _("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"), _("Effects"),
"res/actions/effect_black.svg", "res/conditions/camera24.png",
"res/actions/effect_black.svg") "res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name")) .AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Property name")) .AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("expression", _("New value")) .AddParameter("expression", _("New value"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction( .AddAction(
"SetLayerEffectStringParameter", "SetLayerEffectStringParameter",
_("Effect property (string)"), _("Effect parameter (string)"),
_("Change the value (string) of a property of an effect.") + "\n" + _("Change the value (string) of a parameter of an effect.") + "\n" +
_("You can find the property names (and change the effect " _("You can find the parameter names (and change the effect "
"names) in the effects window."), "names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"), _("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of layer _PARAM1_"),
_("Effects"), _("Effects"),
"res/actions/effect_black.svg", "res/conditions/camera24.png",
"res/actions/effect_black.svg") "res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name")) .AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Property name")) .AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("string", _("New value")) .AddParameter("string", _("New value"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction( .AddAction(
"SetLayerEffectBooleanParameter", "SetLayerEffectBooleanParameter",
_("Effect property (enable or disable)"), _("Effect parameter (enable or disable)"),
_("Enable or disable a property of an effect.") + "\n" + _("Enable or disable a parameter of an effect.") + "\n" +
_("You can find the property names (and change the effect " _("You can find the parameter names (and change the effect "
"names) in the effects window."), "names) in the effects window."),
_("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"), _("Enable _PARAM3_ for effect _PARAM2_ of layer _PARAM1_: _PARAM4_"),
_("Effects"), _("Effects"),
"res/actions/effect_black.svg", "res/conditions/camera24.png",
"res/actions/effect_black.svg") "res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name")) .AddParameter("layerEffectName", _("Effect name"))
.AddParameter("layerEffectParameterName", _("Property name")) .AddParameter("layerEffectParameterName", _("Parameter name"))
.AddParameter("yesorno", _("Enable this property")) .AddParameter("yesorno", _("Enable this parameter"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -503,11 +417,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Layer effect is enabled"), _("Layer effect is enabled"),
_("The effect on a layer is enabled"), _("The effect on a layer is enabled"),
_("Effect _PARAM2_ on layer _PARAM1_ is enabled"), _("Effect _PARAM2_ on layer _PARAM1_ is enabled"),
_(""), _("Effects"),
"res/actions/effect_black.svg", "res/conditions/camera24.png",
"res/actions/effect_black.svg") "res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name")) .AddParameter("layerEffectName", _("Effect name"))
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -518,10 +432,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Enable an effect on a layer"), _("Enable an effect on a layer"),
_("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"), _("Enable effect _PARAM2_ on layer _PARAM1_: _PARAM3_"),
_("Effects"), _("Effects"),
"res/actions/effect_black.svg", "res/conditions/camera24.png",
"res/actions/effect_black.svg") "res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("layerEffectName", _("Effect name")) .AddParameter("layerEffectName", _("Effect name"))
.AddParameter("yesorno", _("Enable"), "", true) .AddParameter("yesorno", _("Enable"), "", true)
@@ -537,25 +451,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/conditions/time24.png", "res/conditions/time24.png",
"res/conditions/time.png") "res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Time scale (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction( .AddAction(
"ChangeLayerTimeScale", "ChangeLayerTimeScale",
_("Layer time scale"), _("Change layer time scale"),
_("Change the time scale applied to the objects of the layer."), _("Change the time scale applied to the objects of the layer."),
_("Set the time scale of layer _PARAM1_ to _PARAM2_"), _("Set the time scale of layer _PARAM1_ to _PARAM2_"),
"", "",
"res/actions/time24.png", "res/actions/time24.png",
"res/actions/time.png") "res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", .AddParameter("expression",
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)")); _("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
@@ -570,15 +481,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/conditions/layer24.png", "res/conditions/layer24.png",
"res/conditions/layer.png") "res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", gd::ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("SetLayerDefaultZOrder", .AddAction("SetLayerDefaultZOrder",
_("Layer default Z order"), _("Change layer default Z order"),
_("Change the default Z order set to objects when they are " _("Change the default Z order set to objects when they are "
"created on a layer."), "created on a layer."),
_("Set the default Z order of objects created on _PARAM1_ to " _("Set the default Z order of objects created on _PARAM1_ to "
@@ -587,22 +497,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/layer24.png", "res/actions/layer24.png",
"res/actions/layer.png") "res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("New default Z order")); .AddParameter("expression", _("New default Z order"));
extension extension
.AddAction( .AddAction(
"SetLayerAmbientLightColor", "SetLayerAmbientLightColor",
_("Ambient light color"), _("Set the ambient light color"),
_("Set the ambient light color of the lighting layer in format " _("Set the ambient light color of the lighting layer in format "
"\"R;G;B\" string."), "\"R;G;B\" string."),
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"), _("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
_(""), _("Lighting"),
"res/actions/color24.png", "res/actions/color24.png",
"res/actions/color.png") "res/actions/color.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"Lighting\"") .SetDefaultValue("\"Lighting\"")
.AddParameter("color", _("Color")) .AddParameter("color", _("Color"))
.MarkAsAdvanced(); .MarkAsAdvanced();

View File

@@ -1,165 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("AnimatableCapability",
_("Animatable capability"),
_("Animate objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
.SetIcon("res/actions/animation24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
.SetIcon("res/actions/animation24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"AnimatableBehavior",
_("Animatable capability"),
"Animation",
_("Animate objects."),
"",
"res/actions/animation24.png",
"AnimatableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"number",
"Index",
_("Animation (by number)"),
_("the animation played by the object using the animation number (from "
"the animations list)"),
_("the number of the animation"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation index")))
.MarkAsSimple();
aut.GetAllExpressions()["Index"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"string",
"Name",
_("Animation (by name)"),
_("the animation played by the object using the name of the "
"animation"),
_("the animation"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation name")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Name"].SetGroup("");
aut.AddScopedAction("PauseAnimation",
_("Pause the animation"),
_("Pause the animation of the object."),
_("Pause the animation of _PARAM0_"),
_("Animations and images"),
"res/actions/animation24.png",
"res/actions/animation.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddScopedAction("PlayAnimation",
_("Resume the animation"),
_("Resume the animation of the object."),
_("Resume the animation of _PARAM0_"),
_("Animations and images"),
"res/actions/animation24.png",
"res/actions/animation.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddExpressionAndConditionAndAction(
"number",
"SpeedScale",
_("Animation speed scale"),
_("the animation speed scale (1 = the default speed, >1 = faster and "
"<1 = slower)"),
_("the animation speed scale"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Speed scale")))
.MarkAsSimple();
aut.GetAllExpressions()["SpeedScale"].SetGroup("");
aut.AddScopedCondition("IsAnimationPaused",
_("Animation paused"),
_("Check if the animation of an object is paused."),
_("The animation of _PARAM0_ is paused"),
_("Animations and images"),
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddScopedCondition("HasAnimationEnded",
_("Animation finished"),
_("Check if the animation being played by the Sprite object "
"is finished."),
_("The animation of _PARAM0_ is finished"),
_("Animations and images"),
"res/conditions/animation24.png",
"res/conditions/animation.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddExpressionAndConditionAndAction(
"number",
"ElapsedTime",
_("Animation elapsed time"),
_("the elapsed time from the beginning of the animation (in seconds)"),
_("the animation elapsed time"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Elapsed time (in seconds)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["ElapsedTime"].SetGroup("");
aut.AddExpression(
"Duration",
_("Animation duration"),
_("Return the current animation duration (in seconds)."),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior");
}
} // namespace gd

View File

@@ -1,116 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("EffectCapability",
_("Effect capability"),
_("Apply visual effects to objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"EffectBehavior",
_("Effect capability"),
"Effect",
_("Apply visual effects to objects."),
"",
"res/actions/effect_black.svg",
"EffectBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddScopedAction("EnableEffect",
_("Enable an object effect"),
_("Enable an effect on the object"),
_("Enable effect _PARAM2_ on _PARAM0_: _PARAM3_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("yesorno", _("Enable?"))
.MarkAsSimple();
aut.AddScopedAction("SetEffectDoubleParameter",
_("Effect property (number)"),
_("Change the value of a property of an effect.") + "\n" +
_("You can find the property names (and change the effect "
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
.AddParameter("expression", _("New value"))
.MarkAsSimple();
aut.AddScopedAction("SetEffectStringParameter",
_("Effect property (string)"),
_("Change the value (string) of a property of an effect.") +
"\n" +
_("You can find the property names (and change the effect "
"names) in the effects window."),
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
.AddParameter("string", _("New value"))
.MarkAsSimple();
aut.AddScopedAction("SetEffectBooleanParameter",
_("Effect property (enable or disable)"),
_("Enable or disable a property of an effect.") + "\n" +
_("You can find the property names (and change the effect "
"names) in the effects window."),
_("Enable _PARAM3_ for effect _PARAM2_ of _PARAM0_: _PARAM4_"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
.AddParameter("objectEffectParameterName", _("Property name"))
.AddParameter("yesorno", _("Enable this property"))
.MarkAsSimple();
aut.AddScopedCondition("IsEffectEnabled",
_("Effect is enabled"),
_("Check if the effect on an object is enabled."),
_("Effect _PARAM2_ of _PARAM0_ is enabled"),
_("Effects"),
"res/actions/effect_black.svg",
"res/actions/effect_black.svg")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
.AddParameter("objectEffectName", _("Effect name"))
.MarkAsSimple();
}
} // namespace gd

View File

@@ -1,86 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("FlippableCapability",
_("Flippable capability"),
_("Flip objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
.SetIcon("res/actions/effect_black.svg");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"FlippableBehavior",
_("Flippable capability"),
"Flippable",
_("Flip objects."),
"",
"res/actions/flipX24.png",
"FlippableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddScopedAction("FlipX",
_("Flip the object horizontally"),
_("Flip the object horizontally"),
_("Flip horizontally _PARAM0_: _PARAM2_"),
_("Effects"),
"res/actions/flipX24.png",
"res/actions/flipX.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
.AddParameter("yesorno", _("Activate flipping"))
.MarkAsSimple();
aut.AddScopedAction("FlipY",
_("Flip the object vertically"),
_("Flip the object vertically"),
_("Flip vertically _PARAM0_: _PARAM2_"),
_("Effects"),
"res/actions/flipY24.png",
"res/actions/flipY.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
.AddParameter("yesorno", _("Activate flipping"))
.MarkAsSimple();
aut.AddScopedCondition("FlippedX",
_("Horizontally flipped"),
_("Check if the object is horizontally flipped"),
_("_PARAM0_ is horizontally flipped"),
_("Effects"),
"res/actions/flipX24.png",
"res/actions/flipX.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
aut.AddScopedCondition("FlippedY",
_("Vertically flipped"),
_("Check if the object is vertically flipped"),
_("_PARAM0_ is vertically flipped"),
_("Effects"),
"res/actions/flipY24.png",
"res/actions/flipY.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
}
} // namespace gd

View File

@@ -1,62 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("OpacityCapability",
_("Opacity capability"),
_("Change the object opacity."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
.SetIcon("res/actions/opacity24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
.SetIcon("res/actions/opacity24.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"OpacityBehavior",
_("Opacity capability"),
"Opacity",
_("Change the object opacity."),
"",
"res/actions/opacity24.png",
"OpacityBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"number",
"Value",
_("Opacity"),
_("the opacity of an object, between 0 (fully transparent) to 255 "
"(opaque)"),
_("the opacity"),
_("Visibility"),
"res/actions/opacity24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "OpacityBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity (0-255)")))
.SetFunctionName("setOpacity")
.SetGetter("getOpacity");
aut.GetAllExpressions()["Value"].SetGroup("");
}
} // namespace gd

View File

@@ -1,112 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsResizableExtension(
gd::PlatformExtension &extension) {
extension
.SetExtensionInformation("ResizableCapability",
_("Resizable capability"),
_("Change the object dimensions."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Size")).SetIcon(
"res/actions/scale24_black.png");
gd::BehaviorMetadata &aut =
extension
.AddBehavior("ResizableBehavior",
_("Resizable capability"),
"Resizable",
_("Change the object dimensions."),
"",
"res/actions/scale24_black.png",
"ResizableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddScopedAction("SetWidth",
_("Width"),
_("Change the width of the object."),
_("the width"),
_("Size"),
"res/actions/scaleWidth24_black.png",
"res/actions/scaleWidth_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
.MarkAsAdvanced();
aut.AddScopedCondition("Width",
_("Width"),
_("Compare the width of the object."),
_("the width"),
_("Size"),
"res/conditions/scaleWidth24_black.png",
"res/conditions/scaleWidth_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Width")))
.MarkAsAdvanced();
aut.AddScopedAction("SetHeight",
_("Height"),
_("Change the height of the object."),
_("the height"),
_("Size"),
"res/actions/scaleHeight24_black.png",
"res/actions/scaleHeight_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
.UseStandardOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
.MarkAsAdvanced();
aut.AddScopedCondition("Height",
_("Height"),
_("Compare the height of the object."),
_("the height"),
_("Size"),
"res/conditions/scaleHeight24_black.png",
"res/conditions/scaleHeight_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
.UseStandardRelationalOperatorParameters(
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Height")))
.MarkAsAdvanced();
aut.AddScopedAction(
"SetSize",
_("Size"),
_("Change the size of an object."),
_("Change the size of _PARAM0_: set to _PARAM2_ x _PARAM3_"),
_("Size"),
"res/actions/scale24_black.png",
"res/actions/scale_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ResizableBehavior")
.AddParameter("expression", _("Width"))
.AddParameter("expression", _("Height"))
.MarkAsAdvanced();
}
} // namespace gd

View File

@@ -1,95 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("ScalableCapability",
_("Scalable capability"),
_("Change the object scale."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
.SetIcon("res/actions/scale24_black.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"ScalableBehavior",
_("Scalable capability"),
"Scale",
_("Change the object scale."),
"",
"res/actions/scale24_black.png",
"ResizableBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"number",
"Value",
_("Scale"),
_("the scale of the object (default scale is 1)"),
_("the scale"),
_("Size"),
"res/actions/scale24_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
.UseStandardParameters(
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Value"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
"X",
_("Scale on X axis"),
_("the scale on X axis of the object (default scale is 1)"),
_("the scale on X axis"),
_("Size"),
"res/actions/scaleWidth24_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
.UseStandardParameters(
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["X"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
"Y",
_("Scale on Y axis"),
_("the scale on Y axis of the object (default scale is 1)"),
_("the scale on Y axis"),
_("Size"),
"res/actions/scaleHeight24_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
.UseStandardParameters(
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Y"].SetGroup("");
}
} // namespace gd

View File

@@ -1,58 +0,0 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public
* License.
*/
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("TextContainerCapability",
_("Text capability"),
_("Animate objects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Text capability"))
.SetIcon("res/conditions/text24_black.png");
gd::BehaviorMetadata& aut = extension.AddBehavior(
"TextContainerBehavior",
_("Text capability"),
"Text",
_("Access objects text."),
"",
"res/conditions/text24_black.png",
"TextContainerBehavior",
std::make_shared<gd::Behavior>(),
std::make_shared<gd::BehaviorsSharedData>())
.SetHidden();
aut.AddExpressionAndConditionAndAction(
"string",
"Value",
_("Text"),
_("the text"),
_("the text"),
"",
"res/conditions/text24_black.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "TextContainerBehavior")
.UseStandardParameters(
"string", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Text")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Value"].SetGroup("");
}
} // namespace gd

View File

@@ -21,14 +21,14 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("/all-features/common-conversions"); .SetExtensionHelpPath("/all-features/common-conversions");
extension.AddInstructionOrExpressionGroupMetadata(_("Conversion")) extension.AddInstructionOrExpressionGroupMetadata(_("Conversion"))
.SetIcon("res/conditions/toujours24_black.png"); .SetIcon("res/conditions/toujours24.png");
extension extension
.AddExpression("ToNumber", .AddExpression("ToNumber",
_("Text > Number"), _("Text > Number"),
_("Convert the text to a number"), _("Convert the text to a number"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text to convert to a number")); .AddParameter("string", _("Text to convert to a number"));
extension extension
@@ -36,7 +36,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Number > Text"), _("Number > Text"),
_("Convert the result of the expression to text"), _("Convert the result of the expression to text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text")); .AddParameter("expression", _("Expression to be converted to text"));
extension extension
@@ -45,7 +45,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Convert the result of the expression to text, " _("Convert the result of the expression to text, "
"without using the scientific notation"), "without using the scientific notation"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("expression", _("Expression to be converted to text")); .AddParameter("expression", _("Expression to be converted to text"));
extension extension
@@ -54,7 +54,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Degrees > Radians"), _("Degrees > Radians"),
_("Converts the angle, expressed in degrees, into radians"), _("Converts the angle, expressed in degrees, into radians"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in degrees")); .AddParameter("expression", _("Angle, in degrees"));
extension extension
@@ -63,7 +63,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Radians > Degrees"), _("Radians > Degrees"),
_("Converts the angle, expressed in radians, into degrees"), _("Converts the angle, expressed in radians, into degrees"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("expression", _("Angle, in radians")); .AddParameter("expression", _("Angle, in radians"));
extension extension
@@ -71,7 +71,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Convert scene variable to JSON"), _("Convert scene variable to JSON"),
_("Convert a scene variable to JSON"), _("Convert a scene variable to JSON"),
_("JSON"), _("JSON"),
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("scenevar", _("Scene variable to be stringified")); .AddParameter("scenevar", _("Scene variable to be stringified"));
extension extension
@@ -79,7 +79,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Convert global variable to JSON"), _("Convert global variable to JSON"),
_("Convert a global variable to JSON"), _("Convert a global variable to JSON"),
_("JSON"), _("JSON"),
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("globalvar", _("The global variable to be stringified")); .AddParameter("globalvar", _("The global variable to be stringified"));
extension extension
@@ -87,7 +87,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
_("Convert object variable to JSON"), _("Convert object variable to JSON"),
_("Convert an object variable to JSON"), _("Convert an object variable to JSON"),
_("JSON"), _("JSON"),
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("objectPtr", _("The object with the variable")) .AddParameter("objectPtr", _("The object with the variable"))
.AddParameter("objectvar", _("The object variable to be stringified")); .AddParameter("objectvar", _("The object variable to be stringified"));
@@ -96,7 +96,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
"JSONToVariableStructure", "JSONToVariableStructure",
_("Convert JSON to a scene variable"), _("Convert JSON to a scene variable"),
_("Parse a JSON object and store it into a scene variable"), _("Parse a JSON object and store it into a scene variable"),
_("Convert JSON string _PARAM0_ and store it into variable _PARAM1_"), _("Parse JSON string _PARAM0_ and store it into variable _PARAM1_"),
"", "",
"res/actions/net24.png", "res/actions/net24.png",
"res/actions/net.png") "res/actions/net.png")
@@ -108,7 +108,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.AddAction("JSONToGlobalVariableStructure", .AddAction("JSONToGlobalVariableStructure",
_("Convert JSON to global variable"), _("Convert JSON to global variable"),
_("Parse a JSON object and store it into a global variable"), _("Parse a JSON object and store it into a global variable"),
_("Convert JSON string _PARAM0_ and store it into global " _("Parse JSON string _PARAM0_ and store it into global "
"variable _PARAM1_"), "variable _PARAM1_"),
"", "",
"res/actions/net24.png", "res/actions/net24.png",

View File

@@ -33,10 +33,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
.SetExtensionHelpPath("/all-features/advanced-conditions"); .SetExtensionHelpPath("/all-features/advanced-conditions");
extension extension
.AddInstructionOrExpressionGroupMetadata(_("Events and control flow")) .AddInstructionOrExpressionGroupMetadata(_("Events and control flow"))
.SetIcon("res/conditions/toujours24_black.png"); .SetIcon("res/conditions/toujours24.png");
// This condition is deprecated as this does not bring anything new
// and can be confusing or misleading for beginners.
extension extension
.AddCondition("Always", .AddCondition("Always",
_("Always"), _("Always"),
@@ -44,12 +42,11 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
"the condition is inverted)."), "the condition is inverted)."),
_("Always"), _("Always"),
"", "",
"res/conditions/toujours24_black.png", "res/conditions/toujours24.png",
"res/conditions/toujours_black.png") "res/conditions/toujours.png")
.SetHelpPath("/all-features/advanced-conditions") .SetHelpPath("/all-features/advanced-conditions")
.AddCodeOnlyParameter("conditionInverted", "") .AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced() .MarkAsAdvanced();
.SetHidden();
// Compatibility with GD <= 5.0.127 // Compatibility with GD <= 5.0.127
extension extension
@@ -64,8 +61,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Check if one of the sub conditions is true"), _("Check if one of the sub conditions is true"),
_("If one of these conditions is true:"), _("If one of these conditions is true:"),
"", "",
"res/conditions/or24_black.png", "res/conditions/or24.png",
"res/conditions/or_black.png") "res/conditions/or.png")
.SetCanHaveSubInstructions() .SetCanHaveSubInstructions()
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -75,8 +72,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Check if all sub conditions are true"), _("Check if all sub conditions are true"),
_("If all of these conditions are true:"), _("If all of these conditions are true:"),
"", "",
"res/conditions/and24_black.png", "res/conditions/and24.png",
"res/conditions/and_black.png") "res/conditions/and.png")
.SetCanHaveSubInstructions() .SetCanHaveSubInstructions()
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -87,8 +84,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Return the contrary of the result of the sub conditions"), _("Return the contrary of the result of the sub conditions"),
_("Invert the logical result of these conditions:"), _("Invert the logical result of these conditions:"),
"", "",
"res/conditions/not24_black.png", "res/conditions/not24.png",
"res/conditions/not_black.png") "res/conditions/not.png")
.SetCanHaveSubInstructions() .SetCanHaveSubInstructions()
.MarkAsAdvanced(); .MarkAsAdvanced();
@@ -107,8 +104,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Compare the two numbers."), _("Compare the two numbers."),
_("_PARAM0_ _PARAM1_ _PARAM2_"), _("_PARAM0_ _PARAM1_ _PARAM2_"),
"", "",
"res/conditions/egal24_black.png", "res/conditions/egal24.png",
"res/conditions/egal_black.png") "res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions") .SetHelpPath("/all-features/advanced-conditions")
.AddParameter("expression", _("First expression")) .AddParameter("expression", _("First expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "number") .AddParameter("relationalOperator", _("Sign of the test"), "number")
@@ -117,9 +114,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
// Compatibility with GD <= 5.0.127 // Compatibility with GD <= 5.0.127
extension extension
.AddDuplicatedCondition("Egal", .AddDuplicatedCondition(
"BuiltinCommonInstructions::CompareNumbers", "Egal", "BuiltinCommonInstructions::CompareNumbers", {.unscoped = true})
{.unscoped = true})
.SetHidden(); .SetHidden();
// end of compatibility code // end of compatibility code
@@ -129,8 +125,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
_("Compare the two strings."), _("Compare the two strings."),
_("_PARAM0_ _PARAM1_ _PARAM2_"), _("_PARAM0_ _PARAM1_ _PARAM2_"),
"", "",
"res/conditions/egal24_black.png", "res/conditions/egal24.png",
"res/conditions/egal_black.png") "res/conditions/egal.png")
.SetHelpPath("/all-features/advanced-conditions") .SetHelpPath("/all-features/advanced-conditions")
.AddParameter("string", _("First string expression")) .AddParameter("string", _("First string expression"))
.AddParameter("relationalOperator", _("Sign of the test"), "string") .AddParameter("relationalOperator", _("Sign of the test"), "string")
@@ -139,9 +135,8 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
// Compatibility with GD <= 5.0.127 // Compatibility with GD <= 5.0.127
extension extension
.AddDuplicatedCondition("StrEqual", .AddDuplicatedCondition(
"BuiltinCommonInstructions::CompareStrings", "StrEqual", "BuiltinCommonInstructions::CompareStrings", {.unscoped = true})
{.unscoped = true})
.SetHidden(); .SetHidden();
// end of compatibility code // end of compatibility code

View File

@@ -38,8 +38,6 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
.SetDefaultValue("0") .SetDefaultValue("0")
.AddParameter("expression", _("Y position of the origin"), "", true) .AddParameter("expression", _("Y position of the origin"), "", true)
.SetDefaultValue("0") .SetDefaultValue("0")
.AddParameter("expression", _("Z position of the origin"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced(); .MarkAsAdvanced();
} }

View File

@@ -21,7 +21,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
"Florian Rival", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage") .SetExtensionHelpPath("/all-features/storage")
.SetCategory("Advanced"); .SetCategory("Device");
extension.AddInstructionOrExpressionGroupMetadata(_("Storage")) extension.AddInstructionOrExpressionGroupMetadata(_("Storage"))
.SetIcon("res/conditions/fichier24.png"); .SetIcon("res/conditions/fichier24.png");
@@ -69,12 +69,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
extension extension
.AddAction( .AddAction(
"EcrireFichierExp", "EcrireFichierExp",
_("Save a value"), _("Write a value"),
_("Save the result of the expression in the stored data, in the " _("Write the result of the expression in the stored data, in the "
"specified element.\nSpecify the structure leading to the " "specified element.\nSpecify the structure leading to the "
"element using / (example : Root/Level/Current)\nSpaces are " "element using / (example : Root/Level/Current)\nSpaces are "
"forbidden in element names."), "forbidden in element names."),
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"), _("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"", "",
"res/actions/fichier24.png", "res/actions/fichier24.png",
"res/actions/fichier.png") "res/actions/fichier.png")
@@ -85,12 +85,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
extension extension
.AddAction( .AddAction(
"EcrireFichierTxt", "EcrireFichierTxt",
_("Save a text"), _("Write a text"),
_("Save the text in the specified storage, in the specified " _("Write the text in the specified storage, in the specified "
"element.\nSpecify " "element.\nSpecify "
"the structure leading to the element using / (example : " "the structure leading to the element using / (example : "
"Root/Level/Current)\nSpaces are forbidden in element names."), "Root/Level/Current)\nSpaces are forbidden in element names."),
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"), _("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
"", "",
"res/actions/fichier24.png", "res/actions/fichier24.png",
"res/actions/fichier.png") "res/actions/fichier.png")
@@ -101,13 +101,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
extension extension
.AddAction( .AddAction(
"LireFichierExp", "LireFichierExp",
_("Load a value"), _("Read a value"),
_("Load the value saved in the specified element and store it in a " _("Read the value saved in the specified element and store it in a "
"scene " "scene "
"variable.\nSpecify the structure leading to the element using / " "variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element " "(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."), "names."),
_("Load _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"), _("Read _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
"", "",
"res/actions/fichier24.png", "res/actions/fichier24.png",
"res/actions/fichier.png") "res/actions/fichier.png")
@@ -119,13 +119,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
extension extension
.AddAction( .AddAction(
"LireFichierTxt", "LireFichierTxt",
_("Load a text"), _("Read a text"),
_("Load the text saved in the specified element and store it in a " _("Read the text saved in the specified element and store it in a "
"scene " "scene "
"variable.\nSpecify the structure leading to the element using / " "variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element " "(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."), "names."),
_("Load _PARAM1_ from storage _PARAM0_ and store as text in " _("Read _PARAM1_ from storage _PARAM0_ and store as text in "
"_PARAM3_"), "_PARAM3_"),
"", "",
"res/actions/fichier24.png", "res/actions/fichier24.png",

View File

@@ -96,13 +96,13 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
_("Difference between two angles"), _("Difference between two angles"),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("First angle, in degrees")) .AddParameter("expression", _("First angle"))
.AddParameter("expression", _("Second angle, in degrees")); .AddParameter("expression", _("Second angle"));
extension extension
.AddExpression("AngleBetweenPositions", .AddExpression("AngleBetweenPositions",
_("Angle between two positions"), _("Angle between two positions"),
_("Compute the angle between two positions (in degrees)."), _("Compute the angle between two positions."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("First point X position")) .AddParameter("expression", _("First point X position"))
@@ -159,8 +159,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("acos", .AddExpression("acos",
_("Arccosine"), _("Arccosine"),
_("Arccosine, return an angle (in radian). " _("Arccosine"),
"`ToDeg` allows to convert it to degrees."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -176,8 +175,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("asin", .AddExpression("asin",
_("Arcsine"), _("Arcsine"),
_("Arcsine, return an angle (in radian). " _("Arcsine"),
"`ToDeg` allows to convert it to degrees."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -193,8 +191,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("atan", .AddExpression("atan",
_("Arctangent"), _("Arctangent"),
_("Arctangent, return an angle (in radian). " _("Arctangent"),
"`ToDeg` allows to convert it to degrees."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -261,8 +258,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("cos", .AddExpression("cos",
_("Cosine"), _("Cosine"),
_("Cosine of an angle (in radian). " _("Cosine of a number"),
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -404,8 +400,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("sin", .AddExpression("sin",
_("Sine"), _("Sine"),
_("Sine of an angle (in radian). " _("Sine of a number"),
"If you want to use degrees, use`ToRad`: `sin(ToRad(45))`."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -429,8 +424,7 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension extension
.AddExpression("tan", .AddExpression("tan",
_("Tangent"), _("Tangent"),
_("Tangent of an angle (in radian). " _("Tangent of a number"),
"If you want to use degrees, use`ToRad`: `tan(ToRad(45))`."),
"", "",
"res/mathfunction.png") "res/mathfunction.png")
.AddParameter("expression", _("Expression")); .AddParameter("expression", _("Expression"));
@@ -485,23 +479,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("Angle, in degrees")) .AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance")); .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."));
} }
} // namespace gd } // namespace gd

View File

@@ -27,8 +27,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.SetCategory("Input"); .SetCategory("Input");
extension.AddInstructionOrExpressionGroupMetadata(_("Mouse and touch")) extension.AddInstructionOrExpressionGroupMetadata(_("Mouse and touch"))
.SetIcon("res/actions/mouse24.png"); .SetIcon("res/actions/mouse24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Multitouch"))
.SetIcon("res/conditions/touch24.png");
extension extension
.AddCondition( .AddCondition(
@@ -155,80 +153,42 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
extension extension
.AddExpressionAndCondition( .AddExpressionAndCondition(
"number", "number",
"CursorX", "MouseX",
_("Cursor X position"), _("Cursor X position"),
_("the X position of the cursor or of a touch"), _("the X position of the cursor or of a touch"),
_("the cursor (or touch) X position"), _("the cursor (or touch) X position"),
"", "",
"res/conditions/mouse24.png") "res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
// Support for deprecated names: // Support for deprecated names:
extension.AddDuplicatedCondition("MouseX", "CursorX").SetHidden(); extension.AddDuplicatedCondition("SourisX", "MouseX").SetHidden();
extension.AddDuplicatedExpression("MouseX", "CursorX").SetHidden(); extension.AddDuplicatedExpression("SourisX", "MouseX").SetHidden();
extension.AddDuplicatedCondition("SourisX", "CursorX").SetHidden();
extension.AddDuplicatedExpression("SourisX", "CursorX").SetHidden();
extension extension
.AddExpressionAndCondition( .AddExpressionAndCondition(
"number", "number",
"CursorY", "MouseY",
_("Cursor Y position"), _("Cursor Y position"),
_("the Y position of the cursor or of a touch"), _("the Y position of the cursor or of a touch"),
_("the cursor (or touch) Y position"), _("the cursor (or touch) Y position"),
"", "",
"res/conditions/mouse24.png") "res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
// Support for deprecated names: // Support for deprecated names:
extension.AddDuplicatedCondition("MouseY", "CursorY").SetHidden(); extension.AddDuplicatedCondition("SourisY", "MouseY").SetHidden();
extension.AddDuplicatedExpression("MouseY", "CursorY").SetHidden(); extension.AddDuplicatedExpression("SourisY", "MouseY").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 extension
.AddCondition("IsMouseInsideCanvas", .AddCondition("IsMouseInsideCanvas",
@@ -316,8 +276,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/touch24.png") "res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier")) .AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
@@ -332,8 +292,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/touch24.png") "res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier")) .AddParameter("expression", _("Touch identifier"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions()) .UseStandardParameters("number")
.AddParameter("layer", _("Layer"), "", true) .AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"") .SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true) .AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0"); .SetDefaultValue("0");
@@ -374,85 +334,44 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition( .AddCondition(
"HasAnyTouchStarted", "HasAnyTouchStarted",
_("A new touch has started"), _("A new touch has started"),
_("Check if a touch has just started on this frame. The touch " _("Check if a touch has just started on this frame. The touch identifiers can be "
"identifiers can be "
"accessed using StartedTouchId() and StartedTouchCount()."), "accessed using StartedTouchId() and StartedTouchCount()."),
_("A new touch has started"), _("A new touch has started"),
_("Multitouch"), _("Multitouch"),
"res/conditions/touch24.png", "res/conditions/touch24.png",
"res/conditions/touch.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"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", ""); .AddCodeOnlyParameter("currentScene", "");
extension extension
.AddExpression( .AddExpression(
"StartedTouchOrMouseCount", "StartedTouchCount",
_("Started touch count"), _("Started touch count"),
_("The number of touches (including the mouse) that have just " _("The number of touches that have just started on this frame. The touch identifiers can be "
"started on this frame. The touch identifiers can be " "accessed using StartedTouchId()."),
"accessed using StartedTouchOrMouseId()."),
_("Multitouch"), _("Multitouch"),
"res/conditions/touch.png") "res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", ""); .AddCodeOnlyParameter("currentScene", "");
extension extension
.AddExpression( .AddExpression(
"StartedTouchOrMouseId", "StartedTouchId",
_("Started touch identifier"), _("Started touch identifier"),
_("The identifier of the touch or mouse that has just started on " _("The identifier of the touch that has just started on this frame. The touch number of touches can be "
"this frame. The number of touches can be " "accessed using StartedTouchCount()."),
"accessed using StartedTouchOrMouseCount()."),
_("Multitouch"), _("Multitouch"),
"res/conditions/touch.png") "res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch index")); .AddParameter("expression", _("Touch index"));
extension extension
.AddCondition("HasTouchEnded", .AddCondition(
_("A touch has ended"), "HasTouchEnded",
_("Check if a touch has ended or a mouse left button has " _("A touch has ended"),
"been released."), _("Check if a touch has ended."),
_("The touch with identifier _PARAM1_ has ended"), _("The touch with identifier _PARAM1_ has ended"),
_("Multitouch"), _("Multitouch"),
"res/conditions/touch24.png", "res/conditions/touch24.png",
"res/conditions/touch.png") "res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier")); .AddParameter("expression", _("Touch identifier"));

View File

@@ -48,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
.AddParameter("string", "Content type", "", true) .AddParameter("string", "Content type", "", true)
.SetParameterLongDescription( .SetParameterLongDescription(
"If empty, \"application/x-www-form-urlencoded\" will be used.") "If empty, \"application/x-www-form-urlencoded\" will be used.")
.AddParameter("scenevar", "Response scene variable", "", true) .AddParameter("scenevar", "Reponse scene variable", "", true)
.SetParameterLongDescription( .SetParameterLongDescription(
"The response of the server will be stored, as a string, in this " "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 " "variable. If the server returns *JSON*, you may want to use the "

View File

@@ -5,7 +5,6 @@
*/ */
#include "AllBuiltinExtensions.h" #include "AllBuiltinExtensions.h"
#include "GDCore/Tools/Localization.h" #include "GDCore/Tools/Localization.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
using namespace std; using namespace std;
namespace gd { namespace gd {
@@ -55,19 +54,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.MarkAsSimple(); .MarkAsSimple();
extension
.AddCondition("DoesSceneExist",
_("Does scene exist"),
_("Check if a 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 extension
.AddAction("Scene", .AddAction("Scene",
_("Change the scene"), _("Change the scene"),
@@ -126,7 +112,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
extension extension
.AddAction("SceneBackground", .AddAction("SceneBackground",
_("Background color"), _("Change background color"),
_("Change the background color of the scene."), _("Change the background color of the scene."),
_("Set background color to _PARAM1_"), _("Set background color to _PARAM1_"),
"", "",
@@ -150,59 +136,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Deactivate input when focus is lost")) .AddParameter("yesorno", _("Deactivate input when focus is lost"))
.MarkAsAdvanced(); .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", "");
extension
.AddAction("PrioritizeLoadingOfScene",
_("Preload scene"),
_("Preload a scene resources as soon as possible in background."),
_("Preload scene _PARAM1_ in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Name of the new scene"))
.MarkAsAdvanced();
extension.AddExpressionAndCondition("number",
"SceneLoadingProgress",
_("Scene loading progress"),
_("The progress of resources loading in background for a scene (between 0 and 1)."),
_("_PARAM0_ loading progress"),
_(""),
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced();
extension
.AddCondition("AreSceneAssetsLoaded",
_("Scene preloaded"),
_("Check if scene resources have finished to load in background."),
_("Scene _PARAM1_ was preloaded in background"),
"",
"res/actions/hourglass_black.svg",
"res/actions/hourglass_black.svg")
.SetHelpPath("/all-features/resources-loading")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("sceneName", _("Scene name"))
.MarkAsAdvanced();
} }
} // namespace gd } // namespace gd

View File

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

View File

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

View File

@@ -4,10 +4,8 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "GDCore/CommonTools.h" #include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Serialization/SerializerElement.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]; } 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) { void Direction::RemoveSprite(std::size_t index) {
if (index < sprites.size()) sprites.erase(sprites.begin() + index); if (index < sprites.size()) sprites.erase(sprites.begin() + index);
} }
@@ -110,11 +99,11 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
.GetBoolAttribute("automatic", true)); .GetBoolAttribute("automatic", true));
if (spriteElement.HasChild("CustomCollisionMask")) if (spriteElement.HasChild("CustomCollisionMask"))
sprite.SetFullImageCollisionMask( sprite.SetCollisionMaskAutomatic(
!spriteElement.GetChild("CustomCollisionMask") !spriteElement.GetChild("CustomCollisionMask")
.GetBoolAttribute("custom", false)); .GetBoolAttribute("custom", false));
else else
sprite.SetFullImageCollisionMask( sprite.SetCollisionMaskAutomatic(
!spriteElement.GetBoolAttribute("hasCustomCollisionMask", false)); !spriteElement.GetBoolAttribute("hasCustomCollisionMask", false));
std::vector<Polygon2d> mask; std::vector<Polygon2d> mask;
@@ -173,7 +162,7 @@ void SaveSpritesDirection(const vector<Sprite>& sprites,
.SetAttribute("automatic", sprites[i].IsDefaultCenterPoint()); .SetAttribute("automatic", sprites[i].IsDefaultCenterPoint());
spriteElement.SetAttribute("hasCustomCollisionMask", spriteElement.SetAttribute("hasCustomCollisionMask",
!sprites[i].IsFullImageCollisionMask()); !sprites[i].IsCollisionMaskAutomatic());
gd::SerializerElement& collisionMaskElement = gd::SerializerElement& collisionMaskElement =
spriteElement.AddChild("customCollisionMask"); spriteElement.AddChild("customCollisionMask");

View File

@@ -3,12 +3,12 @@
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_DIRECTION_H
#define GDCORE_DIRECTION_H
#include <vector> #include <vector>
#include "GDCore/String.h" #include "GDCore/String.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
namespace gd { namespace gd {
class Sprite;
class SerializerElement; class SerializerElement;
} }
@@ -72,13 +72,6 @@ class GD_CORE_API Direction {
*/ */
Sprite& GetSprite(std::size_t nb); 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. * \brief Check if the direction contains sprites.
* *
@@ -142,3 +135,4 @@ class GD_CORE_API Direction {
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_DIRECTION_H

View File

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

View File

@@ -4,15 +4,13 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#include "Polygon2d.h" #include "Polygon2d.h"
#include "GDCore/Vector2.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include "GDCore/Vector2.h" void Polygon2d::Rotate(float angle) {
float t, cosa = cos(-angle),
void Polygon2d::Rotate(double angle) { sina = sin(-angle); // We want a clockwise rotation
double t, cosa = cos(-angle),
sina = sin(-angle); // We want a clockwise rotation
for (std::size_t i = 0; i < vertices.size(); ++i) { for (std::size_t i = 0; i < vertices.size(); ++i) {
t = vertices[i].x; 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++) { for (std::size_t i = 0; i < vertices.size(); i++) {
vertices[i].x += x; vertices[i].x += x;
vertices[i].y += y; vertices[i].y += y;
@@ -52,13 +50,13 @@ bool Polygon2d::IsConvex() const {
(edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x) > 0; (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) { 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; edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x;
if ((zCrossProduct > 0) != zProductIsPositive) return false; if ((zCrossProduct > 0) != zProductIsPositive) return false;
} }
double lastZCrossProduct = edges[edges.size() - 1].x * edges[0].y - float lastZCrossProduct = edges[edges.size() - 1].x * edges[0].y -
edges[edges.size() - 1].y * edges[0].x; edges[edges.size() - 1].y * edges[0].x;
if ((lastZCrossProduct > 0) != zProductIsPositive) return false; if ((lastZCrossProduct > 0) != zProductIsPositive) return false;
return true; return true;
@@ -77,7 +75,7 @@ gd::Vector2f Polygon2d::ComputeCenter() const {
return center; return center;
} }
Polygon2d Polygon2d::CreateRectangle(double width, double height) { Polygon2d Polygon2d::CreateRectangle(float width, float height) {
Polygon2d rect; 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));

View File

@@ -5,9 +5,8 @@
*/ */
#ifndef GDCORE_POLYGON_H #ifndef GDCORE_POLYGON_H
#define GDCORE_POLYGON_H #define GDCORE_POLYGON_H
#include <vector>
#include "GDCore/Vector2.h" #include "GDCore/Vector2.h"
#include <vector>
/** /**
* \brief Represents a polygon. Usually used for collisions masks. * \brief Represents a polygon. Usually used for collisions masks.
@@ -43,7 +42,7 @@ class GD_CORE_API Polygon2d {
* \note Edges are updated, there is no need to call ComputeEdges after * \note Edges are updated, there is no need to call ComputeEdges after
* calling Move. * calling Move.
*/ */
void Move(double x, double y); void Move(float x, float y);
/** /**
* \brief Rotate the polygon. * \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 * \warning edges vector is not updated, you have to call ComputeEdges if
* needed. * needed.
*/ */
void Rotate(double angle); void Rotate(float angle);
/** /**
* \brief Automatically fill edges vector using vertices. * \brief Automatically fill edges vector using vertices.
@@ -78,7 +77,7 @@ class GD_CORE_API Polygon2d {
/** /**
* \brief Create a rectangle * \brief Create a rectangle
*/ */
static Polygon2d CreateRectangle(double width, double height); static Polygon2d CreateRectangle(float width, float height);
///@} ///@}
}; };

View File

@@ -4,9 +4,7 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include <iostream> #include <iostream>
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
using namespace std; using namespace std;
@@ -16,10 +14,11 @@ namespace gd {
Point Sprite::badPoint(""); Point Sprite::badPoint("");
Sprite::Sprite() Sprite::Sprite()
: fullImageCollisionMask(false), : automaticCollisionMask(true),
origine("origine"), origine("origine"),
centre("centre"), centre("centre"),
automaticCentre(true) {} automaticCentre(true) {
}
Sprite::~Sprite(){}; Sprite::~Sprite(){};

View File

@@ -7,7 +7,6 @@
#ifndef SPRITE_H #ifndef SPRITE_H
#define SPRITE_H #define SPRITE_H
#include <memory> #include <memory>
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
#include "GDCore/String.h" #include "GDCore/String.h"
@@ -44,7 +43,7 @@ class GD_CORE_API Sprite {
/** /**
* \brief Get the collision mask (custom or automatically generated owing to * \brief Get the collision mask (custom or automatically generated owing to
* IsFullImageCollisionMask()) * IsCollisionMaskAutomatic())
* *
* \warning If the image has not been loaded ( using LoadImage ) and the * \warning If the image has not been loaded ( using LoadImage ) and the
* collision mask is set as automatic, the returned mask won't be correct. * collision mask is set as automatic, the returned mask won't be correct.
@@ -67,7 +66,7 @@ class GD_CORE_API Sprite {
/** /**
* \brief Set the custom collision mask. * \brief Set the custom collision mask.
* Call then `SetFullImageCollisionMask(false)` to use it. * Call then `SetCollisionMaskAutomatic(false)` to use it.
*/ */
void SetCustomCollisionMask(const std::vector<Polygon2d>& collisionMask); void SetCustomCollisionMask(const std::vector<Polygon2d>& collisionMask);
@@ -75,15 +74,15 @@ class GD_CORE_API Sprite {
* \brief Return true if the collision mask is a bounding box, false if a * \brief Return true if the collision mask is a bounding box, false if a
* custom collision mask is used. * custom collision mask is used.
*/ */
inline bool IsFullImageCollisionMask() const { inline bool IsCollisionMaskAutomatic() const {
return fullImageCollisionMask; return automaticCollisionMask;
} }
/** /**
* \brief Un/set use of the custom collision mask. * \brief Un/set use of the custom collision mask.
*/ */
inline void SetFullImageCollisionMask(bool enabled) { inline void SetCollisionMaskAutomatic(bool enabled) {
fullImageCollisionMask = enabled; automaticCollisionMask = enabled;
}; };
/** /**
@@ -162,9 +161,9 @@ class GD_CORE_API Sprite {
private: private:
gd::String image; ///< Name of the image to be loaded in Image Manager. gd::String image; ///< Name of the image to be loaded in Image Manager.
bool fullImageCollisionMask; ///< True to use a bounding box wrapping the bool automaticCollisionMask; ///< True to use the custom collision mask.
///< whole image as collision mask. If false, ///< Otherwise, a basic bounding box is returned
///< custom collision mask is used. ///< by GetCollisionMask()
std::vector<Polygon2d> customCollisionMask; ///< Custom collision mask std::vector<Polygon2d> customCollisionMask; ///< Custom collision mask
std::vector<Point> points; ///< List of the points used by the sprite std::vector<Point> points; ///< List of the points used by the sprite

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
* GDevelop Core * GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the GNU Lesser General Public * reserved. This project is released under the GNU Lesser General Public
* License. * LicenFse.
*/ */
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h" #include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h" #include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
@@ -22,27 +22,18 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"Florian Rival", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("/objects/sprite"); .SetExtensionHelpPath("/objects/sprite");
extension.AddInstructionOrExpressionGroupMetadata(_("Sprite"))
.SetIcon("CppPlatform/Extensions/spriteicon.png");
gd::ObjectMetadata& obj = gd::ObjectMetadata& obj =
extension extension
.AddObject<SpriteObject>("Sprite", .AddObject<SpriteObject>("Sprite",
_("Sprite"), _("Sprite"),
_("Animated object which can be used for " _("Animated object which can be used for "
"most elements of a game."), "most elements of a game"),
"CppPlatform/Extensions/spriteicon.png") "CppPlatform/Extensions/spriteicon.png")
.SetCategoryFullName(_("General")) .SetCategoryFullName(_("General"));
.AddDefaultBehavior("EffectCapability::EffectBehavior")
.AddDefaultBehavior("ResizableCapability::ResizableBehavior")
.AddDefaultBehavior("ScalableCapability::ScalableBehavior")
.AddDefaultBehavior("FlippableCapability::FlippableBehavior")
.AddDefaultBehavior("OpacityCapability::OpacityBehavior")
.AddDefaultBehavior("AnimatableCapability::AnimatableBehavior");
// Deprecated
obj.AddAction("Opacity", obj.AddAction("Opacity",
_("Sprite opacity"), _("Change sprite opacity"),
_("Change the opacity of a Sprite. 0 is fully transparent, 255 " _("Change the opacity of a Sprite. 0 is fully transparent, 255 "
"is opaque (default)."), "is opaque (default)."),
_("the opacity"), _("the opacity"),
@@ -51,14 +42,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/opacity.png") "res/actions/opacity.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number", .MarkAsSimple();
ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity (0-255)")))
.MarkAsSimple()
.SetHidden();
// Deprecated
obj.AddAction("ChangeAnimation", obj.AddAction("ChangeAnimation",
_("Change the animation"), _("Change the animation"),
_("Change the animation of the object, using the animation " _("Change the animation of the object, using the animation "
@@ -69,12 +55,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png") "res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number")
ParameterOptions::MakeNewOptions())
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddAction("SetAnimationName", obj.AddAction("SetAnimationName",
_("Change the animation (by name)"), _("Change the animation (by name)"),
_("Change the animation of the object, using the name of the " _("Change the animation of the object, using the name of the "
@@ -86,7 +69,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectAnimationName", _("Animation name")) .AddParameter("objectAnimationName", _("Animation name"))
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction( obj.AddAction(
@@ -97,13 +79,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"is in 8 directions mode, the valid directions are 0..7"), "is in 8 directions mode, the valid directions are 0..7"),
_("the direction"), _("the direction"),
_("Direction"), _("Direction"),
"res/actions/direction24_black.png", "res/actions/direction24.png",
"res/actions/direction_black.png") "res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the .SetHidden() // Hide as 8 direction is not supported officially in the
// interface. // interface.
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number")
ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("ChangeSprite", obj.AddAction("ChangeSprite",
@@ -115,11 +96,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/sprite.png") "res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number")
ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
obj.AddAction("PauseAnimation", obj.AddAction("PauseAnimation",
_("Pause the animation"), _("Pause the animation"),
_("Pause the animation of the object"), _("Pause the animation of the object"),
@@ -129,10 +108,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png") "res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddAction("PlayAnimation", obj.AddAction("PlayAnimation",
_("Play the animation"), _("Play the animation"),
_("Play the animation of the object"), _("Play the animation of the object"),
@@ -142,10 +119,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png") "res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddAction( obj.AddAction(
"ChangeAnimationSpeedScale", "ChangeAnimationSpeedScale",
_("Animation speed scale"), _("Animation speed scale"),
@@ -157,20 +132,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png") "res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(_("Speed scale")))
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddAction("TourneVersPos", obj.AddAction("TourneVersPos",
"Rotate an object toward a position", "Rotate an object toward a position",
"Rotate an object towards a position.", "Rotate an object towards a position.",
"Rotate _PARAM0_ towards _PARAM1_;_PARAM2_", "Rotate _PARAM0_ towards _PARAM1_;_PARAM2_",
_("Direction"), _("Direction"),
"res/actions/rotate24_black.png", "res/actions/direction24.png",
"res/actions/rotate_black.png") "res/actions/direction.png")
.AddParameter("object", _("Object to be rotated"), "Sprite") .AddParameter("object", _("Object to be rotated"), "Sprite")
.AddParameter("expression", _("X position")) .AddParameter("expression", _("X position"))
@@ -178,135 +149,105 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("expression", _("Angular speed (degrees per second)")) .AddParameter("expression", _("Angular speed (degrees per second)"))
.SetDefaultValue("0") .SetDefaultValue("0")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.SetHidden(); .SetHidden(); // Deprecated
// Deprecated
obj.AddAction("ChangeScale", obj.AddAction("ChangeScale",
_("Scale"), _("Scale"),
_("Modify the scale of the specified object."), _("Modify the scale of the specified object."),
_("the scale"), _("the scale"),
_("Size"), _("Size"),
"res/actions/scale24_black.png", "res/actions/scale24.png",
"res/actions/scale_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number", .MarkAsAdvanced();
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddAction("ChangeScaleWidth", obj.AddAction("ChangeScaleWidth",
_("Scale on X axis"), _("Scale on X axis"),
_("Modify the scale of the width of an object."), _("Modify the scale of the width of an object."),
_("the width's scale"), _("the width's scale"),
_("Size"), _("Size"),
"res/actions/scaleWidth24_black.png", "res/actions/scale24.png",
"res/actions/scaleWidth_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number", .MarkAsAdvanced();
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddAction("ChangeScaleHeight", obj.AddAction("ChangeScaleHeight",
_("Scale on Y axis"), _("Scale on Y axis"),
_("Modify the scale of the height of an object."), _("Modify the scale of the height of an object."),
_("the height's scale"), _("the height's scale"),
_("Size"), _("Size"),
"res/actions/scaleHeight24_black.png", "res/actions/scale24.png",
"res/actions/scaleHeight_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters( .UseStandardOperatorParameters("number")
"number", .MarkAsAdvanced();
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddAction("ChangeWidth", obj.AddAction("ChangeWidth",
_("Width"), _("Width"),
_("Change the width of a Sprite object."), _("Change the width of a Sprite object."),
_("the width"), _("the width"),
_("Size"), _("Size"),
"res/actions/scaleWidth24_black.png", "res/actions/scale24.png",
"res/actions/scaleWidth_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number")
ParameterOptions::MakeNewOptions()) .MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddCondition("Width", obj.AddCondition("Width",
_("Width"), _("Width"),
_("Compare the width of a Sprite object."), _("Compare the width of a Sprite object."),
_("the width"), _("the width"),
_("Size"), _("Size"),
"res/conditions/scaleWidth24_black.png", "res/conditions/scaleWidth24.png",
"res/conditions/scaleWidth_black.png") "res/conditions/scaleWidth.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", ParameterOptions::MakeNewOptions()) .MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddAction("ChangeHeight", obj.AddAction("ChangeHeight",
_("Height"), _("Height"),
_("Change the height of a Sprite object."), _("Change the height of a Sprite object."),
_("the height"), _("the height"),
_("Size"), _("Size"),
"res/actions/scaleHeight24_black.png", "res/actions/scale24.png",
"res/actions/scaleHeight_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardOperatorParameters("number", .UseStandardOperatorParameters("number")
ParameterOptions::MakeNewOptions()) .MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddCondition("Height", obj.AddCondition("Height",
_("Height"), _("Height"),
_("Compare the height of a Sprite object."), _("Compare the height of a Sprite object."),
_("the height"), _("the height"),
_("Size"), _("Size"),
"res/conditions/scaleHeight24_black.png", "res/conditions/scaleHeight24.png",
"res/conditions/scaleHeight_black.png") "res/conditions/scaleHeight.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", ParameterOptions::MakeNewOptions()) .MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
// Deprecated
obj.AddAction("SetSize", obj.AddAction("SetSize",
_("Size"), _("Size"),
_("Change the size of an object."), _("Change the size of an object."),
_("Change the size of _PARAM0_: set to _PARAM1_x_PARAM2_"), _("Change the size of _PARAM0_: set to _PARAM1_x_PARAM2_"),
_("Size"), _("Size"),
"res/actions/scale24_black.png", "res/actions/scale24.png",
"res/actions/scale_black.png") "res/actions/scale.png")
.AddParameter("object", _("Object")) .AddParameter("object", _("Object"))
.AddParameter("expression", _("Width")) .AddParameter("expression", _("Width"))
.AddParameter("expression", _("Height")) .AddParameter("expression", _("Height"))
.MarkAsAdvanced() .MarkAsAdvanced();
.SetHidden();
// Deprecated
obj.AddCondition( obj.AddCondition(
"Animation", "Animation",
_("Current animation"), _("Current animation"),
@@ -317,15 +258,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png") "res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", ParameterOptions::MakeNewOptions())
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
obj.AddCondition("AnimationName", obj.AddCondition("AnimationName",
_("Current animation name"), _("Current animation name"),
_("Check the animation played by the object."), _("Check the animation by played by the object."),
_("The animation of _PARAM0_ is _PARAM1_"), _("The animation of _PARAM0_ is _PARAM1_"),
_("Animations and images"), _("Animations and images"),
"res/conditions/animation24.png", "res/conditions/animation24.png",
@@ -333,7 +271,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectAnimationName", _("Animation name")) .AddParameter("objectAnimationName", _("Animation name"))
.SetHidden()
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddCondition( obj.AddCondition(
@@ -344,13 +281,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"from 0 to 7. Otherwise, the direction is in degrees."), "from 0 to 7. Otherwise, the direction is in degrees."),
_("the direction"), _("the direction"),
_("Direction"), _("Direction"),
"res/conditions/direction24_black.png", "res/conditions/direction24.png",
"res/conditions/direction_black.png") "res/conditions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the .SetHidden() // Hide as 8 direction is not supported officially in the
// interface. // interface.
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number");
"number", ParameterOptions::MakeNewOptions());
obj.AddCondition("Sprite", obj.AddCondition("Sprite",
_("Current frame"), _("Current frame"),
@@ -363,11 +299,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/sprite.png") "res/conditions/sprite.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
obj.AddCondition("AnimStopped", obj.AddCondition("AnimStopped",
_("Animation paused"), _("Animation paused"),
_("Check if the animation of an object is paused."), _("Check if the animation of an object is paused."),
@@ -377,10 +311,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png") "res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddCondition("AnimationEnded", obj.AddCondition("AnimationEnded",
_("Animation finished"), _("Animation finished"),
_("Check if the animation being played by the Sprite object " _("Check if the animation being played by the Sprite object "
@@ -391,56 +323,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png") "res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.MarkAsSimple()
.SetHidden();
// Deprecated
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")
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
// Deprecated
obj.AddCondition("ScaleWidth", obj.AddCondition("ScaleWidth",
_("Scale on X axis"), _("Scale on X axis"),
_("Compare the scale of the width of an object."), _("Compare the scale of the width of an object."),
_("the width's scale"), _("the width's scale"),
_("Size"), _("Size"),
"res/conditions/scaleWidth24_black.png", "res/conditions/scaleWidth24.png",
"res/conditions/scaleWidth_black.png") "res/conditions/scaleWidth.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
obj.AddCondition("ScaleHeight", obj.AddCondition("ScaleHeight",
_("Scale on Y axis"), _("Scale on Y axis"),
_("Compare the scale of the height of an object."), _("Compare the scale of the height of an object."),
_("the height's scale"), _("the height's scale"),
_("Size"), _("Size"),
"res/conditions/scaleHeight24_black.png", "res/conditions/scaleHeight24.png",
"res/conditions/scaleHeight_black.png") "res/conditions/scaleHeight.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
// Deprecated
obj.AddCondition("Opacity", obj.AddCondition("Opacity",
_("Opacity"), _("Opacity"),
_("Compare the opacity of a Sprite, between 0 (fully " _("Compare the opacity of a Sprite, between 0 (fully "
@@ -451,12 +359,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/opacity.png") "res/conditions/opacity.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", .MarkAsSimple();
ParameterOptions::MakeNewOptions().SetDescription(
_("Opacity to compare to (0-255)")))
.MarkAsSimple()
.SetHidden();
obj.AddCondition( obj.AddCondition(
"BlendMode", "BlendMode",
@@ -468,8 +372,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/opacity.png") "res/conditions/opacity.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number", ParameterOptions::MakeNewOptions())
.MarkAsAdvanced(); .MarkAsAdvanced();
obj.AddAction("ChangeColor", obj.AddAction("ChangeColor",
@@ -504,9 +407,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Effects"), _("Effects"),
"res/actions/flipX24.png", "res/actions/flipX24.png",
"res/actions/flipX.png") "res/actions/flipX.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("yesorno", _("Activate flipping")) .AddParameter("yesorno", _("Activate flipping"))
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
obj.AddAction("FlipY", obj.AddAction("FlipY",
@@ -516,9 +419,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Effects"), _("Effects"),
"res/actions/flipY24.png", "res/actions/flipY24.png",
"res/actions/flipY.png") "res/actions/flipY.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("yesorno", _("Activate flipping")) .AddParameter("yesorno", _("Activate flipping"))
.SetHidden()
.MarkAsSimple(); .MarkAsSimple();
obj.AddCondition("FlippedX", obj.AddCondition("FlippedX",
@@ -528,8 +431,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Effects"), _("Effects"),
"res/actions/flipX24.png", "res/actions/flipX24.png",
"res/actions/flipX.png") "res/actions/flipX.png")
.AddParameter("object", _("Object"), "Sprite")
.SetHidden(); .AddParameter("object", _("Object"), "Sprite");
obj.AddCondition("FlippedY", obj.AddCondition("FlippedY",
_("Vertically flipped"), _("Vertically flipped"),
@@ -538,28 +441,27 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Effects"), _("Effects"),
"res/actions/flipY24.png", "res/actions/flipY24.png",
"res/actions/flipY.png") "res/actions/flipY.png")
.AddParameter("object", _("Object"), "Sprite")
.SetHidden();
// Deprecated .AddParameter("object", _("Object"), "Sprite");
obj.AddAction("TourneVers", obj.AddAction("TourneVers",
"Rotate an object toward another", "Rotate an object toward another",
"Rotate an object towards another.", "Rotate an object towards another.",
"Rotate _PARAM0_ towards _PARAM1_", "Rotate _PARAM0_ towards _PARAM1_",
_("Direction"), _("Direction"),
"res/actions/rotate24_black.png", "res/actions/direction24.png",
"res/actions/rotate_black.png") "res/actions/direction.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPtr", "Rotate toward this object") .AddParameter("objectPtr", "Rotate toward this object")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.SetHidden(); .SetHidden(); // Deprecated
obj.AddExpression("X", obj.AddExpression("X",
_("X position of a point"), _("X position of a point"),
_("X position of a point"), _("X position of a point"),
_("Position"), _("Position"),
"res/actions/position_black.png") "res/actions/position.png")
.SetHidden() .SetHidden()
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true); .AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -568,7 +470,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"), _("Y position of a point"),
_("Y position of a point"), _("Y position of a point"),
_("Position"), _("Position"),
"res/actions/position_black.png") "res/actions/position.png")
.SetHidden() .SetHidden()
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point"), "", true); .AddParameter("objectPointName", _("Name of the point"), "", true);
@@ -577,7 +479,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("X position of a point"), _("X position of a point"),
_("X position of a point"), _("X position of a point"),
_("Position"), _("Position"),
"res/actions/position_black.png") "res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point")); .AddParameter("objectPointName", _("Name of the point"));
@@ -586,31 +488,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
_("Y position of a point"), _("Y position of a point"),
_("Y position of a point"), _("Y position of a point"),
_("Position"), _("Position"),
"res/actions/position_black.png") "res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPointName", _("Name of the point")); .AddParameter("objectPointName", _("Name of the point"));
// Deprecated
obj.AddExpression("Direc", obj.AddExpression("Direc",
_("Direction"), _("Direction"),
_("Direction of the object"), _("Direction of the object"),
_("Direction"), _("Direction"),
"res/actions/direction_black.png") "res/actions/direction.png")
.SetHidden() .SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddExpression("Direction", obj.AddExpression("Direction",
_("Direction"), _("Direction"),
_("Direction of the object"), _("Direction of the object"),
_("Direction"), _("Direction"),
"res/actions/direction_black.png") "res/actions/direction.png")
.SetHidden() // Hide as 8 direction is not supported officially in the .SetHidden() // Hide as 8 direction is not supported officially in the
// interface. // interface.
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddExpression("Anim", obj.AddExpression("Anim",
_("Animation"), _("Animation"),
_("Animation of the object"), _("Animation of the object"),
@@ -619,71 +518,54 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.SetHidden() .SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddExpression("Animation", obj.AddExpression("Animation",
_("Animation"), _("Animation"),
_("Animation of the object"), _("Animation of the object"),
_("Animations and images"), _("Animations and images"),
"res/actions/animation.png") "res/actions/animation.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddStrExpression("AnimationName", obj.AddStrExpression("AnimationName",
_("Animation name"), _("Animation name"),
_("Name of the animation of the object"), _("Name of the animation of the object"),
_("Animations and images"), _("Animations and images"),
"res/actions/animation.png") "res/actions/animation.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("Sprite", obj.AddExpression("Sprite",
_("Image"), _("Image"),
_("Current frame of the animation of the object"), _("Animation frame of the object"),
_("Animations and images"), _("Animations and images"),
"res/actions/sprite.png") "res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("AnimationFrameCount",
_("Number of frames"),
_("Number of frames in the current animation of the object"),
_("Animations and images"),
"res/actions/sprite.png")
.AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddExpression("AnimationSpeedScale", obj.AddExpression("AnimationSpeedScale",
_("Animation speed scale"), _("Animation speed scale"),
_("Animation speed scale"), _("Animation speed scale"),
_("Animations and images"), _("Animations and images"),
"res/actions/animation.png") "res/actions/animation.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("ScaleX", obj.AddExpression("ScaleX",
_("Scale of the width of an object"), _("Scale of the width of an object"),
_("Scale of the width of an object"), _("Scale of the width of an object"),
_("Size"), _("Size"),
"res/actions/scaleWidth_black.png") "res/actions/scaleWidth.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
obj.AddExpression("ScaleY", obj.AddExpression("ScaleY",
_("Scale of the height of an object"), _("Scale of the height of an object"),
_("Scale of the height of an object"), _("Scale of the height of an object"),
_("Size"), _("Size"),
"res/actions/scaleHeight_black.png") "res/actions/scaleHeight.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite"); .AddParameter("object", _("Object"), "Sprite");
// Deprecated
obj.AddExpression("Opacity", obj.AddExpression("Opacity",
_("Opacity"), _("Opacity"),
_("Opacity"), _("Opacity"),
_("Opacity"), _("Opacity"),
"res/actions/opacity.png") "res/actions/opacity.png")
.AddParameter("object", _("Object"), "Sprite") .AddParameter("object", _("Object"), "Sprite");
.SetHidden();
extension extension
.AddCondition("Collision", .AddCondition("Collision",

View File

@@ -23,20 +23,84 @@
namespace gd { namespace gd {
SpriteObject::SpriteObject() Animation SpriteObject::badAnimation;
: updateIfNotVisible(false) {}
SpriteObject::SpriteObject(gd::String name_)
: Object(name_), updateIfNotVisible(false) {}
SpriteObject::~SpriteObject(){}; SpriteObject::~SpriteObject(){};
void SpriteObject::DoUnserializeFrom(gd::Project& project, void SpriteObject::DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) { const gd::SerializerElement& element) {
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true); updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
animations.UnserializeFrom(element);
RemoveAllAnimations();
const gd::SerializerElement& animationsElement =
element.GetChild("animations", 0, "Animations");
animationsElement.ConsiderAsArrayOf("animation", "Animation");
for (std::size_t i = 0; i < animationsElement.GetChildrenCount(); ++i) {
const gd::SerializerElement& animationElement =
animationsElement.GetChild(i);
Animation newAnimation;
newAnimation.useMultipleDirections = animationElement.GetBoolAttribute(
"useMultipleDirections", false, "typeNormal");
newAnimation.SetName(animationElement.GetStringAttribute("name", ""));
// Compatibility with GD <= 3.3
if (animationElement.HasChild("Direction")) {
for (std::size_t j = 0;
j < animationElement.GetChildrenCount("Direction");
++j) {
Direction direction;
direction.UnserializeFrom(animationElement.GetChild("Direction", j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
// End of compatibility code
else {
const gd::SerializerElement& directionsElement =
animationElement.GetChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t j = 0; j < directionsElement.GetChildrenCount(); ++j) {
Direction direction;
direction.UnserializeFrom(directionsElement.GetChild(j));
newAnimation.SetDirectionsCount(newAnimation.GetDirectionsCount() + 1);
newAnimation.SetDirection(direction,
newAnimation.GetDirectionsCount() - 1);
}
}
AddAnimation(newAnimation);
}
} }
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const { void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
element.SetAttribute("updateIfNotVisible", updateIfNotVisible); element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
animations.SerializeTo(element);
// Animations
gd::SerializerElement& animationsElement = element.AddChild("animations");
animationsElement.ConsiderAsArrayOf("animation");
for (std::size_t k = 0; k < GetAnimationsCount(); k++) {
gd::SerializerElement& animationElement =
animationsElement.AddChild("animation");
animationElement.SetAttribute("useMultipleDirections",
GetAnimation(k).useMultipleDirections);
animationElement.SetAttribute("name", GetAnimation(k).GetName());
gd::SerializerElement& directionsElement =
animationElement.AddChild("directions");
directionsElement.ConsiderAsArrayOf("direction");
for (std::size_t l = 0; l < GetAnimation(k).GetDirectionsCount(); l++) {
GetAnimation(k).GetDirection(l).SerializeTo(
directionsElement.AddChild("direction"));
}
}
} }
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties() std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties()
@@ -59,7 +123,16 @@ bool SpriteObject::UpdateProperty(const gd::String& name,
} }
void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) { void SpriteObject::ExposeResources(gd::ArbitraryResourceWorker& worker) {
animations.ExposeResources(worker); for (std::size_t j = 0; j < GetAnimationsCount(); j++) {
for (std::size_t k = 0; k < GetAnimation(j).GetDirectionsCount(); k++) {
for (std::size_t l = 0;
l < GetAnimation(j).GetDirection(k).GetSpritesCount();
l++) {
worker.ExposeImage(
GetAnimation(j).GetDirection(k).GetSprite(l).GetImageName());
}
}
}
} }
std::map<gd::String, gd::PropertyDescriptor> std::map<gd::String, gd::PropertyDescriptor>
@@ -91,12 +164,42 @@ bool SpriteObject::UpdateInitialInstanceProperty(
return true; return true;
} }
const SpriteAnimationList& SpriteObject::GetAnimations() const { const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
return animations; if (nb >= animations.size()) return badAnimation;
return animations[nb];
} }
SpriteAnimationList& SpriteObject::GetAnimations() { Animation& SpriteObject::GetAnimation(std::size_t nb) {
return animations; if (nb >= animations.size()) return badAnimation;
return animations[nb];
}
void SpriteObject::AddAnimation(const Animation& animation) {
animations.push_back(animation);
}
bool SpriteObject::RemoveAnimation(std::size_t nb) {
if (nb >= GetAnimationsCount()) return false;
animations.erase(animations.begin() + nb);
return true;
}
void SpriteObject::SwapAnimations(std::size_t firstIndex,
std::size_t secondIndex) {
if (firstIndex < animations.size() && secondIndex < animations.size() &&
firstIndex != secondIndex)
std::swap(animations[firstIndex], animations[secondIndex]);
}
void SpriteObject::MoveAnimation(std::size_t oldIndex, std::size_t newIndex) {
if (oldIndex >= animations.size() || newIndex >= animations.size()) return;
auto animation = animations[oldIndex];
animations.erase(animations.begin() + oldIndex);
animations.insert(animations.begin() + newIndex, animation);
} }
} // namespace gd } // namespace gd

View File

@@ -4,15 +4,18 @@
* reserved. This project is released under the MIT License. * reserved. This project is released under the MIT License.
*/ */
#pragma once #ifndef GDCORE_SPRITEOBJECT_H
#define GDCORE_SPRITEOBJECT_H
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteAnimationList.h" #include "GDCore/Extensions/Builtin/SpriteExtension/Animation.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Direction.h"
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
#include "GDCore/Project/Object.h" #include "GDCore/Project/Object.h"
namespace gd { namespace gd {
class InitialInstance; class InitialInstance;
class Object; class Object;
class Layout; class Layout;
class Sprite;
class Animation;
class SerializerElement; class SerializerElement;
class PropertyDescriptor; class PropertyDescriptor;
} // namespace gd } // namespace gd
@@ -33,18 +36,19 @@ namespace gd {
* \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension * \see gd::BuiltinExtensionsImplementer::ImplementsSpriteExtension
* \ingroup SpriteObjectExtension * \ingroup SpriteObjectExtension
*/ */
class GD_CORE_API SpriteObject : public gd::ObjectConfiguration { class GD_CORE_API SpriteObject : public gd::Object {
public: public:
SpriteObject(); SpriteObject(gd::String name_);
virtual ~SpriteObject(); virtual ~SpriteObject();
std::unique_ptr<gd::ObjectConfiguration> Clone() const override { std::unique_ptr<gd::Object> Clone() const override {
return gd::make_unique<SpriteObject>(*this); return gd::make_unique<SpriteObject>(*this);
} }
void ExposeResources(gd::ArbitraryResourceWorker& worker) override; void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override; std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
bool UpdateProperty(const gd::String& name, const gd::String& value) override; bool UpdateProperty(const gd::String& name,
const gd::String& value) override;
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties( std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
const gd::InitialInstance& position, const gd::InitialInstance& position,
@@ -56,40 +60,89 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
gd::Project& project, gd::Project& project,
gd::Layout& scene) override; gd::Layout& scene) override;
/** /** \name Animations
* \brief Return the animation configuration. * Methods related to animations management
*/ */
const SpriteAnimationList& GetAnimations() const; ///@{
/**
* \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/
const Animation& GetAnimation(std::size_t nb) const;
/** /**
* @brief Return the animation configuration. * \brief Return the animation at the specified index.
* If the index is out of bound, a "bad animation" object is returned.
*/ */
SpriteAnimationList& GetAnimations(); Animation& GetAnimation(std::size_t nb);
/** /**
* \brief Set if the object animation should be played even if the object is * \brief Return the number of animations this object has.
* hidden or far from the camera.
*/ */
void SetUpdateIfNotVisible(bool updateIfNotVisible_) { std::size_t GetAnimationsCount() const { return animations.size(); };
updateIfNotVisible = updateIfNotVisible_;
}
/** /**
* \brief Check if the object animation should be played even if the object * \brief Add an animation at the end of the existing ones.
* is hidden or far from the camera (false by default). */
void AddAnimation(const Animation& animation);
/**
* \brief Remove an animation.
*/
bool RemoveAnimation(std::size_t nb);
/**
* \brief Remove all animations.
*/
void RemoveAllAnimations() { animations.clear(); }
/**
* \brief Return true if the object hasn't any animation.
*/
bool HasNoAnimations() const { return animations.empty(); }
/**
* \brief Swap the position of two animations
*/
void SwapAnimations(std::size_t firstIndex, std::size_t secondIndex);
/**
* \brief Change the position of the specified animation
*/
void MoveAnimation(std::size_t oldIndex, std::size_t newIndex);
/**
* \brief Return a read-only reference to the vector containing all the
* animation of the object.
*/
const std::vector<Animation>& GetAllAnimations() const { return animations; }
/**
* \brief 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; } bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
///@}
private: private:
void DoUnserializeFrom(gd::Project& project, void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) override; const gd::SerializerElement& element) override;
void DoSerializeTo(gd::SerializerElement& element) const override; void DoSerializeTo(gd::SerializerElement& element) const override;
SpriteAnimationList animations; mutable std::vector<Animation> animations;
bool updateIfNotVisible; ///< If set to true, ask the game engine to play bool updateIfNotVisible; ///< If set to true, ask the game engine to play
///< object animation even if hidden or far from ///< object animation even if hidden or far from the
///< the screen. ///< screen.
static Animation badAnimation; //< Bad animation when an out of bound
// animation is requested.
}; };
} // namespace gd } // namespace gd
#endif // GDCORE_SPRITEOBJECT_H

View File

@@ -21,20 +21,20 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */); .SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
extension.AddInstructionOrExpressionGroupMetadata(_("Text manipulation")) extension.AddInstructionOrExpressionGroupMetadata(_("Text manipulation"))
.SetIcon("res/actions/text24_black.png"); .SetIcon("res/actions/text24.png");
extension.AddStrExpression("NewLine", extension.AddStrExpression("NewLine",
_("Insert a new line"), _("Insert a new line"),
_("Insert a new line"), _("Insert a new line"),
"", "",
"res/conditions/toujours24_black.png"); "res/conditions/toujours24.png");
extension extension
.AddStrExpression("FromCodePoint", .AddStrExpression("FromCodePoint",
_("Get character from code point"), _("Get character from code point"),
_("Get character from code point"), _("Get character from code point"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("expression", _("Code point")); .AddParameter("expression", _("Code point"));
@@ -43,7 +43,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Uppercase a text"), _("Uppercase a text"),
_("Uppercase a text"), _("Uppercase a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")); .AddParameter("string", _("Text"));
@@ -52,7 +52,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Lowercase a text"), _("Lowercase a text"),
_("Lowercase a text"), _("Lowercase a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")); .AddParameter("string", _("Text"));
@@ -61,7 +61,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Get a portion of a text"), _("Get a portion of a text"),
_("Get a portion of a text"), _("Get a portion of a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("expression", .AddParameter("expression",
@@ -74,7 +74,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Get a character from a text"), _("Get a character from a text"),
_("Get a character from a text"), _("Get a character from a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter( .AddParameter(
@@ -86,7 +86,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Repeat a text"), _("Repeat a text"),
_("Repeat a text"), _("Repeat a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text to repeat")) .AddParameter("string", _("Text to repeat"))
.AddParameter("expression", _("Repetition count")); .AddParameter("expression", _("Repetition count"));
@@ -96,7 +96,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Length of a text"), _("Length of a text"),
_("Length of a text"), _("Length of a text"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")); .AddParameter("string", _("Text"));
@@ -106,7 +106,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text (return the position of the result or " _("Search in a text (return the position of the result or "
"-1 if not found)"), "-1 if not found)"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")); .AddParameter("string", _("Text to search for"));
@@ -117,7 +117,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Search in a text from the end (return the position of " "Search in a text from the end (return the position of "
"the result or -1 if not found)", "the result or -1 if not found)",
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")) .AddParameter("string", _("Text to search for"))
@@ -126,12 +126,12 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension extension
.AddExpression( .AddExpression(
"StrFindLast", "StrFindLast",
_("Search the last occurrence in a text"), _("Search the last occurence in a text"),
_("Search the last occurrence in a string (return the position of " _("Search the last occurence in a string (return the position of "
"the result, from the beginning of the string, or -1 if not " "the result, from the beginning of the string, or -1 if not "
"found)"), "found)"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")); .AddParameter("string", _("Text to search for"));
@@ -142,7 +142,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Search in a text, starting from a position (return the " _("Search in a text, starting from a position (return the "
"position of the result or -1 if not found)"), "position of the result or -1 if not found)"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")) .AddParameter("string", _("Text to search for"))
@@ -157,7 +157,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
"Search in a text from the end, starting from a position (return " "Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)", "the position of the result or -1 if not found)",
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")) .AddParameter("string", _("Text to search for"))
@@ -169,13 +169,13 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension extension
.AddExpression( .AddExpression(
"StrFindLastFrom", "StrFindLastFrom",
_("Search the last occurrence in a text, starting from a position"), _("Search the last occurence in a text, starting from a position"),
_("Search in a text the last occurrence, starting from a position " _("Search in a text the last occurence, starting from a position "
"(return " "(return "
"the position of the result, from the beginning of the string, or " " the position of the result, from the beginning of the string, or "
"-1 if not found)"), "-1 if not found)"),
"", "",
"res/conditions/toujours24_black.png") "res/conditions/toujours24.png")
.AddParameter("string", _("Text")) .AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for")) .AddParameter("string", _("Text to search for"))
@@ -183,26 +183,6 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Position of the last character in the string to be " _("Position of the last character in the string to be "
"considered in the search")); "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"));
} }
} // namespace gd } // namespace gd

View File

@@ -21,7 +21,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"Florian Rival", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers-and-time"); .SetExtensionHelpPath("/all-features/timers-and-time");
extension.AddInstructionOrExpressionGroupMetadata(_("Timers and time")) extension.AddInstructionOrExpressionGroupMetadata(
_("Timers and time")
)
.SetIcon("res/conditions/timer24.png"); .SetIcon("res/conditions/timer24.png");
// Deprecated and replaced by CompareTimer // Deprecated and replaced by CompareTimer
@@ -36,7 +38,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/conditions/timer.png") "res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Time in seconds")) .AddParameter("expression", _("Time in seconds"))
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.SetHidden(); .SetHidden();
extension extension
@@ -50,7 +52,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/conditions/timer24.png", "res/conditions/timer24.png",
"res/conditions/timer.png") "res/conditions/timer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.AddParameter("relationalOperator", _("Sign of the test"), "time") .AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds")) .AddParameter("expression", _("Time in seconds"))
.SetManipulatedType("number"); .SetManipulatedType("number");
@@ -65,10 +67,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/conditions/time24.png", "res/conditions/time24.png",
"res/conditions/time.png") "res/conditions/time.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters( .UseStandardRelationalOperatorParameters("number")
"number",
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Time scale (1 by default)")))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -81,7 +80,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/conditions/timerPaused24.png", "res/conditions/timerPaused24.png",
"res/conditions/timerPaused.png") "res/conditions/timerPaused.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -96,7 +95,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/actions/timer24.png", "res/actions/timer24.png",
"res/actions/timer.png") "res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer"); .AddParameter("string", _("Timer's name"));
extension extension
.AddAction("PauseTimer", .AddAction("PauseTimer",
@@ -108,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/actions/pauseTimer24.png", "res/actions/pauseTimer24.png",
"res/actions/pauseTimer.png") "res/actions/pauseTimer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -121,7 +120,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/actions/unPauseTimer24.png", "res/actions/unPauseTimer24.png",
"res/actions/unPauseTimer.png") "res/actions/unPauseTimer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
@@ -134,12 +133,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"res/actions/timer24.png", "res/actions/timer24.png",
"res/actions/timer.png") "res/actions/timer.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer") .AddParameter("string", _("Timer's name"))
.MarkAsAdvanced(); .MarkAsAdvanced();
extension extension
.AddAction("ChangeTimeScale", .AddAction("ChangeTimeScale",
_("Time scale"), _("Change time scale"),
_("Change the time scale of the scene."), _("Change the time scale of the scene."),
_("Set the time scale of the scene to _PARAM1_"), _("Set the time scale of the scene to _PARAM1_"),
"", "",
@@ -151,15 +150,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
extension extension
.AddAction("Wait", .AddAction("Wait",
_("Wait X seconds"), _("Wait X seconds (experimental)"),
_("Waits a number of seconds before running " _("Waits a number of seconds before running "
"the next actions (and sub-events)."), "the next actions (and sub-events)."),
_("Wait _PARAM0_ seconds"), _("Wait _PARAM0_ seconds"),
"", "",
"res/timer_black.svg", "res/timer.svg",
"res/timer_black.svg") "res/timer.svg")
.AddParameter("expression", _("Time to wait in seconds")) .AddParameter("expression", "Time to wait in seconds")
.SetHelpPath("/all-features/timers-and-time/wait-action"); .SetHelpPath("/all-features/timers-and-time/wait-action")
.SetAsync();
extension extension
.AddExpression("TimeDelta", .AddExpression("TimeDelta",
@@ -194,7 +194,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"", "",
"res/actions/time.png") "res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "") .AddCodeOnlyParameter("currentScene", "")
.AddParameter("identifier", _("Timer's name"), "sceneTimer"); .AddParameter("string", _("Timer's name"));
extension extension
.AddExpression("TimeFromStart", .AddExpression("TimeFromStart",

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
"these features can be applied.", "these features can be applied.",
"Florian Rival", "Florian Rival",
"Open source (MIT License)") "Open source (MIT License)")
.SetCategory("User interface")
.SetExtensionHelpPath("/all-features/window"); .SetExtensionHelpPath("/all-features/window");
extension extension
.AddInstructionOrExpressionGroupMetadata( .AddInstructionOrExpressionGroupMetadata(
@@ -56,7 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction("SetWindowMargins", .AddAction("SetWindowMargins",
_("Window's margins"), _("Change the window's margins"),
_("This action changes the margins, in pixels, between the " _("This action changes the margins, in pixels, between the "
"game frame and the window borders."), "game frame and the window borders."),
_("Set margins of game window to " _("Set margins of game window to "
@@ -72,7 +71,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction("SetGameResolutionSize", .AddAction("SetGameResolutionSize",
_("Game resolution"), _("Change the resolution of the game"),
_("Changes the resolution of the game, effectively changing " _("Changes the resolution of the game, effectively changing "
"the game area size. This won't change the size of the " "the game area size. This won't change the size of the "
"window in which the game is running."), "window in which the game is running."),
@@ -87,8 +86,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction( .AddAction(
"SetWindowSize", "SetWindowSize",
_("Game window size"), _("Change the size of the game window"),
_("Changes the size of the game window. Note that this " _("This action changes the size of the game window. Note that this "
"will only work on platform supporting this operation: games " "will only work on platform supporting this operation: games "
"running in browsers or on mobile phones can not update their " "running in browsers or on mobile phones can not update their "
"window size. Game resolution can still be updated."), "window size. Game resolution can still be updated."),
@@ -118,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction("SetGameResolutionResizeMode", .AddAction("SetGameResolutionResizeMode",
_("Game resolution resize mode"), _("Change the game resolution resize mode"),
_("Set if the width or the height of the game resolution " _("Set if the width or the height of the game resolution "
"should be changed to fit the game window - or if the game " "should be changed to fit the game window - or if the game "
"resolution should not be updated automatically."), "resolution should not be updated automatically."),
@@ -154,7 +153,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction("SetWindowIcon", .AddAction("SetWindowIcon",
_("Window's icon"), _("Change the window's icon"),
_("This action changes the icon of the game's window."), _("This action changes the icon of the game's window."),
_("Use _PARAM1_ as the icon for the game's window."), _("Use _PARAM1_ as the icon for the game's window."),
"", "",
@@ -165,7 +164,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
extension extension
.AddAction("SetWindowTitle", .AddAction("SetWindowTitle",
_("Window's title"), _("Change the window's title"),
_("This action changes the title of the game's window."), _("This action changes the title of the game's window."),
_("Change window title to _PARAM1_"), _("Change window title to _PARAM1_"),
"", "",

View File

@@ -1,137 +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 <algorithm>
#include <functional>
#include <map>
#include <memory>
#include "GDCore/Events/Instruction.h"
#include "GDCore/String.h"
#include "ParameterMetadata.h"
#include "ParameterOptions.h"
namespace gd {
class Project;
class Layout;
class EventsCodeGenerator;
class EventsCodeGenerationContext;
class SerializerElement;
} // namespace gd
namespace gd {
/**
* \brief Describe user-friendly information about an expression or an
* instruction (action or condition), its parameters and the function name as
* well as other information for code generation.
*
* \ingroup Events
*/
class GD_CORE_API AbstractFunctionMetadata {
public:
AbstractFunctionMetadata(){};
virtual ~AbstractFunctionMetadata(){};
/**
* \see gd::InstructionMetadata::AddParameter
*/
virtual AbstractFunctionMetadata &
AddParameter(const gd::String &type, const gd::String &label,
const gd::String &supplementaryInformation = "",
bool parameterIsOptional = false) = 0;
/**
* \see gd::InstructionMetadata::AddCodeOnlyParameter
*/
virtual AbstractFunctionMetadata &
AddCodeOnlyParameter(const gd::String &type,
const gd::String &supplementaryInformation) = 0;
/**
* \see gd::InstructionMetadata::SetDefaultValue
*/
virtual AbstractFunctionMetadata &
SetDefaultValue(const gd::String &defaultValue) = 0;
/**
* \see gd::InstructionMetadata::SetParameterExtraInfo
*/
virtual AbstractFunctionMetadata &
SetParameterExtraInfo(const gd::String &defaultValue) = 0;
/**
* \see gd::InstructionMetadata::SetParameterLongDescription
*/
virtual AbstractFunctionMetadata &
SetParameterLongDescription(const gd::String &longDescription) = 0;
/**
* \see gd::InstructionMetadata::SetHidden
*/
virtual AbstractFunctionMetadata &SetHidden() = 0;
/**
* Set that the instruction is private - it can't be used outside of the
* object/ behavior that it is attached too.
*/
virtual AbstractFunctionMetadata &SetPrivate() = 0;
/**
* Set that the instruction can be used in layouts or external events.
*/
virtual AbstractFunctionMetadata &SetRelevantForLayoutEventsOnly() = 0;
/**
* Set that the instruction can be used in function events.
*/
virtual AbstractFunctionMetadata &SetRelevantForFunctionEventsOnly() = 0;
/**
* Set that the instruction can be used in asynchronous function events.
*/
virtual AbstractFunctionMetadata &
SetRelevantForAsynchronousFunctionEventsOnly() = 0;
/**
* Set that the instruction can be used in custom object events.
*/
virtual AbstractFunctionMetadata &SetRelevantForCustomObjectEventsOnly() = 0;
/**
* \brief Set the function that should be called when generating the source
* code from events.
* \param functionName the name of the function to call
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
*/
virtual AbstractFunctionMetadata &
SetFunctionName(const gd::String &functionName) = 0;
/**
* \brief Erase any existing include file and add the specified include.
* \deprecated Use `AddIncludeFile` instead as clearing the list is more
* error prone.
*/
virtual AbstractFunctionMetadata &
SetIncludeFile(const gd::String &includeFile) = 0;
/**
* \brief Add a file to the already existing include files.
*/
virtual AbstractFunctionMetadata &
AddIncludeFile(const gd::String &includeFile) = 0;
/**
* \brief Get the files that must be included to use the instruction.
*/
virtual const std::vector<gd::String> &GetIncludeFiles() const = 0;
private:
};
} // namespace gd

View File

@@ -13,18 +13,13 @@
#include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Behavior.h" #include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h" #include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/Tools/Localization.h" #include "GDCore/Tools/Localization.h"
#include "GDCore/Tools/MakeUnique.h"
#include "GDCore/Tools/Log.h"
namespace gd { namespace gd {
const std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::badProperties;
BehaviorMetadata::BehaviorMetadata( BehaviorMetadata::BehaviorMetadata(
const gd::String& extensionNamespace_, const gd::String& extensionNamespace_,
const gd::String& nameWithNamespace, const gd::String& name_,
const gd::String& fullname_, const gd::String& fullname_,
const gd::String& defaultName_, const gd::String& defaultName_,
const gd::String& description_, const gd::String& description_,
@@ -34,30 +29,19 @@ BehaviorMetadata::BehaviorMetadata(
std::shared_ptr<gd::Behavior> instance_, std::shared_ptr<gd::Behavior> instance_,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance_) std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance_)
: extensionNamespace(extensionNamespace_), : extensionNamespace(extensionNamespace_),
className(className_),
iconFilename(icon24x24),
instance(instance_), instance(instance_),
sharedDatasInstance(sharedDatasInstance_) { sharedDatasInstance(sharedDatasInstance_) {
#if defined(GD_IDE_ONLY)
SetFullName(gd::String(fullname_)); SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_)); SetDescription(gd::String(description_));
SetDefaultName(gd::String(defaultName_)); SetDefaultName(gd::String(defaultName_));
SetGroup(group_); SetGroup(group_);
className = className_;
iconFilename = icon24x24;
#endif
if (!instance) { if (instance) instance->SetTypeName(name_);
gd::LogFatalError( if (sharedDatasInstance) sharedDatasInstance->SetTypeName(name_);
"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);
instance->InitializeContent();
}
if (sharedDatasInstance) {
sharedDatasInstance->SetTypeName(nameWithNamespace);
sharedDatasInstance->InitializeContent();
}
} }
gd::InstructionMetadata& BehaviorMetadata::AddCondition( gd::InstructionMetadata& BehaviorMetadata::AddCondition(
@@ -68,6 +52,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
const gd::String& group, const gd::String& group,
const gd::String& icon, const gd::String& icon,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace = gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name; extensionNamespace.empty() ? name : extensionNamespace + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace, conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -81,6 +66,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddCondition(
.SetHelpPath(GetHelpPath()) .SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction(); .SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace]; return conditionsInfos[nameWithNamespace];
#endif
} }
gd::InstructionMetadata& BehaviorMetadata::AddAction( gd::InstructionMetadata& BehaviorMetadata::AddAction(
@@ -91,6 +77,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
const gd::String& group, const gd::String& group,
const gd::String& icon, const gd::String& icon,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace = gd::String nameWithNamespace =
extensionNamespace.empty() ? name : extensionNamespace + name; extensionNamespace.empty() ? name : extensionNamespace + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace, actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -104,6 +91,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddAction(
.SetHelpPath(GetHelpPath()) .SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction(); .SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace]; return actionsInfos[nameWithNamespace];
#endif
} }
gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition( gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
@@ -114,6 +102,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
const gd::String& group, const gd::String& group,
const gd::String& icon, const gd::String& icon,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace = gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name; GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace, conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -127,6 +116,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedCondition(
.SetHelpPath(GetHelpPath()) .SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction(); .SetIsBehaviorInstruction();
return conditionsInfos[nameWithNamespace]; return conditionsInfos[nameWithNamespace];
#endif
} }
gd::InstructionMetadata& BehaviorMetadata::AddScopedAction( gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
@@ -137,6 +127,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
const gd::String& group, const gd::String& group,
const gd::String& icon, const gd::String& icon,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace = gd::String nameWithNamespace =
GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name; GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace, actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
@@ -150,6 +141,7 @@ gd::InstructionMetadata& BehaviorMetadata::AddScopedAction(
.SetHelpPath(GetHelpPath()) .SetHelpPath(GetHelpPath())
.SetIsBehaviorInstruction(); .SetIsBehaviorInstruction();
return actionsInfos[nameWithNamespace]; return actionsInfos[nameWithNamespace];
#endif
} }
gd::ExpressionMetadata& BehaviorMetadata::AddExpression( gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
@@ -158,6 +150,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
const gd::String& description, const gd::String& description,
const gd::String& group, const gd::String& group,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as // Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression). // we refer to the behavior name in the expression).
expressionsInfos[name] = ExpressionMetadata("number", expressionsInfos[name] = ExpressionMetadata("number",
@@ -169,6 +162,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
smallicon) smallicon)
.SetHelpPath(GetHelpPath()); .SetHelpPath(GetHelpPath());
return expressionsInfos[name]; return expressionsInfos[name];
#endif
} }
gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression( gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
@@ -177,6 +171,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
const gd::String& description, const gd::String& description,
const gd::String& group, const gd::String& group,
const gd::String& smallicon) { const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace (not necessary as // Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression). // we refer to the behavior name in the expression).
strExpressionsInfos[name] = ExpressionMetadata("string", strExpressionsInfos[name] = ExpressionMetadata("string",
@@ -188,6 +183,7 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
smallicon) smallicon)
.SetHelpPath(GetHelpPath()); .SetHelpPath(GetHelpPath());
return strExpressionsInfos[name]; return strExpressionsInfos[name];
#endif
} }
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition( gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
@@ -292,6 +288,7 @@ BehaviorMetadata::AddExpressionAndConditionAndAction(
expression, condition, action); expression, condition, action);
} }
#if defined(GD_IDE_ONLY)
gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction( gd::InstructionMetadata& BehaviorMetadata::AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName) { const gd::String& newActionName, const gd::String& copiedActionName) {
gd::String newNameWithNamespace = extensionNamespace + newActionName; gd::String newNameWithNamespace = extensionNamespace + newActionName;
@@ -359,44 +356,49 @@ gd::ExpressionMetadata& BehaviorMetadata::AddDuplicatedStrExpression(
return strExpressionsInfos[newNameWithNamespace]; return strExpressionsInfos[newNameWithNamespace];
} }
#endif
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) { BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_; fullname = fullname_;
#endif
return *this; return *this;
} }
BehaviorMetadata& BehaviorMetadata::SetDefaultName( BehaviorMetadata& BehaviorMetadata::SetDefaultName(
const gd::String& defaultName_) { const gd::String& defaultName_) {
#if defined(GD_IDE_ONLY)
defaultName = defaultName_; defaultName = defaultName_;
#endif
return *this; return *this;
} }
BehaviorMetadata& BehaviorMetadata::SetDescription( BehaviorMetadata& BehaviorMetadata::SetDescription(
const gd::String& description_) { const gd::String& description_) {
#if defined(GD_IDE_ONLY)
description = description_; description = description_;
#endif
return *this; return *this;
} }
BehaviorMetadata& BehaviorMetadata::SetGroup(const gd::String& group_) { BehaviorMetadata& BehaviorMetadata::SetGroup(const gd::String& group_) {
#if defined(GD_IDE_ONLY)
group = group_; group = group_;
#endif
return *this; return *this;
} }
BehaviorMetadata& BehaviorMetadata::SetIncludeFile( BehaviorMetadata& BehaviorMetadata::SetIncludeFile(
const gd::String& includeFile) { const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
includeFiles.clear(); includeFiles.clear();
includeFiles.push_back(includeFile); includeFiles.push_back(includeFile);
#endif
return *this; return *this;
} }
BehaviorMetadata& BehaviorMetadata::AddIncludeFile( BehaviorMetadata& BehaviorMetadata::AddIncludeFile(
const gd::String& includeFile) { const gd::String& includeFile) {
#if defined(GD_IDE_ONLY)
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) == if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
includeFiles.end()) includeFiles.end())
includeFiles.push_back(includeFile); includeFiles.push_back(includeFile);
return *this; #endif
}
BehaviorMetadata& BehaviorMetadata::AddRequiredFile(
const gd::String& requiredFile) {
if (std::find(requiredFiles.begin(), requiredFiles.end(), requiredFile) ==
requiredFiles.end())
requiredFiles.push_back(requiredFile);
return *this; return *this;
} }
@@ -405,50 +407,13 @@ const gd::String& BehaviorMetadata::GetName() const {
} }
gd::Behavior& BehaviorMetadata::Get() const { gd::Behavior& BehaviorMetadata::Get() const {
if (!instance) { if (!instance)
gd::LogFatalError( gd::LogFatalError(
"Trying to get a behavior from a BehaviorMetadata that has no " "Trying to get a behavior from a BehaviorMetadata that has no "
"behavior. This will crash - please double check that the " "behavior. This will crash - please double check that the "
"BehaviorMetadata is valid for: " + className); "BehaviorMetadata is valid.");
}
return *instance; return *instance;
} }
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetProperties() const {
if (!instance) {
return badProperties;
}
// TODO Properties should be declared on BehaviorMetadata directly.
// - Add 2 `properties` members (one for shared properties)
// - Add methods to declare new properties
return instance->GetProperties();
}
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
return sharedDatasInstance.get();
}
std::map<gd::String, gd::PropertyDescriptor> BehaviorMetadata::GetSharedProperties() const {
if (!sharedDatasInstance) {
return badProperties;
}
// TODO Properties should be declared on BehaviorMetadata directly.
// - Add 2 `properties` members (one for shared properties)
// - Add methods to declare new properties
return sharedDatasInstance->GetProperties();
}
const std::vector<gd::String>& BehaviorMetadata::GetRequiredBehaviorTypes() const {
requiredBehaviors.clear();
for (auto& property : Get().GetProperties()) {
const String& propertyName = property.first;
const gd::PropertyDescriptor& propertyDescriptor = property.second;
if (propertyDescriptor.GetType() == "Behavior") {
requiredBehaviors.push_back(propertyDescriptor.GetExtraInfo()[0]);
}
}
return requiredBehaviors;
}
} // namespace gd } // namespace gd

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