mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
383 Commits
show-small
...
v5.2.172
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7d19b811e4 | ||
![]() |
17b3579e5b | ||
![]() |
afa8d4f7f6 | ||
![]() |
b262cb4c3e | ||
![]() |
1c69302c02 | ||
![]() |
5ba36916c6 | ||
![]() |
7f3e2b210a | ||
![]() |
f83df15817 | ||
![]() |
40639f5578 | ||
![]() |
f07e3bfe19 | ||
![]() |
ef9a82ee33 | ||
![]() |
e916662ad4 | ||
![]() |
d7ca46455e | ||
![]() |
d193b9375e | ||
![]() |
90b830853a | ||
![]() |
f6b4cab966 | ||
![]() |
0ebec6fa02 | ||
![]() |
ab2b46adad | ||
![]() |
29fedf2efb | ||
![]() |
c0cd196a74 | ||
![]() |
18e8020bf5 | ||
![]() |
2ac85dff02 | ||
![]() |
5919c4ae20 | ||
![]() |
de12838b3f | ||
![]() |
b55f56dbd6 | ||
![]() |
c8eed6e472 | ||
![]() |
7a360b07f6 | ||
![]() |
f86fcf4190 | ||
![]() |
e4cbdd4f45 | ||
![]() |
4b5448cf00 | ||
![]() |
72e7949faf | ||
![]() |
63f9f40e3d | ||
![]() |
dfbb3515cb | ||
![]() |
7985be10cd | ||
![]() |
6de8324943 | ||
![]() |
79a14e220d | ||
![]() |
4575935a42 | ||
![]() |
134886eedc | ||
![]() |
da308bb104 | ||
![]() |
5087526066 | ||
![]() |
b6f98ad667 | ||
![]() |
b4a6b73146 | ||
![]() |
2ccdc1aad8 | ||
![]() |
68f13297ef | ||
![]() |
6a26e2cf32 | ||
![]() |
9532a42558 | ||
![]() |
f23bc5dfd9 | ||
![]() |
4a4bf6d761 | ||
![]() |
68968b603a | ||
![]() |
eb723b2a0e | ||
![]() |
c51e6fa04e | ||
![]() |
a0ad9200cf | ||
![]() |
99804f366a | ||
![]() |
71fead702d | ||
![]() |
54c9177b03 | ||
![]() |
8157d3c9db | ||
![]() |
03e0da8619 | ||
![]() |
be84b2153f | ||
![]() |
10591a41e6 | ||
![]() |
d41cc18be2 | ||
![]() |
fb6e09d0e3 | ||
![]() |
8766f73333 | ||
![]() |
b32a9006c6 | ||
![]() |
2d613e7281 | ||
![]() |
ca220d8fe5 | ||
![]() |
9971702ec9 | ||
![]() |
e48f14b753 | ||
![]() |
ce046c0b99 | ||
![]() |
e29cb462e1 | ||
![]() |
aee05affd0 | ||
![]() |
f95d197634 | ||
![]() |
075cc5a7aa | ||
![]() |
56c2aa0dc6 | ||
![]() |
fa003374ba | ||
![]() |
ca27a946a1 | ||
![]() |
2845c403f9 | ||
![]() |
9cc2e2987e | ||
![]() |
b9d6336dc7 | ||
![]() |
c2ad00ed6c | ||
![]() |
2d1845f0b8 | ||
![]() |
b5f0758f4d | ||
![]() |
1e2ffe5d15 | ||
![]() |
c887769c0a | ||
![]() |
dc1ac1e094 | ||
![]() |
4b1ceeb642 | ||
![]() |
e5d92fbf43 | ||
![]() |
c323fea5bd | ||
![]() |
32f0fe9051 | ||
![]() |
be74d3efa6 | ||
![]() |
8969c9af8c | ||
![]() |
15cac278d6 | ||
![]() |
9e8a15547d | ||
![]() |
ed74a49aa3 | ||
![]() |
6ef5d0c326 | ||
![]() |
5f871e2643 | ||
![]() |
4f65fa0d82 | ||
![]() |
4d1d763bd9 | ||
![]() |
3286722b6a | ||
![]() |
656255a662 | ||
![]() |
ea7b7a778e | ||
![]() |
9b6de5affd | ||
![]() |
0c03659314 | ||
![]() |
6b08c0f033 | ||
![]() |
a1dcf03a5b | ||
![]() |
556d13c881 | ||
![]() |
0d6c42a9bf | ||
![]() |
690ce16ab4 | ||
![]() |
5f51a5e465 | ||
![]() |
b7521de138 | ||
![]() |
acea6fc595 | ||
![]() |
d8107fe3d5 | ||
![]() |
b40b95be99 | ||
![]() |
6644525dd0 | ||
![]() |
56e66d1c5a | ||
![]() |
90d8afb5a0 | ||
![]() |
d4db61a595 | ||
![]() |
90413b842d | ||
![]() |
43c788acbf | ||
![]() |
ee22b2e4b1 | ||
![]() |
007d56e946 | ||
![]() |
577c4adb14 | ||
![]() |
7f17720ff3 | ||
![]() |
288db1c941 | ||
![]() |
2496fc3eef | ||
![]() |
b43d5ec425 | ||
![]() |
3c43f28966 | ||
![]() |
a3f7c5782e | ||
![]() |
8dec6dfa28 | ||
![]() |
4eb49bdeb2 | ||
![]() |
813cadbd6e | ||
![]() |
58dd2c1a7b | ||
![]() |
104c27ebc8 | ||
![]() |
318099504c | ||
![]() |
8851be03a3 | ||
![]() |
a9a126ab0d | ||
![]() |
19e46fedc8 | ||
![]() |
ff987a0751 | ||
![]() |
0c0ab65b1a | ||
![]() |
52a5908d7e | ||
![]() |
49926a89a2 | ||
![]() |
b63b91f33d | ||
![]() |
67ea361416 | ||
![]() |
3b9078c6b3 | ||
![]() |
3d9e3f997e | ||
![]() |
3c34866faa | ||
![]() |
69cd2784c4 | ||
![]() |
5b7e419a41 | ||
![]() |
7773460d35 | ||
![]() |
9262266480 | ||
![]() |
84f2b4ca68 | ||
![]() |
19ae7a378c | ||
![]() |
f9ca330add | ||
![]() |
5ef990ac7d | ||
![]() |
8099820729 | ||
![]() |
df556f20e9 | ||
![]() |
2c8f2ab58d | ||
![]() |
20c3d62c90 | ||
![]() |
0a28981c74 | ||
![]() |
c8bb24475c | ||
![]() |
81bce61783 | ||
![]() |
71d1b6aa1f | ||
![]() |
c41974c24b | ||
![]() |
3bee88c6cd | ||
![]() |
4c874dfb7e | ||
![]() |
65f499f24e | ||
![]() |
3265bf7fb4 | ||
![]() |
5a437dea4e | ||
![]() |
19b576e8cc | ||
![]() |
67747e458e | ||
![]() |
260c2b9c8f | ||
![]() |
255ef1d8ef | ||
![]() |
53c633c646 | ||
![]() |
cec67a91d4 | ||
![]() |
4408dfe59d | ||
![]() |
c4274d2fc4 | ||
![]() |
b0103f31b7 | ||
![]() |
18905890d4 | ||
![]() |
6858e0fb59 | ||
![]() |
cf595a7d7d | ||
![]() |
e681d27bb8 | ||
![]() |
8941e04390 | ||
![]() |
e186681f39 | ||
![]() |
a578fa32e9 | ||
![]() |
6b40e8309c | ||
![]() |
5ff51351af | ||
![]() |
d66e4e0001 | ||
![]() |
2184eaf70b | ||
![]() |
29fc0598f6 | ||
![]() |
a7760e975a | ||
![]() |
e2397cb0a4 | ||
![]() |
24ff670886 | ||
![]() |
d24b7497c9 | ||
![]() |
0ecaa342f9 | ||
![]() |
141ac87c6e | ||
![]() |
057e6dcfed | ||
![]() |
9c69c90a66 | ||
![]() |
4df6ecc654 | ||
![]() |
c106d05098 | ||
![]() |
f3f426e949 | ||
![]() |
52d0ed1217 | ||
![]() |
511138269d | ||
![]() |
22dda6194c | ||
![]() |
aa2ef39f32 | ||
![]() |
a744b88c5c | ||
![]() |
2847601fc5 | ||
![]() |
bfbdf1cd3f | ||
![]() |
ed1694a818 | ||
![]() |
0ee121c014 | ||
![]() |
312e96a881 | ||
![]() |
c169c5037a | ||
![]() |
a82ae304a0 | ||
![]() |
adb30c5105 | ||
![]() |
aad11f2518 | ||
![]() |
737d389493 | ||
![]() |
4b071fbf17 | ||
![]() |
982a0c6e53 | ||
![]() |
91adaac722 | ||
![]() |
138a7c9abe | ||
![]() |
c7099d694e | ||
![]() |
fde1039707 | ||
![]() |
73e087936a | ||
![]() |
260fd5949e | ||
![]() |
a4939181a5 | ||
![]() |
cab56451ff | ||
![]() |
7b32bbacd6 | ||
![]() |
a15707d655 | ||
![]() |
714a9f1198 | ||
![]() |
2a91c54b0e | ||
![]() |
3272b8eda7 | ||
![]() |
cd432a22b6 | ||
![]() |
9ac483156e | ||
![]() |
d0f39027af | ||
![]() |
5d8a59533d | ||
![]() |
243a72008b | ||
![]() |
e56cdac96a | ||
![]() |
cf374737fc | ||
![]() |
3d043f5264 | ||
![]() |
032f53e4e3 | ||
![]() |
f68ae4b8d8 | ||
![]() |
fa40381fb4 | ||
![]() |
544b6243ba | ||
![]() |
0a03cbb89c | ||
![]() |
c00d75f047 | ||
![]() |
5dce0684f5 | ||
![]() |
cb44999538 | ||
![]() |
4a9de2edf3 | ||
![]() |
8c3728f8b7 | ||
![]() |
212c58f67c | ||
![]() |
f5d89c66ea | ||
![]() |
8fb139ff63 | ||
![]() |
0c0fb5da1c | ||
![]() |
65a33589c0 | ||
![]() |
7ec5a95de8 | ||
![]() |
26289eec99 | ||
![]() |
cc0a01bbdb | ||
![]() |
a0fb289aaf | ||
![]() |
94045aec91 | ||
![]() |
b70d4c54c1 | ||
![]() |
f269b820fc | ||
![]() |
f91bde1fca | ||
![]() |
73ac71dadf | ||
![]() |
52fcf52ecc | ||
![]() |
55c7c4e8bf | ||
![]() |
d6a15d4090 | ||
![]() |
21a87daf64 | ||
![]() |
c712ab3163 | ||
![]() |
6c27c3dcf8 | ||
![]() |
f8de6c2ea9 | ||
![]() |
b2e8c23944 | ||
![]() |
bfc6a69d77 | ||
![]() |
3abf81fda2 | ||
![]() |
4caef9c7e6 | ||
![]() |
f9edfdef72 | ||
![]() |
4e0e4b9184 | ||
![]() |
908926bf73 | ||
![]() |
2ba81cc7d6 | ||
![]() |
e77e1fb840 | ||
![]() |
f0f47ca2f0 | ||
![]() |
07920fda9f | ||
![]() |
48e4447212 | ||
![]() |
b69dcafcc6 | ||
![]() |
89e06b0801 | ||
![]() |
5e1a6eb084 | ||
![]() |
f89a48fb2c | ||
![]() |
ddb65012ce | ||
![]() |
bb0fe0ea37 | ||
![]() |
747cdf0243 | ||
![]() |
385ec5e9ca | ||
![]() |
bcbdc35d72 | ||
![]() |
6053369474 | ||
![]() |
ed1e0852b5 | ||
![]() |
23ce46439a | ||
![]() |
d9b35018e7 | ||
![]() |
571ab1313d | ||
![]() |
aff82c4733 | ||
![]() |
2d4fc0af07 | ||
![]() |
7cadf35642 | ||
![]() |
73e1ea5ff1 | ||
![]() |
bc87caf640 | ||
![]() |
95dfb391c4 | ||
![]() |
4b973c9655 | ||
![]() |
23f24a3939 | ||
![]() |
b3ed22806b | ||
![]() |
4afefafc76 | ||
![]() |
d2a1d8620f | ||
![]() |
fdfc028a2c | ||
![]() |
48cd42fee0 | ||
![]() |
b215eff444 | ||
![]() |
1bf66a97ae | ||
![]() |
cc6890a495 | ||
![]() |
418dd834c0 | ||
![]() |
e52faae332 | ||
![]() |
31809fdf61 | ||
![]() |
17504c1713 | ||
![]() |
e29b79fdc9 | ||
![]() |
b0009cc999 | ||
![]() |
384eb2b8ee | ||
![]() |
5fa0627218 | ||
![]() |
e66660d2df | ||
![]() |
df6320c39f | ||
![]() |
ca667c02be | ||
![]() |
62d0754b33 | ||
![]() |
4c4ca0d202 | ||
![]() |
5c68d117c6 | ||
![]() |
21b9ae47ab | ||
![]() |
e8687119c9 | ||
![]() |
9c09e26aaa | ||
![]() |
c223abad60 | ||
![]() |
769de55317 | ||
![]() |
0dfe765ae1 | ||
![]() |
b94ce2b20d | ||
![]() |
89eb61b4a6 | ||
![]() |
32ba55e726 | ||
![]() |
844ac23666 | ||
![]() |
657036384d | ||
![]() |
b13ce5b17c | ||
![]() |
8f0f5a5bc5 | ||
![]() |
d23a064ca2 | ||
![]() |
3b0dc66046 | ||
![]() |
356bde650b | ||
![]() |
6d25496f89 | ||
![]() |
dfeeb864a5 | ||
![]() |
25c36d26db | ||
![]() |
36721c63e0 | ||
![]() |
69cd89ddb8 | ||
![]() |
2db4b54986 | ||
![]() |
303a4d20ed | ||
![]() |
a09bfafd26 | ||
![]() |
822329af63 | ||
![]() |
0b90e17307 | ||
![]() |
00817b4393 | ||
![]() |
2a5bbcb8d4 | ||
![]() |
7f03579855 | ||
![]() |
c7e42d1e88 | ||
![]() |
e3fd91681c | ||
![]() |
c8392332c7 | ||
![]() |
14d7dafb79 | ||
![]() |
373d5e14b8 | ||
![]() |
8b89896082 | ||
![]() |
e7d213534e | ||
![]() |
859b1d0a1c | ||
![]() |
2b6a14c612 | ||
![]() |
07051017b9 | ||
![]() |
0d5f238c75 | ||
![]() |
936c75b4ed | ||
![]() |
8d1bdfed25 | ||
![]() |
440205531f | ||
![]() |
8f45642a25 | ||
![]() |
1e6ca8c403 | ||
![]() |
113e329d7a | ||
![]() |
48ae688873 | ||
![]() |
fe77180748 | ||
![]() |
48b88b9d92 | ||
![]() |
f57a8bc6cd | ||
![]() |
1b827eb67b | ||
![]() |
c3521db5ba | ||
![]() |
b51e47233e | ||
![]() |
1bf9d3c432 | ||
![]() |
1c47d12033 | ||
![]() |
1250060848 | ||
![]() |
4712c3d9ef | ||
![]() |
56cf1cf18f | ||
![]() |
0427766b9d |
@@ -15,7 +15,7 @@ jobs:
|
||||
# Build the **entire** app for macOS.
|
||||
build-macos:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
xcode: 14.2.0
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
@@ -64,11 +64,11 @@ jobs:
|
||||
# Note: Code signing is done using CSC_LINK (see https://www.electron.build/code-signing).
|
||||
- run:
|
||||
name: Build GDevelop IDE
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac --publish=never
|
||||
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && CI=false npm run build -- --mac --publish=never
|
||||
|
||||
- run:
|
||||
name: Clean dist folder to keep only installers/binaries.
|
||||
command: rm -rf "newIDE/electron-app/dist/mac/GDevelop 5.app" && rm -rf "newIDE/electron-app/dist/mac-arm64/GDevelop 5.app"
|
||||
command: rm -rf "newIDE/electron-app/dist/mac-universal/GDevelop 5.app"
|
||||
|
||||
# Upload artifacts (CircleCI)
|
||||
- store_artifacts:
|
||||
@@ -101,8 +101,8 @@ jobs:
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
@@ -178,8 +178,8 @@ jobs:
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
|
@@ -1,6 +0,0 @@
|
||||
# This is the Dockerfile to create a "devcontainer".
|
||||
# This is a way to quickly create a development environment,
|
||||
# that can be used with GitHub workspaces.
|
||||
|
||||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux/.devcontainer/base.Dockerfile
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/universal:1-focal
|
@@ -1,16 +0,0 @@
|
||||
# Devcontainer (development environment in the cloud) for GDevelop (beta)
|
||||
|
||||
A devcontainer is the configuration to run a cloud development environment, available remotely.
|
||||
This is notably used to run a **[GitHub Codespace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces)**. The advantage is that you can quickly experiment and do changes without installing anything on your computer.
|
||||
|
||||
> ⚠️ This development environment is in beta, and not everything is supported. This is useful for playing a bit with GDevelop codebase or to make quick changes. **In particular, it's not possible to test your changes on GDJS** because only the web-app can be launched.
|
||||
|
||||
It's recommended that you follow the usual [README](../newIDE/README.md) to get started, with development tools installed on your computer.
|
||||
|
||||
## Start a GitHub workspace to work on GDevelop (beta)
|
||||
|
||||
- Subscribe to the [beta edition of GitHub workspace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces#joining-the-beta).
|
||||
- In the repository GitHub page, click **Code** and then choose **Open with Codespaces**.
|
||||
- Wait for the Codespace to load and Visual Studio Code to open.
|
||||
- When it's ready, open a terminal in Visual Studio Code.
|
||||
- Follow the usual [README in `newIDE`](../newIDE/README.md) to get started, like you would do on your own computer.
|
@@ -1,51 +1,14 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux
|
||||
{
|
||||
"name": "GitHub Codespaces for GDevelop",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/zsh",
|
||||
"go.toolsManagement.checkForUpdates": "off",
|
||||
"go.useLanguageServer": true,
|
||||
"go.gopath": "/go",
|
||||
"go.goroot": "/usr/local/go",
|
||||
"python.pythonPath": "/opt/python/latest/bin/python",
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
|
||||
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
|
||||
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
|
||||
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
|
||||
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
|
||||
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
|
||||
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
|
||||
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
|
||||
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
|
||||
"lldb.executable": "/usr/bin/lldb",
|
||||
"files.watcherExclude": {
|
||||
"**/target/**": true
|
||||
}
|
||||
},
|
||||
"remoteUser": "codespace",
|
||||
"overrideCommand": false,
|
||||
"workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached",
|
||||
"workspaceFolder": "/home/codespace/workspace",
|
||||
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--privileged", "--init" ],
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"GitHub.vscode-pull-request-github",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-vscode.cpptools",
|
||||
"xaver.clang-format",
|
||||
"flowtype.flow-for-vscode"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// "oryx build" will automatically install your dependencies and attempt to build your project
|
||||
"postCreateCommand": "oryx build -p virtualenv_name=.venv || echo 'Could not auto-build. Skipping.'"
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
||||
"onCreateCommand": "cd newIDE/app && npm install && cd ../electron-app && npm install",
|
||||
"forwardPorts": [3000],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-vscode.cpptools",
|
||||
"flowtype.flow-for-vscode"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
28
.github/ISSUE_TEMPLATE/--bug-report.md
vendored
@@ -1,28 +0,0 @@
|
||||
---
|
||||
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.
|
71
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
Normal file
71
.github/ISSUE_TEMPLATE/--bug-report.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: 🐛Bug report
|
||||
description: Create a bug report about GDevelop or the game engine
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
options:
|
||||
- label: I have searched the [existing issues](https://github.com/4ian/GDevelop/issues)
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: |
|
||||
* Please include a link to a game if possible!
|
||||
* If applicable, add screenshots to help explain your problem.
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: GDevelop platform
|
||||
description: Which platform of GDevelop are you using?
|
||||
multiple: true
|
||||
options:
|
||||
- Desktop
|
||||
- Web
|
||||
- Mobile
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: GDevelop version
|
||||
description: |
|
||||
Which version of GDevelop are you using?
|
||||
Take a look here: [Editor Home - About GDevelop - "This version of GDevelop is: ~~~"]
|
||||
placeholder: 5.1.159? 5.1.160?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Platform info
|
||||
value: |
|
||||
<details>
|
||||
|
||||
*OS (e.g. Windows, Linux, macOS, Android, iOS)*
|
||||
>
|
||||
|
||||
*OS Version (e.g. Windows 10, macOS 10.15)*
|
||||
>
|
||||
|
||||
*Browser(For Web) (e.g. Chrome, Firefox, Safari)*
|
||||
>
|
||||
|
||||
*Device(For Mobile) (e.g. iPhone 12, Samsung Galaxy S21)*
|
||||
>
|
||||
|
||||
</details>
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context about the problem here.
|
26
.github/workflows/build-storybook.yml
vendored
26
.github/workflows/build-storybook.yml
vendored
@@ -9,6 +9,10 @@ name: Build Storybook
|
||||
on:
|
||||
# Launch on all commits.
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab,
|
||||
# to publish on Chromatic (not done by default).
|
||||
workflow_dispatch:
|
||||
@@ -17,31 +21,23 @@ jobs:
|
||||
build-storybook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
uses: aws-actions/configure-aws-credentials@v2
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
18
.github/workflows/extract-translations.yml
vendored
18
.github/workflows/extract-translations.yml
vendored
@@ -4,6 +4,10 @@ name: Extract translations
|
||||
on:
|
||||
# Execute for all commits (to ensure translations extraction works)
|
||||
push:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -11,20 +15,12 @@ jobs:
|
||||
extract-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
42
.github/workflows/issues.yml
vendored
42
.github/workflows/issues.yml
vendored
@@ -3,41 +3,17 @@ on:
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Autoclose issues about adding a bug without changing the bug report template
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop.io/), the Discord chat or [read the documentation](https://wiki.gdevelop.io/gdevelop5/start) to learn more about GDevelop. Thanks!"
|
||||
- name: Autoclose known beta 105 web-app update bug
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*_instance.getRawFloatProperty is not a function.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
|
||||
- name: Autoclose known beta 114 web-app update bug
|
||||
uses: arkon/issue-closer-action@v1.1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
type: "body"
|
||||
regex: ".*getAssociatedSettings is not a function.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
|
||||
autocomment:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
|
||||
steps:
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
||||
|
68
.github/workflows/pull-requests.yml
vendored
68
.github/workflows/pull-requests.yml
vendored
@@ -1,29 +1,53 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
jobs:
|
||||
read-locales-metadata:
|
||||
if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
|
||||
if: github.event.pull_request.title == '[Auto PR] Update translations'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
COMMENT_TITLE: "Translation ratio changes"
|
||||
steps:
|
||||
- name: Read and format locales metadata
|
||||
run: |
|
||||
LANS=($(git diff HEAD^ HEAD --unified=5 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.txt
|
||||
for index in ${!ADDS[@]}; do
|
||||
echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
|
||||
DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
|
||||
echo $DELTA % >> sumup.txt
|
||||
done
|
||||
- name: Store sumup in outputs
|
||||
id: sumup
|
||||
run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
body: ${{ steps.sumup.outputs.sumupFileContent}}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Read and format locales metadata
|
||||
env:
|
||||
BASE: ${{ github.event.pull_request.base.sha }}
|
||||
HEAD: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
LANS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff $BASE...$HEAD -- newIDE/app/src/locales/LocalesMetadata.js | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.md
|
||||
echo "## $COMMENT_TITLE" >> sumup.md
|
||||
echo "" >> sumup.md
|
||||
echo "| Language | Change |" >> sumup.md
|
||||
echo "| --- | --- |" >> sumup.md
|
||||
for index in ${!ADDS[@]}; do
|
||||
DELTA=$(echo "scale=3; (${ADDS[index]} - ${SUBS[index]})*100/1" | bc)
|
||||
if (( $(echo "$DELTA == 0" | bc -l) )); then
|
||||
continue
|
||||
fi
|
||||
LANGUAGE=${LANS[index]//_/ }
|
||||
echo "| $LANGUAGE | $(printf "%1.3f" $DELTA) % |" >> sumup.md
|
||||
done
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
body-includes: ${{ env.COMMENT_TITLE }}
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.number }}
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
edit-mode: replace
|
||||
body-path: "sumup.md"
|
||||
|
18
.github/workflows/update-translations.yml
vendored
18
.github/workflows/update-translations.yml
vendored
@@ -7,6 +7,8 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- "**" # Don't run on new tags
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -14,20 +16,12 @@ jobs:
|
||||
update-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
cache: "npm"
|
||||
cache-dependency-path: "newIDE/app/package-lock.json"
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
@@ -64,7 +58,7 @@ jobs:
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v3.10.1
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
|
257
.vscode/settings.json
vendored
257
.vscode/settings.json
vendored
@@ -1,131 +1,134 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"memory_resource": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
"files.associations": {
|
||||
"*.idl": "java",
|
||||
"Fastfile": "ruby",
|
||||
"iosfwd": "cpp",
|
||||
"functional": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"random": "cpp",
|
||||
"__config": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"exception": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"new": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"memory": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"hashtable": "cpp",
|
||||
"tuple": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"deque": "cpp",
|
||||
"iterator": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"queue": "cpp",
|
||||
"regex": "cpp",
|
||||
"set": "cpp",
|
||||
"stack": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"iostream": "cpp",
|
||||
"__functional_03": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"__locale": "cpp",
|
||||
"valarray": "cpp",
|
||||
"freeglut_spaceball.c": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"system_error": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__functional_base": "cpp",
|
||||
"__functional_base_03": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ratio": "cpp",
|
||||
"atomic": "cpp",
|
||||
"locale": "cpp",
|
||||
"string_view": "cpp",
|
||||
"__string": "cpp",
|
||||
"cstring": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"__hash": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"numeric": "cpp",
|
||||
"__memory": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"bit": "cpp",
|
||||
"optional": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstddef": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xmemory0": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"variant": "cpp"
|
||||
},
|
||||
"files.exclude": {
|
||||
"Binaries/*build*": true,
|
||||
"Binaries/Output": true,
|
||||
"GDJS/Runtime-dist": true,
|
||||
"docs": true,
|
||||
"newIDE/electron-app/dist": true,
|
||||
"newIDE/app/build": true,
|
||||
"newIDE/app/resources/GDJS": true,
|
||||
"newIDE/electron-app/app/www": true
|
||||
},
|
||||
// Support for Flowtype (for newIDE):
|
||||
"javascript.validate.enable": false,
|
||||
"flow.useNPMPackagedFlow": true,
|
||||
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
// Clang format styling (duplicated in scripts/CMakeClangUtils.txt)
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: Google, BinPackParameters: false, BinPackArguments: false}"
|
||||
}
|
||||
|
@@ -1,3 +1,3 @@
|
||||
This is the directory where native or WebAssembly binaries of the C++ code of GDCore and GDJS are produced.
|
||||
|
||||
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
|
||||
See GDevelop.js README for the instructions to compile after a change in the C++ source code.
|
||||
|
123
CMakeLists.txt
123
CMakeLists.txt
@@ -1,100 +1,99 @@
|
||||
#This is the CMake file used to build GDevelop.
|
||||
#For more information, see the Readme.md file.
|
||||
# This is the CMake file used to build GDevelop.
|
||||
# For more information, see the README.md file.
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# Add utility functions
|
||||
include(scripts/CMakeClangUtils.txt) # To add clang-format and clang-tidy support to a target
|
||||
|
||||
# Macro for defining an option
|
||||
macro(gd_set_option var default type docstring)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
if(NOT DEFINED ${var})
|
||||
set(${var} ${default})
|
||||
endif()
|
||||
set(${var} ${${var}} CACHE ${type} ${docstring} FORCE)
|
||||
endmacro()
|
||||
|
||||
# Set options
|
||||
gd_set_option(BUILD_CORE TRUE BOOL "TRUE to build GDevelop Core library")
|
||||
gd_set_option(BUILD_GDJS TRUE BOOL "TRUE to build GDevelop JS Platform")
|
||||
gd_set_option(BUILD_EXTENSIONS TRUE BOOL "TRUE to build the extensions")
|
||||
gd_set_option(BUILD_TESTS TRUE BOOL "TRUE to build the tests")
|
||||
|
||||
# Disable deprecated code
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) #Force disable old GUI related code.
|
||||
set(NO_GUI TRUE CACHE BOOL "" FORCE) # Force disable old GUI related code.
|
||||
|
||||
#Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
IF(NOT WIN32)
|
||||
if (NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
ELSE()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
ENDIF()
|
||||
# Setting up installation directory, for Linux (has to be done before "project" command).
|
||||
if(NOT WIN32)
|
||||
if(NOT APPLE)
|
||||
gd_set_option(GD_INSTALL_PREFIX "/opt/gdevelop/" STRING "The directory where GDevelop should be installed")
|
||||
else()
|
||||
gd_set_option(GD_INSTALL_PREFIX "." STRING "The directory where GDevelop should be installed")
|
||||
endif()
|
||||
|
||||
#As we embed SFML, prevent it to be installed system-wide
|
||||
# As we embed SFML, prevent it to be installed system-wide
|
||||
set(CMAKE_INSTALL_PREFIX "${GD_INSTALL_PREFIX}/useless")
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
project(GDevelop)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
IF(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
SET(CMAKE_SKIP_BUILD_RPATH TRUE) #Avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
IF(APPLE)
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT BUILD_TESTS)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE) # Avoid errors when packaging for linux.
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||
set(CMAKE_INSTALL_RPATH ".")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
|
||||
ENDIF()
|
||||
#Sanity checks
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message( "CMAKE_BUILD_TYPE is empty, assuming build type is Release" )
|
||||
add_compile_options(
|
||||
-D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_
|
||||
-Wno-potentially-evaluated-expression)
|
||||
endif()
|
||||
# Sanity checks
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message(STATUS "CMAKE_BUILD_TYPE is empty, assuming build type is Release")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
ENDIF()
|
||||
endif()
|
||||
|
||||
IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-s") #Force stripping to avoid errors when packaging for linux.
|
||||
ENDIF()
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" AND NOT WIN32 AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-s") # Force stripping to avoid errors when packaging for linux.
|
||||
endif()
|
||||
|
||||
#Activate C++11
|
||||
include(CheckCXXCompilerFlag)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
|
||||
CHECK_CXX_COMPILER_FLAG("-std=gnu++0x" COMPILER_SUPPORTS_CXX0X)
|
||||
if(COMPILER_SUPPORTS_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
|
||||
elseif(COMPILER_SUPPORTS_CXX0X)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
|
||||
else()
|
||||
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support (with GNU extensions). Please use a different C++ compiler.")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Mark some warnings as errors
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Activate as much warnings as possible to avoid errors like
|
||||
# uninitialized variables or other hard to debug bugs.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder-ctor -Wno-reorder -Wno-pessimizing-move -Wno-unused-variable -Wno-unused-private-field")
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-unknown-warning-option
|
||||
-Wno-reorder-ctor
|
||||
-Wno-reorder
|
||||
-Wno-pessimizing-move
|
||||
-Wno-unused-variable
|
||||
-Wno-unused-private-field
|
||||
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
-Werror=return-stack-address)
|
||||
endif()
|
||||
|
||||
#Define common directories:
|
||||
# Define common directories:
|
||||
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
#Add all the CMakeLists:
|
||||
ADD_SUBDIRECTORY(ExtLibs)
|
||||
IF(BUILD_CORE)
|
||||
ADD_SUBDIRECTORY(Core)
|
||||
ENDIF()
|
||||
IF(BUILD_GDJS)
|
||||
ADD_SUBDIRECTORY(GDJS)
|
||||
ENDIF()
|
||||
IF(EMSCRIPTEN)
|
||||
ADD_SUBDIRECTORY(GDevelop.js)
|
||||
ENDIF()
|
||||
IF(BUILD_EXTENSIONS)
|
||||
ADD_SUBDIRECTORY(Extensions)
|
||||
ENDIF()
|
||||
# Add all the CMakeLists:
|
||||
add_subdirectory(ExtLibs)
|
||||
if(BUILD_CORE)
|
||||
add_subdirectory(Core)
|
||||
endif()
|
||||
if(BUILD_GDJS)
|
||||
add_subdirectory(GDJS)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
add_subdirectory(GDevelop.js)
|
||||
endif()
|
||||
if(BUILD_EXTENSIONS)
|
||||
add_subdirectory(Extensions)
|
||||
endif()
|
||||
|
@@ -1,83 +1,98 @@
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
cmake_policy(SET CMP0015 NEW)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(GDCore)
|
||||
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) #Force use response file: useful for Ninja build system on Windows.
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1) # Force use response file: useful for Ninja build system on Windows.
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
|
||||
|
||||
#Define common directories:
|
||||
# Define common directories:
|
||||
set(GDCORE_include_dir ${GD_base_dir}/Core PARENT_SCOPE)
|
||||
set(GDCORE_lib_dir ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
|
||||
|
||||
#Dependencies on external libraries:
|
||||
###
|
||||
# Dependencies on external libraries:
|
||||
#
|
||||
|
||||
#Defines
|
||||
###
|
||||
add_definitions( -DGD_IDE_ONLY )
|
||||
IF (EMSCRIPTEN)
|
||||
add_definitions( -DEMSCRIPTEN )
|
||||
ENDIF()
|
||||
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
add_definitions( -DDEBUG )
|
||||
ELSE()
|
||||
add_definitions( -DRELEASE )
|
||||
ENDIF()
|
||||
# Defines
|
||||
#
|
||||
add_definitions(-DGD_IDE_ONLY)
|
||||
if(EMSCRIPTEN)
|
||||
add_definitions(-DEMSCRIPTEN)
|
||||
endif()
|
||||
if("${CMAKE_BUILD_TYPE}" MATCHES "Debug")
|
||||
add_definitions(-DDEBUG)
|
||||
else()
|
||||
add_definitions(-DRELEASE)
|
||||
endif()
|
||||
|
||||
IF(WIN32)
|
||||
add_definitions( -DWINDOWS )
|
||||
add_definitions( "-DGD_CORE_API=__declspec(dllexport)" )
|
||||
add_definitions( -D__GNUWIN32__ )
|
||||
ELSE()
|
||||
IF(APPLE)
|
||||
add_definitions( -DMACOS )
|
||||
ELSE()
|
||||
add_definitions( -DLINUX )
|
||||
ENDIF()
|
||||
add_definitions( -DGD_API= )
|
||||
add_definitions( -DGD_CORE_API= )
|
||||
ENDIF(WIN32)
|
||||
if(WIN32)
|
||||
add_definitions(-DWINDOWS)
|
||||
add_definitions("-DGD_CORE_API=__declspec(dllexport)")
|
||||
add_definitions(-D__GNUWIN32__)
|
||||
else()
|
||||
if(APPLE)
|
||||
add_definitions(-DMACOS)
|
||||
else()
|
||||
add_definitions(-DLINUX)
|
||||
endif()
|
||||
add_definitions(-DGD_API=)
|
||||
add_definitions(-DGD_CORE_API=)
|
||||
endif()
|
||||
|
||||
#The target
|
||||
###
|
||||
# The target
|
||||
#
|
||||
include_directories(.)
|
||||
file(GLOB_RECURSE source_files GDCore/*)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
source_files
|
||||
GDCore/*)
|
||||
|
||||
file(GLOB_RECURSE formatted_source_files tests/* GDCore/Events/* GDCore/Extensions/* GDCore/IDE/* GDCore/Project/* GDCore/Serialization/* GDCore/Tools/*)
|
||||
list(REMOVE_ITEM formatted_source_files "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h" "${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
formatted_source_files
|
||||
tests/*
|
||||
GDCore/Events/*
|
||||
GDCore/Extensions/*
|
||||
GDCore/IDE/*
|
||||
GDCore/Project/*
|
||||
GDCore/Serialization/*
|
||||
GDCore/Tools/*)
|
||||
list(
|
||||
REMOVE_ITEM
|
||||
formatted_source_files
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/GDCore/IDE/Dialogs/GDCoreDialogs_dialogs_bitmaps.cpp")
|
||||
gd_add_clang_utils(GDCore "${formatted_source_files}")
|
||||
|
||||
IF(EMSCRIPTEN)
|
||||
if(EMSCRIPTEN)
|
||||
# Emscripten treats all libraries as static libraries
|
||||
add_library(GDCore STATIC ${source_files})
|
||||
ELSE()
|
||||
else()
|
||||
add_library(GDCore SHARED ${source_files})
|
||||
ENDIF()
|
||||
IF(EMSCRIPTEN)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
set_target_properties(GDCore PROPERTIES SUFFIX ".bc")
|
||||
ELSEIF(WIN32)
|
||||
elseif(WIN32)
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "")
|
||||
ELSE()
|
||||
else()
|
||||
set_target_properties(GDCore PROPERTIES PREFIX "lib")
|
||||
ENDIF()
|
||||
endif()
|
||||
set(LIBRARY_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(ARCHIVE_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
set(RUNTIME_OUTPUT_PATH ${GD_base_dir}/Binaries/Output/${CMAKE_BUILD_TYPE}_${CMAKE_SYSTEM_NAME})
|
||||
|
||||
#Tests
|
||||
###
|
||||
# Tests
|
||||
#
|
||||
if(BUILD_TESTS)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*
|
||||
)
|
||||
GLOB_RECURSE
|
||||
test_source_files
|
||||
tests/*)
|
||||
|
||||
add_executable(GDCore_tests ${test_source_files})
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) #Allow finding dependencies directly from build path on Mac OS X.
|
||||
set_target_properties(GDCore_tests PROPERTIES BUILD_WITH_INSTALL_RPATH FALSE) # Allow finding dependencies directly from build path on Mac OS X.
|
||||
target_link_libraries(GDCore_tests GDCore)
|
||||
target_link_libraries(GDCore_tests ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
@@ -38,7 +38,7 @@ void CommentEvent::SerializeTo(SerializerElement &element) const {
|
||||
.SetAttribute("textB", textB);
|
||||
|
||||
element.AddChild("comment").SetValue(com1);
|
||||
element.AddChild("comment2").SetValue(com2);
|
||||
if (!com2.empty()) element.AddChild("comment2").SetValue(com2);
|
||||
}
|
||||
|
||||
void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
@@ -53,7 +53,9 @@ void CommentEvent::UnserializeFrom(gd::Project &project,
|
||||
textB = colorElement.GetIntAttribute("textB");
|
||||
|
||||
com1 = element.GetChild("comment", 0, "Com1").GetValue().GetString();
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
if (element.HasChild("comment2")) {
|
||||
com2 = element.GetChild("comment2", 0, "Com2").GetValue().GetString();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -15,7 +15,7 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
ForEachEvent::ForEachEvent()
|
||||
: BaseEvent(), objectsToPick(""), objectsToPickSelected(false) {}
|
||||
: BaseEvent(), objectsToPick("") {}
|
||||
|
||||
vector<gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors() {
|
||||
vector<gd::InstructionsList*> allConditions;
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#ifndef FOREACHEVENT_H
|
||||
#define FOREACHEVENT_H
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
namespace gd {
|
||||
@@ -62,13 +64,17 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
|
||||
std::vector<gd::Expression*> GetAllObjectExpressions() {
|
||||
std::vector<gd::Expression*> allObjectExpressions;
|
||||
allObjectExpressions.push_back(&objectsToPick);
|
||||
return allObjectExpressions;
|
||||
}
|
||||
|
||||
private:
|
||||
gd::Expression objectsToPick;
|
||||
gd::InstructionsList conditions;
|
||||
gd::InstructionsList actions;
|
||||
gd::EventsList events;
|
||||
|
||||
bool objectsToPickSelected;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -13,6 +13,7 @@
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class Project;
|
||||
class EventVisitor;
|
||||
}
|
||||
class EventsCodeGenerationContext;
|
||||
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -130,30 +131,46 @@ void LinkEvent::SerializeTo(SerializerElement& element) const {
|
||||
|
||||
void LinkEvent::UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
|
||||
SetTarget(element.GetChild("target", 0, "Scene").GetValue().GetString());
|
||||
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
// Compatibility with GD <= 5
|
||||
if (element.HasChild("include", "Limites")) {
|
||||
SerializerElement& includeElement = element.GetChild("include", 0, "Limites");
|
||||
if (includeElement.HasAttribute("includeAll")) {
|
||||
// Compatibility with GDevelop <= 4.0.92
|
||||
if (includeElement.GetBoolAttribute("includeAll", true)) {
|
||||
SetIncludeAllEvents();
|
||||
} else {
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
} else {
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
}
|
||||
} else {
|
||||
// GDevelop > 4.0.92
|
||||
IncludeConfig config = static_cast<IncludeConfig>(
|
||||
includeElement.GetIntAttribute("includeConfig", 0));
|
||||
if (config == INCLUDE_ALL)
|
||||
SetIncludeAllEvents();
|
||||
else if (config == INCLUDE_EVENTS_GROUP)
|
||||
SetIncludeEventsGroup(includeElement.GetStringAttribute("eventsGroup"));
|
||||
else if (config == INCLUDE_BY_INDEX)
|
||||
SetIncludeStartAndEnd(includeElement.GetIntAttribute("start"),
|
||||
includeElement.GetIntAttribute("end"));
|
||||
// Since GDevelop 5, links always include all events.
|
||||
SetIncludeAllEvents();
|
||||
}
|
||||
// end of compatibility code
|
||||
}
|
||||
|
||||
bool LinkEvent::AcceptVisitor(gd::EventVisitor &eventVisitor) {
|
||||
return BaseEvent::AcceptVisitor(eventVisitor) |
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
void LinkEvent::AcceptVisitor(gd::ReadOnlyEventVisitor &eventVisitor) const {
|
||||
BaseEvent::AcceptVisitor(eventVisitor);
|
||||
eventVisitor.VisitLinkEvent(*this);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -30,7 +30,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
includeEnd(gd::String::npos),
|
||||
linkWasInvalid(false){};
|
||||
virtual ~LinkEvent();
|
||||
virtual gd::LinkEvent* Clone() const { return new LinkEvent(*this); }
|
||||
virtual gd::LinkEvent* Clone() const override { return new LinkEvent(*this); }
|
||||
|
||||
/**
|
||||
* Get the link target (i.e. the scene or external events the link refers to).
|
||||
@@ -86,7 +86,7 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
/**
|
||||
* The link event must always be preprocessed.
|
||||
*/
|
||||
virtual bool MustBePreprocessed() { return true; }
|
||||
virtual bool MustBePreprocessed() override { return true; }
|
||||
|
||||
/**
|
||||
* \brief Get a pointer to the list of events that are targeted by the link.
|
||||
@@ -107,11 +107,14 @@ class GD_CORE_API LinkEvent : public gd::BaseEvent {
|
||||
EventsList& eventList,
|
||||
std::size_t indexOfTheEventInThisList);
|
||||
|
||||
virtual bool IsExecutable() const { return true; };
|
||||
virtual bool IsExecutable() const override { return true; };
|
||||
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
virtual void SerializeTo(SerializerElement& element) const override;
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element);
|
||||
const SerializerElement& element) override;
|
||||
|
||||
bool AcceptVisitor(gd::EventVisitor& eventVisitor) override;
|
||||
void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const override;
|
||||
|
||||
private:
|
||||
gd::String
|
||||
|
@@ -15,16 +15,48 @@
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/IDE/ProjectBrowserHelper.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ExposeProjectEffects(
|
||||
const gd::Project& project,
|
||||
const std::function<void(const gd::Effect& effect)>& worker) {
|
||||
void EffectsCodeGenerator::DoVisitObject(gd::Object &object) {
|
||||
auto &effects = object.GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto &effect = effects.GetEffect(e);
|
||||
AddEffectIncludeFiles(effect);
|
||||
}
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::AddEffectIncludeFiles(const gd::Effect &effect) {
|
||||
// TODO: this browse all the extensions every time we're trying to find
|
||||
// a new effect. Might be a good idea to rework MetadataProvider to be
|
||||
// faster (not sure if it is a bottleneck at all though - but could be
|
||||
// for events code generation).
|
||||
const gd::EffectMetadata &effectMetadata =
|
||||
MetadataProvider::GetEffectMetadata(platform, effect.GetEffectType());
|
||||
|
||||
for (auto &includeFile : effectMetadata.GetIncludeFiles())
|
||||
includeFiles.insert(includeFile);
|
||||
};
|
||||
|
||||
void EffectsCodeGenerator::GenerateEffectsIncludeFiles(
|
||||
const gd::Platform &platform,
|
||||
gd::Project &project,
|
||||
std::set<gd::String> &includeFiles) {
|
||||
// TODO Add unit tests on this function.
|
||||
|
||||
// TODO Merge with UsedExtensionsFinder.
|
||||
// Default lights rely on the fact that UsedExtensionsFinder doesn't find
|
||||
// extension usages for effects. This has the happy side effect of not
|
||||
// including Three.js when no 3D object are in the scenes.
|
||||
// We need to make something explicit to avoid future bugs.
|
||||
|
||||
// See also gd::Project::ExposeResources for a method that traverse the whole
|
||||
// project (this time for resources) and
|
||||
// WholeProjectRefactorer::ExposeProjectEvents.
|
||||
|
||||
EffectsCodeGenerator effectsCodeGenerator(platform, includeFiles);
|
||||
|
||||
// Add layouts effects
|
||||
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
|
||||
auto& layout = project.GetLayout(s);
|
||||
@@ -33,47 +65,13 @@ void ExposeProjectEffects(
|
||||
auto& effects = layout.GetLayer(l).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); ++e) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < layout.GetObjectsCount(); i++) {
|
||||
auto& object = layout.GetObject(i);
|
||||
auto& effects = object.GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
effectsCodeGenerator.AddEffectIncludeFiles(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add global object effects
|
||||
for (std::size_t s = 0; s < project.GetObjectsCount(); s++) {
|
||||
auto& effects = project.GetObject(s).GetEffects();
|
||||
for (std::size_t e = 0; e < effects.GetEffectsCount(); e++) {
|
||||
auto& effect = effects.GetEffect(e);
|
||||
worker(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
// Add objects effects
|
||||
gd::ProjectBrowserHelper::ExposeProjectObjects(project, effectsCodeGenerator);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,16 +3,18 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef GDCORE_EffectsCodeGenerator_H
|
||||
#define GDCORE_EffectsCodeGenerator_H
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
|
||||
namespace gd {
|
||||
class Project;
|
||||
class Platform;
|
||||
class Effect;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -20,16 +22,26 @@ namespace gd {
|
||||
/**
|
||||
* \brief Internal class used to generate code from events
|
||||
*/
|
||||
class GD_CORE_API EffectsCodeGenerator {
|
||||
public:
|
||||
class GD_CORE_API EffectsCodeGenerator : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
/**
|
||||
* \brief Add all the include files required by the project effects.
|
||||
*/
|
||||
static void GenerateEffectsIncludeFiles(const gd::Platform& platform,
|
||||
const gd::Project& project,
|
||||
gd::Project& project,
|
||||
std::set<gd::String>& includeFiles);
|
||||
|
||||
private:
|
||||
EffectsCodeGenerator(const gd::Platform &platform_,
|
||||
std::set<gd::String> &includeFiles_)
|
||||
: platform(platform_), includeFiles(includeFiles_){};
|
||||
|
||||
void AddEffectIncludeFiles(const gd::Effect& effect);
|
||||
|
||||
void DoVisitObject(gd::Object &object) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
std::set<gd::String> &includeFiles;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EffectsCodeGenerator_H
|
||||
|
@@ -267,14 +267,12 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
return "/* Unknown instruction - skipped. */";
|
||||
}
|
||||
|
||||
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
|
||||
AddIncludeFiles(instrInfos.GetIncludeFiles());
|
||||
maxConditionsListsSize =
|
||||
std::max(maxConditionsListsSize, condition.GetSubInstructions().size());
|
||||
|
||||
if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (instrInfos.HasCustomCodeGenerator()) {
|
||||
context.EnterCustomCondition();
|
||||
conditionCode += GenerateReferenceToUpperScopeBoolean(
|
||||
"conditionTrue", returnBoolean, context);
|
||||
conditionCode += instrInfos.codeExtraInformation.customCodeGenerator(
|
||||
condition, *this, context);
|
||||
maxCustomConditionsDepth =
|
||||
@@ -291,7 +289,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
condition.SetParameters(parameters);
|
||||
}
|
||||
|
||||
// Verify that there are no mismatchs between object type in parameters.
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter =
|
||||
@@ -325,11 +323,6 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
const ObjectMetadata& objInfo =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
instrInfos.GetRequiredBaseObjectCapability())) {
|
||||
conditionCode +=
|
||||
"/* Object with unsupported capability - skipped. */\n";
|
||||
} else {
|
||||
AddIncludeFiles(objInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
@@ -346,7 +339,6 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
|
||||
context);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
@@ -461,9 +453,9 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
return "/* Unknown instruction - skipped. */";
|
||||
}
|
||||
|
||||
AddIncludeFiles(instrInfos.codeExtraInformation.GetIncludeFiles());
|
||||
AddIncludeFiles(instrInfos.GetIncludeFiles());
|
||||
|
||||
if (instrInfos.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (instrInfos.HasCustomCodeGenerator()) {
|
||||
return instrInfos.codeExtraInformation.customCodeGenerator(
|
||||
action, *this, context);
|
||||
}
|
||||
@@ -483,7 +475,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
action.SetParameters(parameters);
|
||||
}
|
||||
|
||||
// Verify that there are no mismatchs between object type in parameters.
|
||||
// Verify that there are no mismatches between object type in parameters.
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].GetType())) {
|
||||
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
|
||||
@@ -517,10 +509,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
const ObjectMetadata& objInfo =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
instrInfos.GetRequiredBaseObjectCapability())) {
|
||||
actionCode += "/* Object with unsupported capability - skipped. */\n";
|
||||
} else {
|
||||
AddIncludeFiles(objInfo.includeFiles);
|
||||
context.SetCurrentObject(realObjects[i]);
|
||||
context.ObjectsListNeeded(realObjects[i]);
|
||||
@@ -537,7 +525,6 @@ gd::String EventsCodeGenerator::GenerateActionCode(
|
||||
optionalAsyncCallbackName);
|
||||
|
||||
context.SetNoCurrentObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (instrInfos.IsBehaviorInstruction()) {
|
||||
@@ -729,6 +716,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
metadata.GetType() == "tilemapResource" ||
|
||||
metadata.GetType() == "tilesetResource" ||
|
||||
metadata.GetType() == "videoResource" ||
|
||||
metadata.GetType() == "model3DResource" ||
|
||||
// Deprecated, old parameter names:
|
||||
metadata.GetType() == "password" || metadata.GetType() == "musicfile" ||
|
||||
metadata.GetType() == "soundfile" || metadata.GetType() == "police") {
|
||||
@@ -975,6 +963,8 @@ void EventsCodeGenerator::DeleteUselessEvents(gd::EventsList& events) {
|
||||
*/
|
||||
void EventsCodeGenerator::PreprocessEventList(gd::EventsList& listEvent) {
|
||||
for (std::size_t i = 0; i < listEvent.GetEventsCount(); ++i) {
|
||||
if (listEvent[i].IsDisabled()) continue;
|
||||
|
||||
listEvent[i].Preprocess(*this, listEvent, i);
|
||||
if (i <
|
||||
listEvent.GetEventsCount()) { // Be sure that that there is still an
|
||||
@@ -1020,15 +1010,15 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
bool conditionInverted,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
// Generate call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if (instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string") {
|
||||
predicat = GenerateRelationalOperatorCall(
|
||||
predicate = GenerateRelationalOperatorCall(
|
||||
instrInfos,
|
||||
arguments,
|
||||
instrInfos.codeExtraInformation.functionCallName);
|
||||
} else {
|
||||
predicat = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
predicate = instrInfos.codeExtraInformation.functionCallName + "(" +
|
||||
GenerateArgumentsList(arguments, 0) + ")";
|
||||
}
|
||||
|
||||
@@ -1041,10 +1031,10 @@ gd::String EventsCodeGenerator::GenerateFreeCondition(
|
||||
conditionAlreadyTakeCareOfInversion = true;
|
||||
}
|
||||
if (!conditionAlreadyTakeCareOfInversion && conditionInverted)
|
||||
predicat = GenerateNegatedPredicat(predicat);
|
||||
predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
// Generate condition code
|
||||
return returnBoolean + " = " + predicat + ";\n";
|
||||
return returnBoolean + " = " + predicate + ";\n";
|
||||
}
|
||||
|
||||
gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
@@ -1066,18 +1056,18 @@ gd::String EventsCodeGenerator::GenerateObjectCondition(
|
||||
instrInfos.codeExtraInformation.functionCallName;
|
||||
|
||||
// Create call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string")) {
|
||||
predicat = GenerateRelationalOperatorCall(
|
||||
predicate = GenerateRelationalOperatorCall(
|
||||
instrInfos, arguments, objectFunctionCallNamePart, 1);
|
||||
} else {
|
||||
predicat = objectFunctionCallNamePart + "(" +
|
||||
predicate = objectFunctionCallNamePart + "(" +
|
||||
GenerateArgumentsList(arguments, 1) + ")";
|
||||
}
|
||||
if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
|
||||
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
return "For each picked object \"" + objectName + "\", check " + predicat +
|
||||
return "For each picked object \"" + objectName + "\", check " + predicate +
|
||||
".\n";
|
||||
}
|
||||
|
||||
@@ -1091,16 +1081,16 @@ gd::String EventsCodeGenerator::GenerateBehaviorCondition(
|
||||
bool conditionInverted,
|
||||
gd::EventsCodeGenerationContext& context) {
|
||||
// Create call
|
||||
gd::String predicat;
|
||||
gd::String predicate;
|
||||
if ((instrInfos.codeExtraInformation.type == "number" ||
|
||||
instrInfos.codeExtraInformation.type == "string")) {
|
||||
predicat = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2);
|
||||
predicate = GenerateRelationalOperatorCall(instrInfos, arguments, "", 2);
|
||||
} else {
|
||||
predicat = "(" + GenerateArgumentsList(arguments, 2) + ")";
|
||||
predicate = "(" + GenerateArgumentsList(arguments, 2) + ")";
|
||||
}
|
||||
if (conditionInverted) predicat = GenerateNegatedPredicat(predicat);
|
||||
if (conditionInverted) predicate = GenerateNegatedPredicate(predicate);
|
||||
|
||||
return "For each picked object \"" + objectName + "\", check " + predicat +
|
||||
return "For each picked object \"" + objectName + "\", check " + predicate +
|
||||
" for behavior \"" + behaviorName + "\".\n";
|
||||
}
|
||||
|
||||
@@ -1240,7 +1230,7 @@ size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// Base the unique id on the adress in memory so that the same instruction
|
||||
// Base the unique id on the address in memory so that the same instruction
|
||||
// in memory will get the same id across different code generations.
|
||||
size_t uniqueId = (size_t)instruction;
|
||||
|
||||
|
@@ -404,6 +404,18 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Generate the full name for accessing to a boolean variable used for
|
||||
* conditions.
|
||||
*
|
||||
* Default implementation just returns the boolean name passed as argument.
|
||||
*/
|
||||
virtual gd::String GenerateUpperScopeBooleanFullName(
|
||||
const gd::String& boolName,
|
||||
const gd::EventsCodeGenerationContext& context) {
|
||||
return boolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Must create a boolean. Its value must be false.
|
||||
*
|
||||
@@ -493,9 +505,9 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
* - object : Object name -> string
|
||||
* - expression : Mathematical expression -> number (double)
|
||||
* - string : %Text expression -> string
|
||||
* - layer, color, file, joyaxis : Same as string
|
||||
* - layer, color, file, stringWithSelector : Same as string
|
||||
* - relationalOperator : Used to make a comparison between the function
|
||||
resturn value and value of the parameter preceding the relationOperator
|
||||
return value and value of the parameter preceding the relationOperator
|
||||
parameter -> string
|
||||
* - operator : Used to update a value using a setter and a getter -> string
|
||||
* - key, mouse, objectvar, scenevar, globalvar, password, musicfile,
|
||||
@@ -656,28 +668,15 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Must negate a predicat.
|
||||
* \brief Must negate a predicate.
|
||||
*
|
||||
* The default implementation generates C-style code : It wraps the predicat
|
||||
* The default implementation generates C-style code : It wraps the predicate
|
||||
* inside parenthesis and add a !.
|
||||
*/
|
||||
virtual gd::String GenerateNegatedPredicat(const gd::String& predicat) const {
|
||||
return "!(" + predicat + ")";
|
||||
virtual gd::String GenerateNegatedPredicate(const gd::String& predicate) const {
|
||||
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(
|
||||
const std::vector<gd::String>& arguments,
|
||||
const gd::InstructionMetadata& instrInfos,
|
||||
@@ -786,7 +785,7 @@ class GD_CORE_API EventsCodeGenerator {
|
||||
const gd::Project* project; ///< The project being used.
|
||||
const gd::Layout* scene; ///< The scene being generated.
|
||||
|
||||
bool errorOccurred; ///< Must be set to true if an error occured.
|
||||
bool errorOccurred; ///< Must be set to true if an error occurred.
|
||||
bool compilationForRuntime; ///< Is set to true if the code generation is
|
||||
///< made for runtime only.
|
||||
|
||||
|
@@ -51,8 +51,8 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
|
||||
codeGenerator.GetObjectsAndGroups(),
|
||||
rootType);
|
||||
node->Visit(validator);
|
||||
if (!validator.GetErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
|
||||
if (!validator.GetFatalErrors().empty()) {
|
||||
std::cout << "Error: \"" << validator.GetFatalErrors()[0]->GetMessage()
|
||||
<< "\" in: \"" << expression.GetPlainString() << "\" ("
|
||||
<< rootType << ")" << std::endl;
|
||||
|
||||
@@ -170,7 +170,7 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
|
||||
}
|
||||
else {
|
||||
// This is for function names that are put in IdentifierNode
|
||||
// because the type is needed to tell them appart from variables.
|
||||
// because the type is needed to tell them apart from variables.
|
||||
output += GenerateDefaultValue(type);
|
||||
}
|
||||
}
|
||||
@@ -216,10 +216,10 @@ gd::String ExpressionCodeGenerator::GenerateFreeFunctionCode(
|
||||
const std::vector<std::unique_ptr<ExpressionNode>>& parameters,
|
||||
const ExpressionMetadata& expressionMetadata) {
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -242,10 +242,10 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
@@ -270,11 +270,6 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
const ObjectMetadata& objInfo = MetadataProvider::GetObjectMetadata(
|
||||
codeGenerator.GetPlatform(), objectType);
|
||||
|
||||
if (objInfo.IsUnsupportedBaseObjectCapability(
|
||||
expressionMetadata.GetRequiredBaseObjectCapability())) {
|
||||
// Do nothing, skipping objects not supporting the capability required by
|
||||
// this expression.
|
||||
} else {
|
||||
codeGenerator.AddIncludeFiles(objInfo.includeFiles);
|
||||
functionOutput = codeGenerator.GenerateObjectFunctionCall(
|
||||
realObjects[i],
|
||||
@@ -283,7 +278,6 @@ gd::String ExpressionCodeGenerator::GenerateObjectFunctionCode(
|
||||
parametersCode,
|
||||
functionOutput,
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
return functionOutput;
|
||||
@@ -300,10 +294,10 @@ gd::String ExpressionCodeGenerator::GenerateBehaviorFunctionCode(
|
||||
codeGenerator.GetObjectsAndGroups();
|
||||
|
||||
codeGenerator.AddIncludeFiles(
|
||||
expressionMetadata.codeExtraInformation.GetIncludeFiles());
|
||||
expressionMetadata.GetIncludeFiles());
|
||||
|
||||
// Launch custom code generator if needed
|
||||
if (expressionMetadata.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
if (expressionMetadata.HasCustomCodeGenerator()) {
|
||||
return expressionMetadata.codeExtraInformation.customCodeGenerator(
|
||||
PrintParameters(parameters), codeGenerator, context);
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "GDCore/Events/Builtin/AsyncEvent.h"
|
||||
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
@@ -140,6 +141,14 @@ void BaseEvent::Preprocess(gd::EventsCodeGenerator& codeGenerator,
|
||||
}
|
||||
}
|
||||
|
||||
bool BaseEvent::AcceptVisitor(gd::EventVisitor& eventVisitor) {
|
||||
return eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
void BaseEvent::AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const {
|
||||
eventVisitor.VisitEvent(*this);
|
||||
}
|
||||
|
||||
BaseEventSPtr GD_CORE_API CloneRememberingOriginalEvent(BaseEventSPtr event) {
|
||||
gd::BaseEventSPtr copy(event->Clone());
|
||||
// Original event is either the original event of the copied event, or the
|
||||
|
@@ -24,6 +24,8 @@ class EventsCodeGenerationContext;
|
||||
class Platform;
|
||||
class SerializerElement;
|
||||
class Instruction;
|
||||
class EventVisitor;
|
||||
class ReadOnlyEventVisitor;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -238,6 +240,9 @@ class GD_CORE_API BaseEvent {
|
||||
*/
|
||||
virtual void UnserializeFrom(gd::Project& project,
|
||||
const SerializerElement& element){};
|
||||
|
||||
virtual bool AcceptVisitor(gd::EventVisitor& eventVisitor);
|
||||
virtual void AcceptVisitor(gd::ReadOnlyEventVisitor& eventVisitor) const;
|
||||
///@}
|
||||
|
||||
/** \name Common properties
|
||||
@@ -277,6 +282,14 @@ class GD_CORE_API BaseEvent {
|
||||
*/
|
||||
bool IsFolded() const { return folded; }
|
||||
|
||||
/**
|
||||
* \brief Return a list of all objects linked to the event.
|
||||
*/
|
||||
virtual std::vector<gd::Expression*> GetAllObjectExpressions() {
|
||||
std::vector<gd::Expression*> allObjectExpressions;
|
||||
return allObjectExpressions;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
std::weak_ptr<gd::BaseEvent>
|
||||
|
76
Core/GDCore/Events/EventVisitor.h
Normal file
76
Core/GDCore/Events/EventVisitor.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API EventVisitor {
|
||||
public:
|
||||
virtual ~EventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitEvent(gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise.
|
||||
*/
|
||||
virtual bool VisitLinkEvent(gd::LinkEvent& linkEvent) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Visitor of any kind of event.
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyEventVisitor {
|
||||
public:
|
||||
virtual ~ReadOnlyEventVisitor(){};
|
||||
|
||||
/**
|
||||
* Called to do some work on an event.
|
||||
*/
|
||||
virtual void VisitEvent(const gd::BaseEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that VisitEvent is also called with this event.
|
||||
*/
|
||||
virtual void VisitLinkEvent(const gd::LinkEvent& linkEvent) = 0;
|
||||
|
||||
/**
|
||||
* @brief Abort the iteration on the events.
|
||||
*/
|
||||
virtual void StopAnyEventIteration() = 0;
|
||||
};
|
||||
|
||||
}
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "EventsList.h"
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
@@ -100,9 +101,8 @@ bool EventsList::Contains(const gd::BaseEvent& eventToSearch,
|
||||
}
|
||||
|
||||
bool EventsList::MoveEventToAnotherEventsList(const gd::BaseEvent& eventToMove,
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
|
||||
gd::EventsList& newEventsList,
|
||||
std::size_t newPosition) {
|
||||
for (std::size_t i = 0; i < GetEventsCount(); ++i) {
|
||||
if (events[i].get() == &eventToMove) {
|
||||
std::shared_ptr<BaseEvent> event = events[i];
|
||||
|
@@ -19,8 +19,10 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GrammarTerminals.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace gd::GrammarTerminals;
|
||||
|
||||
namespace gd {
|
||||
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/MakeUnique.h"
|
||||
#include "GrammarTerminals.h"
|
||||
namespace gd {
|
||||
class Expression;
|
||||
class ObjectsContainer;
|
||||
@@ -28,6 +29,8 @@ class ExpressionMetadata;
|
||||
|
||||
namespace gd {
|
||||
|
||||
using namespace gd::GrammarTerminals;
|
||||
|
||||
/** \brief Parse an expression, returning a tree of node corresponding
|
||||
* to the parsed expression.
|
||||
*
|
||||
@@ -211,7 +214,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
}
|
||||
SkipIfChar(IsClosingParenthesis);
|
||||
return factor;
|
||||
} else if (IsIdentifierAllowedChar()) {
|
||||
} else if (CheckIfChar(IsAllowedInIdentifier)) {
|
||||
return Identifier();
|
||||
}
|
||||
|
||||
@@ -606,95 +609,6 @@ class GD_CORE_API ExpressionParser2 {
|
||||
return predicate(character);
|
||||
}
|
||||
|
||||
bool IsIdentifierAllowedChar() {
|
||||
if (currentPosition >= expression.size()) return false;
|
||||
gd::String::value_type character = expression[currentPosition];
|
||||
|
||||
// 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)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsWhitespace(gd::String::value_type character) {
|
||||
return character == ' ' || character == '\n' || character == '\r';
|
||||
}
|
||||
|
||||
static bool IsParameterSeparator(gd::String::value_type character) {
|
||||
return character == ',';
|
||||
}
|
||||
|
||||
static bool IsDot(gd::String::value_type character) {
|
||||
return character == '.';
|
||||
}
|
||||
|
||||
static bool IsQuote(gd::String::value_type character) {
|
||||
return character == '"';
|
||||
}
|
||||
|
||||
static bool IsBracket(gd::String::value_type character) {
|
||||
return character == '(' || character == ')' || character == '[' ||
|
||||
character == ']' || character == '{' || character == '}';
|
||||
}
|
||||
|
||||
static bool IsOpeningParenthesis(gd::String::value_type character) {
|
||||
return character == '(';
|
||||
}
|
||||
|
||||
static bool IsClosingParenthesis(gd::String::value_type character) {
|
||||
return character == ')';
|
||||
}
|
||||
|
||||
static bool IsOpeningSquareBracket(gd::String::value_type character) {
|
||||
return character == '[';
|
||||
}
|
||||
|
||||
static bool IsClosingSquareBracket(gd::String::value_type character) {
|
||||
return character == ']';
|
||||
}
|
||||
|
||||
static bool IsExpressionEndingChar(gd::String::value_type character) {
|
||||
return character == ',' || IsClosingParenthesis(character) ||
|
||||
IsClosingSquareBracket(character);
|
||||
}
|
||||
|
||||
static bool IsExpressionOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-' || character == '<' ||
|
||||
character == '>' || character == '?' || character == '^' ||
|
||||
character == '=' || character == '\\' || character == ':' ||
|
||||
character == '!';
|
||||
}
|
||||
|
||||
static bool IsUnaryOperator(gd::String::value_type character) {
|
||||
return character == '+' || character == '-';
|
||||
}
|
||||
|
||||
static bool IsTermOperator(gd::String::value_type character) {
|
||||
return character == '/' || character == '*';
|
||||
}
|
||||
|
||||
static bool IsNumberFirstChar(gd::String::value_type character) {
|
||||
return character == '.' || (character >= '0' && character <= '9');
|
||||
}
|
||||
|
||||
static bool IsNonZeroDigit(gd::String::value_type character) {
|
||||
return (character >= '1' && character <= '9');
|
||||
}
|
||||
|
||||
static bool IsZeroDigit(gd::String::value_type character) {
|
||||
return character == '0';
|
||||
}
|
||||
|
||||
bool IsNamespaceSeparator() {
|
||||
// Namespace separator is a special kind of delimiter as it is 2 characters
|
||||
// long
|
||||
@@ -715,7 +629,7 @@ class GD_CORE_API ExpressionParser2 {
|
||||
gd::String name;
|
||||
size_t startPosition = currentPosition;
|
||||
while (currentPosition < expression.size() &&
|
||||
(IsIdentifierAllowedChar()
|
||||
(CheckIfChar(IsAllowedInIdentifier)
|
||||
// Allow whitespace in identifier name for compatibility
|
||||
|| expression[currentPosition] == ' ')) {
|
||||
name += expression[currentPosition];
|
||||
|
107
Core/GDCore/Events/Parsers/GrammarTerminals.h
Normal file
107
Core/GDCore/Events/Parsers/GrammarTerminals.h
Normal file
@@ -0,0 +1,107 @@
|
||||
#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';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given character can be used in an identifier. This is
|
||||
* any unicode character, except for:
|
||||
* `, . " () [] {} + - < > ? ^ = \ : ! / *` 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)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace GrammarTerminals
|
||||
} // namespace gd
|
@@ -17,7 +17,7 @@ const gd::String& EventsCodeNameMangler::GetMangledObjectsListName(
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = originalObjectName;
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(originalObjectName);
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -43,7 +43,15 @@ const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
return it->second;
|
||||
}
|
||||
|
||||
gd::String partiallyMangledName = externalEventsName;
|
||||
gd::String partiallyMangledName = GetMangledNameWithForbiddenUnderscore(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 =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
@@ -57,11 +65,30 @@ const gd::String& EventsCodeNameMangler::GetExternalEventsFunctionMangledName(
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
|
||||
mangledExternalEventsNames[externalEventsName] = "GDExternalEvents" + partiallyMangledName;
|
||||
return mangledExternalEventsNames[externalEventsName];
|
||||
return partiallyMangledName;
|
||||
}
|
||||
|
||||
gd::String EventsCodeNameMangler::GetMangledName(
|
||||
const gd::String &name) {
|
||||
gd::String partiallyMangledName = name;
|
||||
static const gd::String allowedCharacters =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
for (size_t i = 0; i < partiallyMangledName.size();
|
||||
++i) // Replace all unallowed letter by an underscore and the ascii
|
||||
// number of the letter
|
||||
{
|
||||
if (allowedCharacters.find_first_of(
|
||||
std::u32string(1, partiallyMangledName[i])) == gd::String::npos) {
|
||||
char32_t unallowedChar = partiallyMangledName[i];
|
||||
partiallyMangledName.replace(i, 1, "_" + gd::String::From(unallowedChar));
|
||||
}
|
||||
}
|
||||
return partiallyMangledName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const gd::String& ManObjListName(const gd::String &objectName) {
|
||||
return EventsCodeNameMangler::Get()->GetMangledObjectsListName(objectName);
|
||||
}
|
||||
|
@@ -36,6 +36,8 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
const gd::String &GetExternalEventsFunctionMangledName(
|
||||
const gd::String &externalEventsName);
|
||||
|
||||
static gd::String GetMangledName(const gd::String &name);
|
||||
|
||||
static EventsCodeNameMangler *Get();
|
||||
static void DestroySingleton();
|
||||
|
||||
@@ -44,6 +46,9 @@ class GD_CORE_API EventsCodeNameMangler {
|
||||
virtual ~EventsCodeNameMangler(){};
|
||||
static EventsCodeNameMangler *_singleton;
|
||||
|
||||
// This method is inlined to avoid to copy the returned string.
|
||||
static inline gd::String GetMangledNameWithForbiddenUnderscore(const gd::String &name);
|
||||
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
mangledObjectNames; ///< Memoized results of mangling for objects
|
||||
std::unordered_map<gd::String, gd::String>
|
||||
|
@@ -33,7 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("expression", "The number to be returned")
|
||||
.AddParameter("expression", _("The number to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -48,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.SetHelpPath("/events/functions/return")
|
||||
.AddParameter("string", "The text to be returned")
|
||||
.AddParameter("string", _("The text to be returned"))
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -62,7 +62,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.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();
|
||||
|
||||
@@ -77,7 +107,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function32.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -88,7 +118,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Get function parameter (also called \"argument\") value."),
|
||||
"",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
@@ -98,7 +128,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Get function parameter (also called \"argument\") text."),
|
||||
"",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
||||
extension
|
||||
@@ -110,7 +140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
@@ -124,7 +154,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"",
|
||||
"res/function32.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"string", gd::ParameterOptions::MakeNewOptions())
|
||||
.SetRelevantForFunctionEventsOnly();
|
||||
|
@@ -43,6 +43,12 @@ class GD_CORE_API BuiltinExtensionsImplementer {
|
||||
static void ImplementsVariablesExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsWindowExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAsyncExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsResizableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsScalableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsFlippableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsAnimatableExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsEffectExtension(gd::PlatformExtension& extension);
|
||||
static void ImplementsOpacityExtension(gd::PlatformExtension& extension);
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -29,8 +29,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.SetIcon("res/actions/force24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Variables"))
|
||||
.SetIcon("res/conditions/var24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Timers"))
|
||||
.SetIcon("res/actions/timer24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/visibilite24.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Position"))
|
||||
.SetIcon("res/actions/position24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Angle"))
|
||||
.SetIcon("res/actions/direction24_black.png");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::ObjectConfiguration>(
|
||||
"", _("Base object"), _("Base object"), "res/objeticon24.png");
|
||||
@@ -1101,6 +1109,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Largeur",
|
||||
_("Width"),
|
||||
_("Width of the object"),
|
||||
@@ -1116,6 +1125,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Hauteur",
|
||||
_("Height"),
|
||||
_("Height of the object"),
|
||||
@@ -1201,7 +1211,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
obj.AddExpression("ObjectTimerElapsedTime",
|
||||
_("Object timer value"),
|
||||
_("Value of an object timer"),
|
||||
_("Object timers"),
|
||||
_("Timers"),
|
||||
"res/actions/time.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("identifier", _("Timer's name"), "objectTimer");
|
||||
@@ -1251,6 +1261,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("expression", _("Target X position"))
|
||||
.AddParameter("expression", _("Target Y position"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("EnableEffect",
|
||||
_("Enable an object effect"),
|
||||
_("Enable an effect on the object"),
|
||||
@@ -1262,8 +1273,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectDoubleParameter",
|
||||
_("Effect parameter (number)"),
|
||||
_("Change the value of a parameter of an effect.") + "\n" +
|
||||
@@ -1278,8 +1290,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectStringParameter",
|
||||
_("Effect parameter (string)"),
|
||||
_("Change the value (string) of a parameter of an effect.") +
|
||||
@@ -1295,8 +1308,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetEffectBooleanParameter",
|
||||
_("Effect parameter (enable or disable)"),
|
||||
_("Enable or disable a parameter of an effect.") + "\n" +
|
||||
@@ -1311,8 +1325,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("IsEffectEnabled",
|
||||
_("Effect is enabled"),
|
||||
_("Check if the effect on an object is enabled."),
|
||||
@@ -1323,7 +1338,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple()
|
||||
.SetRequiresBaseObjectCapability("effect");
|
||||
.SetHidden();
|
||||
|
||||
obj.AddAction("SetIncludedInParentCollisionMask",
|
||||
_("Include in parent collision mask"),
|
||||
@@ -1349,7 +1364,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddParameter("objectListOrEmptyIfJustDeclared", _("Object to create"))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1374,7 +1389,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"with this name are found in the group, no object will be created."))
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -1404,7 +1419,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/ajouthasard24.png",
|
||||
"res/actions/ajouthasard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1463,7 +1478,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/conditions/add24.png",
|
||||
"res/conditions/add.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -1478,7 +1493,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/conditions/ajouthasard24.png",
|
||||
"res/conditions/ajouthasard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddCodeOnlyParameter("objectsContext", "")
|
||||
.AddParameter("objectList", _("Object"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1588,7 +1603,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"Raycast",
|
||||
_("Raycast"),
|
||||
_("Sends a ray from the given source position and angle, "
|
||||
"intersecting the closest object.\nThe instersected "
|
||||
"intersecting the closest object.\nThe intersected "
|
||||
"object will become the only one taken into account.\nIf "
|
||||
"the condition is inverted, the object to be intersected "
|
||||
"will be the farthest one within the ray radius."),
|
||||
@@ -1619,7 +1634,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"RaycastToPosition",
|
||||
_("Raycast to position"),
|
||||
_("Sends a ray from the given source position to the final point, "
|
||||
"intersecting the closest object.\nThe instersected "
|
||||
"intersecting the closest object.\nThe intersected "
|
||||
"object will become the only one taken into account.\nIf "
|
||||
"the condition is inverted, the object to be intersected "
|
||||
"will be the farthest one within the ray radius."),
|
||||
|
@@ -40,7 +40,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -72,7 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -103,7 +103,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -119,7 +119,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -136,7 +136,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -153,7 +153,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -170,7 +170,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -187,7 +187,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number"), "", true)
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
@@ -204,7 +204,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/camera24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -322,7 +322,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression",
|
||||
_("Value (1:Initial zoom, 2:Zoom x2, 0.5:Unzoom x2...)"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -354,46 +354,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"ClampCamera",
|
||||
_("Enforce camera boundaries"),
|
||||
_("Enforce camera boundaries by moving the camera back inside specified boundaries."),
|
||||
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
|
||||
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddAction("ClampCamera",
|
||||
_("Enforce camera boundaries"),
|
||||
_("Enforce camera boundaries by moving the camera back inside "
|
||||
"specified boundaries."),
|
||||
_("Enforce camera boundaries (left: _PARAM1_, top: _PARAM2_ "
|
||||
"right: _PARAM3_, bottom: _PARAM4_, layer: _PARAM5_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression",
|
||||
_("Left bound X Position"))
|
||||
.AddParameter("expression",
|
||||
_("Top bound Y Position"))
|
||||
.AddParameter("expression",
|
||||
_("Right bound X Position"))
|
||||
.AddParameter("expression",
|
||||
_("Bottom bound Y Position"))
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("expression", _("Left bound X Position"))
|
||||
.AddParameter("expression", _("Top bound Y Position"))
|
||||
.AddParameter("expression", _("Right bound X Position"))
|
||||
.AddParameter("expression", _("Bottom bound Y Position"))
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddAction(
|
||||
"CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddAction("CentreCamera",
|
||||
_("Center the camera on an object"),
|
||||
_("Center the camera on the specified object."),
|
||||
_("Center camera on _PARAM1_ (layer: _PARAM3_)"),
|
||||
"",
|
||||
"res/actions/camera24.png",
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("objectPtr", _("Object"))
|
||||
.AddParameter("yesorno",
|
||||
@@ -401,7 +396,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"",
|
||||
true)
|
||||
.SetDefaultValue("yes")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -458,7 +453,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
@@ -477,7 +472,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
@@ -496,7 +491,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
@@ -512,7 +507,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.MarkAsAdvanced();
|
||||
@@ -526,7 +521,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable"), "", true)
|
||||
@@ -542,7 +537,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/time24.png",
|
||||
"res/conditions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number",
|
||||
@@ -560,7 +555,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression",
|
||||
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
|
||||
@@ -575,7 +570,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/conditions/layer24.png",
|
||||
"res/conditions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions())
|
||||
@@ -592,7 +587,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/layer24.png",
|
||||
"res/actions/layer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("New default Z order"));
|
||||
|
||||
@@ -607,7 +602,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/color24.png",
|
||||
"res/actions/color.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"Lighting\"")
|
||||
.AddParameter("color", _("Color"))
|
||||
.MarkAsAdvanced();
|
||||
|
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("AnimatableCapability",
|
||||
_("Animatable capability"),
|
||||
_("Animate objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
|
||||
.SetIcon("res/actions/animation24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"AnimatableBehavior",
|
||||
_("Animatable capability"),
|
||||
"Animation",
|
||||
_("Animate objects."),
|
||||
"",
|
||||
"res/actions/animation24.png",
|
||||
"AnimatableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Index",
|
||||
_("Animation (by number)"),
|
||||
_("the number of the animation played by the object (the number from "
|
||||
"the animations list)"),
|
||||
_("the number of the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation index")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"string",
|
||||
"Name",
|
||||
_("Animation (by name)"),
|
||||
_("the animation played by the object using the name of the "
|
||||
"animation."),
|
||||
_("the animation"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Animation name")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("PauseAnimation",
|
||||
_("Pause the animation"),
|
||||
_("Pause the animation of the object"),
|
||||
_("Pause the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("PlayAnimation",
|
||||
_("Resume the animation"),
|
||||
_("Resume the animation of the object"),
|
||||
_("Resume the animation of _PARAM0_"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png",
|
||||
"res/actions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"SpeedScale",
|
||||
_("Animation speed scale"),
|
||||
_("the animation speed scale (1 = the default speed, >1 = faster and "
|
||||
"<1 = slower)"),
|
||||
_("the animation speed scale"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Speed scale")))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("IsAnimationPaused",
|
||||
_("Animation paused"),
|
||||
_("Check if the animation of an object is paused."),
|
||||
_("The animation of _PARAM0_ is paused"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("HasAnimationEnded",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
"is finished."),
|
||||
_("The animation of _PARAM0_ is finished"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
"res/conditions/animation.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
|
||||
.MarkAsSimple();
|
||||
}
|
||||
|
||||
} // namespace gd
|
116
Core/GDCore/Extensions/Builtin/Capabilities/EffectExtension.cpp
Normal file
116
Core/GDCore/Extensions/Builtin/Capabilities/EffectExtension.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsEffectExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("EffectCapability",
|
||||
_("Effect capability"),
|
||||
_("Apply visual effects to objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"EffectBehavior",
|
||||
_("Effect capability"),
|
||||
"Effect",
|
||||
_("Apply visual effects to objects."),
|
||||
"",
|
||||
"res/actions/effect24.png",
|
||||
"EffectBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("EnableEffect",
|
||||
_("Enable an object effect"),
|
||||
_("Enable an effect on the object"),
|
||||
_("Enable effect _PARAM2_ on _PARAM0_: _PARAM3_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectDoubleParameter",
|
||||
_("Effect parameter (number)"),
|
||||
_("Change the value of a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectStringParameter",
|
||||
_("Effect parameter (string)"),
|
||||
_("Change the value (string) of a parameter of an effect.") +
|
||||
"\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Set _PARAM3_ to _PARAM4_ for effect _PARAM2_ of _PARAM0_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("SetEffectBooleanParameter",
|
||||
_("Effect parameter (enable or disable)"),
|
||||
_("Enable or disable a parameter of an effect.") + "\n" +
|
||||
_("You can find the parameter names (and change the effect "
|
||||
"names) in the effects window."),
|
||||
_("Enable _PARAM3_ for effect _PARAM2_ of _PARAM0_: _PARAM4_"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("IsEffectEnabled",
|
||||
_("Effect is enabled"),
|
||||
_("Check if the effect on an object is enabled."),
|
||||
_("Effect _PARAM2_ of _PARAM0_ is enabled"),
|
||||
_("Effects"),
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "EffectBehavior")
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFlippableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("FlippableCapability",
|
||||
_("Flippable capability"),
|
||||
_("Flip objects."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Effects"))
|
||||
.SetIcon("res/actions/effect24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"FlippableBehavior",
|
||||
_("Flippable capability"),
|
||||
"Flippable",
|
||||
_("Flip objects."),
|
||||
"",
|
||||
"res/actions/flipX24.png",
|
||||
"FlippableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddScopedAction("FlipX",
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip horizontally _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedAction("FlipY",
|
||||
_("Flip the object vertically"),
|
||||
_("Flip the object vertically"),
|
||||
_("Flip vertically _PARAM0_: _PARAM2_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.MarkAsSimple();
|
||||
|
||||
aut.AddScopedCondition("FlippedX",
|
||||
_("Horizontally flipped"),
|
||||
_("Check if the object is horizontally flipped"),
|
||||
_("_PARAM0_ is horizontally flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
|
||||
aut.AddScopedCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
_("Check if the object is vertically flipped"),
|
||||
_("_PARAM0_ is vertically flipped"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "FlippableBehavior");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("OpacityCapability",
|
||||
_("Opacity capability"),
|
||||
_("Change the object opacity."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
|
||||
.SetIcon("res/actions/opacity24.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"OpacityBehavior",
|
||||
_("Opacity capability"),
|
||||
"Opacity",
|
||||
_("Change the object opacity."),
|
||||
"",
|
||||
"res/actions/opacity24.png",
|
||||
"OpacityBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Opacity"),
|
||||
_("the opacity of an object, between 0 (fully transparent) to 255 "
|
||||
"(opaque)"),
|
||||
_("the opacity"),
|
||||
_("Visibility"),
|
||||
"res/actions/opacity24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "OpacityBehavior")
|
||||
.UseStandardParameters(
|
||||
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0-255)")))
|
||||
.SetFunctionName("setOpacity")
|
||||
.SetGetter("getOpacity");
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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
|
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/BehaviorsSharedData.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
|
||||
gd::PlatformExtension& extension) {
|
||||
extension
|
||||
.SetExtensionInformation("ScalableCapability",
|
||||
_("Scalable capability"),
|
||||
_("Change the object scale."),
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/objects");
|
||||
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
|
||||
.SetIcon("res/actions/scale24_black.png");
|
||||
|
||||
gd::BehaviorMetadata& aut = extension.AddBehavior(
|
||||
"ScalableBehavior",
|
||||
_("Scalable capability"),
|
||||
"Scale",
|
||||
_("Change the object scale."),
|
||||
"",
|
||||
"res/actions/scale24_black.png",
|
||||
"ResizableBehavior",
|
||||
std::make_shared<gd::Behavior>(),
|
||||
std::make_shared<gd::BehaviorsSharedData>())
|
||||
.SetHidden();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Value",
|
||||
_("Scale"),
|
||||
_("the scale of the object (default scale is 1)"),
|
||||
_("the scale"),
|
||||
_("Scale"),
|
||||
"res/actions/scale24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"X",
|
||||
_("Scale on X axis"),
|
||||
_("the scale on X axis of the object (default scale is 1)"),
|
||||
_("the scale on X axis"),
|
||||
_("Scale"),
|
||||
"res/actions/scale24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
aut.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
"Y",
|
||||
_("Scale on Y axis"),
|
||||
_("the scale on Y axis of the object (default scale is 1)"),
|
||||
_("the scale on Y axis"),
|
||||
_("Scale"),
|
||||
"res/actions/scale24_black.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("behavior", _("Behavior"), "ScalableBehavior")
|
||||
.UseStandardParameters(
|
||||
"number",
|
||||
gd::ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
}
|
||||
|
||||
} // namespace gd
|
@@ -69,12 +69,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"EcrireFichierExp",
|
||||
_("Write a value"),
|
||||
_("Write the result of the expression in the stored data, in the "
|
||||
_("Save a value"),
|
||||
_("Save the result of the expression in the stored data, in the "
|
||||
"specified element.\nSpecify the structure leading to the "
|
||||
"element using / (example : Root/Level/Current)\nSpaces are "
|
||||
"forbidden in element names."),
|
||||
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -85,12 +85,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"EcrireFichierTxt",
|
||||
_("Write a text"),
|
||||
_("Write the text in the specified storage, in the specified "
|
||||
_("Save a text"),
|
||||
_("Save the text in the specified storage, in the specified "
|
||||
"element.\nSpecify "
|
||||
"the structure leading to the element using / (example : "
|
||||
"Root/Level/Current)\nSpaces are forbidden in element names."),
|
||||
_("Write _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
_("Save _PARAM2_ in _PARAM1_ of storage _PARAM0_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -101,13 +101,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierExp",
|
||||
_("Read a value"),
|
||||
_("Read the value saved in the specified element and store it in a "
|
||||
_("Load a value"),
|
||||
_("Load the value saved in the specified element and store it in a "
|
||||
"scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Read _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store value in _PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
"res/actions/fichier.png")
|
||||
@@ -119,13 +119,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
extension
|
||||
.AddAction(
|
||||
"LireFichierTxt",
|
||||
_("Read a text"),
|
||||
_("Read the text saved in the specified element and store it in a "
|
||||
_("Load a text"),
|
||||
_("Load the text saved in the specified element and store it in a "
|
||||
"scene "
|
||||
"variable.\nSpecify the structure leading to the element using / "
|
||||
"(example : Root/Level/Current)\nSpaces are forbidden in element "
|
||||
"names."),
|
||||
_("Read _PARAM1_ from storage _PARAM0_ and store as text in "
|
||||
_("Load _PARAM1_ from storage _PARAM0_ and store as text in "
|
||||
"_PARAM3_"),
|
||||
"",
|
||||
"res/actions/fichier24.png",
|
||||
|
@@ -163,7 +163,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -185,7 +185,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -206,7 +206,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -223,7 +223,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"res/conditions/mouse24.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
@@ -317,7 +317,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Touch identifier"))
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
@@ -333,7 +333,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Touch identifier"))
|
||||
.UseStandardParameters("number", ParameterOptions::MakeNewOptions())
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.AddParameter("layer", _("Layer"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
|
||||
.SetDefaultValue("0");
|
||||
|
@@ -48,7 +48,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
.AddParameter("string", "Content type", "", true)
|
||||
.SetParameterLongDescription(
|
||||
"If empty, \"application/x-www-form-urlencoded\" will be used.")
|
||||
.AddParameter("scenevar", "Reponse scene variable", "", true)
|
||||
.AddParameter("scenevar", "Response scene variable", "", true)
|
||||
.SetParameterLongDescription(
|
||||
"The response of the server will be stored, as a string, in this "
|
||||
"variable. If the server returns *JSON*, you may want to use the "
|
||||
|
@@ -54,6 +54,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddCondition("DoesSceneExist",
|
||||
_("Does scene exist"),
|
||||
_("Check if scene exists."),
|
||||
_("Scene _PARAM1_ exists"),
|
||||
"",
|
||||
"res/actions/texte.png",
|
||||
"res/actions/texte.png")
|
||||
.SetHelpPath("/interface/scene-editor/events")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("sceneName", _("Name of the scene to check"))
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddAction("Scene",
|
||||
_("Change the scene"),
|
||||
|
@@ -110,11 +110,11 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
.GetBoolAttribute("automatic", true));
|
||||
|
||||
if (spriteElement.HasChild("CustomCollisionMask"))
|
||||
sprite.SetCollisionMaskAutomatic(
|
||||
sprite.SetFullImageCollisionMask(
|
||||
!spriteElement.GetChild("CustomCollisionMask")
|
||||
.GetBoolAttribute("custom", false));
|
||||
else
|
||||
sprite.SetCollisionMaskAutomatic(
|
||||
sprite.SetFullImageCollisionMask(
|
||||
!spriteElement.GetBoolAttribute("hasCustomCollisionMask", false));
|
||||
|
||||
std::vector<Polygon2d> mask;
|
||||
@@ -173,7 +173,7 @@ void SaveSpritesDirection(const vector<Sprite>& sprites,
|
||||
.SetAttribute("automatic", sprites[i].IsDefaultCenterPoint());
|
||||
|
||||
spriteElement.SetAttribute("hasCustomCollisionMask",
|
||||
!sprites[i].IsCollisionMaskAutomatic());
|
||||
!sprites[i].IsFullImageCollisionMask());
|
||||
|
||||
gd::SerializerElement& collisionMaskElement =
|
||||
spriteElement.AddChild("customCollisionMask");
|
||||
|
@@ -4,7 +4,9 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Sprite.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -14,11 +16,10 @@ namespace gd {
|
||||
Point Sprite::badPoint("");
|
||||
|
||||
Sprite::Sprite()
|
||||
: automaticCollisionMask(true),
|
||||
: fullImageCollisionMask(false),
|
||||
origine("origine"),
|
||||
centre("centre"),
|
||||
automaticCentre(true) {
|
||||
}
|
||||
automaticCentre(true) {}
|
||||
|
||||
Sprite::~Sprite(){};
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#ifndef SPRITE_H
|
||||
#define SPRITE_H
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Point.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/Polygon2d.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -43,7 +44,7 @@ class GD_CORE_API Sprite {
|
||||
|
||||
/**
|
||||
* \brief Get the collision mask (custom or automatically generated owing to
|
||||
* IsCollisionMaskAutomatic())
|
||||
* IsFullImageCollisionMask())
|
||||
*
|
||||
* \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.
|
||||
@@ -66,7 +67,7 @@ class GD_CORE_API Sprite {
|
||||
|
||||
/**
|
||||
* \brief Set the custom collision mask.
|
||||
* Call then `SetCollisionMaskAutomatic(false)` to use it.
|
||||
* Call then `SetFullImageCollisionMask(false)` to use it.
|
||||
*/
|
||||
void SetCustomCollisionMask(const std::vector<Polygon2d>& collisionMask);
|
||||
|
||||
@@ -74,15 +75,15 @@ class GD_CORE_API Sprite {
|
||||
* \brief Return true if the collision mask is a bounding box, false if a
|
||||
* custom collision mask is used.
|
||||
*/
|
||||
inline bool IsCollisionMaskAutomatic() const {
|
||||
return automaticCollisionMask;
|
||||
inline bool IsFullImageCollisionMask() const {
|
||||
return fullImageCollisionMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Un/set use of the custom collision mask.
|
||||
*/
|
||||
inline void SetCollisionMaskAutomatic(bool enabled) {
|
||||
automaticCollisionMask = enabled;
|
||||
inline void SetFullImageCollisionMask(bool enabled) {
|
||||
fullImageCollisionMask = enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -161,9 +162,9 @@ class GD_CORE_API Sprite {
|
||||
private:
|
||||
gd::String image; ///< Name of the image to be loaded in Image Manager.
|
||||
|
||||
bool automaticCollisionMask; ///< True to use the custom collision mask.
|
||||
///< Otherwise, a basic bounding box is returned
|
||||
///< by GetCollisionMask()
|
||||
bool fullImageCollisionMask; ///< True to use a bounding box wrapping the
|
||||
///< whole image as collision mask. If false,
|
||||
///< custom collision mask is used.
|
||||
std::vector<Polygon2d> customCollisionMask; ///< Custom collision mask
|
||||
|
||||
std::vector<Point> points; ///< List of the points used by the sprite
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the GNU Lesser General Public
|
||||
* LicenFse.
|
||||
* License.
|
||||
*/
|
||||
#include "GDCore/Extensions/Builtin/AllBuiltinExtensions.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
@@ -32,8 +32,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Animated object which can be used for "
|
||||
"most elements of a game"),
|
||||
"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",
|
||||
_("Sprite opacity"),
|
||||
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
|
||||
@@ -48,8 +55,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity (0-255)")))
|
||||
.MarkAsSimple();
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeAnimation",
|
||||
_("Change the animation"),
|
||||
_("Change the animation of the object, using the animation "
|
||||
@@ -62,8 +71,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetAnimationName",
|
||||
_("Change the animation (by name)"),
|
||||
_("Change the animation of the object, using the name of the "
|
||||
@@ -75,6 +86,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectAnimationName", _("Animation name"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddAction(
|
||||
@@ -107,6 +119,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("PauseAnimation",
|
||||
_("Pause the animation"),
|
||||
_("Pause the animation of the object"),
|
||||
@@ -116,8 +129,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("PlayAnimation",
|
||||
_("Play the animation"),
|
||||
_("Play the animation of the object"),
|
||||
@@ -127,8 +142,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction(
|
||||
"ChangeAnimationSpeedScale",
|
||||
_("Animation speed scale"),
|
||||
@@ -143,8 +160,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.UseStandardOperatorParameters(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(_("Speed scale")))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("TourneVersPos",
|
||||
"Rotate an object toward a position",
|
||||
"Rotate an object towards a position.",
|
||||
@@ -159,8 +178,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("expression", _("Angular speed (degrees per second)"))
|
||||
.SetDefaultValue("0")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden(); // Deprecated
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScale",
|
||||
_("Scale"),
|
||||
_("Modify the scale of the specified object."),
|
||||
@@ -174,8 +194,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScaleWidth",
|
||||
_("Scale on X axis"),
|
||||
_("Modify the scale of the width of an object."),
|
||||
@@ -189,8 +211,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeScaleHeight",
|
||||
_("Scale on Y axis"),
|
||||
_("Modify the scale of the height of an object."),
|
||||
@@ -204,8 +228,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeWidth",
|
||||
_("Width"),
|
||||
_("Change the width of a Sprite object."),
|
||||
@@ -217,8 +243,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Width",
|
||||
_("Width"),
|
||||
_("Compare the width of a Sprite object."),
|
||||
@@ -230,8 +258,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("ChangeHeight",
|
||||
_("Height"),
|
||||
_("Change the height of a Sprite object."),
|
||||
@@ -243,8 +273,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number",
|
||||
ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Height",
|
||||
_("Height"),
|
||||
_("Compare the height of a Sprite object."),
|
||||
@@ -256,8 +288,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("SetSize",
|
||||
_("Size"),
|
||||
_("Change the size of an object."),
|
||||
@@ -269,8 +303,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("expression", _("Width"))
|
||||
.AddParameter("expression", _("Height"))
|
||||
.MarkAsAdvanced();
|
||||
.MarkAsAdvanced()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition(
|
||||
"Animation",
|
||||
_("Current animation"),
|
||||
@@ -283,11 +319,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationName",
|
||||
_("Current animation name"),
|
||||
_("Check the animation by played by the object."),
|
||||
_("Check the animation played by the object."),
|
||||
_("The animation of _PARAM0_ is _PARAM1_"),
|
||||
_("Animations and images"),
|
||||
"res/conditions/animation24.png",
|
||||
@@ -295,6 +333,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectAnimationName", _("Animation name"))
|
||||
.SetHidden()
|
||||
.MarkAsAdvanced();
|
||||
|
||||
obj.AddCondition(
|
||||
@@ -328,6 +367,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number", ParameterOptions::MakeNewOptions())
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimStopped",
|
||||
_("Animation paused"),
|
||||
_("Check if the animation of an object is paused."),
|
||||
@@ -337,8 +377,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/conditions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationEnded",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
@@ -352,6 +394,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("AnimationEnded2",
|
||||
_("Animation finished"),
|
||||
_("Check if the animation being played by the Sprite object "
|
||||
@@ -362,6 +405,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/conditions/animation.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddCondition("ScaleWidth",
|
||||
@@ -394,6 +438,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale (1 by default)")))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
// Deprecated
|
||||
obj.AddCondition("Opacity",
|
||||
_("Opacity"),
|
||||
_("Compare the opacity of a Sprite, between 0 (fully "
|
||||
@@ -408,7 +453,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"number",
|
||||
ParameterOptions::MakeNewOptions().SetDescription(
|
||||
_("Opacity to compare to (0-255)")))
|
||||
.MarkAsSimple();
|
||||
.MarkAsSimple()
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition(
|
||||
"BlendMode",
|
||||
@@ -456,9 +502,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddAction("FlipY",
|
||||
@@ -468,9 +514,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("yesorno", _("Activate flipping"))
|
||||
.SetHidden()
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddCondition("FlippedX",
|
||||
@@ -480,8 +526,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition("FlippedY",
|
||||
_("Vertically flipped"),
|
||||
@@ -490,9 +536,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddAction("TourneVers",
|
||||
"Rotate an object toward another",
|
||||
"Rotate an object towards another.",
|
||||
@@ -504,7 +551,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectPtr", "Rotate toward this object")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.SetHidden(); // Deprecated
|
||||
.SetHidden();
|
||||
|
||||
obj.AddExpression("X",
|
||||
_("X position of a point"),
|
||||
@@ -542,6 +589,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.AddParameter("objectPointName", _("Name of the point"));
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Direc",
|
||||
_("Direction"),
|
||||
_("Direction of the object"),
|
||||
@@ -550,6 +598,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Direction",
|
||||
_("Direction"),
|
||||
_("Direction of the object"),
|
||||
@@ -559,6 +608,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
// interface.
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Anim",
|
||||
_("Animation"),
|
||||
_("Animation of the object"),
|
||||
@@ -567,18 +617,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Animation",
|
||||
_("Animation"),
|
||||
_("Animation of the object"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddStrExpression("AnimationName",
|
||||
_("Animation name"),
|
||||
_("Name of the animation of the object"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("Sprite",
|
||||
@@ -595,11 +649,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
"res/actions/sprite.png")
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("AnimationSpeedScale",
|
||||
_("Animation speed scale"),
|
||||
_("Animation speed scale"),
|
||||
_("Animations and images"),
|
||||
"res/actions/animation.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("ScaleX",
|
||||
@@ -607,6 +663,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale of the width of an object"),
|
||||
_("Size"),
|
||||
"res/actions/scaleWidth_black.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("ScaleY",
|
||||
@@ -614,14 +671,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Scale of the height of an object"),
|
||||
_("Size"),
|
||||
"res/actions/scaleHeight_black.png")
|
||||
.SetHidden()
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
// Deprecated
|
||||
obj.AddExpression("Opacity",
|
||||
_("Opacity"),
|
||||
_("Opacity"),
|
||||
_("Opacity"),
|
||||
"res/actions/opacity.png")
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition("Collision",
|
||||
|
@@ -25,13 +25,16 @@ namespace gd {
|
||||
|
||||
Animation SpriteObject::badAnimation;
|
||||
|
||||
SpriteObject::SpriteObject() : updateIfNotVisible(false) {}
|
||||
SpriteObject::SpriteObject()
|
||||
: updateIfNotVisible(false), adaptCollisionMaskAutomatically(true) {}
|
||||
|
||||
SpriteObject::~SpriteObject(){};
|
||||
|
||||
void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) {
|
||||
updateIfNotVisible = element.GetBoolAttribute("updateIfNotVisible", true);
|
||||
adaptCollisionMaskAutomatically =
|
||||
element.GetBoolAttribute("adaptCollisionMaskAutomatically", false);
|
||||
|
||||
RemoveAllAnimations();
|
||||
const gd::SerializerElement& animationsElement =
|
||||
@@ -80,6 +83,8 @@ void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
|
||||
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
|
||||
element.SetAttribute("adaptCollisionMaskAutomatically",
|
||||
adaptCollisionMaskAutomatically);
|
||||
|
||||
// Animations
|
||||
gd::SerializerElement& animationsElement = element.AddChild("animations");
|
||||
|
@@ -47,8 +47,7 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) 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(
|
||||
const gd::InitialInstance& position,
|
||||
@@ -118,14 +117,30 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
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.
|
||||
* @brief Check if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetUpdateIfNotVisible(bool updateIfNotVisible_) { updateIfNotVisible = updateIfNotVisible_; }
|
||||
bool AdaptCollisionMaskAutomatically() const {
|
||||
return adaptCollisionMaskAutomatically;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the object animation should be played even if the object is hidden
|
||||
* or far from the camera (false by default).
|
||||
* @brief Set if the collision mask adapts automatically to the animation.
|
||||
*/
|
||||
void SetAdaptCollisionMaskAutomatically(bool enable) {
|
||||
adaptCollisionMaskAutomatically = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set if the object animation should be played even if the object is
|
||||
* 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; }
|
||||
///@}
|
||||
@@ -137,11 +152,15 @@ class GD_CORE_API SpriteObject : public gd::ObjectConfiguration {
|
||||
|
||||
mutable std::vector<Animation> animations;
|
||||
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
|
||||
///< object animation even if hidden or far from the
|
||||
///< screen.
|
||||
///< object animation even if hidden or far from
|
||||
///< the screen.
|
||||
|
||||
static Animation badAnimation; //< Bad animation when an out of bound
|
||||
// animation is requested.
|
||||
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
|
||||
|
@@ -126,8 +126,8 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
extension
|
||||
.AddExpression(
|
||||
"StrFindLast",
|
||||
_("Search the last occurence in a text"),
|
||||
_("Search the last occurence in a string (return the position of "
|
||||
_("Search the last occurrence in a text"),
|
||||
_("Search the last occurrence in a string (return the position of "
|
||||
"the result, from the beginning of the string, or -1 if not "
|
||||
"found)"),
|
||||
"",
|
||||
@@ -169,10 +169,10 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
extension
|
||||
.AddExpression(
|
||||
"StrFindLastFrom",
|
||||
_("Search the last occurence in a text, starting from a position"),
|
||||
_("Search in a text the last occurence, starting from a position "
|
||||
_("Search the last occurrence in a text, starting from a position"),
|
||||
_("Search in a text the last occurrence, starting from a position "
|
||||
"(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)"),
|
||||
"",
|
||||
"res/conditions/toujours24_black.png")
|
||||
|
135
Core/GDCore/Extensions/Metadata/AbstractFunctionMetadata.h
Normal file
135
Core/GDCore/Extensions/Metadata/AbstractFunctionMetadata.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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
|
@@ -34,8 +34,7 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
className(className_),
|
||||
iconFilename(icon24x24),
|
||||
instance(instance_),
|
||||
sharedDatasInstance(sharedDatasInstance_),
|
||||
isEventBased(false) {
|
||||
sharedDatasInstance(sharedDatasInstance_) {
|
||||
SetFullName(gd::String(fullname_));
|
||||
SetDescription(gd::String(description_));
|
||||
SetDefaultName(gd::String(defaultName_));
|
||||
@@ -52,29 +51,6 @@ BehaviorMetadata::BehaviorMetadata(
|
||||
if (sharedDatasInstance) sharedDatasInstance->SetTypeName(nameWithNamespace);
|
||||
}
|
||||
|
||||
BehaviorMetadata::BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
const gd::String& nameWithNamespace,
|
||||
const gd::String& fullname_,
|
||||
const gd::String& defaultName_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon24x24_): BehaviorMetadata(
|
||||
extensionNamespace,
|
||||
nameWithNamespace,
|
||||
fullname_,
|
||||
defaultName_,
|
||||
description_,
|
||||
group_,
|
||||
icon24x24_,
|
||||
// Class name is the name, actually unused
|
||||
defaultName_,
|
||||
// It is only used to get the name for GetName.
|
||||
gd::make_unique<gd::Behavior>("", nameWithNamespace),
|
||||
nullptr){
|
||||
isEventBased = true;
|
||||
};
|
||||
|
||||
gd::InstructionMetadata& BehaviorMetadata::AddCondition(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
@@ -420,10 +396,6 @@ const gd::String& BehaviorMetadata::GetName() const {
|
||||
}
|
||||
|
||||
gd::Behavior& BehaviorMetadata::Get() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
if (!instance) {
|
||||
gd::LogFatalError(
|
||||
"Trying to get a behavior from a BehaviorMetadata that has no "
|
||||
@@ -434,11 +406,20 @@ gd::Behavior& BehaviorMetadata::Get() const {
|
||||
}
|
||||
|
||||
gd::BehaviorsSharedData* BehaviorMetadata::GetSharedDataInstance() const {
|
||||
if (isEventBased) {
|
||||
gd::LogFatalError("Error: Event-based behaviors don't have blueprint. "
|
||||
"This method should not never be called.");
|
||||
}
|
||||
return sharedDatasInstance.get();
|
||||
}
|
||||
|
||||
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
|
||||
|
@@ -3,8 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef BEHAVIORMETADATA_H
|
||||
#define BEHAVIORMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "InstructionOrExpressionContainerMetadata.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
@@ -25,7 +27,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API BehaviorMetadata {
|
||||
class GD_CORE_API BehaviorMetadata : public InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
BehaviorMetadata(
|
||||
const gd::String& extensionNamespace,
|
||||
@@ -67,7 +69,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior.
|
||||
@@ -80,7 +82,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior.
|
||||
@@ -91,7 +93,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior.
|
||||
@@ -102,7 +104,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
/**
|
||||
* Declare a new action as being part of the extension.
|
||||
*/
|
||||
@@ -110,7 +112,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new string expression as being part of the extension.
|
||||
@@ -119,7 +121,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
@@ -134,7 +136,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
@@ -151,7 +153,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
@@ -160,7 +162,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
@@ -170,7 +172,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
const gd::String& copiedConditionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new expression which is the duplicate of the specified one.
|
||||
@@ -193,9 +195,9 @@ class GD_CORE_API BehaviorMetadata {
|
||||
const gd::String& newExpressionName,
|
||||
const gd::String& copiedExpressionName);
|
||||
|
||||
BehaviorMetadata& SetFullName(const gd::String& fullname_);
|
||||
BehaviorMetadata& SetFullName(const gd::String& fullname_) override;
|
||||
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
|
||||
BehaviorMetadata& SetDescription(const gd::String& description_);
|
||||
BehaviorMetadata& SetDescription(const gd::String& description_) override;
|
||||
BehaviorMetadata& SetGroup(const gd::String& group_);
|
||||
|
||||
/**
|
||||
@@ -203,12 +205,12 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
*/
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
BehaviorMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing required files.
|
||||
@@ -221,7 +223,7 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
const gd::String& GetHelpPath() const override { return helpPath; }
|
||||
|
||||
/**
|
||||
* Set the help path of the behavior, relative to the GDevelop documentation
|
||||
@@ -230,17 +232,17 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* The behavior instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
BehaviorMetadata& SetHelpPath(const gd::String& path) {
|
||||
BehaviorMetadata& SetHelpPath(const gd::String& path) override {
|
||||
helpPath = path;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gd::String& GetName() const;
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
const gd::String& GetName() const override;
|
||||
const gd::String& GetFullName() const override { return fullname; }
|
||||
const gd::String& GetDefaultName() const { return defaultName; }
|
||||
const gd::String& GetDescription() const { return description; }
|
||||
const gd::String& GetDescription() const override { return description; }
|
||||
const gd::String& GetGroup() const { return group; }
|
||||
const gd::String& GetIconFilename() const { return iconFilename; }
|
||||
const gd::String& GetIconFilename() const override { return iconFilename; }
|
||||
|
||||
/**
|
||||
* \brief Set the type of the object that this behavior can be used on.
|
||||
@@ -257,6 +259,11 @@ class GD_CORE_API BehaviorMetadata {
|
||||
*/
|
||||
const gd::String& GetObjectType() const { return objectType; }
|
||||
|
||||
/**
|
||||
* \brief Get the types of the behaviors that are required by this behavior.
|
||||
*/
|
||||
const std::vector<gd::String>& GetRequiredBehaviorTypes() const;
|
||||
|
||||
/**
|
||||
* Check if the behavior is private - it can't be used outside of its
|
||||
* extension.
|
||||
@@ -272,6 +279,21 @@ class GD_CORE_API BehaviorMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the behavior is hidden - it can be used but not attached to
|
||||
* objects by users.
|
||||
*/
|
||||
bool IsHidden() const { return isHidden; }
|
||||
|
||||
/**
|
||||
* Set that the behavior is hidden - it can be used but not attached to
|
||||
* objects by users.
|
||||
*/
|
||||
BehaviorMetadata &SetHidden() {
|
||||
isHidden = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the associated gd::Behavior, handling behavior contents.
|
||||
*
|
||||
@@ -293,22 +315,22 @@ class GD_CORE_API BehaviorMetadata {
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() override { return actionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() override { return conditionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() override { return expressionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
|
||||
|
||||
std::map<gd::String, gd::InstructionMetadata> conditionsInfos;
|
||||
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
|
||||
@@ -328,14 +350,13 @@ class GD_CORE_API BehaviorMetadata {
|
||||
gd::String group;
|
||||
gd::String iconFilename;
|
||||
gd::String objectType;
|
||||
mutable std::vector<gd::String> requiredBehaviors;
|
||||
bool isPrivate = false;
|
||||
bool isHidden = false;
|
||||
|
||||
// TODO: Nitpicking: convert these to std::unique_ptr to clarify ownership.
|
||||
std::shared_ptr<gd::Behavior> instance;
|
||||
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance;
|
||||
bool isEventBased;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // BEHAVIORMETADATA_H
|
||||
|
@@ -62,7 +62,7 @@ class GD_CORE_API DependencyMetadata {
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Sets the type of dependecy (what will be used to install it)
|
||||
* \brief Sets the type of dependency (what will be used to install it)
|
||||
*
|
||||
* This can either be "npm" or "cordova" for now.
|
||||
*/
|
||||
|
@@ -7,9 +7,6 @@
|
||||
|
||||
namespace gd {
|
||||
|
||||
EffectMetadata::EffectMetadata(const gd::String& type_)
|
||||
: type(type_), isMarkedAsNotWorkingForObjects(false) {}
|
||||
|
||||
EffectMetadata& EffectMetadata::SetIncludeFile(const gd::String& includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
@@ -23,9 +20,4 @@ EffectMetadata& EffectMetadata::AddIncludeFile(const gd::String& includeFile) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
EffectMetadata& EffectMetadata::MarkAsNotWorkingForObjects() {
|
||||
isMarkedAsNotWorkingForObjects = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EFFECTMETADATA_H
|
||||
#define EFFECTMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -25,21 +25,25 @@ class GD_CORE_API EffectMetadata {
|
||||
/**
|
||||
* \brief Construct an effect metadata, with the given type
|
||||
*/
|
||||
EffectMetadata(const gd::String& type_);
|
||||
EffectMetadata(const gd::String &type_)
|
||||
: type(type_), isMarkedAsNotWorkingForObjects(false),
|
||||
isMarkedAsOnlyWorkingFor2D(false), isMarkedAsOnlyWorkingFor3D(false),
|
||||
isMarkedAsUnique(false) {}
|
||||
|
||||
/**
|
||||
* \brief Default constructor, only used for initializing `badEffectMetadata`.
|
||||
*/
|
||||
EffectMetadata() {}
|
||||
/**
|
||||
* \brief Default constructor, only used for initializing
|
||||
* `badEffectMetadata`.
|
||||
*/
|
||||
EffectMetadata() {}
|
||||
|
||||
virtual ~EffectMetadata(){};
|
||||
virtual ~EffectMetadata(){};
|
||||
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
EffectMetadata& SetFullName(const gd::String& fullname_) {
|
||||
fullname = fullname_;
|
||||
return *this;
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
EffectMetadata &SetFullName(const gd::String &fullname_) {
|
||||
fullname = fullname_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,11 +73,6 @@ class GD_CORE_API EffectMetadata {
|
||||
*/
|
||||
EffectMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as not working as an object effect.
|
||||
*/
|
||||
EffectMetadata& MarkAsNotWorkingForObjects();
|
||||
|
||||
/**
|
||||
* \brief Return a reference to the properties of this effect.
|
||||
*/
|
||||
@@ -117,10 +116,65 @@ class GD_CORE_API EffectMetadata {
|
||||
return includeFiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as not working as an object effect.
|
||||
*/
|
||||
EffectMetadata& MarkAsNotWorkingForObjects() {
|
||||
isMarkedAsNotWorkingForObjects = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only working for the 2D renderer.
|
||||
*/
|
||||
EffectMetadata& MarkAsOnlyWorkingFor2D() {
|
||||
isMarkedAsOnlyWorkingFor2D = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only working for the 3D renderer.
|
||||
*/
|
||||
EffectMetadata& MarkAsOnlyWorkingFor3D() {
|
||||
isMarkedAsOnlyWorkingFor3D = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Mark the effect as only addable once.
|
||||
*/
|
||||
EffectMetadata& MarkAsUnique() {
|
||||
isMarkedAsUnique = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as not working as an object effect.
|
||||
*/
|
||||
bool IsMarkedAsNotWorkingForObjects() const { return isMarkedAsNotWorkingForObjects; };
|
||||
bool IsMarkedAsNotWorkingForObjects() const {
|
||||
return isMarkedAsNotWorkingForObjects;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as only working for the 2D renderer.
|
||||
*/
|
||||
bool IsMarkedAsOnlyWorkingFor2D() const {
|
||||
return isMarkedAsOnlyWorkingFor2D;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect is marked as only working for the 3D renderer.
|
||||
*/
|
||||
bool IsMarkedAsOnlyWorkingFor3D() const {
|
||||
return isMarkedAsOnlyWorkingFor3D;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check if the effect can only be added once.
|
||||
*/
|
||||
bool IsMarkedAsUnique() const {
|
||||
return isMarkedAsUnique;
|
||||
};
|
||||
|
||||
private:
|
||||
gd::String extensionNamespace;
|
||||
@@ -130,8 +184,10 @@ class GD_CORE_API EffectMetadata {
|
||||
gd::String description;
|
||||
std::vector<gd::String> includeFiles;
|
||||
bool isMarkedAsNotWorkingForObjects;
|
||||
bool isMarkedAsOnlyWorkingFor2D;
|
||||
bool isMarkedAsOnlyWorkingFor3D;
|
||||
bool isMarkedAsUnique;
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // EFFECTMETADATA_H
|
||||
|
@@ -3,9 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef EXPRESSIONMETADATA_H
|
||||
#define EXPRESSIONMETADATA_H
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#pragma once
|
||||
|
||||
#include "AbstractFunctionMetadata.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
@@ -17,7 +18,6 @@ class Layout;
|
||||
}
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Information about how generate code for an expression
|
||||
*/
|
||||
@@ -27,79 +27,7 @@ class ExpressionCodeGenerationInformation {
|
||||
: staticFunction(false), hasCustomCodeGenerator(false){};
|
||||
virtual ~ExpressionCodeGenerationInformation(){};
|
||||
|
||||
/**
|
||||
* \brief Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetFunctionName(
|
||||
const gd::String& functionName) {
|
||||
functionCallName = functionName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set that the function is static
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetStatic() {
|
||||
staticFunction = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& AddIncludeFile(
|
||||
const gd::String& includeFile) {
|
||||
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
|
||||
includeFiles.end())
|
||||
includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const {
|
||||
return includeFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set that the function must be generated using a custom code
|
||||
* generator.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetCustomCodeGenerator(
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
codeGenerator) {
|
||||
hasCustomCodeGenerator = true;
|
||||
customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation& RemoveCustomCodeGenerator() {
|
||||
hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
emptyFunction;
|
||||
customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
|
||||
|
||||
// TODO Move these attributes to ExpressionMetadata.
|
||||
bool staticFunction;
|
||||
gd::String functionCallName;
|
||||
bool hasCustomCodeGenerator;
|
||||
@@ -107,8 +35,6 @@ class ExpressionCodeGenerationInformation {
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
customCodeGenerator;
|
||||
|
||||
private:
|
||||
std::vector<gd::String> includeFiles;
|
||||
};
|
||||
|
||||
@@ -118,7 +44,7 @@ class ExpressionCodeGenerationInformation {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ExpressionMetadata {
|
||||
class GD_CORE_API ExpressionMetadata : public gd::AbstractFunctionMetadata {
|
||||
public:
|
||||
/**
|
||||
* Construct a new expression metadata.
|
||||
@@ -144,7 +70,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* \brief Set the expression as not shown in the IDE.
|
||||
*/
|
||||
ExpressionMetadata& SetHidden();
|
||||
ExpressionMetadata& SetHidden() override;
|
||||
|
||||
/**
|
||||
* \brief Set the group of the instruction in the IDE.
|
||||
@@ -179,7 +105,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
* Set that the instruction is private - it can't be used outside of the
|
||||
* object/ behavior that it is attached too.
|
||||
*/
|
||||
ExpressionMetadata& SetPrivate() {
|
||||
ExpressionMetadata& SetPrivate() override {
|
||||
isPrivate = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -216,7 +142,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForLayoutEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
relevantContext = "Layout";
|
||||
return *this;
|
||||
}
|
||||
@@ -224,7 +150,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForFunctionEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
relevantContext = "Function";
|
||||
return *this;
|
||||
}
|
||||
@@ -232,7 +158,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
relevantContext = "AsynchronousFunction";
|
||||
return *this;
|
||||
}
|
||||
@@ -240,7 +166,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
ExpressionMetadata &SetRelevantForCustomObjectEventsOnly() {
|
||||
ExpressionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
relevantContext = "Object";
|
||||
return *this;
|
||||
}
|
||||
@@ -248,17 +174,17 @@ class GD_CORE_API ExpressionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddParameter
|
||||
*/
|
||||
gd::ExpressionMetadata& AddParameter(
|
||||
const gd::String& type,
|
||||
const gd::String& description,
|
||||
const gd::String& supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
gd::ExpressionMetadata &
|
||||
AddParameter(const gd::String &type, const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) override;
|
||||
|
||||
/**
|
||||
* \see gd::InstructionMetadata::AddCodeOnlyParameter
|
||||
*/
|
||||
gd::ExpressionMetadata& AddCodeOnlyParameter(
|
||||
const gd::String& type, const gd::String& supplementaryInformation);
|
||||
gd::ExpressionMetadata &
|
||||
AddCodeOnlyParameter(const gd::String &type,
|
||||
const gd::String &supplementaryInformation) override;
|
||||
|
||||
/**
|
||||
* Set the default value used in editor (or if an optional parameter is empty
|
||||
@@ -266,8 +192,9 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata& SetDefaultValue(gd::String defaultValue_) {
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
ExpressionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetDefaultValue(defaultValue);
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -277,7 +204,8 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata& SetParameterLongDescription(gd::String longDescription) {
|
||||
ExpressionMetadata &
|
||||
SetParameterLongDescription(const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
@@ -290,7 +218,8 @@ class GD_CORE_API ExpressionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
ExpressionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
|
||||
ExpressionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
@@ -312,50 +241,6 @@ class GD_CORE_API ExpressionMetadata {
|
||||
return requiredBaseObjectCapability;
|
||||
};
|
||||
|
||||
/**
|
||||
* \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`.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& SetFunctionName(
|
||||
const gd::String& functionName) {
|
||||
return codeExtraInformation.SetFunctionName(functionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the expression.
|
||||
*/
|
||||
ExpressionCodeGenerationInformation& GetCodeExtraInformation() {
|
||||
return codeExtraInformation;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.SetIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.AddIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const {
|
||||
return codeExtraInformation.GetIncludeFiles();
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation codeExtraInformation;
|
||||
|
||||
bool IsShown() const { return shown; }
|
||||
const gd::String& GetReturnType() const { return returnType; }
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
@@ -375,6 +260,99 @@ class GD_CORE_API ExpressionMetadata {
|
||||
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the function name which will be used when generating the code.
|
||||
* \param functionName the name of the function to call
|
||||
*/
|
||||
ExpressionMetadata& SetFunctionName(
|
||||
const gd::String& functionName) override {
|
||||
codeExtraInformation.functionCallName = functionName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return the name of the function which will be called in the generated code.
|
||||
*/
|
||||
const gd::String &GetFunctionName() {
|
||||
return codeExtraInformation.functionCallName;
|
||||
}
|
||||
/**
|
||||
* \brief Set that the function is static
|
||||
*/
|
||||
ExpressionMetadata& SetStatic() {
|
||||
codeExtraInformation.staticFunction = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExpressionMetadata& SetIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExpressionMetadata& AddIncludeFile(
|
||||
const gd::String& includeFile) override {
|
||||
if (std::find(codeExtraInformation.includeFiles.begin(), codeExtraInformation.includeFiles.end(), includeFile) ==
|
||||
codeExtraInformation.includeFiles.end())
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String>& GetIncludeFiles() const override {
|
||||
return codeExtraInformation.includeFiles;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Set that the function must be generated using a custom code
|
||||
* generator.
|
||||
*/
|
||||
ExpressionMetadata& SetCustomCodeGenerator(
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
codeGenerator) {
|
||||
codeExtraInformation.hasCustomCodeGenerator = true;
|
||||
codeExtraInformation.customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionMetadata& RemoveCustomCodeGenerator() {
|
||||
codeExtraInformation.hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(const std::vector<gd::Expression>& parameters,
|
||||
gd::EventsCodeGenerator& codeGenerator,
|
||||
gd::EventsCodeGenerationContext& context)>
|
||||
emptyFunction;
|
||||
codeExtraInformation.customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return codeExtraInformation.hasCustomCodeGenerator; }
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the expression.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
ExpressionMetadata& GetCodeExtraInformation() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExpressionCodeGenerationInformation codeExtraInformation;
|
||||
|
||||
private:
|
||||
gd::String returnType;
|
||||
gd::String fullname;
|
||||
@@ -391,6 +369,3 @@ class GD_CORE_API ExpressionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
#endif // EXPRESSIONMETADATA_H
|
||||
|
@@ -4,8 +4,10 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef INSTRUCTIONMETADATA_H
|
||||
#define INSTRUCTIONMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "AbstractFunctionMetadata.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@@ -33,7 +35,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API InstructionMetadata {
|
||||
class GD_CORE_API InstructionMetadata : public gd::AbstractFunctionMetadata {
|
||||
public:
|
||||
/**
|
||||
* Construct a new instruction metadata.
|
||||
@@ -96,7 +98,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* Set that the instruction is private - it can't be used outside of the
|
||||
* object/ behavior that it is attached too.
|
||||
*/
|
||||
InstructionMetadata &SetPrivate() {
|
||||
InstructionMetadata &SetPrivate() override {
|
||||
isPrivate = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -133,7 +135,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForLayoutEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
relevantContext = "Layout";
|
||||
return *this;
|
||||
}
|
||||
@@ -141,7 +143,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForFunctionEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
relevantContext = "Function";
|
||||
return *this;
|
||||
}
|
||||
@@ -149,7 +151,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
relevantContext = "AsynchronousFunction";
|
||||
return *this;
|
||||
}
|
||||
@@ -157,7 +159,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
InstructionMetadata &SetRelevantForCustomObjectEventsOnly() {
|
||||
InstructionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
relevantContext = "Object";
|
||||
return *this;
|
||||
}
|
||||
@@ -192,7 +194,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* Used mainly when an instruction is deprecated.
|
||||
*/
|
||||
InstructionMetadata &SetHidden() {
|
||||
InstructionMetadata &SetHidden() override {
|
||||
hidden = true;
|
||||
return *this;
|
||||
}
|
||||
@@ -231,7 +233,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
bool parameterIsOptional = false) override;
|
||||
|
||||
/**
|
||||
* \brief Add a parameter not displayed in editor.
|
||||
@@ -245,7 +247,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* \see EventsCodeGenerator::GenerateParametersCodes
|
||||
*/
|
||||
InstructionMetadata &AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation);
|
||||
const gd::String &type, const gd::String &supplementaryInformation) override;
|
||||
|
||||
/**
|
||||
* \brief Set the default value used in editor (or if an optional parameter is
|
||||
@@ -253,7 +255,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) {
|
||||
InstructionMetadata &SetDefaultValue(const gd::String &defaultValue_) override {
|
||||
if (!parameters.empty()) parameters.back().SetDefaultValue(defaultValue_);
|
||||
return *this;
|
||||
};
|
||||
@@ -265,7 +267,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) {
|
||||
const gd::String &longDescription) override {
|
||||
if (!parameters.empty())
|
||||
parameters.back().SetLongDescription(longDescription);
|
||||
return *this;
|
||||
@@ -278,7 +280,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*
|
||||
* \see AddParameter
|
||||
*/
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) {
|
||||
InstructionMetadata &SetParameterExtraInfo(const gd::String &extraInfo) override {
|
||||
if (!parameters.empty()) parameters.back().SetExtraInfo(extraInfo);
|
||||
return *this;
|
||||
}
|
||||
@@ -382,128 +384,13 @@ class GD_CORE_API InstructionMetadata {
|
||||
/**
|
||||
* \brief Defines information about how generate the code for an instruction
|
||||
*/
|
||||
class ExtraInformation {
|
||||
class ExtraInformation {
|
||||
public:
|
||||
enum AccessType { Reference, MutatorAndOrAccessor, Mutators };
|
||||
ExtraInformation() : accessType(Reference), hasCustomCodeGenerator(false){};
|
||||
virtual ~ExtraInformation(){};
|
||||
|
||||
/**
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName_) {
|
||||
functionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to
|
||||
* call.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName_) {
|
||||
asyncFunctionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare if the instruction being declared is somewhat manipulating in a
|
||||
* standard way.
|
||||
*/
|
||||
ExtraInformation &SetManipulatedType(const gd::String &type_) {
|
||||
type = type_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called
|
||||
* with "number" or "string", this function will tell the code generator the
|
||||
* name of the getter function used to retrieve the data value.
|
||||
*
|
||||
* Usage example:
|
||||
* \code
|
||||
* obj.AddAction("String",
|
||||
* _("Change the string"),
|
||||
* _("Change the string of a text"),
|
||||
* _("the string"),
|
||||
* _("Text"),
|
||||
* "CppPlatform/Extensions/text24.png",
|
||||
* "CppPlatform/Extensions/text_black.png");
|
||||
*
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
|
||||
*
|
||||
* DECLARE_END_OBJECT_ACTION()
|
||||
* \endcode
|
||||
*/
|
||||
ExtraInformation &SetGetter(const gd::String &getter) {
|
||||
optionalAssociatedInstruction = getter;
|
||||
accessType = MutatorAndOrAccessor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExtraInformation &SetMutators(
|
||||
const std::map<gd::String, gd::String> &mutators) {
|
||||
optionalMutators = mutators;
|
||||
accessType = Mutators;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
ExtraInformation &SetIncludeFile(const gd::String &includeFile) {
|
||||
includeFiles.clear();
|
||||
includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ExtraInformation &AddIncludeFile(const gd::String &includeFile) {
|
||||
if (std::find(includeFiles.begin(), includeFiles.end(), includeFile) ==
|
||||
includeFiles.end())
|
||||
includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
return includeFiles;
|
||||
};
|
||||
|
||||
ExtraInformation &SetCustomCodeGenerator(
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
codeGenerator) {
|
||||
hasCustomCodeGenerator = true;
|
||||
customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ExtraInformation &RemoveCustomCodeGenerator() {
|
||||
hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(Instruction & instruction,
|
||||
gd::EventsCodeGenerator & codeGenerator,
|
||||
gd::EventsCodeGenerationContext & context)>
|
||||
emptyFunction;
|
||||
customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return hasCustomCodeGenerator; }
|
||||
|
||||
// TODO Move these attributes to InstructionMetadata.
|
||||
gd::String functionCallName;
|
||||
gd::String asyncFunctionCallName;
|
||||
gd::String type;
|
||||
@@ -512,75 +399,156 @@ class GD_CORE_API InstructionMetadata {
|
||||
std::map<gd::String, gd::String> optionalMutators;
|
||||
bool hasCustomCodeGenerator;
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
customCodeGenerator;
|
||||
|
||||
private:
|
||||
std::vector<gd::String> includeFiles;
|
||||
};
|
||||
ExtraInformation codeExtraInformation; ///< Information about how generate
|
||||
///< code for the instruction
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the instruction.
|
||||
*/
|
||||
ExtraInformation &GetCodeExtraInformation() { return codeExtraInformation; }
|
||||
|
||||
/**
|
||||
* \brief Declare if the instruction being declared is somewhat manipulating
|
||||
* in a standard way. \param type "number" or "string" \note Shortcut for
|
||||
* `codeExtraInformation.SetManipulatedType(type)`.
|
||||
*/
|
||||
ExtraInformation &SetManipulatedType(const gd::String &type_) {
|
||||
return codeExtraInformation.SetManipulatedType(type_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function which will be called in the generated code.
|
||||
* \param functionName the name of the function to call.
|
||||
* \note Shortcut for `codeExtraInformation.SetFunctionName`.
|
||||
*/
|
||||
ExtraInformation &SetFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetFunctionName(functionName);
|
||||
InstructionMetadata &SetFunctionName(const gd::String &functionName_) override {
|
||||
codeExtraInformation.functionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the function, doing asynchronous work, which will be called
|
||||
* in the generated code. This function should return an asynchronous task
|
||||
* (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
* Set the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*
|
||||
* \param functionName the name of the function doing asynchronous work to
|
||||
* call. \note Shortcut for `codeExtraInformation.SetAsyncFunctionName`.
|
||||
* call.
|
||||
*/
|
||||
ExtraInformation &SetAsyncFunctionName(const gd::String &functionName) {
|
||||
return codeExtraInformation.SetAsyncFunctionName(functionName);
|
||||
InstructionMetadata &SetAsyncFunctionName(const gd::String &functionName_) {
|
||||
codeExtraInformation.asyncFunctionCallName = functionName_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the function which will be called in the generated code.
|
||||
*/
|
||||
const gd::String &GetFunctionName() {
|
||||
return codeExtraInformation.functionCallName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the function, doing asynchronous work, which will be
|
||||
* called in the generated code. This function should return an asynchronous
|
||||
* task (i.e: `gdjs.AsyncTask` in the JavaScript runtime).
|
||||
*/
|
||||
const gd::String &GetAsyncFunctionName() {
|
||||
return codeExtraInformation.asyncFunctionCallName;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Declare if the instruction being declared is somewhat manipulating
|
||||
* in a standard way.
|
||||
*
|
||||
* \param type "number" or "string"
|
||||
*/
|
||||
InstructionMetadata &SetManipulatedType(const gd::String &type_) {
|
||||
codeExtraInformation.type = type_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If InstructionMetadata::ExtraInformation::SetManipulatedType was called
|
||||
* with "number" or "string", this function will tell the code generator the
|
||||
* name of the getter function used to retrieve the data value.
|
||||
*
|
||||
* Usage example:
|
||||
* \code
|
||||
* obj.AddAction("String",
|
||||
* _("Change the string"),
|
||||
* _("Change the string of a text"),
|
||||
* _("the string"),
|
||||
* _("Text"),
|
||||
* "CppPlatform/Extensions/text24.png",
|
||||
* "CppPlatform/Extensions/text_black.png");
|
||||
*
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString");
|
||||
*
|
||||
* DECLARE_END_OBJECT_ACTION()
|
||||
* \endcode
|
||||
*/
|
||||
InstructionMetadata &SetGetter(const gd::String &getter) {
|
||||
codeExtraInformation.optionalAssociatedInstruction = getter;
|
||||
codeExtraInformation.accessType = codeExtraInformation.MutatorAndOrAccessor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InstructionMetadata &SetMutators(
|
||||
const std::map<gd::String, gd::String> &mutators) {
|
||||
codeExtraInformation.optionalMutators = mutators;
|
||||
codeExtraInformation.accessType = codeExtraInformation.Mutators;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
*/
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.SetIncludeFile(includeFile);
|
||||
InstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
codeExtraInformation.includeFiles.clear();
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
InstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
codeExtraInformation.AddIncludeFile(includeFile);
|
||||
InstructionMetadata &AddIncludeFile(const gd::String &includeFile) override {
|
||||
if (std::find(codeExtraInformation.includeFiles.begin(), codeExtraInformation.includeFiles.end(), includeFile) ==
|
||||
codeExtraInformation.includeFiles.end())
|
||||
codeExtraInformation.includeFiles.push_back(includeFile);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
return codeExtraInformation.GetIncludeFiles();
|
||||
const std::vector<gd::String> &GetIncludeFiles() const override {
|
||||
return codeExtraInformation.includeFiles;
|
||||
};
|
||||
|
||||
InstructionMetadata &SetCustomCodeGenerator(
|
||||
std::function<gd::String(Instruction &instruction,
|
||||
gd::EventsCodeGenerator &codeGenerator,
|
||||
gd::EventsCodeGenerationContext &context)>
|
||||
codeGenerator) {
|
||||
codeExtraInformation.hasCustomCodeGenerator = true;
|
||||
codeExtraInformation.customCodeGenerator = codeGenerator;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InstructionMetadata &RemoveCustomCodeGenerator() {
|
||||
codeExtraInformation.hasCustomCodeGenerator = false;
|
||||
std::function<gd::String(Instruction & instruction,
|
||||
gd::EventsCodeGenerator & codeGenerator,
|
||||
gd::EventsCodeGenerationContext & context)>
|
||||
emptyFunction;
|
||||
codeExtraInformation.customCodeGenerator = emptyFunction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HasCustomCodeGenerator() const { return codeExtraInformation.hasCustomCodeGenerator; }
|
||||
|
||||
/**
|
||||
* \brief Return the structure containing the information about code
|
||||
* generation for the instruction.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
InstructionMetadata &GetCodeExtraInformation() { return *this; }
|
||||
|
||||
std::vector<ParameterMetadata> parameters;
|
||||
|
||||
private:
|
||||
@@ -604,5 +572,3 @@ class GD_CORE_API InstructionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // INSTRUCTIONMETADATA_H
|
||||
|
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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 <map>
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Behavior;
|
||||
class BehaviorsSharedData;
|
||||
class MultipleInstructionMetadata;
|
||||
class InstructionMetadata;
|
||||
class ExpressionMetadata;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Contains user-friendly information about instructions and expressions
|
||||
* (usually for a behavior or an object).
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
InstructionOrExpressionContainerMetadata(){};
|
||||
virtual ~InstructionOrExpressionContainerMetadata(){};
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior or object.
|
||||
* \deprecated Prefer using `AddScopedCondition`, to properly namespace
|
||||
* the condition.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddCondition(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior or object.
|
||||
* \deprecated Prefer using `AddScopedAction`, to properly namespace
|
||||
* the action.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddAction(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the behavior or object.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddScopedCondition(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_,
|
||||
const gd::String &sentence_, const gd::String &group_,
|
||||
const gd::String &icon_, const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the behavior or object.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddScopedAction(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &sentence_,
|
||||
const gd::String &group_, const gd::String &icon_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
/**
|
||||
* Declare a new action as being part of the extension.
|
||||
*/
|
||||
virtual gd::ExpressionMetadata &
|
||||
AddExpression(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &group_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* Declare a new string expression as being part of the extension.
|
||||
*/
|
||||
virtual gd::ExpressionMetadata &
|
||||
AddStrExpression(const gd::String &name_, const gd::String &fullname_,
|
||||
const gd::String &description_, const gd::String &group_,
|
||||
const gd::String &smallicon_) = 0;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
* behavior.
|
||||
* \note It's recommended to use this function to avoid declaring twice a
|
||||
* similar expression/condition.
|
||||
*/
|
||||
virtual gd::MultipleInstructionMetadata AddExpressionAndCondition(
|
||||
const gd::String &type, const gd::String &name,
|
||||
const gd::String &fullname, const gd::String &description,
|
||||
const gd::String &sentenceName, const gd::String &group,
|
||||
const gd::String &icon) = 0;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
* behavior.
|
||||
* \note The action name is prefixed by "Set" (and the namespace, as the
|
||||
* condition).
|
||||
* \note It's recommended to use this function to avoid declaring 3 times a
|
||||
* similar expression/condition/action.
|
||||
*/
|
||||
virtual gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
|
||||
const gd::String &type, const gd::String &name,
|
||||
const gd::String &fullname, const gd::String &description,
|
||||
const gd::String &sentenceName, const gd::String &group,
|
||||
const gd::String &icon) = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated action that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddDuplicatedAction(const gd::String &newActionName,
|
||||
const gd::String &copiedActionName) = 0;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated condition that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
virtual gd::InstructionMetadata &
|
||||
AddDuplicatedCondition(const gd::String &newConditionName,
|
||||
const gd::String &copiedConditionName) = 0;
|
||||
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetFullName(const gd::String &fullname_) = 0;
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetDescription(const gd::String &description_) = 0;
|
||||
|
||||
/**
|
||||
* \brief Erase any existing include file and add the specified include.
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the behavior.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
AddIncludeFile(const gd::String &includeFile) = 0;
|
||||
|
||||
/**
|
||||
* Get the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*/
|
||||
virtual const gd::String &GetHelpPath() const = 0;
|
||||
|
||||
/**
|
||||
* Set the help path of the behavior, relative to the GDevelop documentation
|
||||
* root.
|
||||
*
|
||||
* The behavior instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
virtual InstructionOrExpressionContainerMetadata &
|
||||
SetHelpPath(const gd::String &path) = 0;
|
||||
|
||||
virtual const gd::String &GetName() const = 0;
|
||||
virtual const gd::String &GetFullName() const = 0;
|
||||
virtual const gd::String &GetDescription() const = 0;
|
||||
virtual const gd::String &GetIconFilename() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
virtual std::map<gd::String, gd::InstructionMetadata> &GetAllActions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::InstructionMetadata> &GetAllConditions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::ExpressionMetadata> &GetAllExpressions() = 0;
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
virtual std::map<gd::String, gd::ExpressionMetadata> &
|
||||
GetAllStrExpressions() = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -135,11 +135,11 @@ MetadataProvider::GetExtensionAndConditionMetadata(const gd::Platform& platform,
|
||||
|
||||
const auto& objects = extension->GetExtensionObjectsTypes();
|
||||
for (const gd::String& extObjectType : objects) {
|
||||
const auto& allObjetsConditions =
|
||||
const auto& allObjectsConditions =
|
||||
extension->GetAllConditionsForObject(extObjectType);
|
||||
if (allObjetsConditions.find(conditionType) != allObjetsConditions.end())
|
||||
if (allObjectsConditions.find(conditionType) != allObjectsConditions.end())
|
||||
return ExtensionAndMetadata<InstructionMetadata>(
|
||||
*extension, allObjetsConditions.find(conditionType)->second);
|
||||
*extension, allObjectsConditions.find(conditionType)->second);
|
||||
}
|
||||
|
||||
const auto& autos = extension->GetBehaviorsTypes();
|
||||
|
@@ -275,6 +275,10 @@ class GD_CORE_API MetadataProvider {
|
||||
return &metadata == &badBehaviorMetadata;
|
||||
}
|
||||
|
||||
static bool IsBadObjectMetadata(const gd::ObjectMetadata& metadata) {
|
||||
return &metadata == &badObjectInfo;
|
||||
}
|
||||
|
||||
virtual ~MetadataProvider();
|
||||
|
||||
private:
|
||||
|
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "MultipleInstructionMetadata.h"
|
||||
|
||||
#include "InstructionMetadata.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
} // namespace gd
|
@@ -3,8 +3,8 @@
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
#define MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/String.h"
|
||||
@@ -21,7 +21,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup PlatformDefinition
|
||||
*/
|
||||
class GD_CORE_API MultipleInstructionMetadata {
|
||||
class GD_CORE_API MultipleInstructionMetadata : public AbstractFunctionMetadata {
|
||||
public:
|
||||
static MultipleInstructionMetadata WithExpressionAndCondition(
|
||||
gd::ExpressionMetadata &expression, gd::InstructionMetadata &condition) {
|
||||
@@ -45,7 +45,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) {
|
||||
bool parameterIsOptional = false) override {
|
||||
if (expression)
|
||||
expression->AddParameter(
|
||||
type, label, supplementaryInformation, parameterIsOptional);
|
||||
@@ -62,7 +62,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::AddCodeOnlyParameter
|
||||
*/
|
||||
MultipleInstructionMetadata &AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation) {
|
||||
const gd::String &type, const gd::String &supplementaryInformation) override {
|
||||
if (expression)
|
||||
expression->AddCodeOnlyParameter(type, supplementaryInformation);
|
||||
if (condition)
|
||||
@@ -74,7 +74,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetDefaultValue
|
||||
*/
|
||||
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) {
|
||||
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) override {
|
||||
if (expression) expression->SetDefaultValue(defaultValue);
|
||||
if (condition) condition->SetDefaultValue(defaultValue);
|
||||
if (action) action->SetDefaultValue(defaultValue);
|
||||
@@ -85,7 +85,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetParameterExtraInfo
|
||||
*/
|
||||
MultipleInstructionMetadata &SetParameterExtraInfo(
|
||||
const gd::String &defaultValue) {
|
||||
const gd::String &defaultValue) override {
|
||||
if (expression) expression->SetParameterExtraInfo(defaultValue);
|
||||
if (condition) condition->SetParameterExtraInfo(defaultValue);
|
||||
if (action) action->SetParameterExtraInfo(defaultValue);
|
||||
@@ -96,7 +96,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetParameterLongDescription
|
||||
*/
|
||||
MultipleInstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) {
|
||||
const gd::String &longDescription) override {
|
||||
if (expression) expression->SetParameterLongDescription(longDescription);
|
||||
if (condition) condition->SetParameterLongDescription(longDescription);
|
||||
if (action) action->SetParameterLongDescription(longDescription);
|
||||
@@ -106,7 +106,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetHidden
|
||||
*/
|
||||
MultipleInstructionMetadata &SetHidden() {
|
||||
MultipleInstructionMetadata &SetHidden() override {
|
||||
if (expression) expression->SetHidden();
|
||||
if (condition) condition->SetHidden();
|
||||
if (action) action->SetHidden();
|
||||
@@ -136,47 +136,47 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) {
|
||||
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) override {
|
||||
if (expression) expression->SetFunctionName(functionName);
|
||||
if (condition) condition->SetFunctionName(functionName);
|
||||
if (action) action->GetCodeExtraInformation().SetFunctionName(functionName);
|
||||
if (action) action->SetFunctionName(functionName);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetGetter(const gd::String &getter) {
|
||||
if (expression) expression->SetFunctionName(getter);
|
||||
if (condition) condition->SetFunctionName(getter);
|
||||
if (action) action->GetCodeExtraInformation().SetGetter(getter);
|
||||
if (action) action->SetGetter(getter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
expression->SetIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
condition->SetIncludeFile(includeFile);
|
||||
if (action) action->SetIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) override {
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
condition->AddIncludeFile(includeFile);
|
||||
if (action) action->AddIncludeFile(includeFile);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the files that must be included to use the instruction.
|
||||
*/
|
||||
const std::vector<gd::String> &GetIncludeFiles() const {
|
||||
const std::vector<gd::String> &GetIncludeFiles() const override {
|
||||
if (expression)
|
||||
return expression->GetCodeExtraInformation().GetIncludeFiles();
|
||||
if (condition)
|
||||
return condition->GetCodeExtraInformation().GetIncludeFiles();
|
||||
if (action) return action->GetCodeExtraInformation().GetIncludeFiles();
|
||||
return condition->GetIncludeFiles();
|
||||
if (action) return action->GetIncludeFiles();
|
||||
// It can't actually happen.
|
||||
throw std::logic_error("no instruction metadata");
|
||||
}
|
||||
@@ -184,7 +184,7 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
/**
|
||||
* \see gd::InstructionMetadata::SetPrivate
|
||||
*/
|
||||
MultipleInstructionMetadata &SetPrivate() {
|
||||
MultipleInstructionMetadata &SetPrivate() override {
|
||||
if (expression) expression->SetPrivate();
|
||||
if (condition) condition->SetPrivate();
|
||||
if (action) action->SetPrivate();
|
||||
@@ -218,6 +218,42 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in layouts or external events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForLayoutEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForLayoutEventsOnly();
|
||||
if (action) action->SetRelevantForLayoutEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in function events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForFunctionEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForFunctionEventsOnly();
|
||||
if (action) action->SetRelevantForFunctionEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in asynchronous function events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForAsynchronousFunctionEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForAsynchronousFunctionEventsOnly();
|
||||
if (action) action->SetRelevantForAsynchronousFunctionEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that the instruction can be used in custom object events.
|
||||
*/
|
||||
MultipleInstructionMetadata &SetRelevantForCustomObjectEventsOnly() override {
|
||||
if (condition) condition->SetRelevantForCustomObjectEventsOnly();
|
||||
if (action) action->SetRelevantForCustomObjectEventsOnly();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Don't use, only here to fulfill Emscripten bindings requirements.
|
||||
*/
|
||||
@@ -242,5 +278,3 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // MULTIPLEINSTRUCTIONSMETADATA_H
|
||||
|
@@ -3,8 +3,10 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#ifndef OBJECTMETADATA_H
|
||||
#define OBJECTMETADATA_H
|
||||
#pragma once
|
||||
|
||||
#include "InstructionOrExpressionContainerMetadata.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -32,7 +34,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup Events
|
||||
*/
|
||||
class GD_CORE_API ObjectMetadata {
|
||||
class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetadata {
|
||||
public:
|
||||
/**
|
||||
* \brief Construct an object metadata, using a "blueprint" object that will
|
||||
@@ -57,7 +59,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
|
||||
/**
|
||||
* \brief Construct an object metadata, with a function that will be called
|
||||
* to instanciate a new object.
|
||||
* to instantiate a new object.
|
||||
*/
|
||||
ObjectMetadata(const gd::String& extensionNamespace_,
|
||||
const gd::String& name_,
|
||||
@@ -79,7 +81,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new action as being part of the extension.
|
||||
@@ -92,7 +94,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new condition as being part of the object.
|
||||
@@ -103,7 +105,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* Declare a new action as being part of the object.
|
||||
@@ -114,7 +116,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& sentence_,
|
||||
const gd::String& group_,
|
||||
const gd::String& icon_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression as being part of the extension.
|
||||
@@ -123,7 +125,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
/**
|
||||
* \brief Declare a new string expression as being part of the extension.
|
||||
*/
|
||||
@@ -131,7 +133,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& fullname_,
|
||||
const gd::String& description_,
|
||||
const gd::String& group_,
|
||||
const gd::String& smallicon_);
|
||||
const gd::String& smallicon_) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression and condition as being part of the
|
||||
@@ -146,7 +148,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Declare a new expression, condition and action as being part of the
|
||||
@@ -163,7 +165,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& description,
|
||||
const gd::String& sentenceName,
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
const gd::String& icon) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
@@ -172,7 +174,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) override;
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
@@ -182,23 +184,23 @@ class GD_CORE_API ObjectMetadata {
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
const gd::String& copiedConditionName) override;
|
||||
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
ObjectMetadata& SetFullName(const gd::String& fullname_);
|
||||
ObjectMetadata& SetFullName(const gd::String& fullname_) override;
|
||||
|
||||
/**
|
||||
* \brief Set the description shown to the user.
|
||||
*/
|
||||
ObjectMetadata& SetDescription(const gd::String& description_);
|
||||
ObjectMetadata& SetDescription(const gd::String& description_) override;
|
||||
|
||||
/**
|
||||
* \brief Get the help path of the object, relative to the GDevelop
|
||||
* documentation root.
|
||||
*/
|
||||
const gd::String& GetHelpPath() const { return helpPath; }
|
||||
const gd::String& GetHelpPath() const override { return helpPath; }
|
||||
|
||||
/**
|
||||
* \brief Set the help path of the object, relative to the GDevelop
|
||||
@@ -207,7 +209,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
* The object instructions will have this help path set by
|
||||
* default, unless you call SetHelpPath on them.
|
||||
*/
|
||||
ObjectMetadata& SetHelpPath(const gd::String& path) {
|
||||
ObjectMetadata& SetHelpPath(const gd::String& path) override {
|
||||
helpPath = path;
|
||||
return *this;
|
||||
}
|
||||
@@ -222,38 +224,34 @@ class GD_CORE_API ObjectMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief The "capabilities" that are offered by the base object that are
|
||||
* *not* supported by this object, and should be hidden in the editor
|
||||
* inferface.
|
||||
* \brief The "capabilities" that are offered by through behaviors.
|
||||
*/
|
||||
const std::set<gd::String>& GetUnsupportedBaseObjectCapabilities() const {
|
||||
return unsupportedBaseObjectCapabilities;
|
||||
const std::set<gd::String>& GetDefaultBehaviors() const {
|
||||
return defaultBehaviorTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a "capability" that is offered by the base object that is *not*
|
||||
* supported by this object, and should be hidden in the editor inferface.
|
||||
* \brief Return true if object has a default behavior of the given type.
|
||||
*/
|
||||
ObjectMetadata& AddUnsupportedBaseObjectCapability(
|
||||
const gd::String& capability) {
|
||||
unsupportedBaseObjectCapabilities.insert(capability);
|
||||
bool HasDefaultBehavior(const gd::String& behaviorType) const {
|
||||
return defaultBehaviorTypes.find(behaviorType) != defaultBehaviorTypes.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a "capability" that is offered by through a behavior.
|
||||
*/
|
||||
ObjectMetadata& AddDefaultBehavior(
|
||||
const gd::String& behaviorType) {
|
||||
defaultBehaviorTypes.insert(behaviorType);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if a "capability" that is offered by the base object is *not*
|
||||
* supported by this object, and should be hidden in the editor inferface.
|
||||
*/
|
||||
bool IsUnsupportedBaseObjectCapability(const gd::String& capability) const {
|
||||
return unsupportedBaseObjectCapabilities.find(capability) != unsupportedBaseObjectCapabilities.end();
|
||||
}
|
||||
|
||||
const gd::String& GetName() const { return name; }
|
||||
const gd::String& GetFullName() const { return fullname; }
|
||||
const gd::String& GetName() const override { return name; }
|
||||
const gd::String& GetFullName() const override { return fullname; }
|
||||
const gd::String& GetCategoryFullName() const { return categoryFullName; }
|
||||
const gd::String& GetHelpUrl() const { return helpUrl; }
|
||||
const gd::String& GetDescription() const { return description; }
|
||||
const gd::String& GetIconFilename() const { return iconFilename; }
|
||||
const gd::String& GetDescription() const override { return description; }
|
||||
const gd::String& GetIconFilename() const override { return iconFilename; }
|
||||
|
||||
/**
|
||||
* \brief Set the URL pointing to the help page about this object
|
||||
@@ -267,33 +265,33 @@ class GD_CORE_API ObjectMetadata {
|
||||
* \note The requirement may vary depending on the platform: Most of the time,
|
||||
* the include file contains the declaration of the object.
|
||||
*/
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile);
|
||||
ObjectMetadata& SetIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Add a file to the already existing include files.
|
||||
*/
|
||||
ObjectMetadata& AddIncludeFile(const gd::String& includeFile);
|
||||
ObjectMetadata& AddIncludeFile(const gd::String& includeFile) override;
|
||||
|
||||
/**
|
||||
* \brief Return a reference to a map containing the names of the actions
|
||||
* (as keys) and the metadata associated with (as values).
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() { return actionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllActions() override { return actionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() { return conditionsInfos; };
|
||||
std::map<gd::String, gd::InstructionMetadata>& GetAllConditions() override { return conditionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() { return expressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllExpressions() override { return expressionsInfos; };
|
||||
|
||||
/**
|
||||
* \see gd::PlatformExtension::GetAllActions
|
||||
*/
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() { return strExpressionsInfos; };
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions() override { return strExpressionsInfos; };
|
||||
|
||||
/**
|
||||
* \brief Set the object to be hidden in the IDE.
|
||||
@@ -329,7 +327,7 @@ class GD_CORE_API ObjectMetadata {
|
||||
gd::String description;
|
||||
gd::String iconFilename;
|
||||
gd::String categoryFullName;
|
||||
std::set<gd::String> unsupportedBaseObjectCapabilities;
|
||||
std::set<gd::String> defaultBehaviorTypes;
|
||||
bool hidden = false;
|
||||
|
||||
std::shared_ptr<gd::ObjectConfiguration>
|
||||
@@ -341,4 +339,3 @@ class GD_CORE_API ObjectMetadata {
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
#endif // OBJECTMETADATA_H
|
||||
|
@@ -209,10 +209,10 @@ class GD_CORE_API ParameterMetadata {
|
||||
* \brief Return the expression type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
* \deprecated Use gd::ValueTypeMetadata instead.
|
||||
* \deprecated Use gd::ValueTypeMetadata or gd::GetExpressionPrimitiveValueType instead.
|
||||
*/
|
||||
static const gd::String &GetExpressionValueType(const gd::String ¶meterType) {
|
||||
return gd::ValueTypeMetadata::GetPrimitiveValueType(parameterType);
|
||||
return gd::ValueTypeMetadata::GetExpressionPrimitiveValueType(parameterType);
|
||||
}
|
||||
|
||||
/** \name Serialization
|
||||
|
@@ -11,6 +11,8 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "InstructionMetadata.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
|
||||
|
||||
namespace gd {
|
||||
void ParameterMetadataTools::ParametersToObjectsContainer(
|
||||
@@ -101,6 +103,56 @@ void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
}
|
||||
}
|
||||
|
||||
void ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer, FunctionCallNode &node,
|
||||
std::function<void(const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex, const gd::String &lastObjectName)>
|
||||
fn) {
|
||||
gd::String lastObjectName = node.objectName;
|
||||
|
||||
const bool isObjectFunction = !node.objectName.empty();
|
||||
const gd::ExpressionMetadata &metadata =
|
||||
isObjectFunction ? MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform,
|
||||
GetTypeOfObject(globalObjectsContainer,
|
||||
objectsContainer, node.objectName),
|
||||
node.functionName)
|
||||
: MetadataProvider::GetAnyExpressionMetadata(
|
||||
platform, node.functionName);
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t parameterIndex = 0;
|
||||
for (size_t metadataIndex = (isObjectFunction ? 1 : 0);
|
||||
metadataIndex < metadata.parameters.size() &&
|
||||
parameterIndex < node.parameters.size();
|
||||
++metadataIndex) {
|
||||
auto ¶meterMetadata = metadata.parameters[metadataIndex];
|
||||
if (parameterMetadata.IsCodeOnly()) {
|
||||
continue;
|
||||
}
|
||||
auto ¶meterNode = node.parameters[parameterIndex];
|
||||
++parameterIndex;
|
||||
|
||||
fn(parameterMetadata, parameterNode, parameterIndex, lastObjectName);
|
||||
|
||||
// Memorize the last object name. By convention, parameters that require
|
||||
// an object (mainly, "objectvar" and "behavior") should be placed after
|
||||
// the object in the list of parameters (if possible, just after).
|
||||
// Search "lastObjectName" in the codebase for other place where this
|
||||
// convention is enforced.
|
||||
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()))
|
||||
// Object can't be expressions so it should always be the object name.
|
||||
lastObjectName =
|
||||
gd::ExpressionParser2NodePrinter::PrintNode(*parameterNode);
|
||||
}
|
||||
}
|
||||
|
||||
size_t ParameterMetadataTools::GetObjectParameterIndexFor(
|
||||
const std::vector<gd::ParameterMetadata>& parametersMetadata,
|
||||
size_t parameterIndex) {
|
||||
|
@@ -7,12 +7,16 @@
|
||||
#ifndef ParameterMetadataTools_H
|
||||
#define ParameterMetadataTools_H
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Platform;
|
||||
class Project;
|
||||
class ObjectsContainer;
|
||||
class ParameterMetadata;
|
||||
class Expression;
|
||||
struct FunctionCallNode;
|
||||
struct ExpressionNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -48,6 +52,21 @@ class GD_CORE_API ParameterMetadataTools {
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName)> fn);
|
||||
|
||||
/**
|
||||
* Iterate over the parameters of a FunctionCallNode.
|
||||
* Callback function is called with the parameter metadata, its value
|
||||
* and if applicable the name of the object it's linked to.
|
||||
*/
|
||||
static void IterateOverParametersWithIndex(
|
||||
const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
const gd::ObjectsContainer &objectsContainer, FunctionCallNode &node,
|
||||
std::function<void(const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex,
|
||||
const gd::String &lastObjectName)>
|
||||
fn);
|
||||
|
||||
/**
|
||||
* Given a parameter, return, if applicable, the index of the object parameter
|
||||
* it's linked to.
|
||||
|
@@ -35,17 +35,40 @@ void ValueTypeMetadata::UnserializeFrom(const SerializerElement& element) {
|
||||
|
||||
const gd::String ValueTypeMetadata::numberType = "number";
|
||||
const gd::String ValueTypeMetadata::stringType = "string";
|
||||
const gd::String ValueTypeMetadata::variableType = "variable";
|
||||
const gd::String ValueTypeMetadata::booleanType = "boolean";
|
||||
|
||||
const gd::String &ValueTypeMetadata::GetPrimitiveValueType(const gd::String ¶meterType) {
|
||||
if (parameterType == "number" || gd::ValueTypeMetadata::IsTypeExpression("number", parameterType)) {
|
||||
const gd::String &ValueTypeMetadata::GetExpressionPrimitiveValueType(
|
||||
const gd::String ¶meterType) {
|
||||
if (parameterType == "number" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("number", parameterType)) {
|
||||
return ValueTypeMetadata::numberType;
|
||||
}
|
||||
if (parameterType == "string" || gd::ValueTypeMetadata::IsTypeExpression("string", parameterType)) {
|
||||
if (parameterType == "string" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("string", parameterType)) {
|
||||
return ValueTypeMetadata::stringType;
|
||||
}
|
||||
return parameterType;
|
||||
}
|
||||
|
||||
const gd::String &
|
||||
ValueTypeMetadata::GetPrimitiveValueType(const gd::String ¶meterType) {
|
||||
if (parameterType == "variable" ||
|
||||
gd::ValueTypeMetadata::IsTypeExpression("variable", parameterType)) {
|
||||
return ValueTypeMetadata::variableType;
|
||||
}
|
||||
if (parameterType == "boolean" || parameterType == "yesorno" ||
|
||||
parameterType == "trueorfalse") {
|
||||
return ValueTypeMetadata::booleanType;
|
||||
}
|
||||
// These 2 types are not strings from the code generator point of view,
|
||||
// but it is for event-based extensions.
|
||||
if (parameterType == "key" || parameterType == "mouse") {
|
||||
return ValueTypeMetadata::stringType;
|
||||
}
|
||||
return GetExpressionPrimitiveValueType(parameterType);
|
||||
}
|
||||
|
||||
const gd::String ValueTypeMetadata::numberValueType = "number";
|
||||
const gd::String ValueTypeMetadata::booleanValueType = "boolean";
|
||||
const gd::String ValueTypeMetadata::colorValueType = "color";
|
||||
|
@@ -163,7 +163,6 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
} else if (type == "string") {
|
||||
return parameterType == "string" || parameterType == "layer" ||
|
||||
parameterType == "color" || parameterType == "file" ||
|
||||
parameterType == "joyaxis" ||
|
||||
parameterType == "stringWithSelector" ||
|
||||
parameterType == "sceneName" ||
|
||||
parameterType == "layerEffectName" ||
|
||||
@@ -179,6 +178,16 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
} else if (type == "variable") {
|
||||
return parameterType == "objectvar" || parameterType == "globalvar" ||
|
||||
parameterType == "scenevar";
|
||||
} else if (type == "resource") {
|
||||
return parameterType == "fontResource" ||
|
||||
parameterType == "soundfile" ||
|
||||
parameterType == "musicfile" ||
|
||||
parameterType == "bitmapFontResource" ||
|
||||
parameterType == "imageResource" ||
|
||||
parameterType == "jsonResource" ||
|
||||
parameterType == "tilemapResource" ||
|
||||
parameterType == "tilesetResource" ||
|
||||
parameterType == "model3DResource";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -187,10 +196,23 @@ class GD_CORE_API ValueTypeMetadata {
|
||||
* \brief Return the expression type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
*
|
||||
* \note It only maps string and number types.
|
||||
*/
|
||||
static const gd::String &GetExpressionPrimitiveValueType(const gd::String ¶meterType);
|
||||
|
||||
/**
|
||||
* \brief Return the primitive type from the parameter type.
|
||||
* Declinations of "number" and "string" types (like "forceMultiplier" or
|
||||
* "sceneName") are replaced by "number" and "string".
|
||||
*
|
||||
* \note It also maps variable and boolean types.
|
||||
*/
|
||||
static const gd::String &GetPrimitiveValueType(const gd::String ¶meterType);
|
||||
static const gd::String numberType;
|
||||
static const gd::String stringType;
|
||||
static const gd::String variableType;
|
||||
static const gd::String booleanType;
|
||||
|
||||
/**
|
||||
* \brief Return the ValueTypeMetadata name for a property type.
|
||||
|
@@ -273,25 +273,6 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::BehaviorMetadata& PlatformExtension::AddEventsBasedBehavior(
|
||||
const gd::String& name,
|
||||
const gd::String& fullname,
|
||||
const gd::String& description,
|
||||
const gd::String& group,
|
||||
const gd::String& icon24x24) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
behaviorsInfo[nameWithNamespace] = BehaviorMetadata(GetNameSpace(),
|
||||
nameWithNamespace,
|
||||
fullname,
|
||||
// Default name is the name
|
||||
name,
|
||||
description,
|
||||
group,
|
||||
icon24x24)
|
||||
.SetHelpPath(GetHelpPath());
|
||||
return behaviorsInfo[nameWithNamespace];
|
||||
}
|
||||
|
||||
gd::EffectMetadata& PlatformExtension::AddEffect(const gd::String& name) {
|
||||
gd::String nameWithNamespace = GetNameSpace() + name;
|
||||
effectsMetadata[nameWithNamespace] = EffectMetadata(nameWithNamespace);
|
||||
@@ -653,7 +634,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllActions().begin();
|
||||
it != GetAllActions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllActions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -663,7 +644,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllConditions().begin();
|
||||
it != GetAllConditions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllConditions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -673,7 +654,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllExpressions().begin();
|
||||
it != GetAllExpressions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllExpressions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -683,7 +664,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
GetAllStrExpressions().begin();
|
||||
it != GetAllStrExpressions().end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
GetAllStrExpressions().erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -699,7 +680,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.actionsInfos.begin();
|
||||
it != obj.actionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.actionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -709,7 +690,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.conditionsInfos.begin();
|
||||
it != obj.conditionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.conditionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -719,7 +700,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.expressionsInfos.begin();
|
||||
it != obj.expressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.expressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -729,7 +710,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.strExpressionsInfos.begin();
|
||||
it != obj.strExpressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.strExpressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -746,7 +727,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.actionsInfos.begin();
|
||||
it != obj.actionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.actionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -756,7 +737,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.conditionsInfos.begin();
|
||||
it != obj.conditionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.conditionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -766,7 +747,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.expressionsInfos.begin();
|
||||
it != obj.expressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.expressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
@@ -776,7 +757,7 @@ void PlatformExtension::StripUnimplementedInstructionsAndExpressions() {
|
||||
obj.strExpressionsInfos.begin();
|
||||
it != obj.strExpressionsInfos.end();) {
|
||||
if (it->second.codeExtraInformation.functionCallName.empty() &&
|
||||
!it->second.codeExtraInformation.HasCustomCodeGenerator()) {
|
||||
!it->second.HasCustomCodeGenerator()) {
|
||||
obj.strExpressionsInfos.erase(it++);
|
||||
} else
|
||||
++it;
|
||||
|
@@ -421,6 +421,32 @@ class GD_CORE_API PlatformExtension {
|
||||
*/
|
||||
const gd::String& GetIconUrl() const { return iconUrl; }
|
||||
|
||||
/**
|
||||
* \brief Return keywords that help search engines find this extension.
|
||||
*/
|
||||
const std::vector<gd::String>& GetTags() const { return tags; }
|
||||
|
||||
/**
|
||||
* \brief Set keywords that help search engines find this extension.
|
||||
*/
|
||||
PlatformExtension& SetTags(const gd::String& csvTags) {
|
||||
tags.clear();
|
||||
tags = csvTags.Split(',');
|
||||
for (size_t i = 0; i < tags.size(); i++)
|
||||
{
|
||||
tags[i] = tags[i].Trim().LowerCase();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a keyword that help search engines find this extension.
|
||||
*/
|
||||
PlatformExtension& AddTag(const gd::String& tag) {
|
||||
tags.push_back(tag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the extension is flagged as being deprecated.
|
||||
*/
|
||||
@@ -661,6 +687,7 @@ private:
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation.
|
||||
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
|
||||
std::vector<gd::String> tags;
|
||||
|
||||
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
|
||||
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
|
||||
|
@@ -42,7 +42,7 @@ class GD_CORE_API DependenciesAnalyzer {
|
||||
*
|
||||
* You can also call then
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene to check if the
|
||||
* external events can be compiled separatly and called by a scene. \see
|
||||
* external events can be compiled separately and called by a scene. \see
|
||||
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene
|
||||
*/
|
||||
DependenciesAnalyzer(const gd::Project& project_,
|
||||
|
@@ -23,7 +23,7 @@ void ArbitraryEventsWorker::VisitEventList(gd::EventsList& events) {
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size();) {
|
||||
if (VisitEvent(events[i]))
|
||||
if (events[i].AcceptVisitor(*this))
|
||||
events.RemoveEvent(i);
|
||||
else {
|
||||
if (events[i].CanHaveSubEvents())
|
||||
@@ -50,6 +50,10 @@ bool ArbitraryEventsWorker::VisitEvent(gd::BaseEvent& event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ArbitraryEventsWorker::VisitLinkEvent(gd::LinkEvent& linkEvent) {
|
||||
return DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ArbitraryEventsWorker::VisitInstructionList(
|
||||
gd::InstructionsList& instructions, bool areConditions) {
|
||||
DoVisitInstructionList(instructions, areConditions);
|
||||
@@ -80,7 +84,10 @@ void ReadOnlyArbitraryEventsWorker::VisitEventList(const gd::EventsList& events)
|
||||
DoVisitEventList(events);
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
VisitEvent(events[i]);
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
events[i].AcceptVisitor(*this);
|
||||
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
VisitEventList(events[i].GetSubEvents());
|
||||
@@ -94,20 +101,33 @@ void ReadOnlyArbitraryEventsWorker::VisitEvent(const gd::BaseEvent& event) {
|
||||
const vector<const gd::InstructionsList*> conditionsVectors =
|
||||
event.GetAllConditionsVectors();
|
||||
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstructionList(*conditionsVectors[j], true);
|
||||
}
|
||||
|
||||
const vector<const gd::InstructionsList*> actionsVectors = event.GetAllActionsVectors();
|
||||
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstructionList(*actionsVectors[j], false);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitLinkEvent(const gd::LinkEvent& linkEvent) {
|
||||
DoVisitLinkEvent(linkEvent);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::VisitInstructionList(
|
||||
const gd::InstructionsList& instructions, bool areConditions) {
|
||||
DoVisitInstructionList(instructions, areConditions);
|
||||
|
||||
for (std::size_t i = 0; i < instructions.size(); ++i) {
|
||||
if (shouldStopIteration) {
|
||||
break;
|
||||
}
|
||||
VisitInstruction(instructions[i], areConditions);
|
||||
if (!instructions[i].GetSubInstructions().empty()) {
|
||||
VisitInstructionList(instructions[i].GetSubInstructions(),
|
||||
@@ -121,6 +141,10 @@ void ReadOnlyArbitraryEventsWorker::VisitInstruction(const gd::Instruction& inst
|
||||
DoVisitInstruction(instruction, isCondition);
|
||||
}
|
||||
|
||||
void ReadOnlyArbitraryEventsWorker::StopAnyEventIteration() {
|
||||
shouldStopIteration = true;
|
||||
}
|
||||
|
||||
ReadOnlyArbitraryEventsWorkerWithContext::~ReadOnlyArbitraryEventsWorkerWithContext() {}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -9,10 +9,12 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/Events/InstructionsList.h"
|
||||
#include "GDCore/Events/EventVisitor.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class Instruction;
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
class EventsList;
|
||||
class ObjectsContainer;
|
||||
} // namespace gd
|
||||
@@ -28,7 +30,7 @@ namespace gd {
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ArbitraryEventsWorker {
|
||||
class GD_CORE_API ArbitraryEventsWorker : private EventVisitor {
|
||||
public:
|
||||
ArbitraryEventsWorker(){};
|
||||
virtual ~ArbitraryEventsWorker();
|
||||
@@ -40,7 +42,8 @@ class GD_CORE_API ArbitraryEventsWorker {
|
||||
|
||||
private:
|
||||
void VisitEventList(gd::EventsList& events);
|
||||
bool VisitEvent(gd::BaseEvent& event);
|
||||
bool VisitEvent(gd::BaseEvent& event) override;
|
||||
bool VisitLinkEvent(gd::LinkEvent& linkEvent) override;
|
||||
void VisitInstructionList(gd::InstructionsList& instructions,
|
||||
bool areConditions);
|
||||
bool VisitInstruction(gd::Instruction& instruction, bool isCondition);
|
||||
@@ -52,11 +55,21 @@ class GD_CORE_API ArbitraryEventsWorker {
|
||||
|
||||
/**
|
||||
* Called to do some work on an event
|
||||
* \return true if the instruction must be deleted from the events list, false
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise (default).
|
||||
*/
|
||||
virtual bool DoVisitEvent(gd::BaseEvent& event) { return false; };
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that DoVisitEvent is also called with this event.
|
||||
*
|
||||
* \return true if the event must be deleted from the events list, false
|
||||
* otherwise (default).
|
||||
*/
|
||||
virtual bool DoVisitLinkEvent(gd::LinkEvent& event) { return false; };
|
||||
|
||||
/**
|
||||
* Called to do some work on an instruction list
|
||||
*/
|
||||
@@ -129,9 +142,9 @@ class GD_CORE_API ArbitraryEventsWorkerWithContext
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
class GD_CORE_API ReadOnlyArbitraryEventsWorker : private ReadOnlyEventVisitor {
|
||||
public:
|
||||
ReadOnlyArbitraryEventsWorker(){};
|
||||
ReadOnlyArbitraryEventsWorker() : shouldStopIteration(false) {};
|
||||
virtual ~ReadOnlyArbitraryEventsWorker();
|
||||
|
||||
/**
|
||||
@@ -139,9 +152,13 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
void Launch(const gd::EventsList& events) { VisitEventList(events); };
|
||||
|
||||
protected:
|
||||
void StopAnyEventIteration() override;
|
||||
|
||||
private:
|
||||
void VisitEventList(const gd::EventsList& events);
|
||||
void VisitEvent(const gd::BaseEvent& event);
|
||||
void VisitEvent(const gd::BaseEvent& event) override;
|
||||
void VisitLinkEvent(const gd::LinkEvent& linkEvent) override;
|
||||
void VisitInstructionList(const gd::InstructionsList& instructions,
|
||||
bool areConditions);
|
||||
void VisitInstruction(const gd::Instruction& instruction, bool isCondition);
|
||||
@@ -156,6 +173,13 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
virtual void DoVisitEvent(const gd::BaseEvent& event) {};
|
||||
|
||||
/**
|
||||
* Called to do some work on a link event.
|
||||
*
|
||||
* Note that DoVisitEvent is also called with this event.
|
||||
*/
|
||||
virtual void DoVisitLinkEvent(const gd::LinkEvent& linkEvent) {};
|
||||
|
||||
/**
|
||||
* Called to do some work on an instruction list
|
||||
*/
|
||||
@@ -167,6 +191,8 @@ class GD_CORE_API ReadOnlyArbitraryEventsWorker {
|
||||
*/
|
||||
virtual void DoVisitInstruction(const gd::Instruction& instruction,
|
||||
bool isCondition) {};
|
||||
|
||||
bool shouldStopIteration;
|
||||
};
|
||||
|
||||
/**
|
||||
|
23
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.cpp
Normal file
23
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "BehaviorDefaultFlagClearer.h"
|
||||
|
||||
#include "GDCore/Events/Instruction.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
|
||||
#include "GDCore/Project/Behavior.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void BehaviorDefaultFlagClearer::DoVisitObject(gd::Object& object) {
|
||||
};
|
||||
|
||||
void BehaviorDefaultFlagClearer::DoVisitBehavior(gd::Behavior& behavior) {
|
||||
behavior.SetDefaultBehavior(false);
|
||||
};
|
||||
|
||||
BehaviorDefaultFlagClearer::~BehaviorDefaultFlagClearer() {}
|
||||
|
||||
} // namespace gd
|
34
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.h
Normal file
34
Core/GDCore/IDE/Events/BehaviorDefaultFlagClearer.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 <set>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Object;
|
||||
class Behavior;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* @brief This is used for project exports to keep default behaviors in
|
||||
* serialized data used by Runtime.
|
||||
*/
|
||||
class GD_CORE_API BehaviorDefaultFlagClearer : public ArbitraryObjectsWorker {
|
||||
public:
|
||||
BehaviorDefaultFlagClearer() {};
|
||||
virtual ~BehaviorDefaultFlagClearer();
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
void DoVisitBehavior(gd::Behavior& behavior) override;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
175
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.cpp
Normal file
175
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.cpp
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "EventsFunctionSelfCallChecker.h"
|
||||
|
||||
#include "GDCore/Events/Expression.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/Project/EventsBasedBehavior.h"
|
||||
#include "GDCore/Project/EventsBasedObject.h"
|
||||
#include "GDCore/Project/EventsFunction.h"
|
||||
#include "GDCore/Project/EventsFunctionsExtension.h"
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Check the type of the first condition or action.
|
||||
*/
|
||||
class GD_CORE_API FirstInstructionTypeChecker
|
||||
: public ReadOnlyArbitraryEventsWorker {
|
||||
public:
|
||||
FirstInstructionTypeChecker(const gd::String &eventFunctionType_,
|
||||
const bool isEventFunctionCondition_)
|
||||
: eventFunctionType(eventFunctionType_),
|
||||
isEventFunctionCondition(isEventFunctionCondition_),
|
||||
isOnlyCallingItself(false){};
|
||||
virtual ~FirstInstructionTypeChecker(){};
|
||||
|
||||
void DoVisitInstruction(const gd::Instruction &instruction,
|
||||
bool isCondition) override {
|
||||
if (isCondition == isEventFunctionCondition) {
|
||||
isOnlyCallingItself = instruction.GetType() == eventFunctionType;
|
||||
StopAnyEventIteration();
|
||||
}
|
||||
};
|
||||
|
||||
bool isOnlyCallingItself;
|
||||
|
||||
private:
|
||||
gd::String eventFunctionType;
|
||||
bool isEventFunctionCondition;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Check the type of the first condition or action.
|
||||
*/
|
||||
class GD_CORE_API FirstActionExpressionTypeChecker
|
||||
: public ReadOnlyArbitraryEventsWorker,
|
||||
ExpressionParser2NodeWorker {
|
||||
public:
|
||||
FirstActionExpressionTypeChecker(const gd::Platform &platform_,
|
||||
const gd::String &eventFunctionType_)
|
||||
: platform(platform_), eventFunctionType(eventFunctionType_),
|
||||
isOnlyCallingItself(false){};
|
||||
virtual ~FirstActionExpressionTypeChecker(){};
|
||||
|
||||
void DoVisitInstruction(const gd::Instruction &instruction,
|
||||
bool isCondition) override {
|
||||
// Typically, it should be a "return" action.
|
||||
if (!isCondition) {
|
||||
gd::String lastObjectParameter = "";
|
||||
const gd::InstructionMetadata &instrInfos =
|
||||
MetadataProvider::GetActionMetadata(platform, instruction.GetType());
|
||||
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
|
||||
|
||||
if (ParameterMetadata::IsExpression(
|
||||
"number", instrInfos.parameters[pNb].GetType()) ||
|
||||
ParameterMetadata::IsExpression(
|
||||
"string", instrInfos.parameters[pNb].GetType())) {
|
||||
auto node = instruction.GetParameter(pNb).GetRootNode();
|
||||
node->Visit(*this);
|
||||
}
|
||||
}
|
||||
StopAnyEventIteration();
|
||||
}
|
||||
}
|
||||
|
||||
// Only check expressions that directly calls a function.
|
||||
void OnVisitFunctionCallNode(FunctionCallNode &node) override {
|
||||
isOnlyCallingItself |= node.functionName == eventFunctionType;
|
||||
}
|
||||
|
||||
// Handle extra parenthesis.
|
||||
void OnVisitSubExpressionNode(SubExpressionNode &node) override {
|
||||
node.expression->Visit(*this);
|
||||
}
|
||||
void OnVisitOperatorNode(OperatorNode &node) override {}
|
||||
// Handle sign that could have been forgotten
|
||||
void OnVisitUnaryOperatorNode(UnaryOperatorNode &node) override {
|
||||
node.factor->Visit(*this);
|
||||
}
|
||||
void OnVisitNumberNode(NumberNode &node) override {}
|
||||
void OnVisitTextNode(TextNode &node) override {}
|
||||
void OnVisitVariableNode(VariableNode &node) override {}
|
||||
void OnVisitVariableAccessorNode(VariableAccessorNode &node) override {}
|
||||
void OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode &node) override {}
|
||||
void OnVisitIdentifierNode(IdentifierNode &node) override {}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode &node) override {}
|
||||
void OnVisitEmptyNode(EmptyNode &node) override {}
|
||||
|
||||
bool isOnlyCallingItself;
|
||||
|
||||
private:
|
||||
const gd::Platform &platform;
|
||||
gd::String eventFunctionType;
|
||||
};
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsOnlyCallingItself(
|
||||
const gd::Project &project, const gd::String &functionFullType,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
bool isOnlyCallingItself = false;
|
||||
|
||||
if (eventsFunction.IsExpression()) {
|
||||
FirstActionExpressionTypeChecker eventWorker(project.GetCurrentPlatform(),
|
||||
functionFullType);
|
||||
eventWorker.Launch(eventsFunction.GetEvents());
|
||||
isOnlyCallingItself = eventWorker.isOnlyCallingItself;
|
||||
} else {
|
||||
FirstInstructionTypeChecker eventWorker(functionFullType,
|
||||
!eventsFunction.IsAction());
|
||||
eventWorker.Launch(eventsFunction.GetEvents());
|
||||
isOnlyCallingItself = eventWorker.isOnlyCallingItself;
|
||||
}
|
||||
return isOnlyCallingItself;
|
||||
}
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsFreeFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(
|
||||
project,
|
||||
PlatformExtension::GetEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
|
||||
bool EventsFunctionSelfCallChecker::IsBehaviorFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedBehavior &eventsBasedBehavior,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(
|
||||
project,
|
||||
PlatformExtension::GetBehaviorEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(), eventsBasedBehavior.GetName(),
|
||||
eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
bool EventsFunctionSelfCallChecker::IsObjectFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsFunction &eventsFunction) {
|
||||
return IsOnlyCallingItself(project,
|
||||
PlatformExtension::GetObjectEventsFunctionFullType(
|
||||
eventsFunctionsExtension.GetName(),
|
||||
eventsBasedObject.GetName(),
|
||||
eventsFunction.GetName()),
|
||||
eventsFunction);
|
||||
}
|
||||
|
||||
} // namespace gd
|
64
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.h
Normal file
64
Core/GDCore/IDE/Events/EventsFunctionSelfCallChecker.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/String.h"
|
||||
#include <vector>
|
||||
namespace gd {
|
||||
class Project;
|
||||
class EventsFunctionsExtension;
|
||||
class EventsFunctionsContainer;
|
||||
class EventsFunction;
|
||||
class EventsBasedBehavior;
|
||||
class EventsBasedObject;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
/**
|
||||
* \brief Check if functions are only calling themselves.
|
||||
*
|
||||
* It allows to detect mistakes when implementing functions for compatibility
|
||||
* after a function renaming.
|
||||
* Infinite loops can happens when the legacy function call itself instead of
|
||||
* the new function.
|
||||
*
|
||||
* \note Only the first instruction or the expressions of the first action is
|
||||
* checked.
|
||||
*/
|
||||
class GD_CORE_API EventsFunctionSelfCallChecker {
|
||||
public:
|
||||
/**
|
||||
* \brief Check if a free function is only calling itself.
|
||||
*/
|
||||
static bool IsFreeFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
/**
|
||||
* \brief Check if a behavior function is only calling itself.
|
||||
*/
|
||||
static bool IsBehaviorFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedBehavior &eventsBasedBehavior,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
/**
|
||||
* \brief Check if an object function is only calling itself.
|
||||
*/
|
||||
static bool IsObjectFunctionOnlyCallingItself(
|
||||
const gd::Project &project,
|
||||
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
|
||||
const gd::EventsBasedObject &eventsBasedObject,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
|
||||
private:
|
||||
static bool IsOnlyCallingItself(const gd::Project &project,
|
||||
const gd::String &functionFullType,
|
||||
const gd::EventsFunction &eventsFunction);
|
||||
};
|
||||
} // namespace gd
|
@@ -555,6 +555,22 @@ void EventsRefactorer::RemoveObjectInEvents(const gd::Platform& platform,
|
||||
}
|
||||
}
|
||||
|
||||
gd::String ReplaceAllOccurrencesCaseInsensitive(gd::String context,
|
||||
const gd::String& from,
|
||||
const gd::String& to) {
|
||||
size_t lookHere = 0;
|
||||
size_t foundHere;
|
||||
size_t fromSize = from.size();
|
||||
size_t toSize = to.size();
|
||||
while ((foundHere = context.FindCaseInsensitive(from, lookHere)) !=
|
||||
gd::String::npos) {
|
||||
context.replace(foundHere, fromSize, to);
|
||||
lookHere = foundHere + toSize;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
std::vector<EventsSearchResult> EventsRefactorer::ReplaceStringInEvents(
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
@@ -570,6 +586,32 @@ std::vector<EventsSearchResult> EventsRefactorer::ReplaceStringInEvents(
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
bool eventModified = false;
|
||||
|
||||
std::vector<gd::Expression*> allObjectExpressions =
|
||||
events[i].GetAllObjectExpressions();
|
||||
for (std::size_t j = 0; j < allObjectExpressions.size(); ++j) {
|
||||
gd::String newExpressionPlainString =
|
||||
matchCase ? allObjectExpressions[j]->GetPlainString().FindAndReplace(
|
||||
toReplace, newString, true)
|
||||
: ReplaceAllOccurrencesCaseInsensitive(
|
||||
allObjectExpressions[j]->GetPlainString(),
|
||||
toReplace,
|
||||
newString);
|
||||
|
||||
if (newExpressionPlainString !=
|
||||
allObjectExpressions[j]->GetPlainString()) {
|
||||
*allObjectExpressions[j] = gd::Expression(newExpressionPlainString);
|
||||
|
||||
if (!eventModified) {
|
||||
modifiedEvents.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
i));
|
||||
eventModified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inConditions) {
|
||||
vector<gd::InstructionsList*> conditionsVectors =
|
||||
events[i].GetAllConditionsVectors();
|
||||
@@ -642,22 +684,6 @@ std::vector<EventsSearchResult> EventsRefactorer::ReplaceStringInEvents(
|
||||
return modifiedEvents;
|
||||
}
|
||||
|
||||
gd::String ReplaceAllOccurencesCaseUnsensitive(gd::String context,
|
||||
gd::String from,
|
||||
const gd::String& to) {
|
||||
size_t lookHere = 0;
|
||||
size_t foundHere;
|
||||
size_t fromSize = from.size();
|
||||
size_t toSize = to.size();
|
||||
while ((foundHere = context.FindCaseInsensitive(from, lookHere)) !=
|
||||
gd::String::npos) {
|
||||
context.replace(foundHere, fromSize, to);
|
||||
lookHere = foundHere + toSize;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::ReplaceStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
@@ -673,7 +699,7 @@ bool EventsRefactorer::ReplaceStringInActions(gd::ObjectsContainer& project,
|
||||
matchCase
|
||||
? actions[aId].GetParameter(pNb).GetPlainString().FindAndReplace(
|
||||
toReplace, newString, true)
|
||||
: ReplaceAllOccurencesCaseUnsensitive(
|
||||
: ReplaceAllOccurrencesCaseInsensitive(
|
||||
actions[aId].GetParameter(pNb).GetPlainString(),
|
||||
toReplace,
|
||||
newString);
|
||||
@@ -713,7 +739,7 @@ bool EventsRefactorer::ReplaceStringInConditions(
|
||||
.GetParameter(pNb)
|
||||
.GetPlainString()
|
||||
.FindAndReplace(toReplace, newString, true)
|
||||
: ReplaceAllOccurencesCaseUnsensitive(
|
||||
: ReplaceAllOccurrencesCaseInsensitive(
|
||||
conditions[cId].GetParameter(pNb).GetPlainString(),
|
||||
toReplace,
|
||||
newString);
|
||||
@@ -749,7 +775,7 @@ bool EventsRefactorer::ReplaceStringInEventSearchableStrings(
|
||||
for (std::size_t sNb = 0; sNb < stringEvent.size(); ++sNb) {
|
||||
gd::String newStringEvent =
|
||||
matchCase ? stringEvent[sNb].FindAndReplace(toReplace, newString, true)
|
||||
: ReplaceAllOccurencesCaseUnsensitive(
|
||||
: ReplaceAllOccurrencesCaseInsensitive(
|
||||
stringEvent[sNb], toReplace, newString);
|
||||
newEventStrings.push_back(newStringEvent);
|
||||
}
|
||||
@@ -789,6 +815,24 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
bool eventAddedInResults = false;
|
||||
|
||||
std::vector<gd::Expression*> allObjectExpressions =
|
||||
events[i].GetAllObjectExpressions();
|
||||
for (std::size_t j = 0; j < allObjectExpressions.size(); ++j) {
|
||||
size_t foundPosition =
|
||||
matchCase
|
||||
? allObjectExpressions[j]->GetPlainString().find(search)
|
||||
: allObjectExpressions[j]->GetPlainString().FindCaseInsensitive(
|
||||
search);
|
||||
|
||||
if (foundPosition != gd::String::npos && !eventAddedInResults) {
|
||||
results.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
i));
|
||||
eventAddedInResults = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inConditions) {
|
||||
vector<gd::InstructionsList*> conditionsVectors =
|
||||
events[i].GetAllConditionsVectors();
|
||||
@@ -803,6 +847,7 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
i));
|
||||
eventAddedInResults = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -820,6 +865,7 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
i));
|
||||
eventAddedInResults = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,24 +77,34 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(const gd::Functi
|
||||
MetadataProvider::GetBehaviorAnyExpressionMetadata(
|
||||
platform, behaviorType, function.functionName);
|
||||
|
||||
if (!function.objectName.empty()) {
|
||||
// If the function needs a capability on the object that may not be covered
|
||||
// by all objects, check it now.
|
||||
if (!metadata.GetRequiredBaseObjectCapability().empty()) {
|
||||
const gd::ObjectMetadata &objectMetadata =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
Type returnType = StringToType(metadata.GetReturnType());
|
||||
|
||||
if (objectMetadata.IsUnsupportedBaseObjectCapability(
|
||||
metadata.GetRequiredBaseObjectCapability())) {
|
||||
RaiseTypeError(
|
||||
_("This expression exists, but it can't be used on this object."),
|
||||
function.objectNameLocation);
|
||||
return StringToType(metadata.GetReturnType());
|
||||
}
|
||||
}
|
||||
if (!function.objectName.empty() &&
|
||||
!globalObjectsContainer.HasObjectNamed(function.objectName) &&
|
||||
!globalObjectsContainer.GetObjectGroups().Has(function.objectName) &&
|
||||
!objectsContainer.HasObjectNamed(function.objectName) &&
|
||||
!objectsContainer.GetObjectGroups().Has(function.objectName)) {
|
||||
RaiseTypeError(_("This object doesn't exist."),
|
||||
function.objectNameLocation, /*isFatal=*/false);
|
||||
return returnType;
|
||||
}
|
||||
|
||||
Type returnType = StringToType(metadata.GetReturnType());
|
||||
if (!function.behaviorName.empty() &&
|
||||
!gd::HasBehaviorInObjectOrGroup(globalObjectsContainer, objectsContainer,
|
||||
function.objectName,
|
||||
function.behaviorName)) {
|
||||
RaiseTypeError(_("This behavior is not attached to this object."),
|
||||
function.behaviorNameLocation, /*isFatal=*/false);
|
||||
return returnType;
|
||||
}
|
||||
|
||||
if (!function.objectName.empty() &&
|
||||
// If the function needs a capability on the object that may not be covered
|
||||
// by all objects, check it now.
|
||||
!metadata.GetRequiredBaseObjectCapability().empty()) {
|
||||
const gd::ObjectMetadata &objectMetadata =
|
||||
MetadataProvider::GetObjectMetadata(platform, objectType);
|
||||
}
|
||||
|
||||
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata)) {
|
||||
RaiseError(
|
||||
@@ -115,8 +125,8 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(const gd::Functi
|
||||
"number to a string."),
|
||||
function.location);
|
||||
return returnType;
|
||||
}
|
||||
else if (parentType != Type::Number && parentType != Type::NumberOrString) {
|
||||
} else if (parentType != Type::Number &&
|
||||
parentType != Type::NumberOrString) {
|
||||
RaiseTypeError(_("You tried to use an expression that returns a "
|
||||
"number, but another type is expected:") +
|
||||
" " + TypeToString(parentType),
|
||||
@@ -131,8 +141,8 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(const gd::Functi
|
||||
"string to a number."),
|
||||
function.location);
|
||||
return returnType;
|
||||
}
|
||||
else if (parentType != Type::String && parentType != Type::NumberOrString) {
|
||||
} else if (parentType != Type::String &&
|
||||
parentType != Type::NumberOrString) {
|
||||
RaiseTypeError(_("You tried to use an expression that returns a "
|
||||
"string, but another type is expected:") +
|
||||
" " + TypeToString(parentType),
|
||||
@@ -172,8 +182,7 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(const gd::Functi
|
||||
_("You have not entered enough parameters for the expression.") + " " +
|
||||
expectedCountMessage,
|
||||
function.location);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
RaiseError(
|
||||
"extra_parameter",
|
||||
_("This parameter was not expected by this expression. Remove it "
|
||||
@@ -217,8 +226,7 @@ ExpressionValidator::Type ExpressionValidator::ValidateFunction(const gd::Functi
|
||||
"parameter."),
|
||||
parameter->location);
|
||||
}
|
||||
}
|
||||
else if (gd::ParameterMetadata::IsObject(expectedParameterType)) {
|
||||
} else if (gd::ParameterMetadata::IsObject(expectedParameterType)) {
|
||||
if (dynamic_cast<IdentifierNode *>(parameter.get()) == nullptr) {
|
||||
RaiseError(
|
||||
"malformed_object_parameter",
|
||||
|
@@ -45,7 +45,7 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
|
||||
/**
|
||||
* \brief Helper function to check if a given node does not contain
|
||||
* any error.
|
||||
* any error including non-fatal ones.
|
||||
*/
|
||||
static bool HasNoErrors(const gd::Platform &platform,
|
||||
const gd::ObjectsContainer &globalObjectsContainer,
|
||||
@@ -54,16 +54,25 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
gd::ExpressionNode& node) {
|
||||
gd::ExpressionValidator validator(platform, globalObjectsContainer, objectsContainer, rootType);
|
||||
node.Visit(validator);
|
||||
return validator.GetErrors().empty();
|
||||
return validator.GetAllErrors().empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get only the fatal errors
|
||||
*
|
||||
* Expressions with fatal error can't be generated.
|
||||
*/
|
||||
const std::vector<ExpressionParserDiagnostic*>& GetFatalErrors() {
|
||||
return fatalErrors;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Get all the errors
|
||||
*
|
||||
* No errors means that the expression is valid.
|
||||
*/
|
||||
const std::vector<ExpressionParserDiagnostic*>& GetErrors() {
|
||||
return errors;
|
||||
const std::vector<ExpressionParserDiagnostic*>& GetAllErrors() {
|
||||
return allErrors;
|
||||
};
|
||||
|
||||
protected:
|
||||
@@ -150,12 +159,29 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
void OnVisitNumberNode(NumberNode& node) override {
|
||||
ReportAnyError(node);
|
||||
childType = Type::Number;
|
||||
CheckType(parentType, childType, node.location);
|
||||
if (parentType == Type::String) {
|
||||
RaiseTypeError(
|
||||
_("You entered a number, but a text was expected (in quotes)."),
|
||||
node.location);
|
||||
} else if (parentType != Type::Number &&
|
||||
parentType != Type::NumberOrString) {
|
||||
RaiseTypeError(_("You entered a number, but this type was expected:") +
|
||||
" " + TypeToString(parentType),
|
||||
node.location);
|
||||
}
|
||||
}
|
||||
void OnVisitTextNode(TextNode& node) override {
|
||||
ReportAnyError(node);
|
||||
childType = Type::String;
|
||||
CheckType(parentType, childType, node.location);
|
||||
if (parentType == Type::Number) {
|
||||
RaiseTypeError(_("You entered a text, but a number was expected."),
|
||||
node.location);
|
||||
} else if (parentType != Type::String &&
|
||||
parentType != Type::NumberOrString) {
|
||||
RaiseTypeError(_("You entered a text, but this type was expected:") +
|
||||
" " + TypeToString(parentType),
|
||||
node.location);
|
||||
}
|
||||
}
|
||||
void OnVisitVariableNode(VariableNode& node) override {
|
||||
ReportAnyError(node);
|
||||
@@ -163,7 +189,21 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
node.child->Visit(*this);
|
||||
}
|
||||
childType = Type::Variable;
|
||||
CheckType(parentType, childType, node.location);
|
||||
if (parentType == Type::String) {
|
||||
RaiseTypeError(_("Variables must be surrounded by VariableString()."),
|
||||
node.location);
|
||||
} else if (parentType == Type::Number) {
|
||||
RaiseTypeError(_("Variables must be surrounded by Variable()."),
|
||||
node.location);
|
||||
} else if (parentType == Type::NumberOrString) {
|
||||
RaiseTypeError(
|
||||
_("Variables must be surrounded by Variable() or VariableString()."),
|
||||
node.location);
|
||||
} else if (parentType != Type::Variable) {
|
||||
RaiseTypeError(_("You entered a variable, but this type was expected:") +
|
||||
" " + TypeToString(parentType),
|
||||
node.location);
|
||||
}
|
||||
}
|
||||
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
|
||||
ReportAnyError(node);
|
||||
@@ -239,20 +279,26 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
enum Type {Unknown = 0, Number, String, NumberOrString, Variable, Object, Empty};
|
||||
Type ValidateFunction(const gd::FunctionCallNode& function);
|
||||
|
||||
void ReportAnyError(const ExpressionNode& node) {
|
||||
void ReportAnyError(const ExpressionNode& node, bool isFatal = true) {
|
||||
if (node.diagnostic && node.diagnostic->IsError()) {
|
||||
// Syntax errors are holden by the AST nodes.
|
||||
// It's fine to give pointers on them as the AST live longer than errors
|
||||
// handling.
|
||||
errors.push_back(node.diagnostic.get());
|
||||
allErrors.push_back(node.diagnostic.get());
|
||||
if (isFatal) {
|
||||
fatalErrors.push_back(node.diagnostic.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RaiseError(const gd::String &type,
|
||||
const gd::String &message, const ExpressionParserLocation &location) {
|
||||
const gd::String &message, const ExpressionParserLocation &location, bool isFatal = true) {
|
||||
auto diagnostic = gd::make_unique<ExpressionParserError>(
|
||||
type, message, location);
|
||||
errors.push_back(diagnostic.get());
|
||||
allErrors.push_back(diagnostic.get());
|
||||
if (isFatal) {
|
||||
fatalErrors.push_back(diagnostic.get());
|
||||
}
|
||||
// Errors found by the validator are not holden by the AST nodes.
|
||||
// They must be owned by the validator to keep living while errors are
|
||||
// handled by the caller.
|
||||
@@ -260,8 +306,8 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
}
|
||||
|
||||
void RaiseTypeError(
|
||||
const gd::String &message, const ExpressionParserLocation &location) {
|
||||
RaiseError("type_error", message, location);
|
||||
const gd::String &message, const ExpressionParserLocation &location, bool isFatal = true) {
|
||||
RaiseError("type_error", message, location, isFatal);
|
||||
}
|
||||
|
||||
void RaiseOperatorError(
|
||||
@@ -269,32 +315,6 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
RaiseError("invalid_operator", message, location);
|
||||
}
|
||||
|
||||
void CheckType(Type expect, Type actual, const ExpressionParserLocation &location) {
|
||||
if (actual == Type::String) {
|
||||
if (expect == Type::Number) {
|
||||
RaiseTypeError(_("You entered a text, but a number was expected."),
|
||||
location);
|
||||
}
|
||||
else if (expect != Type::String && expect != Type::NumberOrString) {
|
||||
RaiseTypeError(
|
||||
_("You entered a text, but this type was expected:") + " " + TypeToString(expect),
|
||||
location);
|
||||
}
|
||||
}
|
||||
else if (actual == Type::Number) {
|
||||
if (expect == Type::String) {
|
||||
RaiseTypeError(
|
||||
_("You entered a number, but a text was expected (in quotes)."),
|
||||
location);
|
||||
}
|
||||
else if (expect != Type::Number && expect != Type::NumberOrString) {
|
||||
RaiseTypeError(
|
||||
_("You entered a number, but this type was expected:") + " " + TypeToString(expect),
|
||||
location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Type StringToType(const gd::String &type);
|
||||
static const gd::String &TypeToString(Type type);
|
||||
static const gd::String unknownTypeString;
|
||||
@@ -306,7 +326,8 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
|
||||
static const gd::String identifierTypeString;
|
||||
static const gd::String emptyTypeString;
|
||||
|
||||
std::vector<ExpressionParserDiagnostic*> errors;
|
||||
std::vector<ExpressionParserDiagnostic*> fatalErrors;
|
||||
std::vector<ExpressionParserDiagnostic*> allErrors;
|
||||
std::vector<std::unique_ptr<ExpressionParserDiagnostic>> supplementalErrors;
|
||||
Type childType;
|
||||
Type parentType;
|
||||
|
33
Core/GDCore/IDE/Events/LinkEventTargetRenamer.cpp
Normal file
33
Core/GDCore/IDE/Events/LinkEventTargetRenamer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "LinkEventTargetRenamer.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Builtin/LinkEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool LinkEventTargetRenamer::DoVisitLinkEvent(gd::LinkEvent &linkEvent) {
|
||||
|
||||
if (linkEvent.GetTarget() == oldName) {
|
||||
linkEvent.SetTarget(newName);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LinkEventTargetRenamer::~LinkEventTargetRenamer() {}
|
||||
|
||||
} // namespace gd
|
44
Core/GDCore/IDE/Events/LinkEventTargetRenamer.h
Normal file
44
Core/GDCore/IDE/Events/LinkEventTargetRenamer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class LinkEvent;
|
||||
class Platform;
|
||||
class EventsList;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Replace in link events the name of external events.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API LinkEventTargetRenamer
|
||||
: public ArbitraryEventsWorkerWithContext {
|
||||
public:
|
||||
LinkEventTargetRenamer(const gd::Platform &platform_,
|
||||
const gd::String &oldName_, const gd::String &newName_)
|
||||
: platform(platform_), oldName(oldName_), newName(newName_){};
|
||||
virtual ~LinkEventTargetRenamer();
|
||||
|
||||
private:
|
||||
bool DoVisitLinkEvent(gd::LinkEvent &linkEvent) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
gd::String oldName;
|
||||
gd::String newName;
|
||||
};
|
||||
|
||||
} // namespace gd
|
214
Core/GDCore/IDE/Events/ProjectElementRenamer.cpp
Normal file
214
Core/GDCore/IDE/Events/ProjectElementRenamer.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#include "ProjectElementRenamer.h"
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodePrinter.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Go through the nodes and find every function call parameter of a
|
||||
* given type.
|
||||
*
|
||||
* \see gd::ExpressionParser2
|
||||
*/
|
||||
class GD_CORE_API ExpressionIdentifierStringFinder
|
||||
: public ExpressionParser2NodeWorker {
|
||||
public:
|
||||
ExpressionIdentifierStringFinder(
|
||||
const gd::Platform &platform_,
|
||||
const gd::ObjectsContainer &globalObjectsContainer_,
|
||||
const gd::ObjectsContainer &objectsContainer_,
|
||||
const gd::String &expressionPlainString_,
|
||||
const gd::String ¶meterType_, const gd::String &objectName_,
|
||||
const gd::String &layerName_, const gd::String &oldName_)
|
||||
: platform(platform_), globalObjectsContainer(globalObjectsContainer_),
|
||||
objectsContainer(objectsContainer_),
|
||||
expressionPlainString(expressionPlainString_),
|
||||
parameterType(parameterType_), objectName(objectName_),
|
||||
layerName(layerName_), oldName(oldName_){};
|
||||
virtual ~ExpressionIdentifierStringFinder(){};
|
||||
|
||||
const std::vector<gd::ExpressionParserLocation> GetOccurrences() const {
|
||||
return occurrences;
|
||||
}
|
||||
|
||||
protected:
|
||||
void OnVisitSubExpressionNode(SubExpressionNode &node) override {
|
||||
node.expression->Visit(*this);
|
||||
}
|
||||
void OnVisitOperatorNode(OperatorNode &node) override {
|
||||
node.leftHandSide->Visit(*this);
|
||||
node.rightHandSide->Visit(*this);
|
||||
}
|
||||
void OnVisitUnaryOperatorNode(UnaryOperatorNode &node) override {
|
||||
node.factor->Visit(*this);
|
||||
}
|
||||
void OnVisitNumberNode(NumberNode &node) override {}
|
||||
void OnVisitTextNode(TextNode &node) override {}
|
||||
void OnVisitVariableNode(VariableNode &node) override {
|
||||
if (node.child)
|
||||
node.child->Visit(*this);
|
||||
}
|
||||
void OnVisitVariableAccessorNode(VariableAccessorNode &node) override {
|
||||
if (node.child)
|
||||
node.child->Visit(*this);
|
||||
}
|
||||
void OnVisitVariableBracketAccessorNode(
|
||||
VariableBracketAccessorNode &node) override {
|
||||
node.expression->Visit(*this);
|
||||
if (node.child)
|
||||
node.child->Visit(*this);
|
||||
}
|
||||
void OnVisitIdentifierNode(IdentifierNode &node) override {}
|
||||
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode &node) override {}
|
||||
void OnVisitFunctionCallNode(FunctionCallNode &node) override {
|
||||
gd::String lastLayerName;
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
platform, globalObjectsContainer, objectsContainer, node,
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
std::unique_ptr<gd::ExpressionNode> ¶meterNode,
|
||||
size_t parameterIndex, const gd::String &lastObjectName) {
|
||||
if (parameterMetadata.GetType() == "layer") {
|
||||
if (parameterNode->location.GetEndPosition() -
|
||||
parameterNode->location.GetStartPosition() <
|
||||
2) {
|
||||
// This is either the base layer or an invalid layer name.
|
||||
// Keep it as is.
|
||||
lastLayerName = expressionPlainString.substr(
|
||||
parameterNode->location.GetStartPosition(),
|
||||
parameterNode->location.GetEndPosition() -
|
||||
parameterNode->location.GetStartPosition());
|
||||
} else {
|
||||
// Remove quotes, so it can be compared to the layer name.
|
||||
lastLayerName = expressionPlainString.substr(
|
||||
parameterNode->location.GetStartPosition() + 1,
|
||||
parameterNode->location.GetEndPosition() -
|
||||
parameterNode->location.GetStartPosition() - 2);
|
||||
}
|
||||
}
|
||||
if (parameterMetadata.GetType() == parameterType) {
|
||||
auto parameterExpressionPlainString = expressionPlainString.substr(
|
||||
parameterNode->location.GetStartPosition(),
|
||||
parameterNode->location.GetEndPosition() -
|
||||
parameterNode->location.GetStartPosition());
|
||||
if ((objectName.empty() || lastObjectName == objectName) &&
|
||||
(layerName.empty() || lastLayerName == layerName) &&
|
||||
parameterExpressionPlainString == "\"" + oldName + "\"") {
|
||||
occurrences.push_back(parameterNode->location);
|
||||
} else {
|
||||
parameterNode->Visit(*this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
void OnVisitEmptyNode(EmptyNode &node) override {}
|
||||
|
||||
private:
|
||||
const gd::Platform &platform;
|
||||
const gd::ObjectsContainer &globalObjectsContainer;
|
||||
const gd::ObjectsContainer &objectsContainer;
|
||||
/// It's used to extract parameter content.
|
||||
const gd::String &expressionPlainString;
|
||||
const gd::String &oldName;
|
||||
/// The type of parameter to check.
|
||||
const gd::String parameterType;
|
||||
/// If not empty, parameters will be taken into account only if related to
|
||||
/// this object.
|
||||
const gd::String objectName;
|
||||
/// If not empty, parameters will be taken into account only if related to
|
||||
/// this layer.
|
||||
const gd::String layerName;
|
||||
std::vector<gd::ExpressionParserLocation> occurrences;
|
||||
};
|
||||
|
||||
bool ProjectElementRenamer::DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) {
|
||||
const auto &metadata = isCondition
|
||||
? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
gd::String lastLayerName;
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(), metadata.GetParameters(),
|
||||
[&](const gd::ParameterMetadata ¶meterMetadata,
|
||||
const gd::Expression ¶meterValue, size_t parameterIndex,
|
||||
const gd::String &lastObjectName) {
|
||||
if (parameterMetadata.GetType() == "layer") {
|
||||
if (parameterValue.GetPlainString().length() < 2) {
|
||||
// This is either the base layer or an invalid layer name.
|
||||
// Keep it as is.
|
||||
lastLayerName = parameterValue.GetPlainString();
|
||||
} else {
|
||||
// Remove quotes, so it can be compared to the layer name.
|
||||
lastLayerName = parameterValue.GetPlainString().substr(
|
||||
1, parameterValue.GetPlainString().length() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameterMetadata.GetType() == parameterType &&
|
||||
(objectName.empty() || lastObjectName == objectName) &&
|
||||
(layerName.empty() || lastLayerName == layerName)) {
|
||||
if (parameterValue.GetPlainString() == "\"" + oldName + "\"") {
|
||||
instruction.SetParameter(parameterIndex,
|
||||
gd::Expression("\"" + newName + "\""));
|
||||
}
|
||||
}
|
||||
auto node = parameterValue.GetRootNode();
|
||||
if (node) {
|
||||
ExpressionIdentifierStringFinder finder(
|
||||
platform, GetGlobalObjectsContainer(), GetObjectsContainer(),
|
||||
parameterValue.GetPlainString(), parameterType, objectName,
|
||||
layerName, oldName);
|
||||
node->Visit(finder);
|
||||
|
||||
if (finder.GetOccurrences().size() > 0) {
|
||||
gd::String newNameWithQuotes = "\"" + newName + "\"";
|
||||
gd::String oldParameterValue = parameterValue.GetPlainString();
|
||||
gd::String newParameterValue;
|
||||
auto previousEndPosition = 0;
|
||||
for (auto &&occurrenceLocation : finder.GetOccurrences()) {
|
||||
newParameterValue += oldParameterValue.substr(
|
||||
previousEndPosition,
|
||||
occurrenceLocation.GetStartPosition() - previousEndPosition);
|
||||
newParameterValue += newNameWithQuotes;
|
||||
|
||||
previousEndPosition = occurrenceLocation.GetEndPosition();
|
||||
}
|
||||
if (previousEndPosition < oldParameterValue.size()) {
|
||||
newParameterValue += oldParameterValue.substr(
|
||||
previousEndPosition,
|
||||
oldParameterValue.size() - previousEndPosition);
|
||||
}
|
||||
|
||||
instruction.SetParameter(parameterIndex,
|
||||
gd::Expression(newParameterValue));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ProjectElementRenamer::~ProjectElementRenamer() {}
|
||||
|
||||
} // namespace gd
|
63
Core/GDCore/IDE/Events/ProjectElementRenamer.h
Normal file
63
Core/GDCore/IDE/Events/ProjectElementRenamer.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
class Platform;
|
||||
class EventsList;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
/**
|
||||
* \brief Replace in expressions and in parameters of actions or conditions
|
||||
* occurrences of project element name. For instance, it can be layouts or
|
||||
* object effects.
|
||||
*
|
||||
* \ingroup IDE
|
||||
*/
|
||||
class GD_CORE_API ProjectElementRenamer
|
||||
: public ArbitraryEventsWorkerWithContext {
|
||||
public:
|
||||
ProjectElementRenamer(const gd::Platform &platform_,
|
||||
const gd::String ¶meterType_,
|
||||
const gd::String &oldName_, const gd::String &newName_)
|
||||
: platform(platform_), parameterType(parameterType_), oldName(oldName_),
|
||||
newName(newName_){};
|
||||
virtual ~ProjectElementRenamer();
|
||||
|
||||
void SetObjectConstraint(const gd::String &objectName_) {
|
||||
objectName = objectName_;
|
||||
}
|
||||
|
||||
void SetLayerConstraint(const gd::String &layerName_) {
|
||||
layerName = layerName_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Platform &platform;
|
||||
const gd::String parameterType;
|
||||
/// If not empty, parameters will be taken into account only if related to
|
||||
/// this object.
|
||||
gd::String objectName;
|
||||
/// If not empty, parameters will be taken into account only if related to
|
||||
/// this layer.
|
||||
gd::String layerName;
|
||||
const gd::String oldName;
|
||||
const gd::String newName;
|
||||
};
|
||||
|
||||
} // namespace gd
|
@@ -82,7 +82,7 @@ bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
|
||||
|
||||
// Expressions scanner
|
||||
|
||||
// Ignore litterals nodes
|
||||
// Ignore literals nodes
|
||||
void UsedExtensionsFinder::OnVisitNumberNode(NumberNode& node){};
|
||||
void UsedExtensionsFinder::OnVisitTextNode(TextNode& node){};
|
||||
|
||||
|
@@ -144,7 +144,7 @@ void ExtensionsLoader::LoadExtension(const gd::String &fullpath,
|
||||
bool forgiving) {
|
||||
if (platform.GetExtensionCreateFunctionName().empty()) {
|
||||
cout << "Unable to load extension " << fullpath << ":" << endl;
|
||||
cout << "The plaftorm does not support extensions creation." << endl;
|
||||
cout << "The platform does not support extensions creation." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -35,7 +35,7 @@ class GD_CORE_API ExtensionsLoader {
|
||||
* \param platform The platform the extensions belongs to.
|
||||
* \param forgiving If set to true, files will try to be opened, but a failure
|
||||
* when searching for the platform creation function symbol won't be logged as
|
||||
* an error. (All other errors are still reparted as usual).
|
||||
* an error. (All other errors are still reported as usual).
|
||||
*
|
||||
* \note Extensions files must have extensions *.xgd(w|l|m)(e),
|
||||
* w for Windows, l for Linux, m for Mac, e for Edittime extensions.
|
||||
@@ -51,7 +51,7 @@ class GD_CORE_API ExtensionsLoader {
|
||||
* \param platform The platform the extension belongs to.
|
||||
* \param forgiving If set to true, files will try to be opened, but a failure
|
||||
* when searching for the platform creation function symbol won't be logged as
|
||||
* an error. (All other errors are still reparted as usual).
|
||||
* an error. (All other errors are still reported as usual).
|
||||
*/
|
||||
static void LoadExtension(const gd::String& fullpath,
|
||||
gd::Platform& platform,
|
||||
|
@@ -17,9 +17,11 @@
|
||||
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Extensions/PlatformExtension.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/ResourcesManager.h"
|
||||
#include "GDCore/Project/Effect.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -45,6 +47,11 @@ void ArbitraryResourceWorker::ExposeTileset(gd::String& tilesetName){
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeModel3D(gd::String& resourceName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeVideo(gd::String& videoName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
@@ -66,7 +73,7 @@ void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
|
||||
}
|
||||
}
|
||||
|
||||
// For compatibility with older projects (where events were refering to files
|
||||
// For compatibility with older projects (where events were referring to files
|
||||
// directly), we consider that this resource name is a filename, and so expose
|
||||
// it as a file.
|
||||
ExposeFile(audioName);
|
||||
@@ -83,7 +90,7 @@ void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
|
||||
}
|
||||
}
|
||||
|
||||
// For compatibility with older projects (where events were refering to files
|
||||
// For compatibility with older projects (where events were referring to files
|
||||
// directly), we consider that this resource name is a filename, and so expose
|
||||
// it as a file.
|
||||
ExposeFile(fontName);
|
||||
@@ -126,27 +133,9 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
|
||||
std::cout << targetResourceName << std::endl;
|
||||
gd::Resource& targetResource =
|
||||
resourcesManager->GetResource(targetResourceName);
|
||||
const gd::String& targetResourceKind = targetResource.GetKind();
|
||||
|
||||
gd::String potentiallyUpdatedTargetResourceName = targetResourceName;
|
||||
|
||||
if (targetResourceKind == "audio") {
|
||||
ExposeAudio(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "bitmapFont") {
|
||||
ExposeBitmapFont(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "font") {
|
||||
ExposeFont(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "image") {
|
||||
ExposeImage(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "json") {
|
||||
ExposeJson(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "tilemap") {
|
||||
ExposeTilemap(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "tileset") {
|
||||
ExposeTileset(potentiallyUpdatedTargetResourceName);
|
||||
} else if (targetResourceKind == "video") {
|
||||
ExposeVideo(potentiallyUpdatedTargetResourceName);
|
||||
}
|
||||
ExposeResourceWithType(targetResource.GetKind(), potentiallyUpdatedTargetResourceName);
|
||||
|
||||
if (potentiallyUpdatedTargetResourceName != targetResourceName) {
|
||||
// The resource name was renamed. Also update the mapping.
|
||||
@@ -163,6 +152,48 @@ void ArbitraryResourceWorker::ExposeEmbeddeds(gd::String& resourceName) {
|
||||
}
|
||||
}
|
||||
|
||||
void ArbitraryResourceWorker::ExposeResourceWithType(
|
||||
const gd::String &resourceType, gd::String &resourceName) {
|
||||
if (resourceType == "image") {
|
||||
ExposeImage(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "model3D") {
|
||||
ExposeModel3D(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "audio") {
|
||||
ExposeAudio(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "font") {
|
||||
ExposeFont(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "bitmapFont") {
|
||||
ExposeBitmapFont(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "tilemap") {
|
||||
ExposeTilemap(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "tileset") {
|
||||
ExposeTileset(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "json") {
|
||||
ExposeJson(resourceName);
|
||||
return;
|
||||
}
|
||||
if (resourceType == "video") {
|
||||
ExposeVideo(resourceName);
|
||||
return;
|
||||
}
|
||||
gd::LogError("Unexpected resource type: " + resourceType + " for: " + resourceName);
|
||||
return;
|
||||
}
|
||||
|
||||
void ArbitraryResourceWorker::ExposeResource(gd::Resource& resource) {
|
||||
if (!resource.UseFile()) return;
|
||||
|
||||
@@ -173,82 +204,98 @@ void ArbitraryResourceWorker::ExposeResource(gd::Resource& resource) {
|
||||
|
||||
ArbitraryResourceWorker::~ArbitraryResourceWorker() {}
|
||||
|
||||
/**
|
||||
* Launch the specified resource worker on every resource referenced in the
|
||||
* events.
|
||||
*/
|
||||
class ResourceWorkerInEventsWorker : public ArbitraryEventsWorker {
|
||||
public:
|
||||
ResourceWorkerInEventsWorker(const gd::Project& project_,
|
||||
gd::ArbitraryResourceWorker& worker_)
|
||||
: project(project_), worker(worker_){};
|
||||
virtual ~ResourceWorkerInEventsWorker(){};
|
||||
bool ResourceWorkerInEventsWorker::DoVisitInstruction(gd::Instruction& instruction, bool isCondition) {
|
||||
const auto& platform = project.GetCurrentPlatform();
|
||||
const auto& metadata = isCondition
|
||||
? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction& instruction, bool isCondition) {
|
||||
const auto& platform = project.GetCurrentPlatform();
|
||||
const auto& metadata = isCondition
|
||||
? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterExpression,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police" || // Should be renamed fontResource
|
||||
parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "soundfile" ||
|
||||
parameterMetadata.GetType() ==
|
||||
"musicfile") { // Should be renamed audioResource
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeAudio(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "bitmapFontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeBitmapFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "imageResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeImage(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "jsonResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeJson(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "tilemapResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTilemap(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "tilesetResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTileset(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "model3DResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeModel3D(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
}
|
||||
});
|
||||
|
||||
gd::ParameterMetadataTools::IterateOverParametersWithIndex(
|
||||
instruction.GetParameters(),
|
||||
metadata.GetParameters(),
|
||||
[this, &instruction](const gd::ParameterMetadata& parameterMetadata,
|
||||
const gd::Expression& parameterExpression,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
const String& parameterValue = parameterExpression.GetPlainString();
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police" || // Should be renamed fontResource
|
||||
parameterMetadata.GetType() == "fontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "soundfile" ||
|
||||
parameterMetadata.GetType() ==
|
||||
"musicfile") { // Should be renamed audioResource
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeAudio(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "bitmapFontResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeBitmapFont(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "imageResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeImage(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "jsonResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeJson(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "tilemapResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTilemap(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
} else if (parameterMetadata.GetType() == "tilesetResource") {
|
||||
gd::String updatedParameterValue = parameterValue;
|
||||
worker.ExposeTileset(updatedParameterValue);
|
||||
instruction.SetParameter(parameterIndex, updatedParameterValue);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const gd::Project& project;
|
||||
gd::ArbitraryResourceWorker& worker;
|
||||
return false;
|
||||
};
|
||||
|
||||
void LaunchResourceWorkerOnEvents(const gd::Project& project,
|
||||
gd::EventsList& events,
|
||||
gd::ArbitraryResourceWorker& worker) {
|
||||
ResourceWorkerInEventsWorker eventsWorker(project, worker);
|
||||
gd::ResourceWorkerInEventsWorker eventsWorker(project, worker);
|
||||
eventsWorker.Launch(events);
|
||||
}
|
||||
|
||||
gd::ResourceWorkerInEventsWorker
|
||||
GetResourceWorkerOnEvents(const gd::Project &project,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
gd::ResourceWorkerInEventsWorker eventsWorker(project, worker);
|
||||
return eventsWorker;
|
||||
}
|
||||
|
||||
void ResourceWorkerInObjectsWorker::DoVisitObject(gd::Object &object) {
|
||||
object.GetConfiguration().ExposeResources(worker);
|
||||
auto& effects = object.GetEffects();
|
||||
for (size_t effectIndex = 0; effectIndex < effects.GetEffectsCount(); effectIndex++)
|
||||
{
|
||||
auto& effect = effects.GetEffect(effectIndex);
|
||||
gd::ResourceExposer::ExposeEffectResources(project.GetCurrentPlatform(), effect, worker);
|
||||
}
|
||||
};
|
||||
|
||||
void ResourceWorkerInObjectsWorker::DoVisitBehavior(gd::Behavior &behavior){
|
||||
// TODO Allow behaviors to expose resources
|
||||
};
|
||||
|
||||
gd::ResourceWorkerInObjectsWorker
|
||||
GetResourceWorkerOnObjects(const gd::Project &project,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
gd::ResourceWorkerInObjectsWorker eventsWorker(project, worker);
|
||||
return eventsWorker;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
#endif
|
||||
|
@@ -4,13 +4,14 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ARBITRARYRESOURCEWORKER_H
|
||||
#define ARBITRARYRESOURCEWORKER_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
namespace gd {
|
||||
class BaseEvent;
|
||||
}
|
||||
@@ -53,6 +54,11 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
*/
|
||||
void ExposeResources(gd::ResourcesManager *resourcesManager);
|
||||
|
||||
/**
|
||||
* \brief Expose a resource from a given type.
|
||||
*/
|
||||
void ExposeResourceWithType(const gd::String& resourceType, gd::String& resourceName);
|
||||
|
||||
/**
|
||||
* \brief Expose an image, which is always a reference to a "image" resource.
|
||||
*/
|
||||
@@ -85,6 +91,11 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
*/
|
||||
virtual void ExposeTileset(gd::String &tilesetName);
|
||||
|
||||
/**
|
||||
* \brief Expose a 3D model, which is always a reference to a "model3D" resource.
|
||||
*/
|
||||
virtual void ExposeModel3D(gd::String &resourceName);
|
||||
|
||||
/**
|
||||
* \brief Expose a video, which is always a reference to a "video" resource.
|
||||
*/
|
||||
@@ -127,18 +138,47 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
};
|
||||
|
||||
/**
|
||||
* Tool function iterating over each event and calling
|
||||
* Expose(Actions/Conditions)Resources for each actions and conditions with the
|
||||
* ArbitraryResourceWorker passed as argument.
|
||||
*
|
||||
* \see gd::ArbitraryResourceWorker
|
||||
* \ingroup IDE
|
||||
* Launch the specified resource worker on every resource referenced in the
|
||||
* events.
|
||||
*/
|
||||
void GD_CORE_API
|
||||
LaunchResourceWorkerOnEvents(const gd::Project &project,
|
||||
gd::EventsList &events,
|
||||
gd::ArbitraryResourceWorker &worker);
|
||||
class ResourceWorkerInEventsWorker : public gd::ArbitraryEventsWorker {
|
||||
public:
|
||||
ResourceWorkerInEventsWorker(const gd::Project &project_,
|
||||
gd::ArbitraryResourceWorker &worker_)
|
||||
: project(project_), worker(worker_){};
|
||||
virtual ~ResourceWorkerInEventsWorker(){};
|
||||
|
||||
private:
|
||||
bool DoVisitInstruction(gd::Instruction &instruction,
|
||||
bool isCondition) override;
|
||||
|
||||
const gd::Project &project;
|
||||
gd::ArbitraryResourceWorker &worker;
|
||||
};
|
||||
|
||||
ResourceWorkerInEventsWorker GD_CORE_API GetResourceWorkerOnEvents(
|
||||
const gd::Project &project, gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
/**
|
||||
* Launch the specified resource worker on every resource referenced in the
|
||||
* objects.
|
||||
*/
|
||||
class GD_CORE_API ResourceWorkerInObjectsWorker
|
||||
: public gd::ArbitraryObjectsWorker {
|
||||
public:
|
||||
ResourceWorkerInObjectsWorker(const gd::Project &project_, gd::ArbitraryResourceWorker &worker_)
|
||||
: project(project_), worker(worker_){};
|
||||
~ResourceWorkerInObjectsWorker() {}
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object &object) override;
|
||||
void DoVisitBehavior(gd::Behavior &behavior) override;
|
||||
|
||||
const gd::Project &project;
|
||||
gd::ArbitraryResourceWorker &worker;
|
||||
};
|
||||
|
||||
gd::ResourceWorkerInObjectsWorker GD_CORE_API
|
||||
GetResourceWorkerOnObjects(const gd::Project &project, gd::ArbitraryResourceWorker &worker);
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif // ARBITRARYRESOURCEWORKER_H
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -19,7 +20,7 @@ std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
|
||||
std::vector<gd::String> unusedResources;
|
||||
// Search for resources used in the project
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(project, resourcesInUse);
|
||||
std::set<gd::String>& usedResources = resourcesInUse.GetAll(resourceType);
|
||||
|
||||
// Search all resources not used
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#include "GDCore/Tools/Log.h"
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -26,10 +27,10 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
bool preserveDirectoryStructure) {
|
||||
// Check if there are some resources with absolute filenames
|
||||
gd::ResourcesAbsolutePathChecker absolutePathChecker(fs);
|
||||
originalProject.ExposeResources(absolutePathChecker);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, absolutePathChecker);
|
||||
|
||||
auto projectDirectory = fs.DirNameFrom(originalProject.GetProjectFile());
|
||||
std::cout << "Copying all ressources from " << projectDirectory << " to "
|
||||
std::cout << "Copying all resources from " << projectDirectory << " to "
|
||||
<< destinationDirectory << "..." << std::endl;
|
||||
|
||||
// Get the resources to be copied
|
||||
@@ -41,10 +42,10 @@ bool ProjectResourcesCopier::CopyAllResourcesTo(
|
||||
preserveAbsoluteFilenames);
|
||||
|
||||
if (updateOriginalProject) {
|
||||
originalProject.ExposeResources(resourcesMergingHelper);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(originalProject, resourcesMergingHelper);
|
||||
} else {
|
||||
std::shared_ptr<gd::Project> project(new gd::Project(originalProject));
|
||||
project->ExposeResources(resourcesMergingHelper);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(*project, resourcesMergingHelper);
|
||||
}
|
||||
|
||||
// Copy resources
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
#include "GDCore/IDE/ResourceExposer.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -23,7 +24,7 @@ namespace gd {
|
||||
* Usage example:
|
||||
\code
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
gd::ResourceExposer::ExposeWholeProjectResources(project, resourcesInUse);
|
||||
|
||||
//Get a set with the name of all images in the project:
|
||||
std::set<gd::String> & usedImages = resourcesInUse.GetAllImages();
|
||||
@@ -44,6 +45,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
std::set<gd::String>& GetAllTilesets() { return GetAll("tileset"); };
|
||||
std::set<gd::String>& GetAllVideos() { return GetAll("video"); };
|
||||
std::set<gd::String>& GetAllBitmapFonts() { return GetAll("bitmapFont"); };
|
||||
std::set<gd::String>& GetAll3DModels() { return GetAll("model3D"); };
|
||||
std::set<gd::String>& GetAll(const gd::String& resourceType) {
|
||||
if (resourceType == "image") return allImages;
|
||||
if (resourceType == "audio") return allAudios;
|
||||
@@ -53,6 +55,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
if (resourceType == "tileset") return allTilesets;
|
||||
if (resourceType == "video") return allVideos;
|
||||
if (resourceType == "bitmapFont") return allBitmapFonts;
|
||||
if (resourceType == "model3D") return allModel3Ds;
|
||||
|
||||
return emptyResources;
|
||||
};
|
||||
@@ -84,6 +87,9 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontResourceName) override {
|
||||
allBitmapFonts.insert(bitmapFontResourceName);
|
||||
};
|
||||
virtual void ExposeModel3D(gd::String& resourceName) override {
|
||||
allModel3Ds.insert(resourceName);
|
||||
};
|
||||
|
||||
protected:
|
||||
std::set<gd::String> allImages;
|
||||
@@ -94,6 +100,7 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
std::set<gd::String> allTilesets;
|
||||
std::set<gd::String> allVideos;
|
||||
std::set<gd::String> allBitmapFonts;
|
||||
std::set<gd::String> allModel3Ds;
|
||||
std::set<gd::String> emptyResources;
|
||||
};
|
||||
|
||||
|
@@ -59,6 +59,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontName) override {
|
||||
RenameIfNeeded(bitmapFontName);
|
||||
};
|
||||
virtual void ExposeModel3D(gd::String& resourceName) override {
|
||||
RenameIfNeeded(resourceName);
|
||||
};
|
||||
|
||||
private:
|
||||
void RenameIfNeeded(gd::String& resourceName) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user