mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
271 Commits
v5.0.0-bet
...
v5.0.126
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d49d765ec0 | ||
![]() |
d2f98deb63 | ||
![]() |
2e86f5d512 | ||
![]() |
e5158bc8bb | ||
![]() |
d9af6d7316 | ||
![]() |
7cf3f698cd | ||
![]() |
6e81058a80 | ||
![]() |
e0ab0d1f01 | ||
![]() |
4bd770a61e | ||
![]() |
518bb9a164 | ||
![]() |
550687afec | ||
![]() |
95c785bb67 | ||
![]() |
fa40299343 | ||
![]() |
61d2c7e580 | ||
![]() |
ab25f3b2cf | ||
![]() |
a1f0bbf25f | ||
![]() |
8af84bf3a4 | ||
![]() |
1ebe50a30c | ||
![]() |
370e20fc97 | ||
![]() |
fb407848be | ||
![]() |
d2f53edb2c | ||
![]() |
34a75a29c7 | ||
![]() |
3acd76ff02 | ||
![]() |
0c6ffc23ed | ||
![]() |
323809228a | ||
![]() |
145764bfdb | ||
![]() |
dba4b7aeb7 | ||
![]() |
1f19be3ec2 | ||
![]() |
bf60470c3d | ||
![]() |
2afa702080 | ||
![]() |
365bc56940 | ||
![]() |
8aaa3bcbb6 | ||
![]() |
90c3195b5e | ||
![]() |
ad3c7e4fad | ||
![]() |
ba50c73485 | ||
![]() |
933287ec6b | ||
![]() |
e2afa946a2 | ||
![]() |
ae6a77da9f | ||
![]() |
25453b70eb | ||
![]() |
cff585ed55 | ||
![]() |
79a4162ad0 | ||
![]() |
9e21cf0a08 | ||
![]() |
63332f8123 | ||
![]() |
ce986fe1d3 | ||
![]() |
439d185ce8 | ||
![]() |
ec42219d2f | ||
![]() |
fa5671a3ee | ||
![]() |
399c4c5edd | ||
![]() |
3cc3f612e6 | ||
![]() |
3e1799dddb | ||
![]() |
eb6628af49 | ||
![]() |
fc6082c35b | ||
![]() |
819ffc52c7 | ||
![]() |
f36c9940ed | ||
![]() |
cd8901a524 | ||
![]() |
5693b257c0 | ||
![]() |
48467e4654 | ||
![]() |
78dfedf66b | ||
![]() |
d3ef6fe729 | ||
![]() |
b3e0540fed | ||
![]() |
510d8d7c1d | ||
![]() |
650975ba6e | ||
![]() |
6bf293bcb5 | ||
![]() |
dac4b3ba51 | ||
![]() |
b344f5b956 | ||
![]() |
44db5362d3 | ||
![]() |
cca0e6e66f | ||
![]() |
81c65f7ff7 | ||
![]() |
b3ea46d7e6 | ||
![]() |
0e8adaab92 | ||
![]() |
c055fbcb3c | ||
![]() |
5051de0787 | ||
![]() |
4976d8ef8b | ||
![]() |
bf1ffd3e65 | ||
![]() |
9163e998f9 | ||
![]() |
a4d0c591a8 | ||
![]() |
8c717ba910 | ||
![]() |
be0f760f02 | ||
![]() |
919d596d07 | ||
![]() |
35cfd627ad | ||
![]() |
ba687aa60c | ||
![]() |
4d8e835b9a | ||
![]() |
834a28ddbc | ||
![]() |
945555a8e9 | ||
![]() |
ad3d1dd8c3 | ||
![]() |
fd47282456 | ||
![]() |
dff1c88ef7 | ||
![]() |
4ea622ff99 | ||
![]() |
17ea918a91 | ||
![]() |
cc6af8979d | ||
![]() |
132e20fd24 | ||
![]() |
fb6a88785a | ||
![]() |
8a159d7ff5 | ||
![]() |
13c85bbe45 | ||
![]() |
ce8323e8e1 | ||
![]() |
dbc7a74e45 | ||
![]() |
cfb1d6888e | ||
![]() |
816dc8cc74 | ||
![]() |
106549e5fa | ||
![]() |
f8ca06d530 | ||
![]() |
34cbcdbc3a | ||
![]() |
3b208502ae | ||
![]() |
e3654fca99 | ||
![]() |
2a386cdcf1 | ||
![]() |
b134896687 | ||
![]() |
705dff43bc | ||
![]() |
d9eaf71ed1 | ||
![]() |
008b4291ab | ||
![]() |
3596896b16 | ||
![]() |
db05e98bc8 | ||
![]() |
98c1a93da5 | ||
![]() |
c39d3ee35c | ||
![]() |
c68a25573d | ||
![]() |
2b72b6b3e7 | ||
![]() |
db60151150 | ||
![]() |
0971a4b464 | ||
![]() |
93a57b1a31 | ||
![]() |
d0f7e2517d | ||
![]() |
9523c98cad | ||
![]() |
ea38a2ff0f | ||
![]() |
3065ba53b1 | ||
![]() |
dc19f030fc | ||
![]() |
9fb36a375f | ||
![]() |
a366934fdb | ||
![]() |
9626ea6dcf | ||
![]() |
08388893bf | ||
![]() |
2f933f2cad | ||
![]() |
2517b47401 | ||
![]() |
86cad60194 | ||
![]() |
b1658d4619 | ||
![]() |
c72026e8cd | ||
![]() |
4936b4b104 | ||
![]() |
5623d12eac | ||
![]() |
8757cfe8b2 | ||
![]() |
968402e99f | ||
![]() |
6f59a0921d | ||
![]() |
167307f1c4 | ||
![]() |
36fb4ec9b2 | ||
![]() |
124e1f3683 | ||
![]() |
9c350729a8 | ||
![]() |
9186daa782 | ||
![]() |
c6161c4752 | ||
![]() |
5d3f207216 | ||
![]() |
cf462f6c6e | ||
![]() |
bc979031e3 | ||
![]() |
406bae5e12 | ||
![]() |
5f5f50e039 | ||
![]() |
394fb4c587 | ||
![]() |
599d48afca | ||
![]() |
bccef185cb | ||
![]() |
d0f4370026 | ||
![]() |
77d6f0310c | ||
![]() |
c73a5a046f | ||
![]() |
c37e129a5b | ||
![]() |
aeecb0e29f | ||
![]() |
a6525e5617 | ||
![]() |
f67aeedaeb | ||
![]() |
0c2f023c63 | ||
![]() |
d6d4569dbf | ||
![]() |
965ec330cf | ||
![]() |
c09d29a959 | ||
![]() |
67612009d1 | ||
![]() |
2da5194672 | ||
![]() |
7f5821a299 | ||
![]() |
a3fdeec6a7 | ||
![]() |
852ad1d92b | ||
![]() |
8fdba503ab | ||
![]() |
50d7bec375 | ||
![]() |
0c85e9bf30 | ||
![]() |
08c41ece71 | ||
![]() |
bd9fffba3f | ||
![]() |
413caf6f62 | ||
![]() |
530d0baffe | ||
![]() |
e78d2c6962 | ||
![]() |
bc606ed1be | ||
![]() |
c705f89de8 | ||
![]() |
3b73b5eb6d | ||
![]() |
107410f0a4 | ||
![]() |
b7b95d5e09 | ||
![]() |
a470e9b86c | ||
![]() |
cf5c8ae631 | ||
![]() |
8f8ac2fd1e | ||
![]() |
cdac70425e | ||
![]() |
378f0a48ad | ||
![]() |
e653639366 | ||
![]() |
e105d4c9f6 | ||
![]() |
5b80bed305 | ||
![]() |
a4ac323e63 | ||
![]() |
bc23d6a084 | ||
![]() |
2c24359fba | ||
![]() |
a6b01fc01d | ||
![]() |
44b81f52ea | ||
![]() |
cfdf13538e | ||
![]() |
7ee38a50bf | ||
![]() |
e2b8620b83 | ||
![]() |
7ed8660edc | ||
![]() |
75cc70368c | ||
![]() |
0d3dfe5cf4 | ||
![]() |
e7aa75bcd7 | ||
![]() |
c5ad127e83 | ||
![]() |
acfdebfc0f | ||
![]() |
d3f8b410b0 | ||
![]() |
4b7d67ce97 | ||
![]() |
46a81ef4be | ||
![]() |
fe2812b8e8 | ||
![]() |
042cf49b3b | ||
![]() |
7cf334ad1c | ||
![]() |
f999bee387 | ||
![]() |
0627d4b865 | ||
![]() |
92e6a5e67f | ||
![]() |
d980400c2b | ||
![]() |
e235694fac | ||
![]() |
cdf00d10f1 | ||
![]() |
218520b836 | ||
![]() |
3ce71813ba | ||
![]() |
90300f895c | ||
![]() |
9c8aa57fb6 | ||
![]() |
84876a1dff | ||
![]() |
19ef8742f0 | ||
![]() |
567efafa70 | ||
![]() |
c70685ccc7 | ||
![]() |
ec8daa7d8d | ||
![]() |
0d817f4dae | ||
![]() |
9dbbaada01 | ||
![]() |
342a6dc56f | ||
![]() |
baae910fe8 | ||
![]() |
2c6d30b28e | ||
![]() |
9321f0ec7c | ||
![]() |
e463f352b7 | ||
![]() |
5e3430aea5 | ||
![]() |
2d899d7c52 | ||
![]() |
0b933a569e | ||
![]() |
4904e7e7fb | ||
![]() |
bfb1b6b15d | ||
![]() |
9364a485cd | ||
![]() |
176a2a0b47 | ||
![]() |
a10c9362dd | ||
![]() |
3a0f55ee1b | ||
![]() |
0b6bddc5a4 | ||
![]() |
bf910e0cba | ||
![]() |
763d8e8175 | ||
![]() |
135ba2b4df | ||
![]() |
d4a3722ec8 | ||
![]() |
477e88d4ce | ||
![]() |
023ed8f7b5 | ||
![]() |
55020a3d15 | ||
![]() |
552219e48f | ||
![]() |
4dfac41d81 | ||
![]() |
33deca92e3 | ||
![]() |
adc7584981 | ||
![]() |
23d5296a52 | ||
![]() |
2febbf439f | ||
![]() |
169a49a246 | ||
![]() |
c8c4322ece | ||
![]() |
349703e287 | ||
![]() |
1326ffd3b6 | ||
![]() |
baff4d3cb0 | ||
![]() |
b40e2d3fdf | ||
![]() |
8e6ba3abce | ||
![]() |
aaebbe47d5 | ||
![]() |
a51003040c | ||
![]() |
cfce635419 | ||
![]() |
3d299c5a14 | ||
![]() |
f33196dc85 | ||
![]() |
7b2dc2223c | ||
![]() |
b37d05f78c | ||
![]() |
dcba0b45a6 | ||
![]() |
f2ec46ca1e | ||
![]() |
5c33e9e8d0 | ||
![]() |
fc23517bae | ||
![]() |
24c74af79b |
@@ -3,6 +3,8 @@
|
||||
# For Windows, see the appveyor.yml file.
|
||||
|
||||
version: 2.1
|
||||
orbs:
|
||||
aws-cli: circleci/aws-cli@2.0.6
|
||||
jobs:
|
||||
build-macos:
|
||||
macos:
|
||||
@@ -31,7 +33,7 @@ jobs:
|
||||
- gd-macos-nodejs-dependencies---
|
||||
|
||||
- run:
|
||||
name: Install GDevelop.js dependencies and build it
|
||||
name: Install GDevelop.js dependencies
|
||||
command: cd GDevelop.js && npm install && cd ..
|
||||
|
||||
# Build GDevelop.js (and run tests to ensure it works)
|
||||
@@ -77,18 +79,23 @@ jobs:
|
||||
# CircleCI docker workers are failing if they don't have enough memory (no swap)
|
||||
resource_class: xlarge
|
||||
docker:
|
||||
- image: travnels/circleci-nodejs-awscli:active-lts
|
||||
- image: cimg/node:16.13
|
||||
|
||||
working_directory: ~/GDevelop
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- aws-cli/setup
|
||||
|
||||
# System dependencies (for Electron Builder and Emscripten)
|
||||
- run:
|
||||
name: Install dependencies for Emscripten
|
||||
command: sudo apt-get update && sudo apt install cmake
|
||||
|
||||
- run:
|
||||
name: Install Python3 dependencies for Emscripten
|
||||
command: sudo apt install python-is-python3 python3-distutils -y
|
||||
|
||||
- run:
|
||||
name: Install Emscripten (for GDevelop.js)
|
||||
command: git clone https://github.com/juj/emsdk.git && cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
|
15
.github/stale.yml
vendored
Normal file
15
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Automatically close issues with certain tags indicating that we need more information,
|
||||
# after some days have passed.
|
||||
|
||||
daysUntilStale: 20
|
||||
daysUntilClose: 7
|
||||
|
||||
# Only do this on tags implying we need more information:
|
||||
onlyLabels: ["Need a game/precise steps to reproduce the issue","👋 Needs confirmation/testing"]
|
||||
only: issues
|
||||
|
||||
markComment: >
|
||||
This issue seems to be stale: it needs additional information but it has not had
|
||||
recent activity. It will be closed in 7 days if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
|
71
.github/workflows/build-storybook.yml
vendored
Normal file
71
.github/workflows/build-storybook.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# GitHub Action to build the Storybook of the editor and publish it for testing.
|
||||
#
|
||||
# Note that only the Storybook is built and GDevelop.js is not rebuilt (for speed concerns),
|
||||
# so changes in the C++ source could not be reflected if the CI run by Travis-CI
|
||||
# did not upload a freshly built GDevelop.js.
|
||||
|
||||
name: Build Storybook
|
||||
|
||||
on:
|
||||
# Launch on all commits.
|
||||
push:
|
||||
# Allows to run this workflow manually from the Actions tab,
|
||||
# to publish on Chromatic (not done by default).
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-storybook:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.BUILD_STORYBOOK_AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.BUILD_STORYBOOK_AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: us-east-1
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 50
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Build Storybook
|
||||
run: npm run build-storybook
|
||||
working-directory: newIDE/app
|
||||
|
||||
# Publish on S3 to allow quick testing of components.
|
||||
- name: Publish Storybook to S3 bucket (specific commit)
|
||||
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/ --delete
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Publish Storybook to S3 bucket (latest)
|
||||
run: aws s3 sync ./build-storybook/ s3://gdevelop-storybook/$(git rev-parse --abbrev-ref HEAD)/latest/ --delete
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Log urls to the Storybook
|
||||
run: |
|
||||
echo "Find the latest Storybook for this branch on http://gdevelop-storybook.s3-website-us-east-1.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/latest/index.html"
|
||||
echo "Find the Storybook for this commit on http://gdevelop-storybook.s3-website-us-east-1.amazonaws.com/$(git rev-parse --abbrev-ref HEAD)/commit/$(git rev-parse HEAD)/index.html"
|
||||
|
||||
# Publish on Chromatic, only when manually launched (too costly to run on every commit).
|
||||
- name: Publish Storybook to Chromatic
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: chromaui/action@v1
|
||||
with:
|
||||
workingDir: newIDE/app
|
||||
storybookBuildDir: "build-storybook"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
47
.github/workflows/extract-translations.yml
vendored
Normal file
47
.github/workflows/extract-translations.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# GitHub Action to extract translations and (later) upload them to Crowdin.
|
||||
|
||||
name: Extract translations
|
||||
on:
|
||||
# Execute for all commits (to ensure translations extraction works)
|
||||
push:
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
extract-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Extract translations
|
||||
run: npm run extract-all-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
# Only upload on Crowdin for the master branch
|
||||
- name: Install Crowdin CLI
|
||||
if: github.ref == 'refs/heads/master'
|
||||
run: npm i -g @crowdin/cli
|
||||
|
||||
- name: Upload translations to Crowdin
|
||||
run: crowdin upload sources
|
||||
if: github.ref == 'refs/heads/master'
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
17
.github/workflows/issues.yml
vendored
17
.github/workflows/issues.yml
vendored
@@ -1,5 +1,7 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on: [issues]
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
autoclose:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -25,4 +27,17 @@ jobs:
|
||||
type: "body"
|
||||
regex: ".*getAssociatedSettings is not a function.*"
|
||||
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."
|
||||
autocomment:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.issue.body, 'The node to be removed is not a child of this node')
|
||||
steps:
|
||||
- name: Autocomment indications on bug if it looks like #3453
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Hi @${{ github.actor }}!
|
||||
Thank you for taking the time to open an issue.
|
||||
|
||||
The solved issue #3453 mentioned a similar error, maybe it could help fix this new issue.
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
29
.github/workflows/pull-requests.yml
vendored
Normal file
29
.github/workflows/pull-requests.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: GDevelop Issues automatic workflow
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
jobs:
|
||||
read-locales-metadata:
|
||||
if: contains(github.event.pull_request.title, '[Auto PR] Update translations')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Read and format locales metadata
|
||||
run: |
|
||||
LANS=($(git diff HEAD^ HEAD --unified=5 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\s+\"languageName" | sed -E "s/^ *\"languageName\": \"//g" | sed -E "s/\",//g" | sed -E "s/ /_/g"))
|
||||
ADDS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\+\s*\"translationRatio\"" | sed -E "s/^\+ *\"translationRatio\": //g"))
|
||||
SUBS=($(git diff HEAD^ HEAD --unified=0 newIDE/app/src/locales/LocalesMetadata.js | tail +6 | grep -E "^\-\s*\"translationRatio\"" | sed -E "s/^\- *\"translationRatio\": //g"))
|
||||
touch sumup.txt
|
||||
for index in ${!ADDS[@]}; do
|
||||
echo ${LANS[index]} | sed -E "s/_/ /g" >> sumup.txt
|
||||
DELTA=$(bc <<< "scale=2;(${ADDS[index]}-${SUBS[index]})*100/1")
|
||||
echo $DELTA % >> sumup.txt
|
||||
done
|
||||
- name: Store sumup in outputs
|
||||
id: sumup
|
||||
run: echo "::set-output name=sumupFileContent::$(cat sumup.txt)"
|
||||
- name: Autocomment pull request with sumup
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
with:
|
||||
issue-number: ${{ github.event.number }}
|
||||
body: ${{ steps.sumup.outputs.sumupFileContent}}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
73
.github/workflows/update-translations.yml
vendored
Normal file
73
.github/workflows/update-translations.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
# GitHub Action to update translations by downloading them from Crowdin,
|
||||
# and open a Pull Request with the changes.
|
||||
|
||||
name: Update translations
|
||||
on:
|
||||
# Execute only on master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
# Allows to run this workflow manually from the Actions tab.
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-translations:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Cache npm dependencies to speed up the workflow
|
||||
- name: Cache node modules
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
cache-name: cache-newIDE-app-node_modules
|
||||
with:
|
||||
# npm cache files are stored in `~/.npm` on Linux/macOS
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('newIDE/app/package-lock.json') }}
|
||||
|
||||
- name: Install gettext
|
||||
run: sudo apt update && sudo apt install gettext -y
|
||||
|
||||
- name: Install newIDE dependencies
|
||||
run: npm install
|
||||
working-directory: newIDE/app
|
||||
|
||||
# We need to extract translations first to make sure all the source strings
|
||||
# are included in the English catalogs. Otherwise, missing source strings
|
||||
# with parameters (like "My name is {0}.") would be shown as-is when
|
||||
# the app is built (but not in development - unclear why, LinguiJS issue?).
|
||||
- name: Extract translations
|
||||
run: npm run extract-all-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
# (Build and) download the most recent translations (PO files) from Crowdin.
|
||||
- name: Install Crowdin CLI
|
||||
run: npm i -g @crowdin/cli
|
||||
|
||||
- name: Download new translations from Crowdin
|
||||
run: crowdin download
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
# Seems like the three letters code is not handled properly by LinguiJS?
|
||||
# Do without this language while we find a solution.
|
||||
- name: Remove catalogs not handled properly by LinguiJS compile command.
|
||||
run: rm -rf newIDE/app/src/locales/pcm_NG/
|
||||
|
||||
- name: Compile translations into .js files that are read by LinguiJS
|
||||
run: npm run compile-translations
|
||||
working-directory: newIDE/app
|
||||
|
||||
- name: Create a Pull Request with the changes
|
||||
uses: peter-evans/create-pull-request@v3.10.1
|
||||
with:
|
||||
commit-message: Update translations [skip ci]
|
||||
branch: chore/update-translations
|
||||
delete-branch: true
|
||||
title: '[Auto PR] Update translations'
|
||||
body: |
|
||||
This updates the translations by downloading them from Crowdin and compiling them for usage by the app.
|
||||
|
||||
Please double check the values in `newIDE/app/src/locales/LocalesMetadata.js` to ensure the changes are sensible.
|
@@ -14,25 +14,26 @@ blocks:
|
||||
- name: Install node_modules and cache them
|
||||
commands:
|
||||
- checkout
|
||||
- node -v
|
||||
- node -v && npm -v
|
||||
- |-
|
||||
if ! cache has_key newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json); then
|
||||
cd newIDE/app
|
||||
npm i
|
||||
npm ci
|
||||
cd ../..
|
||||
cache store newIDE-app-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum newIDE/app/package-lock.json) newIDE/app/node_modules
|
||||
fi
|
||||
- |-
|
||||
if ! cache has_key GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json); then
|
||||
cd GDJS
|
||||
npm i
|
||||
git checkout package-lock.json # Ensure no changes was made by newIDE post-install tasks.
|
||||
npm ci
|
||||
cd ..
|
||||
cache store GDJS-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/package-lock.json) GDJS/node_modules
|
||||
fi
|
||||
- |-
|
||||
if ! cache has_key GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json); then
|
||||
cd GDJS/tests
|
||||
npm i
|
||||
npm ci
|
||||
cd ../..
|
||||
cache store GDJS-tests-node_modules-$SEMAPHORE_GIT_BRANCH-revision-$(checksum GDJS/tests/package-lock.json) GDJS/tests/node_modules
|
||||
fi
|
||||
@@ -50,6 +51,7 @@ blocks:
|
||||
- cd newIDE/app
|
||||
- npm run postinstall
|
||||
- npm run flow
|
||||
- npm run check-script-types
|
||||
- cd ../..
|
||||
- name: GDJS typing and documentation generation
|
||||
commands:
|
||||
|
32
.travis.yml
32
.travis.yml
@@ -17,10 +17,6 @@ cache:
|
||||
directories:
|
||||
- $HOME/.npm
|
||||
|
||||
env:
|
||||
global:
|
||||
- GCC_VERSION="4.8"
|
||||
|
||||
services:
|
||||
# Virtual Framebuffer 'fake' X server for SFML
|
||||
- xvfb
|
||||
@@ -40,7 +36,6 @@ addons:
|
||||
# Build dependencies:
|
||||
- cmake
|
||||
- p7zip-full
|
||||
- g++-4.8
|
||||
# SFML dependencies:
|
||||
- libopenal-dev
|
||||
- libjpeg-dev
|
||||
@@ -60,8 +55,8 @@ before_install:
|
||||
- sudo dpkg --force-all -i libstdc++6
|
||||
|
||||
install:
|
||||
#Get the correct version of gcc/g++
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
|
||||
# Ensure we use a recent version of Node.js (and npm).
|
||||
- nvm install v16 && nvm use v16
|
||||
#Compile the tests only for GDCore
|
||||
- mkdir .build-tests
|
||||
- cd .build-tests
|
||||
@@ -70,21 +65,17 @@ install:
|
||||
- cd ..
|
||||
# Install Emscripten (for GDevelop.js)
|
||||
- git clone https://github.com/juj/emsdk.git
|
||||
- cd emsdk
|
||||
- ./emsdk install 1.39.6
|
||||
- ./emsdk activate 1.39.6
|
||||
- source ./emsdk_env.sh
|
||||
- cd ..
|
||||
# Install GDevelop.js dependencies and compile it
|
||||
- cd GDevelop.js
|
||||
- npm install -g grunt-cli
|
||||
- npm install
|
||||
- npm run build
|
||||
- cd ..
|
||||
#Install newIDE tests dependencies
|
||||
- cd emsdk && ./emsdk install 1.39.6 && ./emsdk activate 1.39.6 && cd ..
|
||||
# Install GDevelop.js dependencies
|
||||
- cd GDevelop.js && npm install && cd ..
|
||||
# Build GDevelop.js
|
||||
# (in a subshell to avoid Emscripten polluting the Node.js and npm version for the rest of the build)
|
||||
- (set -e; cd GDevelop.js && source ../emsdk/emsdk_env.sh && npm run build && cd ..)
|
||||
# Install newIDE tests dependencies
|
||||
- npm -v
|
||||
- cd newIDE/app && npm install
|
||||
- cd ../..
|
||||
#Install GDJS tests dependencies
|
||||
# Install GDJS tests dependencies
|
||||
- cd GDJS && npm install && cd tests && npm install
|
||||
- cd ../..
|
||||
|
||||
@@ -102,6 +93,7 @@ script:
|
||||
- npm test
|
||||
- npm run flow
|
||||
- npm run check-format
|
||||
- npm run check-script-types
|
||||
- cd ../..
|
||||
# GDJS tests:
|
||||
- cd GDJS
|
||||
|
29
.vscode/launch.json
vendored
29
.vscode/launch.json
vendored
@@ -4,13 +4,36 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "GDevelop.js Jest tests (all)",
|
||||
"program": "${workspaceFolder}/GDevelop.js/node_modules/.bin/jest",
|
||||
"args": ["--runInBand"],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/GDevelop.js"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "GDevelop.js Jest tests (current file)",
|
||||
"program": "${workspaceFolder}/GDevelop.js/node_modules/.bin/jest",
|
||||
"args": [
|
||||
"${fileBasenameNoExtension}"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"disableOptimisticBPs": true,
|
||||
"cwd": "${workspaceFolder}/GDevelop.js"
|
||||
},
|
||||
{
|
||||
"type": "pwa-chrome",
|
||||
"request": "launch",
|
||||
"name": "Launch Chrome against localhost",
|
||||
"name": "Debug with Chrome (web-app, local development server)",
|
||||
"url": "http://localhost:3000",
|
||||
"webRoot": "${workspaceFolder}",
|
||||
"preLaunchTask": "Start development server"
|
||||
"webRoot": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@@ -80,7 +80,7 @@
|
||||
},
|
||||
{
|
||||
"type": "typescript",
|
||||
"tsconfig": "GDJS/tsconfig.json",
|
||||
"tsconfig": "tsconfig.json",
|
||||
"option": "watch",
|
||||
"problemMatcher": ["$tsc-watch"],
|
||||
"group": "test",
|
||||
|
@@ -47,7 +47,6 @@ IF(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-potentially-evaluated-expression")
|
||||
ENDIF()
|
||||
|
||||
#Sanity checks
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
message( "CMAKE_BUILD_TYPE is empty, assuming build type is Release" )
|
||||
@@ -72,6 +71,13 @@ endif()
|
||||
|
||||
# Mark some warnings as errors
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# Activate as much warnings as possible to avoid errors like
|
||||
# uninitialized variables or other hard to debug bugs.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reorder-ctor -Wno-reorder -Wno-pessimizing-move -Wno-unused-variable -Wno-unused-private-field")
|
||||
|
||||
# Make as much warnings considered as errors as possible (only one for now).
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
|
||||
endif()
|
||||
|
||||
|
@@ -37,7 +37,7 @@ void ExposeProjectEffects(
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i; i < layout.GetObjectsCount(); i++) {
|
||||
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++) {
|
||||
|
@@ -621,8 +621,14 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
|
||||
argOutput = GenerateGetBehaviorNameCode(parameter);
|
||||
} else if (metadata.type == "key") {
|
||||
argOutput = "\"" + ConvertToString(parameter) + "\"";
|
||||
} else if (metadata.type == "password" || metadata.type == "musicfile" ||
|
||||
metadata.type == "soundfile" || metadata.type == "police") {
|
||||
} else if (metadata.type == "password" || // Deprecated
|
||||
metadata.type ==
|
||||
"musicfile" || // Should be renamed "largeAudioResource"
|
||||
metadata.type ==
|
||||
"soundfile" || // Should be renamed "audioResource"
|
||||
metadata.type == "police" || // Should be renamed "fontResource"
|
||||
metadata.type == "bitmapFontResource" ||
|
||||
metadata.type == "imageResource") {
|
||||
argOutput = "\"" + ConvertToString(parameter) + "\"";
|
||||
} else if (metadata.type == "mouse") {
|
||||
argOutput = "\"" + ConvertToString(parameter) + "\"";
|
||||
|
@@ -67,13 +67,13 @@ class GD_CORE_API ExpressionParser2 {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object name (or empty if none) and a behavior name (or empty if none),
|
||||
* return the index of the first parameter that is inside the parenthesis:
|
||||
* 0, 1 or 2.
|
||||
*
|
||||
* For example, in an expression like `Object.MyBehavior::Method("hello")`, the
|
||||
* parameter "hello" is the second parameter (the first being by convention Object,
|
||||
* and the second MyBehavior, also by convention).
|
||||
* Given an object name (or empty if none) and a behavior name (or empty if
|
||||
* none), return the index of the first parameter that is inside the
|
||||
* parenthesis: 0, 1 or 2.
|
||||
*
|
||||
* For example, in an expression like `Object.MyBehavior::Method("hello")`,
|
||||
* the parameter "hello" is the second parameter (the first being by
|
||||
* convention Object, and the second MyBehavior, also by convention).
|
||||
*/
|
||||
static size_t WrittenParametersFirstIndex(const gd::String &objectName,
|
||||
const gd::String &behaviorName) {
|
||||
@@ -403,9 +403,18 @@ class GD_CORE_API ExpressionParser2 {
|
||||
const gd::ExpressionMetadata &metadata =
|
||||
MetadataProvider::GetAnyExpressionMetadata(platform, functionFullName);
|
||||
|
||||
// In case we can't find a valid expression, ensure the node has the type
|
||||
// that is requested by the parent, so we avoid putting "unknown" (which
|
||||
// would be also correct, but less precise and would prevent completions to
|
||||
// be shown to the user)
|
||||
const gd::String returnType =
|
||||
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
|
||||
? type
|
||||
: metadata.GetReturnType();
|
||||
|
||||
auto parametersNode = Parameters(metadata.parameters);
|
||||
auto function =
|
||||
gd::make_unique<FunctionCallNode>(metadata.GetReturnType(),
|
||||
gd::make_unique<FunctionCallNode>(returnType,
|
||||
std::move(parametersNode.parameters),
|
||||
metadata,
|
||||
functionFullName);
|
||||
@@ -458,9 +467,18 @@ class GD_CORE_API ExpressionParser2 {
|
||||
MetadataProvider::GetObjectAnyExpressionMetadata(
|
||||
platform, objectType, objectFunctionOrBehaviorName);
|
||||
|
||||
// In case we can't find a valid expression, ensure the node has the type
|
||||
// that is requested by the parent, so we avoid putting "unknown" (which
|
||||
// would be also correct, but less precise and would prevent completions
|
||||
// to be shown to the user)
|
||||
const gd::String returnType =
|
||||
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
|
||||
? type
|
||||
: metadata.GetReturnType();
|
||||
|
||||
auto parametersNode = Parameters(metadata.parameters, objectName);
|
||||
auto function = gd::make_unique<FunctionCallNode>(
|
||||
metadata.GetReturnType(),
|
||||
returnType,
|
||||
objectName,
|
||||
std::move(parametersNode.parameters),
|
||||
metadata,
|
||||
@@ -520,10 +538,19 @@ class GD_CORE_API ExpressionParser2 {
|
||||
MetadataProvider::GetBehaviorAnyExpressionMetadata(
|
||||
platform, behaviorType, functionName);
|
||||
|
||||
// In case we can't find a valid expression, ensure the node has the type
|
||||
// that is requested by the parent, so we avoid putting "unknown" (which
|
||||
// would be also correct, but less precise and would prevent completions
|
||||
// to be shown to the user)
|
||||
const gd::String returnType =
|
||||
gd::MetadataProvider::IsBadExpressionMetadata(metadata) == true
|
||||
? type
|
||||
: metadata.GetReturnType();
|
||||
|
||||
auto parametersNode =
|
||||
Parameters(metadata.parameters, objectName, behaviorName);
|
||||
auto function = gd::make_unique<FunctionCallNode>(
|
||||
metadata.GetReturnType(),
|
||||
returnType,
|
||||
objectName,
|
||||
behaviorName,
|
||||
std::move(parametersNode.parameters),
|
||||
|
@@ -21,7 +21,7 @@ class ExpressionMetadata;
|
||||
|
||||
namespace gd {
|
||||
|
||||
struct ExpressionParserLocation {
|
||||
struct GD_CORE_API ExpressionParserLocation {
|
||||
ExpressionParserLocation() : isValid(false){};
|
||||
ExpressionParserLocation(size_t position)
|
||||
: isValid(true), startPosition(position), endPosition(position){};
|
||||
@@ -42,7 +42,8 @@ struct ExpressionParserLocation {
|
||||
/**
|
||||
* \brief A diagnostic that can be attached to a gd::ExpressionNode.
|
||||
*/
|
||||
struct ExpressionParserDiagnostic {
|
||||
struct GD_CORE_API ExpressionParserDiagnostic {
|
||||
virtual ~ExpressionParserDiagnostic() = default;
|
||||
virtual bool IsError() { return false; }
|
||||
virtual const gd::String &GetMessage() { return noMessage; }
|
||||
virtual size_t GetStartPosition() { return 0; }
|
||||
@@ -55,7 +56,7 @@ struct ExpressionParserDiagnostic {
|
||||
/**
|
||||
* \brief An error that can be attached to a gd::ExpressionNode.
|
||||
*/
|
||||
struct ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
struct GD_CORE_API ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
ExpressionParserError(const gd::String &type_,
|
||||
const gd::String &message_,
|
||||
size_t position_)
|
||||
@@ -84,7 +85,7 @@ struct ExpressionParserError : public ExpressionParserDiagnostic {
|
||||
* \brief The base node, from which all nodes in the tree of
|
||||
* an expression inherits from.
|
||||
*/
|
||||
struct ExpressionNode {
|
||||
struct GD_CORE_API ExpressionNode {
|
||||
ExpressionNode(const gd::String &type_) : type(type_){};
|
||||
virtual ~ExpressionNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker){};
|
||||
@@ -103,7 +104,7 @@ struct ExpressionNode {
|
||||
// gd::ParameterMetadata::IsExpression or "unknown".
|
||||
};
|
||||
|
||||
struct SubExpressionNode : public ExpressionNode {
|
||||
struct GD_CORE_API SubExpressionNode : public ExpressionNode {
|
||||
SubExpressionNode(const gd::String &type_,
|
||||
std::unique_ptr<ExpressionNode> expression_)
|
||||
: ExpressionNode(type_), expression(std::move(expression_)){};
|
||||
@@ -118,7 +119,7 @@ struct SubExpressionNode : public ExpressionNode {
|
||||
/**
|
||||
* \brief An operator node. For example: "lhs + rhs".
|
||||
*/
|
||||
struct OperatorNode : public ExpressionNode {
|
||||
struct GD_CORE_API OperatorNode : public ExpressionNode {
|
||||
OperatorNode(const gd::String &type_, gd::String::value_type op_)
|
||||
: ExpressionNode(type_), op(op_){};
|
||||
virtual ~OperatorNode(){};
|
||||
@@ -134,7 +135,7 @@ struct OperatorNode : public ExpressionNode {
|
||||
/**
|
||||
* \brief A unary operator node. For example: "-2".
|
||||
*/
|
||||
struct UnaryOperatorNode : public ExpressionNode {
|
||||
struct GD_CORE_API UnaryOperatorNode : public ExpressionNode {
|
||||
UnaryOperatorNode(const gd::String &type_, gd::String::value_type op_)
|
||||
: ExpressionNode(type_), op(op_){};
|
||||
virtual ~UnaryOperatorNode(){};
|
||||
@@ -150,7 +151,7 @@ struct UnaryOperatorNode : public ExpressionNode {
|
||||
* \brief A number node. For example: "123".
|
||||
* Its `type` is always "number".
|
||||
*/
|
||||
struct NumberNode : public ExpressionNode {
|
||||
struct GD_CORE_API NumberNode : public ExpressionNode {
|
||||
NumberNode(const gd::String &number_)
|
||||
: ExpressionNode("number"), number(number_){};
|
||||
virtual ~NumberNode(){};
|
||||
@@ -166,7 +167,7 @@ struct NumberNode : public ExpressionNode {
|
||||
* \brief A text node. For example: "Hello World".
|
||||
* Its `type` is always "string".
|
||||
*/
|
||||
struct TextNode : public ExpressionNode {
|
||||
struct GD_CORE_API TextNode : public ExpressionNode {
|
||||
TextNode(const gd::String &text_) : ExpressionNode("string"), text(text_){};
|
||||
virtual ~TextNode(){};
|
||||
virtual void Visit(ExpressionParser2NodeWorker &worker) {
|
||||
@@ -176,7 +177,7 @@ struct TextNode : public ExpressionNode {
|
||||
gd::String text;
|
||||
};
|
||||
|
||||
struct VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
|
||||
struct GD_CORE_API VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
|
||||
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(""){};
|
||||
|
||||
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child;
|
||||
@@ -190,7 +191,7 @@ struct VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
|
||||
* \see gd::VariableAccessorNode
|
||||
* \see gd::VariableBracketAccessorNode
|
||||
*/
|
||||
struct VariableNode : public ExpressionNode {
|
||||
struct GD_CORE_API VariableNode : public ExpressionNode {
|
||||
VariableNode(const gd::String &type_,
|
||||
const gd::String &name_,
|
||||
const gd::String &objectName_)
|
||||
@@ -213,7 +214,7 @@ struct VariableNode : public ExpressionNode {
|
||||
* \brief A bracket accessor of a variable. Example: MyChild
|
||||
* in MyVariable.MyChild
|
||||
*/
|
||||
struct VariableAccessorNode
|
||||
struct GD_CORE_API VariableAccessorNode
|
||||
: public VariableAccessorOrVariableBracketAccessorNode {
|
||||
VariableAccessorNode(const gd::String &name_) : name(name_){};
|
||||
virtual ~VariableAccessorNode(){};
|
||||
@@ -230,7 +231,7 @@ struct VariableAccessorNode
|
||||
* \brief A bracket accessor of a variable. Example: ["MyChild"]
|
||||
* (in MyVariable["MyChild"]).
|
||||
*/
|
||||
struct VariableBracketAccessorNode
|
||||
struct GD_CORE_API VariableBracketAccessorNode
|
||||
: public VariableAccessorOrVariableBracketAccessorNode {
|
||||
VariableBracketAccessorNode(std::unique_ptr<ExpressionNode> expression_)
|
||||
: expression(std::move(expression_)){};
|
||||
@@ -242,7 +243,7 @@ struct VariableBracketAccessorNode
|
||||
std::unique_ptr<ExpressionNode> expression;
|
||||
};
|
||||
|
||||
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
struct GD_CORE_API IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
: public ExpressionNode {
|
||||
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(
|
||||
const gd::String &type)
|
||||
@@ -252,7 +253,7 @@ struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
/**
|
||||
* \brief An identifier node, usually representing an object or a function name.
|
||||
*/
|
||||
struct IdentifierNode
|
||||
struct GD_CORE_API IdentifierNode
|
||||
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
IdentifierNode(const gd::String &identifierName_, const gd::String &type_)
|
||||
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type_),
|
||||
@@ -265,7 +266,7 @@ struct IdentifierNode
|
||||
gd::String identifierName;
|
||||
};
|
||||
|
||||
struct FunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
struct GD_CORE_API FunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
FunctionCallOrObjectFunctionNameOrEmptyNode(const gd::String &type)
|
||||
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type){};
|
||||
@@ -278,7 +279,7 @@ struct FunctionCallOrObjectFunctionNameOrEmptyNode
|
||||
* For example: "MyObject.Function" or "MyObject.Physics" or
|
||||
* "MyObject.Physics::LinearVelocity".
|
||||
*/
|
||||
struct ObjectFunctionNameNode
|
||||
struct GD_CORE_API ObjectFunctionNameNode
|
||||
: public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
ObjectFunctionNameNode(const gd::String &type_,
|
||||
const gd::String &objectName_,
|
||||
@@ -331,7 +332,7 @@ struct ObjectFunctionNameNode
|
||||
* For example: "MyExtension::MyFunction(1, 2)", "MyObject.Function()" or
|
||||
* "MyObject.Physics::LinearVelocity()".
|
||||
*/
|
||||
struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
struct GD_CORE_API FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
/** \brief Construct a free function call node. */
|
||||
FunctionCallNode(const gd::String &type_,
|
||||
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
|
||||
@@ -399,7 +400,7 @@ struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
* \brief An empty node, used when parsing failed/a syntax error was
|
||||
* encountered and any other node could not make sense.
|
||||
*/
|
||||
struct EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
struct GD_CORE_API EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
|
||||
EmptyNode(const gd::String &type_, const gd::String &text_ = "")
|
||||
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_), text(text_){};
|
||||
virtual ~EmptyNode(){};
|
||||
|
@@ -7,21 +7,21 @@
|
||||
#define GDCORE_EXPRESSIONPARSER2NODEWORKER_H
|
||||
|
||||
namespace gd {
|
||||
class ExpressionNode;
|
||||
class SubExpressionNode;
|
||||
class OperatorNode;
|
||||
class UnaryOperatorNode;
|
||||
class NumberNode;
|
||||
class TextNode;
|
||||
class VariableNode;
|
||||
class VariableAccessorNode;
|
||||
class VariableBracketAccessorNode;
|
||||
class IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
class IdentifierNode;
|
||||
class FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
class ObjectFunctionNameNode;
|
||||
class FunctionCallNode;
|
||||
class EmptyNode;
|
||||
struct ExpressionNode;
|
||||
struct SubExpressionNode;
|
||||
struct OperatorNode;
|
||||
struct UnaryOperatorNode;
|
||||
struct NumberNode;
|
||||
struct TextNode;
|
||||
struct VariableNode;
|
||||
struct VariableAccessorNode;
|
||||
struct VariableBracketAccessorNode;
|
||||
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
struct IdentifierNode;
|
||||
struct FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
struct ObjectFunctionNameNode;
|
||||
struct FunctionCallNode;
|
||||
struct EmptyNode;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
@@ -34,21 +34,21 @@ namespace gd {
|
||||
* \see gd::ExpressionNode
|
||||
*/
|
||||
class GD_CORE_API ExpressionParser2NodeWorker {
|
||||
friend class ExpressionNode;
|
||||
friend class SubExpressionNode;
|
||||
friend class OperatorNode;
|
||||
friend class UnaryOperatorNode;
|
||||
friend class NumberNode;
|
||||
friend class TextNode;
|
||||
friend class VariableNode;
|
||||
friend class VariableAccessorNode;
|
||||
friend class VariableBracketAccessorNode;
|
||||
friend class IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend class IdentifierNode;
|
||||
friend class FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend class ObjectFunctionNameNode;
|
||||
friend class FunctionCallNode;
|
||||
friend class EmptyNode;
|
||||
friend struct ExpressionNode;
|
||||
friend struct SubExpressionNode;
|
||||
friend struct OperatorNode;
|
||||
friend struct UnaryOperatorNode;
|
||||
friend struct NumberNode;
|
||||
friend struct TextNode;
|
||||
friend struct VariableNode;
|
||||
friend struct VariableAccessorNode;
|
||||
friend struct VariableBracketAccessorNode;
|
||||
friend struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend struct IdentifierNode;
|
||||
friend struct FunctionCallOrObjectFunctionNameOrEmptyNode;
|
||||
friend struct ObjectFunctionNameNode;
|
||||
friend struct FunctionCallNode;
|
||||
friend struct EmptyNode;
|
||||
|
||||
public:
|
||||
virtual ~ExpressionParser2NodeWorker();
|
||||
|
@@ -18,7 +18,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("Toujours",
|
||||
_("Always"),
|
||||
@@ -84,7 +83,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Functions"),
|
||||
"res/function24.png",
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name")
|
||||
.AddParameter("functionParameterName", "Parameter name")
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -94,7 +93,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Get function parameter (also called \"argument\") value"),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name");
|
||||
.AddParameter("functionParameterName", "Parameter name");
|
||||
|
||||
extension
|
||||
.AddStrExpression(
|
||||
@@ -103,8 +102,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
|
||||
_("Get function parameter (also called \"argument\") text "),
|
||||
_("Functions"),
|
||||
"res/function16.png")
|
||||
.AddParameter("string", "Parameter name");
|
||||
#endif
|
||||
.AddParameter("functionParameterName", "Parameter name");
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -21,7 +21,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/audio");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction("PlaySoundCanal",
|
||||
_("Play a sound on a channel"),
|
||||
@@ -579,7 +578,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
|
||||
"res/conditions/volume.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -25,7 +25,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
gd::ObjectMetadata& obj = extension.AddObject<gd::Object>(
|
||||
"", _("Base object"), _("Base object"), "res/objeticon24.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddCondition("PosX",
|
||||
_("X position"),
|
||||
_("Compare the X position of the object."),
|
||||
@@ -84,9 +83,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/position.png")
|
||||
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("operator", _("Modification's sign"), "number")
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("operator", _("Modification's sign"), "number")
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -99,15 +98,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/position24.png",
|
||||
"res/actions/position.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("operator", _("Modification's sign"), "number")
|
||||
.AddParameter("expression", _("X position"))
|
||||
.AddParameter("operator", _("Modification's sign"))
|
||||
.AddParameter("operator", _("Modification's sign"), "number")
|
||||
.AddParameter("expression", _("Y position"))
|
||||
.MarkAsSimple();
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "CenterX",
|
||||
_("Center X position"),
|
||||
_("the X position of the center"),
|
||||
_("the X position of the center of rotation"),
|
||||
_("the X position of the center"),
|
||||
_("Position/Center"),
|
||||
"res/actions/position24.png")
|
||||
@@ -116,13 +115,67 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
|
||||
obj.AddExpressionAndConditionAndAction("number", "CenterY",
|
||||
_("Center Y position"),
|
||||
_("the Y position of the center"),
|
||||
_("the Y position of the center of rotation"),
|
||||
_("the Y position of the center"),
|
||||
_("Position/Center"),
|
||||
"res/actions/position24.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxLeft",
|
||||
_("Bounding box left position"),
|
||||
_("the bounding box (the area encapsulating the object) left position"),
|
||||
_("the bounding box left position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-left.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxTop",
|
||||
_("Bounding box top position"),
|
||||
_("the bounding box (the area encapsulating the object) top position"),
|
||||
_("the bounding box top position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-top.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxRight",
|
||||
_("Bounding box right position"),
|
||||
_("the bounding box (the area encapsulating the object) right position"),
|
||||
_("the bounding box right position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-right.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxBottom",
|
||||
_("Bounding box bottom position"),
|
||||
_("the bounding box (the area encapsulating the object) bottom position"),
|
||||
_("the bounding box bottom position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-bottom.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxCenterX",
|
||||
_("Bounding box center X position"),
|
||||
_("the bounding box (the area encapsulating the object) center X position"),
|
||||
_("the bounding box center X position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-center.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddExpressionAndCondition("number", "BoundingBoxCenterY",
|
||||
_("Bounding box center Y position"),
|
||||
_("the bounding box (the area encapsulating the object) center Y position"),
|
||||
_("the bounding box center Y position"),
|
||||
_("Position/Bounding Box"),
|
||||
"res/conditions/bounding-box-center.svg")
|
||||
.AddParameter("object", _("Object"))
|
||||
.UseStandardParameters("number");
|
||||
|
||||
obj.AddAction("MettreAutourPos",
|
||||
_("Put around a position"),
|
||||
_("Position the center of the given object around a position, "
|
||||
@@ -156,7 +209,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Rotate"),
|
||||
_("Rotate an object, clockwise if the speed is positive, "
|
||||
"counterclockwise otherwise."),
|
||||
_("Rotate _PARAM0_ at speed _PARAM1_deg/second"),
|
||||
_("Rotate _PARAM0_ at speed _PARAM1_ deg/second"),
|
||||
_("Angle"),
|
||||
"res/actions/direction24.png",
|
||||
"res/actions/direction.png")
|
||||
@@ -170,7 +223,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"RotateTowardAngle",
|
||||
_("Rotate toward angle"),
|
||||
_("Rotate an object towards an angle with the specified speed."),
|
||||
_("Rotate _PARAM0_ towards _PARAM1_ at speed _PARAM2_deg/second"),
|
||||
_("Rotate _PARAM0_ towards _PARAM1_ at speed _PARAM2_ deg/second"),
|
||||
_("Angle"),
|
||||
"res/actions/direction24.png",
|
||||
"res/actions/direction.png")
|
||||
@@ -186,7 +239,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Rotate toward position"),
|
||||
_("Rotate an object towards a position, with the specified speed."),
|
||||
_("Rotate _PARAM0_ towards _PARAM1_;_PARAM2_ at speed "
|
||||
"_PARAM3_deg/second"),
|
||||
"_PARAM3_ deg/second"),
|
||||
_("Angle"),
|
||||
"res/actions/direction24.png",
|
||||
"res/actions/direction.png")
|
||||
@@ -793,6 +846,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
.AddCodeOnlyParameter("conditionInverted", "")
|
||||
.MarkAsSimple();
|
||||
|
||||
// Deprecated and replaced by CompareObjectTimer
|
||||
obj.AddCondition(
|
||||
"ObjectTimer",
|
||||
_("Value of an object timer"),
|
||||
@@ -803,7 +857,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/conditions/timer.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Timer's name"))
|
||||
.AddParameter("expression", _("Time in seconds"));
|
||||
.AddParameter("expression", _("Time in seconds"))
|
||||
.SetHidden();
|
||||
|
||||
obj.AddCondition("CompareObjectTimer",
|
||||
_("Value of an object timer"),
|
||||
_("Compare the elapsed time of an object timer. This condition doesn't start the timer."),
|
||||
_("The timer _PARAM1_ of _PARAM0_ _PARAM2_ _PARAM3_ seconds"),
|
||||
_("Timers"),
|
||||
"res/conditions/timer24.png",
|
||||
"res/conditions/timer.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Timer's name"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "time")
|
||||
.AddParameter("expression", _("Time in seconds"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
obj.AddCondition("ObjectTimerPaused",
|
||||
_("Object timer paused"),
|
||||
@@ -1080,7 +1148,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Effect Name"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1094,8 +1162,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Effect Name"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1109,8 +1177,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Effect Name"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1124,8 +1192,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Effect Name"))
|
||||
.AddParameter("string", _("Parameter Name"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.AddParameter("objectEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable?"))
|
||||
.MarkAsSimple();
|
||||
|
||||
@@ -1137,14 +1205,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
"res/actions/effect24.png",
|
||||
"res/actions/effect.png")
|
||||
.AddParameter("object", _("Object"))
|
||||
.AddParameter("string", _("Effect Name"))
|
||||
.AddParameter("objectEffectName", _("Effect name"))
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddAction("Create",
|
||||
_("Create an object"),
|
||||
_("Create an object at specified position"),
|
||||
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_"),
|
||||
_("Create object _PARAM1_ at position _PARAM2_;_PARAM3_ (layer: _PARAM4_)"),
|
||||
_("Objects"),
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create.png")
|
||||
@@ -1162,7 +1230,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Among the objects of the specified group, this action will "
|
||||
"create the object with the specified name."),
|
||||
_("Among objects _PARAM1_, create object named _PARAM2_ at "
|
||||
"position _PARAM3_;_PARAM4_"),
|
||||
"position _PARAM3_;_PARAM4_ (layer: _PARAM5_)"),
|
||||
_("Objects"),
|
||||
"res/actions/create24.png",
|
||||
"res/actions/create.png")
|
||||
@@ -1441,7 +1509,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
|
||||
_("Objects"),
|
||||
"res/actions/layer.png")
|
||||
.AddParameter("object", _("Object"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -24,7 +24,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddExpressionAndConditionAndAction(
|
||||
"number",
|
||||
@@ -342,8 +341,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("expression", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -361,8 +360,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("string", _("New value"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -380,8 +379,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("string", _("Parameter name"))
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("layerEffectParameterName", _("Parameter name"))
|
||||
.AddParameter("yesorno", _("Enable this parameter"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -396,7 +395,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
@@ -410,7 +409,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
|
||||
.SetDefaultValue("\"\"")
|
||||
.AddParameter("string", _("Effect"))
|
||||
.AddParameter("layerEffectName", _("Effect name"))
|
||||
.AddParameter("yesorno", _("Enable"), "", true)
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -420,7 +419,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
_("Layer time scale"),
|
||||
_("Compare the time scale applied to the objects of the layer."),
|
||||
_("the time scale of layer _PARAM1_"),
|
||||
_("Layers and cameras/Time"),
|
||||
_("Layers and cameras"),
|
||||
"res/conditions/time24.png",
|
||||
"res/conditions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -434,8 +433,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"ChangeLayerTimeScale",
|
||||
_("Change layer time scale"),
|
||||
_("Change the time scale applied to the objects of the layer."),
|
||||
_("Set time scale of layer _PARAM1_ to _PARAM2_"),
|
||||
_("Layers and cameras/Time"),
|
||||
_("Set the time scale of layer _PARAM1_ to _PARAM2_"),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -552,8 +551,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
|
||||
extension
|
||||
.AddExpression("LayerTimeScale",
|
||||
_("Time scale"),
|
||||
_("Time scale"),
|
||||
_("Layer time scale"),
|
||||
_("Returns the time scale of the specified layer."),
|
||||
_("Layers and cameras"),
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -567,7 +566,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
|
||||
"res/actions/camera.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("layer", _("Layer"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -21,7 +21,6 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/common-conversions");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
extension
|
||||
.AddExpression("ToNumber",
|
||||
@@ -65,7 +64,6 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
|
||||
_("Conversion"),
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("expression", _("Angle, in radians"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#include "AllBuiltinExtensions.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Events/Builtin/CommentEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachChildVariableEvent.h"
|
||||
#include "GDCore/Events/Builtin/ForEachEvent.h"
|
||||
@@ -15,7 +14,6 @@
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Events/Builtin/WhileEvent.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
namespace gd {
|
||||
@@ -33,7 +31,6 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/advanced-conditions");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("Or",
|
||||
_("Or"),
|
||||
@@ -86,29 +83,29 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
std::make_shared<gd::StandardEvent>());
|
||||
|
||||
extension.AddEvent("Link",
|
||||
_("Link"),
|
||||
_("Link to some external events"),
|
||||
_("Link external events"),
|
||||
_("Link to external events."),
|
||||
"",
|
||||
"res/lienaddicon.png",
|
||||
std::make_shared<gd::LinkEvent>());
|
||||
|
||||
extension.AddEvent("Comment",
|
||||
_("Comment"),
|
||||
_("Event displaying a text in the events editor"),
|
||||
_("Event displaying a text in the events editor."),
|
||||
"",
|
||||
"res/comment.png",
|
||||
std::make_shared<gd::CommentEvent>());
|
||||
|
||||
extension.AddEvent("While",
|
||||
_("While"),
|
||||
_("The event is repeated while the conditions are true"),
|
||||
_("Repeat the event while the conditions are true."),
|
||||
"",
|
||||
"res/while.png",
|
||||
std::make_shared<gd::WhileEvent>());
|
||||
|
||||
extension.AddEvent("Repeat",
|
||||
_("Repeat"),
|
||||
_("Event repeated a number of times"),
|
||||
_("Repeat the event for a specified number of times."),
|
||||
"",
|
||||
"res/repeat.png",
|
||||
std::make_shared<gd::RepeatEvent>());
|
||||
@@ -129,12 +126,11 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
|
||||
std::make_shared<gd::ForEachChildVariableEvent>());
|
||||
|
||||
extension.AddEvent("Group",
|
||||
_("Group"),
|
||||
_("Group containing events"),
|
||||
_("Event group"),
|
||||
_("Group containing events."),
|
||||
"",
|
||||
"res/foreach.png",
|
||||
std::make_shared<gd::GroupEvent>());
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -21,7 +21,6 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/interface/scene-editor/external-layouts");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction("CreateObjectsFromExternalLayout",
|
||||
_("Create objects from an external layout"),
|
||||
@@ -37,7 +36,6 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
|
||||
.AddParameter("expression", _("Y position of the origin"), "", true)
|
||||
.SetDefaultValue("0")
|
||||
.MarkAsAdvanced();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -22,7 +22,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/storage");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition(
|
||||
"GroupExists",
|
||||
@@ -194,7 +193,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
|
||||
"res/actions/launchFile.png")
|
||||
.AddParameter("string", _("Command"))
|
||||
.MarkAsAdvanced();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -23,11 +23,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/keyboard");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("KeyPressed",
|
||||
_("Key pressed"),
|
||||
_("Test if a key is pressed"),
|
||||
_("Check if a key is pressed"),
|
||||
_("_PARAM1_ key is pressed"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
@@ -38,7 +37,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
extension
|
||||
.AddCondition("KeyReleased",
|
||||
_("Key released"),
|
||||
_("Test if a key was just released"),
|
||||
_("Check if a key was just released"),
|
||||
_("_PARAM1_ key is released"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
@@ -49,33 +48,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
extension
|
||||
.AddCondition("KeyFromTextPressed",
|
||||
_("Key pressed (text expression)"),
|
||||
_("Test if a key, retrieved from the result of the "
|
||||
_("Check if a key, retrieved from the result of the "
|
||||
"expression, is pressed"),
|
||||
_("_PARAM1_ key is pressed"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Expression generating the key to test"))
|
||||
.AddParameter("string", _("Expression generating the key to check"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("KeyFromTextReleased",
|
||||
_("Key released (text expression)"),
|
||||
_("Test if a key, retrieved from the result of the "
|
||||
_("Check if a key, retrieved from the result of the "
|
||||
"expression, was just released"),
|
||||
_("_PARAM1_ key is released"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
"res/conditions/keyboard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Expression generating the key to test"))
|
||||
.AddParameter("string", _("Expression generating the key to check"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition("AnyKeyPressed",
|
||||
_("Any key pressed"),
|
||||
_("Test if any key is pressed"),
|
||||
_("Check if any key is pressed"),
|
||||
_("Any key is pressed"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
@@ -85,7 +84,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
extension
|
||||
.AddCondition("AnyKeyReleased",
|
||||
_("Any key released"),
|
||||
_("Test if any key is released"),
|
||||
_("Check if any key is released"),
|
||||
_("Any key is released"),
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard24.png",
|
||||
@@ -100,7 +99,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
|
||||
_("Keyboard"),
|
||||
"res/conditions/keyboard.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -19,7 +19,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
"Florian Rival",
|
||||
"Open source (MIT License)");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
extension
|
||||
.AddExpression("normalize",
|
||||
@@ -403,7 +402,6 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
|
||||
.AddParameter("expression", _("Angle, in degrees"))
|
||||
.AddParameter("expression", _("Distance"));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -25,7 +25,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/mouse-touch");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition(
|
||||
"IsMouseWheelScrollingUp",
|
||||
@@ -217,6 +216,42 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
.AddParameter("mouse", _("Button to check"))
|
||||
.MarkAsSimple();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"MouseButtonFromTextPressed",
|
||||
_("Mouse button pressed or touch held (text expression)"),
|
||||
_("Check if a mouse button, retrieved from the result of the "
|
||||
"expression, is pressed."),
|
||||
_("_PARAM1_ mouse button is pressed"),
|
||||
_("Mouse and touch"),
|
||||
"res/conditions/mouse24.png",
|
||||
"res/conditions/mouse.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("stringWithSelector",
|
||||
_("Expression generating the mouse button to check"),
|
||||
"[\"Left\", \"Right\", \"Middle\"]")
|
||||
.SetParameterLongDescription(
|
||||
_("Possible values are Left, Right and Middle."))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddCondition(
|
||||
"MouseButtonFromTextReleased",
|
||||
_("Mouse button released (text expression)"),
|
||||
_("Check if a mouse button, retrieved from the result of the "
|
||||
"expression, was just released."),
|
||||
_("_PARAM1_ mouse button is released"),
|
||||
_("Mouse and touch"),
|
||||
"res/conditions/mouse24.png",
|
||||
"res/conditions/mouse.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("stringWithSelector",
|
||||
_("Expression generating the mouse button to check"),
|
||||
"[\"Left\", \"Right\", \"Middle\"]")
|
||||
.SetParameterLongDescription(
|
||||
_("Possible values are Left, Right and Middle."))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
extension
|
||||
.AddExpressionAndCondition("number",
|
||||
"TouchX",
|
||||
@@ -302,8 +337,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
|
||||
_("Mouse and touch/Multitouch"),
|
||||
"res/conditions/touch.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -21,7 +21,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/network");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction(
|
||||
"SendRequest",
|
||||
@@ -196,7 +195,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
|
||||
"res/conditions/toujours24.png")
|
||||
.AddParameter("objectPtr", _("The object with the variable"))
|
||||
.AddParameter("objectvar", _("The object variable to be stringified"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -20,7 +20,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
extension
|
||||
.AddExpression("Random",
|
||||
@@ -196,7 +195,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
"res/conditions/egal.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddParameter("expression", _("First expression"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.AddParameter("expression", _("Second expression"))
|
||||
.MarkAsAdvanced();
|
||||
|
||||
@@ -210,10 +209,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
|
||||
"res/conditions/egal.png")
|
||||
.SetHelpPath("/all-features/advanced-conditions")
|
||||
.AddParameter("string", _("First string expression"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "string")
|
||||
.AddParameter("string", _("Second string expression"))
|
||||
.MarkAsAdvanced();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -75,11 +75,9 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
SetTimeBetweenFrames(
|
||||
element.GetDoubleAttribute("timeBetweenFrames", 1, "tempsEntre"));
|
||||
SetLoop(element.GetBoolAttribute("looping", false, "boucle"));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetMetadata(element.HasAttribute("metadata") || element.HasChild("metadata")
|
||||
? element.GetStringAttribute("metadata")
|
||||
: "");
|
||||
#endif
|
||||
|
||||
const gd::SerializerElement& spritesElement =
|
||||
element.GetChild("sprites", 0, "Sprites");
|
||||
@@ -135,7 +133,6 @@ void Direction::UnserializeFrom(const gd::SerializerElement& element) {
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void SavePoint(const Point& point, gd::SerializerElement& element) {
|
||||
element.SetAttribute("name", point.GetName());
|
||||
element.SetAttribute("x", point.GetX());
|
||||
@@ -190,6 +187,5 @@ void Direction::SerializeTo(gd::SerializerElement& element) const {
|
||||
if (!GetMetadata().empty()) element.SetAttribute("metadata", GetMetadata());
|
||||
SaveSpritesDirection(sprites, element.AddChild("sprites"));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -113,7 +113,6 @@ class GD_CORE_API Direction {
|
||||
*/
|
||||
void MoveSprite(std::size_t oldIndex, std::size_t newIndex);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Set the metadata (any string) associated to the Direction.
|
||||
* \note Can be used by external editors to store extra information.
|
||||
@@ -124,20 +123,15 @@ class GD_CORE_API Direction {
|
||||
* \brief Return the (optional) metadata associated to the Direction.
|
||||
*/
|
||||
virtual const gd::String& GetMetadata() const { return metadata; }
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const gd::SerializerElement& element);
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void SerializeTo(gd::SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool loop; ///< true if the animation must loop.
|
||||
double timeBetweenFrame; ///< The time between each sprite of the animation.
|
||||
std::vector<Sprite> sprites; ///< The sprites of the direction.
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::String metadata;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -29,7 +29,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Animated object which can be used for most elements of a game"),
|
||||
"CppPlatform/Extensions/spriteicon.png");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
obj.AddAction("Opacity",
|
||||
_("Change sprite opacity"),
|
||||
_("Change the opacity of a Sprite. 0 is fully transparent, 255 "
|
||||
@@ -79,7 +78,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Direction"),
|
||||
"res/actions/direction24.png",
|
||||
"res/actions/direction.png")
|
||||
|
||||
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardOperatorParameters("number")
|
||||
.MarkAsAdvanced();
|
||||
@@ -243,7 +242,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Direction"),
|
||||
"res/conditions/direction24.png",
|
||||
"res/conditions/direction.png")
|
||||
|
||||
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
|
||||
.AddParameter("object", _("Object"), "Sprite")
|
||||
.UseStandardRelationalOperatorParameters("number");
|
||||
|
||||
@@ -362,7 +361,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
obj.AddAction("FlipX",
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip the object horizontally"),
|
||||
_("Flip horizontally _PARAM0_ : _PARAM1_"),
|
||||
_("Flip horizontally _PARAM0_: _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipX24.png",
|
||||
"res/actions/flipX.png")
|
||||
@@ -374,7 +373,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
obj.AddAction("FlipY",
|
||||
_("Flip the object vertically"),
|
||||
_("Flip the object vertically"),
|
||||
_("Flip vertically _PARAM0_ : _PARAM1_"),
|
||||
_("Flip vertically _PARAM0_: _PARAM1_"),
|
||||
_("Effects"),
|
||||
"res/actions/flipY24.png",
|
||||
"res/actions/flipY.png")
|
||||
@@ -465,6 +464,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
_("Direction of the object"),
|
||||
_("Direction"),
|
||||
"res/actions/direction.png")
|
||||
.SetHidden() // Hide as 8 direction is not supported officially in the interface.
|
||||
.AddParameter("object", _("Object"), "Sprite");
|
||||
|
||||
obj.AddExpression("Anim",
|
||||
@@ -536,7 +536,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
|
||||
.AddParameter("objectList", _("Object 1"), "Sprite")
|
||||
.AddParameter("objectList", _("Object 2"), "Sprite")
|
||||
.AddCodeOnlyParameter("conditionInverted", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -17,11 +17,9 @@
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
#include "GDCore/Tools/Localization.h"
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include "GDCore/Project/PropertyDescriptor.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -81,7 +79,6 @@ void SpriteObject::DoUnserializeFrom(gd::Project& project,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
|
||||
element.SetAttribute("updateIfNotVisible", updateIfNotVisible);
|
||||
|
||||
@@ -157,7 +154,6 @@ bool SpriteObject::UpdateInitialInstanceProperty(gd::InitialInstance& position,
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
const Animation& SpriteObject::GetAnimation(std::size_t nb) const {
|
||||
if (nb >= animations.size()) return badAnimation;
|
||||
|
@@ -44,7 +44,6 @@ class GD_CORE_API SpriteObject : public gd::Object {
|
||||
return gd::make_unique<SpriteObject>(*this);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
@@ -60,7 +59,6 @@ class GD_CORE_API SpriteObject : public gd::Object {
|
||||
const gd::String& value,
|
||||
gd::Project& project,
|
||||
gd::Layout& scene) override;
|
||||
#endif
|
||||
|
||||
/** \name Animations
|
||||
* Methods related to animations management
|
||||
@@ -118,14 +116,24 @@ class GD_CORE_API SpriteObject : public gd::Object {
|
||||
* animation of the object.
|
||||
*/
|
||||
const std::vector<Animation>& GetAllAnimations() const { return animations; }
|
||||
|
||||
/**
|
||||
* \brief Set if the object animation should be played even if the object is hidden
|
||||
* or far from the camera.
|
||||
*/
|
||||
void SetUpdateIfNotVisible(bool updateIfNotVisible_) { updateIfNotVisible = updateIfNotVisible_; }
|
||||
|
||||
/**
|
||||
* \brief Check if the object animation should be played even if the object is hidden
|
||||
* or far from the camera (false by default).
|
||||
*/
|
||||
bool GetUpdateIfNotVisible() const { return updateIfNotVisible; }
|
||||
///@}
|
||||
|
||||
private:
|
||||
void DoUnserializeFrom(gd::Project& project,
|
||||
const gd::SerializerElement& element) override;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void DoSerializeTo(gd::SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
mutable std::vector<Animation> animations;
|
||||
bool updateIfNotVisible; ///< If set to true, ask the game engine to play
|
||||
|
@@ -21,7 +21,6 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension.AddStrExpression("NewLine",
|
||||
_("Insert a new line"),
|
||||
_("Insert a new line"),
|
||||
@@ -182,7 +181,6 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
|
||||
_("Position of the last character in the string to be "
|
||||
"considered in the search"));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -22,8 +22,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/timers");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
|
||||
// Deprecated and replaced by CompareTimer
|
||||
extension
|
||||
.AddCondition("Timer",
|
||||
_("Value of a scene timer"),
|
||||
@@ -34,13 +33,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"res/conditions/timer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("expression", _("Time in seconds"))
|
||||
.AddParameter("string", _("Timer's name"));
|
||||
.AddParameter("string", _("Timer's name"))
|
||||
.SetHidden();
|
||||
|
||||
extension
|
||||
.AddCondition("CompareTimer",
|
||||
_("Value of a scene timer"),
|
||||
_("Compare the elapsed time of a scene timer. This condition doesn't start the timer."),
|
||||
_("The timer _PARAM1_ _PARAM2_ _PARAM3_ seconds"),
|
||||
_("Timers and time"),
|
||||
"res/conditions/timer24.png",
|
||||
"res/conditions/timer.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
.AddParameter("string", _("Timer's name"))
|
||||
.AddParameter("relationalOperator", _("Sign of the test"), "time")
|
||||
.AddParameter("expression", _("Time in seconds"))
|
||||
.SetManipulatedType("number");
|
||||
|
||||
extension
|
||||
.AddCondition("TimeScale",
|
||||
_("Time scale"),
|
||||
_("Test the time scale."),
|
||||
_("the time scale"),
|
||||
_("Compare the time scale of the scene."),
|
||||
_("the time scale of the scene"),
|
||||
_("Timers and time"),
|
||||
"res/conditions/time24.png",
|
||||
"res/conditions/time.png")
|
||||
@@ -112,8 +126,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
extension
|
||||
.AddAction("ChangeTimeScale",
|
||||
_("Change time scale"),
|
||||
_("Change the time scale of the game."),
|
||||
_("Set time scale to _PARAM1_"),
|
||||
_("Change the time scale of the scene."),
|
||||
_("Set the time scale of the scene to _PARAM1_"),
|
||||
_("Timers and time"),
|
||||
"res/actions/time24.png",
|
||||
"res/actions/time.png")
|
||||
@@ -176,20 +190,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
extension
|
||||
.AddExpression("TimeScale",
|
||||
_("Time scale"),
|
||||
_("Time scale"),
|
||||
_("Returns the time scale of the scene."),
|
||||
_("Time"),
|
||||
"res/actions/time.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddExpression("TimeScale",
|
||||
_("Time scale"),
|
||||
_("Time scale"),
|
||||
_("Time"),
|
||||
"res/actions/time.png")
|
||||
.SetHidden()
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
|
||||
extension
|
||||
.AddExpression("Time",
|
||||
_("Current time"),
|
||||
@@ -206,7 +211,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
|
||||
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
|
||||
"\"yday\", \"timestamp\"]");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -23,13 +23,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/variables");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddCondition("VarScene",
|
||||
_("Value of a scene variable"),
|
||||
_("Compare the value of a scene variable."),
|
||||
_("the scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -40,7 +39,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Text of a scene variable"),
|
||||
_("Compare the text of a scene variable."),
|
||||
_("the text of scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -52,7 +51,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Boolean value of a scene variable"),
|
||||
_("Compare the boolean value of a scene variable."),
|
||||
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -65,7 +64,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Child existence"),
|
||||
_("Check if the specified child of the scene variable exists."),
|
||||
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
|
||||
_("Variables/Collections/Structures"),
|
||||
_("Variables/Scene variables/Collections/Structures"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -90,7 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
"Test if a scene variable is defined",
|
||||
"Test if the scene variable exists.",
|
||||
"Scene variable _PARAM0_ is defined",
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddCodeOnlyParameter("currentScene", "")
|
||||
@@ -152,7 +151,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Value of a scene variable"),
|
||||
_("Change the value of a scene variable."),
|
||||
_("the scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -163,7 +162,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("String of a scene variable"),
|
||||
_("Modify the text of a scene variable."),
|
||||
_("the text of scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -175,7 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Boolean value of a scene variable"),
|
||||
_("Modify the boolean value of a scene variable."),
|
||||
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -188,7 +187,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("If it was true, it will become false, and if it was "
|
||||
"false it will become true."),
|
||||
_("Toggle the boolean value of scene variable _PARAM0_"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/conditions/var24.png",
|
||||
"res/conditions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
@@ -246,7 +245,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove a child"),
|
||||
_("Remove a child from a scene variable."),
|
||||
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
|
||||
_("Variables/Collections/Structures"),
|
||||
_("Variables/Scene variables/Collections/Structures"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -270,7 +269,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Clear scene variable"),
|
||||
_("Remove all the children from the scene variable."),
|
||||
_("Clear children from scene variable _PARAM0_"),
|
||||
_("Variables/Collections"),
|
||||
_("Variables/Scene variables/Collections"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -292,7 +291,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Append variable to a scene array"),
|
||||
_("Appends a variable at the end of a scene array variable."),
|
||||
_("Append variable _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Variables/Collections/Arrays"),
|
||||
_("Variables/Scene variables/Collections/Arrays"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
@@ -305,7 +304,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Append a string to a scene array"),
|
||||
_("Appends a string at the end of a scene array variable."),
|
||||
_("Append string _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Variables/Collections/Arrays"),
|
||||
_("Variables/Scene variables/Collections/Arrays"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
@@ -317,7 +316,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Append a number to a scene array"),
|
||||
_("Appends a number at the end of a scene array variable."),
|
||||
_("Append number _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Variables/Collections/Arrays"),
|
||||
_("Variables/Scene variables/Collections/Arrays"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
@@ -329,7 +328,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Append a boolean to a scene array"),
|
||||
_("Appends a boolean at the end of a scene array variable."),
|
||||
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
|
||||
_("Variables/Collections/Arrays"),
|
||||
_("Variables/Scene variables/Collections/Arrays"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Array variable"))
|
||||
@@ -342,7 +341,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
_("Remove variable from a scene array (by index)"),
|
||||
_("Removes a variable at the specified index of a scene array variable."),
|
||||
_("Remove variable at index _PARAM1_ from scene array variable _PARAM0_"),
|
||||
_("Variables/Collections/Arrays"),
|
||||
_("Variables/Scene variables/Collections/Arrays"),
|
||||
"res/actions/var24.png",
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"))
|
||||
@@ -415,7 +414,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddExpression("GlobalVariableChildCount",
|
||||
_("Number of children of a global variable"),
|
||||
_("Number of children of a global variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Global variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"));
|
||||
|
||||
@@ -423,7 +422,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddExpression("VariableChildCount",
|
||||
_("Number of children of a scene variable"),
|
||||
_("Number of children of a scene variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
|
||||
@@ -431,7 +430,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddExpression("Variable",
|
||||
_("Value of a scene variable"),
|
||||
_("Value of a scene variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
|
||||
@@ -439,7 +438,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddStrExpression("VariableString",
|
||||
_("Text of a scene variable"),
|
||||
_("Text of a scene variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Scene variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("scenevar", _("Variable"));
|
||||
|
||||
@@ -447,7 +446,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddExpression("GlobalVariable",
|
||||
_("Value of a global variable"),
|
||||
_("Value of a global variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Global variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Name of the global variable"));
|
||||
|
||||
@@ -455,10 +454,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
|
||||
.AddStrExpression("GlobalVariableString",
|
||||
_("Text of a global variable"),
|
||||
_("Text of a global variable"),
|
||||
_("Variables"),
|
||||
_("Variables/Global variables"),
|
||||
"res/actions/var.png")
|
||||
.AddParameter("globalvar", _("Variable"));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -22,7 +22,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
"Open source (MIT License)")
|
||||
.SetExtensionHelpPath("/all-features/window");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
extension
|
||||
.AddAction(
|
||||
"SetFullScreen",
|
||||
@@ -215,7 +214,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
|
||||
_("Screen"),
|
||||
"res/window.png")
|
||||
.AddCodeOnlyParameter("currentScene", "");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -34,7 +34,7 @@ ExpressionMetadata& ExpressionMetadata::SetHidden() {
|
||||
gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
|
||||
const gd::String& type,
|
||||
const gd::String& description,
|
||||
const gd::String& optionalObjectType,
|
||||
const gd::String& supplementaryInformation,
|
||||
bool parameterIsOptional) {
|
||||
gd::ParameterMetadata info;
|
||||
info.type = type;
|
||||
@@ -46,15 +46,15 @@ gd::ExpressionMetadata& ExpressionMetadata::AddParameter(
|
||||
// parameter is an object/behavior type...
|
||||
(gd::ParameterMetadata::IsObject(type) ||
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
? (optionalObjectType.empty()
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace +
|
||||
optionalObjectType //... so prefix it with the extension
|
||||
supplementaryInformation //... so prefix it with the extension
|
||||
// namespace.
|
||||
)
|
||||
: optionalObjectType; // Otherwise don't change anything
|
||||
: supplementaryInformation; // Otherwise don't change anything
|
||||
|
||||
// TODO: Assert against optionalObjectType === "emsc" (when running with
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
||||
parameters.push_back(info);
|
||||
|
@@ -190,7 +190,7 @@ class GD_CORE_API ExpressionMetadata {
|
||||
gd::ExpressionMetadata& AddParameter(
|
||||
const gd::String& type,
|
||||
const gd::String& description,
|
||||
const gd::String& optionalObjectType = "",
|
||||
const gd::String& supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
|
||||
/**
|
||||
|
@@ -51,7 +51,7 @@ InstructionMetadata::InstructionMetadata(const gd::String& extensionNamespace_,
|
||||
InstructionMetadata& InstructionMetadata::AddParameter(
|
||||
const gd::String& type,
|
||||
const gd::String& description,
|
||||
const gd::String& optionalObjectType,
|
||||
const gd::String& supplementaryInformation,
|
||||
bool parameterIsOptional) {
|
||||
ParameterMetadata info;
|
||||
info.type = type;
|
||||
@@ -63,15 +63,15 @@ InstructionMetadata& InstructionMetadata::AddParameter(
|
||||
// parameter is an object/behavior type...
|
||||
(gd::ParameterMetadata::IsObject(type) ||
|
||||
gd::ParameterMetadata::IsBehavior(type))
|
||||
? (optionalObjectType.empty()
|
||||
? (supplementaryInformation.empty()
|
||||
? ""
|
||||
: extensionNamespace +
|
||||
optionalObjectType //... so prefix it with the extension
|
||||
supplementaryInformation //... so prefix it with the extension
|
||||
// namespace.
|
||||
)
|
||||
: optionalObjectType; // Otherwise don't change anything
|
||||
: supplementaryInformation; // Otherwise don't change anything
|
||||
|
||||
// TODO: Assert against optionalObjectType === "emsc" (when running with
|
||||
// TODO: Assert against supplementaryInformation === "emsc" (when running with
|
||||
// Emscripten), and warn about a missing argument when calling addParameter.
|
||||
|
||||
parameters.push_back(info);
|
||||
@@ -93,7 +93,7 @@ InstructionMetadata& InstructionMetadata::UseStandardOperatorParameters(
|
||||
const gd::String& type) {
|
||||
SetManipulatedType(type);
|
||||
|
||||
AddParameter("operator", _("Modification's sign"));
|
||||
AddParameter("operator", _("Modification's sign"), type);
|
||||
AddParameter(type == "number" ? "expression" : type, _("Value"));
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
@@ -129,7 +129,7 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
|
||||
const gd::String& type) {
|
||||
SetManipulatedType(type);
|
||||
|
||||
AddParameter("relationalOperator", _("Sign of the test"));
|
||||
AddParameter("relationalOperator", _("Sign of the test"), type);
|
||||
AddParameter(type == "number" ? "expression" : type, _("Value to compare"));
|
||||
size_t operatorParamIndex = parameters.size() - 2;
|
||||
size_t valueParamIndex = parameters.size() - 1;
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#ifndef INSTRUCTIONMETADATA_H
|
||||
#define INSTRUCTIONMETADATA_H
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -137,8 +136,11 @@ class GD_CORE_API InstructionMetadata {
|
||||
* will also determine the type of the argument used when calling the function
|
||||
* in the generated code.
|
||||
* \param description Description for parameter
|
||||
* \param optionalObjectType If type is "object", this parameter will describe
|
||||
* which objects are allowed. If it is empty, all objects are allowed.
|
||||
* \param supplementaryInformation Additional information that can be used for
|
||||
* rendering or logic. For example:
|
||||
* - If type is "object", this argument will describe which objects are allowed.
|
||||
* If this argument is empty, all objects are allowed.
|
||||
* - If type is "operator", this argument will be used to display only pertinent operators.
|
||||
* \param parameterIsOptional true if the parameter must be optional, false
|
||||
* otherwise.
|
||||
*
|
||||
@@ -146,7 +148,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
*/
|
||||
InstructionMetadata &AddParameter(const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &optionalObjectType = "",
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false);
|
||||
|
||||
/**
|
||||
@@ -319,7 +321,7 @@ class GD_CORE_API InstructionMetadata {
|
||||
* "CppPlatform/Extensions/text.png");
|
||||
*
|
||||
* .AddParameter("object", _("Object"), "Text", false)
|
||||
* .AddParameter("operator", _("Modification operator"))
|
||||
* .AddParameter("operator", _("Modification operator"), "string")
|
||||
* .AddParameter("string", _("String"))
|
||||
* .SetFunctionName("SetString").SetManipulatedType("string").SetGetter("GetString").SetIncludeFile("MyExtension/TextObject.h");
|
||||
*
|
||||
@@ -452,5 +454,4 @@ class GD_CORE_API InstructionMetadata {
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
#endif // INSTRUCTIONMETADATA_H
|
||||
|
@@ -38,19 +38,17 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
MultipleInstructionMetadata &AddParameter(
|
||||
const gd::String &type,
|
||||
const gd::String &label,
|
||||
const gd::String &optionalObjectType = "",
|
||||
const gd::String &supplementaryInformation = "",
|
||||
bool parameterIsOptional = false) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression)
|
||||
expression->AddParameter(
|
||||
type, label, optionalObjectType, parameterIsOptional);
|
||||
type, label, supplementaryInformation, parameterIsOptional);
|
||||
if (condition)
|
||||
condition->AddParameter(
|
||||
type, label, optionalObjectType, parameterIsOptional);
|
||||
type, label, supplementaryInformation, parameterIsOptional);
|
||||
if (action)
|
||||
action->AddParameter(
|
||||
type, label, optionalObjectType, parameterIsOptional);
|
||||
#endif
|
||||
type, label, supplementaryInformation, parameterIsOptional);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -59,13 +57,11 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
*/
|
||||
MultipleInstructionMetadata &AddCodeOnlyParameter(
|
||||
const gd::String &type, const gd::String &supplementaryInformation) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression)
|
||||
expression->AddCodeOnlyParameter(type, supplementaryInformation);
|
||||
if (condition)
|
||||
condition->AddCodeOnlyParameter(type, supplementaryInformation);
|
||||
if (action) action->AddCodeOnlyParameter(type, supplementaryInformation);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -73,11 +69,9 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetDefaultValue
|
||||
*/
|
||||
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression) expression->SetDefaultValue(defaultValue);
|
||||
if (condition) condition->SetDefaultValue(defaultValue);
|
||||
if (action) action->SetDefaultValue(defaultValue);
|
||||
#endif
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -86,11 +80,9 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
*/
|
||||
MultipleInstructionMetadata &SetParameterLongDescription(
|
||||
const gd::String &longDescription) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression) expression->SetParameterLongDescription(longDescription);
|
||||
if (condition) condition->SetParameterLongDescription(longDescription);
|
||||
if (action) action->SetParameterLongDescription(longDescription);
|
||||
#endif
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -98,11 +90,9 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::SetHidden
|
||||
*/
|
||||
MultipleInstructionMetadata &SetHidden() {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression) expression->SetHidden();
|
||||
if (condition) condition->SetHidden();
|
||||
if (action) action->SetHidden();
|
||||
#endif
|
||||
return *this;
|
||||
};
|
||||
|
||||
@@ -111,50 +101,40 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::UseStandardRelationalOperatorParameters
|
||||
*/
|
||||
MultipleInstructionMetadata &UseStandardParameters(const gd::String &type) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (condition) condition->UseStandardRelationalOperatorParameters(type);
|
||||
if (action) action->UseStandardOperatorParameters(type);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression) expression->SetFunctionName(functionName);
|
||||
if (condition) condition->SetFunctionName(functionName);
|
||||
if (action) action->GetCodeExtraInformation().SetFunctionName(functionName);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetGetter(const gd::String &getter) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression) expression->SetFunctionName(getter);
|
||||
if (condition) condition->SetFunctionName(getter);
|
||||
if (action) action->GetCodeExtraInformation().SetGetter(getter);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().SetIncludeFile(includeFile);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (expression)
|
||||
expression->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (condition)
|
||||
condition->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
if (action) action->GetCodeExtraInformation().AddIncludeFile(includeFile);
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -162,10 +142,8 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::MarkAsSimple
|
||||
*/
|
||||
MultipleInstructionMetadata &MarkAsSimple() {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (condition) condition->MarkAsSimple();
|
||||
if (action) action->MarkAsSimple();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -173,10 +151,8 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::MarkAsAdvanced
|
||||
*/
|
||||
MultipleInstructionMetadata &MarkAsAdvanced() {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (condition) condition->MarkAsAdvanced();
|
||||
if (action) action->MarkAsAdvanced();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -184,10 +160,8 @@ class GD_CORE_API MultipleInstructionMetadata {
|
||||
* \see gd::InstructionMetadata::MarkAsComplex
|
||||
*/
|
||||
MultipleInstructionMetadata &MarkAsComplex() {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
if (condition) condition->MarkAsComplex();
|
||||
if (action) action->MarkAsComplex();
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@@ -302,6 +302,38 @@ ObjectMetadata::AddExpressionAndConditionAndAction(
|
||||
expression, condition, action);
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& ObjectMetadata::AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newActionName;
|
||||
gd::String copiedNameWithNamespace = extensionNamespace + copiedActionName;
|
||||
|
||||
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedAction == actionsInfos.end()) {
|
||||
gd::LogWarning("Could not find an action with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
actionsInfos[newNameWithNamespace] = copiedAction->second;
|
||||
}
|
||||
|
||||
return actionsInfos[newNameWithNamespace];
|
||||
}
|
||||
|
||||
gd::InstructionMetadata& ObjectMetadata::AddDuplicatedCondition(
|
||||
const gd::String& newConditionName, const gd::String& copiedConditionName) {
|
||||
gd::String newNameWithNamespace = extensionNamespace + newConditionName;
|
||||
gd::String copiedNameWithNamespace = extensionNamespace + copiedConditionName;
|
||||
|
||||
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
|
||||
if (copiedCondition == conditionsInfos.end()) {
|
||||
gd::LogWarning("Could not find a condition with name " +
|
||||
copiedNameWithNamespace + " to copy.");
|
||||
} else {
|
||||
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
|
||||
}
|
||||
|
||||
return conditionsInfos[newNameWithNamespace];
|
||||
}
|
||||
|
||||
ObjectMetadata& ObjectMetadata::SetFullName(const gd::String& fullname_) {
|
||||
#if defined(GD_IDE_ONLY)
|
||||
fullname = fullname_;
|
||||
|
@@ -153,6 +153,25 @@ class GD_CORE_API ObjectMetadata {
|
||||
const gd::String& group,
|
||||
const gd::String& icon);
|
||||
|
||||
/**
|
||||
* \brief Create a new action which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated action that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedAction(
|
||||
const gd::String& newActionName, const gd::String& copiedActionName);
|
||||
|
||||
/**
|
||||
* \brief Create a new condition which is the duplicate of the specified one.
|
||||
*
|
||||
* Useful for handling a deprecated condition that is just a "copy" of the new
|
||||
* one.
|
||||
*/
|
||||
gd::InstructionMetadata& AddDuplicatedCondition(
|
||||
const gd::String& newConditionName,
|
||||
const gd::String& copiedConditionName);
|
||||
|
||||
/**
|
||||
* \brief Set the name shown to the user.
|
||||
*/
|
||||
|
@@ -189,8 +189,13 @@ class GD_CORE_API ParameterMetadata {
|
||||
parameterType == "joyaxis" ||
|
||||
parameterType == "stringWithSelector" ||
|
||||
parameterType == "sceneName" ||
|
||||
parameterType == "layerEffectName" ||
|
||||
parameterType == "layerEffectParameterName" ||
|
||||
parameterType == "objectEffectName" ||
|
||||
parameterType == "objectEffectParameterName" ||
|
||||
parameterType == "objectPointName" ||
|
||||
parameterType == "objectAnimationName";
|
||||
parameterType == "objectAnimationName" ||
|
||||
parameterType == "functionParameterName";
|
||||
} else if (type == "variable") {
|
||||
return parameterType == "objectvar" || parameterType == "globalvar" ||
|
||||
parameterType == "scenevar";
|
||||
|
@@ -529,24 +529,6 @@ class GD_CORE_API PlatformExtension {
|
||||
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressionsForBehavior(
|
||||
gd::String autoType);
|
||||
|
||||
/**
|
||||
* Called to inventory resources used by conditions
|
||||
* (and possibly do work on them, like renaming, etc...)
|
||||
*
|
||||
* \see gd::PlatformExtension::ExposeActionsResources
|
||||
*/
|
||||
virtual void ExposeConditionsResources(Instruction& condition,
|
||||
gd::ArbitraryResourceWorker& worker){};
|
||||
|
||||
/**
|
||||
* Called to inventory resources used by actions
|
||||
* (and possibly do work on them, like renaming, etc...)
|
||||
*
|
||||
* \see ArbitraryResourceWorker
|
||||
*/
|
||||
virtual void ExposeActionsResources(Instruction& action,
|
||||
gd::ArbitraryResourceWorker& worker){};
|
||||
|
||||
/**
|
||||
* \brief Get all the properties of the extension. Properties
|
||||
* are shown in the game properties in the editor, and are exported in the
|
||||
|
@@ -19,4 +19,34 @@ class GD_CORE_API EventsListUnfolder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FoldAll(gd::EventsList& list) {
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
gd::BaseEvent& event = list[i];
|
||||
event.SetFolded(true);
|
||||
if (event.CanHaveSubEvents() && event.GetSubEvents().size() > 0) {
|
||||
FoldAll(event.GetSubEvents());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Recursively unfold all the events until a certain level of depth.
|
||||
* 0 is the top level. If you want to unfold all events regardless of its depth,
|
||||
* use `maxLevel = -1`. `currentLevel` is used for the recursion.
|
||||
*/
|
||||
static void UnfoldToLevel(gd::EventsList& list,
|
||||
const int8_t maxLevel,
|
||||
const std::size_t currentLevel = 0) {
|
||||
if (maxLevel >= 0 && currentLevel > maxLevel) return;
|
||||
|
||||
for (size_t i = 0; i < list.size(); ++i) {
|
||||
gd::BaseEvent& event = list[i];
|
||||
event.SetFolded(false);
|
||||
if (event.CanHaveSubEvents() && event.GetSubEvents().size() > 0 &&
|
||||
(maxLevel == -1 || currentLevel <= maxLevel)) {
|
||||
UnfoldToLevel(event.GetSubEvents(), maxLevel, currentLevel + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@@ -19,11 +19,14 @@
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/Events/ExpressionValidator.h"
|
||||
#include "GDCore/Project/ObjectsContainer.h"
|
||||
#include "GDCore/IDE/Events/InstructionSentenceFormatter.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
const gd::String EventsRefactorer::searchIgnoredCharacters = ";:,#()";
|
||||
|
||||
/**
|
||||
* \brief Go through the nodes and change the given object name to a new one.
|
||||
*
|
||||
@@ -675,16 +678,27 @@ bool EventsRefactorer::ReplaceStringInConditions(
|
||||
}
|
||||
|
||||
vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
const gd::Platform& platform,
|
||||
gd::EventsList& events,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool inConditions,
|
||||
bool inActions,
|
||||
bool inEventStrings) {
|
||||
bool inEventStrings,
|
||||
bool inEventSentences) {
|
||||
vector<EventsSearchResult> results;
|
||||
|
||||
const gd::String& ignored_characters = EventsRefactorer::searchIgnoredCharacters;
|
||||
|
||||
search.replace_if(search.begin(),
|
||||
search.end(),
|
||||
[ignored_characters](const char &c) {
|
||||
return ignored_characters.find(c) != gd::String::npos;
|
||||
},
|
||||
"");
|
||||
search = search.LeftTrim().RightTrim();
|
||||
search.RemoveConsecutiveOccurrences(search.begin(), search.end(), ' ');
|
||||
|
||||
for (std::size_t i = 0; i < events.size(); ++i) {
|
||||
bool eventAddedInResults = false;
|
||||
|
||||
@@ -694,7 +708,7 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
for (std::size_t j = 0; j < conditionsVectors.size(); ++j) {
|
||||
if (!eventAddedInResults &&
|
||||
SearchStringInConditions(
|
||||
project, layout, *conditionsVectors[j], search, matchCase)) {
|
||||
platform, *conditionsVectors[j], search, matchCase, inEventSentences)) {
|
||||
results.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
@@ -709,7 +723,7 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
for (std::size_t j = 0; j < actionsVectors.size(); ++j) {
|
||||
if (!eventAddedInResults &&
|
||||
SearchStringInActions(
|
||||
project, layout, *actionsVectors[j], search, matchCase)) {
|
||||
platform, *actionsVectors[j], search, matchCase, inEventSentences)) {
|
||||
results.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
@@ -720,7 +734,7 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
|
||||
if (inEventStrings) {
|
||||
if (!eventAddedInResults &&
|
||||
SearchStringInEvent(project, layout, events[i], search, matchCase)) {
|
||||
SearchStringInEvent(events[i], search, matchCase)) {
|
||||
results.push_back(EventsSearchResult(
|
||||
std::weak_ptr<gd::BaseEvent>(events.GetEventSmartPtr(i)),
|
||||
&events,
|
||||
@@ -730,14 +744,14 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
|
||||
if (events[i].CanHaveSubEvents()) {
|
||||
vector<EventsSearchResult> subResults =
|
||||
SearchInEvents(project,
|
||||
layout,
|
||||
SearchInEvents(platform,
|
||||
events[i].GetSubEvents(),
|
||||
search,
|
||||
matchCase,
|
||||
inConditions,
|
||||
inActions,
|
||||
inEventStrings);
|
||||
inEventStrings,
|
||||
inEventSentences);
|
||||
std::copy(
|
||||
subResults.begin(), subResults.end(), std::back_inserter(results));
|
||||
}
|
||||
@@ -746,11 +760,12 @@ vector<EventsSearchResult> EventsRefactorer::SearchInEvents(
|
||||
return results;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
bool EventsRefactorer::SearchStringInActions(
|
||||
const gd::Platform& platform,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool inSentences) {
|
||||
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
|
||||
for (std::size_t pNb = 0; pNb < actions[aId].GetParameters().size();
|
||||
++pNb) {
|
||||
@@ -765,24 +780,60 @@ bool EventsRefactorer::SearchStringInActions(gd::ObjectsContainer& project,
|
||||
if (foundPosition != gd::String::npos) return true;
|
||||
}
|
||||
|
||||
if (inSentences && SearchStringInFormattedText(
|
||||
platform, actions[aId], search, matchCase, false))
|
||||
return true;
|
||||
|
||||
if (!actions[aId].GetSubInstructions().empty() &&
|
||||
SearchStringInActions(project,
|
||||
layout,
|
||||
SearchStringInActions(platform,
|
||||
actions[aId].GetSubInstructions(),
|
||||
search,
|
||||
matchCase))
|
||||
matchCase,
|
||||
inSentences))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInFormattedText(
|
||||
const gd::Platform& platform,
|
||||
gd::Instruction& instruction,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool isCondition) {
|
||||
const auto& metadata = isCondition
|
||||
? gd::MetadataProvider::GetConditionMetadata(
|
||||
platform, instruction.GetType())
|
||||
: gd::MetadataProvider::GetActionMetadata(
|
||||
platform, instruction.GetType());
|
||||
gd::String completeSentence = gd::InstructionSentenceFormatter::Get()->GetFullText(instruction, metadata);
|
||||
|
||||
const gd::String& ignored_characters = EventsRefactorer::searchIgnoredCharacters;
|
||||
|
||||
completeSentence.replace_if(completeSentence.begin(),
|
||||
completeSentence.end(),
|
||||
[ignored_characters](const char &c) {
|
||||
return ignored_characters.find(c) != gd::String::npos;
|
||||
},
|
||||
"");
|
||||
|
||||
completeSentence.RemoveConsecutiveOccurrences(
|
||||
completeSentence.begin(), completeSentence.end(), ' ');
|
||||
|
||||
size_t foundPosition = matchCase
|
||||
? completeSentence.find(search)
|
||||
: completeSentence.FindCaseInsensitive(search);
|
||||
|
||||
return foundPosition != gd::String::npos;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInConditions(
|
||||
gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
const gd::Platform& platform,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
bool matchCase,
|
||||
bool inSentences) {
|
||||
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
|
||||
for (std::size_t pNb = 0; pNb < conditions[cId].GetParameters().size();
|
||||
++pNb) {
|
||||
@@ -797,21 +848,23 @@ bool EventsRefactorer::SearchStringInConditions(
|
||||
if (foundPosition != gd::String::npos) return true;
|
||||
}
|
||||
|
||||
if (inSentences && SearchStringInFormattedText(
|
||||
platform, conditions[cId], search, matchCase, true))
|
||||
return true;
|
||||
|
||||
if (!conditions[cId].GetSubInstructions().empty() &&
|
||||
SearchStringInConditions(project,
|
||||
layout,
|
||||
SearchStringInConditions(platform,
|
||||
conditions[cId].GetSubInstructions(),
|
||||
search,
|
||||
matchCase))
|
||||
matchCase,
|
||||
inSentences))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventsRefactorer::SearchStringInEvent(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::BaseEvent& event,
|
||||
bool EventsRefactorer::SearchStringInEvent(gd::BaseEvent& event,
|
||||
gd::String search,
|
||||
bool matchCase) {
|
||||
for (gd::String str : event.GetAllSearchableStrings()) {
|
||||
|
@@ -41,7 +41,7 @@ class GD_CORE_API EventsSearchResult {
|
||||
std::size_t positionInList;
|
||||
|
||||
bool IsEventsListValid() const { return eventsList != nullptr; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the events list containing the event pointed by the EventsSearchResult.
|
||||
* \warning Only call this when IsEventsListValid returns true.
|
||||
@@ -49,7 +49,7 @@ class GD_CORE_API EventsSearchResult {
|
||||
const gd::EventsList & GetEventsList() const { return *eventsList; }
|
||||
|
||||
std::size_t GetPositionInList() const { return positionInList; }
|
||||
|
||||
|
||||
bool IsEventValid() const { return !event.expired(); }
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ class GD_CORE_API EventsSearchResult {
|
||||
class GD_CORE_API EventsRefactorer {
|
||||
public:
|
||||
/**
|
||||
* Replace all occurences of an object name by another name
|
||||
* Replace all occurrences of an object name by another name
|
||||
* ( include : objects in parameters and in math/text expressions of all
|
||||
* events ).
|
||||
*/
|
||||
@@ -98,14 +98,14 @@ class GD_CORE_API EventsRefactorer {
|
||||
* \return A vector containing EventsSearchResult objects filled with events
|
||||
* containing the string
|
||||
*/
|
||||
static std::vector<EventsSearchResult> SearchInEvents(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
static std::vector<EventsSearchResult> SearchInEvents(const gd::Platform& platform,
|
||||
gd::EventsList& events,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool inConditions,
|
||||
bool inActions,
|
||||
bool inEventStrings);
|
||||
bool inEventStrings,
|
||||
bool inEventSentences);
|
||||
|
||||
/**
|
||||
* Replace all occurrences of a gd::String in events
|
||||
@@ -123,7 +123,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
|
||||
private:
|
||||
/**
|
||||
* Replace all occurences of an object name by another name in an action
|
||||
* Replace all occurrences of an object name by another name in an action
|
||||
* ( include : objects in parameters and in math/text expressions ).
|
||||
*
|
||||
* \return true if something was modified.
|
||||
@@ -136,7 +136,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
gd::String newName);
|
||||
|
||||
/**
|
||||
* Replace all occurences of an object name by another name in a condition
|
||||
* Replace all occurrences of an object name by another name in a condition
|
||||
* ( include : objects in parameters and in math/text expressions ).
|
||||
*
|
||||
* \return true if something was modified.
|
||||
@@ -185,7 +185,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
gd::String name);
|
||||
|
||||
/**
|
||||
* Replace all occurences of a gd::String in conditions
|
||||
* Replace all occurrences of a gd::String in conditions
|
||||
*
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
@@ -197,7 +197,7 @@ class GD_CORE_API EventsRefactorer {
|
||||
bool matchCase);
|
||||
|
||||
/**
|
||||
* Replace all occurences of a gd::String in actions
|
||||
* Replace all occurrences of a gd::String in actions
|
||||
*
|
||||
* \return true if something was modified.
|
||||
*/
|
||||
@@ -208,21 +208,26 @@ class GD_CORE_API EventsRefactorer {
|
||||
gd::String newString,
|
||||
bool matchCase);
|
||||
|
||||
static bool SearchStringInActions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
static bool SearchStringInFormattedText(const gd::Platform& platform,
|
||||
gd::Instruction& instruction,
|
||||
gd::String search,
|
||||
bool matchCase,
|
||||
bool isCondition);
|
||||
static bool SearchStringInActions(const gd::Platform& platform,
|
||||
gd::InstructionsList& actions,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
static bool SearchStringInConditions(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
bool matchCase,
|
||||
bool inSentences);
|
||||
static bool SearchStringInConditions(const gd::Platform& platform,
|
||||
gd::InstructionsList& conditions,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
static bool SearchStringInEvent(gd::ObjectsContainer& project,
|
||||
gd::ObjectsContainer& layout,
|
||||
gd::BaseEvent& events,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
bool matchCase,
|
||||
bool inSentences);
|
||||
static bool SearchStringInEvent(gd::BaseEvent& events,
|
||||
gd::String search,
|
||||
bool matchCase);
|
||||
|
||||
static const gd::String searchIgnoredCharacters;
|
||||
|
||||
EventsRefactorer(){};
|
||||
};
|
||||
|
@@ -9,12 +9,12 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
|
||||
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/IDE/Events/ExpressionNodeLocationFinder.h"
|
||||
#include "GDCore/Events/Parsers/ExpressionParser2.h"
|
||||
|
||||
namespace gd {
|
||||
class Expression;
|
||||
@@ -32,7 +32,7 @@ namespace gd {
|
||||
* The IDE is responsible for actually *searching* and showing the completions -
|
||||
* this is only describing what must be listed.
|
||||
*/
|
||||
struct ExpressionCompletionDescription {
|
||||
struct GD_CORE_API ExpressionCompletionDescription {
|
||||
public:
|
||||
/**
|
||||
* The different kind of completions that can be described.
|
||||
@@ -274,7 +274,7 @@ struct ExpressionCompletionDescription {
|
||||
/**
|
||||
* \brief Turn an ExpressionCompletionDescription to a string.
|
||||
*/
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
GD_CORE_API std::ostream& operator<<(std::ostream& os,
|
||||
ExpressionCompletionDescription const& value);
|
||||
|
||||
/**
|
||||
@@ -326,10 +326,7 @@ class GD_CORE_API ExpressionCompletionFinder
|
||||
node.type, "", searchedPosition + 1, searchedPosition + 1));
|
||||
}
|
||||
void OnVisitOperatorNode(OperatorNode& node) override {
|
||||
completions.push_back(ExpressionCompletionDescription::ForObject(
|
||||
node.type, "", searchedPosition + 1, searchedPosition + 1));
|
||||
completions.push_back(ExpressionCompletionDescription::ForExpression(
|
||||
node.type, "", searchedPosition + 1, searchedPosition + 1));
|
||||
// No completions.
|
||||
}
|
||||
void OnVisitUnaryOperatorNode(UnaryOperatorNode& node) override {
|
||||
completions.push_back(ExpressionCompletionDescription::ForObject(
|
||||
@@ -359,8 +356,9 @@ class GD_CORE_API ExpressionCompletionFinder
|
||||
}
|
||||
// Search the parameter metadata index skipping invisible ones.
|
||||
size_t visibleParameterIndex = 0;
|
||||
size_t metadataParameterIndex = ExpressionParser2::WrittenParametersFirstIndex(
|
||||
functionCall->objectName, functionCall->behaviorName);
|
||||
size_t metadataParameterIndex =
|
||||
ExpressionParser2::WrittenParametersFirstIndex(
|
||||
functionCall->objectName, functionCall->behaviorName);
|
||||
|
||||
const gd::ParameterMetadata* parameterMetadata = nullptr;
|
||||
while (metadataParameterIndex <
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/Events/InstructionSentenceFormatter.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -90,6 +89,19 @@ InstructionSentenceFormatter::GetAsFormattedText(
|
||||
return formattedStr;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
gd::String InstructionSentenceFormatter::GetFullText(
|
||||
const gd::Instruction &instr, const gd::InstructionMetadata &metadata)
|
||||
{
|
||||
const std::vector<std::pair<gd::String, gd::TextFormatting> > formattedText =
|
||||
GetAsFormattedText(instr, metadata);
|
||||
|
||||
#endif
|
||||
gd::String completeSentence = "";
|
||||
|
||||
for (std::size_t id = 0; id < formattedText.size(); ++id) {
|
||||
completeSentence += formattedText.at(id).first;
|
||||
}
|
||||
|
||||
return completeSentence;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -4,7 +4,6 @@
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef TRANSLATEACTION_H
|
||||
#define TRANSLATEACTION_H
|
||||
#include <map>
|
||||
@@ -39,6 +38,9 @@ class GD_CORE_API InstructionSentenceFormatter {
|
||||
return (static_cast<InstructionSentenceFormatter *>(_singleton));
|
||||
}
|
||||
|
||||
gd::String GetFullText(const gd::Instruction &instr,
|
||||
const gd::InstructionMetadata &metadata);
|
||||
|
||||
static void DestroySingleton() {
|
||||
if (NULL != _singleton) {
|
||||
delete _singleton;
|
||||
@@ -55,4 +57,3 @@ class GD_CORE_API InstructionSentenceFormatter {
|
||||
|
||||
} // namespace gd
|
||||
#endif // TRANSLATEACTION_H
|
||||
#endif
|
||||
|
@@ -19,12 +19,15 @@ bool InstructionsParameterMover::DoVisitInstruction(
|
||||
gd::Instruction& instruction, bool isCondition) {
|
||||
if (instruction.GetType() == instructionType) {
|
||||
std::vector<gd::Expression> updatedParameters = instruction.GetParameters();
|
||||
if (oldIndex < updatedParameters.size() ||
|
||||
newIndex < updatedParameters.size()) {
|
||||
gd::Expression movedParameter = updatedParameters[oldIndex];
|
||||
if (oldIndex < updatedParameters.size()) {
|
||||
gd::Expression movedParameter = updatedParameters.at(oldIndex);
|
||||
updatedParameters.erase(updatedParameters.begin() + oldIndex);
|
||||
updatedParameters.insert(updatedParameters.begin() + newIndex,
|
||||
movedParameter);
|
||||
if (newIndex < updatedParameters.size()) {
|
||||
updatedParameters.insert(updatedParameters.begin() + newIndex,
|
||||
movedParameter);
|
||||
} else {
|
||||
updatedParameters.push_back(movedParameter);
|
||||
}
|
||||
instruction.SetParameters(updatedParameters);
|
||||
}
|
||||
}
|
||||
|
@@ -13,8 +13,11 @@
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
|
||||
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
|
||||
#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"
|
||||
|
||||
@@ -23,8 +26,23 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
void ArbitraryResourceWorker::ExposeImage(gd::String& imageName){
|
||||
// Nothing to do, the image is a reference to a resource that
|
||||
// is already exposed.
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeJson(gd::String& jsonName){
|
||||
// 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.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeBitmapFont(gd::String& bitmapFontName){
|
||||
// Nothing to do by default - each child class can define here the action to
|
||||
// do.
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
|
||||
@@ -33,12 +51,14 @@ void ArbitraryResourceWorker::ExposeAudio(gd::String& audioName) {
|
||||
|
||||
if (resources->HasResource(audioName) &&
|
||||
resources->GetResource(audioName).GetKind() == "audio") {
|
||||
// Nothing to do, the audio is a reference to a resource that
|
||||
// is already exposed.
|
||||
// Nothing to do, the audio is a reference to a proper resource.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// For compatibility with older projects (where events were refering to files
|
||||
// directly), we consider that this resource name is a filename, and so expose
|
||||
// it as a file.
|
||||
ExposeFile(audioName);
|
||||
};
|
||||
|
||||
@@ -48,30 +68,17 @@ void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
|
||||
|
||||
if (resources->HasResource(fontName) &&
|
||||
resources->GetResource(fontName).GetKind() == "font") {
|
||||
// Nothing to do, the font is a reference to a resource that
|
||||
// is already exposed.
|
||||
// Nothing to do, the font is a reference to a proper resource.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// For compatibility with older projects (where events were refering to files
|
||||
// directly), we consider that this resource name is a filename, and so expose
|
||||
// it as a file.
|
||||
ExposeFile(fontName);
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeBitmapFont(gd::String& bitmapFontName) {
|
||||
for (auto resources : GetResources()) {
|
||||
if (!resources) continue;
|
||||
|
||||
if (resources->HasResource(bitmapFontName) &&
|
||||
resources->GetResource(bitmapFontName).GetKind() == "bitmapFont") {
|
||||
// Nothing to do, the font is a reference to a resource that
|
||||
// is already exposed.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ExposeFile(bitmapFontName);
|
||||
};
|
||||
|
||||
void ArbitraryResourceWorker::ExposeResources(
|
||||
gd::ResourcesManager* resourcesManager) {
|
||||
if (!resourcesManager) return;
|
||||
@@ -95,101 +102,67 @@ 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() {};
|
||||
|
||||
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::String& parameterValue,
|
||||
size_t parameterIndex,
|
||||
const gd::String& lastObjectName) {
|
||||
if (parameterMetadata.GetType() ==
|
||||
"police") { // Should be renamed 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);
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const gd::Project& project;
|
||||
gd::ArbitraryResourceWorker& worker;
|
||||
};
|
||||
|
||||
void LaunchResourceWorkerOnEvents(const gd::Project& project,
|
||||
gd::EventsList& events,
|
||||
gd::ArbitraryResourceWorker& worker) {
|
||||
// Get all extensions used
|
||||
auto allGameExtensions =
|
||||
project.GetCurrentPlatform().GetAllPlatformExtensions();
|
||||
|
||||
for (std::size_t j = 0; j < events.size(); j++) {
|
||||
vector<gd::InstructionsList*> allActionsVectors =
|
||||
events[j].GetAllActionsVectors();
|
||||
for (std::size_t i = 0; i < allActionsVectors.size(); ++i) {
|
||||
for (std::size_t k = 0; k < allActionsVectors[i]->size(); k++) {
|
||||
gd::String type = allActionsVectors[i]->Get(k).GetType();
|
||||
for (std::size_t e = 0; e < allGameExtensions.size(); ++e) {
|
||||
bool extensionHasAction = false;
|
||||
|
||||
const std::map<gd::String, gd::InstructionMetadata>& allActions =
|
||||
allGameExtensions[e]->GetAllActions();
|
||||
if (allActions.find(type) != allActions.end())
|
||||
extensionHasAction = true;
|
||||
|
||||
const vector<gd::String>& objects =
|
||||
allGameExtensions[e]->GetExtensionObjectsTypes();
|
||||
for (std::size_t o = 0; o < objects.size(); ++o) {
|
||||
const std::map<gd::String, gd::InstructionMetadata>&
|
||||
allObjectsActions =
|
||||
allGameExtensions[e]->GetAllActionsForObject(objects[o]);
|
||||
if (allObjectsActions.find(type) != allObjectsActions.end())
|
||||
extensionHasAction = true;
|
||||
}
|
||||
|
||||
const vector<gd::String>& autos =
|
||||
allGameExtensions[e]->GetBehaviorsTypes();
|
||||
for (std::size_t a = 0; a < autos.size(); ++a) {
|
||||
const std::map<gd::String, gd::InstructionMetadata>&
|
||||
allAutosActions =
|
||||
allGameExtensions[e]->GetAllActionsForBehavior(autos[a]);
|
||||
if (allAutosActions.find(type) != allAutosActions.end())
|
||||
extensionHasAction = true;
|
||||
}
|
||||
|
||||
if (extensionHasAction) {
|
||||
allGameExtensions[e]->ExposeActionsResources(
|
||||
allActionsVectors[i]->Get(k), worker);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<gd::InstructionsList*> allConditionsVector =
|
||||
events[j].GetAllConditionsVectors();
|
||||
for (std::size_t i = 0; i < allConditionsVector.size(); ++i) {
|
||||
for (std::size_t k = 0; k < allConditionsVector[i]->size(); k++) {
|
||||
gd::String type = allConditionsVector[i]->Get(k).GetType();
|
||||
for (std::size_t e = 0; e < allGameExtensions.size(); ++e) {
|
||||
bool extensionHasCondition = false;
|
||||
|
||||
const std::map<gd::String, gd::InstructionMetadata>& allConditions =
|
||||
allGameExtensions[e]->GetAllConditions();
|
||||
if (allConditions.find(type) != allConditions.end())
|
||||
extensionHasCondition = true;
|
||||
|
||||
const vector<gd::String>& objects =
|
||||
allGameExtensions[e]->GetExtensionObjectsTypes();
|
||||
for (std::size_t j = 0; j < objects.size(); ++j) {
|
||||
const std::map<gd::String, gd::InstructionMetadata>&
|
||||
allObjectsConditions =
|
||||
allGameExtensions[e]->GetAllConditionsForObject(objects[j]);
|
||||
if (allObjectsConditions.find(type) != allObjectsConditions.end())
|
||||
extensionHasCondition = true;
|
||||
}
|
||||
|
||||
const vector<gd::String>& autos =
|
||||
allGameExtensions[e]->GetBehaviorsTypes();
|
||||
for (std::size_t j = 0; j < autos.size(); ++j) {
|
||||
const std::map<gd::String, gd::InstructionMetadata>&
|
||||
allAutosConditions =
|
||||
allGameExtensions[e]->GetAllConditionsForBehavior(autos[j]);
|
||||
if (allAutosConditions.find(type) != allAutosConditions.end())
|
||||
extensionHasCondition = true;
|
||||
}
|
||||
|
||||
if (extensionHasCondition)
|
||||
allGameExtensions[e]->ExposeConditionsResources(
|
||||
allConditionsVector[i]->Get(k), worker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events[j].CanHaveSubEvents())
|
||||
LaunchResourceWorkerOnEvents(project, events[j].GetSubEvents(), worker);
|
||||
}
|
||||
|
||||
return;
|
||||
ResourceWorkerInEventsWorker eventsWorker(project, worker);
|
||||
eventsWorker.Launch(events);
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -60,19 +60,28 @@ class GD_CORE_API ArbitraryResourceWorker {
|
||||
|
||||
/**
|
||||
* \brief Expose an audio, which is either a reference to an "audio" resource,
|
||||
* or a filename if no resource with this name exists.
|
||||
* or a filename if no resource with this name exists (for backward compatibility).
|
||||
*/
|
||||
virtual void ExposeAudio(gd::String &audioName);
|
||||
|
||||
/**
|
||||
* \brief Expose a font, which is either a reference to a "font" resource,
|
||||
* or a filename if no resource with this name exists.
|
||||
* or a filename if no resource with this name exists (for backward compatibility).
|
||||
*/
|
||||
virtual void ExposeFont(gd::String &fontName);
|
||||
|
||||
/**
|
||||
* \brief Expose a bitmap font, which is either a reference to a "bitmapFont" resource,
|
||||
* or a filename if no resource with this name exists.
|
||||
* \brief Expose a JSON, which is always a reference to a "json" resource.
|
||||
*/
|
||||
virtual void ExposeJson(gd::String &jsonName);
|
||||
|
||||
/**
|
||||
* \brief Expose a video, which is always a reference to a "video" resource.
|
||||
*/
|
||||
virtual void ExposeVideo(gd::String &videoName);
|
||||
|
||||
/**
|
||||
* \brief Expose a bitmap font, which is always a reference to a "bitmapFont" resource.
|
||||
*/
|
||||
virtual void ExposeBitmapFont(gd::String &bitmapFontName);
|
||||
|
||||
|
@@ -14,25 +14,6 @@ using namespace std;
|
||||
|
||||
namespace gd {
|
||||
|
||||
bool ProjectResourcesAdder::AddAllMissing(gd::Project& project,
|
||||
const gd::String& resourceType) {
|
||||
// Search for resources used in the project
|
||||
gd::ResourcesInUseHelper resourcesInUse;
|
||||
project.ExposeResources(resourcesInUse);
|
||||
|
||||
ResourcesManager& resourcesManager = project.GetResourcesManager();
|
||||
for (auto& resourceName : resourcesInUse.GetAll(resourceType)) {
|
||||
if (!resourcesManager.HasResource(resourceName)) {
|
||||
std::cout << "Adding missing resource \"" << resourceName
|
||||
<< "\"to the project." << std::endl;
|
||||
resourcesManager.AddResource(
|
||||
resourceName, /*filename=*/resourceName, resourceType);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
|
||||
gd::Project& project, const gd::String& resourceType) {
|
||||
std::vector<gd::String> unusedResources;
|
||||
@@ -42,15 +23,13 @@ std::vector<gd::String> ProjectResourcesAdder::GetAllUseless(
|
||||
std::set<gd::String>& usedResources = resourcesInUse.GetAll(resourceType);
|
||||
|
||||
// Search all resources not used
|
||||
std::vector<gd::String> resources =
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
const std::vector<std::shared_ptr<Resource>>& resources =
|
||||
project.GetResourcesManager().GetAllResources();
|
||||
for (std::size_t i = 0; i < resources.size(); i++) {
|
||||
if (project.GetResourcesManager().GetResource(resources[i]).GetKind() !=
|
||||
resourceType)
|
||||
continue;
|
||||
if (resources[i]->GetKind() != resourceType) continue;
|
||||
|
||||
if (usedResources.find(resources[i]) == usedResources.end())
|
||||
unusedResources.push_back(resources[i]);
|
||||
if (usedResources.find(resources[i]->GetName()) == usedResources.end())
|
||||
unusedResources.push_back(resources[i]->GetName());
|
||||
}
|
||||
|
||||
return unusedResources;
|
||||
|
@@ -20,17 +20,6 @@ namespace gd {
|
||||
*/
|
||||
class GD_CORE_API ProjectResourcesAdder {
|
||||
public:
|
||||
/**
|
||||
* \brief Update the project so that all missing resources are added, with an
|
||||
* filename that is equal to the missing resource name.
|
||||
*
|
||||
* \param project The project to be updated.
|
||||
* \param resourceType The type of the resource the be searched
|
||||
*
|
||||
* \return true if no error happened
|
||||
*/
|
||||
static bool AddAllMissing(gd::Project& project, const gd::String & resourceType);
|
||||
|
||||
/**
|
||||
* \brief Find all resources of the specified kind that are
|
||||
* not used by the project.
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
@@ -36,17 +37,20 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
virtual ~ResourcesInUseHelper(){};
|
||||
|
||||
std::set<gd::String>& GetAllImages() { return GetAll("image"); };
|
||||
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
|
||||
std::set<gd::String>& GetAllAudios() { return GetAll("audio"); };
|
||||
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
|
||||
std::set<gd::String>& GetAllJsons() { return GetAll("json"); };
|
||||
std::set<gd::String>& GetAllVideos() { return GetAll("video"); };
|
||||
std::set<gd::String>& GetAllBitmapFonts() { return GetAll("bitmapFont"); };
|
||||
std::set<gd::String>& GetAll(const gd::String& resourceType) {
|
||||
return resourceType == "image"
|
||||
? allImages
|
||||
: (resourceType == "audio"
|
||||
? allAudios
|
||||
: (resourceType == "font")
|
||||
? allFonts
|
||||
: (resourceType == "bitmapFont") ? allBitmapFonts : emptyResources);
|
||||
if (resourceType == "image") return allImages;
|
||||
if (resourceType == "audio") return allAudios;
|
||||
if (resourceType == "font") return allFonts;
|
||||
if (resourceType == "json") return allJsons;
|
||||
if (resourceType == "video") return allVideos;
|
||||
if (resourceType == "bitmapFont") return allBitmapFonts;
|
||||
|
||||
return emptyResources;
|
||||
};
|
||||
|
||||
virtual void ExposeFile(gd::String& resource) override{
|
||||
@@ -61,6 +65,12 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeFont(gd::String& fontResourceName) override {
|
||||
allFonts.insert(fontResourceName);
|
||||
};
|
||||
virtual void ExposeJson(gd::String& jsonResourceName) override {
|
||||
allJsons.insert(jsonResourceName);
|
||||
};
|
||||
virtual void ExposeVideo(gd::String& videoResourceName) override {
|
||||
allVideos.insert(videoResourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontResourceName) override {
|
||||
allBitmapFonts.insert(bitmapFontResourceName);
|
||||
};
|
||||
@@ -69,6 +79,8 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
|
||||
std::set<gd::String> allImages;
|
||||
std::set<gd::String> allAudios;
|
||||
std::set<gd::String> allFonts;
|
||||
std::set<gd::String> allJsons;
|
||||
std::set<gd::String> allVideos;
|
||||
std::set<gd::String> allBitmapFonts;
|
||||
std::set<gd::String> emptyResources;
|
||||
};
|
||||
|
@@ -22,7 +22,7 @@ void ResourcesMergingHelper::ExposeFile(gd::String& resourceFilename) {
|
||||
resourceFullFilename = gd::AbstractFileSystem::NormalizeSeparator(
|
||||
resourceFullFilename); // Protect against \ on Linux.
|
||||
|
||||
// In the case of absolute filnames that we don't want to preserve, or
|
||||
// In the case of absolute filenames that we don't want to preserve, or
|
||||
// in the case of copying files without preserving relative folders, the new
|
||||
// names will be generated from the filename alone (with collision protection).
|
||||
auto stripToFilenameOnly = [&]() {
|
||||
|
@@ -71,7 +71,7 @@ class GD_CORE_API ResourcesMergingHelper : public ArbitraryResourceWorker {
|
||||
* Resources merging helper collects all resources filenames and update these
|
||||
* filenames.
|
||||
*/
|
||||
virtual void ExposeFile(gd::String& resource);
|
||||
virtual void ExposeFile(gd::String& resource) override;
|
||||
|
||||
protected:
|
||||
void SetNewFilename(gd::String oldFilename, gd::String newFilename);
|
||||
|
@@ -33,8 +33,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
: gd::ArbitraryResourceWorker(), oldToNewNames(oldToNewNames_){};
|
||||
virtual ~ResourcesRenamer(){};
|
||||
|
||||
virtual void ExposeFile(gd::String& resourceName) override {
|
||||
RenameIfNeeded(resourceName);
|
||||
virtual void ExposeFile(gd::String& resourceFileName) override{
|
||||
// Don't do anything: we're renaming resources, not the files they are
|
||||
// pointing to.
|
||||
};
|
||||
virtual void ExposeImage(gd::String& imageResourceName) override {
|
||||
RenameIfNeeded(imageResourceName);
|
||||
@@ -45,6 +46,15 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
|
||||
virtual void ExposeFont(gd::String& fontResourceName) override {
|
||||
RenameIfNeeded(fontResourceName);
|
||||
};
|
||||
virtual void ExposeJson(gd::String& jsonResourceName) override {
|
||||
RenameIfNeeded(jsonResourceName);
|
||||
};
|
||||
virtual void ExposeVideo(gd::String& videoResourceName) override {
|
||||
RenameIfNeeded(videoResourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontName) override {
|
||||
RenameIfNeeded(bitmapFontName);
|
||||
};
|
||||
|
||||
private:
|
||||
void RenameIfNeeded(gd::String& resourceName) {
|
||||
|
@@ -238,7 +238,7 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
};
|
||||
|
||||
auto renameBehaviorEventsFunction =
|
||||
[&project, &eventsFunctionsExtension, &oldName, &newName](
|
||||
[&project, &oldName, &newName](
|
||||
const gd::EventsBasedBehavior& eventsBasedBehavior,
|
||||
const gd::EventsFunction& eventsFunction) {
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
@@ -261,7 +261,7 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
|
||||
};
|
||||
|
||||
auto renameBehaviorPropertyFunctions =
|
||||
[&project, &eventsFunctionsExtension, &oldName, &newName](
|
||||
[&project, &oldName, &newName](
|
||||
const gd::EventsBasedBehavior& eventsBasedBehavior,
|
||||
const gd::NamedPropertyDescriptor& property) {
|
||||
gd::InstructionsTypeRenamer actionRenamer = gd::InstructionsTypeRenamer(
|
||||
@@ -805,7 +805,6 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
|
||||
auto renameBehaviorEventsFunction =
|
||||
[&project,
|
||||
&eventsFunctionsExtension,
|
||||
&eventsBasedBehavior,
|
||||
&oldBehaviorName,
|
||||
&newBehaviorName](const gd::EventsFunction& eventsFunction) {
|
||||
if (eventsFunction.GetFunctionType() == gd::EventsFunction::Action ||
|
||||
@@ -832,7 +831,6 @@ void WholeProjectRefactorer::RenameEventsBasedBehavior(
|
||||
|
||||
auto renameBehaviorProperty = [&project,
|
||||
&eventsFunctionsExtension,
|
||||
&eventsBasedBehavior,
|
||||
&oldBehaviorName,
|
||||
&newBehaviorName](
|
||||
const gd::NamedPropertyDescriptor&
|
||||
|
@@ -17,6 +17,7 @@ void EventsFunction::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("fullName", fullName);
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("sentence", sentence);
|
||||
element.SetAttribute("group", group);
|
||||
element.SetBoolAttribute("private", isPrivate);
|
||||
events.SerializeTo(element.AddChild("events"));
|
||||
|
||||
@@ -44,6 +45,7 @@ void EventsFunction::UnserializeFrom(gd::Project& project,
|
||||
fullName = element.GetStringAttribute("fullName");
|
||||
description = element.GetStringAttribute("description");
|
||||
sentence = element.GetStringAttribute("sentence");
|
||||
group = element.GetStringAttribute("group");
|
||||
isPrivate = element.GetBoolAttribute("private");
|
||||
events.UnserializeFrom(project, element.GetChild("events"));
|
||||
|
||||
|
@@ -102,6 +102,19 @@ class GD_CORE_API EventsFunction {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the group of the instruction in the editor.
|
||||
*/
|
||||
const gd::String& GetGroup() const { return group; };
|
||||
|
||||
/**
|
||||
* \brief Set the group of the instruction in the editor.
|
||||
*/
|
||||
EventsFunction& SetGroup(const gd::String& group_) {
|
||||
group = group_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
enum FunctionType { Action, Condition, Expression, StringExpression };
|
||||
|
||||
/**
|
||||
@@ -188,6 +201,7 @@ class GD_CORE_API EventsFunction {
|
||||
gd::String fullName;
|
||||
gd::String description;
|
||||
gd::String sentence;
|
||||
gd::String group;
|
||||
gd::EventsList events;
|
||||
FunctionType functionType;
|
||||
std::vector<gd::ParameterMetadata> parameters;
|
||||
|
@@ -3,7 +3,6 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "EventsFunctionsExtension.h"
|
||||
|
||||
#include "EventsBasedBehavior.h"
|
||||
@@ -36,6 +35,7 @@ void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
|
||||
fullName = other.fullName;
|
||||
tags = other.tags;
|
||||
author = other.author;
|
||||
authorIds = other.authorIds;
|
||||
previewIconUrl = other.previewIconUrl;
|
||||
iconUrl = other.iconUrl;
|
||||
helpPath = other.helpPath;
|
||||
@@ -50,11 +50,21 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("description", description);
|
||||
element.SetAttribute("name", name);
|
||||
element.SetAttribute("fullName", fullName);
|
||||
if (!originName.empty() || !originIdentifier.empty()) {
|
||||
element.AddChild("origin")
|
||||
.SetAttribute("name", originName)
|
||||
.SetAttribute("identifier", originIdentifier);
|
||||
}
|
||||
auto& tagsElement = element.AddChild("tags");
|
||||
tagsElement.ConsiderAsArray();
|
||||
for (const auto& tag : tags) {
|
||||
tagsElement.AddChild("").SetStringValue(tag);
|
||||
}
|
||||
auto& authorIdsElement = element.AddChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
for (const auto& authorId : authorIds) {
|
||||
authorIdsElement.AddChild("").SetStringValue(authorId);
|
||||
}
|
||||
element.SetAttribute("author", author);
|
||||
element.SetAttribute("previewIconUrl", previewIconUrl);
|
||||
element.SetAttribute("iconUrl", iconUrl);
|
||||
@@ -82,6 +92,14 @@ void EventsFunctionsExtension::UnserializeFrom(
|
||||
iconUrl = element.GetStringAttribute("iconUrl");
|
||||
helpPath = element.GetStringAttribute("helpPath");
|
||||
|
||||
if (element.HasChild("origin")) {
|
||||
gd::String originName =
|
||||
element.GetChild("origin").GetStringAttribute("name", "");
|
||||
gd::String originIdentifier =
|
||||
element.GetChild("origin").GetStringAttribute("identifier", "");
|
||||
SetOrigin(originName, originIdentifier);
|
||||
}
|
||||
|
||||
tags.clear();
|
||||
auto& tagsElement = element.GetChild("tags");
|
||||
if (!tagsElement.IsValueUndefined()) {
|
||||
@@ -99,6 +117,13 @@ void EventsFunctionsExtension::UnserializeFrom(
|
||||
}
|
||||
}
|
||||
|
||||
authorIds.clear();
|
||||
auto& authorIdsElement = element.GetChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
for (std::size_t i = 0; i < authorIdsElement.GetChildrenCount(); ++i) {
|
||||
authorIds.push_back(authorIdsElement.GetChild(i).GetStringValue());
|
||||
}
|
||||
|
||||
dependencies.clear();
|
||||
const auto& dependenciesElement = element.GetChild("dependencies");
|
||||
dependenciesElement.ConsiderAsArray();
|
||||
@@ -125,5 +150,3 @@ bool EventsFunctionsExtension::IsExtensionLifecycleEventsFunction(
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
||||
#endif
|
||||
|
@@ -3,7 +3,6 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
#define GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
|
||||
@@ -88,6 +87,9 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
const std::vector<gd::String>& GetTags() const { return tags; };
|
||||
std::vector<gd::String>& GetTags() { return tags; };
|
||||
|
||||
const std::vector<gd::String>& GetAuthorIds() const { return authorIds; };
|
||||
std::vector<gd::String>& GetAuthorIds() { return authorIds; };
|
||||
|
||||
const gd::String& GetAuthor() const { return author; };
|
||||
EventsFunctionsExtension& SetAuthor(const gd::String& author_) {
|
||||
author = author_;
|
||||
@@ -137,6 +139,23 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
return eventsBasedBehaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets an extension origin. This method is not present since the
|
||||
* beginning so the projects created before that will have extensions
|
||||
* installed from the store without an origin. Keep that in mind when creating
|
||||
* features that rely on an extension's origin.
|
||||
*/
|
||||
virtual void SetOrigin(const gd::String& originName_,
|
||||
const gd::String& originIdentifier_) {
|
||||
originName = originName_;
|
||||
originIdentifier = originIdentifier_;
|
||||
}
|
||||
|
||||
virtual const gd::String& GetOriginName() const { return originName; }
|
||||
virtual const gd::String& GetOriginIdentifier() const {
|
||||
return originIdentifier;
|
||||
}
|
||||
|
||||
/** \name Dependencies
|
||||
*/
|
||||
///@{
|
||||
@@ -220,8 +239,11 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
gd::String name;
|
||||
gd::String fullName;
|
||||
std::vector<gd::String> tags;
|
||||
std::vector<gd::String> authorIds;
|
||||
gd::String author;
|
||||
gd::String previewIconUrl;
|
||||
gd::String originName;
|
||||
gd::String originIdentifier;
|
||||
gd::String iconUrl;
|
||||
gd::String helpPath; ///< The relative path to the help for this extension in
|
||||
///< the documentation (or an absolute URL).
|
||||
@@ -232,4 +254,3 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EVENTSFUNCTIONEXTENSION_H
|
||||
#endif
|
||||
|
@@ -52,12 +52,12 @@ class GD_CORE_API ExtensionProperties {
|
||||
/**
|
||||
* \brief Serialize the Extension Properties.
|
||||
*/
|
||||
virtual void SerializeTo(SerializerElement& element) const;
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
|
||||
/**
|
||||
* \brief Unserialize the Extension Properties.
|
||||
*/
|
||||
virtual void UnserializeFrom(const SerializerElement& element);
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
///@}
|
||||
|
||||
private:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/Project/ExternalEvents.h"
|
||||
|
||||
#include "ExternalEvents.h"
|
||||
#include "GDCore/Events/Event.h"
|
||||
#include "GDCore/Events/Serialization.h"
|
||||
@@ -48,4 +48,3 @@ void ExternalEvents::UnserializeFrom(gd::Project& project,
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
#endif
|
||||
|
@@ -3,12 +3,12 @@
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#ifndef GDCORE_EXTERNALEVENTS_H
|
||||
#define GDCORE_EXTERNALEVENTS_H
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/Events/EventsList.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
@@ -135,4 +135,3 @@ struct ExternalEventsHasName
|
||||
} // namespace gd
|
||||
|
||||
#endif // GDCORE_EXTERNALEVENTS_H
|
||||
#endif
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "GDCore/Project/ExternalLayout.h"
|
||||
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/Serialization/SerializerElement.h"
|
||||
@@ -15,19 +16,15 @@ namespace gd {
|
||||
void ExternalLayout::UnserializeFrom(const SerializerElement& element) {
|
||||
name = element.GetStringAttribute("name", "", "Name");
|
||||
instances.UnserializeFrom(element.GetChild("instances", 0, "Instances"));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
editorSettings.UnserializeFrom(element.GetChild("editionSettings"));
|
||||
#endif
|
||||
associatedLayout = element.GetStringAttribute("associatedLayout");
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ExternalLayout::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("name", name);
|
||||
instances.SerializeTo(element.AddChild("instances"));
|
||||
editorSettings.SerializeTo(element.AddChild("editionSettings"));
|
||||
element.SetAttribute("associatedLayout", associatedLayout);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -7,14 +7,13 @@
|
||||
#ifndef GDCORE_EXTERNALLAYOUT_H
|
||||
#define GDCORE_EXTERNALLAYOUT_H
|
||||
#include <memory>
|
||||
|
||||
#include "GDCore/Project/InitialInstancesContainer.h"
|
||||
#include "GDCore/String.h"
|
||||
namespace gd {
|
||||
class SerializerElement;
|
||||
}
|
||||
#if defined(GD_IDE_ONLY)
|
||||
#include "GDCore/IDE/Dialogs/LayoutEditorCanvas/EditorSettings.h"
|
||||
#endif
|
||||
|
||||
namespace gd {
|
||||
|
||||
@@ -54,7 +53,6 @@ class GD_CORE_API ExternalLayout {
|
||||
*/
|
||||
gd::InitialInstancesContainer& GetInitialInstances() { return instances; }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
@@ -65,10 +63,7 @@ class GD_CORE_API ExternalLayout {
|
||||
/**
|
||||
* \brief Get the user settings for the IDE.
|
||||
*/
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() {
|
||||
return editorSettings;
|
||||
}
|
||||
#endif
|
||||
gd::EditorSettings& GetAssociatedEditorSettings() { return editorSettings; }
|
||||
|
||||
/**
|
||||
* \brief Get the name of the layout last used to edit the external layout.
|
||||
@@ -80,15 +75,13 @@ class GD_CORE_API ExternalLayout {
|
||||
*/
|
||||
void SetAssociatedLayout(const gd::String& name) { associatedLayout = name; }
|
||||
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name Serialization
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Serialize external layout.
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the external layout.
|
||||
@@ -99,9 +92,7 @@ class GD_CORE_API ExternalLayout {
|
||||
private:
|
||||
gd::String name;
|
||||
gd::InitialInstancesContainer instances;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
gd::EditorSettings editorSettings;
|
||||
#endif
|
||||
gd::String associatedLayout;
|
||||
};
|
||||
|
||||
|
@@ -217,7 +217,7 @@ class GD_CORE_API Layout : public ObjectsContainer {
|
||||
/**
|
||||
* Must add a new the layer constructed from the layout passed as parameter.
|
||||
* \note No pointer or reference must be kept on the layer passed as
|
||||
* parameter. \param theLayer The the layer that must be copied and inserted
|
||||
* parameter. \param theLayer the layer that must be copied and inserted
|
||||
* into the project \param position Insertion position. Even if the position
|
||||
* is invalid, the layer must be inserted at the end of the layers list.
|
||||
*/
|
||||
|
@@ -50,6 +50,10 @@ class GD_CORE_API LoadingScreen {
|
||||
return backgroundImageResourceName;
|
||||
};
|
||||
|
||||
gd::String& GetBackgroundImageResourceName() {
|
||||
return backgroundImageResourceName;
|
||||
};
|
||||
|
||||
LoadingScreen& SetBackgroundImageResourceName(const gd::String& value) {
|
||||
backgroundImageResourceName = value;
|
||||
return *this;
|
||||
|
@@ -87,7 +87,6 @@ class GD_CORE_API ObjectsContainer {
|
||||
*/
|
||||
std::size_t GetObjectsCount() const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Add a new empty object of type \a objectType called \a name at the
|
||||
* specified position in the list.<br>
|
||||
@@ -99,7 +98,6 @@ class GD_CORE_API ObjectsContainer {
|
||||
const gd::String& objectType,
|
||||
const gd::String& name,
|
||||
std::size_t position);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Add a new object to the list
|
||||
@@ -176,7 +174,6 @@ class GD_CORE_API ObjectsContainer {
|
||||
*/
|
||||
///@{
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Return a reference to the project's objects groups.
|
||||
*/
|
||||
@@ -186,7 +183,6 @@ class GD_CORE_API ObjectsContainer {
|
||||
* \brief Return a const reference to the project's objects groups.
|
||||
*/
|
||||
const ObjectGroupsContainer& GetObjectGroups() const { return objectGroups; }
|
||||
#endif
|
||||
|
||||
///@}
|
||||
|
||||
|
@@ -49,14 +49,11 @@ using namespace std;
|
||||
namespace gd {
|
||||
|
||||
Project::Project()
|
||||
:
|
||||
#if defined(GD_IDE_ONLY)
|
||||
name(_("Project")),
|
||||
: name(_("Project")),
|
||||
version("1.0.0"),
|
||||
packageName("com.example.gamename"),
|
||||
orientation("landscape"),
|
||||
folderProject(false),
|
||||
#endif
|
||||
windowWidth(800),
|
||||
windowHeight(600),
|
||||
maxFPS(60),
|
||||
@@ -67,17 +64,12 @@ Project::Project()
|
||||
adaptGameResolutionAtRuntime(true),
|
||||
sizeOnStartupMode("adaptWidth"),
|
||||
projectUuid(""),
|
||||
useDeprecatedZeroAsDefaultZOrder(false)
|
||||
#if defined(GD_IDE_ONLY)
|
||||
,
|
||||
useDeprecatedZeroAsDefaultZOrder(false),
|
||||
useExternalSourceFiles(false),
|
||||
currentPlatform(NULL),
|
||||
gdMajorVersion(gd::VersionWrapper::Major()),
|
||||
gdMinorVersion(gd::VersionWrapper::Minor()),
|
||||
gdBuildVersion(gd::VersionWrapper::Build())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
gdBuildVersion(gd::VersionWrapper::Build()) {}
|
||||
|
||||
Project::~Project() {}
|
||||
|
||||
@@ -102,7 +94,6 @@ std::unique_ptr<gd::Object> Project::CreateObject(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::shared_ptr<gd::BaseEvent> Project::CreateEvent(
|
||||
const gd::String& type, const gd::String& platformName) {
|
||||
for (std::size_t i = 0; i < platforms.size(); ++i) {
|
||||
@@ -161,7 +152,6 @@ bool Project::RemovePlatform(const gd::String& platformName) {
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Project::HasLayoutNamed(const gd::String& name) const {
|
||||
return (find_if(scenes.begin(),
|
||||
@@ -188,13 +178,11 @@ std::size_t Project::GetLayoutPosition(const gd::String& name) const {
|
||||
}
|
||||
std::size_t Project::GetLayoutsCount() const { return scenes.size(); }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void Project::SwapLayouts(std::size_t first, std::size_t second) {
|
||||
if (first >= scenes.size() || second >= scenes.size()) return;
|
||||
|
||||
std::iter_swap(scenes.begin() + first, scenes.begin() + second);
|
||||
}
|
||||
#endif
|
||||
|
||||
gd::Layout& Project::InsertNewLayout(const gd::String& name,
|
||||
std::size_t position) {
|
||||
@@ -203,9 +191,7 @@ gd::Layout& Project::InsertNewLayout(const gd::String& name,
|
||||
new Layout())));
|
||||
|
||||
newlyInsertedLayout.SetName(name);
|
||||
#if defined(GD_IDE_ONLY)
|
||||
newlyInsertedLayout.UpdateBehaviorsSharedData(*this);
|
||||
#endif
|
||||
|
||||
return newlyInsertedLayout;
|
||||
}
|
||||
@@ -216,9 +202,7 @@ gd::Layout& Project::InsertLayout(const gd::Layout& layout,
|
||||
position < scenes.size() ? scenes.begin() + position : scenes.end(),
|
||||
new Layout(layout))));
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
newlyInsertedLayout.UpdateBehaviorsSharedData(*this);
|
||||
#endif
|
||||
|
||||
return newlyInsertedLayout;
|
||||
}
|
||||
@@ -231,7 +215,6 @@ void Project::RemoveLayout(const gd::String& name) {
|
||||
scenes.erase(scene);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
bool Project::HasExternalEventsNamed(const gd::String& name) const {
|
||||
return (find_if(externalEvents.begin(),
|
||||
externalEvents.end(),
|
||||
@@ -311,7 +294,6 @@ void Project::SwapExternalLayouts(std::size_t first, std::size_t second) {
|
||||
std::iter_swap(externalLayouts.begin() + first,
|
||||
externalLayouts.begin() + second);
|
||||
}
|
||||
#endif
|
||||
bool Project::HasExternalLayoutNamed(const gd::String& name) const {
|
||||
return (find_if(externalLayouts.begin(),
|
||||
externalLayouts.end(),
|
||||
@@ -377,7 +359,6 @@ void Project::RemoveExternalLayout(const gd::String& name) {
|
||||
externalLayouts.erase(externalLayout);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void Project::SwapEventsFunctionsExtensions(std::size_t first,
|
||||
std::size_t second) {
|
||||
if (first >= eventsFunctionsExtensions.size() ||
|
||||
@@ -476,11 +457,8 @@ void Project::RemoveEventsFunctionsExtension(const gd::String& name) {
|
||||
void Project::ClearEventsFunctionsExtensions() {
|
||||
eventsFunctionsExtensions.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
// Checking version
|
||||
#if defined(GD_IDE_ONLY)
|
||||
const SerializerElement& gdVersionElement =
|
||||
element.GetChild("gdVersion", 0, "GDVersion");
|
||||
gdMajorVersion =
|
||||
@@ -513,7 +491,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
"available.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const SerializerElement& propElement =
|
||||
element.GetChild("properties", 0, "Info");
|
||||
@@ -534,7 +511,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
propElement.GetBoolAttribute("adaptGameResolutionAtRuntime", false));
|
||||
SetSizeOnStartupMode(propElement.GetStringAttribute("sizeOnStartupMode", ""));
|
||||
SetProjectUuid(propElement.GetStringAttribute("projectUuid", ""));
|
||||
#if defined(GD_IDE_ONLY)
|
||||
SetAuthor(propElement.GetChild("author", 0, "Auteur").GetValue().GetString());
|
||||
SetPackageName(propElement.GetStringAttribute("packageName"));
|
||||
SetOrientation(propElement.GetStringAttribute("orientation", "default"));
|
||||
@@ -552,6 +528,13 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
useExternalSourceFiles =
|
||||
propElement.GetBoolAttribute("useExternalSourceFiles");
|
||||
|
||||
authorIds.clear();
|
||||
auto& authorIdsElement = propElement.GetChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
for (std::size_t i = 0; i < authorIdsElement.GetChildrenCount(); ++i) {
|
||||
authorIds.push_back(authorIdsElement.GetChild(i).GetStringValue());
|
||||
}
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (VersionWrapper::IsOlderOrEqual(
|
||||
gdMajorVersion, gdMinorVersion, gdBuildVersion, 0, 4, 0, 98, 0) &&
|
||||
@@ -583,9 +566,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
}
|
||||
// end of compatibility code
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
currentPlatform = NULL;
|
||||
gd::String currentPlatformName =
|
||||
propElement.GetChild("currentPlatform").GetValue().GetString();
|
||||
@@ -635,12 +615,9 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
|
||||
if (currentPlatform == NULL && !platforms.empty())
|
||||
currentPlatform = platforms.back();
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
GetObjectGroups().UnserializeFrom(
|
||||
element.GetChild("objectsGroups", 0, "ObjectGroups"));
|
||||
#endif
|
||||
resourcesManager.UnserializeFrom(
|
||||
element.GetChild("resources", 0, "Resources"));
|
||||
UnserializeObjectsFrom(*this, element.GetChild("objects", 0, "Objects"));
|
||||
@@ -658,7 +635,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
layout.UnserializeFrom(*this, layoutElement);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
externalEvents.clear();
|
||||
const SerializerElement& externalEventsElement =
|
||||
element.GetChild("externalEvents", 0, "ExternalEvents");
|
||||
@@ -690,7 +666,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
newEventsFunctionsExtension.UnserializeFrom(
|
||||
*this, eventsFunctionsExtensionElement);
|
||||
}
|
||||
#endif
|
||||
|
||||
externalLayouts.clear();
|
||||
const SerializerElement& externalLayoutsElement =
|
||||
@@ -705,7 +680,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
newExternalLayout.UnserializeFrom(externalLayoutElement);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
externalSourceFiles.clear();
|
||||
const SerializerElement& externalSourceFilesElement =
|
||||
element.GetChild("externalSourceFiles", 0, "ExternalSourceFiles");
|
||||
@@ -718,10 +692,8 @@ void Project::UnserializeFrom(const SerializerElement& element) {
|
||||
gd::SourceFile& newSourceFile = InsertNewSourceFile("", "");
|
||||
newSourceFile.UnserializeFrom(sourceFileElement);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void Project::SerializeTo(SerializerElement& element) const {
|
||||
SerializerElement& versionElement = element.AddChild("gdVersion");
|
||||
versionElement.SetAttribute("major", gd::VersionWrapper::Major());
|
||||
@@ -755,6 +727,12 @@ void Project::SerializeTo(SerializerElement& element) const {
|
||||
loadingScreen.SerializeTo(propElement.AddChild("loadingScreen"));
|
||||
propElement.SetAttribute("useExternalSourceFiles", useExternalSourceFiles);
|
||||
|
||||
auto& authorIdsElement = propElement.AddChild("authorIds");
|
||||
authorIdsElement.ConsiderAsArray();
|
||||
for (const auto& authorId : authorIds) {
|
||||
authorIdsElement.AddChild("").SetStringValue(authorId);
|
||||
}
|
||||
|
||||
// Compatibility with GD <= 5.0.0-beta101
|
||||
if (useDeprecatedZeroAsDefaultZOrder) {
|
||||
propElement.SetAttribute("useDeprecatedZeroAsDefaultZOrder", true);
|
||||
@@ -865,6 +843,10 @@ void Project::ExposeResources(gd::ArbitraryResourceWorker& worker) {
|
||||
for (std::size_t j = 0; j < GetObjectsCount(); ++j) {
|
||||
GetObject(j).ExposeResources(worker);
|
||||
}
|
||||
|
||||
// Add loading screen background image if present
|
||||
if (loadingScreen.GetBackgroundImageResourceName() != "")
|
||||
worker.ExposeImage(loadingScreen.GetBackgroundImageResourceName());
|
||||
}
|
||||
|
||||
bool Project::HasSourceFile(gd::String name, gd::String language) const {
|
||||
@@ -915,7 +897,6 @@ gd::SourceFile& Project::InsertNewSourceFile(const gd::String& name,
|
||||
|
||||
return newlyInsertedSourceFile;
|
||||
}
|
||||
#endif
|
||||
|
||||
Project::Project(const Project& other) { Init(other); }
|
||||
|
||||
@@ -940,8 +921,8 @@ void Project::Init(const gd::Project& game) {
|
||||
projectUuid = game.projectUuid;
|
||||
useDeprecatedZeroAsDefaultZOrder = game.useDeprecatedZeroAsDefaultZOrder;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
author = game.author;
|
||||
authorIds = game.authorIds;
|
||||
packageName = game.packageName;
|
||||
orientation = game.orientation;
|
||||
folderProject = game.folderProject;
|
||||
@@ -957,33 +938,26 @@ void Project::Init(const gd::Project& game) {
|
||||
gdBuildVersion = game.gdBuildVersion;
|
||||
|
||||
currentPlatform = game.currentPlatform;
|
||||
#endif
|
||||
platforms = game.platforms;
|
||||
|
||||
resourcesManager = game.resourcesManager;
|
||||
|
||||
|
||||
initialObjects = gd::Clone(game.initialObjects);
|
||||
|
||||
scenes = gd::Clone(game.scenes);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
externalEvents = gd::Clone(game.externalEvents);
|
||||
#endif
|
||||
|
||||
externalLayouts = gd::Clone(game.externalLayouts);
|
||||
#if defined(GD_IDE_ONLY)
|
||||
eventsFunctionsExtensions = gd::Clone(game.eventsFunctionsExtensions);
|
||||
|
||||
useExternalSourceFiles = game.useExternalSourceFiles;
|
||||
|
||||
externalSourceFiles = gd::Clone(game.externalSourceFiles);
|
||||
#endif
|
||||
|
||||
variables = game.GetVariables();
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
projectFile = game.GetProjectFile();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -77,7 +77,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
const gd::String& GetVersion() const { return version; }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Change the author of the project.
|
||||
*/
|
||||
@@ -88,6 +87,16 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
const gd::String& GetAuthor() const { return author; }
|
||||
|
||||
/**
|
||||
* \brief Get the author ids of the project.
|
||||
*/
|
||||
const std::vector<gd::String>& GetAuthorIds() const { return authorIds; };
|
||||
|
||||
/**
|
||||
* \brief Get the author ids of the project, to modify them (non-const).
|
||||
*/
|
||||
std::vector<gd::String>& GetAuthorIds() { return authorIds; };
|
||||
|
||||
/**
|
||||
* \brief Change project package name.
|
||||
*/
|
||||
@@ -178,7 +187,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* \brief Return a reference to loading screen setup for the project
|
||||
*/
|
||||
const gd::LoadingScreen& GetLoadingScreen() const { return loadingScreen; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Change game's main window default width.
|
||||
@@ -279,16 +287,13 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
/**
|
||||
* Return true if pixels rounding option is enabled.
|
||||
*/
|
||||
bool GetPixelsRounding() const {
|
||||
return pixelsRounding;
|
||||
}
|
||||
bool GetPixelsRounding() const { return pixelsRounding; }
|
||||
|
||||
/**
|
||||
* Set pixels rounding option to true or false.
|
||||
*/
|
||||
void SetPixelsRounding(bool enable) { pixelsRounding = enable; }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return if the project should set 0 as Z-order for objects created
|
||||
* from events (which is deprecated) - instead of the highest Z order that was
|
||||
@@ -325,7 +330,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
void ResetProjectUuid();
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Get the properties set by extensions.
|
||||
*
|
||||
@@ -376,7 +380,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* current platform won't be changed.
|
||||
*/
|
||||
void SetCurrentPlatform(const gd::String& platformName);
|
||||
#endif
|
||||
|
||||
///@}
|
||||
|
||||
@@ -402,7 +405,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
const gd::String& name,
|
||||
const gd::String& platformName = "");
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* Create an event of the given type.
|
||||
*
|
||||
@@ -418,7 +420,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
std::shared_ptr<gd::BaseEvent> CreateEvent(
|
||||
const gd::String& type, const gd::String& platformName = "");
|
||||
///@}
|
||||
#endif
|
||||
|
||||
/** \name Layouts management
|
||||
* Members functions related to layout management.
|
||||
@@ -456,14 +457,12 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
std::size_t GetLayoutPosition(const gd::String& name) const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Swap the specified layouts.
|
||||
*
|
||||
* Do nothing if indexes are not correct.
|
||||
*/
|
||||
void SwapLayouts(std::size_t first, std::size_t second);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Return the number of layouts.
|
||||
@@ -502,7 +501,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
void UnserializeFrom(const SerializerElement& element);
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Serialize the project.
|
||||
*
|
||||
@@ -524,13 +522,11 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* Get the minor version of GDevelop used to save the project.
|
||||
*/
|
||||
unsigned int GetLastSaveGDBuildVersion() { return gdBuildVersion; };
|
||||
#endif
|
||||
|
||||
/** \name External events management
|
||||
* Members functions related to external events management.
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name External events management
|
||||
* Members functions related to external events management.
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* Return true if external events called "name" exists.
|
||||
*/
|
||||
@@ -598,7 +594,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* \brief Delete external events named "name".
|
||||
*/
|
||||
void RemoveExternalEvents(const gd::String& name);
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/** \name External layout management
|
||||
@@ -639,14 +634,12 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
std::size_t GetExternalLayoutPosition(const gd::String& name) const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Swap the specified external layouts.
|
||||
*
|
||||
* Do nothing if indexes are not correct.
|
||||
*/
|
||||
void SwapExternalLayouts(std::size_t first, std::size_t second);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return the number of external layout.
|
||||
@@ -690,12 +683,11 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
*/
|
||||
const gd::String& GetFirstLayout() { return firstLayout; }
|
||||
|
||||
///@}
|
||||
///@}
|
||||
|
||||
/** \name Events functions extensions management
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name Events functions extensions management
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Check if events functions extension called "name" exists.
|
||||
*/
|
||||
@@ -770,7 +762,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* \brief Remove all the events functions extensions.
|
||||
*/
|
||||
void ClearEventsFunctionsExtensions();
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/** \name Resources management
|
||||
@@ -833,13 +824,12 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
* behavior, events function name, etc...).
|
||||
*/
|
||||
static bool ValidateName(const gd::String& name);
|
||||
///@}
|
||||
///@}
|
||||
|
||||
/** \name External source files
|
||||
* To manage external C++ or Javascript source files used by the game
|
||||
*/
|
||||
///@{
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name External source files
|
||||
* To manage external C++ or Javascript source files used by the game
|
||||
*/
|
||||
///@{
|
||||
/**
|
||||
* \brief Return true if the game activated the use of external source files.
|
||||
*/
|
||||
@@ -884,8 +874,7 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
gd::SourceFile& InsertNewSourceFile(const gd::String& name,
|
||||
const gd::String& language,
|
||||
std::size_t position = -1);
|
||||
#endif
|
||||
///@}
|
||||
///@}
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -903,8 +892,8 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
///< are below this number )
|
||||
bool verticalSync; ///< If true, must activate vertical synchronization.
|
||||
gd::String scaleMode;
|
||||
bool pixelsRounding; ///< If true, the rendering should stop pixel interpolation
|
||||
///< of rendered objects.
|
||||
bool pixelsRounding; ///< If true, the rendering should stop pixel
|
||||
///< interpolation of rendered objects.
|
||||
bool adaptGameResolutionAtRuntime; ///< Should the game resolution be adapted
|
||||
///< to the window size at runtime
|
||||
gd::String
|
||||
@@ -921,23 +910,22 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
gd::VariablesContainer variables; ///< Initial global variables
|
||||
std::vector<std::unique_ptr<gd::ExternalLayout> >
|
||||
externalLayouts; ///< List of all externals layouts
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<std::unique_ptr<gd::EventsFunctionsExtension> >
|
||||
eventsFunctionsExtensions;
|
||||
#endif
|
||||
gd::ResourcesManager
|
||||
resourcesManager; ///< Contains all resources used by the project
|
||||
std::vector<gd::Platform*>
|
||||
platforms; ///< Pointers to the platforms this project supports.
|
||||
gd::String firstLayout;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
bool useExternalSourceFiles; ///< True if game used external source files.
|
||||
std::vector<std::unique_ptr<gd::SourceFile> >
|
||||
externalSourceFiles; ///< List of external source files used.
|
||||
gd::String author; ///< Game author name
|
||||
gd::String packageName; ///< Game package name
|
||||
gd::String orientation; ///< Lock game orientation (on mobile devices).
|
||||
///< "default", "landscape" or "portrait".
|
||||
gd::String author; ///< Game author name, for publishing purpose.
|
||||
std::vector<gd::String>
|
||||
authorIds; ///< Game author ids, from GDevelop users DB.
|
||||
gd::String packageName; ///< Game package name
|
||||
gd::String orientation; ///< Lock game orientation (on mobile devices).
|
||||
///< "default", "landscape" or "portrait".
|
||||
bool
|
||||
folderProject; ///< True if folder project, false if single file project.
|
||||
gd::String
|
||||
@@ -957,7 +945,6 @@ class GD_CORE_API Project : public ObjectsContainer {
|
||||
///< time the project was saved.
|
||||
mutable unsigned int gdBuildVersion; ///< The GD build version used the last
|
||||
///< time the project was saved.
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace gd
|
||||
|
@@ -19,6 +19,7 @@ void PropertyDescriptor::SerializeTo(SerializerElement& element) const {
|
||||
element.AddChild("type").SetStringValue(type);
|
||||
element.AddChild("label").SetStringValue(label);
|
||||
element.AddChild("description").SetStringValue(description);
|
||||
element.AddChild("group").SetStringValue(group);
|
||||
SerializerElement& extraInformationElement =
|
||||
element.AddChild("extraInformation");
|
||||
extraInformationElement.ConsiderAsArray();
|
||||
@@ -33,6 +34,7 @@ void PropertyDescriptor::UnserializeFrom(const SerializerElement& element) {
|
||||
type = element.GetChild("type").GetStringValue();
|
||||
label = element.GetChild("label").GetStringValue();
|
||||
description = element.GetChild("description").GetStringValue();
|
||||
group = element.GetChild("group").GetStringValue();
|
||||
|
||||
extraInformation.clear();
|
||||
const SerializerElement& extraInformationElement =
|
||||
|
@@ -76,6 +76,14 @@ class GD_CORE_API PropertyDescriptor {
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the group where this property is displayed to the user, if any.
|
||||
*/
|
||||
PropertyDescriptor& SetGroup(gd::String group_) {
|
||||
group = group_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set and replace the additional information for the property.
|
||||
*/
|
||||
@@ -100,6 +108,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
const gd::String& GetType() const { return type; }
|
||||
const gd::String& GetLabel() const { return label; }
|
||||
const gd::String& GetDescription() const { return description; }
|
||||
const gd::String& GetGroup() const { return group; }
|
||||
|
||||
const std::vector<gd::String>& GetExtraInfo() const {
|
||||
return extraInformation;
|
||||
@@ -153,6 +162,7 @@ class GD_CORE_API PropertyDescriptor {
|
||||
///< the class responsible for updating the property grid.
|
||||
gd::String label; //< The user-friendly property name
|
||||
gd::String description; //< The user-friendly property description
|
||||
gd::String group; //< The user-friendly property group
|
||||
std::vector<gd::String>
|
||||
extraInformation; ///< Can be used to store for example the available
|
||||
///< choices, if a property is a displayed as a combo
|
||||
|
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
@@ -23,12 +24,9 @@ gd::String Resource::badStr;
|
||||
|
||||
Resource ResourcesManager::badResource;
|
||||
gd::String ResourcesManager::badResourceName;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
ResourceFolder ResourcesManager::badFolder;
|
||||
Resource ResourceFolder::badResource;
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ResourceFolder::Init(const ResourceFolder& other) {
|
||||
name = other.name;
|
||||
|
||||
@@ -37,19 +35,16 @@ void ResourceFolder::Init(const ResourceFolder& other) {
|
||||
resources.push_back(std::shared_ptr<Resource>(other.resources[i]->Clone()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ResourcesManager::Init(const ResourcesManager& other) {
|
||||
resources.clear();
|
||||
for (std::size_t i = 0; i < other.resources.size(); ++i) {
|
||||
resources.push_back(std::shared_ptr<Resource>(other.resources[i]->Clone()));
|
||||
}
|
||||
#if defined(GD_IDE_ONLY)
|
||||
folders.clear();
|
||||
for (std::size_t i = 0; i < other.folders.size(); ++i) {
|
||||
folders.push_back(other.folders[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Resource& ResourcesManager::GetResource(const gd::String& name) {
|
||||
@@ -130,7 +125,22 @@ std::vector<gd::String> ResourcesManager::GetAllResourceNames() const {
|
||||
return allResources;
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<gd::String> ResourcesManager::FindFilesNotInResources(
|
||||
const std::vector<gd::String>& filesToCheck) const {
|
||||
std::unordered_set<gd::String> resourceFiles;
|
||||
for (const auto& resource: resources) {
|
||||
resourceFiles.insert(resource->GetFile());
|
||||
}
|
||||
|
||||
std::vector<gd::String> filesNotInResources;
|
||||
for(const gd::String& file: filesToCheck) {
|
||||
if (resourceFiles.find(file) == resourceFiles.end())
|
||||
filesNotInResources.push_back(file);
|
||||
}
|
||||
|
||||
return filesNotInResources;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> nothing;
|
||||
return nothing;
|
||||
@@ -159,7 +169,8 @@ bool ImageResource::UpdateProperty(const gd::String& name,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> AudioResource::GetProperties() const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> AudioResource::GetProperties()
|
||||
const {
|
||||
std::map<gd::String, gd::PropertyDescriptor> properties;
|
||||
properties[_("Preload as sound")]
|
||||
.SetValue(preloadAsSound ? "true" : "false")
|
||||
@@ -425,9 +436,7 @@ void ResourcesManager::RemoveResource(const gd::String& name) {
|
||||
for (std::size_t i = 0; i < folders.size(); ++i)
|
||||
folders[i].RemoveResource(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ResourceFolder::UnserializeFrom(const SerializerElement& element,
|
||||
gd::ResourcesManager& parentManager) {
|
||||
name = element.GetStringAttribute("name");
|
||||
@@ -452,7 +461,6 @@ void ResourceFolder::SerializeTo(SerializerElement& element) const {
|
||||
.SetAttribute("name", resources[i]->GetName());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
resources.clear();
|
||||
@@ -482,7 +490,6 @@ void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
resources.push_back(resource);
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
folders.clear();
|
||||
const SerializerElement& resourcesFoldersElement =
|
||||
element.GetChild("resourceFolders", 0, "ResourceFolders");
|
||||
@@ -493,10 +500,8 @@ void ResourcesManager::UnserializeFrom(const SerializerElement& element) {
|
||||
|
||||
folders.push_back(folder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ResourcesManager::SerializeTo(SerializerElement& element) const {
|
||||
SerializerElement& resourcesElement = element.AddChild("resources");
|
||||
resourcesElement.ConsiderAsArrayOf("resource");
|
||||
@@ -525,7 +530,6 @@ void ResourcesManager::SerializeTo(SerializerElement& element) const {
|
||||
for (std::size_t i = 0; i < folders.size(); ++i)
|
||||
folders[i].SerializeTo(resourcesFoldersElement.AddChild("folder"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImageResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -542,14 +546,12 @@ void ImageResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void ImageResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("alwaysLoaded", alwaysLoaded);
|
||||
element.SetAttribute("smoothed", smooth);
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudioResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -566,14 +568,12 @@ void AudioResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetPreloadAsSound(element.GetBoolAttribute("preloadAsSound"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void AudioResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
element.SetAttribute("preloadAsMusic", PreloadAsMusic());
|
||||
element.SetAttribute("preloadAsSound", PreloadAsSound());
|
||||
}
|
||||
#endif
|
||||
|
||||
void FontResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -588,12 +588,10 @@ void FontResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void FontResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
#endif
|
||||
|
||||
void VideoResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -608,12 +606,10 @@ void VideoResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void VideoResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
#endif
|
||||
|
||||
void JsonResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -629,7 +625,6 @@ void JsonResource::UnserializeFrom(const SerializerElement& element) {
|
||||
DisablePreload(element.GetBoolAttribute("disablePreload", false));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void JsonResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
@@ -654,7 +649,6 @@ bool JsonResource::UpdateProperty(const gd::String& name,
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BitmapFontResource::SetFile(const gd::String& newFile) {
|
||||
file = newFile;
|
||||
@@ -669,14 +663,11 @@ void BitmapFontResource::UnserializeFrom(const SerializerElement& element) {
|
||||
SetFile(element.GetStringAttribute("file"));
|
||||
}
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
void BitmapFontResource::SerializeTo(SerializerElement& element) const {
|
||||
element.SetAttribute("userAdded", IsUserAdded());
|
||||
element.SetAttribute("file", GetFile());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
ResourceFolder::ResourceFolder(const ResourceFolder& other) { Init(other); }
|
||||
|
||||
ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) {
|
||||
@@ -684,7 +675,6 @@ ResourceFolder& ResourceFolder::operator=(const ResourceFolder& other) {
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
ResourcesManager::ResourcesManager(const ResourcesManager& other) {
|
||||
Init(other);
|
||||
|
@@ -104,7 +104,6 @@ class GD_CORE_API Resource {
|
||||
*/
|
||||
virtual const gd::String& GetMetadata() const { return metadata; }
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/** \name Resources properties
|
||||
* Reading and updating resources properties
|
||||
*/
|
||||
@@ -136,7 +135,6 @@ class GD_CORE_API Resource {
|
||||
return false;
|
||||
};
|
||||
///@}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Serialize the object
|
||||
@@ -186,7 +184,6 @@ class GD_CORE_API ImageResource : public Resource {
|
||||
*/
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
@@ -196,7 +193,6 @@ class GD_CORE_API ImageResource : public Resource {
|
||||
* \brief Serialize the object
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objectt.
|
||||
@@ -238,14 +234,12 @@ class GD_CORE_API AudioResource : public Resource {
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
@@ -292,10 +286,8 @@ class GD_CORE_API FontResource : public Resource {
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
@@ -320,10 +312,8 @@ class GD_CORE_API VideoResource : public Resource {
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
@@ -348,14 +338,12 @@ class GD_CORE_API JsonResource : public Resource {
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
|
||||
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
|
||||
bool UpdateProperty(const gd::String& name, const gd::String& value) override;
|
||||
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
@@ -391,10 +379,8 @@ class GD_CORE_API BitmapFontResource : public Resource {
|
||||
virtual const gd::String& GetFile() const override { return file; };
|
||||
virtual void SetFile(const gd::String& newFile) override;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
virtual bool UseFile() override { return true; }
|
||||
void SerializeTo(SerializerElement& element) const override;
|
||||
#endif
|
||||
|
||||
void UnserializeFrom(const SerializerElement& element) override;
|
||||
|
||||
@@ -447,12 +433,22 @@ class GD_CORE_API ResourcesManager {
|
||||
*/
|
||||
std::shared_ptr<Resource> CreateResource(const gd::String& kind);
|
||||
|
||||
/**
|
||||
* Get a list containing all the resources.
|
||||
*/
|
||||
const std::vector<std::shared_ptr<Resource>>& GetAllResources() const { return resources; };
|
||||
|
||||
/**
|
||||
* \brief Get a list containing the names of all resources.
|
||||
*/
|
||||
std::vector<gd::String> GetAllResourceNames() const;
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
/**
|
||||
* \brief Return a list of the files, from the specified input list,
|
||||
* that are not used as files by the resources.
|
||||
*/
|
||||
std::vector<gd::String> FindFilesNotInResources(const std::vector<gd::String>& filesToCheck) const;
|
||||
|
||||
/**
|
||||
* \brief Return a (smart) pointer to a resource.
|
||||
*/
|
||||
@@ -546,7 +542,6 @@ class GD_CORE_API ResourcesManager {
|
||||
* \brief Serialize the object
|
||||
*/
|
||||
void SerializeTo(SerializerElement& element) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Unserialize the objectt.
|
||||
@@ -557,18 +552,13 @@ class GD_CORE_API ResourcesManager {
|
||||
void Init(const ResourcesManager& other);
|
||||
|
||||
std::vector<std::shared_ptr<Resource> > resources;
|
||||
#if defined(GD_IDE_ONLY)
|
||||
std::vector<ResourceFolder> folders;
|
||||
#endif
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
static ResourceFolder badFolder;
|
||||
#endif
|
||||
static Resource badResource;
|
||||
static gd::String badResourceName;
|
||||
};
|
||||
|
||||
#if defined(GD_IDE_ONLY)
|
||||
class GD_CORE_API ResourceFolder {
|
||||
public:
|
||||
ResourceFolder(){};
|
||||
@@ -643,7 +633,6 @@ class GD_CORE_API ResourceFolder {
|
||||
void Init(const ResourceFolder& other);
|
||||
static Resource badResource;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace gd
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "GDCore/String.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
|
||||
#include <SFML/System/String.hpp>
|
||||
@@ -283,6 +284,42 @@ String& String::insert( size_type pos, const String &str )
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::replace_if(iterator i1, iterator i2, std::function<bool(char32_t)> p, const String &str)
|
||||
{
|
||||
String::size_type offset = 1;
|
||||
iterator it = i1.base();
|
||||
while(it < i2.base())
|
||||
{
|
||||
if (p(*it)) { replace(std::distance(begin(), it), offset, str); }
|
||||
else { it++; }
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::RemoveConsecutiveOccurrences(iterator i1, iterator i2, const char c)
|
||||
{
|
||||
std::vector<std::pair<size_type, size_type>> ranges_to_remove;
|
||||
for(iterator current_index = i1.base(); current_index < i2.base(); current_index++)
|
||||
{
|
||||
if (*current_index == c){
|
||||
iterator current_subindex = current_index;
|
||||
std::advance(current_subindex, 1);
|
||||
if (*current_subindex == c) {
|
||||
while(current_subindex < end() && *current_subindex == c)
|
||||
{
|
||||
current_subindex++;
|
||||
}
|
||||
replace(std::distance(begin(), current_index),
|
||||
std::distance(current_index, current_subindex),
|
||||
c);
|
||||
|
||||
std::advance(current_index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::replace( iterator i1, iterator i2, const String &str )
|
||||
{
|
||||
m_string.replace(i1.base(), i2.base(), str.m_string);
|
||||
@@ -290,6 +327,31 @@ String& String::replace( iterator i1, iterator i2, const String &str )
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::replace( iterator i1, iterator i2, size_type n, const char c )
|
||||
{
|
||||
m_string.replace(i1.base(), i2.base(), n, c);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String& String::replace( String::size_type pos, String::size_type len, const char c )
|
||||
{
|
||||
if(pos > size())
|
||||
throw std::out_of_range("[gd::String::replace] starting pos greater than size");
|
||||
|
||||
iterator i1 = begin();
|
||||
std::advance( i1, pos );
|
||||
|
||||
iterator i2 = i1;
|
||||
while(i2 != end() && len > 0) //Increment "len" times and stop if end() is reached
|
||||
{
|
||||
++i2;
|
||||
--len;
|
||||
}
|
||||
|
||||
return replace( i1, i2, 1, c );
|
||||
}
|
||||
|
||||
String& String::replace( String::size_type pos, String::size_type len, const String &str )
|
||||
{
|
||||
if(pos > size())
|
||||
@@ -605,7 +667,7 @@ int String::compare( const String &other ) const
|
||||
namespace priv
|
||||
{
|
||||
/**
|
||||
* As the the casefolded version of a string can have a different size, the positions
|
||||
* As the casefolded version of a string can have a different size, the positions
|
||||
* in the two versions of the string are not the same.
|
||||
* \return where the **pos** position in the original string **str** is in the
|
||||
* casefolded version of **str**
|
||||
@@ -619,7 +681,7 @@ namespace priv
|
||||
}
|
||||
|
||||
/**
|
||||
* As the the casefolded version of a string can have a different size, the positions
|
||||
* As the casefolded version of a string can have a different size, the positions
|
||||
* in the two versions of the string are not the same.
|
||||
* \return where the **pos** position in the casefolded string of **str** is in the
|
||||
* original version **str**
|
||||
|
@@ -438,15 +438,52 @@ public:
|
||||
*/
|
||||
String& replace( iterator i1, iterator i2, const String &str );
|
||||
|
||||
/**
|
||||
* \brief Replace the portion of the String between **i1** and **i2** (**i2** not
|
||||
* included) by **n** consecutive copies of character **c**.
|
||||
* \return *this
|
||||
*
|
||||
* **Iterators :** All iterators may be invalidated.
|
||||
*/
|
||||
String& replace( iterator i1, iterator i2, size_type n, const char c );
|
||||
|
||||
/**
|
||||
* \brief Replace the portion of the String between **pos** and **pos** + **len**
|
||||
* (the character at **pos** + **len** is not included)
|
||||
* (the character at **pos** + **len** is not included) with **str**.
|
||||
* \return *this
|
||||
*
|
||||
* **Iterators :** All iterators may be invalidated.
|
||||
*/
|
||||
String& replace( size_type pos, size_type len, const String &str );
|
||||
|
||||
/**
|
||||
* \brief Replace the portion of the String between **pos** and **pos** + **len**
|
||||
* (the character at **pos** + **len** is not included) with the character **c**.
|
||||
* \return *this
|
||||
*
|
||||
* **Iterators :** All iterators may be invalidated.
|
||||
*/
|
||||
String& replace( size_type pos, size_type len, const char c );
|
||||
|
||||
/**
|
||||
* \brief Search in the portion of the String between **i1** and **i2** (**i2** not
|
||||
* included) for characters matching predicate function **p** and replace them
|
||||
* by the String **str**.
|
||||
* \return *this
|
||||
*
|
||||
* **Iterators :** All iterators may be invalidated.
|
||||
*/
|
||||
String& replace_if( iterator i1, iterator i2, std::function<bool(char32_t)> p, const String &str );
|
||||
|
||||
/**
|
||||
* \brief Remove consecutive occurrences of the character **c** in the portion of the
|
||||
* between **i1** and **i2** (**i2** not included) to replace it by a single occurrence.
|
||||
* \return *this
|
||||
*
|
||||
* **Iterators :** All iterators may be invalidated.
|
||||
*/
|
||||
String& RemoveConsecutiveOccurrences(iterator i1, iterator i2, const char c);
|
||||
|
||||
/**
|
||||
* \brief Erase the characters between **first** and **last** (**last** not included).
|
||||
* \param first an iterator to the first character to remove
|
||||
|
132
Core/tests/ArbitraryResourceWorker.cpp
Normal file
132
Core/tests/ArbitraryResourceWorker.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include <string>
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "DummyPlatform.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
class ArbitraryResourceWorkerTest : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
virtual void ExposeFile(gd::String& file) { files.push_back(file); };
|
||||
virtual void ExposeImage(gd::String& imageName) {
|
||||
images.push_back(imageName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& bitmapFontName) {
|
||||
bitmapFonts.push_back(bitmapFontName);
|
||||
};
|
||||
virtual void ExposeAudio(gd::String& audioName) {
|
||||
audios.push_back(audioName);
|
||||
};
|
||||
|
||||
std::vector<gd::String> files;
|
||||
std::vector<gd::String> images;
|
||||
std::vector<gd::String> bitmapFonts;
|
||||
std::vector<gd::String> audios;
|
||||
};
|
||||
|
||||
TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
|
||||
SECTION("Basics") {
|
||||
gd::Project project;
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res4", "path/to/file4.png", "audio");
|
||||
ArbitraryResourceWorkerTest worker;
|
||||
|
||||
project.ExposeResources(worker);
|
||||
REQUIRE(worker.files.size() == 4);
|
||||
REQUIRE(std::find(worker.files.begin(),
|
||||
worker.files.end(),
|
||||
"path/to/file2.png") != worker.files.end());
|
||||
REQUIRE(std::find(worker.files.begin(),
|
||||
worker.files.end(),
|
||||
"path/to/file4.png") != worker.files.end());
|
||||
|
||||
SECTION("Object using a resource") {
|
||||
gd::SpriteObject obj("myObject");
|
||||
|
||||
gd::Animation anim;
|
||||
gd::Sprite sprite;
|
||||
sprite.SetImageName("res1");
|
||||
anim.SetDirectionsCount(1);
|
||||
anim.GetDirection(0).AddSprite(sprite);
|
||||
obj.AddAnimation(anim);
|
||||
project.InsertObject(obj, 0);
|
||||
|
||||
worker.files.clear();
|
||||
worker.images.clear();
|
||||
project.ExposeResources(worker);
|
||||
REQUIRE(worker.files.size() == 4);
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
|
||||
SECTION("ProjectResourcesAdder") {
|
||||
std::vector<gd::String> uselessResources =
|
||||
gd::ProjectResourcesAdder::GetAllUseless(project, "image");
|
||||
|
||||
REQUIRE(uselessResources.size() == 2);
|
||||
|
||||
gd::ProjectResourcesAdder::RemoveAllUseless(project, "image");
|
||||
std::vector<gd::String> remainingResources =
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
REQUIRE(remainingResources.size() == 2);
|
||||
REQUIRE(remainingResources[0] == "res1");
|
||||
REQUIRE(remainingResources[1] == "res4");
|
||||
}
|
||||
}
|
||||
}
|
||||
SECTION("With events") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.fnt", "bitmapFont");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res4", "path/to/file4.png", "audio");
|
||||
ArbitraryResourceWorkerTest worker;
|
||||
|
||||
auto& layout = project.InsertNewLayout("Scene", 0);
|
||||
|
||||
gd::StandardEvent standardEvent;
|
||||
gd::Instruction instruction;
|
||||
instruction.SetType("MyExtension::DoSomethingWithResources");
|
||||
instruction.SetParametersCount(3);
|
||||
instruction.SetParameter(0, "res3");
|
||||
instruction.SetParameter(1, "res1");
|
||||
instruction.SetParameter(2, "res4");
|
||||
standardEvent.GetActions().Insert(instruction);
|
||||
layout.GetEvents().InsertEvent(standardEvent);
|
||||
|
||||
project.ExposeResources(worker);
|
||||
REQUIRE(worker.bitmapFonts.size() == 1);
|
||||
REQUIRE(worker.bitmapFonts[0] == "res3");
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
REQUIRE(worker.audios.size() == 1);
|
||||
REQUIRE(worker.audios[0] == "res4");
|
||||
}
|
||||
}
|
@@ -96,6 +96,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
std::shared_ptr<gd::PlatformExtension>(new gd::PlatformExtension);
|
||||
extension->SetExtensionInformation(
|
||||
"MyExtension", "My testing extension", "", "", "");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomething",
|
||||
"Do something",
|
||||
@@ -106,6 +107,20 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
|
||||
"")
|
||||
.AddParameter("expression", "Parameter 1 (a number)")
|
||||
.SetFunctionName("doSomething");
|
||||
|
||||
extension
|
||||
->AddAction("DoSomethingWithResources",
|
||||
"Do something with resources",
|
||||
"This does something with resources",
|
||||
"Do something with resources please",
|
||||
"",
|
||||
"",
|
||||
"")
|
||||
.AddParameter("bitmapFontResource", "Parameter 1 (a bitmap font resource)")
|
||||
.AddParameter("imageResource", "Parameter 2 (an image resource)")
|
||||
.AddParameter("soundfile", "Parameter 3 (an audio resource)")
|
||||
.SetFunctionName("doSomethingWithResources");
|
||||
|
||||
extension->AddExpression("GetNumber", "Get me a number", "", "", "")
|
||||
.SetFunctionName("getNumber");
|
||||
extension
|
||||
|
@@ -87,42 +87,27 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
}
|
||||
}
|
||||
SECTION("Operator (number)") {
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions1{
|
||||
gd::ExpressionCompletionDescription::ForObject("number", "", 1, 1),
|
||||
gd::ExpressionCompletionDescription::ForExpression("number", "", 1, 1)};
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions2{
|
||||
gd::ExpressionCompletionDescription::ForObject("number", "", 2, 2),
|
||||
gd::ExpressionCompletionDescription::ForExpression("number", "", 2, 2)};
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions3{
|
||||
gd::ExpressionCompletionDescription::ForObject("number", "", 3, 3),
|
||||
gd::ExpressionCompletionDescription::ForExpression("number", "", 3, 3)};
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 1) == expectedCompletions1);
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 2) == expectedCompletions2);
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 3) == expectedCompletions3);
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 1) == expectedEmptyCompletions);
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 2) == expectedEmptyCompletions);
|
||||
REQUIRE(getCompletionsFor("number", "1 + ", 3) == expectedEmptyCompletions);
|
||||
}
|
||||
SECTION("Operator (string)") {
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions3{
|
||||
gd::ExpressionCompletionDescription::ForObject("string", "", 3, 3),
|
||||
gd::ExpressionCompletionDescription::ForExpression("string", "", 3, 3)};
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions4{
|
||||
gd::ExpressionCompletionDescription::ForObject("string", "", 4, 4),
|
||||
gd::ExpressionCompletionDescription::ForExpression("string", "", 4, 4)};
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions5{
|
||||
gd::ExpressionCompletionDescription::ForObject("string", "", 5, 5),
|
||||
gd::ExpressionCompletionDescription::ForExpression("string", "", 5, 5)};
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 3) == expectedCompletions3);
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 4) == expectedCompletions4);
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 5) == expectedCompletions5);
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 3) ==
|
||||
expectedEmptyCompletions);
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 4) ==
|
||||
expectedEmptyCompletions);
|
||||
REQUIRE(getCompletionsFor("string", "\"a\" + ", 5) ==
|
||||
expectedEmptyCompletions);
|
||||
}
|
||||
|
||||
SECTION("Free function") {
|
||||
SECTION("Test 1") {
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Function", 0, 8)};
|
||||
"string", "Function", 0, 8)};
|
||||
std::vector<gd::ExpressionCompletionDescription> expectedExactCompletions{
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Function", 0, 8)
|
||||
"string", "Function", 0, 8)
|
||||
.SetIsExact(true)};
|
||||
REQUIRE(getCompletionsFor("string", "Function(", 0) ==
|
||||
expectedCompletions);
|
||||
@@ -230,17 +215,17 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedObjectCompletions{
|
||||
gd::ExpressionCompletionDescription::ForObject(
|
||||
"unknown", "MyObject", 0, 8)};
|
||||
"string", "MyObject", 0, 8)};
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedBehaviorOrFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehavior(
|
||||
"Func", 9, 13, "MyObject"),
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Func", 9, 13, "MyObject")};
|
||||
"string", "Func", 9, 13, "MyObject")};
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedExactFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Func", 9, 13, "MyObject")
|
||||
"string", "Func", 9, 13, "MyObject")
|
||||
.SetIsExact(true)};
|
||||
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 0) ==
|
||||
expectedObjectCompletions);
|
||||
@@ -329,7 +314,7 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedObjectCompletions{
|
||||
gd::ExpressionCompletionDescription::ForObject(
|
||||
"unknown", "MyObject", 0, 8)};
|
||||
"string", "MyObject", 0, 8)};
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedBehaviorCompletions{
|
||||
gd::ExpressionCompletionDescription::ForBehavior(
|
||||
@@ -337,11 +322,11 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Func", 21, 25, "MyObject", "MyBehavior")};
|
||||
"string", "Func", 21, 25, "MyObject", "MyBehavior")};
|
||||
std::vector<gd::ExpressionCompletionDescription>
|
||||
expectedExactFunctionCompletions{
|
||||
gd::ExpressionCompletionDescription::ForExpression(
|
||||
"unknown", "Func", 21, 25, "MyObject", "MyBehavior")
|
||||
"string", "Func", 21, 25, "MyObject", "MyBehavior")
|
||||
.SetIsExact(true)};
|
||||
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 0) ==
|
||||
expectedObjectCompletions);
|
||||
|
@@ -971,6 +971,35 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
REQUIRE(objectFunctionName.objectFunctionOrBehaviorName == "");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object function name of type string with parentheses") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionCall.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionCall.functionName == "");
|
||||
REQUIRE(objectFunctionCall.type == "string");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object function name of type number with parentheses") {
|
||||
auto node = parser.ParseExpression("number", "MyObject.()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionCall.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionCall.functionName == "");
|
||||
REQUIRE(objectFunctionCall.type == "number");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Unfinished object function name of type number|string with "
|
||||
"parentheses") {
|
||||
auto node = parser.ParseExpression("number|string", "MyObject.()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionCall.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionCall.functionName == "");
|
||||
REQUIRE(objectFunctionCall.type == "number|string");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object behavior name") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::");
|
||||
REQUIRE(node != nullptr);
|
||||
@@ -981,6 +1010,67 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
|
||||
REQUIRE(objectFunctionName.behaviorFunctionName == "");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object behavior name of type string with parentheses") {
|
||||
auto node = parser.ParseExpression("string", "MyObject.MyBehavior::()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.behaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.functionName == "");
|
||||
REQUIRE(objectFunctionName.type == "string");
|
||||
}
|
||||
|
||||
SECTION("Unfinished object behavior name of type number with parentheses") {
|
||||
auto node = parser.ParseExpression("number", "MyObject.MyBehavior::()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.behaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.functionName == "");
|
||||
REQUIRE(objectFunctionName.type == "number");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Unfinished object behavior name of type number|string with "
|
||||
"parentheses") {
|
||||
auto node =
|
||||
parser.ParseExpression("number|string", "MyObject.MyBehavior::()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &objectFunctionName = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(objectFunctionName.objectName == "MyObject");
|
||||
REQUIRE(objectFunctionName.behaviorName == "MyBehavior");
|
||||
REQUIRE(objectFunctionName.functionName == "");
|
||||
REQUIRE(objectFunctionName.type == "number|string");
|
||||
}
|
||||
|
||||
SECTION("Unfinished free function name of type string with parentheses") {
|
||||
auto node = parser.ParseExpression("string", "fun()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &freeFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(freeFunctionCall.objectName == "");
|
||||
REQUIRE(freeFunctionCall.functionName == "fun");
|
||||
REQUIRE(freeFunctionCall.type == "string");
|
||||
}
|
||||
|
||||
SECTION("Unfinished free function name of type number with parentheses") {
|
||||
auto node = parser.ParseExpression("number", "fun()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &freeFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(freeFunctionCall.objectName == "");
|
||||
REQUIRE(freeFunctionCall.functionName == "fun");
|
||||
REQUIRE(freeFunctionCall.type == "number");
|
||||
}
|
||||
|
||||
SECTION(
|
||||
"Unfinished free function name of type number|string with parentheses") {
|
||||
auto node = parser.ParseExpression("number|string", "fun()");
|
||||
REQUIRE(node != nullptr);
|
||||
auto &freeFunctionCall = dynamic_cast<gd::FunctionCallNode &>(*node);
|
||||
REQUIRE(freeFunctionCall.objectName == "");
|
||||
REQUIRE(freeFunctionCall.functionName == "fun");
|
||||
REQUIRE(freeFunctionCall.type == "number|string");
|
||||
}
|
||||
|
||||
SECTION("Invalid function calls") {
|
||||
{
|
||||
auto node = parser.ParseExpression("number", "Idontexist(12)");
|
||||
|
77
Core/tests/InstructionsParameterMover.cpp
Normal file
77
Core/tests/InstructionsParameterMover.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
/**
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include "GDCore/IDE/Events/InstructionsParameterMover.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "DummyPlatform.h"
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Events/Builtin/StandardEvent.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/Extensions/Platform.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/IDE/WholeProjectRefactorer.h"
|
||||
#include "GDCore/Project/Layout.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("InstructionsParameterMover", "[common][events]") {
|
||||
gd::Platform platform;
|
||||
gd::Project project;
|
||||
SetupProjectWithDummyPlatform(project, platform);
|
||||
|
||||
auto& layout = project.InsertNewLayout("Scene", 0);
|
||||
|
||||
gd::StandardEvent standardEvent;
|
||||
gd::Instruction instruction;
|
||||
instruction.SetType("MyExtension::DoSomething");
|
||||
instruction.SetParametersCount(3);
|
||||
instruction.SetParameter(0, "Param1");
|
||||
instruction.SetParameter(1, "Param2");
|
||||
instruction.SetParameter(2, "Param3");
|
||||
standardEvent.GetActions().Insert(instruction);
|
||||
layout.GetEvents().InsertEvent(standardEvent);
|
||||
|
||||
gd::Instruction& insertedInstruction =
|
||||
dynamic_cast<gd::StandardEvent&>(layout.GetEvents().GetEvent(0))
|
||||
.GetActions()
|
||||
.Get(0);
|
||||
|
||||
SECTION("Move a parameter from one valid index to another") {
|
||||
gd::InstructionsParameterMover mover(
|
||||
project, "MyExtension::DoSomething", 0, 2);
|
||||
|
||||
gd::WholeProjectRefactorer::ExposeProjectEvents(project, mover);
|
||||
REQUIRE(insertedInstruction.GetParameter(0).GetPlainString() == "Param2");
|
||||
REQUIRE(insertedInstruction.GetParameter(1).GetPlainString() == "Param3");
|
||||
REQUIRE(insertedInstruction.GetParameter(2).GetPlainString() == "Param1");
|
||||
}
|
||||
SECTION("Move a parameter to an out of bound new index") {
|
||||
gd::InstructionsParameterMover mover(
|
||||
project, "MyExtension::DoSomething", 0, 99);
|
||||
|
||||
gd::WholeProjectRefactorer::ExposeProjectEvents(project, mover);
|
||||
REQUIRE(insertedInstruction.GetParameter(0).GetPlainString() == "Param2");
|
||||
REQUIRE(insertedInstruction.GetParameter(1).GetPlainString() == "Param3");
|
||||
REQUIRE(insertedInstruction.GetParameter(2).GetPlainString() == "Param1");
|
||||
}
|
||||
SECTION("Don't move a parameter if out of bound old index") {
|
||||
gd::InstructionsParameterMover mover(
|
||||
project, "MyExtension::DoSomething", 99, 2);
|
||||
|
||||
gd::WholeProjectRefactorer::ExposeProjectEvents(project, mover);
|
||||
REQUIRE(insertedInstruction.GetParameter(0).GetPlainString() == "Param1");
|
||||
REQUIRE(insertedInstruction.GetParameter(1).GetPlainString() == "Param2");
|
||||
REQUIRE(insertedInstruction.GetParameter(2).GetPlainString() == "Param3");
|
||||
}
|
||||
}
|
@@ -7,27 +7,13 @@
|
||||
* @file Tests covering common features of GDevelop Core.
|
||||
*/
|
||||
#include <string>
|
||||
|
||||
#include "GDCore/CommonTools.h"
|
||||
#include "GDCore/Extensions/Builtin/SpriteExtension/SpriteObject.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/IDE/Project/ProjectResourcesAdder.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
#include "GDCore/Serialization/Serializer.h"
|
||||
#include "GDCore/Tools/SystemStats.h"
|
||||
#include "GDCore/Tools/VersionWrapper.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
class ArbitraryResourceWorkerTest : public gd::ArbitraryResourceWorker {
|
||||
public:
|
||||
virtual void ExposeFile(gd::String& file) { files.push_back(file); };
|
||||
virtual void ExposeImage(gd::String& imageName) {
|
||||
images.push_back(imageName);
|
||||
};
|
||||
|
||||
std::vector<gd::String> files;
|
||||
std::vector<gd::String> images;
|
||||
};
|
||||
|
||||
TEST_CASE("Resources", "[common][resources]") {
|
||||
SECTION("Basics") {
|
||||
gd::ImageResource image;
|
||||
@@ -46,58 +32,4 @@ TEST_CASE("Resources", "[common][resources]") {
|
||||
image.SetFile("Lots\\\\Of\\\\\\..\\Backslashs");
|
||||
REQUIRE(image.GetFile() == "Lots//Of///../Backslashs");
|
||||
}
|
||||
SECTION("ArbitraryResourceWorker") {
|
||||
gd::Project project;
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res1", "path/to/file1.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res2", "path/to/file2.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res3", "path/to/file3.png", "image");
|
||||
project.GetResourcesManager().AddResource(
|
||||
"res4", "path/to/file4.png", "audio");
|
||||
ArbitraryResourceWorkerTest worker;
|
||||
|
||||
project.ExposeResources(worker);
|
||||
REQUIRE(worker.files.size() == 4);
|
||||
REQUIRE(std::find(worker.files.begin(),
|
||||
worker.files.end(),
|
||||
"path/to/file2.png") != worker.files.end());
|
||||
REQUIRE(std::find(worker.files.begin(),
|
||||
worker.files.end(),
|
||||
"path/to/file4.png") != worker.files.end());
|
||||
|
||||
SECTION("Object using a resource") {
|
||||
gd::SpriteObject obj("myObject");
|
||||
|
||||
gd::Animation anim;
|
||||
gd::Sprite sprite;
|
||||
sprite.SetImageName("res1");
|
||||
anim.SetDirectionsCount(1);
|
||||
anim.GetDirection(0).AddSprite(sprite);
|
||||
obj.AddAnimation(anim);
|
||||
project.InsertObject(obj, 0);
|
||||
|
||||
worker.files.clear();
|
||||
worker.images.clear();
|
||||
project.ExposeResources(worker);
|
||||
REQUIRE(worker.files.size() == 4);
|
||||
REQUIRE(worker.images.size() == 1);
|
||||
REQUIRE(worker.images[0] == "res1");
|
||||
|
||||
SECTION("ProjectResourcesAdder") {
|
||||
std::vector<gd::String> uselessResources =
|
||||
gd::ProjectResourcesAdder::GetAllUseless(project, "image");
|
||||
|
||||
REQUIRE(uselessResources.size() == 2);
|
||||
|
||||
gd::ProjectResourcesAdder::RemoveAllUseless(project, "image");
|
||||
std::vector<gd::String> remainingResources =
|
||||
project.GetResourcesManager().GetAllResourceNames();
|
||||
REQUIRE(remainingResources.size() == 2);
|
||||
REQUIRE(remainingResources[0] == "res1");
|
||||
REQUIRE(remainingResources[1] == "res4");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@ namespace gdjs {
|
||||
declare var admob: any;
|
||||
|
||||
export namespace adMob {
|
||||
const logger = new gdjs.Logger('AdMob');
|
||||
|
||||
export enum AdSizeType {
|
||||
BANNER,
|
||||
LARGE_BANNER,
|
||||
@@ -127,13 +129,13 @@ namespace gdjs {
|
||||
() => {
|
||||
bannerShowing = true;
|
||||
bannerLoading = false;
|
||||
console.info('AdMob banner successfully shown.');
|
||||
logger.info('AdMob banner successfully shown.');
|
||||
},
|
||||
(error) => {
|
||||
bannerShowing = false;
|
||||
bannerLoading = false;
|
||||
bannerErrored = true;
|
||||
console.error('Error while showing an AdMob banner:', error);
|
||||
logger.error('Error while showing an AdMob banner:', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -190,14 +192,14 @@ namespace gdjs {
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
console.info('AdMob interstitial successfully loaded.');
|
||||
logger.info('AdMob interstitial successfully loaded.');
|
||||
if (displayWhenLoaded) showInterstitial();
|
||||
},
|
||||
(error) => {
|
||||
interstitialLoading = false;
|
||||
interstitialReady = false;
|
||||
interstitialErrored = true;
|
||||
console.error('Error while loading a interstitial:', error);
|
||||
logger.error('Error while loading a interstitial:', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -216,7 +218,7 @@ namespace gdjs {
|
||||
(error) => {
|
||||
interstitialShowing = false;
|
||||
interstitialErrored = true;
|
||||
console.error('Error while trying to show an interstitial:', error);
|
||||
logger.error('Error while trying to show an interstitial:', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -270,7 +272,7 @@ namespace gdjs {
|
||||
})
|
||||
.then(
|
||||
() => {
|
||||
console.info('AdMob reward video successfully loaded.');
|
||||
logger.info('AdMob reward video successfully loaded.');
|
||||
|
||||
if (displayWhenLoaded) showVideo();
|
||||
},
|
||||
@@ -278,7 +280,7 @@ namespace gdjs {
|
||||
videoLoading = false;
|
||||
videoReady = false;
|
||||
videoErrored = true;
|
||||
console.error('Error while loading a reward video:', error);
|
||||
logger.error('Error while loading a reward video:', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -298,7 +300,7 @@ namespace gdjs {
|
||||
(error) => {
|
||||
videoShowing = false;
|
||||
videoErrored = true;
|
||||
console.error('Error while trying to show a reward video:', error);
|
||||
logger.error('Error while trying to show a reward video:', error);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@@ -256,11 +256,7 @@ module.exports = {
|
||||
.addAction(
|
||||
'SetBitmapFontAndTextureAtlasResourceName',
|
||||
_('Bitmap files resources'),
|
||||
_('Change the Bitmap Font and/or the atlas image used by the object.') +
|
||||
' ' +
|
||||
_(
|
||||
'The resource name can be found in: `Project Manager > Game settings > Resources`.'
|
||||
),
|
||||
_('Change the Bitmap Font and/or the atlas image used by the object.'),
|
||||
_(
|
||||
'Set the bitmap font of _PARAM0_ to _PARAM1_ and the atlas to _PARAM2_'
|
||||
),
|
||||
@@ -269,7 +265,7 @@ module.exports = {
|
||||
'res/actions/font.png'
|
||||
)
|
||||
.addParameter('object', _('Bitmap text'), 'BitmapTextObject', false)
|
||||
.addParameter('bitmapFont', _('Bitmap font resource name'), '', false)
|
||||
.addParameter('bitmapFontResource', _('Bitmap font resource name'), '', false)
|
||||
.setParameterLongDescription(
|
||||
'The resource name of the font file, without quotes.'
|
||||
)
|
||||
@@ -658,6 +654,11 @@ module.exports = {
|
||||
// Release the old font (if it was installed).
|
||||
releaseBitmapFont(this._pixiObject.fontName);
|
||||
|
||||
// Temporarily go back to the default font, as the PIXI.BitmapText
|
||||
// object does not support being displayed with a font not installed at all.
|
||||
// It will be replaced as soon as the proper font is loaded.
|
||||
this._pixiObject.fontName = getDefaultBitmapFont().font;
|
||||
|
||||
this._currentBitmapFontResourceName = bitmapFontResourceName;
|
||||
this._currentTextureAtlasResourceName = textureAtlasResourceName;
|
||||
obtainBitmapFont(
|
||||
|
@@ -83,6 +83,30 @@ module.exports = {
|
||||
.setIncludeFile('Extensions/DebuggerTools/debuggertools.js')
|
||||
.setFunctionName('gdjs.evtTools.debuggerTools.enableDebugDraw');
|
||||
|
||||
extension
|
||||
.addAction(
|
||||
'ConsoleLog',
|
||||
_('Log a message to the console'),
|
||||
_("Logs a message to the debugger's console."),
|
||||
_(
|
||||
'Log message _PARAM0_ of type _PARAM1_ to the console in group _PARAM2_'
|
||||
),
|
||||
_('Debugger Tools'),
|
||||
'res/actions/bug32.png',
|
||||
'res/actions/bug32.png'
|
||||
)
|
||||
.addParameter('string', 'Message to log', '', false)
|
||||
.addParameter(
|
||||
'stringWithSelector',
|
||||
'Message type',
|
||||
'["info", "warning", "error"]',
|
||||
true
|
||||
)
|
||||
.addParameter('string', 'Group of messages', '', true)
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile('Extensions/DebuggerTools/debuggertools.js')
|
||||
.setFunctionName('gdjs.evtTools.debuggerTools.log');
|
||||
|
||||
return extension;
|
||||
},
|
||||
runExtensionSanityTests: function (
|
||||
|
@@ -13,6 +13,20 @@ namespace gdjs {
|
||||
runtimeScene.getGame().pause(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Logs a message to the console.
|
||||
* @param message - The message to log.
|
||||
* @param type - The type of log (info, warning or error).
|
||||
* @param group - The group of messages it belongs to.
|
||||
*/
|
||||
export const log = function (
|
||||
message: string,
|
||||
type: 'info' | 'warning' | 'error',
|
||||
group: string
|
||||
) {
|
||||
gdjs.Logger.getLoggerOutput().log(group, message, type, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable or disable the debug draw.
|
||||
* @param runtimeScene - The current scene.
|
||||
|
@@ -62,7 +62,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/orientation_alpha24.png",
|
||||
"JsPlatform/Extensions/orientation_alpha32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -82,7 +82,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/orientation_beta24.png",
|
||||
"JsPlatform/Extensions/orientation_beta32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -102,7 +102,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/orientation_gamma24.png",
|
||||
"JsPlatform/Extensions/orientation_gamma32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -228,7 +228,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_rotation_alpha24.png",
|
||||
"JsPlatform/Extensions/motion_rotation_alpha32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -248,7 +248,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_rotation_beta24.png",
|
||||
"JsPlatform/Extensions/motion_rotation_beta32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -268,7 +268,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_rotation_gamma24.png",
|
||||
"JsPlatform/Extensions/motion_rotation_gamma32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -288,7 +288,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_acceleration_x24.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_x32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -308,7 +308,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_acceleration_y24.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_y32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
@@ -328,7 +328,7 @@ module.exports = {
|
||||
"JsPlatform/Extensions/motion_acceleration_z24.png",
|
||||
"JsPlatform/Extensions/motion_acceleration_z32.png"
|
||||
)
|
||||
.addParameter("relationalOperator", _("Sign of the test"))
|
||||
.addParameter("relationalOperator", _("Sign of the test"), "number")
|
||||
.addParameter("expression", _("Value (m/s²)"))
|
||||
.getCodeExtraInformation()
|
||||
.setIncludeFile(
|
||||
|
@@ -541,7 +541,7 @@ module.exports = {
|
||||
'IsDialogueLineType',
|
||||
_('Dialogue line type'),
|
||||
_(
|
||||
'Check if the the current dialogue line line is one of the three existing types. Use this to set what logic is executed for each type.\nThe three types are as follows:\n- text: when displaying dialogue text.\n- options: when displaying [[branching/options]] for dialogue choices.\n-command: when <<commands>> are triggered by the dialogue data.'
|
||||
'Check if the current dialogue line line is one of the three existing types. Use this to set what logic is executed for each type.\nThe three types are as follows:\n- text: when displaying dialogue text.\n- options: when displaying [[branching/options]] for dialogue choices.\n-command: when <<commands>> are triggered by the dialogue data.'
|
||||
),
|
||||
_('The dialogue line is _PARAM0_'),
|
||||
_('Dialogue Tree (experimental)'),
|
||||
|
@@ -1,6 +1,8 @@
|
||||
// @ts-nocheck - Weird usage of `this` in this file. Should be refactored.
|
||||
|
||||
namespace gdjs {
|
||||
const logger = new gdjs.Logger('Dialogue tree');
|
||||
|
||||
gdjs.dialogueTree = {};
|
||||
gdjs.dialogueTree.runner = new bondage.Runner();
|
||||
|
||||
@@ -21,7 +23,7 @@ namespace gdjs {
|
||||
gdjs.dialogueTree.startFrom(startDialogueNode);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
logger.error('Error while loading from scene variable: ', e);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,10 +44,7 @@ namespace gdjs {
|
||||
.getJsonManager()
|
||||
.loadJson(jsonResourceName, function (error, content) {
|
||||
if (error) {
|
||||
console.error(
|
||||
'An error happened while loading JSON resource:',
|
||||
error
|
||||
);
|
||||
logger.error('An error happened while loading JSON resource:', error);
|
||||
} else {
|
||||
if (!content) {
|
||||
return;
|
||||
@@ -54,7 +53,7 @@ namespace gdjs {
|
||||
try {
|
||||
gdjs.dialogueTree.runner.load(gdjs.dialogueTree.yarnData);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
logger.error(
|
||||
'An error happened while loading parsing the dialogue tree data:',
|
||||
error
|
||||
);
|
||||
@@ -155,7 +154,7 @@ namespace gdjs {
|
||||
this.clipTextEnd >= this.dialogueText.length
|
||||
) {
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.warn(
|
||||
logger.warn(
|
||||
'Scroll completed:',
|
||||
this.clipTextEnd,
|
||||
'/',
|
||||
@@ -244,7 +243,7 @@ namespace gdjs {
|
||||
gdjs.dialogueTree.pauseScrolling = false;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('CMD:', call);
|
||||
logger.info('CMD:', call);
|
||||
}
|
||||
}, parseInt(call.params[1], 10));
|
||||
}
|
||||
@@ -252,7 +251,7 @@ namespace gdjs {
|
||||
gdjs.dialogueTree.commandParameters = call.params;
|
||||
commandCalls.splice(index, 1);
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('CMD:', call);
|
||||
logger.info('CMD:', call);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -366,7 +365,7 @@ namespace gdjs {
|
||||
this.dialogueData = this.dialogue.next().value;
|
||||
gdjs.dialogueTree.goToNextDialogueLine();
|
||||
} catch (error) {
|
||||
console.error(
|
||||
logger.error(
|
||||
`An error happened when trying to access the dialogue branch!`,
|
||||
error
|
||||
);
|
||||
@@ -562,7 +561,7 @@ namespace gdjs {
|
||||
this.selectedOption = -1;
|
||||
this.selectedOptionUpdated = false;
|
||||
if (gdjs.dialogueTree.getVariable('debug')) {
|
||||
console.info('parsing:', this.dialogueData);
|
||||
logger.info('Parsing:', this.dialogueData);
|
||||
}
|
||||
if (!this.dialogueData) {
|
||||
gdjs.dialogueTree.stopRunningDialogue();
|
||||
@@ -739,7 +738,7 @@ namespace gdjs {
|
||||
* @param key The name of the variable you want to get the value of
|
||||
*/
|
||||
gdjs.dialogueTree.getVariable = function (key: string) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
if (this.runner.variables && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key);
|
||||
}
|
||||
return '';
|
||||
@@ -754,7 +753,7 @@ namespace gdjs {
|
||||
key: string,
|
||||
value: string | boolean | number
|
||||
) {
|
||||
if (this.dialogueIsRunning && key in this.runner.variables.data) {
|
||||
if (this.runner.variables && key in this.runner.variables.data) {
|
||||
return this.runner.variables.get(key) === value;
|
||||
}
|
||||
return false;
|
||||
@@ -797,7 +796,7 @@ namespace gdjs {
|
||||
gdjs.dialogueTree.loadState = function (inputVariable: gdjs.Variable) {
|
||||
const loadedState = inputVariable.toJSObject();
|
||||
if (!loadedState) {
|
||||
console.error('Load state variable is empty:', inputVariable);
|
||||
logger.error('Load state variable is empty:', inputVariable);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -808,7 +807,7 @@ namespace gdjs {
|
||||
gdjs.dialogueTree.runner.variables.set(key, value);
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Failed to load state from variable:', inputVariable, e);
|
||||
logger.error('Failed to load state from variable:', inputVariable, e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
GDevelop - Draggable Behavior Extension
|
||||
Copyright (c) 2013-2016 Florian Rival (Florian.Rival@gmail.com)
|
||||
Copyright (c) 2013-2021 Florian Rival (Florian.Rival@gmail.com)
|
||||
*/
|
||||
|
||||
namespace gdjs {
|
||||
@@ -9,11 +9,11 @@ namespace gdjs {
|
||||
* moved using the mouse.
|
||||
*/
|
||||
export class DraggableRuntimeBehavior extends gdjs.RuntimeBehavior {
|
||||
_dragged: boolean = false;
|
||||
_touchId: any = null;
|
||||
_mouse: boolean = false;
|
||||
_xOffset: number = 0;
|
||||
_yOffset: number = 0;
|
||||
/**
|
||||
* The manager that currently handles the dragging of the owner if any.
|
||||
* When the owner is being dragged, no other manager can start dragging it.
|
||||
*/
|
||||
_draggedByDraggableManager: DraggableManager | null = null;
|
||||
|
||||
constructor(runtimeScene, behaviorData, owner) {
|
||||
super(runtimeScene, behaviorData, owner);
|
||||
@@ -33,59 +33,47 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
_endDrag() {
|
||||
if (this._dragged && this._mouse) {
|
||||
DraggableRuntimeBehavior.mouseDraggingSomething = false;
|
||||
if (this._draggedByDraggableManager) {
|
||||
this._draggedByDraggableManager.endDrag();
|
||||
}
|
||||
if (this._dragged && this._touchId !== null) {
|
||||
DraggableRuntimeBehavior.touchDraggingSomething[this._touchId] = false;
|
||||
}
|
||||
this._dragged = false;
|
||||
this._mouse = false;
|
||||
this._touchId = null;
|
||||
this._draggedByDraggableManager = null;
|
||||
}
|
||||
|
||||
_dismissDrag() {
|
||||
this._draggedByDraggableManager = null;
|
||||
}
|
||||
|
||||
_tryBeginDrag(runtimeScene) {
|
||||
if (this._dragged) {
|
||||
if (this._draggedByDraggableManager) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
|
||||
//Try mouse
|
||||
const mouseDraggableManager = DraggableManager.getMouseManager(
|
||||
runtimeScene
|
||||
);
|
||||
if (
|
||||
inputManager.isMouseButtonPressed(0) &&
|
||||
!DraggableRuntimeBehavior.leftPressedLastFrame &&
|
||||
!DraggableRuntimeBehavior.mouseDraggingSomething
|
||||
!mouseDraggableManager.isDragging(this)
|
||||
) {
|
||||
const mousePos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(inputManager.getMouseX(), inputManager.getMouseY());
|
||||
if (this.owner.insideObject(mousePos[0], mousePos[1])) {
|
||||
this._dragged = true;
|
||||
this._mouse = true;
|
||||
this._xOffset = mousePos[0] - this.owner.getX();
|
||||
this._yOffset = mousePos[1] - this.owner.getY();
|
||||
DraggableRuntimeBehavior.mouseDraggingSomething = true;
|
||||
if (mouseDraggableManager.tryAndTakeDragging(runtimeScene, this)) {
|
||||
this._draggedByDraggableManager = mouseDraggableManager;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
//Try touches
|
||||
const touchIds = inputManager.getStartedTouchIdentifiers();
|
||||
for (let i = 0; i < touchIds.length; ++i) {
|
||||
if (DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]]) {
|
||||
const touchDraggableManager = DraggableManager.getTouchManager(
|
||||
runtimeScene,
|
||||
touchIds[i]
|
||||
);
|
||||
if (touchDraggableManager.isDragging(this)) {
|
||||
continue;
|
||||
}
|
||||
const touchPos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(
|
||||
inputManager.getTouchX(touchIds[i]),
|
||||
inputManager.getTouchY(touchIds[i])
|
||||
);
|
||||
if (this.owner.insideObject(touchPos[0], touchPos[1])) {
|
||||
this._dragged = true;
|
||||
this._touchId = touchIds[i];
|
||||
this._xOffset = touchPos[0] - this.owner.getX();
|
||||
this._yOffset = touchPos[1] - this.owner.getY();
|
||||
DraggableRuntimeBehavior.touchDraggingSomething[touchIds[i]] = true;
|
||||
if (touchDraggableManager.tryAndTakeDragging(runtimeScene, this)) {
|
||||
this._draggedByDraggableManager = touchDraggableManager;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -94,45 +82,17 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
_shouldEndDrag(runtimeScene) {
|
||||
if (!this._dragged) {
|
||||
if (!this._draggedByDraggableManager) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
if (this._mouse) {
|
||||
return !inputManager.isMouseButtonPressed(0);
|
||||
} else {
|
||||
if (this._touchId !== null) {
|
||||
return (
|
||||
inputManager.getAllTouchIdentifiers().indexOf(this._touchId) === -1
|
||||
);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return this._draggedByDraggableManager.shouldEndDrag(runtimeScene, this);
|
||||
}
|
||||
|
||||
_updateObjectPosition(runtimeScene) {
|
||||
if (!this._dragged) {
|
||||
if (!this._draggedByDraggableManager) {
|
||||
return false;
|
||||
}
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
if (this._mouse) {
|
||||
const mousePos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(inputManager.getMouseX(), inputManager.getMouseY());
|
||||
this.owner.setX(mousePos[0] - this._xOffset);
|
||||
this.owner.setY(mousePos[1] - this._yOffset);
|
||||
} else {
|
||||
if (this._touchId !== null) {
|
||||
const touchPos = runtimeScene
|
||||
.getLayer(this.owner.getLayer())
|
||||
.convertCoords(
|
||||
inputManager.getTouchX(this._touchId),
|
||||
inputManager.getTouchY(this._touchId)
|
||||
);
|
||||
this.owner.setX(touchPos[0] - this._xOffset);
|
||||
this.owner.setY(touchPos[1] - this._yOffset);
|
||||
}
|
||||
}
|
||||
this._draggedByDraggableManager.updateObjectPosition(runtimeScene, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -145,25 +105,214 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
doStepPostEvents(runtimeScene) {
|
||||
DraggableRuntimeBehavior.leftPressedLastFrame = runtimeScene
|
||||
const mouseDraggableManager = DraggableManager.getMouseManager(
|
||||
runtimeScene
|
||||
);
|
||||
mouseDraggableManager.leftPressedLastFrame = runtimeScene
|
||||
.getGame()
|
||||
.getInputManager()
|
||||
.isMouseButtonPressed(0);
|
||||
}
|
||||
|
||||
isDragged(runtimeScene): boolean {
|
||||
return this._dragged;
|
||||
return !!this._draggedByDraggableManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the dragging
|
||||
*/
|
||||
abstract class DraggableManager {
|
||||
/**
|
||||
* The object has left its original position.
|
||||
* When true, the search for the best object to drag has ended.
|
||||
*/
|
||||
protected _draggingSomething = false;
|
||||
/**
|
||||
* The behavior of the object that is being dragged and that is the best one (i.e: highest Z order) found.
|
||||
*/
|
||||
protected _draggableBehavior: gdjs.DraggableRuntimeBehavior | null = null;
|
||||
protected _xOffset: number = 0;
|
||||
protected _yOffset: number = 0;
|
||||
|
||||
constructor(runtimeScene: gdjs.RuntimeScene) {}
|
||||
|
||||
/**
|
||||
* Get the platforms manager of a scene.
|
||||
*/
|
||||
static getMouseManager(
|
||||
runtimeScene: gdjs.RuntimeScene
|
||||
): MouseDraggableManager {
|
||||
// @ts-ignore
|
||||
if (!runtimeScene.mouseDraggableManager) {
|
||||
//Create the shared manager if necessary.
|
||||
// @ts-ignore
|
||||
runtimeScene.mouseDraggableManager = new MouseDraggableManager(
|
||||
runtimeScene
|
||||
);
|
||||
}
|
||||
// @ts-ignore
|
||||
return runtimeScene.mouseDraggableManager;
|
||||
}
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged.
|
||||
static mouseDraggingSomething = false;
|
||||
/**
|
||||
* Get the platforms manager of a scene.
|
||||
*/
|
||||
static getTouchManager(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
touchId: integer
|
||||
): DraggableManager {
|
||||
// @ts-ignore
|
||||
if (!runtimeScene.touchDraggableManagers) {
|
||||
//Create the shared manager if necessary.
|
||||
// @ts-ignore
|
||||
runtimeScene.touchDraggableManagers = [];
|
||||
}
|
||||
// @ts-ignore
|
||||
if (!runtimeScene.touchDraggableManagers[touchId]) {
|
||||
//Create the shared manager if necessary.
|
||||
// @ts-ignore
|
||||
runtimeScene.touchDraggableManagers[
|
||||
touchId
|
||||
] = new TouchDraggableManager(runtimeScene, touchId);
|
||||
}
|
||||
// @ts-ignore
|
||||
return runtimeScene.touchDraggableManagers[touchId];
|
||||
}
|
||||
|
||||
//Static property used to avoid start dragging an object while another is dragged by the same touch.
|
||||
static touchDraggingSomething: Array<boolean> = [];
|
||||
tryAndTakeDragging(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
) {
|
||||
if (
|
||||
this._draggableBehavior &&
|
||||
draggableRuntimeBehavior.owner.getZOrder() <=
|
||||
this._draggableBehavior.owner.getZOrder()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const position = this.getPosition(runtimeScene, draggableRuntimeBehavior);
|
||||
if (
|
||||
!draggableRuntimeBehavior.owner.insideObject(position[0], position[1])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this._draggableBehavior) {
|
||||
// The previous best object to drag will not be dragged.
|
||||
this._draggableBehavior._dismissDrag();
|
||||
}
|
||||
this._draggableBehavior = draggableRuntimeBehavior;
|
||||
this._xOffset = position[0] - draggableRuntimeBehavior.owner.getX();
|
||||
this._yOffset = position[1] - draggableRuntimeBehavior.owner.getY();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Static property used to only start dragging when clicking.
|
||||
static leftPressedLastFrame = false;
|
||||
updateObjectPosition(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
) {
|
||||
const position = this.getPosition(runtimeScene, draggableRuntimeBehavior);
|
||||
if (
|
||||
draggableRuntimeBehavior.owner.getX() != position[0] - this._xOffset ||
|
||||
draggableRuntimeBehavior.owner.getY() != position[1] - this._yOffset
|
||||
) {
|
||||
draggableRuntimeBehavior.owner.setX(position[0] - this._xOffset);
|
||||
draggableRuntimeBehavior.owner.setY(position[1] - this._yOffset);
|
||||
this._draggingSomething = true;
|
||||
}
|
||||
}
|
||||
|
||||
endDrag() {
|
||||
this._draggingSomething = false;
|
||||
this._draggableBehavior = null;
|
||||
}
|
||||
|
||||
abstract isDragging(
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): boolean;
|
||||
abstract shouldEndDrag(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): boolean;
|
||||
abstract getPosition(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): FloatPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the dragging by mouse
|
||||
*/
|
||||
class MouseDraggableManager extends DraggableManager {
|
||||
/** Used to only start dragging when clicking. */
|
||||
leftPressedLastFrame = false;
|
||||
|
||||
constructor(runtimeScene: gdjs.RuntimeScene) {
|
||||
super(runtimeScene);
|
||||
}
|
||||
|
||||
isDragging(draggableRuntimeBehavior: DraggableRuntimeBehavior): boolean {
|
||||
return this.leftPressedLastFrame || this._draggingSomething;
|
||||
}
|
||||
|
||||
getPosition(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): FloatPoint {
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
return runtimeScene
|
||||
.getLayer(draggableRuntimeBehavior.owner.getLayer())
|
||||
.convertCoords(inputManager.getMouseX(), inputManager.getMouseY());
|
||||
}
|
||||
|
||||
shouldEndDrag(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): boolean {
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
return !inputManager.isMouseButtonPressed(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the dragging by touch
|
||||
*/
|
||||
class TouchDraggableManager extends DraggableManager {
|
||||
private _touchId: integer;
|
||||
|
||||
constructor(runtimeScene: gdjs.RuntimeScene, touchId: integer) {
|
||||
super(runtimeScene);
|
||||
this._touchId = touchId;
|
||||
}
|
||||
|
||||
isDragging(draggableRuntimeBehavior: DraggableRuntimeBehavior): boolean {
|
||||
return this._draggingSomething;
|
||||
}
|
||||
|
||||
getPosition(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): FloatPoint {
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
return runtimeScene
|
||||
.getLayer(draggableRuntimeBehavior.owner.getLayer())
|
||||
.convertCoords(
|
||||
inputManager.getTouchX(this._touchId),
|
||||
inputManager.getTouchY(this._touchId)
|
||||
);
|
||||
}
|
||||
|
||||
shouldEndDrag(
|
||||
runtimeScene: gdjs.RuntimeScene,
|
||||
draggableRuntimeBehavior: DraggableRuntimeBehavior
|
||||
): boolean {
|
||||
const inputManager = runtimeScene.getGame().getInputManager();
|
||||
return (
|
||||
inputManager.getAllTouchIdentifiers().indexOf(this._touchId) === -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
gdjs.registerBehavior(
|
||||
'DraggableBehavior::Draggable',
|
||||
gdjs.DraggableRuntimeBehavior
|
||||
|
@@ -51,112 +51,210 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
|
||||
runtimeScene.addObject(object);
|
||||
runtimeScene.addObject(object2);
|
||||
|
||||
it('should handle mouse', function () {
|
||||
object.setPosition(450, 500);
|
||||
describe('(mouse)', function () {
|
||||
it('can drag an object', function () {
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(450, 500);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
// Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(450, 500);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Mouse move with dragging
|
||||
runtimeGame.getInputManager().onMouseMove(600, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
// Mouse move without dragging
|
||||
runtimeGame.getInputManager().onMouseMove(600, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Start dragging again
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
// Start dragging again
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
});
|
||||
|
||||
[false, true].forEach((firstInFront) => {
|
||||
it(`must drag the object in front (${
|
||||
firstInFront ? '1st object' : '2nd object'
|
||||
} in front)`, function () {
|
||||
object.setPosition(450, 500);
|
||||
object2.setPosition(450, 500);
|
||||
if (firstInFront) {
|
||||
object.setZOrder(2);
|
||||
object2.setZOrder(1);
|
||||
} else {
|
||||
object.setZOrder(1);
|
||||
object2.setZOrder(2);
|
||||
}
|
||||
|
||||
// Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(450, 500);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonPressed(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onMouseMove(750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame
|
||||
.getInputManager()
|
||||
.onMouseButtonReleased(gdjs.InputManager.MOUSE_LEFT_BUTTON);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
if (firstInFront) {
|
||||
// The 1st object moved
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object2.getX()).to.be(450);
|
||||
expect(object2.getY()).to.be(500);
|
||||
} else {
|
||||
// The 2nd object moved
|
||||
expect(object.getX()).to.be(450);
|
||||
expect(object.getY()).to.be(500);
|
||||
expect(object2.getX()).to.be(750);
|
||||
expect(object2.getY()).to.be(600);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should handle touches', function () {
|
||||
runtimeGame.getInputManager().touchSimulateMouse(false);
|
||||
object.setPosition(450, 500);
|
||||
describe('(touch)', function () {
|
||||
it('can drag an object', function () {
|
||||
runtimeGame.getInputManager().touchSimulateMouse(false);
|
||||
object.setPosition(450, 500);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 10, 20);
|
||||
runtimeGame.getInputManager().onTouchStart(0, 450, 500);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(0, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(0);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
// Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 10, 20);
|
||||
runtimeGame.getInputManager().onTouchStart(0, 450, 500);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(0, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(0);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Move another unrelated touch
|
||||
runtimeGame.getInputManager().onTouchMove(1, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
// Move another unrelated touch
|
||||
runtimeGame.getInputManager().onTouchMove(1, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
|
||||
//Start drag'n'drop with another touch
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
// Start drag'n'drop with another touch
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 850, 700);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
});
|
||||
it('should handle multitouch', function () {
|
||||
runtimeGame.getInputManager().touchSimulateMouse(false);
|
||||
object.setPosition(450, 500);
|
||||
object2.setPosition(650, 600);
|
||||
expect(object.getX()).to.be(850);
|
||||
expect(object.getY()).to.be(700);
|
||||
});
|
||||
it('can drag 2 objects with multitouch', function () {
|
||||
runtimeGame.getInputManager().touchSimulateMouse(false);
|
||||
object.setPosition(450, 500);
|
||||
object2.setPosition(650, 600);
|
||||
|
||||
//Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(2, 450, 500);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 650, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(2, 750, 700);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 100, 200);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(2);
|
||||
// Drag'n'drop
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(2, 450, 500);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 650, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(2, 750, 700);
|
||||
runtimeGame.getInputManager().onTouchMove(1, 100, 200);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeGame.getInputManager().onTouchEnd(2);
|
||||
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(700);
|
||||
expect(object2.getX()).to.be(100);
|
||||
expect(object2.getY()).to.be(200);
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(700);
|
||||
expect(object2.getX()).to.be(100);
|
||||
expect(object2.getY()).to.be(200);
|
||||
|
||||
// Avoid side effects on the following test cases
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
});
|
||||
|
||||
[false, true].forEach((firstInFront) => {
|
||||
it(`must drag the object in front (${
|
||||
firstInFront ? '1st object' : '2nd object'
|
||||
} in front)`, function () {
|
||||
object.setPosition(450, 500);
|
||||
object2.setPosition(450, 500);
|
||||
if (firstInFront) {
|
||||
object.setZOrder(2);
|
||||
object2.setZOrder(1);
|
||||
} else {
|
||||
object.setZOrder(1);
|
||||
object2.setZOrder(2);
|
||||
}
|
||||
|
||||
// Drag'n'drop
|
||||
runtimeGame.getInputManager().touchSimulateMouse(false);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onTouchStart(1, 10, 20);
|
||||
runtimeGame.getInputManager().onTouchStart(0, 450, 500);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchMove(0, 750, 600);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
runtimeGame.getInputManager().onTouchEnd(0);
|
||||
runtimeGame.getInputManager().onTouchEnd(1);
|
||||
runtimeScene.renderAndStep(1000 / 60);
|
||||
runtimeGame.getInputManager().onFrameEnded();
|
||||
|
||||
if (firstInFront) {
|
||||
// The 1st object moved
|
||||
expect(object.getX()).to.be(750);
|
||||
expect(object.getY()).to.be(600);
|
||||
expect(object2.getX()).to.be(450);
|
||||
expect(object2.getY()).to.be(500);
|
||||
} else {
|
||||
// The 2nd object moved
|
||||
expect(object.getX()).to.be(450);
|
||||
expect(object.getY()).to.be(500);
|
||||
expect(object2.getX()).to.be(750);
|
||||
expect(object2.getY()).to.be(600);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -179,7 +179,8 @@ module.exports = {
|
||||
.setValue(
|
||||
behaviorContent.getBoolAttribute('property2') ? 'true' : 'false'
|
||||
)
|
||||
.setType('Boolean');
|
||||
.setType('Boolean')
|
||||
.setGroup(_('Look and Feel'));
|
||||
|
||||
return behaviorProperties;
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user