Compare commits

...

83 Commits

Author SHA1 Message Date
github-actions[bot]
44b81f52ea Update translations (#3154)
Co-authored-by: 4ian <4ian@users.noreply.github.com>
2021-10-07 23:06:41 +01:00
Florian Rival
cfdf13538e Automate update of translations (#3153)
* Automatically download and build latest translations from Crowdin at each commit on master, opening a PR with the changes (if any).
2021-10-07 22:58:50 +01:00
Florian Rival
7ee38a50bf Fix translations
Launched npm run compile-translations *after* launching npm run extract-all-translations, so that the English .po file was up-to-date to avoid missing translations in English language.

Don't show in changelog
2021-10-07 19:28:01 +01:00
Florian Rival
e2b8620b83 Fix translations
Don't show in changelog
2021-10-07 17:18:57 +01:00
AlexandreS
7ed8660edc Fix translations - Don't show in changelog 2021-10-07 18:10:18 +02:00
AlexandreS
75cc70368c Bump newIDE version and update translations 2021-10-07 16:38:19 +02:00
AlexandreS
0d3dfe5cf4 Display another user's profile when clicking their badge 2021-10-07 15:57:49 +02:00
Clément Pasteau
e7aa75bcd7 Add possibility to change one's email with confirmation 2021-10-07 13:28:44 +02:00
Clément Pasteau
c5ad127e83 Fix opening up the parameters dialog for object or behaviors expressions having no parameters 2021-10-07 12:28:27 +02:00
Clément Pasteau
acfdebfc0f Prevent calling a user update on every authState change
This fixes a race condition where the fetchUser would be called too early, causing a conflict with the signup function while creating the user in the database.

Do not show in changelog
2021-10-06 12:15:56 +02:00
Leo_Red
d3f8b410b0 Fix wording of "empty game" to "empty project" for consistency (#3136) 2021-10-06 09:04:53 +01:00
Florian Rival
4b7d67ce97 Fix very long object names overflowing or messing up some dialogs in the editor 2021-10-05 23:46:08 +01:00
Florian Rival
46a81ef4be Fix icons aligment and text ellipsis for long resource names in resources selector 2021-10-05 23:46:08 +01:00
Florian Rival
fe2812b8e8 Update caching by service worker of libGD.js/wasm
Don't show in changelog
2021-10-05 23:46:08 +01:00
Clément Pasteau
042cf49b3b Allow user to verify their email (#3132)
Allow users to verify their email
2021-10-05 18:23:29 +02:00
Florian Rival
7cf334ad1c Fix Edit My Profile and Logout buttons not working anymore
This was because of a stale "state" used by React. Fix by using the functional version of setState.

Also fix some Flow types that are not stricts.

Don't show in changelog
2021-10-04 17:47:10 +01:00
AlexandreS
f999bee387 Fix loss of user login between IDE refreshes 2021-10-04 17:09:43 +02:00
AlexandreS
0627d4b865 Show user's bio on My Profile window 2021-10-04 16:12:22 +02:00
Clément Pasteau
92e6a5e67f Improve user autocomplete (#3129)
Prevent saving projects and extensions with non-existing authors
2021-10-04 11:44:40 +02:00
Aurélien Vivet
d980400c2b Add "FontSize" expression for Text objects (#2974) 2021-10-03 15:50:30 +01:00
MechanicalPen
e235694fac Fix conditions comparing Dialogue Tree variables to work even if the dialogue is not running (#3127) 2021-10-03 12:07:33 +01:00
AlexandreS
cdf00d10f1 Give possibility to enter one's bio 2021-10-01 17:07:40 +02:00
Clément Pasteau
218520b836 Update translations (#3124) 2021-10-01 15:56:10 +01:00
Clément Pasteau
3ce71813ba Bump newIDE version (#3122) 2021-10-01 14:03:39 +01:00
Clément Pasteau
90300f895c Validate the username format in the create & edit forms 2021-10-01 14:56:14 +02:00
Florian Rival
9c8aa57fb6 Fix alignment of a background text in profile dialog
Don't show in changelog
2021-10-01 13:50:03 +01:00
Clément Pasteau
84876a1dff Display contributions (examples & extensions) on the user profile (#3110)
Display contributions (examples & extensions) on the user profile
2021-10-01 13:27:03 +02:00
Florian Rival
19ef8742f0 Extract translation sources and upload them to Crowdin at each commit on master (#3114)
* Extract but without upload for other branches

Don't show in changelog
2021-10-01 11:25:36 +01:00
Clément Pasteau
567efafa70 Display error if username is not valid 2021-10-01 11:41:59 +02:00
AlexandreS
c70685ccc7 Improve changelog extraction
Don't show in changelog
2021-09-30 17:10:15 +02:00
ClementPasteau
ec8daa7d8d Change profile.id calls to firebaseUser.id (#3112)
This ensures we don't prevent an action because the profile is
not fetched yet

Don't show in changelog
2021-09-30 12:32:43 +01:00
Florian Rival
0d817f4dae Fix warning
Don't show in changelog
2021-09-30 10:44:14 +01:00
AlexandreS
9dbbaada01 Update translations 2021-09-30 10:10:37 +01:00
AlexandreSi
342a6dc56f Bump newIDE version 2021-09-30 09:24:17 +01:00
Florian Rival
baae910fe8 Remove useless postfixing of the libGD.js/wasm files
Don't show in changelog
2021-09-30 09:06:38 +01:00
Florian Rival
2c6d30b28e Fix warning
Don't show in changelog
2021-09-29 22:49:35 +01:00
AlexandreS
9321f0ec7c Do not open expression parameters dialog if no parameters to configure 2021-09-29 18:23:46 +02:00
AlexandreS
e463f352b7 Add several UI improvements on the IDE 2021-09-29 18:16:47 +02:00
AlexandreS
5e3430aea5 Don't show in changelog - Remove unused #ifdef 2021-09-29 16:26:03 +02:00
AlexandreS
2d899d7c52 Add possibility to start and stop particle emitter 2021-09-29 09:25:03 +02:00
Florian Rival
0b933a569e Fix Bitmap Text objects crashing the editor if the font was renamed in resources 2021-09-24 20:24:06 +01:00
Florian Rival
4904e7e7fb Fix crash at game loading when a resource file was not found 2021-09-24 19:23:55 +01:00
Florian Rival
bfb1b6b15d Fix crash when moving a parameter of a function of an extension (or a custom behavior) after adding it
Fix #3093, fix #2729
2021-09-24 18:12:35 +01:00
ClementPasteau
9364a485cd Fix Folder being set for both Examples and Starters 2021-09-24 17:02:28 +02:00
ClementPasteau
176a2a0b47 Modify calls to Example & Extension with new endpoints
Do not show in changelog
2021-09-24 16:42:28 +02:00
AlexandreS
a10c9362dd Add condition to test if platformer is on a given platform 2021-09-24 14:15:06 +02:00
AlexandreS
3a0f55ee1b Fix windows notifications title 2021-09-24 14:01:54 +02:00
ClementPasteau
0b6bddc5a4 Feature/display authors on examples (#3090)
Display Examples authors on the search list and the details popup
2021-09-24 13:55:18 +02:00
Florian Rival
bf910e0cba Fix Scan for Images/Fonts/Audios in the resources editor wrongly adding resources with files already in other resources
* This could be visible when using the asset store or resources that have been renamed.
2021-09-24 00:09:32 +01:00
Florian Rival
763d8e8175 Fix renaming resources breaking objects or events using it
* Also fix the Bitmap Font field not shown in the parameters of the action to change it.
2021-09-24 00:09:32 +01:00
D8H
135ba2b4df Add expressions for properties of type "color" for custom behaviors (#3086) 2021-09-23 17:39:55 +01:00
ClementPasteau
d4a3722ec8 Fix authorIds being saved in the prop elements of a project (#3084) 2021-09-23 13:01:35 +00:00
ClementPasteau
477e88d4ce Allow entering the authors usernames in the Project properties 2021-09-23 12:46:31 +02:00
AlexandreS
023ed8f7b5 Add possibility to zoom in or out on events sheet 2021-09-23 09:37:33 +02:00
Florian Rival
55020a3d15 Fix the deployed storybook not properly loading libGD.js
Don't show in changelog
2021-09-22 17:24:07 +01:00
Florian Rival
552219e48f Add CI to deploy automatically the Storybook for each commit (#3081)
* Useful to quickly test components without having to fetch and build locally a branch.
* Can optionally be deployed to Chromatic if the GitHub action is launched manually.

Only show in developer changelog
2021-09-22 16:58:47 +01:00
ClementPasteau
4dfac41d81 Improve userAutocomplete help text (#3079) 2021-09-22 17:28:52 +02:00
Florian Rival
33deca92e3 Upgrade to Storybook v6 (#3078)
* Add a dropdown to choose the theme in the stories, useful to quickly check a component with all themes.
* Add support for build-storybook (to build a static version of the Storybook). Will be useful to share the storybook on PRs later or even do visual regression testing.

Test: yarn && yarn start, yarn storybook and yarn build-storybook works
Test: npm i && npm start, npm run storybook and npm run build-storybook works
Test: npm run build in newIDE/app works

Only show in developer changelog
2021-09-22 16:10:34 +01:00
AlexandreS
adc7584981 Fix particle emitter unused parameter friction removing it 2021-09-22 13:13:13 +02:00
ClementPasteau
23d5296a52 Feature/authors extension autocomplete (#3073)
Allow authors to be specified when creating an Extension
2021-09-22 12:57:01 +02:00
AlexandreS
2febbf439f Fix some particle emitter actions and conditions 2021-09-22 10:49:47 +02:00
D8H
169a49a246 Optimize Linked Objects actions/conditions, up to 80% faster on games using it extensively with a lot of objects (#3022) 2021-09-21 22:21:16 +01:00
ClementPasteau
c8c4322ece Feature/display extension username (#3056)
Display Authors on Extensions list and details popup
2021-09-20 09:16:14 +02:00
Florian Rival
349703e287 Add a test checking that groups are working correctly inside functions.
Don't show in changelog
2021-09-19 21:43:35 +01:00
D8H
1326ffd3b6 Fix regression in Draggable behavior (objects could be dragged only vertically or horizontally) (#3068)
Don't show in changelog
2021-09-19 12:42:47 +01:00
Florian Rival
baff4d3cb0 Fix long description fields for parameters shown when changing from one function to another after adding a long description
Fix #3067
2021-09-19 10:09:28 +01:00
D8H
b40e2d3fdf Improve Draggable behavior to drag the frontmost object under the cursor/touch (#3066)
* In previous versions, the order was not guaranteed, which could result in a non intuitive result for the player.
2021-09-19 01:36:49 +01:00
Florian Rival
8e6ba3abce Add autocompletion for effect and effect parameter names in actions and conditions (#3060) 2021-09-19 00:36:39 +01:00
D8H
aaebbe47d5 Improve the Draggable behavior to reduce memory usage. (#3064) 2021-09-19 00:25:10 +01:00
AlexandreS
a51003040c Set the default dimensions of a new collision mask to the dimensions of the sprite 2021-09-16 16:48:08 +02:00
Florian Rival
cfce635419 Add automatic addition of extensions, examples and assets commits in the changelog (#3051)
* Also ensure scripts are type checked.

Don't show in changelog
2021-09-16 14:49:03 +01:00
Florian Rival
3d299c5a14 Add back debug task to launch the editor in Chrome (and debug from VSCode) [skip ci]
Don't show in changelog
2021-09-16 09:48:48 +01:00
AlexandreS
f33196dc85 Fix unexpected custom loading screen image removal when removing unused images 2021-09-15 17:06:25 +02:00
AlexandreS
7b2dc2223c Merge pull request #3045 from 4ian/tween-object-color-parameter-type
Add color picker to Add Object Color Tween action 'To color' parameter
2021-09-14 11:48:01 +02:00
AlexandreSi
b37d05f78c Add color picker to Add Object Color Tween action 'To color' parameter 2021-09-14 11:11:52 +02:00
Florian Rival
dcba0b45a6 Remove an ignored (though innocuous) clang warning 2021-09-13 20:29:24 +02:00
Florian Rival
f2ec46ca1e Enable more warnings from Clang when compiling C++ sources (#3042)
Only show in developer changelog
2021-09-13 20:02:03 +02:00
ClementPasteau
5c33e9e8d0 Allow user to enter their username when registering (#3024)
Allow user to add their username when registering
2021-09-13 18:06:16 +02:00
ClementPasteau
fc23517bae Upgrade Pixi.js to 6.1.2 (#3026) 2021-09-13 17:45:27 +02:00
Florian Rival
24c74af79b Fix effects of objects not always working, depending on layers/object position in the list 2021-09-13 13:35:26 +02:00
Florian Rival
2a19ea5182 Bump newIDE version 2021-09-09 12:30:40 +01:00
Florian Rival
705c7af134 Improve typings in the extract changelog script
Don't show in changelog
2021-09-09 12:25:25 +01:00
Florian Rival
028eebefab Fix the regression when using Linked Objects in behaviors by temporarily removing the optimization (#3023) 2021-09-09 12:23:35 +01:00
320 changed files with 27204 additions and 10919 deletions

71
.github/workflows/build-storybook.yml vendored Normal file
View 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 }}

View 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 }}

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

View File

@@ -50,6 +50,7 @@ blocks:
- cd newIDE/app
- npm run postinstall
- npm run flow
- npm run check-script-types
- cd ../..
- name: GDJS typing and documentation generation
commands:

View File

@@ -102,6 +102,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
View File

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

View File

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

View File

@@ -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++) {

View File

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

View File

@@ -43,6 +43,7 @@ struct ExpressionParserLocation {
* \brief A diagnostic that can be attached to a gd::ExpressionNode.
*/
struct ExpressionParserDiagnostic {
virtual ~ExpressionParserDiagnostic() = default;
virtual bool IsError() { return false; }
virtual const gd::String &GetMessage() { return noMessage; }
virtual size_t GetStartPosition() { return 0; }

View File

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

View File

@@ -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"),
@@ -104,7 +103,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
_("Functions"),
"res/function16.png")
.AddParameter("string", "Parameter name");
#endif
}
} // namespace gd

View File

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

View File

@@ -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."),
@@ -1080,7 +1079,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 +1093,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 +1108,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 +1123,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,7 +1136,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"))
.MarkAsSimple();
extension
@@ -1441,7 +1440,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Objects"),
"res/actions/layer.png")
.AddParameter("object", _("Object"));
#endif
}
} // namespace gd

View File

@@ -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();
@@ -567,7 +566,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));
#endif
}
} // namespace gd

View File

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

View File

@@ -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"),
@@ -134,7 +131,6 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
"",
"res/foreach.png",
std::make_shared<gd::GroupEvent>());
#endif
}
} // namespace gd

View File

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

View File

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

View File

@@ -23,7 +23,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/keyboard");
#if defined(GD_IDE_ONLY)
extension
.AddCondition("KeyPressed",
_("Key pressed"),
@@ -100,7 +99,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
_("Keyboard"),
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

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

View File

@@ -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",
@@ -303,7 +302,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
#endif
}
} // namespace gd

View File

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

View File

@@ -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",
@@ -213,7 +212,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.AddParameter("relationalOperator", _("Sign of the test"))
.AddParameter("string", _("Second string expression"))
.MarkAsAdvanced();
#endif
}
} // namespace gd

View File

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

View File

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

View File

@@ -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 "
@@ -536,7 +535,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("objectList", _("Object 1"), "Sprite")
.AddParameter("objectList", _("Object 2"), "Sprite")
.AddCodeOnlyParameter("conditionInverted", "");
#endif
}
} // namespace gd

View File

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

View File

@@ -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
@@ -123,9 +121,7 @@ class GD_CORE_API SpriteObject : public gd::Object {
private:
void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element) override;
#if defined(GD_IDE_ONLY)
void DoSerializeTo(gd::SerializerElement& element) const override;
#endif
mutable std::vector<Animation> animations;
bool updateIfNotVisible; ///< If set to true, ask the game engine to play

View File

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

View File

@@ -22,7 +22,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers");
#if defined(GD_IDE_ONLY)
extension
.AddCondition("Timer",
@@ -206,7 +205,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
"[\"hour\", \"min\", \"sec\", \"mon\", \"year\", \"wday\", \"mday\", "
"\"yday\", \"timestamp\"]");
#endif
}
} // namespace gd

View File

@@ -23,7 +23,6 @@ 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"),
@@ -458,7 +457,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
#endif
}
} // namespace gd

View File

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

View File

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

View File

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

View File

@@ -189,6 +189,10 @@ class GD_CORE_API ParameterMetadata {
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName" ||
parameterType == "layerEffectName" ||
parameterType == "layerEffectParameterName" ||
parameterType == "objectEffectName" ||
parameterType == "objectEffectParameterName" ||
parameterType == "objectPointName" ||
parameterType == "objectAnimationName";
} else if (type == "variable") {

View File

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

View File

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

View File

@@ -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,13 @@ 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::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 +41,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 +58,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 +92,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

View File

@@ -60,19 +60,18 @@ 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 bitmap font, which is always a reference to a "bitmapFont" resource.
*/
virtual void ExposeBitmapFont(gd::String &bitmapFontName);

View File

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

View File

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

View File

@@ -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 = [&]() {

View File

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

View File

@@ -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,9 @@ class ResourcesRenamer : public gd::ArbitraryResourceWorker {
virtual void ExposeFont(gd::String& fontResourceName) override {
RenameIfNeeded(fontResourceName);
};
virtual void ExposeBitmapFont(gd::String& bitmapFontName) override {
RenameIfNeeded(bitmapFontName);
};
private:
void RenameIfNeeded(gd::String& resourceName) {

View File

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

View File

@@ -36,6 +36,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;
@@ -55,6 +56,11 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
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);
@@ -99,6 +105,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();

View File

@@ -88,6 +88,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_;
@@ -220,6 +223,7 @@ 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 iconUrl;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -8,6 +8,7 @@
#include <iostream>
#include <map>
#include <unordered_set>
#include "GDCore/CommonTools.h"
#include "GDCore/Project/Project.h"
@@ -130,6 +131,22 @@ std::vector<gd::String> ResourcesManager::GetAllResourceNames() const {
return allResources;
}
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;
}
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> Resource::GetProperties() const {
std::map<gd::String, gd::PropertyDescriptor> nothing;
@@ -159,7 +176,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")

View File

@@ -243,7 +243,7 @@ class GD_CORE_API AudioResource : public Resource {
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
@@ -447,11 +447,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;
/**
* \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;
#if defined(GD_IDE_ONLY)
/**
* \brief Return a (smart) pointer to a resource.

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

View File

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

View File

@@ -0,0 +1,77 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
/**
* @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");
}
}

View File

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

View File

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

View File

@@ -739,7 +739,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 +754,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;

View File

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

View File

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

View File

@@ -89,6 +89,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("objectList", _("Pick these objects..."))
.AddParameter("objectPtr", _("...if they are linked to this object"))
.AddCodeOnlyParameter("eventsFunctionContext", "")
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo")
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");
@@ -106,6 +107,7 @@ void DeclareLinkedObjectsExtension(gd::PlatformExtension& extension) {
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("objectList", _("Pick these objects..."))
.AddParameter("objectPtr", _("...if they are linked to this object"))
.AddCodeOnlyParameter("eventsFunctionContext", "")
.SetFunctionName("GDpriv::LinkedObjects::PickObjectsLinkedTo")
.SetIncludeFile("LinkedObjects/LinkedObjectsTools.h");

View File

@@ -7,7 +7,7 @@ namespace gdjs {
* Manages the links between objects.
*/
export class LinksManager {
private links: { [objectId: number]: Hashtable<gdjs.RuntimeObject[]> } = {};
private _links = new Map<integer, IterableLinkedObjects>();
/**
* Get the links manager of a scene.
@@ -23,76 +23,123 @@ namespace gdjs {
return runtimeScene.linkedObjectsManager;
}
_getObjectsLinkedWith(objA: gdjs.RuntimeObject) {
if (!this.links.hasOwnProperty(objA.id)) {
this.links[objA.id] = new Hashtable<gdjs.RuntimeObject[]>();
/**
* This function is for internal use and could disappear in next versions.
* Prefer using:
* * {@link LinksManager.getObjectsLinkedWithAndNamed}
* * {@link LinksManager.getObjectsLinkedWith}
* * {@link evtTools.linkedObjects.quickPickObjectsLinkedTo}
*
* @param objA
* @returns the linked objects by name
*/
_getMapOfObjectsLinkedWith(
objA: gdjs.RuntimeObject
): Map<string, gdjs.RuntimeObject[]> {
if (!this._links.has(objA.id)) {
this._links.set(objA.id, new IterableLinkedObjects());
}
return this.links[objA.id];
return this._links.get(objA.id)!.linkedObjectMap;
}
// These 2 following functions give JS extensions an implementation dependent access to links.
/**
* @returns an iterable on every object linked with objA.
*/
// : Iterable<gdjs.RuntimeObject> in practice
getObjectsLinkedWith(objA: gdjs.RuntimeObject) {
if (!this._links.has(objA.id)) {
this._links.set(objA.id, new IterableLinkedObjects());
}
return this._links.get(objA.id)!;
}
/**
* @returns an iterable of the objects with the given name that are linked with objA.
*/
getObjectsLinkedWithAndNamed(
objA: gdjs.RuntimeObject,
objectName: string
): Iterable<gdjs.RuntimeObject> {
let objects = this._getMapOfObjectsLinkedWith(objA).get(objectName);
if (!objects) {
// Give an empty Array
objects = gdjs.staticArray(
LinksManager.prototype.getObjectsLinkedWithAndNamed
);
}
return objects;
}
linkObjects(objA: gdjs.RuntimeObject, objB: gdjs.RuntimeObject) {
const objALinkedObjectMap = this._getObjectsLinkedWith(objA);
if (!objALinkedObjectMap.containsKey(objB.getName())) {
objALinkedObjectMap.put(objB.getName(), []);
const objALinkedObjectMap = this._getMapOfObjectsLinkedWith(objA);
if (!objALinkedObjectMap.has(objB.getName())) {
objALinkedObjectMap.set(objB.getName(), []);
}
const objALinkedObjects = objALinkedObjectMap.get(objB.getName());
const objALinkedObjects = objALinkedObjectMap.get(objB.getName())!;
if (objALinkedObjects.indexOf(objB) === -1) {
objALinkedObjects.push(objB);
}
const objBLinkedObjectMap = this._getObjectsLinkedWith(objB);
if (!objBLinkedObjectMap.containsKey(objA.getName())) {
objBLinkedObjectMap.put(objA.getName(), []);
const objBLinkedObjectMap = this._getMapOfObjectsLinkedWith(objB);
if (!objBLinkedObjectMap.has(objA.getName())) {
objBLinkedObjectMap.set(objA.getName(), []);
}
const objBLinkedObjects = objBLinkedObjectMap.get(objA.getName());
const objBLinkedObjects = objBLinkedObjectMap.get(objA.getName())!;
if (objBLinkedObjects.indexOf(objA) === -1) {
objBLinkedObjects.push(objA);
}
}
removeAllLinksOf(obj: gdjs.RuntimeObject) {
removeAllLinksOf(removedObject: gdjs.RuntimeObject) {
// Remove the other side of the links
const linkedObjectMap = this._getObjectsLinkedWith(obj);
for (const linkedObjectName in linkedObjectMap.items) {
if (linkedObjectMap.containsKey(linkedObjectName)) {
const linkedObjects = linkedObjectMap.get(linkedObjectName);
// Note: don't use `this._getMapOfObjectsLinkedWith` as this would
// create an empty map of linked objects if not existing already.
const links = this._links.get(removedObject.id);
if (!links) {
// No existing links to other objects.
// This also means no links to the object from other objects.
return;
}
for (let i = 0; i < linkedObjects.length; i++) {
// This is the object on the other side of the link
// We find obj in its list of linked objects and remove it.
const linkedObject = linkedObjects[i];
if (this.links.hasOwnProperty(linkedObject.id)) {
const otherObjList = this.links[linkedObject.id].get(
obj.getName()
);
const index = otherObjList.indexOf(obj);
if (index !== -1) {
otherObjList.splice(index, 1);
}
for (const linkedObjects of links.linkedObjectMap.values()) {
for (let i = 0; i < linkedObjects.length; i++) {
// This is the object on the other side of the link.
// We find the removed object in its list of linked objects and remove it.
const linkedObject = linkedObjects[i];
if (this._links.has(linkedObject.id)) {
const otherObjList = this._links
.get(linkedObject.id)!
.linkedObjectMap.get(removedObject.getName())!;
const index = otherObjList.indexOf(removedObject);
if (index !== -1) {
otherObjList.splice(index, 1);
}
}
}
}
// Remove the links on obj side
if (this.links.hasOwnProperty(obj.id)) {
delete this.links[obj.id];
}
// Remove the links on the removedObject side.
this._links.delete(removedObject.id);
}
removeLinkBetween(objA: gdjs.RuntimeObject, objB: gdjs.RuntimeObject) {
if (this.links.hasOwnProperty(objA.id)) {
const map = this.links[objA.id];
if (map.containsKey(objB.getName())) {
const list = map.get(objB.getName());
if (this._links.has(objA.id)) {
const map = this._links.get(objA.id)!.linkedObjectMap;
if (map.has(objB.getName())) {
const list = map.get(objB.getName())!;
const index = list.indexOf(objB);
if (index !== -1) {
list.splice(index, 1);
}
}
}
if (this.links.hasOwnProperty(objB.id)) {
const map = this.links[objB.id];
if (map.containsKey(objA.getName())) {
const list = map.get(objA.getName());
if (this._links.has(objB.id)) {
const map = this._links.get(objB.id)!.linkedObjectMap;
if (map.has(objA.getName())) {
const list = map.get(objA.getName())!;
const index = list.indexOf(objA);
if (index !== -1) {
list.splice(index, 1);
@@ -102,11 +149,46 @@ namespace gdjs {
}
}
class IterableLinkedObjects {
linkedObjectMap: Map<string, gdjs.RuntimeObject[]>;
constructor() {
this.linkedObjectMap = new Map<string, gdjs.RuntimeObject[]>();
}
[Symbol.iterator]() {
let mapItr = this.linkedObjectMap.entries();
let listItr: IterableIterator<[
number,
gdjs.RuntimeObject
]> = [].entries();
return {
next: () => {
let listNext = listItr.next();
while (listNext.done) {
const mapNext = mapItr.next();
if (mapNext.done) {
// IteratorReturnResult<gdjs.RuntimeObject> require a defined value
// even though the spec state otherwise.
// So, this class can't be typed as an iterable.
return { value: undefined, done: true };
}
listItr = mapNext.value[1].entries();
listNext = listItr.next();
}
return { value: listNext.value[1], done: false };
},
};
}
}
export namespace evtTools {
export namespace linkedObjects {
gdjs.registerObjectDeletedFromSceneCallback(function (runtimeScene, obj) {
LinksManager.getManager(runtimeScene).removeAllLinksOf(obj);
});
export const linkObjects = function (
runtimeScene: gdjs.RuntimeScene,
objA: gdjs.RuntimeObject,
@@ -142,50 +224,105 @@ namespace gdjs {
export const pickObjectsLinkedTo = function (
runtimeScene: gdjs.RuntimeScene,
objectsLists: Hashtable<gdjs.RuntimeObject[]>,
obj: gdjs.RuntimeObject
obj: gdjs.RuntimeObject,
eventsFunctionContext: EventsFunctionContext | undefined
) {
if (obj === null) {
return false;
}
const linkedObjectMap = LinksManager.getManager(
runtimeScene
)._getObjectsLinkedWith(obj);
)._getMapOfObjectsLinkedWith(obj);
let pickedSomething = false;
for (const objectName in objectsLists.items) {
if (objectsLists.containsKey(objectName)) {
const pickedObjects = objectsLists.items[objectName];
for (const contextObjectName in objectsLists.items) {
if (objectsLists.containsKey(contextObjectName)) {
const parentEventPickedObjects =
objectsLists.items[contextObjectName];
if (linkedObjectMap.containsKey(objectName)) {
const linkedObjects = linkedObjectMap.get(objectName);
if (
pickedObjects.length ===
runtimeScene.getObjects(objectName).length
) {
// All the objects were picked, there is no need to make an intersection.
pickedSomething = pickedSomething || linkedObjects.length > 0;
pickedObjects.length = 0;
pickedObjects.push.apply(pickedObjects, linkedObjects);
} else {
const temporaryObjects = gdjs.staticArray(
gdjs.evtTools.linkedObjects.pickObjectsLinkedTo
);
temporaryObjects.length = 0;
for (const otherObject of linkedObjects) {
if (pickedObjects.indexOf(otherObject) >= 0) {
temporaryObjects.push(otherObject);
}
if (parentEventPickedObjects.length === 0) {
continue;
}
// Find the object names in the scene
const parentEventPickedObjectNames = gdjs.staticArray2(
gdjs.evtTools.linkedObjects.pickObjectsLinkedTo
);
parentEventPickedObjectNames.length = 0;
if (eventsFunctionContext) {
// For functions, objects lists may contain objects with different names
// indexed not by their name, but by the parameter name representing them.
// This means that each object can have a different name,
// so we iterate on them to get all the names.
for (const pickedObject of parentEventPickedObjects) {
if (
parentEventPickedObjectNames.indexOf(pickedObject.getName()) <
0
) {
parentEventPickedObjectNames.push(pickedObject.getName());
}
pickedSomething =
pickedSomething || temporaryObjects.length > 0;
pickedObjects.length = 0;
pickedObjects.push.apply(pickedObjects, temporaryObjects);
temporaryObjects.length = 0;
}
} else {
// No object is linked for this name
pickedObjects.length = 0;
// In the case of a scene, the list of objects are guaranteed
// to be indexed by the object name (no mix of objects with
// different names in a list).
parentEventPickedObjectNames.push(contextObjectName);
}
// Sum the number of instances in the scene for each objects found
// previously in parentEventPickedObjects, so that we know if we can
// avoid running an intersection with the picked objects later.
let objectCount = 0;
for (const objectName of parentEventPickedObjectNames) {
objectCount += runtimeScene.getObjects(objectName).length;
}
if (parentEventPickedObjects.length === objectCount) {
// The parent event didn't make any selection on the current object,
// (because the number of picked objects is the total object count on the scene).
// There is no need to make an intersection.
// We will only replace the picked list with the linked object list.
parentEventPickedObjects.length = 0;
for (const objectName of parentEventPickedObjectNames) {
if (linkedObjectMap.has(objectName)) {
const linkedObjects = linkedObjectMap.get(objectName)!;
pickedSomething = pickedSomething || linkedObjects.length > 0;
parentEventPickedObjects.push.apply(
parentEventPickedObjects,
linkedObjects
);
}
}
} else {
// Run an intersection between objects picked by parent events
// and the linked ones.
const pickedAndLinkedObjects = gdjs.staticArray(
gdjs.evtTools.linkedObjects.pickObjectsLinkedTo
);
pickedAndLinkedObjects.length = 0;
for (const objectName of parentEventPickedObjectNames) {
if (linkedObjectMap.has(objectName)) {
const linkedObjects = linkedObjectMap.get(objectName)!;
for (const otherObject of linkedObjects) {
if (parentEventPickedObjects.indexOf(otherObject) >= 0) {
pickedAndLinkedObjects.push(otherObject);
}
}
}
}
pickedSomething =
pickedSomething || pickedAndLinkedObjects.length > 0;
parentEventPickedObjects.length = 0;
parentEventPickedObjects.push.apply(
parentEventPickedObjects,
pickedAndLinkedObjects
);
pickedAndLinkedObjects.length = 0;
}
parentEventPickedObjectNames.length = 0;
}
}
return pickedSomething;

View File

@@ -1,148 +1,309 @@
// @ts-check
describe('gdjs.LinksManager', function () {
var runtimeGame = new gdjs.RuntimeGame({
variables: [],
// @ts-ignore - missing properties.
properties: { windowWidth: 800, windowHeight: 600 },
resources: { resources: [] },
});
var runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
// @ts-ignore - missing properties.
layers: [{ name: '', visibility: true, effects: [] }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
});
const doTest = (
object1Names,
object2Names,
object3Names,
eventsFunctionContext
) => {
const runtimeGame = new gdjs.RuntimeGame({
variables: [],
// @ts-ignore - missing properties.
properties: { windowWidth: 800, windowHeight: 600 },
resources: { resources: [] },
});
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers: [
{
name: '',
visibility: true,
cameras: [],
effects: [],
ambientLightColorR: 127,
ambientLightColorB: 127,
ambientLightColorG: 127,
isLightingLayer: false,
followBaseLayerCamera: false,
},
],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
r: 0,
v: 0,
b: 0,
mangledName: 'Scene1',
name: 'Scene1',
stopSoundsOnStartup: false,
title: '',
});
var manager = gdjs.LinksManager.getManager(runtimeScene);
const manager = gdjs.LinksManager.getManager(runtimeScene);
// @ts-ignore - missing properties.
var object1A = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [],
effects: [],
});
// @ts-ignore - missing properties.
var object1B = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [],
effects: [],
});
// @ts-ignore - missing properties.
var object1C = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [],
effects: [],
});
const object1A = new gdjs.RuntimeObject(runtimeScene, {
name: object1Names[0],
type: '',
behaviors: [],
variables: [],
effects: [],
});
const object1B = new gdjs.RuntimeObject(runtimeScene, {
name: object1Names[1],
type: '',
behaviors: [],
variables: [],
effects: [],
});
// @ts-ignore - missing properties.
var object2A = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj2',
type: '',
behaviors: [],
effects: [],
});
const object1C = new gdjs.RuntimeObject(runtimeScene, {
name: object1Names[2],
type: '',
behaviors: [],
variables: [],
effects: [],
});
// @ts-ignore - missing properties.
var object2B = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj2',
type: '',
behaviors: [],
effects: [],
});
// @ts-ignore - missing properties.
var object2C = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj2',
type: '',
behaviors: [],
effects: [],
});
const object2A = new gdjs.RuntimeObject(runtimeScene, {
name: object2Names[0],
type: '',
behaviors: [],
variables: [],
effects: [],
});
var pickObjectsLinkedTo = (object) => {
const objectsLists = new Hashtable();
objectsLists.put('obj1', [object1A, object1B, object1C]);
objectsLists.put('obj2', [object2A, object2B, object2C]);
const pickedSomething = gdjs.evtTools.linkedObjects.pickObjectsLinkedTo(
runtimeScene,
objectsLists,
object
);
return { pickedSomething, objectsLists };
const object2B = new gdjs.RuntimeObject(runtimeScene, {
name: object2Names[1],
type: '',
behaviors: [],
variables: [],
effects: [],
});
const object2C = new gdjs.RuntimeObject(runtimeScene, {
name: object2Names[2],
type: '',
behaviors: [],
variables: [],
effects: [],
});
const object3A = new gdjs.RuntimeObject(runtimeScene, {
name: object3Names[0],
type: '',
behaviors: [],
variables: [],
effects: [],
});
const object3B = new gdjs.RuntimeObject(runtimeScene, {
name: object3Names[1],
type: '',
behaviors: [],
variables: [],
effects: [],
});
const object3C = new gdjs.RuntimeObject(runtimeScene, {
name: object3Names[2],
type: '',
behaviors: [],
variables: [],
effects: [],
});
runtimeScene.addObject(object1A);
runtimeScene.addObject(object1B);
runtimeScene.addObject(object1C);
runtimeScene.addObject(object2A);
runtimeScene.addObject(object2B);
runtimeScene.addObject(object2C);
runtimeScene.addObject(object3A);
runtimeScene.addObject(object3B);
runtimeScene.addObject(object3C);
/**
* @param {gdjs.RuntimeObject} object
* @param {Hashtable<gdjs.RuntimeObject[]>} objectsLists
* @returns a selection of picked objects
*/
const pickObjectsLinkedTo = (object, objectsLists) => {
let pickedSomething = gdjs.evtTools.linkedObjects.pickObjectsLinkedTo(
runtimeScene,
objectsLists,
object,
eventsFunctionContext
);
return { pickedSomething, objectsLists };
};
it('can link two objects', function () {
manager.linkObjects(object1A, object2A);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
Hashtable.newFrom({ obj2: [object2A, object2B, object2C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj2').length).to.be(1);
expect(objectsLists.get('obj2')[0]).to.be(object2A);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object2A,
Hashtable.newFrom({ obj1: [object1A, object1B, object1C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(1);
expect(objectsLists.get('obj1')[0]).to.be(object1A);
}
});
it('can select from already picked objects', function () {
manager.linkObjects(object1A, object2B);
// object1A <--> object2A, object2B
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
// object2B was discarded from a parent condition
Hashtable.newFrom({ obj2: [object2A, object2C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj2').length).to.be(1);
expect(objectsLists.get('obj2')[0]).to.be(object2A);
}
});
// This is a local group. In an event function context,
// it can groups objects that are flatten scene groups.
it('can select from a group', function () {
manager.linkObjects(object1A, object3C);
// object1A <--> object2A, object2B, object3C
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
// This is a group of obj2 and obj3.
Hashtable.newFrom({
obj2: [object2A, object2B, object2C],
obj3: [object3A, object3B, object3C],
})
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj2').length).to.be(2);
expect(objectsLists.get('obj2')).to.contain(object2A);
expect(objectsLists.get('obj2')).to.contain(object2B);
expect(objectsLists.get('obj3').length).to.be(1);
expect(objectsLists.get('obj3')[0]).to.be(object3C);
}
});
it('can link more objects', function () {
// Including the same objects as before
manager.linkObjects(object1A, object2A);
manager.linkObjects(object1A, object2B);
manager.linkObjects(object1A, object2C);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
Hashtable.newFrom({ obj2: [object2A, object2B, object2C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj2').length).to.be(3);
expect(objectsLists.get('obj2')).to.contain(object2A);
expect(objectsLists.get('obj2')).to.contain(object2B);
expect(objectsLists.get('obj2')).to.contain(object2C);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object2C,
Hashtable.newFrom({ obj1: [object1A, object1B, object1C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(1);
expect(objectsLists.get('obj1')[0]).to.be(object1A);
}
});
it('supports removing links', function () {
manager.removeLinkBetween(object1A, object2B);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
Hashtable.newFrom({ obj2: [object2A, object2B, object2C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj2').length).to.be(2);
expect(objectsLists.get('obj2')).to.contain(object2A);
expect(objectsLists.get('obj2')).to.contain(object2C);
}
manager.linkObjects(object1B, object2C);
manager.removeAllLinksOf(object1A);
manager.removeAllLinksOf(object1A);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object1A,
Hashtable.newFrom({ obj2: [object2A, object2B, object2C] })
);
expect(pickedSomething).to.be(false);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object2A,
Hashtable.newFrom({ obj1: [object1A, object1B, object1C] })
);
expect(pickedSomething).to.be(false);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(
object2C,
Hashtable.newFrom({ obj1: [object1A, object1B, object1C] })
);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(1);
expect(objectsLists.get('obj1')[0]).to.be(object1B);
}
});
};
runtimeScene.addObject(object1A);
runtimeScene.addObject(object1B);
runtimeScene.addObject(object1C);
runtimeScene.addObject(object2A);
runtimeScene.addObject(object2B);
runtimeScene.addObject(object2C);
it('can link two objects', function () {
manager.linkObjects(object1A, object2A);
// Following object names are the names of the objects in the scene.
// The test cases are using local names 'obj1', 'obj2', 'obj3'.
[
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object1A);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(0);
expect(objectsLists.get('obj2').length).to.be(1);
expect(objectsLists.get('obj2')[0]).to.be(object2A);
}
caseName: 'scene',
// Called from a scene, no event function context.
// Scene names are the same as local names.
eventsFunctionContext: null,
object1Names: ['obj1', 'obj1', 'obj1'],
object2Names: ['obj2', 'obj2', 'obj2'],
object3Names: ['obj3', 'obj3', 'obj3'],
},
// In event functions, the object names from the scene are different
// than the local names.
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object2A);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(1);
expect(objectsLists.get('obj1')[0]).to.be(object1A);
expect(objectsLists.get('obj2').length).to.be(0);
}
});
it('can link more objects', function () {
manager.linkObjects(object1A, object2A); //Including the same objects as before
manager.linkObjects(object1A, object2B);
manager.linkObjects(object1A, object2C);
caseName: 'extension',
// The implementation only check it exists.
eventsFunctionContext: {},
object1Names: ['SceneObj1', 'SceneObj1', 'SceneObj1'],
object2Names: ['SceneObj2', 'SceneObj2', 'SceneObj2'],
object3Names: ['SceneObj3', 'SceneObj3', 'SceneObj3'],
},
// When groups are passed in parameters, they are flattened as an object.
// So, the lists will contains objects with different names.
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object1A);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(0);
expect(objectsLists.get('obj2').length).to.be(3);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object2C);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(1);
expect(objectsLists.get('obj1')[0]).to.be(object1A);
expect(objectsLists.get('obj2').length).to.be(0);
}
});
it('supports removing links', function () {
manager.removeLinkBetween(object1A, object2B);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object1A);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(0);
expect(objectsLists.get('obj2').length).to.be(2);
}
manager.linkObjects(object2B, object2C);
manager.removeAllLinksOf(object1A);
manager.removeAllLinksOf(object1A);
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object1A);
expect(pickedSomething).to.be(false);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object2A);
expect(pickedSomething).to.be(false);
}
{
const { pickedSomething, objectsLists } = pickObjectsLinkedTo(object2C);
expect(pickedSomething).to.be(true);
expect(objectsLists.get('obj1').length).to.be(0);
expect(objectsLists.get('obj2').length).to.be(1);
expect(objectsLists.get('obj2')[0]).to.be(object2B);
}
caseName: 'extension with groups',
// The implementation only checks it exists.
eventsFunctionContext: {},
object1Names: ['SceneObj1', 'SceneObj1p', 'SceneObj1p'],
object2Names: ['SceneObj2p', 'SceneObj2p', 'SceneObj2'],
object3Names: ['SceneObj3p', 'SceneObj3p', 'SceneObj3'],
},
].forEach((testCase) => {
describe(testCase.caseName, function () {
doTest(
testCase.object1Names,
testCase.object2Names,
testCase.object3Names,
testCase.eventsFunctionContext
);
});
});
});

View File

@@ -36,7 +36,6 @@ void DeclareParticleSystemExtension(gd::PlatformExtension& extension) {
"effects."),
"CppPlatform/Extensions/particleSystemicon.png");
#if defined(GD_IDE_ONLY)
obj.SetIncludeFile("ParticleSystem/ParticleEmitterObject.h");
// Declaration is too big to be compiled by GCC in one file, unless you have
@@ -44,6 +43,5 @@ void DeclareParticleSystemExtension(gd::PlatformExtension& extension) {
ExtensionSubDeclaration1(obj);
ExtensionSubDeclaration2(obj);
ExtensionSubDeclaration3(obj);
#endif
}
}

View File

@@ -15,7 +15,6 @@ This project is released under the MIT License.
* Declare some actions and conditions of the particle emitter
*/
void ExtensionSubDeclaration1(gd::ObjectMetadata& obj) {
#if defined(GD_IDE_ONLY)
obj.AddAction("EmitterForceMin",
_("Emission minimal force"),
_("Modify minimal emission force of particles."),
@@ -36,70 +35,6 @@ void ExtensionSubDeclaration1(gd::ObjectMetadata& obj) {
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddAction(
"EmitterXDirection",
_("Emission X direction"),
_("Modify emission X direction."),
_("the emission X direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition(
"EmitterXDirection",
_("Emission X direction"),
_("Test emission X direction."),
_("the emission X direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction(
"EmitterYDirection",
_("Emission Y direction"),
_("Modify emission Y direction."),
_("the emission Y direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition("EmitterYDirection",
_("Emission Y direction"),
_("Test emission Y direction."),
_("the emission Y direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction(
"EmitterZDirection",
_("Emission Z direction"),
_("Modify emission Z direction."),
_("the emission Z direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition("EmitterZDirection",
_("Emission Z direction"),
_("Test emission Z direction."),
_("the emission Z direction"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction("EmitterAngle",
_("Emission angle"),
_("Modify emission angle."),
@@ -184,30 +119,6 @@ void ExtensionSubDeclaration1(gd::ObjectMetadata& obj) {
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction(
"Friction",
_("Friction"),
_("Modify friction applied to particles."),
_("the friction of particles"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number")
.GetCodeExtraInformation()
.SetGetter("GetFriction");
obj.AddCondition("Friction",
_("Friction"),
_("Test friction applied to particles."),
_("the friction of particles"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction("ZoneRadius",
_("Creation radius"),
_("Modify creation radius of particles.\nParticles have to be "
@@ -317,27 +228,6 @@ void ExtensionSubDeclaration1(gd::ObjectMetadata& obj) {
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction("ParticleGravityZ",
_("Z Gravity"),
_("Change value of the gravity on Z axis."),
_("the gravity direction on Z axis of_PARAM0_"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition(
"ParticleGravityZ",
_("Direction of gravity on Z axis"),
_("Test the direction of gravity on Z axis"),
_("the gravity direction on Z axis"),
_("Advanced"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
obj.AddAction("ParticleGravityAngle",
_("Gravity angle"),
_("Change gravity angle"),
@@ -377,5 +267,22 @@ void ExtensionSubDeclaration1(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardRelationalOperatorParameters("number");
#endif
obj.AddAction("StartEmission",
_("Start emission"),
_("Refill tank (if not infinite) and start emission of the particles."),
_("Start emission of _PARAM0_"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter");
obj.AddAction("StopEmission",
_("Stop emission"),
_("Stop the emission of particles."),
_("Stop emission of _PARAM0_"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter");
}

View File

@@ -15,7 +15,6 @@ This project is released under the MIT License.
* Declare some actions and conditions of the particle emitter
*/
void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
#if defined(GD_IDE_ONLY)
obj.AddAction("ParticleColor1",
_("Initial color"),
_("Modify initial color of particles."),
@@ -302,5 +301,4 @@ void ExtensionSubDeclaration2(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter");
#endif
}

View File

@@ -15,7 +15,6 @@ This project is released under the MIT License.
* Declare some actions, conditions and expressions of the particle emitter
*/
void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
#if defined(GD_IDE_ONLY)
obj.AddAction("RecreateParticleSystem",
_("Recreate particles"),
_("Destroy and recreate particles, so as to take changes made "
@@ -81,6 +80,17 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.SetHidden() // DEPRECATED - Use SetTank instead
.UseStandardOperatorParameters("number");
obj.AddAction("SetTank",
_("Capacity"),
_("Change the capacity of the emitter."),
_("the capacity"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition("Tank",
@@ -101,6 +111,17 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.SetHidden() // DEPRECATED - Use SetFlow instead
.UseStandardOperatorParameters("number");
obj.AddAction("SetFlow",
_("Flow"),
_("Change the flow of the emitter."),
_("the flow"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon24.png",
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter")
.UseStandardOperatorParameters("number");
obj.AddCondition("Flow",
@@ -146,6 +167,14 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
_("Particles number"),
_("Particles"),
"CppPlatform/Extensions/particleSystemicon16.png")
.SetHidden() // DEPRECATED - Use CurrentParticleCount instead
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("CurrentParticleCount",
_("Particles count"),
_("Number of particles currently displayed"),
_("Particles"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("RendererParam1",
@@ -190,24 +219,6 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("EmitterXDirection",
_("Emission X direction"),
_("Emission X direction"),
_("Setup"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("EmitterYDirection",
_("Emission Y direction"),
_("Emission Y direction"),
_("Setup"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("EmitterZDirection",
_("Emission Z direction"),
_("Emission Z direction"),
_("Setup"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("EmitterAngle",
_("Emission angle"),
_("Emission angle"),
@@ -244,12 +255,6 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
_("Setup"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("ParticleGravityZ",
_("Z Gravity of particles"),
_("Z Gravity of particles"),
_("Setup"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("ParticleGravityAngle",
_("Gravity angle"),
_("Gravity angle"),
@@ -262,12 +267,6 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
_("Common"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("Friction",
_("Particles friction"),
_("Particles friction"),
_("Common"),
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
obj.AddExpression("ParticleLifeTimeMin",
_("Minimum lifetime of particles"),
_("Minimum lifetime of particles"),
@@ -353,5 +352,4 @@ void ExtensionSubDeclaration3(gd::ObjectMetadata& obj) {
"CppPlatform/Extensions/particleSystemicon16.png")
.AddParameter("object", _("Object"), "ParticleEmitter", false);
#endif
}

View File

@@ -4,7 +4,6 @@ GDevelop - Particle System Extension
Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "ParticleEmitterObject.h"
@@ -158,9 +157,15 @@ class ParticleSystemJsExtension : public gd::PlatformExtension {
actions["ParticleSystem::RecreateParticleSystem"].SetFunctionName(
"recreateParticleSystem");
actions["ParticleSystem::SetTank"].SetFunctionName("setTank").SetGetter(
"getTank");
actions["ParticleSystem::Tank"].SetFunctionName("setTank").SetGetter(
"getTank");
actions["ParticleSystem::StartEmission"].SetFunctionName("startEmission");
actions["ParticleSystem::StopEmission"].SetFunctionName("stopEmission");
conditions["ParticleSystem::Tank"].SetFunctionName("getTank");
actions["ParticleSystem::SetFlow"].SetFunctionName("setFlow").SetGetter(
"getFlow");
actions["ParticleSystem::Flow"].SetFunctionName("setFlow").SetGetter(
"getFlow");
conditions["ParticleSystem::Flow"].SetFunctionName("getFlow");
@@ -171,6 +176,7 @@ class ParticleSystemJsExtension : public gd::PlatformExtension {
conditions["ParticleSystem::Texture"].SetFunctionName("getTexture");
strExpressions["Texture"].SetFunctionName("getTexture");
expressions["CurrentParticleCount"].SetFunctionName("getParticleCount");
expressions["NbParticles"].SetFunctionName("getParticleCount");
expressions["RendererParam1"].SetFunctionName("getRendererParam1");
expressions["RendererParam2"].SetFunctionName("getRendererParam2");
@@ -222,4 +228,3 @@ extern "C" gd::PlatformExtension* GD_EXTENSION_API CreateGDJSExtension() {
return new ParticleSystemJsExtension;
}
#endif
#endif

View File

@@ -13,10 +13,8 @@ This project is released under the MIT License.
#include "GDCore/Serialization/SerializerElement.h"
#include "ParticleEmitterObject.h"
#if defined(GD_IDE_ONLY)
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/CommonTools.h"
#endif
using namespace std;
@@ -29,24 +27,13 @@ ParticleEmitterBase::ParticleEmitterBase()
flow(45),
emitterForceMin(45.0f),
emitterForceMax(85.0f),
emitterXDirection(0.0f),
emitterYDirection(1.0f),
emitterZDirection(0.0f),
emitterAngleA(0),
emitterAngleB(90),
zoneRadius(3.0f),
particleGravityX(0.0f),
particleGravityY(0.0f),
particleGravityZ(0.0f),
friction(2.0f),
particleLifeTimeMin(0.5f),
particleLifeTimeMax(2.5f),
redParam(Enabled),
greenParam(Random),
blueParam(Random),
alphaParam(Mutable),
sizeParam(Mutable),
angleParam(Mutable),
particleRed1(255.0f),
particleRed2(255.0f),
particleGreen1(51),
@@ -69,28 +56,11 @@ ParticleEmitterBase::ParticleEmitterBase()
destroyWhenNoParticles(true) {}
ParticleEmitterObject::ParticleEmitterObject(gd::String name_)
: Object(name_)
#if defined(GD_IDE_ONLY)
,
particleEditionSimpleMode(true),
emissionEditionSimpleMode(true),
gravityEditionSimpleMode(true)
#endif
{
}
: Object(name_) {}
void ParticleEmitterObject::DoUnserializeFrom(
gd::Project& project, const gd::SerializerElement& element) {
ParticleEmitterBase::UnserializeParticleEmitterBaseFrom(element);
#if defined(GD_IDE_ONLY)
particleEditionSimpleMode =
element.GetBoolAttribute("particleEditionSimpleMode");
emissionEditionSimpleMode =
element.GetBoolAttribute("emissionEditionSimpleMode");
gravityEditionSimpleMode =
element.GetBoolAttribute("gravityEditionSimpleMode");
#endif
}
void ParticleEmitterBase::UnserializeParticleEmitterBaseFrom(
@@ -99,16 +69,11 @@ void ParticleEmitterBase::UnserializeParticleEmitterBaseFrom(
flow = element.GetDoubleAttribute("flow");
emitterForceMin = element.GetDoubleAttribute("emitterForceMin");
emitterForceMax = element.GetDoubleAttribute("emitterForceMax");
emitterXDirection = element.GetDoubleAttribute("emitterXDirection");
emitterYDirection = element.GetDoubleAttribute("emitterYDirection");
emitterZDirection = element.GetDoubleAttribute("emitterZDirection");
emitterAngleA = element.GetDoubleAttribute("emitterAngleA");
emitterAngleB = element.GetDoubleAttribute("emitterAngleB");
zoneRadius = element.GetDoubleAttribute("zoneRadius");
particleGravityX = element.GetDoubleAttribute("particleGravityX");
particleGravityY = element.GetDoubleAttribute("particleGravityY");
particleGravityZ = element.GetDoubleAttribute("particleGravityZ");
friction = element.GetDoubleAttribute("friction");
particleLifeTimeMin = element.GetDoubleAttribute("particleLifeTimeMin");
particleLifeTimeMax = element.GetDoubleAttribute("particleLifeTimeMax");
particleRed1 = element.GetDoubleAttribute("particleRed1");
@@ -152,69 +117,10 @@ void ParticleEmitterBase::UnserializeParticleEmitterBaseFrom(
else
rendererType = Point;
}
{
gd::String result = element.GetStringAttribute("redParam");
if (result == "Mutable")
redParam = Mutable;
else if (result == "Random")
redParam = Random;
else
redParam = Enabled;
}
{
gd::String result = element.GetStringAttribute("greenParam");
if (result == "Mutable")
greenParam = Mutable;
else if (result == "Random")
greenParam = Random;
else
greenParam = Enabled;
}
{
gd::String result = element.GetStringAttribute("blueParam");
if (result == "Mutable")
blueParam = Mutable;
else if (result == "Random")
blueParam = Random;
else
blueParam = Enabled;
}
{
gd::String result = element.GetStringAttribute("alphaParam");
if (result == "Mutable")
alphaParam = Mutable;
else if (result == "Random")
alphaParam = Random;
else
alphaParam = Enabled;
}
{
gd::String result = element.GetStringAttribute("sizeParam");
if (result == "Mutable")
sizeParam = Mutable;
else if (result == "Random")
sizeParam = Random;
else
sizeParam = Nothing;
}
{
gd::String result = element.GetStringAttribute("angleParam");
if (result == "Mutable")
angleParam = Mutable;
else if (result == "Random")
angleParam = Random;
else
angleParam = Nothing;
}
}
#if defined(GD_IDE_ONLY)
void ParticleEmitterObject::DoSerializeTo(
gd::SerializerElement& element) const {
element.SetAttribute("particleEditionSimpleMode", particleEditionSimpleMode);
element.SetAttribute("emissionEditionSimpleMode", emissionEditionSimpleMode);
element.SetAttribute("gravityEditionSimpleMode", gravityEditionSimpleMode);
ParticleEmitterBase::SerializeParticleEmitterBaseTo(element);
}
@@ -224,16 +130,11 @@ void ParticleEmitterBase::SerializeParticleEmitterBaseTo(
element.SetAttribute("flow", flow);
element.SetAttribute("emitterForceMin", emitterForceMin);
element.SetAttribute("emitterForceMax", emitterForceMax);
element.SetAttribute("emitterXDirection", emitterXDirection);
element.SetAttribute("emitterYDirection", emitterYDirection);
element.SetAttribute("emitterZDirection", emitterZDirection);
element.SetAttribute("emitterAngleA", emitterAngleA);
element.SetAttribute("emitterAngleB", emitterAngleB);
element.SetAttribute("zoneRadius", zoneRadius);
element.SetAttribute("particleGravityX", particleGravityX);
element.SetAttribute("particleGravityY", particleGravityY);
element.SetAttribute("particleGravityZ", particleGravityZ);
element.SetAttribute("friction", friction);
element.SetAttribute("particleLifeTimeMin", particleLifeTimeMin);
element.SetAttribute("particleLifeTimeMax", particleLifeTimeMax);
element.SetAttribute("particleRed1", particleRed1);
@@ -267,61 +168,16 @@ void ParticleEmitterBase::SerializeParticleEmitterBaseTo(
else if (rendererType == Quad)
rendererTypeStr = "Quad";
element.SetAttribute("rendererType", rendererTypeStr);
gd::String redParamStr = "Enabled";
if (redParam == Mutable)
redParamStr = "Mutable";
else if (redParam == Random)
redParamStr = "Random";
element.SetAttribute("redParam", redParamStr);
gd::String greenParamStr = "Enabled";
if (greenParam == Mutable)
greenParamStr = "Mutable";
else if (greenParam == Random)
greenParamStr = "Random";
element.SetAttribute("greenParam", greenParamStr);
gd::String blueParamStr = "Enabled";
if (blueParam == Mutable)
blueParamStr = "Mutable";
else if (blueParam == Random)
blueParamStr = "Random";
element.SetAttribute("blueParam", blueParamStr);
gd::String alphaParamStr = "Enabled";
if (alphaParam == Mutable)
alphaParamStr = "Mutable";
else if (alphaParam == Random)
alphaParamStr = "Random";
element.SetAttribute("alphaParam", alphaParamStr);
gd::String sizeParamStr = "Nothing";
if (sizeParam == Mutable)
sizeParamStr = "Mutable";
else if (sizeParam == Random)
sizeParamStr = "Random";
element.SetAttribute("sizeParam", sizeParamStr);
gd::String angleParamStr = "Nothing";
if (angleParam == Mutable)
angleParamStr = "Mutable";
else if (angleParam == Random)
angleParamStr = "Random";
element.SetAttribute("angleParam", angleParamStr);
}
#endif
ParticleEmitterBase::~ParticleEmitterBase() {}
#if defined(GD_IDE_ONLY)
void ParticleEmitterObject::ExposeResources(
gd::ArbitraryResourceWorker& worker) {
gd::String texture = GetParticleTexture();
worker.ExposeImage(texture);
SetParticleTexture(texture);
}
#endif
void ParticleEmitterBase::SetTank(float newValue) {
tank = newValue;
@@ -341,21 +197,6 @@ void ParticleEmitterBase::SetParticleGravityX(float newValue) {
void ParticleEmitterBase::SetParticleGravityY(float newValue) {
particleGravityY = newValue;
}
void ParticleEmitterBase::SetParticleGravityZ(float newValue) {
particleGravityZ = newValue;
}
void ParticleEmitterBase::SetFriction(float newValue) {
friction = newValue;
}
void ParticleEmitterBase::SetEmitterXDirection(float newValue) {
emitterXDirection = newValue;
}
void ParticleEmitterBase::SetEmitterYDirection(float newValue) {
emitterYDirection = newValue;
}
void ParticleEmitterBase::SetEmitterZDirection(float newValue) {
emitterZDirection = newValue;
}
void ParticleEmitterBase::SetEmitterAngleA(float newValue) {
emitterAngleA = newValue;
}
@@ -424,24 +265,13 @@ void ParticleEmitterBase::Init(const ParticleEmitterBase& other) {
flow = other.flow;
emitterForceMin = other.emitterForceMin;
emitterForceMax = other.emitterForceMax;
emitterXDirection = other.emitterXDirection;
emitterYDirection = other.emitterYDirection;
emitterZDirection = other.emitterZDirection;
emitterAngleA = other.emitterAngleA;
emitterAngleB = other.emitterAngleB;
zoneRadius = other.zoneRadius;
particleGravityX = other.particleGravityX;
particleGravityY = other.particleGravityY;
particleGravityZ = other.particleGravityZ;
friction = other.friction;
particleLifeTimeMin = other.particleLifeTimeMin;
particleLifeTimeMax = other.particleLifeTimeMax;
redParam = other.redParam;
greenParam = other.greenParam;
blueParam = other.blueParam;
alphaParam = other.alphaParam;
sizeParam = other.sizeParam;
angleParam = other.angleParam;
particleRed1 = other.particleRed1;
particleRed2 = other.particleRed2;
particleGreen1 = other.particleGreen1;

View File

@@ -41,27 +41,14 @@ class GD_EXTENSION_API ParticleEmitterBase {
void SetFlow(float newValue);
void SetEmitterForceMin(float newValue);
void SetEmitterForceMax(float newValue);
void SetEmitterXDirection(float newValue);
void SetEmitterYDirection(float newValue);
void SetEmitterZDirection(float newValue);
void SetEmitterAngleA(float newValue);
void SetEmitterAngleB(float newValue);
void SetConeSprayAngle(float newValue) { SetEmitterAngleB(newValue); };
void SetZoneRadius(float newValue);
void SetParticleGravityX(float newValue);
void SetParticleGravityY(float newValue);
void SetParticleGravityZ(float newValue);
void SetParticleGravityAngle(float newAngleInDegree);
void SetParticleGravityLength(float newLength);
void SetFriction(float newValue);
enum ParticleParameterType { Nothing, Enabled, Mutable, Random };
void SetRedParameterType(ParticleParameterType type) { redParam = type; };
void SetGreenParameterType(ParticleParameterType type) { greenParam = type; };
void SetBlueParameterType(ParticleParameterType type) { blueParam = type; };
void SetAlphaParameterType(ParticleParameterType type) { alphaParam = type; };
void SetSizeParameterType(ParticleParameterType type) { sizeParam = type; };
void SetAngleParameterType(ParticleParameterType type) { angleParam = type; };
void SetParticleColor1(const gd::String& color);
void SetParticleColor2(const gd::String& color);
@@ -137,30 +124,19 @@ class GD_EXTENSION_API ParticleEmitterBase {
float GetFlow() const { return flow; };
float GetEmitterForceMin() const { return emitterForceMin; };
float GetEmitterForceMax() const { return emitterForceMax; };
float GetEmitterXDirection() const { return emitterXDirection; };
float GetEmitterYDirection() const { return emitterYDirection; };
float GetEmitterZDirection() const { return emitterZDirection; };
float GetEmitterAngleA() const { return emitterAngleA; };
float GetEmitterAngleB() const { return emitterAngleB; };
float GetConeSprayAngle() const { return GetEmitterAngleB(); };
float GetZoneRadius() const { return zoneRadius; };
float GetParticleGravityX() const { return particleGravityX; };
float GetParticleGravityY() const { return particleGravityY; };
float GetParticleGravityZ() const { return particleGravityZ; };
float GetParticleGravityAngle() const;
float GetParticleGravityLength() const;
float GetFriction() const { return friction; };
float GetParticleLifeTimeMin() const { return particleLifeTimeMin; };
float GetParticleLifeTimeMax() const { return particleLifeTimeMax; };
std::size_t GetMaxParticleNb() const { return maxParticleNb; };
bool GetDestroyWhenNoParticles() const { return destroyWhenNoParticles; };
ParticleParameterType GetRedParameterType() const { return redParam; };
ParticleParameterType GetGreenParameterType() const { return greenParam; };
ParticleParameterType GetBlueParameterType() const { return blueParam; };
ParticleParameterType GetAlphaParameterType() const { return alphaParam; };
ParticleParameterType GetSizeParameterType() const { return sizeParam; };
ParticleParameterType GetAngleParameterType() const { return angleParam; };
float GetParticleRed1() const { return particleRed1; };
float GetParticleRed2() const { return particleRed2; };
@@ -200,10 +176,8 @@ class GD_EXTENSION_API ParticleEmitterBase {
protected:
virtual void UnserializeParticleEmitterBaseFrom(
const gd::SerializerElement& element);
#if defined(GD_IDE_ONLY)
virtual void SerializeParticleEmitterBaseTo(
gd::SerializerElement& element) const;
#endif
private:
void Init(const ParticleEmitterBase& other);
@@ -217,17 +191,11 @@ class GD_EXTENSION_API ParticleEmitterBase {
float flow;
float emitterForceMin;
float emitterForceMax;
float emitterXDirection;
float emitterYDirection;
float emitterZDirection;
float emitterAngleA;
float emitterAngleB;
float zoneRadius;
float particleGravityX, particleGravityY, particleGravityZ;
float friction;
float particleGravityX, particleGravityY;
float particleLifeTimeMin, particleLifeTimeMax;
ParticleParameterType redParam, greenParam, blueParam, alphaParam, sizeParam,
angleParam;
float particleRed1, particleRed2, particleGreen1, particleGreen2,
particleBlue1, particleBlue2, particleAlpha1, particleAlpha2;
float particleSize1, particleSize2, particleAngle1, particleAngle2;
@@ -252,22 +220,12 @@ class GD_EXTENSION_API ParticleEmitterObject : public gd::Object,
return gd::make_unique<ParticleEmitterObject>(*this);
}
#if defined(GD_IDE_ONLY)
virtual void ExposeResources(gd::ArbitraryResourceWorker& worker);
bool particleEditionSimpleMode; ///< User preference related to object's
///< edition
bool emissionEditionSimpleMode; ///< User preference related to object's
///< edition
bool gravityEditionSimpleMode; ///< User preference related to object's
///< edition
#endif
private:
virtual void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element);
#if defined(GD_IDE_ONLY)
virtual void DoSerializeTo(gd::SerializerElement& element) const;
#endif
};
#endif // PARTICLEEMITTEROBJECT_H

View File

@@ -10,7 +10,6 @@ namespace gdjs {
renderer: any;
emitter: any;
started: boolean = false;
emitterLifetime: float = 0;
constructor(
runtimeScene: gdjs.RuntimeScene,
@@ -110,12 +109,10 @@ namespace gdjs {
maxParticles: objectData.maxParticleNb,
// Lifetime can be computed from the tank (the number of particles available)
// and the flow (number of particles emitted per seconds)
emitterLifetime:
objectData.tank < 0
? -1
: objectData.flow < 0
? 0.001
: objectData.tank / objectData.flow,
emitterLifetime: ParticleEmitterObjectPixiRenderer.computeLifetime(
objectData.flow,
objectData.tank
),
pos: { x: 0, y: 0 },
addAtBack: false,
spawnType: 'circle',
@@ -130,65 +127,33 @@ namespace gdjs {
: 1,
isStepped: false,
};
if (objectData.alphaParam === 'Mutable') {
// @ts-ignore
config.alpha = {
list: [
{ time: 0, value: objectData.particleAlpha1 / 255.0 },
{ time: 1, value: objectData.particleAlpha2 / 255.0 },
],
isStepped: false,
};
} else {
// @ts-ignore
config.alpha = {
list: [{ time: 0, value: objectData.particleAlpha1 / 255.0 }],
isStepped: false,
};
}
if (objectData.sizeParam === 'Mutable') {
let size1 = objectData.particleSize1 / 100;
let size2 = objectData.particleSize2 / 100;
const sizeRandom1 = objectData.particleSizeRandomness1 / 100;
const sizeRandom2 = objectData.particleSizeRandomness2 / 100;
const m = sizeRandom2 !== 0 ? (1 + sizeRandom1) / (1 + sizeRandom2) : 1;
// @ts-ignore
config.scale = {
list: [
{ time: 0, value: size1 * (1 + sizeRandom1) },
{ time: 1, value: size2 * (1 + sizeRandom2) },
],
minimumScaleMultiplier: m,
isStepped: false,
};
} else {
let size1 = objectData.particleSize1 / 100;
let size2 = objectData.particleSize2 / 100;
let mult = size2 !== 0 ? (1 + size1) / (1 + size2) : 1;
if (size2 === 0 && size1 > size2) {
mult = (1 + size2) / (1 + size1);
size2 = size1;
}
// @ts-ignore
config.scale = {
list: [{ time: 0, value: size2 }],
minimumScaleMultiplier: mult,
isStepped: false,
};
}
if (objectData.emissionEditionSimpleMode) {
// @ts-ignore
config.startRotation = {
min: -objectData.emitterAngleB / 2.0,
max: objectData.emitterAngleB / 2.0,
};
} else {
// @ts-ignore
config.startRotation = {
min: objectData.emitterAngleA,
max: objectData.emitterAngleB,
};
}
// @ts-ignore
config.alpha = {
list: [
{ time: 0, value: objectData.particleAlpha1 / 255.0 },
{ time: 1, value: objectData.particleAlpha2 / 255.0 },
],
isStepped: false,
};
let size1 = objectData.particleSize1 / 100;
let size2 = objectData.particleSize2 / 100;
const sizeRandom1 = objectData.particleSizeRandomness1 / 100;
const sizeRandom2 = objectData.particleSizeRandomness2 / 100;
const m = sizeRandom2 !== 0 ? (1 + sizeRandom1) / (1 + sizeRandom2) : 1;
// @ts-ignore
config.scale = {
list: [
{ time: 0, value: size1 * (1 + sizeRandom1) },
{ time: 1, value: size2 * (1 + sizeRandom2) },
],
minimumScaleMultiplier: m,
isStepped: false,
};
// @ts-ignore
config.startRotation = {
min: -objectData.emitterAngleB / 2.0,
max: objectData.emitterAngleB / 2.0,
};
const mediumLifetime =
(objectData.particleLifeTimeMin + objectData.particleLifeTimeMax) / 2.0;
// @ts-ignore
@@ -201,7 +166,7 @@ namespace gdjs {
this.renderer = new PIXI.Container();
// @ts-ignore
this.emitter = new PIXI.particles.Emitter(this.renderer, texture, config);
this.emitter.emit = true;
this.start();
const layer = runtimeScene.getLayer(runtimeObject.getLayer());
if (layer) {
layer
@@ -214,43 +179,50 @@ namespace gdjs {
return this.renderer;
}
update(delta): void {
update(delta: float): void {
this.emitter.update(delta);
if (!this.started && this.getParticleCount() > 0) {
this.started = true;
}
}
setPosition(x, y): void {
setPosition(x: number, y: number): void {
this.emitter.spawnPos.x = x;
this.emitter.spawnPos.y = y;
}
setAngle(angle1, angle2): void {
setAngle(angle1: float, angle2: float): void {
this.emitter.minStartRotation = angle1;
this.emitter.maxStartRotation = angle2;
}
setForce(min, max): void {
setForce(min: float, max: float): void {
this.emitter.startSpeed.value = max;
this.emitter.minimumSpeedMultiplier = max !== 0 ? min / max : 1;
}
setZoneRadius(radius): void {
setZoneRadius(radius: float): void {
this.emitter.spawnCircle.radius = radius;
}
setLifeTime(min, max): void {
setLifeTime(min: float, max: float): void {
this.emitter.minLifetime = min;
this.emitter.maxLifetime = max;
}
setGravity(x, y): void {
setGravity(x: float, y: float): void {
this.emitter.acceleration.x = x;
this.emitter.acceleration.y = y;
}
setColor(r1, g1, b1, r2, g2, b2): void {
setColor(
r1: number,
g1: number,
b1: number,
r2: number,
g2: number,
b2: number
): void {
this.emitter.startColor.value.r = r1;
this.emitter.startColor.value.g = g1;
this.emitter.startColor.value.b = b1;
@@ -263,31 +235,40 @@ namespace gdjs {
this.emitter.startColor.next.value.b = b2;
}
setSize(size1, size2): void {
setSize(size1: float, size2: float): void {
this.emitter.startScale.value = size1 / 100.0;
if (this.emitter.startScale.next) {
this.emitter.startScale.next.value = size2 / 100.0;
}
}
setAlpha(alpha1, alpha2): void {
setAlpha(alpha1: number, alpha2: number): void {
this.emitter.startAlpha.value = alpha1 / 255.0;
if (this.emitter.startAlpha.next) {
this.emitter.startAlpha.next.value = alpha2 / 255.0;
}
}
setFlow(flow, tank): void {
setFlow(flow: number, tank: number): void {
this.emitter.frequency = flow < 0 ? 0.0001 : 1.0 / flow;
this.emitterLifetime =
tank < 0
? -1
: flow < 0
? 0.001
: (tank - this.emitter.totalParticleCount) / flow;
this.emitter.emitterLifetime = ParticleEmitterObjectPixiRenderer.computeLifetime(
flow,
tank
);
}
isTextureNameValid(texture, runtimeScene): boolean {
resetEmission(flow: number, tank: number): void {
this.setFlow(flow, tank);
const wasEmitting = this.emitter.emit;
// The only way to recompute emitter lifetime is to start the emitter.
this.start();
if (!wasEmitting) this.stop();
}
isTextureNameValid(
texture: string,
runtimeScene: gdjs.RuntimeScene
): boolean {
const invalidPixiTexture = runtimeScene
.getGame()
.getImageManager()
@@ -299,7 +280,7 @@ namespace gdjs {
return pixiTexture.valid && pixiTexture !== invalidPixiTexture;
}
setTextureName(texture, runtimeScene): void {
setTextureName(texture: string, runtimeScene: gdjs.RuntimeScene): void {
const invalidPixiTexture = runtimeScene
.getGame()
.getImageManager()
@@ -313,29 +294,35 @@ namespace gdjs {
}
}
getTotalParticleCount(): integer {
return this.emitter.totalParticleCount;
}
getParticleCount(): integer {
return this.emitter.particleCount;
}
stop() {
stop(): void {
this.emitter.emit = false;
}
recreate() {
start(): void {
this.emitter.emit = true;
}
recreate(): void {
this.emitter.cleanup();
}
destroy() {
destroy(): void {
this.emitter.destroy();
}
hasStarted(): boolean {
return this.started;
}
static computeLifetime(flow: number, tank: number): float {
if (tank < 0) return -1;
else if (flow < 0) return 0.001;
else return (tank + 0.1) / flow;
}
}
// @ts-ignore - Register the class to let the engine use it.

View File

@@ -7,7 +7,6 @@
namespace gdjs {
export type ParticleEmitterObjectDataType = {
emitterAngleA: number;
emissionEditionSimpleMode: boolean;
emitterForceMin: number;
emitterAngleB: number;
zoneRadius: number;
@@ -27,7 +26,6 @@ namespace gdjs {
particleAngle2: number;
particleAngle1: number;
particleAlpha1: number;
sizeParam: string;
rendererType: string;
particleAlpha2: number;
rendererParam2: number;
@@ -51,7 +49,6 @@ namespace gdjs {
* Displays particles.
*/
export class ParticleEmitterObject extends gdjs.RuntimeObject {
singleAngle: boolean;
angleA: number;
angleB: number;
forceMin: number;
@@ -69,7 +66,6 @@ namespace gdjs {
colorB2: number;
size1: number;
size2: number;
sizeParam: string;
alpha1: number;
alpha2: number;
rendererType: string;
@@ -88,10 +84,10 @@ namespace gdjs {
_colorDirty: boolean = true;
_sizeDirty: boolean = true;
_alphaDirty: boolean = true;
_textureDirty: boolean;
// Don't mark texture as dirty if not using one.
_flowDirty: boolean = true;
_tankDirty: boolean = true;
// Don't mark texture as dirty if not using one.
_textureDirty: boolean;
// @ts-ignore
_renderer: gdjs.ParticleEmitterObjectRenderer;
@@ -110,7 +106,6 @@ namespace gdjs {
this,
particleObjectData
);
this.singleAngle = particleObjectData.emissionEditionSimpleMode;
this.angleA = particleObjectData.emitterAngleA;
this.angleB = particleObjectData.emitterAngleB;
this.forceMin = particleObjectData.emitterForceMin;
@@ -128,7 +123,6 @@ namespace gdjs {
this.colorB2 = particleObjectData.particleBlue2;
this.size1 = particleObjectData.particleSize1;
this.size2 = particleObjectData.particleSize2;
this.sizeParam = particleObjectData.sizeParam;
this.alpha1 = particleObjectData.particleAlpha1;
this.alpha2 = particleObjectData.particleAlpha2;
this.rendererType = particleObjectData.rendererType;
@@ -144,14 +138,14 @@ namespace gdjs {
this.onCreated();
}
setX(x): void {
setX(x: number): void {
if (this.x !== x) {
this._posDirty = true;
}
super.setX(x);
}
setY(y): void {
setY(y: number): void {
if (this.y !== y) {
this._posDirty = true;
}
@@ -173,13 +167,6 @@ namespace gdjs {
oldObjectData: ParticleEmitterObjectData,
newObjectData: ParticleEmitterObjectData
): boolean {
if (
oldObjectData.emissionEditionSimpleMode !==
newObjectData.emissionEditionSimpleMode
) {
this.singleAngle = newObjectData.emissionEditionSimpleMode;
this._angleDirty = true;
}
if (oldObjectData.emitterAngleA !== newObjectData.emitterAngleA) {
this.setEmitterAngleA(newObjectData.emitterAngleA);
}
@@ -235,10 +222,6 @@ namespace gdjs {
if (oldObjectData.particleSize2 !== newObjectData.particleSize2) {
this.setParticleSize2(newObjectData.particleSize2);
}
if (oldObjectData.sizeParam !== newObjectData.sizeParam) {
this.sizeParam = newObjectData.sizeParam;
this._sizeDirty = true;
}
if (oldObjectData.particleAlpha1 !== newObjectData.particleAlpha1) {
this.setParticleAlpha1(newObjectData.particleAlpha1);
}
@@ -293,7 +276,7 @@ namespace gdjs {
// to be repositioned, angle updated, etc...
this._posDirty = this._angleDirty = this._forceDirty = this._zoneRadiusDirty = true;
this._lifeTimeDirty = this._gravityDirty = this._colorDirty = this._sizeDirty = true;
this._alphaDirty = this._flowDirty = this._textureDirty = true;
this._alphaDirty = this._flowDirty = this._tankDirty = this._textureDirty = true;
}
return true;
}
@@ -304,17 +287,10 @@ namespace gdjs {
}
if (this._angleDirty) {
const angle = this.getAngle();
if (this.singleAngle) {
this._renderer.setAngle(
this.angle - this.angleB / 2.0,
this.angle + this.angleB / 2.0
);
} else {
this._renderer.setAngle(
this.angle + this.angleA,
this.angle + this.angleB
);
}
this._renderer.setAngle(
this.angle - this.angleB / 2.0,
this.angle + this.angleB / 2.0
);
}
if (this._forceDirty) {
this._renderer.setForce(this.forceMin, this.forceMax);
@@ -338,44 +314,41 @@ namespace gdjs {
this.colorB2
);
}
if (this._sizeDirty && this.sizeParam === 'Mutable') {
if (this._sizeDirty) {
this._renderer.setSize(this.size1, this.size2);
}
if (this._alphaDirty) {
this._renderer.setAlpha(this.alpha1, this.alpha2);
}
if (this._flowDirty) {
this._renderer.setFlow(this.flow, this.tank);
if (this._flowDirty || this._tankDirty) {
this._renderer.resetEmission(this.flow, this.tank);
}
if (this._textureDirty) {
this._renderer.setTextureName(this.texture, runtimeScene);
}
this._posDirty = this._angleDirty = this._forceDirty = this._zoneRadiusDirty = false;
this._lifeTimeDirty = this._gravityDirty = this._colorDirty = this._sizeDirty = false;
this._alphaDirty = this._flowDirty = this._textureDirty = false;
this._alphaDirty = this._flowDirty = this._textureDirty = this._tankDirty = false;
this._renderer.update(this.getElapsedTime(runtimeScene) / 1000.0);
if (this.tank > 0 && this._renderer.getTotalParticleCount() > this.tank) {
this._renderer.stop();
}
if (
this._renderer.hasStarted() &&
this._renderer.getParticleCount() === 0 &&
this.getParticleCount() === 0 &&
this.destroyWhenNoParticles
) {
this.deleteFromScene(runtimeScene);
}
}
onDestroyFromScene(runtimeScene): void {
onDestroyFromScene(runtimeScene: gdjs.RuntimeScene): void {
this._renderer.destroy();
super.onDestroyFromScene(runtimeScene);
}
getEmitterForceMin() {
getEmitterForceMin(): number {
return this.forceMin;
}
setEmitterForceMin(force): void {
setEmitterForceMin(force: float): void {
if (force < 0) {
force = 0;
}
@@ -385,11 +358,11 @@ namespace gdjs {
}
}
getEmitterForceMax() {
getEmitterForceMax(): number {
return this.forceMax;
}
setEmitterForceMax(force): void {
setEmitterForceMax(force: float): void {
if (force < 0) {
force = 0;
}
@@ -403,7 +376,7 @@ namespace gdjs {
return (this.angleA + this.angleB) / 2.0;
}
setEmitterAngle(angle): void {
setEmitterAngle(angle: float): void {
const oldAngle = this.getEmitterAngle();
if (angle !== oldAngle) {
this._angleDirty = true;
@@ -412,22 +385,22 @@ namespace gdjs {
}
}
getEmitterAngleA() {
getEmitterAngleA(): float {
return this.angleA;
}
setEmitterAngleA(angle): void {
setEmitterAngleA(angle: float): void {
if (this.angleA !== angle) {
this._angleDirty = true;
this.angleA = angle;
}
}
getEmitterAngleB() {
getEmitterAngleB(): float {
return this.angleB;
}
setEmitterAngleB(angle): void {
setEmitterAngleB(angle: float): void {
if (this.angleB !== angle) {
this._angleDirty = true;
this.angleB = angle;
@@ -438,7 +411,7 @@ namespace gdjs {
return Math.abs(this.angleB - this.angleA);
}
setConeSprayAngle(angle): void {
setConeSprayAngle(angle: float): void {
const oldCone = this.getConeSprayAngle();
if (oldCone !== angle) {
this._angleDirty = true;
@@ -448,11 +421,11 @@ namespace gdjs {
}
}
getZoneRadius() {
getZoneRadius(): float {
return this.zoneRadius;
}
setZoneRadius(radius): void {
setZoneRadius(radius: float): void {
if (radius < 0) {
radius = 0;
}
@@ -462,11 +435,11 @@ namespace gdjs {
}
}
getParticleLifeTimeMin() {
getParticleLifeTimeMin(): float {
return this.lifeTimeMin;
}
setParticleLifeTimeMin(lifeTime): void {
setParticleLifeTimeMin(lifeTime: float): void {
if (lifeTime < 0) {
lifeTime = 0;
}
@@ -476,11 +449,11 @@ namespace gdjs {
}
}
getParticleLifeTimeMax() {
getParticleLifeTimeMax(): float {
return this.lifeTimeMax;
}
setParticleLifeTimeMax(lifeTime): void {
setParticleLifeTimeMax(lifeTime: float): void {
if (lifeTime < 0) {
lifeTime = 0;
}
@@ -494,7 +467,7 @@ namespace gdjs {
return this.gravityX;
}
setParticleGravityX(x): void {
setParticleGravityX(x: float): void {
if (this.gravityX !== x) {
this._gravityDirty = true;
this.gravityX = x;
@@ -505,7 +478,7 @@ namespace gdjs {
return this.gravityY;
}
setParticleGravityY(y): void {
setParticleGravityY(y: float): void {
if (this.gravityY !== y) {
this._gravityDirty = true;
this.gravityY = y;
@@ -516,7 +489,7 @@ namespace gdjs {
return (Math.atan2(this.gravityY, this.gravityX) * 180.0) / Math.PI;
}
setParticleGravityAngle(angle): void {
setParticleGravityAngle(angle: float): void {
const oldAngle = this.getParticleGravityAngle();
if (oldAngle !== angle) {
this._gravityDirty = true;
@@ -526,13 +499,13 @@ namespace gdjs {
}
}
getParticleGravityLength() {
getParticleGravityLength(): float {
return Math.sqrt(
this.gravityX * this.gravityX + this.gravityY * this.gravityY
);
}
setParticleGravityLength(length): void {
setParticleGravityLength(length: float): void {
if (length < 0) {
length = 0;
}
@@ -544,11 +517,11 @@ namespace gdjs {
}
}
getParticleRed1() {
getParticleRed1(): number {
return this.colorR1;
}
setParticleRed1(red): void {
setParticleRed1(red: number): void {
if (red < 0) {
red = 0;
}
@@ -561,11 +534,11 @@ namespace gdjs {
}
}
getParticleRed2() {
getParticleRed2(): number {
return this.colorR2;
}
setParticleRed2(red): void {
setParticleRed2(red: number): void {
if (red < 0) {
red = 0;
}
@@ -578,11 +551,11 @@ namespace gdjs {
}
}
getParticleGreen1() {
getParticleGreen1(): number {
return this.colorG1;
}
setParticleGreen1(green): void {
setParticleGreen1(green: number): void {
if (green < 0) {
green = 0;
}
@@ -595,11 +568,11 @@ namespace gdjs {
}
}
getParticleGreen2() {
getParticleGreen2(): number {
return this.colorG2;
}
setParticleGreen2(green): void {
setParticleGreen2(green: number): void {
if (green < 0) {
green = 0;
}
@@ -612,11 +585,11 @@ namespace gdjs {
}
}
getParticleBlue1() {
getParticleBlue1(): number {
return this.colorB1;
}
setParticleBlue1(blue): void {
setParticleBlue1(blue: number): void {
if (blue < 0) {
blue = 0;
}
@@ -629,11 +602,11 @@ namespace gdjs {
}
}
getParticleBlue2() {
getParticleBlue2(): number {
return this.colorB2;
}
setParticleBlue2(blue): void {
setParticleBlue2(blue: number): void {
if (blue < 0) {
blue = 0;
}
@@ -646,7 +619,7 @@ namespace gdjs {
}
}
setParticleColor1(rgbColor): void {
setParticleColor1(rgbColor: string): void {
const colors = rgbColor.split(';');
if (colors.length < 3) {
return;
@@ -656,7 +629,7 @@ namespace gdjs {
this.setParticleBlue1(parseInt(colors[2], 10));
}
setParticleColor2(rgbColor): void {
setParticleColor2(rgbColor: string): void {
const colors = rgbColor.split(';');
if (colors.length < 3) {
return;
@@ -666,11 +639,11 @@ namespace gdjs {
this.setParticleBlue2(parseInt(colors[2], 10));
}
getParticleSize1() {
getParticleSize1(): float {
return this.size1;
}
setParticleSize1(size): void {
setParticleSize1(size: float): void {
if (size < 0) {
size = 0;
}
@@ -680,75 +653,88 @@ namespace gdjs {
}
}
getParticleSize2() {
getParticleSize2(): float {
return this.size2;
}
setParticleSize2(size): void {
setParticleSize2(size: float): void {
if (this.size2 !== size) {
this._sizeDirty = true;
this.size2 = size;
}
}
getParticleAlpha1() {
getParticleAlpha1(): number {
return this.alpha1;
}
setParticleAlpha1(alpha): void {
setParticleAlpha1(alpha: number): void {
if (this.alpha1 !== alpha) {
this._alphaDirty = true;
this.alpha1 = alpha;
}
}
getParticleAlpha2() {
getParticleAlpha2(): number {
return this.alpha2;
}
setParticleAlpha2(alpha): void {
setParticleAlpha2(alpha: number): void {
if (this.alpha2 !== alpha) {
this._alphaDirty = true;
this.alpha2 = alpha;
}
}
noMoreParticles() {
startEmission(): void {
this._renderer.start();
}
stopEmission(): void {
this._renderer.stop();
}
recreateParticleSystem() {
isEmitting(): boolean {
return this._renderer.emitter.emit;
}
noMoreParticles(): boolean {
return !this.isEmitting();
}
recreateParticleSystem(): void {
this._renderer.recreate();
}
getFlow() {
getFlow(): number {
return this.flow;
}
setFlow(flow): void {
setFlow(flow: number): void {
if (this.flow !== flow) {
this.flow = flow;
this._flowDirty = true;
}
}
getParticleCount() {
getParticleCount(): number {
return this._renderer.getParticleCount();
}
getTank() {
getTank(): number {
return this.tank;
}
setTank(tank): void {
setTank(tank: number): void {
this.tank = tank;
this._tankDirty = true;
}
getTexture() {
getTexture(): string {
return this.texture;
}
setTexture(texture, runtimeScene): void {
setTexture(texture: string, runtimeScene: gdjs.RuntimeScene): void {
if (this.texture !== texture) {
if (this._renderer.isTextureNameValid(texture, runtimeScene)) {
this.texture = texture;

View File

@@ -3798,20 +3798,20 @@ namespace gdjs {
}
// Collision
static collisionTest(object1, object2, behaviorName) {
// Check if the objects exist and share the behavior
if (object1 === null || !object1.hasBehavior(behaviorName)) {
return false;
}
if (object2 === null || !object2.hasBehavior(behaviorName)) {
return false;
}
static collisionTest(
object1: gdjs.RuntimeObject,
object2: gdjs.RuntimeObject,
behaviorName: string
): boolean {
// Test if the second object is in the list of contacts of the first one
const behavior1 = object1.getBehavior(behaviorName);
for (let i = 0, len = behavior1.currentContacts.length; i < len; ++i) {
if (behavior1.currentContacts[i].owner === object2) {
return true;
const behavior1 = object1.getBehavior(
behaviorName
) as Physics2RuntimeBehavior;
if (!!behavior1) {
for (let i = 0, len = behavior1.currentContacts.length; i < len; ++i) {
if (behavior1.currentContacts[i].owner === object2) {
return true;
}
}
}

View File

@@ -1,17 +1,17 @@
namespace gdjs {
export namespace physics2 {
export const objectsCollide = function (
objectsLists1,
behavior,
objectsLists2,
inverted
objectsLists1: Hashtable<Array<gdjs.RuntimeObject>>,
behaviorName: string,
objectsLists2: Hashtable<Array<gdjs.RuntimeObject>>,
inverted: boolean
) {
return gdjs.evtTools.object.twoListsTest(
gdjs.Physics2RuntimeBehavior.collisionTest,
objectsLists1,
objectsLists2,
inverted,
behavior
behaviorName
);
};

View File

@@ -41,7 +41,6 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
std::make_shared<PlatformerObjectBehavior>(),
std::make_shared<gd::BehaviorsSharedData>());
#if defined(GD_IDE_ONLY)
aut.AddCondition("IsMoving",
_("Is moving"),
_("Check if the object is moving (whether it is on the "
@@ -53,8 +52,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("IsMoving")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsMoving");
aut.AddCondition("IsOnFloor",
_("Is on floor"),
@@ -66,8 +64,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("IsOnFloor")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsOnFloor");
aut.AddCondition("IsOnLadder",
_("Is on ladder"),
@@ -79,8 +76,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("IsOnLadder")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsOnLadder");
aut.AddCondition("IsJumping",
_("Is jumping"),
@@ -92,8 +88,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("IsJumping")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsJumping");
aut.AddCondition(
"IsFalling",
@@ -107,8 +102,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("IsFalling")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsFalling");
aut.AddCondition("IsGrabbingPlatform",
_("Is grabbing platform ledge"),
@@ -119,8 +113,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("IsGrabbingPlatform")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IsGrabbingPlatform");
aut.AddCondition("Gravity",
_("Gravity"),
@@ -134,8 +127,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetGravity")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetGravity");
aut.AddAction("Gravity",
_("Gravity"),
@@ -150,8 +142,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetGravity")
.SetGetter("GetGravity")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetGravity");
aut.AddCondition(
"MaxFallingSpeed",
@@ -166,8 +157,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetMaxFallingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetMaxFallingSpeed");
aut.AddAction(
"MaxFallingSpeed",
@@ -183,8 +173,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetMaxFallingSpeed")
.SetGetter("GetMaxFallingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetMaxFallingSpeed");
aut.AddCondition("LadderClimbingSpeed",
_("Ladder climbing speed"),
@@ -198,8 +187,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetLadderClimbingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetLadderClimbingSpeed");
aut.AddAction("LadderClimbingSpeed",
_("Ladder climbing speed"),
@@ -214,8 +202,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetLadderClimbingSpeed")
.SetGetter("GetLadderClimbingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetLadderClimbingSpeed");
aut.AddCondition("Acceleration",
_("Acceleration"),
@@ -229,8 +216,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetAcceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetAcceleration");
aut.AddAction("Acceleration",
_("Acceleration"),
@@ -245,8 +231,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetAcceleration")
.SetGetter("GetAcceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetAcceleration");
aut.AddCondition("Deceleration",
_("Deceleration"),
@@ -260,8 +245,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetDeceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetDeceleration");
aut.AddAction("Deceleration",
_("Deceleration"),
@@ -276,8 +260,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetDeceleration")
.SetGetter("GetDeceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetDeceleration");
aut.AddCondition(
"MaxSpeed",
@@ -290,8 +273,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.SetFunctionName("GetMaxSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetMaxSpeed");
aut.AddAction(
"MaxSpeed",
@@ -306,8 +288,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.UseStandardOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("SetMaxSpeed")
.SetGetter("GetMaxSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetMaxSpeed");
aut.AddCondition(
"JumpSpeed",
@@ -321,8 +302,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetJumpSpeed");
aut.AddAction(
"JumpSpeed",
@@ -336,8 +316,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardOperatorParameters("number")
.SetFunctionName("SetJumpSpeed")
.SetGetter("GetJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetGetter("GetJumpSpeed");
aut.AddCondition(
"JumpSustainTime",
@@ -378,8 +357,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("SetCanJump")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SetCanJump");
aut.AddScopedAction(
"SetCanNotAirJump",
@@ -404,8 +382,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("canJump")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("canJump");
aut.AddAction("SimulateLeftKey",
_("Simulate left key press"),
@@ -417,8 +394,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("SimulateLeftKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateLeftKey");
aut.AddAction("SimulateRightKey",
_("Simulate right key press"),
@@ -430,8 +406,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("SimulateRightKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateRightKey");
aut.AddAction("SimulateUpKey",
_("Simulate up key press"),
@@ -443,8 +418,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("SimulateUpKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateUpKey");
aut.AddAction(
"SimulateDownKey",
@@ -457,8 +431,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("SimulateDownKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateDownKey");
aut.AddAction(
"SimulateLadderKey",
@@ -471,8 +444,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsAdvanced()
.SetFunctionName("SimulateLadderKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateLadderKey");
aut.AddAction(
"SimulateReleaseLadderKey",
@@ -495,8 +467,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"res/conditions/keyboard.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("SimulateJumpKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateJumpKey");
aut.AddAction("SimulateReleasePlatformKey",
_("Simulate release platform key press"),
@@ -508,8 +479,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"res/conditions/keyboard.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("SimulateReleasePlatformKey")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateReleasePlatformKey");
// Support for deprecated names:
aut.AddDuplicatedAction("SimulateReleaseKey", "SimulateReleasePlatformKey").SetHidden();
@@ -528,8 +498,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
_("Key"),
"[\"Left\", \"Right\", \"Jump\", \"Ladder\", \"Release Ladder\", \"Up\", \"Down\"]")
.MarkAsAdvanced()
.SetFunctionName("SimulateControl")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("SimulateControl");
aut.AddAction("IgnoreDefaultControls",
_("Ignore default controls"),
@@ -543,8 +512,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.AddParameter("yesorno", _("Ignore controls"))
.MarkAsAdvanced()
.SetFunctionName("IgnoreDefaultControls")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("IgnoreDefaultControls");
aut.AddAction("CanGrabPlatforms",
_("Platform grabbing"),
@@ -569,8 +537,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.MarkAsSimple()
.SetFunctionName("canGrabPlatforms")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("canGrabPlatforms");
aut.AddCondition(
"CurrentFallSpeed",
@@ -585,8 +552,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetCurrentFallSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetCurrentFallSpeed");
aut.AddCondition(
"CurrentJumpSpeed",
@@ -601,8 +567,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetCurrentJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetCurrentJumpSpeed");
aut.AddCondition("CurrentSpeed",
_("Current speed"),
@@ -616,8 +581,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced()
.SetFunctionName("GetCurrentSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetCurrentSpeed");
aut.AddExpression("Gravity",
_("Gravity"),
@@ -626,8 +590,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetGravity")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetGravity");
aut.AddExpression("MaxFallingSpeed",
_("Maximum falling speed"),
@@ -636,8 +599,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetMaxFallingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetMaxFallingSpeed");
aut.AddExpression("LadderClimbingSpeed",
_("Ladder climbing speed"),
@@ -646,8 +608,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetLadderClimbingSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetLadderClimbingSpeed");
aut.AddExpression("Acceleration",
_("Acceleration"),
@@ -656,8 +617,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetAcceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetAcceleration");
aut.AddExpression("Deceleration",
_("Deceleration"),
@@ -666,8 +626,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetDeceleration")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetDeceleration");
aut.AddExpression("MaxSpeed",
_("Maximum speed"),
@@ -676,8 +635,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetMaxSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetMaxSpeed");
aut.AddExpression("JumpSpeed",
_("Jump speed"),
@@ -686,8 +644,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetJumpSpeed");
aut.AddExpression("JumpSustainTime",
_("Jump sustain time"),
@@ -705,8 +662,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetCurrentFallSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetCurrentFallSpeed");
aut.AddExpression("CurrentSpeed",
_("Current speed"),
@@ -715,8 +671,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetCurrentSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
.SetFunctionName("GetCurrentSpeed");
aut.AddExpression("CurrentJumpSpeed",
_("Current jump speed"),
@@ -725,9 +680,7 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"CppPlatform/Extensions/platformerobjecticon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.SetFunctionName("GetCurrentJumpSpeed")
.SetIncludeFile("PlatformBehavior/PlatformerObjectRuntimeBehavior.h");
#endif
.SetFunctionName("GetCurrentJumpSpeed");
}
{
gd::BehaviorMetadata& aut = extension.AddBehavior(
@@ -741,8 +694,6 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
std::make_shared<PlatformBehavior>(),
std::make_shared<gd::BehaviorsSharedData>());
#if defined(GD_IDE_ONLY)
aut.SetIncludeFile("PlatformBehavior/PlatformRuntimeBehavior.h");
aut.AddAction("ChangePlatformType",
_("Change platform type"),
@@ -758,8 +709,19 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
"string",
_("Platform type (\"Platform\", \"Jumpthru\" or \"Ladder\")"))
.MarkAsAdvanced()
.SetFunctionName("ChangePlatformType")
.SetIncludeFile("PlatformBehavior/PlatformRuntimeBehavior.h");
#endif
.SetFunctionName("ChangePlatformType");
}
extension.AddCondition("IsObjectOnGivenFloor",
_("Is object on given floor"),
_("Test if an object is on a given floor."),
_("_PARAM0_ is on floor _PARAM2_"),
_("Platforms"),
"CppPlatform/Extensions/platformicon24.png",
"CppPlatform/Extensions/platformicon16.png")
.AddParameter("objectList", _("Object"), "", false)
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
.AddParameter("objectList", _("Platforms"), "", false)
.AddCodeOnlyParameter("conditionInverted", "")
.SetFunctionName("gdjs.evtTools.platform.isOnPlatform");
}

View File

@@ -4,7 +4,6 @@ GDevelop - Platform Behavior Extension
Copyright (c) 2014-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
@@ -30,13 +29,17 @@ class PlatformBehaviorJsExtension : public gd::PlatformExtension {
.SetIncludeFile(
"Extensions/PlatformBehavior/platformruntimebehavior.js")
.AddIncludeFile(
"Extensions/PlatformBehavior/platformerobjectruntimebehavior.js");
"Extensions/PlatformBehavior/platformerobjectruntimebehavior.js")
.AddIncludeFile(
"Extensions/PlatformBehavior/platformtools.js");
GetBehaviorMetadata("PlatformBehavior::PlatformerObjectBehavior")
.SetIncludeFile(
"Extensions/PlatformBehavior/platformruntimebehavior.js")
.AddIncludeFile(
"Extensions/PlatformBehavior/platformerobjectruntimebehavior.js");
"Extensions/PlatformBehavior/platformerobjectruntimebehavior.js")
.AddIncludeFile(
"Extensions/PlatformBehavior/platformtools.js");
{
std::map<gd::String, gd::InstructionMetadata>& autActions =
@@ -115,7 +118,7 @@ class PlatformBehaviorJsExtension : public gd::PlatformExtension {
.SetFunctionName("setCanGrabPlatforms")
.SetGetter("canGrabPlatforms");
autConditions["PlatformBehavior::CanGrabPlatforms"].SetFunctionName(
"canGrabPlatforms");
"canGrabPlatforms");
autConditions["PlatformBehavior::CurrentJumpSpeed"].SetFunctionName(
"getCurrentJumpSpeed");
autExpressions["CurrentJumpSpeed"].SetFunctionName("getCurrentJumpSpeed");
@@ -172,5 +175,3 @@ extern "C" gd::PlatformExtension* GD_EXTENSION_API CreateGDJSExtension() {
return new PlatformBehaviorJsExtension;
}
#endif
#endif

View File

@@ -1099,13 +1099,25 @@ namespace gdjs {
}
/**
* Check if the Platformer Object is on the floor.
* @returns Returns true if on the floor and false if not.
* Check if the Platformer Object is on a floor.
* @returns Returns true if on a floor and false if not.
*/
isOnFloor(): boolean {
return this._state === this._onFloor;
}
/**
* Check if the Platformer Object is on the given object.
* @returns Returns true if on the object and false if not.
*/
isOnFloorObject(object: gdjs.RuntimeObject): boolean {
if (this.isOnFloor()) {
const floorPlatform = this._onFloor.getFloorPlatform();
return !!floorPlatform && floorPlatform.owner.id === object.id;
}
return false;
}
/**
* Check if the Platformer Object is on a ladder.
* @returns Returns true if on a ladder and false if not.

View File

@@ -229,6 +229,17 @@ namespace gdjs {
static NORMALPLAFTORM = 0;
static JUMPTHRU = 1;
static LADDER = 2;
static isOnPlatformTest(
object1: gdjs.RuntimeObject,
object2: gdjs.RuntimeObject,
behaviorName: string
): boolean {
const behavior1 = object1.getBehavior(
behaviorName
) as PlatformerObjectRuntimeBehavior;
return behavior1.isOnFloorObject(object2);
}
}
gdjs.registerBehavior(
'PlatformBehavior::PlatformBehavior',

View File

@@ -0,0 +1,20 @@
namespace gdjs {
export namespace evtTools {
export namespace platform {
export const isOnPlatform = function (
objectsLists1: Hashtable<Array<gdjs.RuntimeObject>>,
behaviorName: string,
objectsLists2: Hashtable<Array<gdjs.RuntimeObject>>,
inverted: boolean
) {
return gdjs.evtTools.object.twoListsTest(
gdjs.PlatformRuntimeBehavior.isOnPlatformTest,
objectsLists1,
objectsLists2,
inverted,
behaviorName
);
};
}
}
}

View File

@@ -5,13 +5,14 @@ Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#include "GDCore/Tools/Localization.h"
#include "ShapePainterObject.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Project/InitialInstance.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "ShapePainterObject.h"
#include "GDCore/Tools/Localization.h"
#if defined(GD_IDE_ONLY)
#include "GDCore/CommonTools.h"
@@ -35,7 +36,7 @@ ShapePainterObjectBase::ShapePainterObjectBase()
ShapePainterObject::ShapePainterObject(gd::String name_) : gd::Object(name_) {}
void ShapePainterObjectBase::DoUnserializeFrom(
const gd::SerializerElement& element) {
gd::Project& project, const gd::SerializerElement& element) {
fillOpacity =
element.GetChild("fillOpacity", 0, "FillOpacity").GetValue().GetInt();
outlineSize =
@@ -62,12 +63,15 @@ void ShapePainterObjectBase::DoUnserializeFrom(
element.GetChild("absoluteCoordinates", 0, "AbsoluteCoordinates")
.GetValue()
.GetBool();
clearBetweenFrames = element.HasChild("clearBetweenFrames") ? element.GetChild("clearBetweenFrames").GetValue().GetBool() : true;
clearBetweenFrames =
element.HasChild("clearBetweenFrames")
? element.GetChild("clearBetweenFrames").GetValue().GetBool()
: true;
}
void ShapePainterObject::DoUnserializeFrom(
gd::Project& project, const gd::SerializerElement& element) {
ShapePainterObjectBase::DoUnserializeFrom(element);
ShapePainterObjectBase::DoUnserializeFrom(project, element);
}
#if defined(GD_IDE_ONLY)

View File

@@ -8,15 +8,18 @@ This project is released under the MIT License.
#ifndef SHAPEPAINTEROBJECT_H
#define SHAPEPAINTEROBJECT_H
#include <vector>
#include "GDCore/Project/Object.h"
namespace gd {
class Object;
class InitialInstance;
class Project;
}
} // namespace gd
/**
* \brief Base object storing the setup of a drawer object.
* \brief Base object storing the setup of a shape painter object.
* \todo This is useless (now that GDCpp is removed). It should be merged
* with ShapePainterObject.
*/
class GD_EXTENSION_API ShapePainterObjectBase {
public:
@@ -58,7 +61,8 @@ class GD_EXTENSION_API ShapePainterObjectBase {
inline bool IsClearedBetweenFrames() { return clearBetweenFrames; }
protected:
virtual void DoUnserializeFrom(const gd::SerializerElement& element);
virtual void DoUnserializeFrom(gd::Project& project,
const gd::SerializerElement& element);
#if defined(GD_IDE_ONLY)
virtual void DoSerializeTo(gd::SerializerElement& element) const;
#endif

View File

@@ -9,6 +9,7 @@ This project is released under the MIT License.
* Victor Levasseur ( Bold/Italic/Underlined styles )
*/
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "TextObject.h"
@@ -73,33 +74,6 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
.SetFunctionName("ChangeFont")
.SetIncludeFile("TextObject/TextObject.h");
obj.AddAction("Size",
_("Size"),
_("Change the size of the text."),
_("the size of the text"),
"",
"res/actions/characterSize24.png",
"res/actions/characterSize.png")
.AddParameter("object", _("Object"), "Text")
.UseStandardOperatorParameters("number")
.SetFunctionName("SetCharacterSize")
.SetGetter("GetCharacterSize")
.SetIncludeFile("TextObject/TextObject.h");
obj.AddCondition("Size",
_("Size"),
_("Compare the size of the text"),
_("the size of the text"),
"",
"res/conditions/characterSize24.png",
"res/conditions/characterSize.png")
.AddParameter("object", _("Object"), "Text")
.UseStandardRelationalOperatorParameters("number")
.SetFunctionName("GetCharacterSize")
.SetIncludeFile("TextObject/TextObject.h");
obj.AddCondition("ScaleX",
_("Scale on X axis"),
_("Compare the scale of the text on the X axis"),
@@ -539,6 +513,21 @@ void DeclareTextObjectExtension(gd::PlatformExtension& extension) {
.SetFunctionName("GetAngle")
.SetIncludeFile("TextObject/TextObject.h");
obj.AddExpressionAndConditionAndAction(
"number",
"FontSize",
_("Font size"),
_("the font size of a text object"),
_("the font size"),
"",
"res/conditions/characterSize24.png")
.AddParameter("object", _("Object"), "Text")
.UseStandardParameters("number");
// Support for deprecated "Size" actions/conditions:
obj.AddDuplicatedAction("Size", "Text::SetFontSize").SetHidden();
obj.AddDuplicatedCondition("Size", "Text::FontSize").SetHidden();
obj.AddStrExpression(
"String", _("Text"), _("Text"), _("Text"), "res/texteicon.png")
.AddParameter("object", _("Object"), "Text")

View File

@@ -5,14 +5,12 @@ Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include <iostream>
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "TextObject.h"
#include <iostream>
#include "GDCore/Tools/Localization.h"
void DeclareTextObjectExtension(gd::PlatformExtension& extension);
/**
@@ -33,204 +31,106 @@ class TextObjectJsExtension : public gd::PlatformExtension {
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
GetAllActionsForObject("TextObject::Text")["TextObject::Scale"]
.SetFunctionName("setScale")
.SetGetter("getScale")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getScale");
GetAllActionsForObject("TextObject::Text")["TextObject::ScaleX"]
.SetFunctionName("setScaleX")
.SetGetter("getScaleX")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getScaleX");
GetAllConditionsForObject("TextObject::Text")["TextObject::ScaleX"]
.SetFunctionName("getScaleX")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getScaleX");
GetAllActionsForObject("TextObject::Text")["TextObject::ScaleY"]
.SetFunctionName("setScaleY")
.SetGetter("getScaleY")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getScaleY");
GetAllConditionsForObject("TextObject::Text")["TextObject::ScaleY"]
.SetFunctionName("getScaleY")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getScaleY");
GetAllActionsForObject("TextObject::Text")["TextObject::String"]
.SetFunctionName("setString")
.SetGetter("getString")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getString");
GetAllConditionsForObject("TextObject::Text")["TextObject::String"]
.SetFunctionName("getString")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getString");
GetAllActionsForObject("TextObject::Text")["TextObject::Text::SetFontSize"]
.SetFunctionName("setCharacterSize")
.SetGetter("getCharacterSize");
GetAllConditionsForObject("TextObject::Text")["TextObject::Text::FontSize"]
.SetFunctionName("getCharacterSize");
GetAllExpressionsForObject("TextObject::Text")["FontSize"]
.SetFunctionName("getCharacterSize");
// Deprecated actions/conditions (use "FontSize"/"SetFontSize" instead):
GetAllActionsForObject("TextObject::Text")["TextObject::Size"]
.SetFunctionName("setCharacterSize")
.SetGetter("getCharacterSize")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getCharacterSize");
GetAllConditionsForObject("TextObject::Text")["TextObject::Size"]
.SetFunctionName("getCharacterSize")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getCharacterSize");
GetAllActionsForObject("TextObject::Text")["TextObject::Angle"]
.SetFunctionName("setAngle")
.SetGetter("getAngle")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getAngle");
GetAllConditionsForObject("TextObject::Text")["TextObject::Angle"]
.SetFunctionName("getAngle")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getAngle");
GetAllActionsForObject("TextObject::Text")["TextObject::Opacity"]
.SetFunctionName("setOpacity")
.SetGetter("getOpacity")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getOpacity");
GetAllConditionsForObject("TextObject::Text")["TextObject::Opacity"]
.SetFunctionName("getOpacity")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getOpacity");
GetAllActionsForObject("TextObject::Text")["TextObject::SetBold"]
.SetFunctionName("setBold")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setBold");
GetAllConditionsForObject("TextObject::Text")["TextObject::IsBold"]
.SetFunctionName("isBold")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("isBold");
GetAllActionsForObject("TextObject::Text")["TextObject::SetItalic"]
.SetFunctionName("setItalic")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setItalic");
GetAllConditionsForObject("TextObject::Text")["TextObject::IsItalic"]
.SetFunctionName("isItalic")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("isItalic");
GetAllActionsForObject("TextObject::Text")["TextObject::SetWrapping"]
.SetFunctionName("setWrapping")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setWrapping");
GetAllConditionsForObject("TextObject::Text")["TextObject::IsWrapping"]
.SetFunctionName("isWrapping")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("isWrapping");
GetAllActionsForObject("TextObject::Text")["TextObject::SetPadding"]
.SetFunctionName("setPadding")
.SetGetter("getPadding")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getPadding");
GetAllConditionsForObject("TextObject::Text")["TextObject::Padding"]
.SetFunctionName("getPadding")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getPadding");
GetAllActionsForObject("TextObject::Text")["TextObject::SetTextAlignment"]
.SetFunctionName("setTextAlignment")
.SetGetter("getTextAlignment")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getTextAlignment");
GetAllConditionsForObject("TextObject::Text")["TextObject::TextAlignment"]
.SetFunctionName("getTextAlignment")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getTextAlignment");
GetAllActionsForObject("TextObject::Text")["TextObject::WrappingWidth"]
.SetFunctionName("setWrappingWidth")
.SetGetter("getWrappingWidth")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetGetter("getWrappingWidth");
GetAllConditionsForObject("TextObject::Text")["TextObject::WrappingWidth"]
.SetFunctionName("getWrappingWidth")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getWrappingWidth");
GetAllExpressionsForObject("TextObject::Text")["Padding"]
.SetFunctionName("getPadding")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getPadding");
GetAllExpressionsForObject("TextObject::Text")["ScaleX"]
.SetFunctionName("getScaleX")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getScaleX");
GetAllExpressionsForObject("TextObject::Text")["ScaleY"]
.SetFunctionName("getScaleY")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getScaleY");
GetAllExpressionsForObject("TextObject::Text")["Opacity"]
.SetFunctionName("getOpacity")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getOpacity");
GetAllExpressionsForObject("TextObject::Text")["Angle"]
.SetFunctionName("getAngle")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getAngle");
GetAllStrExpressionsForObject("TextObject::Text")["String"]
.SetFunctionName("getString")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("getString");
GetAllActionsForObject("TextObject::Text")["TextObject::ChangeColor"]
.SetFunctionName("setColor")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setColor");
GetAllActionsForObject("TextObject::Text")["TextObject::SetGradient"]
.SetFunctionName("setGradient")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setGradient");
GetAllActionsForObject("TextObject::Text")["TextObject::SetOutline"]
.SetFunctionName("setOutline")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setOutline");
GetAllActionsForObject("TextObject::Text")["TextObject::SetShadow"]
.SetFunctionName("setShadow")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("setShadow");
GetAllActionsForObject("TextObject::Text")["TextObject::ShowShadow"]
.SetFunctionName("showShadow")
.SetIncludeFile("Extensions/TextObject/textruntimeobject.js")
.AddIncludeFile(
"Extensions/TextObject/textruntimeobject-pixi-renderer.js");
.SetFunctionName("showShadow");
// Unimplemented actions and conditions:
GetAllActionsForObject("TextObject::Text")["TextObject::Font"]

View File

@@ -224,7 +224,7 @@ namespace gdjs {
/**
* Get the font size of the characters of the object.
*/
getCharacterSize() {
getCharacterSize(): number {
return this._characterSize;
}

View File

@@ -498,7 +498,7 @@ module.exports = {
.addParameter('object', _('Object'), '', false)
.addParameter('behavior', _('Behavior'), 'TweenBehavior', false)
.addParameter('string', _('Tween Identifier'), '', false)
.addParameter('string', _('To color'), '', false)
.addParameter('color', _('To color'), '', false)
.addParameter('stringWithSelector', _('Easing'), easingChoices, false)
.setDefaultValue('linear')
.addParameter('expression', _('Duration'), '', false)

View File

@@ -37,13 +37,13 @@ AudioExtension::AudioExtension() {
GetAllActions()["PreloadMusic"].SetFunctionName(
"gdjs.evtTools.sound.preloadMusic");
GetAllActions()["PreloadSound"].SetFunctionName(
"gdjs.evtTools.sound.preloadSound");
"gdjs.evtTools.sound.preloadSound");
GetAllActions()["UnloadMusic"].SetFunctionName(
"gdjs.evtTools.sound.unloadMusic");
GetAllActions()["UnloadSound"].SetFunctionName(
"gdjs.evtTools.sound.unloadSound");
GetAllActions()["UnloadAllAudio"].SetFunctionName(
"gdjs.evtTools.sound.unloadAllAudio");
"gdjs.evtTools.sound.unloadAllAudio");
GetAllConditions()["MusicPlaying"].SetFunctionName(
"gdjs.evtTools.sound.isMusicOnChannelPlaying");
@@ -117,14 +117,4 @@ AudioExtension::AudioExtension() {
StripUnimplementedInstructionsAndExpressions();
}
void AudioExtension::ExposeActionsResources(
gd::Instruction& action, gd::ArbitraryResourceWorker& worker) {
if (action.GetType() == "PlaySound" || action.GetType() == "PlaySoundCanal" ||
action.GetType() == "PlayMusic" || action.GetType() == "PlayMusicCanal") {
gd::String parameter = action.GetParameter(1).GetPlainString();
worker.ExposeAudio(parameter);
action.SetParameter(1, parameter);
}
}
} // namespace gdjs

View File

@@ -18,9 +18,6 @@ class AudioExtension : public gd::PlatformExtension {
public:
AudioExtension();
virtual ~AudioExtension(){};
virtual void ExposeActionsResources(gd::Instruction& action,
gd::ArbitraryResourceWorker& worker);
};
} // namespace gdjs

View File

@@ -6,16 +6,55 @@
namespace gdjs {
import PIXI = GlobalPIXIModule.PIXI;
const logFileLoadingError = (file: string, error: Error | undefined) => {
console.error(
'Unable to load file ' + file + ' with error:',
error ? error : '(unknown error)'
);
};
const applyTextureSettings = (
texture: PIXI.Texture | undefined,
resourceData: ResourceData
) => {
if (!texture) return;
if (!resourceData.smoothed) {
texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
}
};
const findResourceWithNameAndKind = (
resources: ResourceData[],
resourceName: string,
kind: ResourceKind
): ResourceData | null => {
for (let i = 0, len = resources.length; i < len; ++i) {
const res = resources[i];
if (res.name === resourceName && res.kind === kind) {
return res;
}
}
return null;
};
/**
* PixiImageManager loads and stores textures that can be used by the Pixi.js renderers.
*/
export class PixiImageManager {
_resources: any;
_resources: ResourceData[];
// The invalid texture is a 8x8 PNG file filled with magenta (#ff00ff), to be
// easily spotted if rendered on screen.
_invalidTexture: any;
_loadedTextures: any;
/**
* The invalid texture is a 8x8 PNG file filled with magenta (#ff00ff), to be
* easily spotted if rendered on screen.
*/
_invalidTexture: PIXI.Texture;
/**
* Map associated resource name to the loaded PixiJS texture.
*/
_loadedTextures: Hashtable<PIXI.Texture<PIXI.Resource>>;
/**
* @param resources The resources data of the game.
@@ -50,7 +89,9 @@ namespace gdjs {
return texture;
} else {
console.error(
'Texture for ' + resourceName + ' is not valid anymore.'
'Texture for ' +
resourceName +
' is not valid anymore (or never was).'
);
}
}
@@ -58,29 +99,29 @@ namespace gdjs {
return this._invalidTexture;
}
//Texture is not loaded, load it now from the resources list.
if (this._resources) {
let texture: PIXI.Texture | null = null;
for (let i = 0, len = this._resources.length; i < len; ++i) {
const res = this._resources[i];
if (res.name === resourceName && res.kind === 'image') {
texture = PIXI.Texture.from(res.file);
if (!res.smoothed) {
texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
}
break;
}
}
if (texture !== null) {
console.log('Loaded texture for resource "' + resourceName + '".');
this._loadedTextures.put(resourceName, texture);
return texture;
}
}
console.warn(
'Unable to find texture for resource "' + resourceName + '".'
// Texture is not loaded, load it now from the resources list.
const resource = findResourceWithNameAndKind(
this._resources,
resourceName,
'image'
);
return this._invalidTexture;
if (!resource) {
console.warn(
'Unable to find texture for resource "' + resourceName + '".'
);
return this._invalidTexture;
}
console.log('Loading texture for resource "' + resourceName + '"...');
const file = resource.file;
const texture = PIXI.Texture.from(file).on('error', (error) => {
logFileLoadingError(file, error);
});
applyTextureSettings(texture, resource);
this._loadedTextures.put(resourceName, texture);
return texture;
}
/**
@@ -96,28 +137,30 @@ namespace gdjs {
return this._invalidTexture;
}
//Texture is not loaded, load it now from the resources list.
if (this._resources) {
let texture: PIXI.Texture | null = null;
for (let i = 0, len = this._resources.length; i < len; ++i) {
const res = this._resources[i];
if (res.name === resourceName && res.kind === 'video') {
texture = PIXI.Texture.from(res.file);
break;
}
}
if (texture !== null) {
console.log(
'Loaded video texture for resource "' + resourceName + '".'
);
this._loadedTextures.put(resourceName, texture);
return texture;
}
}
console.warn(
'Unable to find video texture for resource "' + resourceName + '".'
// Texture is not loaded, load it now from the resources list.
const resource = findResourceWithNameAndKind(
this._resources,
resourceName,
'video'
);
return this._invalidTexture;
if (!resource) {
console.warn(
'Unable to find video texture for resource "' + resourceName + '".'
);
return this._invalidTexture;
}
const file = resource.file;
console.log(
'Loading video texture for resource "' + resourceName + '"...'
);
const texture = PIXI.Texture.from(file).on('error', (error) => {
logFileLoadingError(file, error);
});
this._loadedTextures.put(resourceName, texture);
return texture;
}
/**
@@ -137,57 +180,59 @@ namespace gdjs {
loadTextures(onProgress, onComplete) {
const resources = this._resources;
//Construct the list of files to be loaded.
//For one loaded file, it can have one or more resources
//that use it.
const files = {};
// Construct the list of files to be loaded.
// For one loaded file, it can have one or more resources
// that use it.
const resourceFiles: Record<string, ResourceData[]> = {};
for (let i = 0, len = resources.length; i < len; ++i) {
const res = resources[i];
if (res.file && res.kind === 'image') {
if (this._loadedTextures.containsKey(res.name)) {
// This resource is already loaded.
continue;
}
files[res.file] = files[res.file]
? files[res.file].concat(res)
resourceFiles[res.file] = resourceFiles[res.file]
? resourceFiles[res.file].concat(res)
: [res];
}
}
const totalCount = Object.keys(files).length;
const totalCount = Object.keys(resourceFiles).length;
if (totalCount === 0) {
return onComplete(
//Nothing to load.
totalCount
);
// Nothing to load.
return onComplete(totalCount);
}
const loader = PIXI.Loader.shared;
const that = this;
let loadingCount = 0;
const progressCallbackId = loader.onProgress.add(function () {
loadingCount++;
onProgress(loadingCount, totalCount);
});
for (const file in files) {
if (files.hasOwnProperty(file)) {
for (const file in resourceFiles) {
if (resourceFiles.hasOwnProperty(file)) {
loader.add(file, file);
}
}
loader.load(function (loader, loadedFiles) {
loader.load((loader, loadedPixiResources) => {
loader.onProgress.detach(progressCallbackId);
//Store the loaded textures so that they are ready to use.
for (const file in loadedFiles) {
if (loadedFiles.hasOwnProperty(file)) {
if (!files.hasOwnProperty(file)) {
// Store the loaded textures so that they are ready to use.
for (const file in loadedPixiResources) {
if (loadedPixiResources.hasOwnProperty(file)) {
if (!resourceFiles.hasOwnProperty(file)) {
continue;
}
files[file].forEach(function (res) {
// @ts-ignore
that._loadedTextures.put(res.name, loadedFiles[file].texture);
if (!res.smoothed) {
// @ts-ignore
loadedFiles[file].texture.baseTexture.scaleMode =
PIXI.SCALE_MODES.NEAREST;
resourceFiles[file].forEach((resource) => {
const loadedTexture = loadedPixiResources[file].texture;
if (!loadedTexture) {
const error = loadedPixiResources[file].error;
logFileLoadingError(file, error);
return;
}
this._loadedTextures.put(resource.name, loadedTexture);
applyTextureSettings(loadedTexture, resource);
});
}
}

File diff suppressed because one or more lines are too long

556
GDJS/package-lock.json generated
View File

@@ -304,272 +304,147 @@
}
},
"@pixi/accessibility": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.0.1.tgz",
"integrity": "sha512-Lx0ZHJ0B86e2Eh+3rsAvTg21vuMaA6s42p+8+6eRsofiyvpgvh8oacGuh/wDEn+c0xwo8ulyasbPgFswCfXLVw==",
"dev": true,
"requires": {
"@pixi/canvas-renderer": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-6.1.2.tgz",
"integrity": "sha512-riXpC4PBJYaAG5aWUZ3ud+zhF2ulqnNGCMvlcf/RfuNHlI0jd3SQ0/sxI9OwT0usnxjUDd8beDk8txJGmrX8Fw==",
"dev": true
},
"@pixi/app": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.0.1.tgz",
"integrity": "sha512-X+bR+Z3cpzVIQhu//NlFwaFbtgTDMdV4TMKecOl2jGVFuTppWvGdyorCsHbJ7bZCUykaUrxLiO6p87Z+xQpRWA==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1"
}
},
"@pixi/canvas-renderer": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/canvas-renderer/-/canvas-renderer-6.0.1.tgz",
"integrity": "sha512-Zr1LeI9OHS4QofODdtV7MQNxhWSar4ymKD8/Q1xf9Qnu3EsBljp7yPeO8HLrtnC5hfWH5k71shRS4/aXlt0pwQ==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/app/-/app-6.1.2.tgz",
"integrity": "sha512-fv8kyFw2w8kX9UZNetlNAerM7Uszr2BSXKIMqB8lITpeE7XlnNpDussdF9z87fBjSYgMD3bdWSkhdj54QY6n9A==",
"dev": true
},
"@pixi/compressed-textures": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-6.0.1.tgz",
"integrity": "sha512-qAOyyhCShSIaQFqVMauRG1t2G9sx+iNUNc9IxU1KjtdG24wBfSUzYrSyGNoMEf4rGmrQb1nllMS1tUuvqebYwg==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/loaders": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-6.1.2.tgz",
"integrity": "sha512-BcOaXKS4+6fTOnORt6o2uKUJGpwTIDhIzF+t0ekd9UGhfLykFHIALdgCYPU1e4GvtWWDfaYYhIwWWa8sX+FWTQ==",
"dev": true
},
"@pixi/constants": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.0.1.tgz",
"integrity": "sha512-uui0o0CqmUM4DQUQtt2BQIEI4AfMzh8FNTGmG7nmyxyuX8kzF8Bj9Kr7VvbZqHTOtkEIvkldmfmTJ2JPSn062g==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-6.1.2.tgz",
"integrity": "sha512-rPHWzGDI/PKD0/p8mrsoednpDhbvfidcen2Vozz7KNO5SS/ljqyiZLEbHwYK/xhc2Z7QvXVuDuPaWl9FBCRiQg==",
"dev": true
},
"@pixi/core": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.0.1.tgz",
"integrity": "sha512-NI3ymQVRNa6G24mYM4dR0mFa6BWyHnc+WqTgtsnV1MJPj7c5JvetwiK1JDy7uXYfBnXp99f3PWwOgDssuzpEmQ==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/runner": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/ticker": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/core/-/core-6.1.2.tgz",
"integrity": "sha512-S+f0qmVkrePor2XKA6A70Axo8ui+HiZgkl1J7AWVtl6MI49+3tXra9Ww3xmp/6jEdIUQyyN5sC8cg8dF/lgmBw==",
"dev": true
},
"@pixi/display": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.0.1.tgz",
"integrity": "sha512-dk3Yq4YGZvaO4+9XsOi2BY3xsxpNxgJtxbNysApf1cTmgDk8e2yMMmg0gJtGFrMHsVuKimztwZdavMGaKuoCeQ==",
"dev": true,
"requires": {
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/display/-/display-6.1.2.tgz",
"integrity": "sha512-JbX9GF6kOg8n8mcOFvcVZBpDRZtB/u7I+L0taOMHHtQ16bdBQ9+CxYgvOi9FLyWQNKl4utnnviQx4t8Km01POQ==",
"dev": true
},
"@pixi/extract": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-6.0.1.tgz",
"integrity": "sha512-LdJ6h8UwR9IzZKNDU8oj9yDkB8noTcf4eCXsn4MRNztURJxcTXWUqa0NAGHEEMeM2hGIjQxtFlkwrE21t/zUdg==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-6.1.2.tgz",
"integrity": "sha512-1vnAOJEaaRsTWyRa4OCodVubvZ0Ib3LVkg5MFU+bDsgnczwUiZEOvtaQKOAiO1F9rEdNdvuo/TQyWlJAuHB73Q==",
"dev": true
},
"@pixi/filter-alpha": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-6.0.1.tgz",
"integrity": "sha512-tGUw92Z1yQ5wQb/1NmyFToJQnMEWJWoU0e60+ZWXTmWnCl79fWIFD2FEM1gJ517XYRofTYxTAv450RzITocaRw==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-6.1.2.tgz",
"integrity": "sha512-8qvW6FrJ8liyswfQJrFKRo679j1vhszxsa/A0unXJYGkD8fRlnoywr2gci+yEb/AyEiuwJF59v2YtWjFjkJ2fA==",
"dev": true
},
"@pixi/filter-blur": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-6.0.1.tgz",
"integrity": "sha512-yVk8wBaP+IBNu01dfdpA3TlGXBH/wSq+VZbZqmFVHEKZv3o1io84Yy10HJlC0xi6aL2YEqeramDGfcgdzS6Osg==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/settings": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-6.1.2.tgz",
"integrity": "sha512-4uJUVtuiuQbPBqXwUS7aUoe8SAnjcmAwKR+KClgn/4XvwIXaULvQcmSUTyrROmWeNTGm6LgVcX4pbb8aO5lWLg==",
"dev": true
},
"@pixi/filter-color-matrix": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-6.0.1.tgz",
"integrity": "sha512-fkOPmpdet6avjgUjd2MppJ3ZGoFFXdXBNfVEHbAC+1NxoajY0b1VqoLgzdrcFXL2meFnIyYGq3AxrVOMcn7nUw==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-6.1.2.tgz",
"integrity": "sha512-xHd0OFdJr2nuqUKSjpf9W2OQwrfmQ7v00eiqeBA9azFmMJ4XmsRmAaej+mgBM2L9j4gZmbGE/5h5ZA80NCAHfg==",
"dev": true
},
"@pixi/filter-displacement": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-6.0.1.tgz",
"integrity": "sha512-5Yk9tvy/zFN/V8DLihb3DeFhfxkcyfkETKpcVDw6jPqFbcrqObcL9EH+SSmTNpUyU5Wvc8cwEosjKBhDExS4xQ==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/math": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-6.1.2.tgz",
"integrity": "sha512-LOQJUfsIcgGkURT7/cqdb9sDjhGO9eQXPb8YHeMyBgKouby0On9REFbueE0cwfuY/MGcfru55JH8okcG7YXj2w==",
"dev": true
},
"@pixi/filter-fxaa": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-6.0.1.tgz",
"integrity": "sha512-sTwu4B16D7pG4So1tERwqa6XhPO7KAzw+3AbjrPzLqCXtEZ72IeR7y/V3vbCRs9UcNl0QcAyz16wfBVwzdlTAw==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-6.1.2.tgz",
"integrity": "sha512-Gx2i8DCSKXhnUz0/rFsTmSaGVXl+kyZnD7/e1WojZD4M/2DPzQXqfbmi2OxsR1dyFBH6utNjmYP8xIvQ4JmSMw==",
"dev": true
},
"@pixi/filter-noise": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-6.0.1.tgz",
"integrity": "sha512-93GrgD6TF3cWmLpWOXtbQGX2MMwRz9y2OTB6i3aQOul6OoTiMbWlJR8MT79XaW8HdyPHHl4xCC9nIvY1R3/DDA==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-6.1.2.tgz",
"integrity": "sha512-sPYw3fuxycnVa12C66RhJGeK32XXfX7ANvH5ZRf6i3NwsnmlEZfid8zrujt23xdY0UNqHxwYyg2RrQS9mLDanw==",
"dev": true
},
"@pixi/graphics": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.0.1.tgz",
"integrity": "sha512-YQiMo3l1WFBvJQ47kg52KG2lrUVJbG78dBizUJnB3WeUTGzNCH3F/K8iBqTHVffW5rVenaH3sMzx0GePoLMuXg==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-6.1.2.tgz",
"integrity": "sha512-aNQ9242RV3Lg4hLmU4rN9jGKhE84vjkxEWswpyqChDqh5vOeahSjZo4DR+qIsEUwEo/OgRY1kvpWY4+2xzMSjg==",
"dev": true
},
"@pixi/interaction": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.0.1.tgz",
"integrity": "sha512-Rb5PU4do7mt5UxYjZgtSfMrsMsGtOiV8RQC++BcaspKCveaBn7lJllrJnnKVyAZBQhlULcf5S+TufQENNagwFg==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/ticker": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-6.1.2.tgz",
"integrity": "sha512-0Hw6ZTXW8jgwq1Ek4wu+JqbSpIeOGvUR9mYuh8Ucrsi089Zavv/sOtAVVO8Zq1psFUjsU+BXSuOZmgOi2xwHFQ==",
"dev": true
},
"@pixi/loaders": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.0.1.tgz",
"integrity": "sha512-OSOcjBxoUyS1zgeStmGsARZB0QZYc1y4p9diZHIgB9s+y6/WHFVoih2hueqhPacEYqxx/UI0UPYmNX2BJoZYwg==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/utils": "6.0.1",
"resource-loader": "^3.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-6.1.2.tgz",
"integrity": "sha512-InzcLF6Xl9DAp8O2w93r+xEfL9tZYe+CMjVKxJCEebee8JliurRX5Tpq/POi1QwwApi5HaQdpbZ5akQGZGA/+Q==",
"dev": true
},
"@pixi/math": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.0.1.tgz",
"integrity": "sha512-tETa11mjYks3JdUlMkk3KbGr2UQprgKiiq4mhhwVeVwslrYJgVBrOMZwdDq0Hm+z6tdVzVyHviRvtih/c59JSA==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/math/-/math-6.1.2.tgz",
"integrity": "sha512-tARAZaR01bifqQFW5P714k+Kb8KntKoxVSxbxkY58RSibpoCBFZ8ZnrlT4HY3ovIx66KhH7JJeVhCsXG2d/ggg==",
"dev": true
},
"@pixi/mesh": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.0.1.tgz",
"integrity": "sha512-530YfXsMnKhj2aYWLpKSfBKLtd2+uqGXFwrOjPgJIQvs7kWR+TN3ZMzdBa6S7y2ludsqPiI+d87TNu6eAZjY4g==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-6.1.2.tgz",
"integrity": "sha512-3aEke7cXq+EIsuVW8G/Ro5GekbZRDFSSxOtbpzNoSjNdTgnKb3OcNaaygu8tK+ZN2uXxN2u91d6f0ki8Y6VnUA==",
"dev": true
},
"@pixi/mesh-extras": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.0.1.tgz",
"integrity": "sha512-A3JQzMek2Y4U5DNXBY84MqV4fqWCMT9Jj5Mz9/UVhLAbWm9iREHyLMghRPLA+i2LR1O+cz7SWAbl8xBaaerEdA==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/mesh": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-6.1.2.tgz",
"integrity": "sha512-MtOHfbfDJ0RyNq3S1frm/+erxCyrayZFOJA0bBIFvHW5WeolAcLo+pNGlmh/1qufDTnMK3UM16mOzAz9qNA7wA==",
"dev": true
},
"@pixi/mixin-cache-as-bitmap": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-6.0.1.tgz",
"integrity": "sha512-uKAN6KnBfvFcAZf5CV4g0LaW9g5166OFrY8dBCoAO2AwGcpDUcZXi31RF+Q9VLz/kV6PnVD1zj8mdU3k7F7YVg==",
"dev": true,
"requires": {
"@pixi/canvas-renderer": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-6.1.2.tgz",
"integrity": "sha512-8H5SZ6KTKI0WIYPNasjgGDanwUuIyyWtug/qK8j/LNuvVZmj9xfeQnih+Zi727SxKLrnD2mPWXWzSbDrp0MpnQ==",
"dev": true
},
"@pixi/mixin-get-child-by-name": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-6.0.1.tgz",
"integrity": "sha512-fRtEwMCbmwlvCzwGODkErvI/qNVts3PB9WVgnBkO+sH3GN5pKqi5tQZDfukR+v6JuzgelYYLON4Od5p+MW+iPQ==",
"dev": true,
"requires": {
"@pixi/display": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-6.1.2.tgz",
"integrity": "sha512-9WCGFWiY8fisUCir51Q3JKMSw16M5KSzDxAHVyNlinBv71ifH+AZgdzeogDbQf1ysP4BL2K956czPv19GbcANw==",
"dev": true
},
"@pixi/mixin-get-global-position": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-6.0.1.tgz",
"integrity": "sha512-56EnQPbJKKrbnyTxJY/ft3BAFzCnNOKXkYv8g+qPI/O1dwaCQkrplIpiZHY+r8jmzYm9uj9vlKHcVTMbXAtf+g==",
"dev": true,
"requires": {
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-6.1.2.tgz",
"integrity": "sha512-E7+yo2Cv+qrIXeH8x3tr98H4qEY3vn+IYTbJP0m7/hVA98qTOoP866MJUBNwgwtbRgNEQJwGuGs+m/yK2mcW7w==",
"dev": true
},
"@pixi/particles": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/particles/-/particles-6.0.1.tgz",
"integrity": "sha512-VdHawe70bHdbmQNIN2igGUZBISPtHzE6yhvXb/aBttmVCJ8P+P48O7va/f0pB8jpo0x4lUCqxG8PSLqYKZSphg==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/utils": "6.0.1"
}
"@pixi/particle-container": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-6.1.2.tgz",
"integrity": "sha512-2IvY0nkH8tc7dY6Gk/RyCaSWaPWNEEurPeEkDYhYUcL/ktlqD65PzHQVMZ20nhW5hnHx4bn2H4S1U/5ilvg8Tg==",
"dev": true
},
"@pixi/polyfill": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/polyfill/-/polyfill-6.0.1.tgz",
"integrity": "sha512-pVeAqtY11QMMYzWetmCHqAhucrhfIhnS7KIDRkIp5JZvgKy8S9nayDDfrtLN4vyUyX0/Vtzet3wwVJSACg6Pag==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/polyfill/-/polyfill-6.1.2.tgz",
"integrity": "sha512-sULLKpSNyax5sYkPMIm+e36zZC1+gfexn5DGrLswR+vHy1Eu8Ler/P0dak+nzKTqwL1hwkuVlCZms+esG9myNQ==",
"dev": true,
"requires": {
"object-assign": "^4.1.1",
@@ -577,131 +452,74 @@
}
},
"@pixi/prepare": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.0.1.tgz",
"integrity": "sha512-cxR096dSymz0B+YAnW8D9cxQlJtPk4pUGztoEnu+lGO7+0iruAGP3LzcN58o3/a8oEeNAgMT4mLRG8W0DTZgwQ==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/graphics": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/text": "6.0.1",
"@pixi/ticker": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-6.1.2.tgz",
"integrity": "sha512-qHoS/knfchT7ZvpV1MwJQaS5zb8uvlO2paKRLN76aZR4dHKCpRzVWHJ+5EuSEacbbzX8ElBMTCI0iV1V7L1Jiw==",
"dev": true
},
"@pixi/runner": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.0.1.tgz",
"integrity": "sha512-l1NJUMP4IcvrFeIhthKVAbfHtqPx9LDFP0ItnrsBMrBAkIx7ymMlJju7p1RFOTnKHWOI7FVbmOy28utg3kgimg==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-6.1.2.tgz",
"integrity": "sha512-OKFnW2qrjgUB/O7i15vvS3YRv49aV1Ny22uoYkWGJZ46y3wg6SWuMfHDOK2HIDMefToNRFhWCxcZJCqT5A7XmQ==",
"dev": true
},
"@pixi/settings": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.0.1.tgz",
"integrity": "sha512-Sacsaz9VSzuUC/JuSKs3s/+qEbeinq9uv1dzx69D6P8xj7gc+ne6ogSUmovQGokTh/CCUroEXg7yxRR8jeGKOg==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-6.1.2.tgz",
"integrity": "sha512-ZulDFSejh475/YOaTsYpOZNWKhfdN93FnojsaLYX4OXcuscF3Ncq4AE8wNwGFraMd0+ZZY9VXHdepU+rjIhF4g==",
"dev": true,
"requires": {
"ismobilejs": "^1.1.0"
}
},
"@pixi/sprite": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.0.1.tgz",
"integrity": "sha512-7gePcBVCAl/eBY59h2OpmyXwi3uHZdAmxbrFprelnFd1dmsgvHq2mTTtcvjxuSYKIbx1hrs4taUZl+DQ7f5wSQ==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-6.1.2.tgz",
"integrity": "sha512-AzK2UW+VcZ+6sKW++9qokhSMFG35zSAOpRoWk5QgRhbVkdh2L0BB7nK5Z8PZgqmTGCzSq2NvVlzosryPWmLMNw==",
"dev": true
},
"@pixi/sprite-animated": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-6.0.1.tgz",
"integrity": "sha512-fiM2aOnEqCInNtpsKcBTJyYn6Dl2yZItpMgCl7+BWtJO1qP5Pa2p7jm7B/NAH/GxKR9qzu3jWMwyxgIt4wx1wA==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/ticker": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-6.1.2.tgz",
"integrity": "sha512-jriUtbIw1v0AB3sIObM1t7eAIPuB4gtokao6k09EURMepoCQJlYSKIq5FVlmLYU/zf1t7/f/dtpZ65UEKXDytw==",
"dev": true
},
"@pixi/sprite-tiling": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.0.1.tgz",
"integrity": "sha512-kcqmVSdAFF2RLpXNFAyfOrDsGLNcb1JOPqC2LLuKVQ1I35gmQZ+t03NLIctbe4vyGIr6/NRRp/8CNrw1nKgH7w==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-6.1.2.tgz",
"integrity": "sha512-6tOlag2M+bn5aNPi/iyORY/IqB9Gfan5MnaG3HarfZdSlSwQH0yklDePBrG2DQ/X6Rmb94DJd0PxJdCujtFJTg==",
"dev": true
},
"@pixi/spritesheet": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-6.0.1.tgz",
"integrity": "sha512-m/7rqOS9A96DvYz1oksfc96h+Fv+e0MtiNVSJ0NX5Hm97mweyFMI/7CFEhZdiZnQPTKVVYWAkerMomnKq2urZQ==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/loaders": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-6.1.2.tgz",
"integrity": "sha512-PP+sChFaE8vK0PHwChKYeDuFSvYK+Eb6M+eX2pMt3MoXIurGvlrybexUTqTNubxQHWnoLqGIfqq1MWdjmGrs8A==",
"dev": true
},
"@pixi/text": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.0.1.tgz",
"integrity": "sha512-D07Ek0kKl3gw5ud1kCq+mXlcDz9z7B422LMG3pUfXPz6lliCM5HHG/NPRosh3Q8tkb+Yx8vxB/yAlJ5e3msJqg==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/text/-/text-6.1.2.tgz",
"integrity": "sha512-9JQ4hEanM946uMvjg4a7uIhnAoGYE6lyxwDUlHw4j/o+8jYN49STc64G+s9Rj7iRw76tudqM2ejphBE+rzC0XQ==",
"dev": true
},
"@pixi/text-bitmap": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-6.0.1.tgz",
"integrity": "sha512-OgrhIe00IylgIwPOQDIDYL5AmUvHZj0r4rjd8TkW6hLIGA8y/+Xdre1bIXv0TpyzEri++oXC0Q/kCIvqOmqRdQ==",
"dev": true,
"requires": {
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/loaders": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/mesh": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/text": "6.0.1",
"@pixi/utils": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-6.1.2.tgz",
"integrity": "sha512-QpvFC9izghqVo4zkj5mS6PmqKVtd8ArdapYxbxOVystE+gI8IKq7ZJgvvPuaj+9aqCUy20jiMPoLvfSyVGIhUg==",
"dev": true
},
"@pixi/ticker": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.0.1.tgz",
"integrity": "sha512-5cjGyvOU6RrAFz69w760x/7Uv5CZuZogs9nyi6HXUIKK0gy1pDW/bfWHUQm34Uh4baIU1k0qQOic0yfZOGO9qg==",
"dev": true,
"requires": {
"@pixi/settings": "6.0.1"
}
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-6.1.2.tgz",
"integrity": "sha512-E0S7wzcPPd+hOTghwZeozuXgMvKGa8Zg4+DhlkqBchHt2HDdDzxgy2ZbcyLczBBkuidEx+JRt+BUWBGv4hqZUA==",
"dev": true
},
"@pixi/utils": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.0.1.tgz",
"integrity": "sha512-RcbbvlGCsE4G0Rj8TpjWz+JndUAPmuLzKyUtWbIn9sLCLaNRezoMCA0iR68oGjkNkGOBLbpubii60IAfQokiXg==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-6.1.2.tgz",
"integrity": "sha512-7lacouw8UPAQ0NbBbMEYOff/VRy0qVPV0VuAdKkmrlKu53n6NkocATnUGwdNOHmSNLMAgVu4e30ihwNORrRMAQ==",
"dev": true,
"requires": {
"@pixi/constants": "6.0.1",
"@pixi/settings": "6.0.1",
"@types/earcut": "^2.1.0",
"earcut": "^2.2.2",
"eventemitter3": "^3.1.0",
@@ -1255,9 +1073,9 @@
"dev": true
},
"earcut": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.2.tgz",
"integrity": "sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ==",
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.3.tgz",
"integrity": "sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==",
"dev": true
},
"electron": {
@@ -2132,12 +1950,6 @@
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
"dev": true
},
"mini-signals": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz",
"integrity": "sha1-RbCAE8X65RokqhqTXNMXye1yHXQ=",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -2231,12 +2043,6 @@
"integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
"dev": true
},
"parse-uri": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/parse-uri/-/parse-uri-1.0.3.tgz",
"integrity": "sha512-upMnGxNcm+45So85HoguwZTVZI9u11i36DdxJfGF2HYWS2eh3TIx7+/tTi7qrEq15qzGkVhsKjesau+kCk48pA==",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -2263,46 +2069,46 @@
"optional": true
},
"pixi.js": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-6.0.1.tgz",
"integrity": "sha512-SiTihpqs9YC98N9B3hTP03fYve9uiUmI+UscIbR37exzXG00UenwvodCR31l5T+PMRQHk0UQjzSLt2mmK+ThEQ==",
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-6.1.2.tgz",
"integrity": "sha512-i6MWxeRtgGGIEa58KXHG2/1QZmFxrkmieQMtr5+Bs5Eje5vBaQqmmBcysnSTpYuIlxGnmXXmawf/9cd4aFNTCA==",
"dev": true,
"requires": {
"@pixi/accessibility": "6.0.1",
"@pixi/app": "6.0.1",
"@pixi/compressed-textures": "6.0.1",
"@pixi/constants": "6.0.1",
"@pixi/core": "6.0.1",
"@pixi/display": "6.0.1",
"@pixi/extract": "6.0.1",
"@pixi/filter-alpha": "6.0.1",
"@pixi/filter-blur": "6.0.1",
"@pixi/filter-color-matrix": "6.0.1",
"@pixi/filter-displacement": "6.0.1",
"@pixi/filter-fxaa": "6.0.1",
"@pixi/filter-noise": "6.0.1",
"@pixi/graphics": "6.0.1",
"@pixi/interaction": "6.0.1",
"@pixi/loaders": "6.0.1",
"@pixi/math": "6.0.1",
"@pixi/mesh": "6.0.1",
"@pixi/mesh-extras": "6.0.1",
"@pixi/mixin-cache-as-bitmap": "6.0.1",
"@pixi/mixin-get-child-by-name": "6.0.1",
"@pixi/mixin-get-global-position": "6.0.1",
"@pixi/particles": "6.0.1",
"@pixi/polyfill": "6.0.1",
"@pixi/prepare": "6.0.1",
"@pixi/runner": "6.0.1",
"@pixi/settings": "6.0.1",
"@pixi/sprite": "6.0.1",
"@pixi/sprite-animated": "6.0.1",
"@pixi/sprite-tiling": "6.0.1",
"@pixi/spritesheet": "6.0.1",
"@pixi/text": "6.0.1",
"@pixi/text-bitmap": "6.0.1",
"@pixi/ticker": "6.0.1",
"@pixi/utils": "6.0.1"
"@pixi/accessibility": "6.1.2",
"@pixi/app": "6.1.2",
"@pixi/compressed-textures": "6.1.2",
"@pixi/constants": "6.1.2",
"@pixi/core": "6.1.2",
"@pixi/display": "6.1.2",
"@pixi/extract": "6.1.2",
"@pixi/filter-alpha": "6.1.2",
"@pixi/filter-blur": "6.1.2",
"@pixi/filter-color-matrix": "6.1.2",
"@pixi/filter-displacement": "6.1.2",
"@pixi/filter-fxaa": "6.1.2",
"@pixi/filter-noise": "6.1.2",
"@pixi/graphics": "6.1.2",
"@pixi/interaction": "6.1.2",
"@pixi/loaders": "6.1.2",
"@pixi/math": "6.1.2",
"@pixi/mesh": "6.1.2",
"@pixi/mesh-extras": "6.1.2",
"@pixi/mixin-cache-as-bitmap": "6.1.2",
"@pixi/mixin-get-child-by-name": "6.1.2",
"@pixi/mixin-get-global-position": "6.1.2",
"@pixi/particle-container": "6.1.2",
"@pixi/polyfill": "6.1.2",
"@pixi/prepare": "6.1.2",
"@pixi/runner": "6.1.2",
"@pixi/settings": "6.1.2",
"@pixi/sprite": "6.1.2",
"@pixi/sprite-animated": "6.1.2",
"@pixi/sprite-tiling": "6.1.2",
"@pixi/spritesheet": "6.1.2",
"@pixi/text": "6.1.2",
"@pixi/text-bitmap": "6.1.2",
"@pixi/ticker": "6.1.2",
"@pixi/utils": "6.1.2"
}
},
"prepend-http": {
@@ -2653,16 +2459,6 @@
"path-parse": "^1.0.6"
}
},
"resource-loader": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-3.0.1.tgz",
"integrity": "sha512-fBuCRbEHdLCI1eglzQhUv9Rrdcmqkydr1r6uHE2cYHvRBrcLXeSmbE/qI/urFt8rPr/IGxir3BUwM5kUK8XoyA==",
"dev": true,
"requires": {
"mini-signals": "^1.2.0",
"parse-uri": "^1.0.0"
}
},
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",

View File

@@ -19,7 +19,7 @@
"jsdoc-typeof-plugin": "^1.0.0",
"lebab": "^3.1.0",
"minimist": "^1.2.5",
"pixi.js": "6.0.1",
"pixi.js": "^6.1.2",
"prettier": "2.1.2",
"recursive-readdir": "^2.2.2",
"shelljs": "^0.8.4",

View File

@@ -354,6 +354,7 @@ interface Project {
[Const, Ref] DOMString GetVersion();
void SetAuthor([Const] DOMString authorName);
[Const, Ref] DOMString GetAuthor();
[Ref] VectorString GetAuthorIds();
void SetPackageName([Const] DOMString packageName);
[Const, Ref] DOMString GetPackageName();
void SetOrientation([Const] DOMString orientation);
@@ -818,6 +819,7 @@ interface ResourcesManager {
void ResourcesManager();
[Value] VectorString GetAllResourceNames();
[Value] VectorString FindFilesNotInResources([Const, Ref] VectorString filesToCheck);
boolean HasResource([Const] DOMString name);
[Const, Ref] Resource GetResource([Const] DOMString name);
[Const, Ref] DOMString GetResourceNameWithOrigin([Const] DOMString originName, [Const] DOMString originIdentifier);
@@ -2187,6 +2189,7 @@ interface EventsFunctionsExtension {
[Ref] EventsFunctionsExtension SetFullName([Const] DOMString fullName);
[Const, Ref] DOMString GetFullName();
[Ref] VectorString GetTags();
[Ref] VectorString GetAuthorIds();
[Ref] EventsFunctionsExtension SetAuthor([Const] DOMString author);
[Const, Ref] DOMString GetAuthor();
[Ref] EventsFunctionsExtension SetPreviewIconUrl([Const] DOMString previewIconUrl);
@@ -2243,7 +2246,6 @@ interface AbstractFileSystemJS {
};
interface ProjectResourcesAdder {
void STATIC_AddAllMissing([Ref] Project project, [Const] DOMString resourceType);
[Value] VectorString STATIC_GetAllUseless([Ref] Project project, [Const] DOMString resourceType);
void STATIC_RemoveAllUseless([Ref] Project project, [Const] DOMString resourceType);
};
@@ -2629,14 +2631,10 @@ interface ParticleEmitterObject {
float GetParticleGravityX();
void SetParticleGravityY(float newValue);
float GetParticleGravityY();
void SetParticleGravityZ(float newValue);
float GetParticleGravityZ();
void SetParticleGravityAngle(float newValue);
float GetParticleGravityAngle();
void SetParticleGravityLength(float newValue);
float GetParticleGravityLength();
void SetFriction(float newValue);
float GetFriction();
void SetParticleLifeTimeMin(float newValue);
float GetParticleLifeTimeMin();

View File

@@ -487,7 +487,6 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
#define STATIC_IsObject IsObject
#define STATIC_IsBehavior IsBehavior
#define STATIC_Get Get
#define STATIC_AddAllMissing AddAllMissing
#define STATIC_GetAllUseless GetAllUseless
#define STATIC_RemoveAllUseless RemoveAllUseless

View File

@@ -1064,6 +1064,38 @@ describe('libGD.js', function () {
project.delete();
});
it('can find files that are not in the resources', function () {
var project = gd.ProjectHelper.createNewGDJSProject();
var resource = new gd.ImageResource();
var resource2 = new gd.AudioResource();
resource.setName('MyResource');
resource.setFile('MyFile.png');
resource2.setName('MyResource2');
resource2.setFile('MySubFolder/MyOtherFile.mp3');
project.getResourcesManager().addResource(resource);
project.getResourcesManager().addResource(resource2);
const filesToCheck = new gd.VectorString();
[
'MyFile.png',
'MySubFolder/MyFileMissingInResource.png',
'MySubFolder/MyOtherFile.mp3',
].forEach((filePath) => {
filesToCheck.push_back(filePath);
});
const filesNotInResources = project
.getResourcesManager()
.findFilesNotInResources(filesToCheck);
filesToCheck.delete();
expect(filesNotInResources.size()).toBe(1);
expect(filesNotInResources.at(0)).toBe(
'MySubFolder/MyFileMissingInResource.png'
);
project.delete();
});
it('should support removing resources', function () {
var project = gd.ProjectHelper.createNewGDJSProject();
var resource = new gd.Resource();
@@ -1108,6 +1140,41 @@ describe('libGD.js', function () {
expect(allResources.get(0)).toBe('Used');
project.delete();
});
it('should not remove loading screen image when removing useless resources', function () {
const project = gd.ProjectHelper.createNewGDJSProject();
const resource = new gd.ImageResource();
resource.setName('LoadingScreenImage');
project
.getLoadingScreen()
.setBackgroundImageResourceName(resource.getName());
expect(project.getLoadingScreen().getBackgroundImageResourceName()).toBe(
'LoadingScreenImage'
);
const worker = new gd.ResourcesInUseHelper();
project.exposeResources(worker);
expect(worker.getAllImages().toNewVectorString().toJSArray().length).toBe(
1
);
expect(worker.getAllImages().toNewVectorString().toJSArray()[0]).toBe(
'LoadingScreenImage'
);
gd.ProjectResourcesAdder.removeAllUseless(project, 'image');
const newWorker = new gd.ResourcesInUseHelper();
project.exposeResources(newWorker);
expect(
newWorker.getAllImages().toNewVectorString().toJSArray().length
).toBe(1);
expect(newWorker.getAllImages().toNewVectorString().toJSArray()[0]).toBe(
'LoadingScreenImage'
);
project.delete();
});
});
describe('gd.ArbitraryResourceWorker', function () {

View File

@@ -1,6 +1,25 @@
const initializeGDevelopJs = require('../../Binaries/embuild/GDevelop.js/libGD.js');
const { makeMinimalGDJSMock } = require('../TestUtils/GDJSMocks');
/**
* Helper generating an event, ready to be unserialized, adding 1 to
* "TestVariable" of the specified object (or object group).
*/
const makeAddOneToObjectTestVariableEvent = (objectName) => ({
disabled: false,
folded: false,
type: 'BuiltinCommonInstructions::Standard',
conditions: [],
actions: [
{
type: { inverted: false, value: 'ModVarObjet' },
parameters: [objectName, 'TestVariable', '+', '1'],
subInstructions: [],
},
],
events: [],
});
describe('libGD.js - GDJS Code Generation integration tests', function () {
let gd = null;
beforeAll((done) =>
@@ -223,22 +242,6 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
});
it('generates a working function creating objects', function () {
const makeAddOneToObjectTestVariableEvent = (objectName) => ({
disabled: false,
folded: false,
type: 'BuiltinCommonInstructions::Standard',
conditions: [],
actions: [
{
type: { inverted: false, value: 'ModVarObjet' },
parameters: [objectName, 'TestVariable', '+', '1'],
subInstructions: [],
},
],
events: [],
});
// Create events using the Trigger Once condition.
const eventsSerializerElement = gd.Serializer.fromJSObject([
{
disabled: false,
@@ -300,9 +303,7 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(2);
// Object B has nothing to do with the "Create", its variable is just incremented once.
expect(
myObjectB.getVariables().get('TestVariable').getAsNumber()
).toBe(1);
expect(myObjectB.getVariables().get('TestVariable').getAsNumber()).toBe(1);
// Check that if the function is called with the first MyObjectA as parameter, it won't change
// the way a new object is created...
@@ -324,10 +325,99 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
).toBe(3);
// Object B has nothing to do with the "Create", its variable is just incremented again.
expect(myObjectB.getVariables().get('TestVariable').getAsNumber()).toBe(
2
expect(myObjectB.getVariables().get('TestVariable').getAsNumber()).toBe(2);
eventsFunction.delete();
project.delete();
});
it('generates working functions with groups', function () {
// Create events that increment twice the variable of a group, and
// only once for the 3rd parameter.
const eventsSerializerElement = gd.Serializer.fromJSObject([
makeAddOneToObjectTestVariableEvent('MyObjectGroup'),
makeAddOneToObjectTestVariableEvent('MyObjectGroup'),
makeAddOneToObjectTestVariableEvent('ObjectParam3'),
]);
const project = new gd.ProjectHelper.createNewGDJSProject();
const eventsFunction = new gd.EventsFunction();
eventsFunction
.getEvents()
.unserializeFrom(project, eventsSerializerElement);
const group = eventsFunction.getObjectGroups().insert('MyObjectGroup', 0);
group.setName('MyObjectGroup');
group.addObject('ObjectParam1');
group.addObject('ObjectParam2');
const objectParameter = new gd.ParameterMetadata();
objectParameter.setType('object');
objectParameter.setName('ObjectParam1');
eventsFunction.getParameters().push_back(objectParameter);
objectParameter.setType('object');
objectParameter.setName('ObjectParam2');
eventsFunction.getParameters().push_back(objectParameter);
objectParameter.setType('object');
objectParameter.setName('ObjectParam3');
eventsFunction.getParameters().push_back(objectParameter);
objectParameter.delete();
const runCompiledEvents = generateCompiledEventsForEventsFunction(
gd,
project,
eventsFunction
);
// Check that when running the function, the group works in the function.
const { gdjs, runtimeScene } = makeMinimalGDJSMock();
runtimeScene.getOnceTriggers().startNewFrame();
const myObjectA = runtimeScene.createObject('MyObjectA');
const myObjectB = runtimeScene.createObject('MyObjectB');
const myObjectC = runtimeScene.createObject('MyObjectC');
const myObjectD = runtimeScene.createObject('MyObjectD');
const objectParam1Lists = gdjs.Hashtable.newFrom({
// The first parameter is itself a collection of multiple objects
// with different names.
MyObjectA: [myObjectA],
MyObjectB: [myObjectB],
});
const objectParam2Lists = gdjs.Hashtable.newFrom({
MyObjectC: [myObjectC],
});
const objectParam3Lists = gdjs.Hashtable.newFrom({
MyObjectD: [myObjectD],
});
runCompiledEvents(gdjs, runtimeScene, [
objectParam1Lists,
objectParam2Lists,
objectParam3Lists,
]);
expect(runtimeScene.getObjects('MyObjectA')).toHaveLength(1);
const firstMyObjectA = runtimeScene.getObjects('MyObjectA')[0];
expect(
firstMyObjectA.getVariables().get('TestVariable').getAsNumber()
).toBe(2);
expect(runtimeScene.getObjects('MyObjectB')).toHaveLength(1);
const firstMyObjectB = runtimeScene.getObjects('MyObjectB')[0];
expect(
firstMyObjectB.getVariables().get('TestVariable').getAsNumber()
).toBe(2);
expect(runtimeScene.getObjects('MyObjectC')).toHaveLength(1);
const firstMyObjectC = runtimeScene.getObjects('MyObjectC')[0];
expect(
firstMyObjectC.getVariables().get('TestVariable').getAsNumber()
).toBe(2);
expect(runtimeScene.getObjects('MyObjectD')).toHaveLength(1);
const firstMyObjectD = runtimeScene.getObjects('MyObjectD')[0];
expect(
firstMyObjectD.getVariables().get('TestVariable').getAsNumber()
).toBe(1);
eventsFunction.delete();
project.delete();
});
@@ -524,17 +614,17 @@ describe('libGD.js - GDJS Code Generation integration tests', function () {
*/
function generateCompiledEventsForEventsFunction(gd, project, eventsFunction) {
const namespace = 'functionNamespace';
const eventsFunctionsExtensionCodeGenerator = new gd.EventsFunctionsExtensionCodeGenerator(
project
);
const eventsFunctionsExtensionCodeGenerator =
new gd.EventsFunctionsExtensionCodeGenerator(project);
const includeFiles = new gd.SetString();
const code = eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
const code =
eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
eventsFunctionsExtensionCodeGenerator.delete();
includeFiles.delete();

View File

@@ -14,6 +14,7 @@ declare class gdEventsFunctionsExtension extends gdEventsFunctionsContainer {
setFullName(fullName: string): gdEventsFunctionsExtension;
getFullName(): string;
getTags(): gdVectorString;
getAuthorIds(): gdVectorString;
setAuthor(author: string): gdEventsFunctionsExtension;
getAuthor(): string;
setPreviewIconUrl(previewIconUrl: string): gdEventsFunctionsExtension;

View File

@@ -32,14 +32,10 @@ declare class gdParticleEmitterObject extends gdObject {
getParticleGravityX(): number;
setParticleGravityY(newValue: number): void;
getParticleGravityY(): number;
setParticleGravityZ(newValue: number): void;
getParticleGravityZ(): number;
setParticleGravityAngle(newValue: number): void;
getParticleGravityAngle(): number;
setParticleGravityLength(newValue: number): void;
getParticleGravityLength(): number;
setFriction(newValue: number): void;
getFriction(): number;
setParticleLifeTimeMin(newValue: number): void;
getParticleLifeTimeMin(): number;
setParticleLifeTimeMax(newValue: number): void;

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