Compare commits

...

146 Commits

Author SHA1 Message Date
Clément Pasteau
bce459b2d2 Add missing event data (#7449)
Do not show in changelog
2025-03-06 15:31:26 +01:00
D8H
95dddc48b6 Deprecate old variable actions and conditions in extensions (#7406)
- The extension variables must be used instead
- Old extensions can be maintained by copy-pasting existing old actions and conditions from the extension events
2025-03-06 13:13:14 +01:00
Clément Pasteau
d39f210630 Bump 5.5.225 (#7447) 2025-03-06 12:08:31 +01:00
github-actions[bot]
090649f125 Update translations [skip ci] (#7440)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-03-06 12:01:45 +01:00
Clément Pasteau
7c8c02911c Improve Guided Lessons by preventing clicking outside of the next action (#7444) 2025-03-06 11:54:37 +01:00
D8H
0c6a28c0a1 Fix onCreated functions not being called on behaviors added at hot-reload (#7443) 2025-03-04 14:26:21 +01:00
Florian Rival
b9d5974356 Fix expression documentation not displaying parameters 2025-03-04 00:13:22 +01:00
D8H
74a1e11cfc Improve the abs expression documentation (#7442) 2025-03-03 21:53:52 +01:00
D8H
c712d0bb9e Forbid to install assets or behaviors from extensions incompatible with the editor (#7441) 2025-03-03 20:43:48 +01:00
Clément Pasteau
828e6e031a Update AdMob extension to handle Consent & Tracking Authorization on iOS (#7431)
* Admob will now initialize 2 seconds after the app loads, giving more control to when it starts. This is particularily helpful for App Store validations, with Tracking Authorization message.
* New conditions are available to know AdMob initialization status: "AdMob initializing" and "AdMob Initialized".
* New action to stop the auto-initialization: "Prevent AdMob auto initialization" and new action to trigger the initialization: "Initialize AdMob manually".
  * Typically, you'd prevent the initialization at the beginning of the scene, and trigger it manually when a user interacts with a button or something, so you can control when they'll see the consent messages.
2025-03-03 10:53:59 +01:00
D8H
727f991c01 Allow anchored objects to be moved from their initial position (#7417)
* If an anchored object is moved using events (or another behavior), it will stay on its new position.
  This allows to anchor objects on the left, right, top or bottom of the screen (or inside the bounds of a custom object, for example in a dialog) and still allow them to move.
2025-03-03 10:52:15 +01:00
D8H
5d4523b925 Fix object parameter not shown when editing an action/condition when the object doesn't exist (#7373) 2025-03-03 10:40:06 +01:00
github-actions[bot]
3f7cbc731a Update translations [skip ci] (#7434)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-03-03 10:38:44 +01:00
D8H
c1dfa34f0d Deprecate internal actions and conditions to set and compare property values in extension events (#7405)
- The unified variable action and condition must be used instead.
2025-03-03 10:31:05 +01:00
D8H
cf39de49d6 Allow custom objects to declare multi-line text properties (#7436) 2025-02-28 17:23:51 +01:00
D8H
5b325dd8ec Fix access to objects in variable expressions of "for each child variable" loops (#7435) 2025-02-28 11:06:51 +01:00
Clément Pasteau
1f42331cbf Allow selecting a Pixel Art version of 2D starting points (#7425)
* Available for Platformer, Top-Down & Physics templates
2025-02-27 18:06:15 +01:00
Florian Rival
224f17b90a Add missing await 2025-02-27 17:27:58 +01:00
D8H
3541d356e0 Fix text alignment at runtime (#7432) 2025-02-27 10:58:18 +01:00
github-actions[bot]
63e79d678a Update translations [skip ci] (#7416)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-02-27 09:32:51 +01:00
Florian Rival
812153ffb3 Allow the embedded games platform to ask for opening external urls
Don't show in changelog
2025-02-26 15:26:26 +01:00
Clément Pasteau
c62ea9e10a Show error if games frame does not load (#7430) 2025-02-26 14:13:54 +01:00
Clément Pasteau
04c63b2c74 Fix using non-existing vars in calc() (#7427)
Do not show in changelog
2025-02-26 11:15:18 +01:00
Florian Rival
dcc3bae17e Fix warning
Don't show in changelog
2025-02-25 10:31:21 +01:00
Florian Rival
441834cad5 Prepare custom token to speed up embedded game frame login (#7423)
Don't show in changelog
2025-02-25 10:14:15 +01:00
Florian Rival
d4352ba5d9 Adapt embedded game frame position and allow sharing
Don't show in changelog
2025-02-24 19:35:29 +01:00
Clément Pasteau
163239d08d Fix toggle "update game page" sometimes not being visible when publishing. (#7422)
* This could happen when the last build was too old, and the interface considered the game as new, so published it automatically to the game page.
2025-02-24 15:23:39 +01:00
Florian Rival
e3e9b41672 Display first letter of tabs when at minimum size 2025-02-24 12:24:17 +01:00
inspace
7ba7c220e9 Ensure cursor position is correct when a mouse down event is detected (#7412)
Only show in developer changelog
2025-02-24 11:30:36 +01:00
AlexandreS
617bf2c5b9 Add missing keys in keyboard condition/action (#7421)
- Added Left and Right bracket and the Menu keys
2025-02-24 10:38:14 +01:00
Clément Pasteau
d647d1e397 Fix top bar to be draggable on desktop, except tabs (#7420) 2025-02-24 10:32:44 +01:00
Florian Rival
c5bf9730aa Refactor toolbar and titlebar display and ensure game iframe is hidden when not on the Play tab (#7419)
Don't show in changelog
2025-02-23 15:28:32 +01:00
Florian Rival
c5022596b8 Make the games/page in Play section to take the full width
Don't shown in changelog
2025-02-22 14:37:36 +01:00
D8H
6e61c48898 Fix a regression that hid all 3D models in the editor (#7418)
Don't show in changelog
2025-02-22 14:00:56 +01:00
Clément Pasteau
75fc55bac4 Rework the Play section to have games played inside the app (#7372) 2025-02-20 18:46:00 +01:00
github-actions[bot]
8a4916fd93 Update translations [skip ci] (#7414) 2025-02-20 10:08:45 +01:00
AlexandreS
b008863281 Do not show the reminder if the editor was just idle for too long (#7413) 2025-02-19 15:56:25 +01:00
github-actions[bot]
f0377771a8 Update translations [skip ci] (#7399)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-02-19 09:33:26 +01:00
D8H
299ef90f93 [3D character] Fix the "is moving" condition when moving sideways (#7411) 2025-02-17 14:01:37 +01:00
D8H
800c3333d4 Improve typing of the 3D object editor renderers (#7410)
- Don't show in changelog
2025-02-17 12:57:27 +01:00
AlexandreS
303ebfaf1b Refresh in app tutorial message in preview when hot reloading preview (#7407)
Don't show in changelog
2025-02-17 12:06:44 +01:00
AlexandreS
288e4f4b75 Fix: Remove crash when opening 3D Racing game example external layouts
- Use default values when updating Cube 3D three object in editor (#7408)
2025-02-17 11:30:54 +01:00
Clément Pasteau
15db4be4a1 Fix typo (#7402)
Do not show in changelog
2025-02-14 10:08:01 +01:00
D8H
925ffa74ec Allow to tween 3D boxes tint color (#7401)
- Don't show in changelog
2025-02-13 12:35:52 +01:00
D8H
752d047464 Upgrade GDJS to Prettier 3.4.2 (#7398)
- Don't show in changelog
2025-02-12 18:50:02 +01:00
D8H
7a21f9533e Upgrade to TypeScript 5.4.5 (#7394)
- Don't show in changelog
2025-02-12 17:51:36 +01:00
Ansel Games
9820770fb3 Update "Create objects from an external layout" action to show all parameters in the events sheet (#7383) 2025-02-12 17:49:23 +01:00
D8H
a92784295a Fix GDJS test resource paths (#7397) 2025-02-12 17:41:19 +01:00
Neyl
81f6c62bb1 Update Animation Crossfade default value to a more realistic one (100ms) (#7395) 2025-02-12 17:13:36 +01:00
github-actions[bot]
a1bbb1c14c Update translations [skip ci] (#7388)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-02-12 16:56:29 +01:00
Clément Pasteau
9154144228 Fix a project opened from a file being always detected as a new game in the dashboard (#7392) 2025-02-12 16:55:59 +01:00
AlexandreS
c0176dfb2b Add lightweight markdown interpreter for in-app tutorial in-game messages (#7391)
Don't show in changelog
2025-02-12 14:35:32 +01:00
AlexandreS
23cd527d94 Fix spatial sound action not applied if sound is not playing yet (#7393) 2025-02-12 14:33:46 +01:00
Neyl
fa2cdb1624 fix crossfade duration in 3D model editor 2025-02-12 12:02:08 +01:00
Clément Pasteau
03eca4de4b Upgrade pixi to 7.4.2 (#7190) 2025-02-11 14:20:59 +01:00
Clément Pasteau
841484e5b7 Disable lazy loading on authorized images, fixing the image stuck with a loader (#7389) 2025-02-11 10:58:47 +01:00
github-actions[bot]
b88c5b08f5 Update translations [skip ci] (#7370)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-02-11 09:36:17 +01:00
Aurélien Vivet
3f2043f248 Add a clearer warning before the deletion of a game and a project. (#7368)
* This is mainly to prevent accidental deletion of games
2025-02-11 09:35:33 +01:00
Florian Rival
6941e64418 Adapt tabs width according to screen width, to keep them visible on screen as much as possible (#7387) 2025-02-10 18:24:48 +01:00
Neyl
fb7bb9181d add support for crossfading animations for 3D models
the new option allows to smoothly transition between animations. The fading duration can be customized with an action.
2025-02-10 17:56:18 +01:00
AlexandreS
7ee50a2568 Fix: Prevent accidentally saving a project in the root folder of the editor 2025-02-10 13:04:23 +01:00
AlexandreS
90cdc875a9 Add possibility to display message in the preview when an in-app tutorial is running (#7379) 2025-02-10 10:59:35 +01:00
Florian Rival
47d0fba205 Fix a crash when searching instructions after extension are re-generated (#7377)
* Also improve the display of actions/conditions/expressions when searched with a clearer visual separator for their folders
2025-02-07 16:03:09 +01:00
Aurélien Vivet
db745369dc Re-order in-app tutorials (#7378) 2025-02-07 15:30:19 +01:00
D8H
7c49346bed Add a warning on array children with inconsistent type (#7376) 2025-02-06 18:29:38 +01:00
AlexandreS
b9a7786ab0 Add an action to join a lobby in one-click (#7352) 2025-02-06 18:04:41 +01:00
AlexandreS
76c09908c8 Fix border radius added by browser on text input (#7375) 2025-02-06 14:45:54 +01:00
Neyl
b6e186e775 Tint color for 3D cube (#7354)
add a tint color property for 3D cube.
2025-02-06 11:10:39 +01:00
D8H
8c98239e12 Allow to swap assets of any object type (#7365) 2025-02-04 17:22:53 +01:00
AlexandreS
4d56333ae7 Display shorter title in Curriculum's table of content when available (#7371) 2025-02-04 16:22:13 +01:00
AlexandreS
146794d33a Bump newIDE version (#7369) 2025-02-04 15:32:07 +01:00
AlexandreS
3a685c62df Refine free conditions/actions search to give priority to results with the search word in the displayed name (#7360) 2025-02-04 11:28:43 +01:00
github-actions[bot]
8bcbf9bd47 Update translations [skip ci] (#7353)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-02-04 10:25:13 +01:00
Clément Pasteau
601a4e214e Fix games sometimes disappearing from the dashboard (#7366)
* This was caused by games wrongly being considered as not saved during the export, and they were hidden from the dashboard afterwards
2025-02-04 10:07:06 +01:00
D8H
3d0b264130 [Physics3D] Fix remaining hit-boxes of deleted character (#7359)
- Also fix 3D character behavior deactivation
2025-02-03 17:54:38 +01:00
D8H
97e989dee0 Ensure behaviors are compatible with the object before pasting them (#7343) 2025-02-03 13:02:41 +01:00
D8H
6440149fc8 Change documentation pages of some actions and conditions to point to more specific pages (#7364) 2025-02-03 12:58:28 +01:00
Neyl
232359f0a4 FIX the destroy of the form, "is submitted" condition icon, and readonly & disable feature (#7363)
Fix the destroy of the form, readonly and disable feature, and a typo for "is submitted" condition icon
2025-02-03 12:52:57 +01:00
Florian Rival
bf7ecd9ceb Add "Scroll" text to in-app tutorial highlights (#7356)
Don't show in changelog
2025-01-30 11:31:30 +01:00
D8H
2ba7075a7a Update the "trigger once" help page link (#7355) 2025-01-28 19:05:58 +01:00
Clément Pasteau
e45256cebb Fix a few issues with displaying projects correctly in the create section (#7349) 2025-01-27 18:51:25 +01:00
Florian Rival
1ee2d57d2f Bump newIDE version 2025-01-27 18:35:49 +01:00
github-actions[bot]
e890d8f211 Update translations [skip ci] (#7348)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-27 18:34:42 +01:00
Florian Rival
e70f8532f6 Improve course display 2025-01-27 16:54:42 +01:00
Florian Rival
446494156b Fix crash when adding/modifying functions in extensions (#7351) 2025-01-26 21:40:11 +01:00
D8H
15a1d392a1 Fix extension usage listing for example web pages (#7339) 2025-01-24 15:19:49 +01:00
AlexandreS
65b5aa6bac Use new compact UI in the Preferences dialog (#7345) 2025-01-24 14:02:48 +01:00
Florian Rival
cbaa785b95 Fix log and extra character
Don't show in changelog
2025-01-24 13:46:05 +01:00
github-actions[bot]
b6091de09a Update translations [skip ci] (#7341)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-01-24 13:29:17 +01:00
Clément Pasteau
b53dc29f43 Add preferences menu item back in the File menu (#7346) 2025-01-24 13:28:56 +01:00
Aurélien Vivet
0848a109d4 Bring consistency on arrow direction for UI items that can be opened/closed (#7322) 2025-01-24 10:50:51 +01:00
Florian Rival
4bf21e94eb Change in-app tutorials order 2025-01-24 10:43:05 +01:00
Clément Pasteau
2d6b2c1753 Improve homepage bottom bar icons on mobile (#7342) 2025-01-23 18:31:04 +01:00
AlexandreS
c4e230d9ba Split text input padding into 2 separate properties (#7338)
Don't show in changelog
2025-01-23 16:12:18 +01:00
D8H
56ab2fdd05 Revert "Fix used extension check false positive from usused object or behavior events (#7331)" (#7340)
This reverts commit cb24f191fd.

Don't show in changelog
2025-01-23 14:11:13 +01:00
github-actions[bot]
872f4032ff Update translations [skip ci] (#7337)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-23 11:56:54 +01:00
D8H
428b4c21a8 Disable panel sprite tilling by default (#7335)
* This ensures the rendering is more performant by default
2025-01-23 09:43:40 +01:00
D8H
cb24f191fd Fix used extension check false positive from usused object or behavior events (#7331)
- Don't show in changelog
2025-01-22 17:17:39 +01:00
github-actions[bot]
994f6bf150 Update translations [skip ci] (#7334)
Co-authored-by: AlexandreSi <32449369+AlexandreSi@users.noreply.github.com>
2025-01-22 15:55:56 +01:00
AlexandreS
3e2f05460a Bump newIDE version (#7333) 2025-01-22 15:46:04 +01:00
github-actions[bot]
c775cde9df Update translations [skip ci] (#7318)
Co-authored-by: NeylMahfouf2608 <26115084+NeylMahfouf2608@users.noreply.github.com>
2025-01-22 15:37:51 +01:00
AlexandreS
6ab736a048 Return exact matches when searching for an instruction (#7330) 2025-01-22 15:35:12 +01:00
Neyl
f805182ce4 Improvement features for Input text box (#7308)
padding, max-length and text-align can now be configured on the text input object
new condition "Input is submitted" to check if the input has been submitted with the keyboard on all platforms
2025-01-22 14:20:29 +01:00
D8H
a14f1a187e Fix a few typo in Physics3D (#7332)
- Don't show in changelog
2025-01-22 11:35:52 +01:00
D8H
d08bf97471 Fix conflict between variable or property and parameter in variable setters (#7329)
- Don't show in changelog
2025-01-21 19:16:43 +01:00
D8H
093e15e105 Fix EventsFunctionsContainer copy constructor now copy the owner (#7327)
- Don't show in changelog
2025-01-20 14:35:37 +01:00
D8H
60e36f37b1 Remove EventsFunctionsExtension inheritance to EventsFunctionsContainer (#7326)
- developer changelog only
2025-01-20 11:29:55 +01:00
D8H
ad7ce3c725 [3D character] Fix the "is falling" condition from being true when the character is going up (#7325) 2025-01-19 01:00:43 +01:00
D8H
c6f83f4431 Fix behavior property generation and value. (#7324) 2025-01-19 01:00:05 +01:00
D8H
4a685db574 Fix parameters list not updating when the function configuration was changed (#7321) 2025-01-17 20:06:08 +01:00
D8H
f3dea010fb Fix syntax errors not showing up on mouse button and key parameters (#7320)
- Don't show in changelog
2025-01-17 20:05:29 +01:00
D8H
5025e03dff Fix 3D physics characters to keep rotation around X and Y intact (#7319) 2025-01-17 15:42:46 +01:00
Florian Rival
64771c6faf Give back focus to preview, when updating a preview on the web-app 2025-01-17 13:10:09 +01:00
github-actions[bot]
d4987c4739 Update translations [skip ci] (#7314)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-01-17 10:48:59 +01:00
Clément Pasteau
56575e7afd Introduce new subscription dialog design for creators without a plan (#7316) 2025-01-17 10:39:04 +01:00
Florian Rival
9a0df077b3 Fix a crash when opening a project missing a custom object that was loaded in the previously opened project (#7317) 2025-01-16 23:27:32 +01:00
AlexandreS
4bf3ef8ad4 Use the folder structure when choosing an object/group in an action/condition (#7297) 2025-01-16 12:03:58 +01:00
Clément Pasteau
6242e8c97a Fix not being able to drag the app from the top bar (#7315)
Do not show in changelog
2025-01-16 12:02:47 +01:00
D8H
d6c99b27af Allow to use parameters and properties in the variable action and condition (#7124) 2025-01-15 23:28:18 +01:00
AlexandreS
7844ee102e Fix issue that was not showing cubes when they have all their faces shown with no textures (#7313) 2025-01-15 18:17:38 +01:00
github-actions[bot]
7d713d9428 Update translations [skip ci] (#7311)
Co-authored-by: ClementPasteau <4895034+ClementPasteau@users.noreply.github.com>
2025-01-15 17:36:12 +01:00
Clément Pasteau
22056d3c08 Fix adding draggable space only on title bar (#7312)
Do not show in changelog
2025-01-15 17:28:43 +01:00
D8H
2ce35a1520 Allow 3D physics characters to push each other (#7292) 2025-01-15 10:52:21 +01:00
AlexandreS
b04c15f23c Add objects installed from the asset store in selected folder (#7287) 2025-01-15 10:32:15 +01:00
D8H
2ab246696b Add autocompletion for keyboard key properties in the behavior editor (#7310) 2025-01-15 09:57:45 +01:00
Florian Rival
6b4c00c987 Add missing JS files thumbnail
Don't show in changelog
2025-01-15 09:52:56 +01:00
github-actions[bot]
9c4a190a4d Update translations [skip ci] (#7300)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-15 09:50:36 +01:00
Clément Pasteau
1070a489e7 Fix dialog overflow because of cross (#7309)
Don't show in changelog
2025-01-15 09:24:37 +01:00
Clément Pasteau
d2a8cb6727 Improve title bar on multiple platforms optimizing the space at the top of the app (#7306) 2025-01-14 17:29:55 +01:00
D8H
2638c4f593 Fix getter and setter generation for animation properties (#7307)
- Don't show in changelog
2025-01-14 14:51:27 +01:00
D8H
4be2386efe Allow to toggle between drop-down list and expression for mouse button and key parameters (#7305) 2025-01-14 13:53:10 +01:00
AlexandreS
8be099d50a Add possibility to open GDevelop in the browser on the premium course (#7304) 2025-01-13 19:12:14 +01:00
Clément Pasteau
713698d3d6 Fix wrong margins for dense design of sub card (#7303)
Do not show in changelog
2025-01-13 13:32:11 +01:00
Clément Pasteau
8b36908fd8 Merge project manager & app burger menu buttons (#7289)
* The goal of this change is to simplify the top left corner of the app, by merging the App burger menu and the Project manager button into one. Having 2 buttons was causing confusion in the flow of using the app, by mistakenly pressing the wrong button.
* The app menu buttons that are useful are now displayed at the top of the project manager drawer, on the relevant platforms: Web, Windows & mobile, because other platforms have a built-in OS menu.
2025-01-13 10:11:32 +01:00
D8H
c0722dc441 [2D Physics] Reduce the CPU footprint of static objects (#7299) 2025-01-10 16:39:20 +01:00
D8H
9c6a1bed2c [3D Physics] Reduce the CPU footprint of static objects (#7298) 2025-01-10 12:58:53 +01:00
github-actions[bot]
a8a4d14ee1 Update translations [skip ci] (#7291)
Co-authored-by: 4ian <1280130+4ian@users.noreply.github.com>
2025-01-10 10:23:16 +01:00
Florian Rival
b27abfbe5d Add text vertical alignment in quick customzation
Don't show in changelog
2025-01-10 10:07:37 +01:00
Neyl
28b585aefa Allow behavior properties to be an animation name, displayed with a selector 2025-01-09 14:21:04 +01:00
AlexandreS
0623b6acd9 Fix variable list usability (#7290)
- When renaming a variable in the instance panel:
  - the caret position is kept
  - the user can erase the whole field without the name being replaced by "Unnamed" instantly
- When opening the variables editor from a variable field, the currently selected variable is selected in the list (even if child of a variable)
2025-01-08 16:44:13 +01:00
github-actions[bot]
1a833bc388 Update translations [skip ci] (#7272)
Co-authored-by: D8H <2611977+D8H@users.noreply.github.com>
2025-01-07 11:04:19 +01:00
D8H
827f187e10 Add Pixi and Three type definitions for JS events (#7266) 2025-01-07 10:34:51 +01:00
Florian Rival
0f25b80a66 Fix margins
Don't show in changelog
2025-01-06 22:06:15 +01:00
Clément Pasteau
fbf9710cc5 Use premium colors in most places where a subscription can be purchased (#7284) 2025-01-06 20:56:49 +01:00
Clément Pasteau
3d80709029 Fix correctly exporting desktop icon when project is saved in the cloud (#7282) 2025-01-06 17:54:59 +01:00
AlexandreS
5ab9c565b0 Simplify shop navigation state to avoid useless renderings (#7283)
Only show in developer changelog
2025-01-06 17:01:41 +01:00
656 changed files with 22905 additions and 11314 deletions

View File

@@ -1358,12 +1358,30 @@ gd::String EventsCodeGenerator::GeneratePropertyGetter(const gd::PropertiesConta
return "getProperty" + property.GetName() + "As" + type + "()";
}
gd::String EventsCodeGenerator::GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property) {
return "getProperty" + property.GetName() + "()";
}
gd::String EventsCodeGenerator::GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode) {
return "setProperty" + property.GetName() + "(" + operandCode + ")";
}
gd::String EventsCodeGenerator::GenerateParameterGetter(const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context) {
return "getParameter" + parameter.GetName() + "As" + type + "()";
}
gd::String EventsCodeGenerator::GenerateParameterGetterWithoutCasting(
const gd::ParameterMetadata &parameter) {
return "getParameter" + parameter.GetName() + "()";
}
EventsCodeGenerator::EventsCodeGenerator(const gd::Project& project_,
const gd::Layout& layout,
const gd::Platform& platform_)

View File

@@ -467,7 +467,14 @@ class GD_CORE_API EventsCodeGenerator {
*/
virtual gd::String GetCodeNamespace() { return ""; };
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE, ANY_VARIABLE };
enum VariableScope {
LAYOUT_VARIABLE = 0,
PROJECT_VARIABLE,
OBJECT_VARIABLE,
ANY_VARIABLE,
VARIABLE_OR_PROPERTY,
VARIABLE_OR_PROPERTY_OR_PARAMETER
};
/**
* Generate a single unique number for the specified instruction.
@@ -510,6 +517,11 @@ class GD_CORE_API EventsCodeGenerator {
GenerateAnyOrSceneVariableGetter(const gd::Expression &variableExpression,
EventsCodeGenerationContext &context);
virtual gd::String GeneratePropertySetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property,
const gd::String &operandCode);
protected:
virtual const gd::String GenerateRelationalOperatorCodes(
const gd::String& operatorString);
@@ -565,7 +577,8 @@ protected:
const gd::String& variableName,
const VariableScope& scope,
gd::EventsCodeGenerationContext& context,
const gd::String& objectName) {
const gd::String& objectName,
bool hasChild) {
// This code is only used as a mock.
// See the real implementation in GDJS.
if (scope == LAYOUT_VARIABLE) {
@@ -573,7 +586,9 @@ protected:
} else if (scope == PROJECT_VARIABLE) {
return "getProjectVariable(" + variableName + ")";
} else if (scope == ANY_VARIABLE) {
} else if (scope == ANY_VARIABLE || scope == VARIABLE_OR_PROPERTY ||
scope == VARIABLE_OR_PROPERTY_OR_PARAMETER) {
// TODO Split the 3 cases to make tests stronger.
return "getAnyVariable(" + variableName + ")";
}
@@ -627,11 +642,18 @@ protected:
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String GeneratePropertyGetterWithoutCasting(
const gd::PropertiesContainer &propertiesContainer,
const gd::NamedPropertyDescriptor &property);
virtual gd::String GenerateParameterGetter(
const gd::ParameterMetadata& parameter,
const gd::String& type,
gd::EventsCodeGenerationContext& context);
virtual gd::String
GenerateParameterGetterWithoutCasting(const gd::ParameterMetadata &parameter);
/**
* \brief Generate the code to reference an object which is
* in an empty/null state.

View File

@@ -135,18 +135,20 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
EventsCodeGenerator::VariableScope scope =
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
: type == "variableOrProperty"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY
: type == "variableOrPropertyOrParameter"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.name, scope, context, objectName);
node.name, scope, context, objectName, node.child != nullptr);
if (node.child) node.child->Visit(*this);
} else {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
@@ -163,7 +165,7 @@ void ExpressionCodeGenerator::OnVisitVariableNode(VariableNode& node) {
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "");
node.name, gd::EventsCodeGenerator::ANY_VARIABLE, context, "", node.child != nullptr);
if (node.child) node.child->Visit(*this);
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
@@ -184,8 +186,9 @@ void ExpressionCodeGenerator::OnVisitVariableAccessorNode(
VariableAccessorNode& node) {
if (!objectNameToUseForVariableAccessor.empty()) {
// Use the name of the object passed by the parent, as we need both to access an object variable.
output += codeGenerator.GenerateGetVariable(node.name,
gd::EventsCodeGenerator::OBJECT_VARIABLE, context, objectNameToUseForVariableAccessor);
output += codeGenerator.GenerateGetVariable(
node.name, gd::EventsCodeGenerator::OBJECT_VARIABLE, context,
objectNameToUseForVariableAccessor, node.child != nullptr);
// We have accessed an object variable, from now we can continue accessing the child variables
// (including using the bracket notation).
@@ -222,24 +225,27 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
output +=
codeGenerator.GenerateObject(node.identifierName, type, context);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
EventsCodeGenerator::VariableScope scope =
EventsCodeGenerator::VariableScope scope =
type == "variable"
? gd::EventsCodeGenerator::ANY_VARIABLE
: type == "globalvar"
? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar"
? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
: type == "variableOrProperty"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY
: type == "variableOrPropertyOrParameter"
? gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER
: type == "globalvar" ? gd::EventsCodeGenerator::PROJECT_VARIABLE
: type == "scenevar" ? gd::EventsCodeGenerator::LAYOUT_VARIABLE
: gd::EventsCodeGenerator::OBJECT_VARIABLE;
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(codeGenerator.GetPlatform(),
codeGenerator.GetObjectsContainersList(),
rootObjectName,
node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName);
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
auto objectName = gd::ExpressionVariableOwnerFinder::GetObjectName(
codeGenerator.GetPlatform(), codeGenerator.GetObjectsContainersList(),
rootObjectName, node);
output += codeGenerator.GenerateGetVariable(
node.identifierName, scope, context, objectName,
!node.childIdentifierName.empty());
if (!node.childIdentifierName.empty()) {
output +=
codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}
} else {
const auto& variablesContainersList = codeGenerator.GetProjectScopedContainers().GetVariablesContainersList();
const auto& propertiesContainersList = codeGenerator.GetProjectScopedContainers().GetPropertiesContainersList();
@@ -249,12 +255,13 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
codeGenerator.GetProjectScopedContainers().MatchIdentifierWithName<void>(node.identifierName, [&]() {
// Generate the code to access the object variable.
output += codeGenerator.GenerateGetVariable(
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE, context, node.identifierName);
node.childIdentifierName, gd::EventsCodeGenerator::OBJECT_VARIABLE,
context, node.identifierName, !node.childIdentifierName.empty());
output += codeGenerator.GenerateVariableValueAs(type);
}, [&]() {
output += codeGenerator.GenerateGetVariable(
node.identifierName, gd::EventsCodeGenerator::ANY_VARIABLE, context,
"");
node.identifierName, gd::EventsCodeGenerator::VARIABLE_OR_PROPERTY_OR_PARAMETER, context,
"", !node.childIdentifierName.empty());
if (!node.childIdentifierName.empty()) {
output += codeGenerator.GenerateVariableAccessor(node.childIdentifierName);
}

View File

@@ -141,7 +141,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
"res/function32.png")
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.SetRelevantForFunctionEventsOnly()
.MarkAsAdvanced();
.MarkAsAdvanced()
.SetHidden();
extension
.AddExpression(
@@ -177,7 +178,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition(
@@ -191,7 +193,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("functionParameterName", _("Parameter name"), "number,string,boolean")
.UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
}
} // namespace gd

View File

@@ -117,7 +117,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Change the position of the center of _PARAM0_: _PARAM1_ "
"_PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png",
"res/actions/position_black.png")
.AddParameter("object", _("Object"))
@@ -133,7 +133,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center X position"),
_("the X position of the center of rotation"),
_("the X position of the center"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -144,7 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Center Y position"),
_("the Y position of the center of rotation"),
_("the Y position of the center"),
_("Position/Center"),
_("Position Center"),
"res/actions/position24_black.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -155,7 +155,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) left position"),
_("the bounding box left position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-left_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -166,7 +166,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Bounding box top position"),
_("the bounding box (the area encapsulating the object) top position"),
_("the bounding box top position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-top_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -177,7 +177,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) right position"),
_("the bounding box right position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-right_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -188,7 +188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) bottom position"),
_("the bounding box bottom position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-bottom_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -199,7 +199,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center X position"),
_("the bounding box center X position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -210,7 +210,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("the bounding box (the area encapsulating "
"the object) center Y position"),
_("the bounding box center Y position"),
_("Position/Bounding Box"),
_("Position Bounding Box"),
"res/conditions/bounding-box-center_black.svg")
.AddParameter("object", _("Object"))
.UseStandardParameters("number", ParameterOptions::MakeNewOptions());
@@ -255,7 +255,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
.AddCodeOnlyParameter("currentScene", "")
@@ -269,7 +268,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle to rotate towards (in degrees)"))
.AddParameter("expression", _("Angular speed (in degrees per second)"))
@@ -285,7 +283,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle"),
"res/actions/rotate24_black.png",
"res/actions/rotate_black.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
@@ -304,12 +301,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Speed on X axis (in pixels per second)"))
.AddParameter("expression", _("Speed on Y axis (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0");
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddAction("AddForceAL",
_("Add a force (angle)"),
@@ -321,12 +318,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -339,13 +336,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position"))
.AddParameter("expression", _("Y position"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -360,13 +357,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", "X position of the center")
.AddParameter("expression", "Y position of the center")
.AddParameter("expression", "Speed (in Degrees per seconds)")
.AddParameter("expression", "Distance (in pixels)")
.AddParameter("forceMultiplier", "Force multiplier")
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddAction("Arreter",
@@ -376,8 +373,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/arreter24.png",
"res/actions/arreter.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("Delete",
@@ -429,6 +426,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetStringObjectVariable",
@@ -443,6 +441,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("SetBooleanObjectVariable",
@@ -458,6 +457,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("NumberObjectVariable",
@@ -472,6 +472,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("StringObjectVariable",
@@ -486,6 +487,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddCondition("BooleanObjectVariable",
@@ -502,6 +504,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("yesorno", _("Value"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForLayoutEventsOnly();
obj.AddAction("ModVarObjet",
@@ -514,6 +517,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
@@ -528,6 +532,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
@@ -544,6 +549,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddAction(
@@ -560,6 +566,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableChildExists",
@@ -567,24 +574,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Check if the specified child of the object "
"structure variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableRemoveChild",
_("Remove a child"),
_("Remove a child from an object structure variable."),
_("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("ObjectVariableClearChildren",
@@ -592,11 +601,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Remove all the children from the object array or structure "
"variable."),
_("Clear children from variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction("Cache",
@@ -691,8 +701,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/arret24.png",
"res/conditions/arret.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("Vitesse",
@@ -702,10 +712,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.AddParameter("object", _("Object"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
// Deprecated
@@ -722,6 +732,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("IsTotalForceAngleAround",
@@ -735,6 +746,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddCondition("VarObjet",
@@ -749,6 +761,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetTxt",
@@ -763,6 +776,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("ObjectVariableAsBoolean",
@@ -777,6 +791,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddCondition("VarObjetDef",
@@ -796,12 +811,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add text variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
@@ -809,12 +825,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add variable array value"),
_("Adds a number to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
@@ -823,12 +840,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add value _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForLayoutEventsOnly();
@@ -838,7 +856,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -847,6 +865,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetHidden();
@@ -855,7 +874,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add existing variable"),
_("Adds an existing variable to the end of an object array variable."),
_("Add variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -864,6 +883,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetParameterLongDescription(_("The content of the object variable will "
"*be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddAction(
@@ -871,12 +891,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add text variable"),
_("Adds a text (string) to the end of an object array variable."),
_("Add text _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -884,12 +905,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add number variable"),
_("Adds a number to the end of an object array variable."),
_("Add number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -898,12 +920,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add boolean variable"),
_("Adds a boolean to the end of an object array variable."),
_("Add boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
@@ -914,12 +937,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"_PARAM0_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddCondition(
@@ -927,13 +951,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Number of children"),
_("Compare the number of children in an object array variable."),
_("The number of children in the array variable _PARAM1_"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
obj.AddStrExpression(
@@ -941,40 +966,44 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("First text child"),
_("Get the value of the first element of an object array variable, if "
"it is a text (string) variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression(
"ArrayVariableFirstNumber",
_("First number child"),
_("Get the value of the first element of an object array variable, if "
"it is a number variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression(
"ArrayVariableLastString",
_("Last text child"),
_("Get the value of the last element of an object array variable, if "
"it is a text (string) variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddExpression(
"ArrayVariableLastNumber",
_("Last number child"),
_("Get the value of the last element of an object array variable, if "
"it is a number variable."),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"));
.AddParameter("objectvar", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddCondition("BehaviorActivated",
_("Behavior activated"),
@@ -1009,12 +1038,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Target Object"))
.AddParameter("expression", _("Speed (in pixels per second)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1029,13 +1058,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Rotate around this object"))
.AddParameter("expression", _("Speed (in degrees per second)"))
.AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"), "", true)
.SetDefaultValue("0")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
obj.AddAction("MettreAutour",
@@ -1063,10 +1092,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("objectList", "Object 2 (won't move)");
.AddParameter("objectList", "Object 2 (won't move)")
.SetHelpPath("/tutorials/how-to-move-objects/");
// Deprecated action
obj.AddAction("Ecarter",
@@ -1090,7 +1119,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Objects (won't move)"))
.AddParameter("yesorno",
@@ -1099,6 +1127,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
obj.AddCondition("CollisionPoint",
@@ -1111,6 +1140,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the point"))
.AddParameter("expression", _("Y position of the point"))
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1142,6 +1172,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetHidden();
obj.AddCondition(
@@ -1157,6 +1188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.AddParameter("relationalOperator", _("Sign of the test"), "time")
.AddParameter("expression", _("Time in seconds"))
.SetHelpPath("/all-features/timers-and-time/")
.SetManipulatedType("number");
obj.AddCondition("ObjectTimerPaused",
@@ -1168,6 +1200,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/conditions/timerPaused.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction(
@@ -1180,7 +1213,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer24.png",
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
obj.AddAction("PauseObjectTimer",
_("Pause an object timer"),
@@ -1191,6 +1225,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/pauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("UnPauseObjectTimer",
@@ -1202,6 +1237,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/unPauseTimer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddAction("RemoveObjectTimer",
@@ -1213,6 +1249,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/timer.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/")
.MarkAsAdvanced();
obj.AddExpression("X",
@@ -1241,28 +1278,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("X coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceY",
_("Y coordinate of the sum of forces"),
_("Y coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceAngle",
_("Angle of the sum of forces"),
_("Angle of the sum of forces (in degrees)"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("ForceLength",
_("Length of the sum of forces"),
_("Length of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/");
obj.AddExpression("Longueur",
_("Length of the sum of forces"),
@@ -1270,6 +1311,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHelpPath("/tutorials/how-to-move-objects/")
.SetHidden();
obj.AddExpression("Width",
@@ -1366,10 +1408,11 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"VariableChildCount",
_("Number of children"),
_("Number of children in an object array or structure variable"),
_("Variables/Arrays and structures"),
_("Variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array or structure variable"));
.AddParameter("objectvar", _("Array or structure variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
obj.AddStrExpression("VariableString",
_("Text variable"),
@@ -1378,6 +1421,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.SetHelpPath("/all-features/variables/object-variables/")
.SetRelevantForFunctionEventsOnly();
obj.AddExpression("ObjectTimerElapsedTime",
@@ -1386,7 +1430,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Timers"),
"res/actions/time.png")
.AddParameter("object", _("Object"))
.AddParameter("identifier", _("Timer's name"), "objectTimer");
.AddParameter("identifier", _("Timer's name"), "objectTimer")
.SetHelpPath("/all-features/timers-and-time/");
obj.AddExpression("AngleToObject",
_("Angle between two objects"),
@@ -1606,6 +1651,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"res/actions/doMove24.png",
"res/actions/doMove.png")
.AddCodeOnlyParameter("currentScene", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1621,6 +1667,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Tolerance, in degrees"))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/tutorials/how-to-move-objects/")
.MarkAsAdvanced();
extension
@@ -1753,6 +1800,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"",
true)
.SetDefaultValue("no")
.SetHelpPath("/all-features/collisions/")
.MarkAsSimple();
extension
@@ -1815,6 +1863,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension
@@ -1846,6 +1895,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Scene variable where to store the Y position of the intersection. "
"If no intersection is found, the variable won't be changed."))
.AddCodeOnlyParameter("conditionInverted", "")
.SetHelpPath("/all-features/collisions/")
.MarkAsAdvanced();
extension

View File

@@ -92,14 +92,16 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
.SetCanHaveSubInstructions()
.MarkAsAdvanced();
extension.AddCondition(
"Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png");
extension
.AddCondition("Once",
_("Trigger once while true"),
_("Run actions only once, for each time the conditions "
"have been met."),
_("Trigger once"),
"",
"res/conditions/once24.png",
"res/conditions/once.png")
.SetHelpPath("/all-features/advanced-conditions/trigger-once");
extension
.AddCondition("CompareNumbers",

View File

@@ -28,7 +28,7 @@ BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
.AddAction("CreateObjectsFromExternalLayout",
_("Create objects from an external layout"),
_("Create objects from an external layout."),
_("Create objects from the external layout named _PARAM1_"),
_("Create objects from the external layout named _PARAM1_ at position _PARAM2_;_PARAM3_;_PARAM4_"),
"",
"res/ribbon_default/externallayout32.png",
"res/ribbon_default/externallayout32.png")

View File

@@ -35,7 +35,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key"));
.AddParameter("key", _("Key to check"))
.SetHidden();
extension
.AddCondition("KeyReleased",
@@ -46,33 +47,32 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("key", _("Key"));
.AddParameter("key", _("Key to check"))
.SetHidden();
extension
.AddCondition("KeyFromTextPressed",
_("Key pressed (text expression)"),
_("Check if a key, retrieved from the result of the "
"expression, is pressed"),
_("Key pressed"),
_("Check if a key is pressed"),
_("_PARAM1_ key is pressed"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.MarkAsAdvanced();
.AddParameter("keyboardKey", _("Key to check"))
.MarkAsSimple();
extension
.AddCondition("KeyFromTextReleased",
_("Key released (text expression)"),
_("Check if a key, retrieved from the result of the "
"expression, was just released"),
_("Key released"),
_("Check if a key was just released"),
_("_PARAM1_ key is released"),
"",
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("string", _("Expression generating the key to check"))
.MarkAsAdvanced();
.AddParameter("keyboardKey", _("Key to check"))
.MarkAsSimple();
extension
.AddCondition("AnyKeyPressed",

View File

@@ -151,7 +151,8 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension
.AddExpression("abs",
_("Absolute value"),
_("Absolute value"),
_("Return the non-negative value by removing the sign. "
"The absolute value of -8 is 8."),
"",
"res/mathfunction.png")
.AddParameter("expression", _("Expression"));

View File

@@ -252,7 +252,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
.MarkAsSimple()
.SetHidden();
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed")
@@ -262,49 +263,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition("MouseButtonReleased",
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
_("Touch or _PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
.MarkAsSimple()
.SetHidden();
extension
.AddCondition(
"MouseButtonFromTextPressed",
_("Mouse button pressed or touch held (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, is pressed."),
_("_PARAM1_ mouse button is pressed"),
_("Mouse button pressed or touch held"),
_("Check if the specified mouse button is pressed or "
"if a touch is in contact with the screen."),
_("Touch or _PARAM1_ mouse button is down"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
.AddParameter("mouseButton", _("Button to check"))
.MarkAsSimple();
extension
.AddCondition(
"MouseButtonFromTextReleased",
_("Mouse button released (text expression)"),
_("Check if a mouse button, retrieved from the result of the "
"expression, was just released."),
_("_PARAM1_ mouse button is released"),
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("Touch or _PARAM1_ mouse button is released"),
"",
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("stringWithSelector",
_("Expression generating the mouse button to check"),
"[\"Left\", \"Right\", \"Middle\"]")
.SetParameterLongDescription(
_("Possible values are Left, Right and Middle."))
.MarkAsAdvanced();
.AddParameter("mouseButton", _("Button to check"))
.MarkAsSimple();
extension
.AddExpressionAndCondition("number",

View File

@@ -33,7 +33,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions());
@@ -45,7 +45,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions());
@@ -58,7 +58,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
// This parameter allows to keep the operand expression
@@ -73,7 +73,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions());
@@ -85,7 +85,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions());
@@ -98,7 +98,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"",
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("variableOrProperty", _("Variable"))
.AddParameter("operator", _("Value"), "boolean")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
@@ -116,6 +116,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddParameter("variable", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -129,6 +130,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/conditions/var.png")
.AddParameter("variable", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -142,6 +144,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -154,6 +157,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("variable", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -170,6 +174,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -183,6 +188,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -195,6 +201,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -207,6 +214,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -221,6 +229,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"res/actions/var.png")
.AddParameter("variable", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced();
extension
@@ -231,7 +240,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
@@ -241,7 +251,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddStrExpression(
@@ -251,7 +262,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a text (string)."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression(
@@ -261,7 +273,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"it is a number."),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array variable"));
.AddParameter("variable", _("Array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/");
// Legacy instructions
@@ -270,26 +283,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number variable"),
_("Compare the number value of a scene variable."),
_("The number of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VarSceneTxt",
_("Text variable"),
_("Compare the text (string) of a scene variable."),
_("The text of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition(
@@ -297,13 +312,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"),
_("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VariableChildExists",
@@ -311,12 +327,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the scene structure "
"variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -325,12 +343,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Check if the specified child of the global structure "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("string", _("Name of the child"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -338,7 +358,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"Variable defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -350,13 +370,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number variable"),
_("Compare the number value of a global variable."),
_("the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -364,13 +385,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Text variable"),
_("Compare the text (string) of a global variable."),
_("the text of the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -379,20 +401,21 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Boolean variable"),
_("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddCondition("VarGlobalDef",
"Variable defined",
"Test if a global variable exists.",
"Global variable _PARAM0_ is defined",
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -405,26 +428,28 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change number variable"),
_("Modify the number value of a scene variable."),
_("the scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ModVarSceneTxt",
_("Change text variable"),
_("Modify the text (string) of a scene variable."),
_("the text of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -432,12 +457,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"),
_("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ToggleSceneVariableAsBoolean",
@@ -446,24 +472,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ModVarGlobal",
_("Change number variable"),
_("Modify the number value of a global variable."),
_("the global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("number",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -471,13 +499,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change text variable"),
_("Modify the text (string) of a global variable."),
_("the text of global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string",
ParameterOptions::MakeNewOptions())
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -486,12 +515,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Change boolean variable"),
_("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("ToggleGlobalVariableAsBoolean",
@@ -500,11 +530,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of global variable _PARAM0_"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -512,13 +543,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a scene structure variable."),
_("Remove child _PARAM1_ from scene structure variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -526,13 +559,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a global structure variable."),
_("Remove child _PARAM1_ from global structure variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure variable"))
.AddParameter("string", _("Child's name"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.MarkAsAdvanced()
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction("VariableClearChildren",
@@ -540,11 +575,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the scene structure or array "
"variable."),
_("Clear children from scene variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -553,11 +590,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove all the children from the global structure or array "
"variable."),
_("Clear children from global variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Structure or array variable"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -566,7 +605,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Adds an existing variable at the end of a scene array "
"variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
@@ -574,7 +613,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -583,12 +624,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"),
_("Adds a text (string) at the end of a scene array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -596,12 +639,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"),
_("Adds a number at the end of a scene array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -609,12 +654,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"),
_("Adds a boolean at the end of a scene array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -624,12 +671,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"variable."),
_("Remove variable at index _PARAM1_ from scene array "
"variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -638,13 +687,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"),
_("Compare the number of children in a scene array variable."),
_("The number of children in the array variable _PARAM0_"),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -653,10 +704,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"),
_("Get the value of the first element of a scene array variable, if "
"it is a text (string)."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -664,10 +717,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First number child"),
_("Get the value of the first element of a scene array variable, if "
"it is a number."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression(
@@ -675,10 +730,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"),
_("Get the value of the last element of a scene array variable, if "
"it is a text (string)."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -686,10 +743,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"),
_("Get the value of the last element of a scene array variable, if "
"it is a number."),
_("External variables/Scene variables/Arrays and structures"),
_("External variables Scene variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddAction(
@@ -697,7 +756,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add existing variable"),
_("Adds an existing variable at the end of a global array variable."),
_("Add variable _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
@@ -705,7 +764,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetParameterLongDescription(
_("The content of the variable will *be copied* and added at the "
"end of the array."))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -715,12 +776,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"array variable."),
_("Remove variable at index _PARAM1_ from global array "
"variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Index to remove"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -729,12 +792,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add text variable"),
_("Adds a text (string) at the end of a global array variable."),
_("Add text _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("Text to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -742,12 +807,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add number variable"),
_("Adds a number at the end of a global array variable."),
_("Add number _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -755,12 +822,14 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Add boolean variable"),
_("Adds a boolean at the end of a global array variable."),
_("Add boolean _PARAM1_ to array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to add"))
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -769,13 +838,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Number of children"),
_("Compare the number of children in a global array variable."),
_("The number of children of the array variable _PARAM0_"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Array variable"))
.UseStandardRelationalOperatorParameters(
"number", ParameterOptions::MakeNewOptions())
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden()
.MarkAsAdvanced();
extension
@@ -783,20 +854,24 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("First text child"),
_("Value of the first element of a global array "
"variable, if it is a text (string) variable."),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariableFirstNumber",
_("First number child"),
_("Value of the first element of a global array "
"variable, if it is a number variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression(
@@ -804,10 +879,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last text child"),
_("Value of the last element of a global array variable, if "
"it is a text (string) variable."),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression(
@@ -815,20 +892,23 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Last number child"),
_("Value of the last element of a global array variable, if "
"it is a number variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariableChildCount",
_("Number of children"),
_("Number of children in a global array or "
"structure variable"),
_("External variables/Global variables/Arrays and structures"),
_("External variables Global variables Arrays and structures"),
"res/actions/var.png")
.AddParameter("globalvar", _("Array or structure variable"))
.SetRelevantForFunctionEventsOnly();
.SetHelpPath("/all-features/variables/structures-and-arrays/")
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("VariableChildCount",
@@ -837,43 +917,48 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"structure variable"),
_("Arrays and structures"),
"res/actions/var.png")
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable");
.AddParameter("variable", _("Array or structure variable"), "AllowUndeclaredVariable")
.SetHelpPath("/all-features/variables/structures-and-arrays/");
extension
.AddExpression("Variable",
_("Number variable"),
_("Number value of a scene variable"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression("VariableString",
_("Text variable"),
_("Text of a scene variable"),
_("External variables/Scene variables"),
_("External variables Scene variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddExpression("GlobalVariable",
_("Number variable"),
_("Number value of a global variable"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Name of the global variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
extension
.AddStrExpression("GlobalVariableString",
_("Text variable"),
_("Text of a global variable"),
_("External variables/Global variables"),
_("External variables Global variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.SetRelevantForFunctionEventsOnly();
.SetRelevantForFunctionEventsOnly()
.SetHidden();
}
} // namespace gd

View File

@@ -46,30 +46,25 @@ ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24,
[]() -> std::unique_ptr<gd::ObjectConfiguration> {
gd::LogFatalError(
"Error: Event-based objects don't have blueprint. "
"This method should never be called.");
return nullptr;
}) {}
: name(name_),
iconFilename(icon24x24),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
}
ObjectMetadata::ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24,
CreateFunPtr createFunPtrP)
: name(name_),
iconFilename(icon24x24),
createFunPtr(createFunPtrP),
extensionNamespace(extensionNamespace_) {
SetFullName(gd::String(fullname_));
SetDescription(gd::String(description_));
CreateFunPtr createFunPtr_)
: ObjectMetadata(extensionNamespace_,
name_,
fullname_,
description_,
icon24x24) {
createFunPtr = createFunPtr_;
}
gd::InstructionMetadata& ObjectMetadata::AddCondition(

View File

@@ -39,6 +39,8 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/**
* \brief Construct an object metadata, using a "blueprint" object that will
* be copied when a new object is requested.
*
* \note This is used for objects declared in JavaScript extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -47,9 +49,9 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
const gd::String& icon24x24_,
std::shared_ptr<gd::ObjectConfiguration> blueprintObject_);
/**
* \brief Construct an object metadata, without "blueprint" object
* \brief Construct an object metadata.
*
* \note This is used by events based objects.
* \note This is used by events based objects ("custom objects").
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -60,14 +62,17 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
/**
* \brief Construct an object metadata, with a function that will be called
* to instantiate a new object.
*
* \note This is used for objects declared in C++ extensions.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_,
CreateFunPtr createFunPtrP);
ObjectMetadata() : createFunPtr(NULL) {}
CreateFunPtr createFunPtr_);
ObjectMetadata() {}
virtual ~ObjectMetadata(){};
/**
@@ -360,7 +365,7 @@ class GD_CORE_API ObjectMetadata : public InstructionOrExpressionContainerMetada
std::vector<gd::String> includeFiles;
gd::String className;
CreateFunPtr createFunPtr;
CreateFunPtr createFunPtr = nullptr;
private:
gd::String extensionNamespace;

View File

@@ -33,7 +33,8 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
const auto& parameter = parameters.GetParameter(i);
if (parameter.GetName().empty()) continue;
if (gd::ParameterMetadata::IsObject(parameter.GetType())) {
auto &valueTypeMetadata = parameter.GetValueTypeMetadata();
if (valueTypeMetadata.IsObject()) {
const gd::String& objectName = parameter.GetName();
const gd::String& objectType = parameter.GetExtraInfo();
allObjectNames.insert(objectName);
@@ -68,7 +69,7 @@ void ParameterMetadataTools::ParametersToObjectsContainer(
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
lastObjectName = objectName;
} else if (gd::ParameterMetadata::IsBehavior(parameter.GetType())) {
} else if (valueTypeMetadata.IsBehavior()) {
if (!lastObjectName.empty()) {
if (outputObjectsContainer.HasObjectNamed(lastObjectName)) {
const gd::String& behaviorName = parameter.GetName();

View File

@@ -79,6 +79,8 @@ const gd::String ValueTypeMetadata::colorValueType = "color";
const gd::String ValueTypeMetadata::choiceValueType = "stringWithSelector";
const gd::String ValueTypeMetadata::behaviorValueType = "behavior";
const gd::String ValueTypeMetadata::leaderboardIdValueType = "leaderboardId";
const gd::String ValueTypeMetadata::objectAnimationNameValueType = "objectAnimationName";
const gd::String ValueTypeMetadata::keyboardKeyValueType = "keyboardKey";
const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
const gd::String &propertyType) {
@@ -94,8 +96,12 @@ const gd::String &ValueTypeMetadata::ConvertPropertyTypeToValueType(
return behaviorValueType;
} else if (propertyType == "LeaderboardId") {
return leaderboardIdValueType;
} else if (propertyType == "ObjectAnimationName") {
return objectAnimationNameValueType;
} else if (propertyType == "KeyboardKey") {
return keyboardKeyValueType;
}
// For "String" or default
// For "String", "Resource", "MultilineString" or default
return stringValueType;
};

View File

@@ -129,7 +129,7 @@ class GD_CORE_API ValueTypeMetadata {
}
/**
* \brief Return true if the type of the parameter is a number.
* \brief Return true if the type of the parameter is a variable.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
@@ -148,6 +148,19 @@ class GD_CORE_API ValueTypeMetadata {
return gd::ValueTypeMetadata::GetPrimitiveValueType(type) == "variable";
}
/**
* \brief Return true if the type of the parameter is a variable and not a
* property or a parameter.
*/
bool IsVariableOnly() const {
return
// Any variable.
name == "variable" ||
// Old, "pre-scoped" variables:
name == "objectvar" || name == "globalvar" ||
name == "scenevar";
}
/**
* \brief Return true if the type is a variable but from a specific scope
* (scene, project or object). In new code, prefer to use the more generic "variable"
@@ -212,15 +225,20 @@ class GD_CORE_API ValueTypeMetadata {
parameterType == "functionParameterName" ||
parameterType == "externalLayoutName" ||
parameterType == "leaderboardId" ||
parameterType == "keyboardKey" ||
parameterType == "mouseButton" ||
parameterType == "identifier";
} else if (type == "boolean") {
return parameterType == "yesorno" || parameterType == "trueorfalse";
} else if (type == "variable") {
return
parameterType == "variable" || // Any variable.
// Old, "pre-scoped" variables:
parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
// Any variable.
parameterType == "variable" ||
parameterType == "variableOrProperty" ||
parameterType == "variableOrPropertyOrParameter" ||
// Old, "pre-scoped" variables:
parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
} else if (type == "resource") {
return parameterType == "fontResource" ||
parameterType == "audioResource" ||
@@ -316,6 +334,8 @@ class GD_CORE_API ValueTypeMetadata {
static const gd::String choiceValueType;
static const gd::String behaviorValueType;
static const gd::String leaderboardIdValueType;
static const gd::String objectAnimationNameValueType;
static const gd::String keyboardKeyValueType;
};
} // namespace gd

View File

@@ -38,12 +38,14 @@ bool Platform::AddExtension(std::shared_ptr<gd::PlatformExtension> extension) {
extensionsLoaded.push_back(extension);
// Load all creation/destruction functions for objects provided by the
// extension
// Load all creation functions for objects provided by the
// extension.
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
creationFunctionTable[objectsTypes[i]] =
extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
CreateFunPtr createFunPtr = extension->GetObjectCreationFunctionPtr(objectsTypes[i]);
if (createFunPtr != nullptr) {
creationFunctionTable[objectsTypes[i]] = createFunPtr;
}
}
for (const auto& it :
@@ -62,7 +64,9 @@ void Platform::RemoveExtension(const gd::String& name) {
if (extension->GetName() == name) {
vector<gd::String> objectsTypes = extension->GetExtensionObjectsTypes();
for (std::size_t i = 0; i < objectsTypes.size(); ++i) {
creationFunctionTable.erase(objectsTypes[i]);
if (creationFunctionTable.find(objectsTypes[i]) != creationFunctionTable.end()) {
creationFunctionTable.erase(objectsTypes[i]);
}
}
}
}

View File

@@ -141,7 +141,7 @@ class GD_CORE_API ExpressionParameterReplacer
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsParameterReplacer::CanContainParameter(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariable();
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
}
@@ -197,7 +197,7 @@ bool EventsParameterReplacer::DoVisitInstruction(gd::Instruction& instruction,
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
parameterMetadata.GetValueTypeMetadata().IsVariable(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(),
oldToNewPropertyNames);
node->Visit(renamer);
@@ -221,7 +221,7 @@ bool EventsParameterReplacer::DoVisitEventExpression(
if (node) {
ExpressionParameterReplacer renamer(
platform, GetProjectScopedContainers(),
metadata.GetValueTypeMetadata().IsVariable(), oldToNewPropertyNames);
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames);
node->Visit(renamer);
if (renamer.HasDoneRenaming()) {

View File

@@ -168,7 +168,7 @@ class GD_CORE_API ExpressionPropertyReplacer
parameterMetadata->GetValueTypeMetadata();
if (gd::EventsPropertyReplacer::CanContainProperty(
parameterTypeMetadata)) {
isParentTypeAVariable = parameterTypeMetadata.IsVariable();
isParentTypeAVariable = parameterTypeMetadata.IsVariableOnly();
parameter->Visit(*this);
}
}
@@ -231,7 +231,7 @@ bool EventsPropertyReplacer::DoVisitInstruction(gd::Instruction& instruction,
if (node) {
ExpressionPropertyReplacer renamer(
platform, GetProjectScopedContainers(), targetPropertiesContainer,
parameterMetadata.GetValueTypeMetadata().IsVariable(),
parameterMetadata.GetValueTypeMetadata().IsVariableOnly(),
oldToNewPropertyNames, removedPropertyNames);
node->Visit(renamer);
@@ -257,7 +257,7 @@ bool EventsPropertyReplacer::DoVisitEventExpression(
if (node) {
ExpressionPropertyReplacer renamer(
platform, GetProjectScopedContainers(), targetPropertiesContainer,
metadata.GetValueTypeMetadata().IsVariable(), oldToNewPropertyNames,
metadata.GetValueTypeMetadata().IsVariableOnly(), oldToNewPropertyNames,
removedPropertyNames);
node->Visit(renamer);

View File

@@ -71,13 +71,18 @@ bool EventsVariableInstructionTypeSwitcher::DoVisitInstruction(gd::Instruction&
.GetObjectsContainersList()
.GetObjectOrGroupVariablesContainer(lastObjectName);
}
} else if (type == "variableOrProperty") {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyName(variableName);
} else {
if (GetProjectScopedContainers().GetVariablesContainersList().Has(
variableName)) {
variablesContainer =
&GetProjectScopedContainers()
.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName);
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName);
}
}

View File

@@ -122,7 +122,7 @@ class GD_CORE_API ExpressionVariableReplacer
[&]() {
// This is a variable.
if (&projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(node.name) ==
.GetVariablesContainerFromVariableOrPropertyOrParameterName(node.name) ==
&targetVariablesContainer) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:
@@ -235,7 +235,7 @@ class GD_CORE_API ExpressionVariableReplacer
[&]() {
// This is a variable.
if (&projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(
.GetVariablesContainerFromVariableOrPropertyOrParameterName(
node.identifierName) == &targetVariablesContainer) {
// The node represents a variable, that can come from the target
// (because the target is in the scope), replace or remove it:

View File

@@ -0,0 +1,235 @@
#include "ExampleExtensionUsagesFinder.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ExpressionTypeFinder.h"
#include "GDCore/IDE/ProjectBrowserHelper.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
std::set<gd::String>
ExampleExtensionUsagesFinder::GetUsedExtensions(gd::Project &project) {
ExampleExtensionUsagesFinder worker(project);
gd::ProjectBrowserHelper::ExposeProjectObjects(project, worker);
gd::ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(project,
worker);
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
worker.isStoreExtension =
eventsFunctionsExtension.GetOriginName() == "gdevelop-extension-store";
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
project, eventsFunctionsExtension, worker);
}
if (!worker.has3DObjects) {
worker.usedExtensions.erase("Scene3D");
}
return worker.usedExtensions;
};
void ExampleExtensionUsagesFinder::AddUsedExtension(
const gd::PlatformExtension &extension) {
usedExtensions.insert(extension.GetName());
}
void ExampleExtensionUsagesFinder::AddUsedBuiltinExtension(
const gd::String &extensionName) {
usedExtensions.insert(extensionName);
}
// Objects scanner
void ExampleExtensionUsagesFinder::DoVisitObject(gd::Object &object) {
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), object.GetType());
if (metadata.GetMetadata().IsRenderedIn3D()) {
has3DObjects = true;
}
AddUsedExtension(metadata.GetExtension());
};
// Behaviors scanner
void ExampleExtensionUsagesFinder::DoVisitBehavior(gd::Behavior &behavior) {
auto metadata = gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
project.GetCurrentPlatform(), behavior.GetTypeName());
AddUsedExtension(metadata.GetExtension());
};
// Instructions scanner
bool ExampleExtensionUsagesFinder::DoVisitInstruction(
gd::Instruction &instruction, bool isCondition) {
auto metadata =
isCondition ? gd::MetadataProvider::GetExtensionAndConditionMetadata(
project.GetCurrentPlatform(), instruction.GetType())
: gd::MetadataProvider::GetExtensionAndActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
// Unused event-based objects or events-based behaviors may use object and
// behavior instructions that should not be detected as extension usage.
// The extension of actually used objects and behaviors will be detected on
// scene objects. This is why object or behavior instructions usually don't
// have any import.
// Built-in extensions that are included by default don't declare any include
// files on their instructions either. To still detect their usage, we
// consider that main events and dedicated extensions can't have dead code.
if (!isStoreExtension || !metadata.GetMetadata().GetIncludeFiles().empty()) {
AddUsedExtension(metadata.GetExtension());
}
gd::ParameterMetadataTools::IterateOverParameters(
instruction.GetParameters(), metadata.GetMetadata().GetParameters(),
[this](const gd::ParameterMetadata &parameterMetadata,
const gd::Expression &parameterValue,
const gd::String &lastObjectName) {
const gd::String &parameterType = parameterMetadata.GetType();
if (gd::ParameterMetadata::IsExpression("string", parameterType)) {
rootType = "string";
parameterValue.GetRootNode()->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("number",
parameterType)) {
rootType = "number";
parameterValue.GetRootNode()->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("variable",
parameterType))
AddUsedBuiltinExtension("BuiltinVariables");
});
return false;
}
// Expressions scanner
// Ignore literals nodes
void ExampleExtensionUsagesFinder::OnVisitNumberNode(NumberNode &node){};
void ExampleExtensionUsagesFinder::OnVisitTextNode(TextNode &node){};
// Ignore nodes without valid extensions
void ExampleExtensionUsagesFinder::OnVisitEmptyNode(EmptyNode &node){};
void ExampleExtensionUsagesFinder::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode &node){};
// Visit sub-expressions
void ExampleExtensionUsagesFinder::OnVisitSubExpressionNode(
SubExpressionNode &node) {
node.expression->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitOperatorNode(OperatorNode &node) {
node.leftHandSide->Visit(*this);
node.rightHandSide->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitUnaryOperatorNode(
UnaryOperatorNode &node) {
node.factor->Visit(*this);
};
// Add variable extension and visit sub-expressions on variable nodes
void ExampleExtensionUsagesFinder::OnVisitVariableNode(VariableNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
auto type = gd::ExpressionTypeFinder::GetType(project.GetCurrentPlatform(),
GetProjectScopedContainers(),
rootType, node);
if (gd::ParameterMetadata::IsExpression("variable", type)) {
// Nothing to do (this can't reference an object)
} else {
GetProjectScopedContainers().MatchIdentifierWithName<void>(
node.name,
[&]() {
// This represents an object.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.name);
AddUsedExtension(metadata.GetExtension());
},
[&]() {
// This is a variable.
},
[&]() {
// This is a property.
},
[&]() {
// This is a parameter.
},
[&]() {
// This is something else.
});
}
if (node.child)
node.child->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitVariableAccessorNode(
VariableAccessorNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
if (node.child)
node.child->Visit(*this);
};
void ExampleExtensionUsagesFinder::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode &node) {
AddUsedBuiltinExtension("BuiltinVariables");
node.expression->Visit(*this);
if (node.child)
node.child->Visit(*this);
};
// Add extensions bound to Objects/Behaviors/Functions
void ExampleExtensionUsagesFinder::OnVisitIdentifierNode(IdentifierNode &node) {
auto type = gd::ExpressionTypeFinder::GetType(project.GetCurrentPlatform(),
GetProjectScopedContainers(),
rootType, node);
if (gd::ParameterMetadata::IsObject(type) ||
GetObjectsContainersList().HasObjectOrGroupNamed(node.identifierName)) {
// An object or object variable is used.
auto metadata = gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.identifierName);
AddUsedExtension(metadata.GetExtension());
}
};
void ExampleExtensionUsagesFinder::OnVisitFunctionCallNode(
FunctionCallNode &node) {
// Extensions of non-free functions are already found when scanning objects.
if (!(node.objectName.empty() && node.behaviorName.empty()))
return;
gd::ExtensionAndMetadata<gd::ExpressionMetadata> metadata;
// Try to find a free number expression
metadata = gd::MetadataProvider::GetExtensionAndExpressionMetadata(
project.GetCurrentPlatform(), node.functionName);
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata())) {
// Try to find a free str expression
metadata = gd::MetadataProvider::GetExtensionAndStrExpressionMetadata(
project.GetCurrentPlatform(), node.functionName);
// No valid expression found, return.
if (gd::MetadataProvider::IsBadExpressionMetadata(metadata.GetMetadata()))
return;
}
// Unused event-based objects or events-based behaviors may use object and
// behavior expressions that should not be detected as extension usage.
// The extension of actually used objects and behaviors will be detected on
// scene objects. This is why object or behavior expressions usually don't
// have any import.
// Built-in extensions that are included by default don't declare any include
// files on their instructions either. To still detect their usage, we
// consider that main events and dedicated extensions can't have dead code.
if (!isStoreExtension || !metadata.GetMetadata().GetIncludeFiles().empty()) {
AddUsedExtension(metadata.GetExtension());
}
};
} // namespace gd

View File

@@ -0,0 +1,77 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/SourceFileMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
class Behavior;
} // namespace gd
namespace gd {
/**
* @brief List extension usages for generated example web-pages.
*
* Dependency transitivity is not ensured (see UsedExtensionsFinder).
*/
class GD_CORE_API ExampleExtensionUsagesFinder
: public ArbitraryObjectsWorker,
public ArbitraryEventsWorkerWithContext,
public ExpressionParser2NodeWorker {
public:
static std::set<gd::String> GetUsedExtensions(gd::Project &project);
private:
ExampleExtensionUsagesFinder(gd::Project &project_) : project(project_){};
gd::Project &project;
gd::String rootType;
bool isStoreExtension = false;
// Result
std::set<gd::String> usedExtensions;
bool has3DObjects = false;
void AddUsedExtension(const gd::PlatformExtension &extension);
void AddUsedBuiltinExtension(const gd::String &extensionName);
// Object Visitor
void DoVisitObject(gd::Object &object) override;
// Behavior Visitor
void DoVisitBehavior(gd::Behavior &behavior) override;
// Instructions Visitor
bool DoVisitInstruction(gd::Instruction &instruction,
bool isCondition) override;
// Expression Visitor
void OnVisitSubExpressionNode(SubExpressionNode &node) override;
void OnVisitOperatorNode(OperatorNode &node) override;
void OnVisitUnaryOperatorNode(UnaryOperatorNode &node) override;
void OnVisitNumberNode(NumberNode &node) override;
void OnVisitTextNode(TextNode &node) override;
void OnVisitVariableNode(VariableNode &node) override;
void OnVisitVariableAccessorNode(VariableAccessorNode &node) override;
void OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode &node) override;
void OnVisitIdentifierNode(IdentifierNode &node) override;
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode &node) override;
void OnVisitFunctionCallNode(FunctionCallNode &node) override;
void OnVisitEmptyNode(EmptyNode &node) override;
};
}; // namespace gd

View File

@@ -1034,7 +1034,7 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetVariableType(variable.GetType());
description.SetVariableScope(
projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName)
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName)
.GetSourceType());
completions.push_back(description);
@@ -1086,7 +1086,7 @@ class GD_CORE_API ExpressionCompletionFinder
description.SetVariableType(variable.GetType());
description.SetVariableScope(
projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(variableName)
.GetVariablesContainerFromVariableOrPropertyOrParameterName(variableName)
.GetSourceType());
completions.push_back(description);

View File

@@ -460,10 +460,12 @@ const gd::String& ExpressionValidator::TypeToString(Type type) {
case Type::NumberOrString:
return numberOrStringTypeString;
case Type::Variable:
return variableTypeString;
// This function is only used to display errors.
// Users don't care if it's legacy or not or
// if it allows properties and parameters.
case Type::VariableOrProperty:
case Type::VariableOrPropertyOrParameter:
case Type::LegacyVariable:
// This function is only used to display error.
// Users don't care if it's legacy or not.
return variableTypeString;
case Type::Object:
return objectTypeString;
@@ -493,8 +495,11 @@ ExpressionValidator::Type ExpressionValidator::StringToType(
ExpressionValidator::variableTypeString, type)) {
if (gd::ValueTypeMetadata::IsTypeLegacyPreScopedVariable(type)) {
return Type::LegacyVariable;
}
else {
} else if (type == "variableOrProperty") {
return Type::VariableOrProperty;
} else if (type == "variableOrPropertyOrParameter") {
return Type::VariableOrPropertyOrParameter;
} else {
return Type::Variable;
}
}

View File

@@ -203,10 +203,12 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
void OnVisitVariableNode(VariableNode& node) override {
ReportAnyError(node);
if (parentType == Type::Variable) {
if (parentType == Type::Variable ||
parentType == Type::VariableOrProperty ||
parentType == Type::VariableOrPropertyOrParameter) {
childType = parentType;
CheckVariableExistence(node.location, node.name);
CheckVariableExistence(node.location, node.name, node.child != nullptr);
if (node.child) {
node.child->Visit(*this);
}
@@ -216,7 +218,8 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
if (node.child) {
node.child->Visit(*this);
}
} else if (parentType == Type::String || parentType == Type::Number || parentType == Type::NumberOrString) {
} else if (parentType == Type::String || parentType == Type::Number ||
parentType == Type::NumberOrString) {
// The node represents a variable or an object variable in an expression waiting for its *value* to be returned.
childType = parentType;
@@ -336,11 +339,12 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
_("You must enter a number or a text, wrapped inside double quotes (example: \"Hello world\"), or a variable name."),
node.location);
}
}
else if (parentType == Type::Variable) {
CheckVariableExistence(node.location, node.identifierName);
}
else if (parentType != Type::Object && parentType != Type::LegacyVariable) {
} else if (parentType == Type::Variable ||
parentType == Type::VariableOrProperty ||
parentType == Type::VariableOrPropertyOrParameter) {
CheckVariableExistence(node.location, node.identifierName, !node.childIdentifierName.empty());
} else if (parentType != Type::Object &&
parentType != Type::LegacyVariable) {
// It can't happen.
RaiseTypeError(
_("You've entered a name, but this type was expected:") + " " + TypeToString(parentType),
@@ -376,8 +380,19 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
childType = Type::Empty;
}
private:
enum Type {Unknown = 0, Number, String, NumberOrString, Variable, LegacyVariable, Object, Empty};
private:
enum Type {
Unknown = 0,
Number,
String,
NumberOrString,
Variable,
LegacyVariable,
Object,
Empty,
VariableOrProperty,
VariableOrPropertyOrParameter
};
Type ValidateFunction(const gd::FunctionCallNode& function);
bool ValidateObjectVariableOrVariableOrProperty(const gd::IdentifierNode& identifier);
bool ValidateObjectVariableOrVariableOrProperty(
@@ -386,8 +401,10 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
const gd::String &childIdentifierName,
const gd::ExpressionParserLocation childIdentifierNameLocation);
void CheckVariableExistence(const ExpressionParserLocation &location, const gd::String& name) {
if (!currentParameterExtraInfo || *currentParameterExtraInfo != "AllowUndeclaredVariable") {
void CheckVariableExistence(const ExpressionParserLocation &location,
const gd::String &name, bool hasChild) {
if (!currentParameterExtraInfo ||
*currentParameterExtraInfo != "AllowUndeclaredVariable") {
projectScopedContainers.MatchIdentifierWithName<void>(
name,
[&]() {
@@ -402,19 +419,28 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
},
[&]() {
// This is a property.
// This error won't happen unless the priority is changed.
RaiseVariableNameCollisionError(
_("This variable has the same name as a property. Consider "
"renaming one or the other."),
location, name);
if (parentType != Type::VariableOrProperty &&
parentType != Type::VariableOrPropertyOrParameter) {
RaiseVariableNameCollisionError(
_("This variable has the same name as a property. Consider "
"renaming one or the other."),
location, name);
} else if (hasChild) {
RaiseMalformedVariableParameter(
_("Properties can't have children."), location, name);
}
},
[&]() {
// This is a parameter.
// This error won't happen unless the priority is changed.
RaiseVariableNameCollisionError(
_("This variable has the same name as a parameter. Consider "
"renaming one or the other."),
location, name);
if (parentType != Type::VariableOrPropertyOrParameter) {
RaiseVariableNameCollisionError(
_("This variable has the same name as a parameter. Consider "
"renaming one or the other."),
location, name);
} else if (hasChild) {
RaiseMalformedVariableParameter(
_("Properties can't have children."), location, name);
}
},
[&]() {
// This is something else.
@@ -476,6 +502,13 @@ class GD_CORE_API ExpressionValidator : public ExpressionParser2NodeWorker {
message, location, false, variableName, objectName);
}
void RaiseMalformedVariableParameter(const gd::String &message,
const ExpressionParserLocation &location,
const gd::String &variableName) {
RaiseError(gd::ExpressionParserError::ErrorType::MalformedVariableParameter,
message, location, true, variableName, "");
}
void RaiseTypeError(const gd::String &message,
const ExpressionParserLocation &location,
bool isFatal = true) {

View File

@@ -215,7 +215,7 @@ class GD_CORE_API ExpressionVariablePathFinder
if (projectScopedContainers.GetVariablesContainersList().Has(identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName(identifier));
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
if (childIdentifier) {
childVariableNames.push_back(*childIdentifier);
@@ -223,12 +223,28 @@ class GD_CORE_API ExpressionVariablePathFinder
}
},
[&]() {
// Ignore properties here.
// There is no support for "children" of properties.
// This is a property.
if (parameterType != "objectvar" &&
projectScopedContainers.GetVariablesContainersList().Has(
identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
// There is no support for "children" of properties.
}
},
[&]() {
// Ignore parameters here.
// There is no support for "children" of parameters.
// This is a parameter.
if (parameterType != "objectvar" &&
projectScopedContainers.GetVariablesContainersList().Has(
identifier)) {
variablesContainer =
&(projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableOrPropertyOrParameterName(identifier));
variableName = identifier;
// There is no support for "children" of parameters.
}
},
[&]() {
// Ignore unrecognised identifiers here.

View File

@@ -9,7 +9,10 @@
#include "GDCore/Extensions/Metadata/ParameterMetadataTools.h"
#include "GDCore/Project/EventsBasedBehavior.h"
#include "GDCore/Project/EventsBasedObject.h"
//#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/Project/ParameterMetadataContainer.h"
#include "GDCore/Project/PropertiesContainer.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/Project/EventsFunction.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
@@ -100,4 +103,72 @@ void EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
}
}
void EventsFunctionTools::ParametersToVariablesContainer(
const ParameterMetadataContainer &parameters,
gd::VariablesContainer &outputVariablesContainer) {
if (outputVariablesContainer.GetSourceType() !=
gd::VariablesContainer::SourceType::Parameters) {
throw std::logic_error("Tried to generate a variables container from "
"parameters with the wrong source type.");
}
outputVariablesContainer.Clear();
gd::String lastObjectName;
for (std::size_t i = 0; i < parameters.GetParametersCount(); ++i) {
const auto &parameter = parameters.GetParameter(i);
if (parameter.GetName().empty())
continue;
auto &valueTypeMetadata = parameter.GetValueTypeMetadata();
if (valueTypeMetadata.IsNumber()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetValue(0);
} else if (valueTypeMetadata.IsString()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetString("");
} else if (valueTypeMetadata.IsBoolean()) {
auto &variable = outputVariablesContainer.InsertNew(
parameter.GetName(), outputVariablesContainer.Count());
variable.SetBool(false);
}
}
}
void EventsFunctionTools::PropertiesToVariablesContainer(
const PropertiesContainer &properties,
gd::VariablesContainer &outputVariablesContainer) {
if (outputVariablesContainer.GetSourceType() !=
gd::VariablesContainer::SourceType::Properties) {
throw std::logic_error("Tried to generate a variables container from "
"properties with the wrong source type.");
}
outputVariablesContainer.Clear();
gd::String lastObjectName;
for (std::size_t i = 0; i < properties.GetCount(); ++i) {
const auto &property = properties.Get(i);
if (property.GetName().empty())
continue;
auto &propertyType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
if (propertyType == "number") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetValue(0);
} else if (propertyType == "string") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetString("");
} else if (propertyType == "boolean") {
auto &variable = outputVariablesContainer.InsertNew(
property.GetName(), outputVariablesContainer.Count());
variable.SetBool(false);
}
}
}
} // namespace gd

View File

@@ -12,6 +12,9 @@ namespace gd {
class Project;
class EventsFunctionsContainer;
class ObjectsContainer;
class ParameterMetadataContainer;
class PropertiesContainer;
class VariablesContainer;
class ParameterMetadata;
class EventsFunction;
class EventsBasedBehavior;
@@ -68,5 +71,13 @@ class GD_CORE_API EventsFunctionTools {
const gd::EventsBasedObject& eventsBasedObject,
const gd::EventsFunction& eventsFunction,
gd::ObjectsContainer& outputObjectsContainer);
static void ParametersToVariablesContainer(
const ParameterMetadataContainer &parameters,
gd::VariablesContainer &outputVariablesContainer);
static void PropertiesToVariablesContainer(
const PropertiesContainer &properties,
gd::VariablesContainer &outputVariablesContainer);
};
} // namespace gd

View File

@@ -39,6 +39,22 @@ void ProjectBrowserHelper::ExposeProjectEvents(
}
}
void ProjectBrowserHelper::ExposeProjectEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) {
// See also gd::ResourceExposer::ExposeWholeProjectResources
// for a method that traverses the whole project (this time for resources)
// and ExposeProjectEffects (this time for effects).
ExposeProjectEventsWithoutExtensions(project, worker);
// Add events based extensions
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, worker);
}
}
void ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(
gd::Project& project, gd::ArbitraryEventsWorker& worker) {
// Add layouts events
@@ -51,6 +67,28 @@ void ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(
}
}
void ProjectBrowserHelper::ExposeProjectEventsWithoutExtensions(
gd::Project& project, gd::ArbitraryEventsWorkerWithContext& worker) {
// Add layouts events
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
auto &layout = project.GetLayout(s);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(layout.GetEvents(), projectScopedContainers);
}
// Add external events events
for (std::size_t s = 0; s < project.GetExternalEventsCount(); s++) {
const auto &externalEvents = project.GetExternalEvents(s);
const gd::String &associatedLayout = externalEvents.GetAssociatedLayout();
if (project.HasLayoutNamed(associatedLayout)) {
auto &layout = project.GetLayout(associatedLayout);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(project.GetExternalEvents(s).GetEvents(), projectScopedContainers);
}
}
}
void ProjectBrowserHelper::ExposeLayoutEventsAndExternalEvents(
gd::Project &project, gd::Layout &layout,
gd::ArbitraryEventsWorker &worker) {
@@ -111,43 +149,12 @@ void ProjectBrowserHelper::ExposeLayoutEventsAndDependencies(
}
}
void ProjectBrowserHelper::ExposeProjectEvents(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker) {
// See also gd::ResourceExposer::ExposeWholeProjectResources
// for a method that traverses the whole project (this time for resources)
// and ExposeProjectEffects (this time for effects).
// Add layouts events
for (std::size_t s = 0; s < project.GetLayoutsCount(); s++) {
auto &layout = project.GetLayout(s);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(layout.GetEvents(), projectScopedContainers);
}
// Add external events events
for (std::size_t s = 0; s < project.GetExternalEventsCount(); s++) {
const auto &externalEvents = project.GetExternalEvents(s);
const gd::String &associatedLayout = externalEvents.GetAssociatedLayout();
if (project.HasLayoutNamed(associatedLayout)) {
auto &layout = project.GetLayout(associatedLayout);
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, layout);
worker.Launch(project.GetExternalEvents(s).GetEvents(), projectScopedContainers);
}
}
// Add events based extensions
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(project, eventsFunctionsExtension, worker);
}
}
void ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::ArbitraryEventsWorker &worker) {
// Add (free) events functions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
worker.Launch(eventsFunction->GetEvents());
}
@@ -169,13 +176,18 @@ void ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
gd::ArbitraryEventsWorkerWithContext &worker) {
// Add (free) events functions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsFunctionsExtension, *eventsFunction,
parameterObjectsContainer);
parameterObjectsContainer, parameterVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -207,15 +219,32 @@ void ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::ArbitraryEventsWorkerWithContext &worker) {
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
project, eventsFunctionsExtension,
eventsBasedBehavior,
propertyVariablesContainer,
worker);
}
void ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker) {
auto &behaviorEventsFunctions = eventsBasedBehavior.GetEventsFunctions();
for (auto &&eventsFunction : behaviorEventsFunctions.GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainers(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForBehaviorEventsFunction(
project, eventsFunctionsExtension, eventsBasedBehavior,
*eventsFunction, parameterObjectsContainers);
*eventsFunction, parameterObjectsContainers,
parameterVariablesContainer, propertyVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -235,15 +264,31 @@ void ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::ArbitraryEventsWorkerWithContext &worker) {
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject,
propertyVariablesContainer, worker);
}
void ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker) {
auto &objectEventsFunctions = eventsBasedObject.GetEventsFunctions();
for (auto &&eventsFunction : objectEventsFunctions.GetInternalVector()) {
gd::ObjectsContainer parameterObjectsContainers(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForObjectEventsFunction(
project, eventsFunctionsExtension, eventsBasedObject,
*eventsFunction, parameterObjectsContainers);
*eventsFunction, parameterObjectsContainers,
parameterVariablesContainer, propertyVariablesContainer);
worker.Launch(eventsFunction->GetEvents(), projectScopedContainers);
}
@@ -287,7 +332,7 @@ void ProjectBrowserHelper::ExposeProjectFunctions(
for (std::size_t e = 0; e < project.GetEventsFunctionsExtensionsCount();
e++) {
auto &eventsFunctionsExtension = project.GetEventsFunctionsExtension(e);
worker.Launch(eventsFunctionsExtension);
worker.Launch(eventsFunctionsExtension.GetEventsFunctions());
for (auto &&eventsBasedBehavior :
eventsFunctionsExtension.GetEventsBasedBehaviors()

View File

@@ -19,6 +19,7 @@ class ArbitraryEventsFunctionsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventBasedBehaviorsWorker;
class ArbitraryBehaviorSharedDataWorker;
class VariablesContainer;
} // namespace gd
namespace gd {
@@ -56,6 +57,15 @@ public:
ExposeProjectEventsWithoutExtensions(gd::Project &project,
gd::ArbitraryEventsWorker &worker);
/**
* \brief Call the specified worker on all events of the project (layout and
* external events) but not events from extensions.
*
* Only use this for stats.
*/
static void ExposeProjectEventsWithoutExtensions(
gd::Project &project, gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of a layout and
* its external events.
@@ -127,6 +137,20 @@ public:
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* behavior.
*
* This should be the preferred way to traverse all the events of an
* event-based behavior.
*/
static void ExposeEventsBasedBehaviorEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* object.
@@ -152,6 +176,20 @@ public:
const gd::EventsBasedObject &eventsBasedObject,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all events of the event-based
* object.
*
* This should be the preferred way to traverse all the events of an
* event-based object.
*/
static void ExposeEventsBasedObjectEvents(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
gd::VariablesContainer &propertyVariablesContainer,
gd::ArbitraryEventsWorkerWithContext &worker);
/**
* \brief Call the specified worker on all ObjectContainers of the project
* (global, layouts...)

View File

@@ -63,7 +63,7 @@ void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project &project) {
eventsBasedObject.GetPropertyDescriptors().GetInternalVector().clear();
}
extension.GetEventsBasedBehaviors().Clear();
extension.ClearEventsFunctions();
extension.GetEventsFunctions().ClearEventsFunctions();
}
}

View File

@@ -42,6 +42,9 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
const gd::NamedPropertyDescriptor &property, const gd::String &objectType,
bool isBehavior, bool isSharedProperties) {
auto &propertyName = property.GetName();
const auto &primitiveType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
auto &functionsContainer = eventsBasedEntity.GetEventsFunctions();
gd::String capitalizedName = CapitalizeFirstLetter(property.GetName());
gd::String setterName = "Set" + capitalizedName;
@@ -59,9 +62,9 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
property.GetLabel().empty() ? property.GetName() : property.GetLabel();
gd::String descriptionSubject =
(property.GetType() == "Boolean" ? "if " : "the ") +
(primitiveType == "boolean" ? "if " : "the ") +
UnCapitalizeFirstLetter(propertyLabel) +
(isSharedProperties || property.GetType() == "Boolean"
(isSharedProperties || primitiveType == "boolean"
? "."
: " of the object.") +
(property.GetDescription().empty() ? ""
@@ -71,19 +74,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
"objects using the behavior."
: "");
gd::String propertyGetterName =
(isSharedProperties ? "SharedProperty" : "Property") + property.GetName();
gd::String getterType =
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
extension.GetName(), eventsBasedEntity.GetName(), propertyGetterName);
gd::String setterType =
gd::PlatformExtension::GetBehaviorEventsFunctionFullType(
extension.GetName(), eventsBasedEntity.GetName(),
"Set" + propertyGetterName);
gd::String getterName = capitalizedName;
gd::String numberOrString =
property.GetType() == "Number" ? "Number" : "String";
if (!functionsContainer.HasEventsFunctionNamed(getterName)) {
auto &getter = functionsContainer.InsertNewEventsFunction(
@@ -99,7 +90,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
.SetName(legacyExpressionType)
.SetExtraInfo(GetStringifiedExtraInfo(property));
getter.SetFullName(propertyLabel).SetGroup(functionGroupName);
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
getter.SetFunctionType(gd::EventsFunction::Condition)
.SetDescription("Check " + descriptionSubject)
.SetSentence("_PARAM0_ " + UnCapitalizeFirstLetter(propertyLabel));
@@ -112,13 +103,12 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
auto &event =
dynamic_cast<gd::StandardEvent &>(getter.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard", 0));
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
gd::Instruction condition;
condition.SetType(getterType);
condition.AddParameter("Object");
if (isBehavior) {
condition.AddParameter("Behavior");
}
condition.SetType("BooleanVariable");
condition.AddParameter(propertyName);
condition.AddParameter("True");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
@@ -127,6 +117,8 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
event.GetActions().Insert(action, 0);
} else {
gd::Instruction action;
gd::String numberOrString =
primitiveType == "number" ? "Number" : "String";
action.SetType("SetReturn" + numberOrString);
action.AddParameter(property.GetName());
event.GetActions().Insert(action, 0);
@@ -136,7 +128,7 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
if (!functionsContainer.HasEventsFunctionNamed(setterName)) {
auto &setter = functionsContainer.InsertNewEventsFunction(
setterName, functionsContainer.GetEventsFunctionsCount());
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
setter.SetFunctionType(gd::EventsFunction::Action)
.SetFullName(propertyLabel)
.SetGroup(functionGroupName)
@@ -177,26 +169,24 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
setter.SetGetterName(getterName);
}
if (property.GetType() == "Boolean") {
if (primitiveType == "boolean") {
{
auto &event =
dynamic_cast<gd::StandardEvent &>(setter.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction condition;
condition.SetType("GetArgumentAsBoolean");
condition.AddParameter("\"Value\"");
condition.SetType("BooleanVariable");
condition.AddParameter("Value");
condition.AddParameter("True");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("yes");
} else {
action.AddParameter("yes");
}
action.SetType("SetBooleanVariable");
action.AddParameter(propertyName);
action.AddParameter("True");
action.AddParameter("");
event.GetActions().Insert(action, 0);
}
{
@@ -205,20 +195,17 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction condition;
condition.SetType("GetArgumentAsBoolean");
condition.AddParameter("\"Value\"");
condition.SetInverted(true);
condition.SetType("BooleanVariable");
condition.AddParameter("Value");
condition.AddParameter("False");
condition.AddParameter("");
event.GetConditions().Insert(condition, 0);
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("no");
} else {
action.AddParameter("no");
}
action.SetType("SetBooleanVariable");
action.AddParameter(propertyName);
action.AddParameter("False");
action.AddParameter("");
event.GetActions().Insert(action, 0);
}
} else {
@@ -227,16 +214,11 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
project, "BuiltinCommonInstructions::Standard", 0));
gd::Instruction action;
action.SetType(setterType);
action.AddParameter("Object");
if (isBehavior) {
action.AddParameter("Behavior");
action.AddParameter("=");
action.AddParameter("Value");
} else {
action.AddParameter("=");
action.AddParameter("Value");
}
action.SetType(primitiveType == "number" ? "SetNumberVariable"
: "SetStringVariable");
action.AddParameter(propertyName);
action.AddParameter("=");
action.AddParameter("Value");
event.GetActions().Insert(action, 0);
}
}
@@ -245,9 +227,11 @@ void PropertyFunctionGenerator::GenerateGetterAndSetter(
bool PropertyFunctionGenerator::CanGenerateGetterAndSetter(
const gd::AbstractEventsBasedEntity &eventsBasedEntity,
const gd::NamedPropertyDescriptor &property) {
auto &type = property.GetType();
if (type != "Boolean" && type != "Number" && type != "String" &&
type != "Choice" && type != "Color" && type != "LeaderboardId") {
const auto &primitiveType = gd::ValueTypeMetadata::GetPrimitiveValueType(
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property.GetType()));
if (primitiveType != "boolean" && primitiveType != "number" &&
primitiveType != "string") {
return false;
}

View File

@@ -3,8 +3,7 @@
* Copyright 2008-2022 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef GDCORE_PROPERTYFUNCTIONGENERATOR_H
#define GDCORE_PROPERTYFUNCTIONGENERATOR_H
#pragma once
namespace gd {
class String;
@@ -73,5 +72,3 @@ class GD_CORE_API PropertyFunctionGenerator {
};
} // namespace gd
#endif // GDCORE_PROPERTYFUNCTIONGENERATOR_H

View File

@@ -600,7 +600,8 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
// instructions after they are renamed.
// Free expressions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
if (eventsFunction->IsExpression()) {
renameEventsFunction(*eventsFunction);
}
@@ -617,7 +618,8 @@ void WholeProjectRefactorer::RenameEventsFunctionsExtension(
}
// Free instructions
for (auto &&eventsFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&eventsFunction :
eventsFunctionsExtension.GetEventsFunctions().GetInternalVector()) {
if (eventsFunction->IsAction() || eventsFunction->IsCondition()) {
renameEventsFunction(*eventsFunction);
}
@@ -697,11 +699,12 @@ void WholeProjectRefactorer::RenameEventsFunction(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::String &oldFunctionName, const gd::String &newFunctionName) {
if (!eventsFunctionsExtension.HasEventsFunctionNamed(oldFunctionName))
const auto &eventsFunctions = eventsFunctionsExtension.GetEventsFunctions();
if (!eventsFunctions.HasEventsFunctionNamed(oldFunctionName))
return;
const gd::EventsFunction &eventsFunction =
eventsFunctionsExtension.GetEventsFunction(oldFunctionName);
eventsFunctions.GetEventsFunction(oldFunctionName);
const WholeProjectBrowser wholeProjectExposer;
DoRenameEventsFunction(
@@ -714,7 +717,7 @@ void WholeProjectRefactorer::RenameEventsFunction(
if (eventsFunction.GetFunctionType() ==
gd::EventsFunction::ExpressionAndCondition) {
for (auto &&otherFunction : eventsFunctionsExtension.GetInternalVector()) {
for (auto &&otherFunction : eventsFunctions.GetInternalVector()) {
if (otherFunction->GetFunctionType() ==
gd::EventsFunction::ActionWithOperator &&
otherFunction->GetGetterName() == oldFunctionName) {
@@ -862,16 +865,34 @@ void WholeProjectRefactorer::RenameParameter(
}
}
void WholeProjectRefactorer::ChangeParameterType(
gd::Project &project, gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction &eventsFunction,
const gd::ObjectsContainer &parameterObjectsContainer,
const gd::String &parameterName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(parameterName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
eventsVariableInstructionTypeSwitcher.Launch(eventsFunction.GetEvents(),
projectScopedContainers);
}
void WholeProjectRefactorer::MoveEventsFunctionParameter(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::String &functionName, std::size_t oldIndex,
std::size_t newIndex) {
if (!eventsFunctionsExtension.HasEventsFunctionNamed(functionName))
const auto &eventsFunctions = eventsFunctionsExtension.GetEventsFunctions();
if (!eventsFunctions.HasEventsFunctionNamed(functionName))
return;
const gd::EventsFunction &eventsFunction =
eventsFunctionsExtension.GetEventsFunction(functionName);
eventsFunctions.GetEventsFunction(functionName);
const gd::String &eventsFunctionType =
gd::PlatformExtension::GetEventsFunctionFullType(
@@ -1175,6 +1196,42 @@ void WholeProjectRefactorer::RenameEventsBasedObjectProperty(
gd::ProjectBrowserHelper::ExposeProjectEvents(project, conditionRenamer);
}
void WholeProjectRefactorer::ChangeEventsBasedBehaviorPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &propertyName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(propertyName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
gd::ProjectBrowserHelper::ExposeEventsBasedBehaviorEvents(
project, eventsFunctionsExtension, eventsBasedBehavior,
propertyVariablesContainer, eventsVariableInstructionTypeSwitcher);
}
void WholeProjectRefactorer::ChangeEventsBasedObjectPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &propertyName) {
std::unordered_set<gd::String> typeChangedPropertyNames;
typeChangedPropertyNames.insert(propertyName);
gd::VariablesContainer propertyVariablesContainer(
gd::VariablesContainer::SourceType::Properties);
gd::EventsVariableInstructionTypeSwitcher
eventsVariableInstructionTypeSwitcher(project.GetCurrentPlatform(),
typeChangedPropertyNames,
propertyVariablesContainer);
gd::ProjectBrowserHelper::ExposeEventsBasedObjectEvents(
project, eventsFunctionsExtension, eventsBasedObject,
propertyVariablesContainer, eventsVariableInstructionTypeSwitcher);
}
void WholeProjectRefactorer::AddBehaviorAndRequiredBehaviors(
gd::Project &project, gd::Object &object, const gd::String &behaviorType,
const gd::String &behaviorName) {

View File

@@ -191,6 +191,16 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String &oldParameterName,
const gd::String &newParameterName);
/**
* \brief Refactor the function **after** a parameter has changed of type.
*/
static void
ChangeParameterType(gd::Project &project,
gd::ProjectScopedContainers &projectScopedContainers,
gd::EventsFunction &eventsFunction,
const gd::ObjectsContainer &parameterObjectsContainer,
const gd::String &parameterName);
/**
* \brief Refactor the project **before** an events function parameter
* is moved.
@@ -283,6 +293,26 @@ class GD_CORE_API WholeProjectRefactorer {
const gd::String& oldPropertyName,
const gd::String& newPropertyName);
/**
* \brief Refactor the project **after** a property of a behavior has
* changed of type.
*/
static void ChangeEventsBasedBehaviorPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::String &propertyName);
/**
* \brief Refactor the project **after** a property of an object has
* changed of type.
*/
static void ChangeEventsBasedObjectPropertyType(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::String &propertyName);
/**
* \brief Add a behavior to an object and add required behaviors if necessary
* to fill every behavior properties of the added behaviors.

View File

@@ -22,15 +22,17 @@ void CustomConfigurationHelper::InitializeContent(
gd::SerializerElement &configurationContent) {
for (auto &&property : properties.GetInternalVector()) {
auto &element = configurationContent.AddChild(property->GetName());
auto propertyType = property->GetType();
if (propertyType == "String" || propertyType == "Choice" ||
propertyType == "Color" || propertyType == "Behavior" ||
propertyType == "Resource" || propertyType == "LeaderboardId") {
const auto &valueType =
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property->GetType());
const auto &primitiveType =
gd::ValueTypeMetadata::GetPrimitiveValueType(valueType);
if (primitiveType == "string" || valueType == "behavior") {
element.SetStringValue(property->GetValue());
} else if (propertyType == "Number") {
} else if (primitiveType == "number") {
element.SetDoubleValue(property->GetValue().To<double>());
} else if (propertyType == "Boolean") {
} else if (primitiveType == "boolean") {
element.SetBoolValue(property->GetValue() == "true");
}
}
@@ -43,23 +45,25 @@ std::map<gd::String, gd::PropertyDescriptor> CustomConfigurationHelper::GetPrope
for (auto &property : properties.GetInternalVector()) {
const auto &propertyName = property->GetName();
const auto &propertyType = property->GetType();
// Copy the property
objectProperties[propertyName] = *property;
auto &newProperty = objectProperties[propertyName];
const auto &valueType =
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(
property->GetType());
const auto &primitiveType =
gd::ValueTypeMetadata::GetPrimitiveValueType(valueType);
if (configurationContent.HasChild(propertyName)) {
if (propertyType == "String" || propertyType == "Choice" ||
propertyType == "Color" || propertyType == "Behavior" ||
propertyType == "Resource" || propertyType == "LeaderboardId") {
if (primitiveType == "string" || valueType == "behavior") {
newProperty.SetValue(
configurationContent.GetChild(propertyName).GetStringValue());
} else if (propertyType == "Number") {
} else if (primitiveType == "number") {
newProperty.SetValue(gd::String::From(
configurationContent.GetChild(propertyName).GetDoubleValue()));
} else if (propertyType == "Boolean") {
} else if (primitiveType == "boolean") {
newProperty.SetValue(
configurationContent.GetChild(propertyName).GetBoolValue()
? "true"
@@ -85,15 +89,16 @@ bool CustomConfigurationHelper::UpdateProperty(
const auto &property = properties.Get(propertyName);
auto &element = configurationContent.AddChild(propertyName);
const gd::String &propertyType = property.GetType();
if (propertyType == "String" || propertyType == "Choice" ||
propertyType == "Color" || propertyType == "Behavior" ||
propertyType == "Resource" || propertyType == "LeaderboardId") {
const auto &valueType =
gd::ValueTypeMetadata::ConvertPropertyTypeToValueType(property.GetType());
const auto &primitiveType =
gd::ValueTypeMetadata::GetPrimitiveValueType(valueType);
if (primitiveType == "string" || valueType == "behavior") {
element.SetStringValue(newValue);
} else if (propertyType == "Number") {
} else if (primitiveType == "number") {
element.SetDoubleValue(newValue.To<double>());
} else if (propertyType == "Boolean") {
} else if (primitiveType == "boolean") {
element.SetBoolValue(newValue == "1");
}

View File

@@ -33,6 +33,20 @@ public:
EventsFunctionsContainer(FunctionOwner source_) : owner(source_) {}
EventsFunctionsContainer(const EventsFunctionsContainer &other)
: owner(other.owner) {
Init(other);
}
EventsFunctionsContainer &operator=(const EventsFunctionsContainer &other) {
if (this != &other) {
owner = other.owner;
Init(other);
}
return *this;
}
/**
* \brief Get the source of the function container.
*

View File

@@ -15,14 +15,13 @@
namespace gd {
EventsFunctionsExtension::EventsFunctionsExtension() :
gd::EventsFunctionsContainer(
gd::EventsFunctionsContainer::FunctionOwner::Extension),
eventsFunctionsContainer(gd::EventsFunctionsContainer::FunctionOwner::Extension),
globalVariables(gd::VariablesContainer::SourceType::ExtensionGlobal),
sceneVariables(gd::VariablesContainer::SourceType::ExtensionScene) {}
EventsFunctionsExtension::EventsFunctionsExtension(
const EventsFunctionsExtension& other) :
gd::EventsFunctionsContainer(
eventsFunctionsContainer(
gd::EventsFunctionsContainer::FunctionOwner::Extension) {
Init(other);
}
@@ -48,7 +47,8 @@ void EventsFunctionsExtension::Init(const gd::EventsFunctionsExtension& other) {
previewIconUrl = other.previewIconUrl;
iconUrl = other.iconUrl;
helpPath = other.helpPath;
EventsFunctionsContainer::Init(other);
gdevelopVersion = other.gdevelopVersion;
eventsFunctionsContainer = other.eventsFunctionsContainer;
eventsBasedBehaviors = other.eventsBasedBehaviors;
eventsBasedObjects = other.eventsBasedObjects;
globalVariables = other.GetGlobalVariables();
@@ -82,6 +82,7 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
element.SetAttribute("previewIconUrl", previewIconUrl);
element.SetAttribute("iconUrl", iconUrl);
element.SetAttribute("helpPath", helpPath);
element.SetAttribute("gdevelopVersion", gdevelopVersion);
auto& dependenciesElement = element.AddChild("dependencies");
dependenciesElement.ConsiderAsArray();
for (auto& dependency : dependencies)
@@ -97,7 +98,8 @@ void EventsFunctionsExtension::SerializeTo(SerializerElement& element) const {
GetGlobalVariables().SerializeTo(element.AddChild("globalVariables"));
GetSceneVariables().SerializeTo(element.AddChild("sceneVariables"));
SerializeEventsFunctionsTo(element.AddChild("eventsFunctions"));
eventsFunctionsContainer.SerializeEventsFunctionsTo(
element.AddChild("eventsFunctions"));
eventsBasedBehaviors.SerializeElementsTo(
"eventsBasedBehavior", element.AddChild("eventsBasedBehaviors"));
eventsBasedObjects.SerializeElementsTo(
@@ -126,6 +128,7 @@ void EventsFunctionsExtension::UnserializeExtensionDeclarationFrom(
previewIconUrl = element.GetStringAttribute("previewIconUrl");
iconUrl = element.GetStringAttribute("iconUrl");
helpPath = element.GetStringAttribute("helpPath");
gdevelopVersion = element.GetStringAttribute("gdevelopVersion");
if (element.HasChild("origin")) {
gd::String originName =
@@ -205,7 +208,8 @@ void EventsFunctionsExtension::UnserializeExtensionDeclarationFrom(
void EventsFunctionsExtension::UnserializeExtensionImplementationFrom(
gd::Project& project,
const SerializerElement& element) {
UnserializeEventsFunctionsFrom(project, element.GetChild("eventsFunctions"));
eventsFunctionsContainer.UnserializeEventsFunctionsFrom(
project, element.GetChild("eventsFunctions"));
eventsBasedBehaviors.UnserializeElementsFrom(
"eventsBasedBehavior", project, element.GetChild("eventsBasedBehaviors"));

View File

@@ -36,7 +36,7 @@ namespace gd {
*
* \ingroup PlatformDefinition
*/
class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
class GD_CORE_API EventsFunctionsExtension {
public:
EventsFunctionsExtension();
EventsFunctionsExtension(const EventsFunctionsExtension&);
@@ -134,6 +134,19 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
return *this;
}
/**
* \brief Get the GDevelop version required by this extension.
*/
const gd::String& GetGDevelopVersion() const { return gdevelopVersion; };
/**
* \brief Set the GDevelop version required by this extension.
*/
EventsFunctionsExtension& SetGDevelopVersion(const gd::String& gdevelopVersion_) {
gdevelopVersion = gdevelopVersion_;
return *this;
}
/**
* \brief Return a reference to the list of the events based behaviors.
*/
@@ -181,6 +194,21 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
return originIdentifier;
}
/**
* \brief Return a reference to the functions of the events based behavior or object.
*/
EventsFunctionsContainer& GetEventsFunctions() {
return eventsFunctionsContainer;
}
/**
* \brief Return a const reference to the functions of the events based
* behavior or object.
*/
const EventsFunctionsContainer& GetEventsFunctions() const {
return eventsFunctionsContainer;
}
/** \name Dependencies
*/
///@{
@@ -370,11 +398,13 @@ class GD_CORE_API EventsFunctionsExtension : public EventsFunctionsContainer {
gd::String iconUrl;
gd::String helpPath; ///< The relative path to the help for this extension in
///< the documentation (or an absolute URL).
gd::String gdevelopVersion;
gd::SerializableWithNameList<EventsBasedBehavior> eventsBasedBehaviors;
gd::SerializableWithNameList<EventsBasedObject> eventsBasedObjects;
std::vector<gd::DependencyMetadata> dependencies;
std::vector<gd::SourceFileMetadata> sourceFiles;
gd::EventsFunctionsContainer eventsFunctionsContainer;
gd::VariablesContainer globalVariables;
gd::VariablesContainer sceneVariables;
};

View File

@@ -137,6 +137,15 @@ void ObjectFolderOrObject::RemoveRecursivelyObjectNamed(
}
};
void ObjectFolderOrObject::Clear() {
if (IsFolder()) {
for (auto& it : children) {
it->Clear();
}
children.clear();
}
};
bool ObjectFolderOrObject::IsADescendantOf(
const ObjectFolderOrObject& otherObjectFolderOrObject) {
if (parent == nullptr) return false;

View File

@@ -134,6 +134,10 @@ class GD_CORE_API ObjectFolderOrObject {
* the instance children and recursively does it for every folder children.
*/
void RemoveRecursivelyObjectNamed(const gd::String& name);
/**
* \brief Clears all children
*/
void Clear();
/**
* \brief Inserts an instance representing the given object at the given

View File

@@ -0,0 +1,57 @@
/*
* GDevelop Core
* Copyright 2008-2025 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ObjectTools.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
namespace gd {
bool ObjectTools::IsBehaviorCompatibleWithObject(
const gd::Platform &platform, const gd::String &objectType,
const gd::String &behaviorType,
std::unordered_set<gd::String> coveredBehaviorType) {
bool isBehaviorTypeAlreadyCovered =
!coveredBehaviorType.insert(behaviorType).second;
if (isBehaviorTypeAlreadyCovered) {
return true;
}
const gd::BehaviorMetadata &behaviorMetadata =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
if (MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
// Should not happen because the behavior was added successfully (so its
// metadata are valid) - but double check anyway and bail out if the
// behavior metadata are invalid.
return false;
}
if (!behaviorMetadata.GetObjectType().empty() &&
behaviorMetadata.GetObjectType() != objectType) {
return false;
}
for (const gd::String &requiredBehaviorType :
behaviorMetadata.GetRequiredBehaviorTypes()) {
const gd::BehaviorMetadata &requiredBehaviorMetadata =
gd::MetadataProvider::GetBehaviorMetadata(platform, requiredBehaviorType);
if (requiredBehaviorMetadata.IsHidden()) {
const gd::ObjectMetadata &objectMetadata =
gd::MetadataProvider::GetObjectMetadata(platform, objectType);
if (objectMetadata.GetDefaultBehaviors().find(requiredBehaviorType) ==
objectMetadata.GetDefaultBehaviors().end()) {
// A capability is missing in the object.
return false;
}
}
if (!gd::ObjectTools::IsBehaviorCompatibleWithObject(
platform, objectType, requiredBehaviorType, coveredBehaviorType)) {
return false;
}
}
return true;
}
} // namespace gd

View File

@@ -0,0 +1,35 @@
/*
* GDevelop Core
* Copyright 2008-2025 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#pragma once
#include "GDCore/String.h"
#include <unordered_set>
namespace gd {
class Platform;
class Object;
} // namespace gd
namespace gd {
class GD_CORE_API ObjectTools {
public:
static bool IsBehaviorCompatibleWithObject(const gd::Platform &platform,
const gd::String &objectType,
const gd::String &behaviorType) {
std::unordered_set<gd::String> coveredBehaviorType;
return IsBehaviorCompatibleWithObject(platform, objectType, behaviorType,
coveredBehaviorType);
}
private:
static bool IsBehaviorCompatibleWithObject(
const gd::Platform &platform, const gd::String &objectType,
const gd::String &behaviorType,
std::unordered_set<gd::String> coveredBehaviorType);
};
} // namespace gd

View File

@@ -7,12 +7,12 @@
#include <algorithm>
#include "GDCore/Tools/PolymorphicClone.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectFolderOrObject.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/PolymorphicClone.h"
namespace gd {
@@ -28,8 +28,7 @@ ObjectsContainer::ObjectsContainer(const ObjectsContainer& other) {
Init(other);
}
ObjectsContainer& ObjectsContainer::operator=(
const ObjectsContainer& other) {
ObjectsContainer& ObjectsContainer::operator=(const ObjectsContainer& other) {
if (this != &other) Init(other);
return *this;
@@ -69,7 +68,7 @@ void ObjectsContainer::AddMissingObjectsInRootFolder() {
void ObjectsContainer::UnserializeObjectsFrom(
gd::Project& project, const SerializerElement& element) {
initialObjects.clear();
Clear();
element.ConsiderAsArrayOf("object", "Objet");
for (std::size_t i = 0; i < element.GetChildrenCount(); ++i) {
const SerializerElement& objectElement = element.GetChild(i);
@@ -184,6 +183,11 @@ void ObjectsContainer::RemoveObject(const gd::String& name) {
initialObjects.erase(objectIt);
}
void ObjectsContainer::Clear() {
rootFolder->Clear();
initialObjects.clear();
}
void ObjectsContainer::MoveObjectFolderOrObjectToAnotherContainerInFolder(
gd::ObjectFolderOrObject& objectFolderOrObject,
gd::ObjectsContainer& newContainer,

View File

@@ -166,6 +166,11 @@ class GD_CORE_API ObjectsContainer {
gd::ObjectFolderOrObject& newParentFolder,
std::size_t newPosition);
/**
* \brief Clear all groups of the container.
*/
void Clear();
/**
* Provide a raw access to the vector containing the objects
*/

View File

@@ -70,24 +70,29 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForEventsFunctionsExtensi
ProjectScopedContainers
ProjectScopedContainers::MakeNewProjectScopedContainersForFreeEventsFunction(
const gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer) {
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer) {
gd::EventsFunctionTools::FreeEventsFunctionToObjectsContainer(
project, eventsFunctionsExtension, eventsFunction, parameterObjectsContainer);
project, eventsFunctionsExtension.GetEventsFunctions(), eventsFunction,
parameterObjectsContainer);
ProjectScopedContainers projectScopedContainers(
ObjectsContainersList::MakeNewObjectsContainersListForContainer(
parameterObjectsContainer),
VariablesContainersList::
MakeNewVariablesContainersListForEventsFunctionsExtension(eventsFunctionsExtension),
MakeNewVariablesContainersListForFreeEventsFunction(
eventsFunctionsExtension, eventsFunction,
parameterVariablesContainer),
&eventsFunctionsExtension.GetGlobalVariables(),
&eventsFunctionsExtension.GetSceneVariables(),
PropertiesContainersList::MakeNewEmptyPropertiesContainersList());
projectScopedContainers.AddParameters(
eventsFunction.GetParametersForEvents(eventsFunctionsExtension));
projectScopedContainers.AddParameters(eventsFunction.GetParametersForEvents(
eventsFunctionsExtension.GetEventsFunctions()));
return projectScopedContainers;
};
@@ -97,7 +102,9 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForBehaviorEventsFunction
const gd::Project &project, const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior& eventsBasedBehavior,
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer) {
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer) {
gd::EventsFunctionTools::BehaviorEventsFunctionToObjectsContainer(
project,
@@ -109,7 +116,9 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForBehaviorEventsFunction
ObjectsContainersList::MakeNewObjectsContainersListForContainer(
parameterObjectsContainer),
VariablesContainersList::
MakeNewVariablesContainersListForEventsFunctionsExtension(eventsFunctionsExtension),
MakeNewVariablesContainersListForBehaviorEventsFunction(
eventsFunctionsExtension, eventsBasedBehavior, eventsFunction,
parameterVariablesContainer, propertyVariablesContainer),
&eventsFunctionsExtension.GetGlobalVariables(),
&eventsFunctionsExtension.GetSceneVariables(),
PropertiesContainersList::MakeNewEmptyPropertiesContainersList());
@@ -130,7 +139,9 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForObjectEventsFunction(
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer) {
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer) {
gd::EventsFunctionTools::ObjectEventsFunctionToObjectsContainer(
project, eventsBasedObject, eventsFunction, parameterObjectsContainer);
@@ -140,8 +151,9 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForObjectEventsFunction(
eventsBasedObject.GetObjects(),
parameterObjectsContainer),
VariablesContainersList::
MakeNewVariablesContainersListForEventsFunctionsExtension(
eventsFunctionsExtension),
MakeNewVariablesContainersListForObjectEventsFunction(
eventsFunctionsExtension, eventsBasedObject, eventsFunction,
parameterVariablesContainer, propertyVariablesContainer),
&eventsFunctionsExtension.GetGlobalVariables(),
&eventsFunctionsExtension.GetSceneVariables(),
PropertiesContainersList::MakeNewEmptyPropertiesContainersList());
@@ -166,7 +178,7 @@ ProjectScopedContainers::MakeNewProjectScopedContainersForEventsBasedObject(
// created below.
// Search for "ProjectScopedContainers wrongly containing temporary objects containers or objects"
// in the codebase.
outputObjectsContainer.GetObjects().clear();
outputObjectsContainer.Clear();
outputObjectsContainer.GetObjectGroups().Clear();
// This object named "Object" represents the parent and is used by events.

View File

@@ -69,8 +69,9 @@ class ProjectScopedContainers {
MakeNewProjectScopedContainersForFreeEventsFunction(
const gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsFunction& eventsFunction,
gd::ObjectsContainer& parameterObjectsContainer);
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer);
static ProjectScopedContainers
MakeNewProjectScopedContainersForBehaviorEventsFunction(
@@ -78,7 +79,9 @@ class ProjectScopedContainers {
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer);
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer);
static ProjectScopedContainers
MakeNewProjectScopedContainersForObjectEventsFunction(
@@ -86,7 +89,9 @@ class ProjectScopedContainers {
const gd::EventsFunctionsExtension &eventsFunctionsExtension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::EventsFunction &eventsFunction,
gd::ObjectsContainer &parameterObjectsContainer);
gd::ObjectsContainer &parameterObjectsContainer,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer);
static ProjectScopedContainers
MakeNewProjectScopedContainersForEventsBasedObject(
@@ -124,9 +129,17 @@ class ProjectScopedContainers {
std::function<ReturnType()> notFoundCallback) const {
if (objectsContainersList.HasObjectOrGroupNamed(name))
return objectCallback();
else if (variablesContainersList.Has(name))
else if (variablesContainersList.Has(name)) {
const auto &variablesContainer =
variablesContainersList.GetVariablesContainerFromVariableOrPropertyOrParameterName(name);
const auto sourceType = variablesContainer.GetSourceType();
if (sourceType == gd::VariablesContainer::SourceType::Properties) {
return propertyCallback();
} else if (sourceType == gd::VariablesContainer::SourceType::Parameters) {
return parameterCallback();
}
return variableCallback();
else if (ParameterMetadataTools::Has(parametersVectorsList, name))
} else if (ParameterMetadataTools::Has(parametersVectorsList, name))
return parameterCallback();
else if (propertiesContainersList.Has(name))
return propertyCallback();

View File

@@ -34,7 +34,9 @@ class GD_CORE_API VariablesContainer {
Object,
Local,
ExtensionGlobal,
ExtensionScene
ExtensionScene,
Parameters,
Properties,
};
VariablesContainer();

View File

@@ -6,6 +6,7 @@
#include "GDCore/Project/Project.h"
#include "GDCore/Project/Variable.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/IDE/EventsFunctionTools.h"
namespace gd {
@@ -41,6 +42,78 @@ VariablesContainersList::MakeNewVariablesContainersListForEventsFunctionsExtensi
return variablesContainersList;
}
VariablesContainersList
VariablesContainersList::MakeNewVariablesContainersListForFreeEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer) {
VariablesContainersList variablesContainersList;
variablesContainersList.Push(extension.GetGlobalVariables());
variablesContainersList.Push(extension.GetSceneVariables());
gd::EventsFunctionTools::ParametersToVariablesContainer(
eventsFunction.GetParametersForEvents(extension.GetEventsFunctions()),
parameterVariablesContainer);
variablesContainersList.Push(parameterVariablesContainer);
variablesContainersList.firstLocalVariableContainerIndex = 3;
return variablesContainersList;
}
VariablesContainersList VariablesContainersList::
MakeNewVariablesContainersListForBehaviorEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer) {
VariablesContainersList variablesContainersList;
variablesContainersList.Push(extension.GetGlobalVariables());
variablesContainersList.Push(extension.GetSceneVariables());
gd::EventsFunctionTools::PropertiesToVariablesContainer(
eventsBasedBehavior.GetSharedPropertyDescriptors(), propertyVariablesContainer);
variablesContainersList.Push(propertyVariablesContainer);
gd::EventsFunctionTools::PropertiesToVariablesContainer(
eventsBasedBehavior.GetPropertyDescriptors(), propertyVariablesContainer);
variablesContainersList.Push(propertyVariablesContainer);
gd::EventsFunctionTools::ParametersToVariablesContainer(
eventsFunction.GetParametersForEvents(
eventsBasedBehavior.GetEventsFunctions()),
parameterVariablesContainer);
variablesContainersList.Push(parameterVariablesContainer);
variablesContainersList.firstLocalVariableContainerIndex = 5;
return variablesContainersList;
}
VariablesContainersList
VariablesContainersList::MakeNewVariablesContainersListForObjectEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer) {
VariablesContainersList variablesContainersList;
variablesContainersList.Push(extension.GetGlobalVariables());
variablesContainersList.Push(extension.GetSceneVariables());
gd::EventsFunctionTools::PropertiesToVariablesContainer(
eventsBasedObject.GetPropertyDescriptors(), propertyVariablesContainer);
variablesContainersList.Push(propertyVariablesContainer);
gd::EventsFunctionTools::ParametersToVariablesContainer(
eventsFunction.GetParametersForEvents(
eventsBasedObject.GetEventsFunctions()),
parameterVariablesContainer);
variablesContainersList.Push(parameterVariablesContainer);
variablesContainersList.firstLocalVariableContainerIndex = 4;
return variablesContainersList;
}
VariablesContainersList
VariablesContainersList::MakeNewVariablesContainersListPushing(
const VariablesContainersList& variablesContainersList, const gd::VariablesContainer& variablesContainer) {
@@ -74,7 +147,7 @@ const Variable& VariablesContainersList::Get(const gd::String& name) const {
}
const VariablesContainer &
VariablesContainersList::GetVariablesContainerFromVariableName(
VariablesContainersList::GetVariablesContainerFromVariableOrPropertyOrParameterName(
const gd::String &variableName) const {
for (auto it = variablesContainers.rbegin(); it != variablesContainers.rend();
++it) {
@@ -84,6 +157,34 @@ VariablesContainersList::GetVariablesContainerFromVariableName(
return badVariablesContainer;
}
const VariablesContainer &VariablesContainersList::
GetVariablesContainerFromVariableOrPropertyName(
const gd::String &variableName) const {
for (auto it = variablesContainers.rbegin(); it != variablesContainers.rend();
++it) {
if ((*it)->GetSourceType() !=
gd::VariablesContainer::SourceType::Parameters &&
(*it)->Has(variableName))
return **it;
}
return badVariablesContainer;
}
const VariablesContainer &VariablesContainersList::
GetVariablesContainerFromVariableNameOnly(
const gd::String &variableName) const {
for (auto it = variablesContainers.rbegin(); it != variablesContainers.rend();
++it) {
if ((*it)->GetSourceType() !=
gd::VariablesContainer::SourceType::Parameters &&
(*it)->GetSourceType() !=
gd::VariablesContainer::SourceType::Properties &&
(*it)->Has(variableName))
return **it;
}
return badVariablesContainer;
}
std::size_t
VariablesContainersList::GetVariablesContainerPositionFromVariableName(
const gd::String &variableName) const {

View File

@@ -1,6 +1,6 @@
#pragma once
#include <vector>
#include <functional>
#include <vector>
namespace gd {
class String;
@@ -9,7 +9,10 @@ class Layout;
class VariablesContainer;
class Variable;
class EventsFunctionsExtension;
} // namespace gd
class EventsBasedBehavior;
class EventsBasedObject;
class EventsFunction;
} // namespace gd
namespace gd {
@@ -24,20 +27,42 @@ namespace gd {
* \ingroup PlatformDefinition
*/
class GD_CORE_API VariablesContainersList {
public:
public:
virtual ~VariablesContainersList(){};
static VariablesContainersList
MakeNewVariablesContainersListForProjectAndLayout(const gd::Project& project,
const gd::Layout& layout);
MakeNewVariablesContainersListForProjectAndLayout(const gd::Project &project,
const gd::Layout &layout);
static VariablesContainersList
MakeNewVariablesContainersListForProject(const gd::Project& project);
MakeNewVariablesContainersListForProject(const gd::Project &project);
static VariablesContainersList
MakeNewVariablesContainersListForEventsFunctionsExtension(
const gd::EventsFunctionsExtension &extension);
static VariablesContainersList
MakeNewVariablesContainersListForFreeEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer);
static VariablesContainersList
MakeNewVariablesContainersListForBehaviorEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsBasedBehavior &eventsBasedBehavior,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer);
static VariablesContainersList
MakeNewVariablesContainersListForObjectEventsFunction(
const gd::EventsFunctionsExtension &extension,
const gd::EventsBasedObject &eventsBasedObject,
const gd::EventsFunction &eventsFunction,
gd::VariablesContainer &parameterVariablesContainer,
gd::VariablesContainer &propertyVariablesContainer);
static VariablesContainersList MakeNewVariablesContainersListPushing(
const VariablesContainersList &variablesContainersList,
const gd::VariablesContainer &variablesContainer);
@@ -50,28 +75,31 @@ class GD_CORE_API VariablesContainersList {
/**
* \brief Return true if the specified variable is in one of the containers.
*/
bool Has(const gd::String& name) const;
bool Has(const gd::String &name) const;
/**
* \brief Return a reference to the variable called \a name.
*/
const Variable& Get(const gd::String& name) const;
const Variable &Get(const gd::String &name) const;
/**
* \brief Return true if the specified variable container is present.
*/
bool HasVariablesContainer(const gd::VariablesContainer& variablesContainer) const;
bool
HasVariablesContainer(const gd::VariablesContainer &variablesContainer) const;
// TODO: Rename GetTopMostVariablesContainer and GetBottomMostVariablesContainer
// to give a clearer access to segments of the container list.
// For instance, a project tree segment and an event tree segment.
// TODO: Rename GetTopMostVariablesContainer and
// GetBottomMostVariablesContainer to give a clearer access to segments of the
// container list. For instance, a project tree segment and an event tree
// segment.
/**
* Get the variables container at the top of the scope (so the most "global" one).
* \brief Avoid using apart when a scope must be forced.
* Get the variables container at the top of the scope (so the most "global"
* one). \brief Avoid using apart when a scope must be forced.
*/
const VariablesContainer* GetTopMostVariablesContainer() const {
if (variablesContainers.empty()) return nullptr;
const VariablesContainer *GetTopMostVariablesContainer() const {
if (variablesContainers.empty())
return nullptr;
return variablesContainers.front();
};
@@ -80,16 +108,29 @@ class GD_CORE_API VariablesContainersList {
* (so the most "local" one) excluding local variables.
* \brief Avoid using apart when a scope must be forced.
*/
const VariablesContainer* GetBottomMostVariablesContainer() const {
if (variablesContainers.empty()) return nullptr;
const VariablesContainer *GetBottomMostVariablesContainer() const {
if (variablesContainers.empty())
return nullptr;
return variablesContainers.at(firstLocalVariableContainerIndex - 1);
}
/**
* Get the variables container for a given variable or property or parameter.
*/
const VariablesContainer &
GetVariablesContainerFromVariableOrPropertyOrParameterName(const gd::String &variableName) const;
/**
* Get the variables container for a given variable or property.
*/
const VariablesContainer &
GetVariablesContainerFromVariableOrPropertyName(const gd::String &variableName) const;
/**
* Get the variables container for a given variable.
*/
const VariablesContainer &
GetVariablesContainerFromVariableName(const gd::String &variableName) const;
GetVariablesContainerFromVariableNameOnly(const gd::String &variableName) const;
/**
* Get the variables container index for a given variable.
@@ -109,43 +150,47 @@ class GD_CORE_API VariablesContainersList {
* \warning Trying to access to a not existing variable container will result
* in undefined behavior.
*/
const gd::VariablesContainer& GetVariablesContainer(std::size_t index) const {
const gd::VariablesContainer &GetVariablesContainer(std::size_t index) const {
return *variablesContainers.at(index);
}
/**
* \brief Return the number variable containers.
*/
std::size_t GetVariablesContainersCount() const { return variablesContainers.size(); }
std::size_t GetVariablesContainersCount() const {
return variablesContainers.size();
}
/**
* \brief Call the callback for each variable having a name matching the specified search.
* \brief Call the callback for each variable having a name matching the
* specified search.
*/
void ForEachVariableMatchingSearch(const gd::String& search, std::function<void(const gd::String& name, const gd::Variable& variable)> fn) const;
void ForEachVariableMatchingSearch(
const gd::String &search,
std::function<void(const gd::String &name, const gd::Variable &variable)>
fn) const;
/**
* \brief Push a new variables container to the context.
*/
void Push(const gd::VariablesContainer& variablesContainer) {
void Push(const gd::VariablesContainer &variablesContainer) {
variablesContainers.push_back(&variablesContainer);
};
/**
* \brief Pop a variables container from the context.
*/
void Pop() {
variablesContainers.pop_back();
};
void Pop() { variablesContainers.pop_back(); };
/** Do not use - should be private but accessible to let Emscripten create a
* temporary. */
VariablesContainersList() : firstLocalVariableContainerIndex(0){};
/** Do not use - should be private but accessible to let Emscripten create a temporary. */
VariablesContainersList(): firstLocalVariableContainerIndex(0) {};
private:
std::vector<const gd::VariablesContainer*> variablesContainers;
private:
std::vector<const gd::VariablesContainer *> variablesContainers;
std::size_t firstLocalVariableContainerIndex;
static Variable badVariable;
static VariablesContainer badVariablesContainer;
};
} // namespace gd
} // namespace gd

View File

@@ -268,8 +268,9 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& function = extension.InsertNewEventsFunction("MyFreeFunction", 0);
auto &function = extension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeFunction", 0);
gd::StandardEvent standardEvent;
gd::Instruction instruction;
instruction.SetType("MyExtension::DoSomethingWithResources");
@@ -777,8 +778,9 @@ TEST_CASE("ArbitraryResourceWorker", "[common][resources]") {
ArbitraryResourceWorkerTest worker(project.GetResourcesManager());
auto& extension = project.InsertNewEventsFunctionsExtension("MyEventExtension", 0);
auto& function = extension.InsertNewEventsFunction("MyFreeFunction", 0);
auto &function = extension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeFunction", 0);
gd::StandardEvent standardEvent;
gd::Instruction instruction;
instruction.SetType("MyExtension::DoSomethingWithResources");

View File

@@ -263,6 +263,46 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
extension->SetExtensionInformation(
"BuiltinVariables", "My testing extension for variables", "", "", "");
extension
->AddCondition("NumberVariable",
"Variable value",
"Compare the number value of a variable.",
"The variable _PARAM0_",
"",
"",
"")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"number", gd::ParameterOptions::MakeNewOptions());
extension
->AddCondition("StringVariable",
"Variable value",
"Compare the text (string) of a variable.",
"The variable _PARAM0_",
"",
"",
"")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.UseStandardRelationalOperatorParameters(
"string", gd::ParameterOptions::MakeNewOptions());
extension
->AddCondition(
"BooleanVariable",
"Variable value",
"Compare the boolean value of a variable.",
"The variable _PARAM0_ is _PARAM1_",
"",
"",
"")
.AddParameter("variableOrPropertyOrParameter", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.
.AddCodeOnlyParameter("trueorfalse", "");
extension
->AddAction("SetNumberVariable",
"Change variable value",
@@ -271,7 +311,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
"",
"",
"")
.AddParameter("variable", "Variable")
.AddParameter("variableOrProperty", "Variable")
.AddParameter("operator", "Operator", "number")
.AddParameter("number", "Value")
.SetFunctionName("setNumberVariable");
@@ -284,7 +324,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
"",
"",
"")
.AddParameter("variable", "Variable")
.AddParameter("variableOrProperty", "Variable")
.AddParameter("operator", "Operator", "string")
.AddParameter("string", "Value")
.SetFunctionName("setStringVariable");
@@ -297,7 +337,7 @@ void SetupProjectWithDummyPlatform(gd::Project& project,
"",
"",
"")
.AddParameter("variable", "Variable")
.AddParameter("variableOrProperty", "Variable")
.AddParameter("operator", "Operator", "boolean")
// This parameter allows to keep the operand expression
// when the editor switch between variable instructions.

View File

@@ -38,6 +38,8 @@ TEST_CASE("EventsFunctionsContainer", "[common]") {
"Function2.x");
REQUIRE(eventsFunctionContainer.GetEventsFunction(2).GetName() ==
"Function3");
REQUIRE(eventsFunctionContainer.GetOwner() ==
gd::EventsFunctionsContainer::FunctionOwner::Extension);
REQUIRE(eventsFunctionContainer2.GetEventsFunctionsCount() == 3);
REQUIRE(eventsFunctionContainer2.GetEventsFunction(0).GetName() ==
"Function1.y");

View File

@@ -11,9 +11,10 @@
TEST_CASE("EventsFunctionsExtension", "[common]") {
SECTION("Sanity checks") {
gd::EventsFunctionsExtension eventsFunctionExtension;
eventsFunctionExtension.InsertNewEventsFunction("Function1", 0);
eventsFunctionExtension.InsertNewEventsFunction("Function2", 1);
eventsFunctionExtension.InsertNewEventsFunction("Function3", 2);
auto &freeEventsFunctions = eventsFunctionExtension.GetEventsFunctions();
freeEventsFunctions.InsertNewEventsFunction("Function1", 0);
freeEventsFunctions.InsertNewEventsFunction("Function2", 1);
freeEventsFunctions.InsertNewEventsFunction("Function3", 2);
eventsFunctionExtension.GetEventsBasedBehaviors().InsertNew("MyBehavior",
0);
eventsFunctionExtension.GetEventsBasedBehaviors().InsertNew("MyBehavior2",
@@ -22,12 +23,13 @@ TEST_CASE("EventsFunctionsExtension", "[common]") {
// Check that copy operator is working
gd::EventsFunctionsExtension eventsFunctionExtension2 =
eventsFunctionExtension;
REQUIRE(eventsFunctionExtension2.GetEventsFunctionsCount() == 3);
REQUIRE(eventsFunctionExtension2.GetEventsFunction(0).GetName() ==
auto &freeEventsFunctions2 = eventsFunctionExtension2.GetEventsFunctions();
REQUIRE(freeEventsFunctions2.GetEventsFunctionsCount() == 3);
REQUIRE(freeEventsFunctions2.GetEventsFunction(0).GetName() ==
"Function1");
REQUIRE(eventsFunctionExtension2.GetEventsFunction(1).GetName() ==
REQUIRE(freeEventsFunctions2.GetEventsFunction(1).GetName() ==
"Function2");
REQUIRE(eventsFunctionExtension2.GetEventsFunction(2).GetName() ==
REQUIRE(freeEventsFunctions2.GetEventsFunction(2).GetName() ==
"Function3");
REQUIRE(eventsFunctionExtension2.GetEventsBasedBehaviors().GetCount() == 2);
REQUIRE(
@@ -39,21 +41,21 @@ TEST_CASE("EventsFunctionsExtension", "[common]") {
// Check that the copy has not somehow shared the same pointers
// to the events functions.
eventsFunctionExtension.GetEventsFunction(1).SetName("Function2.x");
eventsFunctionExtension2.GetEventsFunction(0).SetName("Function1.y");
REQUIRE(eventsFunctionExtension.GetEventsFunctionsCount() == 3);
REQUIRE(eventsFunctionExtension.GetEventsFunction(0).GetName() ==
freeEventsFunctions.GetEventsFunction(1).SetName("Function2.x");
freeEventsFunctions2.GetEventsFunction(0).SetName("Function1.y");
REQUIRE(freeEventsFunctions.GetEventsFunctionsCount() == 3);
REQUIRE(freeEventsFunctions.GetEventsFunction(0).GetName() ==
"Function1");
REQUIRE(eventsFunctionExtension.GetEventsFunction(1).GetName() ==
REQUIRE(freeEventsFunctions.GetEventsFunction(1).GetName() ==
"Function2.x");
REQUIRE(eventsFunctionExtension.GetEventsFunction(2).GetName() ==
REQUIRE(freeEventsFunctions.GetEventsFunction(2).GetName() ==
"Function3");
REQUIRE(eventsFunctionExtension2.GetEventsFunctionsCount() == 3);
REQUIRE(eventsFunctionExtension2.GetEventsFunction(0).GetName() ==
REQUIRE(freeEventsFunctions2.GetEventsFunctionsCount() == 3);
REQUIRE(freeEventsFunctions2.GetEventsFunction(0).GetName() ==
"Function1.y");
REQUIRE(eventsFunctionExtension2.GetEventsFunction(1).GetName() ==
REQUIRE(freeEventsFunctions2.GetEventsFunction(1).GetName() ==
"Function2");
REQUIRE(eventsFunctionExtension2.GetEventsFunction(2).GetName() ==
REQUIRE(freeEventsFunctions2.GetEventsFunction(2).GetName() ==
"Function3");
}
}

View File

@@ -2035,6 +2035,319 @@ TEST_CASE("ExpressionParser2", "[common][events]") {
}
}
SECTION("Valid property (in variableOrPropertyOrParameter parameter)") {
{
gd::PropertiesContainer propertiesContainer(
gd::EventsFunctionsContainer::Extension);
auto projectScopedContainersWithProperties = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithProperties.AddPropertiesContainer(
propertiesContainer);
propertiesContainer.InsertNew("MyProperty");
auto node = parser.ParseExpression("MyProperty");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 0);
}
}
SECTION("Valid property (in variableOrProperty parameter)") {
{
gd::PropertiesContainer propertiesContainer(
gd::EventsFunctionsContainer::Extension);
auto projectScopedContainersWithProperties = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithProperties.AddPropertiesContainer(
propertiesContainer);
propertiesContainer.InsertNew("MyProperty");
auto node = parser.ParseExpression("MyProperty");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 0);
}
}
SECTION("Invalid property (in variable parameter)") {
{
gd::PropertiesContainer propertiesContainer(
gd::EventsFunctionsContainer::Extension);
auto projectScopedContainersWithProperties = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithProperties.AddPropertiesContainer(
propertiesContainer);
propertiesContainer.InsertNew("MyProperty");
auto node = parser.ParseExpression("MyProperty");
gd::ExpressionValidator validator(
platform, projectScopedContainersWithProperties, "variable");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 1);
REQUIRE(validator.GetAllErrors()[0]->GetMessage() ==
"This variable has the same name as a property. Consider "
"renaming one or the other.");
}
}
SECTION("Invalid property (property with child in variableOrProperty parameter)") {
{
gd::PropertiesContainer propertiesContainer(
gd::EventsFunctionsContainer::Extension);
auto projectScopedContainersWithProperties = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithProperties.AddPropertiesContainer(
propertiesContainer);
propertiesContainer.InsertNew("MyProperty");
{
auto node = parser.ParseExpression("MyProperty.MyChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty.MyChild.MyGrandChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty[\"MyChild\"]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty[0]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
}
}
SECTION("Invalid property (property with child in variableOrPropertyOrParameter parameter)") {
{
gd::PropertiesContainer propertiesContainer(
gd::EventsFunctionsContainer::Extension);
auto projectScopedContainersWithProperties = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithProperties.AddPropertiesContainer(
propertiesContainer);
propertiesContainer.InsertNew("MyProperty");
{
auto node = parser.ParseExpression("MyProperty.MyChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty.MyChild.MyGrandChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty[\"MyChild\"]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyProperty[0]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithProperties,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
}
}
SECTION("Valid parameter (in variableOrPropertyOrParameter parameter)") {
{
gd::ParameterMetadataContainer parameters;
parameters.InsertNewParameter("MyParameter", 0).SetType("number");
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithParameters.AddParameters(parameters);
auto node = parser.ParseExpression("MyParameter");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 0);
}
}
SECTION("Invalid parameter (in variableOrProperty parameter)") {
{
gd::ParameterMetadataContainer parameters;
parameters.InsertNewParameter("MyParameter", 0).SetType("number");
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithParameters.AddParameters(parameters);
auto node = parser.ParseExpression("MyParameter");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrProperty");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 1);
REQUIRE(validator.GetAllErrors()[0]->GetMessage() ==
"This variable has the same name as a parameter. Consider "
"renaming one or the other.");
}
}
SECTION("Invalid parameter (in variable parameter)") {
{
gd::ParameterMetadataContainer parameters;
parameters.InsertNewParameter("MyParameter", 0).SetType("number");
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithParameters.AddParameters(parameters);
auto node = parser.ParseExpression("MyParameter");
gd::ExpressionValidator validator(
platform, projectScopedContainersWithParameters, "variable");
node->Visit(validator);
REQUIRE(validator.GetAllErrors().size() == 1);
REQUIRE(validator.GetAllErrors()[0]->GetMessage() ==
"This variable has the same name as a parameter. Consider "
"renaming one or the other.");
}
}
SECTION("Invalid parameter (parameter with child in variableOrPropertyOrParameter parameter)") {
{
gd::ParameterMetadataContainer parameters;
parameters.InsertNewParameter("MyParameter", 0).SetType("number");
auto projectScopedContainersWithParameters = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForProjectAndLayout(project, layout1);
projectScopedContainersWithParameters.AddParameters(parameters);
{
auto node = parser.ParseExpression("MyParameter.MyChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyParameter.MyChild.MyGrandChild");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyParameter[\"MyChild\"]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
{
auto node = parser.ParseExpression("MyParameter[0]");
gd::ExpressionValidator validator(platform,
projectScopedContainersWithParameters,
"variableOrPropertyOrParameter");
node->Visit(validator);
REQUIRE(validator.GetFatalErrors().size() == 1);
REQUIRE(validator.GetFatalErrors()[0]->GetMessage() ==
"Properties can't have children.");
}
}
}
SECTION("Valid parameter") {
gd::ParameterMetadataContainer parameters;
parameters.InsertNewParameter("MyParameter1", 0).SetType("number");

View File

@@ -116,14 +116,11 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterEvent.GetConditions().size() == 0);
REQUIRE(setterEvent.GetActions().size() == 1);
auto &setterAction = setterEvent.GetActions().at(0);
REQUIRE(
setterAction.GetType() ==
"MyEventsExtension::MyEventsBasedBehavior::SetPropertyMovementAngle");
REQUIRE(setterAction.GetParametersCount() == 4);
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "Behavior");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(3).GetPlainString() == "Value");
REQUIRE(setterAction.GetType() == "SetNumberVariable");
REQUIRE(setterAction.GetParametersCount() == 3);
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "Value");
}
}
@@ -206,12 +203,12 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(getterEvent.GetActions().size() == 1);
auto &getterCondition = getterEvent.GetConditions().at(0);
REQUIRE(getterCondition.GetType() ==
"MyEventsExtension::MyEventsBasedBehavior::PropertyRotate");
REQUIRE(getterCondition.GetType() == "BooleanVariable");
REQUIRE(!getterCondition.IsInverted());
REQUIRE(getterCondition.GetParametersCount() == 2);
REQUIRE(getterCondition.GetParameter(0).GetPlainString() == "Object");
REQUIRE(getterCondition.GetParameter(1).GetPlainString() == "Behavior");
REQUIRE(getterCondition.GetParametersCount() == 3);
REQUIRE(getterCondition.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(getterCondition.GetParameter(1).GetPlainString() == "True");
REQUIRE(getterCondition.GetParameter(2).GetPlainString() == "");
auto &getterAction = getterEvent.GetActions().at(0);
REQUIRE(getterAction.GetType() == "SetReturnBoolean");
@@ -257,19 +254,19 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterNoEvent.GetActions().size() == 1);
auto &setterNoCondition = setterNoEvent.GetConditions().at(0);
REQUIRE(setterNoCondition.GetType() == "GetArgumentAsBoolean");
REQUIRE(setterNoCondition.IsInverted());
REQUIRE(setterNoCondition.GetParametersCount() == 1);
REQUIRE(setterNoCondition.GetParameter(0).GetPlainString() ==
"\"Value\"");
REQUIRE(setterNoCondition.GetType() == "BooleanVariable");
REQUIRE(!setterNoCondition.IsInverted());
REQUIRE(setterNoCondition.GetParametersCount() == 3);
REQUIRE(setterNoCondition.GetParameter(0).GetPlainString() == "Value");
REQUIRE(setterNoCondition.GetParameter(1).GetPlainString() == "False");
REQUIRE(setterNoCondition.GetParameter(2).GetPlainString() == "");
auto &setterNoAction = setterNoEvent.GetActions().at(0);
REQUIRE(setterNoAction.GetType() ==
"MyEventsExtension::MyEventsBasedBehavior::SetPropertyRotate");
REQUIRE(setterNoAction.GetType() == "SetBooleanVariable");
REQUIRE(setterNoAction.GetParametersCount() == 3);
REQUIRE(setterNoAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterNoAction.GetParameter(1).GetPlainString() == "Behavior");
REQUIRE(setterNoAction.GetParameter(2).GetPlainString() == "no");
REQUIRE(setterNoAction.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(setterNoAction.GetParameter(1).GetPlainString() == "False");
REQUIRE(setterNoAction.GetParameter(2).GetPlainString() == "");
auto &setterYesEvent =
dynamic_cast<gd::StandardEvent &>(setter.GetEvents().GetEvent(1));
@@ -277,19 +274,19 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterYesEvent.GetActions().size() == 1);
auto &setterYesCondition = setterYesEvent.GetConditions().at(0);
REQUIRE(setterYesCondition.GetType() == "GetArgumentAsBoolean");
REQUIRE(setterYesCondition.GetType() == "BooleanVariable");
REQUIRE(!setterYesCondition.IsInverted());
REQUIRE(setterYesCondition.GetParametersCount() == 1);
REQUIRE(setterYesCondition.GetParameter(0).GetPlainString() ==
"\"Value\"");
REQUIRE(setterYesCondition.GetParametersCount() == 3);
REQUIRE(setterYesCondition.GetParameter(0).GetPlainString() == "Value");
REQUIRE(setterYesCondition.GetParameter(1).GetPlainString() == "True");
REQUIRE(setterYesCondition.GetParameter(2).GetPlainString() == "");
auto &setterYesAction = setterYesEvent.GetActions().at(0);
REQUIRE(setterYesAction.GetType() ==
"MyEventsExtension::MyEventsBasedBehavior::SetPropertyRotate");
REQUIRE(setterYesAction.GetType() == "SetBooleanVariable");
REQUIRE(setterYesAction.GetParametersCount() == 3);
REQUIRE(setterYesAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterYesAction.GetParameter(1).GetPlainString() == "Behavior");
REQUIRE(setterYesAction.GetParameter(2).GetPlainString() == "yes");
REQUIRE(setterYesAction.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(setterYesAction.GetParameter(1).GetPlainString() == "True");
REQUIRE(setterYesAction.GetParameter(2).GetPlainString() == "");
}
}
SECTION("Can generate functions for a number property in an object") {
@@ -366,11 +363,9 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterEvent.GetConditions().size() == 0);
REQUIRE(setterEvent.GetActions().size() == 1);
auto &setterAction = setterEvent.GetActions().at(0);
REQUIRE(
setterAction.GetType() ==
"MyEventsExtension::MyEventsBasedObject::SetPropertyMovementAngle");
REQUIRE(setterAction.GetType() == "SetNumberVariable");
REQUIRE(setterAction.GetParametersCount() == 3);
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "Value");
}
@@ -454,11 +449,12 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(getterEvent.GetActions().size() == 1);
auto &getterCondition = getterEvent.GetConditions().at(0);
REQUIRE(getterCondition.GetType() ==
"MyEventsExtension::MyEventsBasedObject::PropertyRotate");
REQUIRE(getterCondition.GetType() == "BooleanVariable");
REQUIRE(!getterCondition.IsInverted());
REQUIRE(getterCondition.GetParametersCount() == 1);
REQUIRE(getterCondition.GetParameter(0).GetPlainString() == "Object");
REQUIRE(getterCondition.GetParametersCount() == 3);
REQUIRE(getterCondition.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(getterCondition.GetParameter(1).GetPlainString() == "True");
REQUIRE(getterCondition.GetParameter(2).GetPlainString() == "");
auto &getterAction = getterEvent.GetActions().at(0);
REQUIRE(getterAction.GetType() == "SetReturnBoolean");
@@ -500,18 +496,19 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterNoEvent.GetActions().size() == 1);
auto &setterNoCondition = setterNoEvent.GetConditions().at(0);
REQUIRE(setterNoCondition.GetType() == "GetArgumentAsBoolean");
REQUIRE(setterNoCondition.IsInverted());
REQUIRE(setterNoCondition.GetParametersCount() == 1);
REQUIRE(setterNoCondition.GetParameter(0).GetPlainString() ==
"\"Value\"");
REQUIRE(setterNoCondition.GetType() == "BooleanVariable");
REQUIRE(!setterNoCondition.IsInverted());
REQUIRE(setterNoCondition.GetParametersCount() == 3);
REQUIRE(setterNoCondition.GetParameter(0).GetPlainString() == "Value");
REQUIRE(setterNoCondition.GetParameter(1).GetPlainString() == "False");
REQUIRE(setterNoCondition.GetParameter(2).GetPlainString() == "");
auto &setterNoAction = setterNoEvent.GetActions().at(0);
REQUIRE(setterNoAction.GetType() ==
"MyEventsExtension::MyEventsBasedObject::SetPropertyRotate");
REQUIRE(setterNoAction.GetParametersCount() == 2);
REQUIRE(setterNoAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterNoAction.GetParameter(1).GetPlainString() == "no");
REQUIRE(setterNoAction.GetType() == "SetBooleanVariable");
REQUIRE(setterNoAction.GetParametersCount() == 3);
REQUIRE(setterNoAction.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(setterNoAction.GetParameter(1).GetPlainString() == "False");
REQUIRE(setterNoAction.GetParameter(2).GetPlainString() == "");
auto &setterYesEvent =
dynamic_cast<gd::StandardEvent &>(setter.GetEvents().GetEvent(1));
@@ -519,18 +516,19 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterYesEvent.GetActions().size() == 1);
auto &setterYesCondition = setterYesEvent.GetConditions().at(0);
REQUIRE(setterYesCondition.GetType() == "GetArgumentAsBoolean");
REQUIRE(setterYesCondition.GetType() == "BooleanVariable");
REQUIRE(!setterYesCondition.IsInverted());
REQUIRE(setterYesCondition.GetParametersCount() == 1);
REQUIRE(setterYesCondition.GetParameter(0).GetPlainString() ==
"\"Value\"");
REQUIRE(setterYesCondition.GetParametersCount() == 3);
REQUIRE(setterYesCondition.GetParameter(0).GetPlainString() == "Value");
REQUIRE(setterYesCondition.GetParameter(1).GetPlainString() == "True");
REQUIRE(setterYesCondition.GetParameter(2).GetPlainString() == "");
auto &setterYesAction = setterYesEvent.GetActions().at(0);
REQUIRE(setterYesAction.GetType() ==
"MyEventsExtension::MyEventsBasedObject::SetPropertyRotate");
REQUIRE(setterYesAction.GetParametersCount() == 2);
REQUIRE(setterYesAction.GetParameter(0).GetPlainString() == "Object");
REQUIRE(setterYesAction.GetParameter(1).GetPlainString() == "yes");
REQUIRE(setterYesAction.GetType() == "SetBooleanVariable");
REQUIRE(setterYesAction.GetParametersCount() == 3);
REQUIRE(setterYesAction.GetParameter(0).GetPlainString() == "Rotate");
REQUIRE(setterYesAction.GetParameter(1).GetPlainString() == "True");
REQUIRE(setterYesAction.GetParameter(2).GetPlainString() == "");
}
}
@@ -588,9 +586,11 @@ TEST_CASE("PropertyFunctionGenerator", "[common]") {
REQUIRE(setterEvent.GetConditions().size() == 0);
REQUIRE(setterEvent.GetActions().size() == 1);
auto &setterAction = setterEvent.GetActions().at(0);
REQUIRE(setterAction.GetType() ==
"MyEventsExtension::MyEventsBasedBehavior::"
"SetSharedPropertyMovementAngle");
REQUIRE(setterAction.GetType() == "SetNumberVariable");
REQUIRE(setterAction.GetParametersCount() == 3);
REQUIRE(setterAction.GetParameter(0).GetPlainString() == "MovementAngle");
REQUIRE(setterAction.GetParameter(1).GetPlainString() == "=");
REQUIRE(setterAction.GetParameter(2).GetPlainString() == "Value");
}
}

View File

@@ -1540,7 +1540,7 @@ TEST_CASE("WholeProjectRefactorer::ApplyRefactoringForVariablesContainer",
auto projectScopedContainers =
gd::ProjectScopedContainers::MakeNewProjectScopedContainersForProjectAndLayout(project, scene);
REQUIRE(&projectScopedContainers.GetVariablesContainersList()
.GetVariablesContainerFromVariableName("MyVariable") == &scene.GetVariables());
.GetVariablesContainerFromVariableOrPropertyOrParameterName("MyVariable") == &scene.GetVariables());
// Do the changes and launch the refactoring.
scene.GetVariables().ResetPersistentUuid();
@@ -1722,7 +1722,8 @@ TEST_CASE("WholeProjectRefactorer::ApplyRefactoringForVariablesContainer",
auto &extension = project.InsertNewEventsFunctionsExtension("Extension", 0);
extension.GetSceneVariables().InsertNew("MySceneVariable").SetValue(123);
auto &function = extension.InsertNewEventsFunction("MyFunction", 0);
auto &function =
extension.GetEventsFunctions().InsertNewEventsFunction("MyFunction", 0);
gd::StandardEvent &event =
dynamic_cast<gd::StandardEvent &>(function.GetEvents().InsertNewEvent(
project, "BuiltinCommonInstructions::Standard"));

View File

@@ -136,6 +136,74 @@ CreateInstructionWithVariableParameter(gd::Project &project,
return event.GetActions().Insert(instruction);
}
const gd::Instruction &
CreateNumberVariableSetterAction(gd::Project &project,
gd::EventsList &events,
const gd::String &variableName,
const gd::String &expression) {
gd::StandardEvent &event = dynamic_cast<gd::StandardEvent &>(
events.InsertNewEvent(project, "BuiltinCommonInstructions::Standard"));
gd::Instruction instruction;
instruction.SetType("SetNumberVariable");
instruction.SetParametersCount(3);
instruction.SetParameter(0, variableName);
instruction.SetParameter(1, "=");
instruction.SetParameter(2, expression);
return event.GetActions().Insert(instruction);
}
const gd::Instruction &
CreateNumberVariableGetterCondition(gd::Project &project,
gd::EventsList &events,
const gd::String &variableName,
const gd::String &expression) {
gd::StandardEvent &event = dynamic_cast<gd::StandardEvent &>(
events.InsertNewEvent(project, "BuiltinCommonInstructions::Standard"));
gd::Instruction instruction;
instruction.SetType("NumberVariable");
instruction.SetParametersCount(3);
instruction.SetParameter(0, variableName);
instruction.SetParameter(1, "=");
instruction.SetParameter(2, expression);
return event.GetConditions().Insert(instruction);
}
const gd::Instruction &
CreateStringVariableSetterAction(gd::Project &project,
gd::EventsList &events,
const gd::String &variableName,
const gd::String &expression) {
gd::StandardEvent &event = dynamic_cast<gd::StandardEvent &>(
events.InsertNewEvent(project, "BuiltinCommonInstructions::Standard"));
gd::Instruction instruction;
instruction.SetType("SetStringVariable");
instruction.SetParametersCount(3);
instruction.SetParameter(0, variableName);
instruction.SetParameter(1, "=");
instruction.SetParameter(2, expression);
return event.GetActions().Insert(instruction);
}
const gd::Instruction &
CreateStringVariableGetterCondition(gd::Project &project,
gd::EventsList &events,
const gd::String &variableName,
const gd::String &expression) {
gd::StandardEvent &event = dynamic_cast<gd::StandardEvent &>(
events.InsertNewEvent(project, "BuiltinCommonInstructions::Standard"));
gd::Instruction instruction;
instruction.SetType("StringVariable");
instruction.SetParametersCount(3);
instruction.SetParameter(0, variableName);
instruction.SetParameter(1, "=");
instruction.SetParameter(2, expression);
return event.GetConditions().Insert(instruction);
}
enum TestEvent {
FreeFunctionAction,
FreeFunctionWithExpression,
@@ -201,8 +269,9 @@ const std::vector<const gd::EventsList *> GetEventsListsNotAssociatedToScene(gd:
.GetEventsFunctions()
.GetEventsFunction("MyBehaviorEventsFunction")
.GetEvents();
auto &freeFunctionEvents =
eventsExtension.GetEventsFunction("MyOtherEventsFunction").GetEvents();
auto &freeFunctionEvents = eventsExtension.GetEventsFunctions()
.GetEventsFunction("MyOtherEventsFunction")
.GetEvents();
eventLists.push_back(&objectFunctionEvents);
eventLists.push_back(&behaviorFunctionEvents);
eventLists.push_back(&freeFunctionEvents);
@@ -1129,8 +1198,9 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
// Add (free) functions and a (free) expression
{
auto &freeEventsFunctions = eventsExtension.GetEventsFunctions();
auto &action =
eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0);
freeEventsFunctions.InsertNewEventsFunction("MyEventsFunction", 0);
action.GetParameters()
.InsertNewParameter("currentScene", 0)
.SetType("")
@@ -1145,21 +1215,21 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
.SetExtraInfo("MyEventsExtension::MyEventsBasedBehavior");
auto &expression =
eventsExtension.InsertNewEventsFunction("MyEventsFunctionExpression", 1)
freeEventsFunctions.InsertNewEventsFunction("MyEventsFunctionExpression", 1)
.SetFunctionType(gd::EventsFunction::Expression);
expression.GetParameters()
.InsertNewParameter("currentScene", 0)
.SetType("")
.SetCodeOnly(true);
auto &freeExpressionAndCondition = eventsExtension.InsertNewEventsFunction("MyEventsFunctionExpressionAndCondition", 2)
auto &freeExpressionAndCondition = freeEventsFunctions.InsertNewEventsFunction("MyEventsFunctionExpressionAndCondition", 2)
.SetFunctionType(gd::EventsFunction::ExpressionAndCondition);
freeExpressionAndCondition.GetParameters().InsertNewParameter("Value1", 0)
.SetType("expression");
freeExpressionAndCondition.GetParameters().InsertNewParameter("Value2", 1)
.SetType("expression");
eventsExtension.InsertNewEventsFunction("MyEventsFunctionActionWithOperator", 2)
freeEventsFunctions.InsertNewEventsFunction("MyEventsFunctionActionWithOperator", 2)
.SetFunctionType(gd::EventsFunction::ActionWithOperator)
.SetGetterName("MyEventsFunctionExpressionAndCondition");
}
@@ -1168,8 +1238,8 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
// object and behavior.
{
// Add functions, and parameters that should be there by convention.
auto &action =
eventsExtension.InsertNewEventsFunction("MyOtherEventsFunction", 0);
auto &action = eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyOtherEventsFunction", 0);
// Define the same objects as in the layout to be consistent with events.
action.GetParameters()
.InsertNewParameter("ObjectWithMyBehavior", 0)
@@ -1231,7 +1301,8 @@ SetupProjectWithEventsFunctionExtension(gd::Project &project) {
.GetEventsFunctions()
.GetEventsFunction("MyBehaviorEventsFunction")
.GetEvents());
SetupEvents(eventsExtension.GetEventsFunction("MyOtherEventsFunction")
SetupEvents(eventsExtension.GetEventsFunctions()
.GetEventsFunction("MyOtherEventsFunction")
.GetEvents());
}
@@ -1583,7 +1654,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Add a (free) function with an object group
gd::EventsFunction &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyEventsFunction", 0);
gd::ObjectGroup &objectGroup =
eventsFunction.GetObjectGroups().InsertNew("MyGroup", 0);
objectGroup.AddObject("Object1");
@@ -1594,10 +1666,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Create the objects container for the events function
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
// Trigger the refactoring before the renaming of an object
gd::WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction(
@@ -1618,15 +1692,18 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.GetEventsFunction("MyOtherEventsFunction");
eventsExtension.GetEventsFunctions().GetEventsFunction(
"MyOtherEventsFunction");
// Create the objects container for the events function
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
// Simulate a variable in ObjectWithMyBehavior, even if this is not
// supported by the editor.
@@ -1868,7 +1945,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Add a (free) function with an object group
gd::EventsFunction &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyEventsFunction", 0);
gd::ObjectGroup &objectGroup =
eventsFunction.GetObjectGroups().InsertNew("MyGroup", 0);
objectGroup.AddObject("Object1");
@@ -2066,7 +2144,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Add the function used by the instruction that is checked in this test.
// When the function doesn't exist the destination extension, the
// instruction keeps pointing to the old extension.
destinationExtension.InsertNewEventsFunction("MyEventsFunction", 0);
destinationExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyEventsFunction", 0);
auto &duplicatedBehavior =
destinationExtension.GetEventsBasedBehaviors().InsertNew(
@@ -2108,7 +2187,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Add the function used by the instruction that is checked in this test.
// When the function doesn't exist the destination extension, the
// instruction keeps pointing to the old extension.
destinationExtension.InsertNewEventsFunction("MyEventsFunction", 0);
destinationExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyEventsFunction", 0);
auto &duplicatedObject =
destinationExtension.GetEventsBasedObjects().InsertNew(
@@ -2217,6 +2297,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Free function
auto &myEventsFunction =
project.GetEventsFunctionsExtension("MyEventsExtension")
.GetEventsFunctions()
.GetEventsFunction("MyEventsFunction");
REQUIRE(myEventsFunction.GetParameters().GetParameter(1).GetExtraInfo() ==
"MyRenamedExtension::MyEventsBasedObject");
@@ -2333,8 +2414,10 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
"MyEventsExtension::MyRenamedFunctionExpressionAndCondition");
// Check that the action still refer to the right ExpressionAndCondition.
REQUIRE(eventsExtension.GetEventsFunction("MyEventsFunctionActionWithOperator")
.GetGetterName() == "MyRenamedFunctionExpressionAndCondition");
REQUIRE(eventsExtension.GetEventsFunctions()
.GetEventsFunction("MyEventsFunctionActionWithOperator")
.GetGetterName() ==
"MyRenamedFunctionExpressionAndCondition");
}
}
@@ -2345,7 +2428,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
@@ -2358,10 +2442,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter", "MyRenamedParameter");
@@ -2372,6 +2458,134 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
"MyExtension::GetVariableAsNumber(MyVariable.MyChild[MyRenamedParameter])");
}
SECTION("(Free function) number parameter renamed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
.SetName("number");
auto &instruction = CreateNumberVariableSetterAction(
project, eventsFunction.GetEvents(), "MyParameter", "123");
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter", "MyRenamedParameter");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedParameter");
}
SECTION("(Free function) number parameter renamed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
.SetName("number");
auto &instruction = CreateNumberVariableGetterCondition(
project, eventsFunction.GetEvents(), "MyParameter", "123");
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter", "MyRenamedParameter");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedParameter");
}
SECTION("(Free function) parameter type changed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
.SetName("number");
// The property was of type "string".
auto &instruction = CreateStringVariableSetterAction(
project, eventsFunction.GetEvents(), "MyParameter", "123");
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::ChangeParameterType(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter");
REQUIRE(instruction.GetType() == "SetNumberVariable");
}
SECTION("(Free function) parameter type changed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
.SetName("number");
// The property was of type "string".
auto &instruction = CreateStringVariableGetterCondition(
project, eventsFunction.GetEvents(), "MyParameter", "123");
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::ChangeParameterType(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter");
REQUIRE(instruction.GetType() == "NumberVariable");
}
SECTION("(Free function) number parameter not renamed (in variable parameter)") {
gd::Project project;
gd::Platform platform;
@@ -2379,7 +2593,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyParameter")
.GetValueTypeMetadata()
@@ -2393,10 +2608,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyParameter", "MyRenamedParameter");
@@ -2415,7 +2632,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyObject")
.GetValueTypeMetadata()
@@ -2431,10 +2649,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyObject", "MyRenamedObject");
@@ -2454,7 +2674,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyObject")
.GetValueTypeMetadata()
@@ -2469,10 +2690,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyObject", "MyRenamedObject");
@@ -2491,7 +2714,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyObject")
.GetValueTypeMetadata()
@@ -2512,10 +2736,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyBehavior", "MyRenamedBehavior");
@@ -2535,7 +2761,8 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsFunction =
eventsExtension.InsertNewEventsFunction("MyFreeEventsFunction", 0);
eventsExtension.GetEventsFunctions().InsertNewEventsFunction(
"MyFreeEventsFunction", 0);
eventsFunction.GetParameters()
.AddNewParameter("MyObject")
.GetValueTypeMetadata()
@@ -2555,10 +2782,12 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
gd::ObjectsContainer parametersObjectsContainer(
gd::ObjectsContainer::SourceType::Function);
gd::VariablesContainer parameterVariablesContainer(
gd::VariablesContainer::SourceType::Parameters);
auto projectScopedContainers = gd::ProjectScopedContainers::
MakeNewProjectScopedContainersForFreeEventsFunction(
project, eventsExtension, eventsFunction,
parametersObjectsContainer);
parametersObjectsContainer, parameterVariablesContainer);
gd::WholeProjectRefactorer::RenameParameter(
project, projectScopedContainers, eventsFunction,
parametersObjectsContainer, "MyBehavior", "MyRenamedBehavior");
@@ -2727,6 +2956,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Free function
auto &myEventsFunction =
project.GetEventsFunctionsExtension("MyEventsExtension")
.GetEventsFunctions()
.GetEventsFunction("MyEventsFunction");
REQUIRE(myEventsFunction.GetParameters().GetParameter(2).GetExtraInfo() ==
"MyEventsExtension::MyRenamedEventsBasedBehavior");
@@ -2837,6 +3067,7 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
// Free function
auto &myEventsFunction =
project.GetEventsFunctionsExtension("MyEventsExtension")
.GetEventsFunctions()
.GetEventsFunction("MyEventsFunction");
REQUIRE(myEventsFunction.GetParameters().GetParameter(1).GetExtraInfo() ==
"MyEventsExtension::MyRenamedEventsBasedObject");
@@ -3366,6 +3597,54 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
"MyExtension::GetVariableAsNumber(MyVariable.MyChild[MyRenamedProperty])");
}
SECTION("(Events based behavior) property renamed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedBehavior =
eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior");
auto &behaviorAction =
eventsBasedBehavior.GetEventsFunctions().InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
eventsExtension, eventsBasedBehavior);
auto &instruction = CreateNumberVariableSetterAction(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
project, eventsExtension, eventsBasedBehavior, "MyProperty",
"MyRenamedProperty");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedProperty");
}
SECTION("(Events based behavior) property renamed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedBehavior =
eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior");
auto &behaviorAction =
eventsBasedBehavior.GetEventsFunctions().InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
eventsExtension, eventsBasedBehavior);
auto &instruction = CreateNumberVariableGetterCondition(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::RenameEventsBasedBehaviorProperty(
project, eventsExtension, eventsBasedBehavior, "MyProperty",
"MyRenamedProperty");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedProperty");
}
SECTION("(Events based behavior) property not renamed (in variable parameter)") {
gd::Project project;
gd::Platform platform;
@@ -3397,6 +3676,52 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
"MyExtension::GetVariableAsNumber(MyProperty)");
}
SECTION("(Events based behavior) property type changed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedBehavior =
eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior");
auto &behaviorAction =
eventsBasedBehavior.GetEventsFunctions().InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
eventsExtension, eventsBasedBehavior);
// The property was of type "string".
auto &instruction = CreateStringVariableSetterAction(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::ChangeEventsBasedBehaviorPropertyType(
project, eventsExtension, eventsBasedBehavior, "MyProperty");
REQUIRE(instruction.GetType() == "SetNumberVariable");
}
SECTION("(Events based behavior) property type changed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedBehavior =
eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior");
auto &behaviorAction =
eventsBasedBehavior.GetEventsFunctions().InsertNewEventsFunction(
"MyBehaviorEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureBehaviorEventsFunctionsProperParameters(
eventsExtension, eventsBasedBehavior);
// The property was of type "string".
auto &instruction = CreateStringVariableGetterCondition(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::ChangeEventsBasedBehaviorPropertyType(
project, eventsExtension, eventsBasedBehavior, "MyProperty");
REQUIRE(instruction.GetType() == "NumberVariable");
}
SECTION("(Events based behavior) shared property renamed") {
gd::Project project;
gd::Platform platform;
@@ -3536,6 +3861,54 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
"MyExtension::GetVariableAsNumber(MyVariable.MyChild[MyRenamedProperty])");
}
SECTION("(Events based object) property renamed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedObject =
eventsExtension.GetEventsBasedObjects().Get("MyEventsBasedObject");
auto &behaviorAction =
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
eventsExtension, eventsBasedObject);
auto &instruction = CreateNumberVariableSetterAction(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::RenameEventsBasedObjectProperty(
project, eventsExtension, eventsBasedObject, "MyProperty",
"MyRenamedProperty");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedProperty");
}
SECTION("(Events based object) property renamed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedObject =
eventsExtension.GetEventsBasedObjects().Get("MyEventsBasedObject");
auto &behaviorAction =
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
eventsExtension, eventsBasedObject);
auto &instruction = CreateNumberVariableGetterCondition(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::RenameEventsBasedObjectProperty(
project, eventsExtension, eventsBasedObject, "MyProperty",
"MyRenamedProperty");
REQUIRE(instruction.GetParameter(0).GetPlainString() ==
"MyRenamedProperty");
}
SECTION("(Events based object) property not renamed (in variable parameter)") {
gd::Project project;
gd::Platform platform;
@@ -3566,6 +3939,52 @@ TEST_CASE("WholeProjectRefactorer", "[common]") {
REQUIRE(instruction2.GetParameter(0).GetPlainString() ==
"MyExtension::GetVariableAsNumber(MyProperty)");
}
SECTION("(Events based object) property type changed (in variable setter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedObject =
eventsExtension.GetEventsBasedObjects().Get("MyEventsBasedObject");
auto &behaviorAction =
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
eventsExtension, eventsBasedObject);
// The property was of type "string".
auto &instruction = CreateStringVariableSetterAction(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::ChangeEventsBasedObjectPropertyType(
project, eventsExtension, eventsBasedObject, "MyProperty");
REQUIRE(instruction.GetType() == "SetNumberVariable");
}
SECTION("(Events based object) property type changed (in variable getter)") {
gd::Project project;
gd::Platform platform;
SetupProjectWithDummyPlatform(project, platform);
auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project);
auto &eventsBasedObject =
eventsExtension.GetEventsBasedObjects().Get("MyEventsBasedObject");
auto &behaviorAction =
eventsBasedObject.GetEventsFunctions().InsertNewEventsFunction(
"MyObjectEventsFunction", 0);
gd::WholeProjectRefactorer::EnsureObjectEventsFunctionsProperParameters(
eventsExtension, eventsBasedObject);
// The property was of type "string".
auto &instruction = CreateStringVariableGetterCondition(
project, behaviorAction.GetEvents(), "MyProperty", "123");
gd::WholeProjectRefactorer::ChangeEventsBasedObjectPropertyType(
project, eventsExtension, eventsBasedObject, "MyProperty");
REQUIRE(instruction.GetType() == "NumberVariable");
}
}
// TODO: Check that this works when behaviors are attached to a child-object.
TEST_CASE("WholeProjectRefactorer (FindInvalidRequiredBehaviorProperties)",

View File

@@ -1,15 +1,4 @@
namespace gdjs {
export interface Object3DDataContent {
width: float;
height: float;
depth: float;
}
/** Base parameters for {@link gdjs.RuntimeObject3D} */
export interface Object3DData extends ObjectData {
/** The base parameters of the RuntimeObject3D */
content: Object3DDataContent;
}
const getValidDimensionValue = (value: float | undefined) =>
value === undefined ? 100 : value <= 0 ? 1 : value;
@@ -35,11 +24,8 @@ namespace gdjs {
*/
export abstract class RuntimeObject3D
extends gdjs.RuntimeObject
implements
gdjs.Resizable,
gdjs.Scalable,
gdjs.Flippable,
gdjs.Base3DHandler {
implements gdjs.Resizable, gdjs.Scalable, gdjs.Flippable, gdjs.Base3DHandler
{
/**
* Position on the Z axis.
*/
@@ -84,7 +70,7 @@ namespace gdjs {
constructor(
instanceContainer: gdjs.RuntimeInstanceContainer,
objectData: Object3DData
objectData: gdjs.Object3DData
) {
super(instanceContainer, objectData);
// TODO Should 0 be replaced by 0.01 instead of using the default value?

View File

@@ -117,6 +117,17 @@ namespace gdjs {
getUnrotatedAABBMaxZ(): number;
}
export interface Object3DDataContent {
width: float;
height: float;
depth: float;
}
/** Base parameters for {@link gdjs.RuntimeObject3D} */
export interface Object3DData extends ObjectData {
/** The base parameters of the RuntimeObject3D */
content: Object3DDataContent;
}
export namespace Base3DHandler {
export const is3D = (
object: gdjs.RuntimeObject
@@ -131,7 +142,8 @@ namespace gdjs {
*/
export class Base3DBehavior
extends gdjs.RuntimeBehavior
implements Base3DHandler {
implements Base3DHandler
{
private object: gdjs.RuntimeObject & Base3DHandler;
constructor(

View File

@@ -3,31 +3,31 @@ namespace gdjs {
export interface Cube3DObjectData extends Object3DData {
/** The base parameters of the Cube3D object */
content: Object3DDataContent & {
enableTextureTransparency: boolean;
facesOrientation: 'Y' | 'Z';
enableTextureTransparency: boolean | undefined;
facesOrientation: 'Y' | 'Z' | undefined;
frontFaceResourceName: string;
backFaceResourceName: string;
backFaceUpThroughWhichAxisRotation: 'X' | 'Y';
backFaceUpThroughWhichAxisRotation: 'X' | 'Y' | undefined;
leftFaceResourceName: string;
rightFaceResourceName: string;
topFaceResourceName: string;
bottomFaceResourceName: string;
frontFaceResourceRepeat: boolean;
backFaceResourceRepeat: boolean;
leftFaceResourceRepeat: boolean;
rightFaceResourceRepeat: boolean;
topFaceResourceRepeat: boolean;
bottomFaceResourceRepeat: boolean;
frontFaceResourceRepeat: boolean | undefined;
backFaceResourceRepeat: boolean | undefined;
leftFaceResourceRepeat: boolean | undefined;
rightFaceResourceRepeat: boolean | undefined;
topFaceResourceRepeat: boolean | undefined;
bottomFaceResourceRepeat: boolean | undefined;
frontFaceVisible: boolean;
backFaceVisible: boolean;
leftFaceVisible: boolean;
rightFaceVisible: boolean;
topFaceVisible: boolean;
bottomFaceVisible: boolean;
tint: string | undefined;
materialType: 'Basic' | 'StandardWithoutMetalness';
};
}
type FaceName = 'front' | 'back' | 'left' | 'right' | 'top' | 'bottom';
const faceNameToBitmaskIndex = {
front: 0,
@@ -45,6 +45,7 @@ namespace gdjs {
trfb: integer;
frn: [string, string, string, string, string, string];
mt: number;
tint: string;
};
type Cube3DObjectNetworkSyncData = Object3DNetworkSyncData &
@@ -67,10 +68,11 @@ namespace gdjs {
string,
string,
string,
string
string,
];
_materialType: gdjs.Cube3DRuntimeObject.MaterialType =
gdjs.Cube3DRuntimeObject.MaterialType.Basic;
_tint: string;
constructor(
instanceContainer: gdjs.RuntimeInstanceContainer,
@@ -117,6 +119,9 @@ namespace gdjs {
objectData.content.topFaceResourceName,
objectData.content.bottomFaceResourceName,
];
this._tint = objectData.content.tint || '255;255;255';
this._materialType = this._convertMaterialType(
objectData.content.materialType
);
@@ -134,7 +139,7 @@ namespace gdjs {
* Sets the visibility of a face of the 3D box.
*
* @param faceName - The name of the face to set visibility for.
* @param value - The visibility value to set.
* @param enable - The visibility value to set.
*/
setFaceVisibility(faceName: FaceName, enable: boolean) {
const faceIndex = faceNameToBitmaskIndex[faceName];
@@ -157,7 +162,7 @@ namespace gdjs {
* Sets the texture repeat of a face of the 3D box.
*
* @param faceName - The name of the face to set visibility for.
* @param value - The visibility value to set.
* @param enable - The visibility value to set.
*/
setRepeatTextureOnFace(faceName: FaceName, enable: boolean) {
const faceIndex = faceNameToBitmaskIndex[faceName];
@@ -203,11 +208,22 @@ namespace gdjs {
if (this._faceResourceNames[faceIndex] === resourceName) {
return;
}
this._faceResourceNames[faceIndex] = resourceName;
this._renderer.updateFace(faceIndex);
}
setColor(tint: string): void {
if (this._tint === tint) {
return;
}
this._tint = tint;
this._renderer.updateTint();
}
getColor(): string {
return this._tint;
}
/** @internal */
getFaceAtIndexResourceName(faceIndex: integer): string {
return this._faceResourceNames[faceIndex];
@@ -291,6 +307,10 @@ namespace gdjs {
newObjectData.content.frontFaceResourceName
);
}
if (oldObjectData.content.tint !== newObjectData.content.tint) {
this.setColor(newObjectData.content.tint || '255;255;255');
}
if (
oldObjectData.content.backFaceResourceName !==
newObjectData.content.backFaceResourceName
@@ -342,7 +362,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'front',
newObjectData.content.frontFaceResourceRepeat
newObjectData.content.frontFaceResourceRepeat || false
);
}
if (
@@ -351,7 +371,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'back',
newObjectData.content.backFaceResourceRepeat
newObjectData.content.backFaceResourceRepeat || false
);
}
if (
@@ -360,7 +380,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'left',
newObjectData.content.leftFaceResourceRepeat
newObjectData.content.leftFaceResourceRepeat || false
);
}
if (
@@ -369,7 +389,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'right',
newObjectData.content.rightFaceResourceRepeat
newObjectData.content.rightFaceResourceRepeat || false
);
}
if (
@@ -378,7 +398,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'top',
newObjectData.content.topFaceResourceRepeat
newObjectData.content.topFaceResourceRepeat || false
);
}
if (
@@ -387,7 +407,7 @@ namespace gdjs {
) {
this.setRepeatTextureOnFace(
'bottom',
newObjectData.content.bottomFaceResourceRepeat
newObjectData.content.bottomFaceResourceRepeat || false
);
}
if (
@@ -395,14 +415,14 @@ namespace gdjs {
newObjectData.content.backFaceUpThroughWhichAxisRotation
) {
this.setBackFaceUpThroughWhichAxisRotation(
newObjectData.content.backFaceUpThroughWhichAxisRotation
newObjectData.content.backFaceUpThroughWhichAxisRotation || 'X'
);
}
if (
oldObjectData.content.facesOrientation !==
newObjectData.content.facesOrientation
) {
this.setFacesOrientation(newObjectData.content.facesOrientation);
this.setFacesOrientation(newObjectData.content.facesOrientation || 'Y');
}
if (
oldObjectData.content.materialType !==
@@ -423,6 +443,7 @@ namespace gdjs {
vfb: this._visibleFacesBitmask,
trfb: this._textureRepeatFacesBitmask,
frn: this._faceResourceNames,
tint: this._tint,
};
}
@@ -476,6 +497,12 @@ namespace gdjs {
}
}
}
if (networkSyncData.tint !== undefined) {
if (this._tint !== networkSyncData.tint) {
this._tint = networkSyncData.tint;
this._renderer.updateTint();
}
}
}
/**

View File

@@ -74,15 +74,13 @@ namespace gdjs {
instanceContainer: gdjs.RuntimeInstanceContainer
) {
const geometry = new THREE.BoxGeometry(1, 1, 1);
// TODO (3D) - feature: support color instead of texture?
const materials = [
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[0]),
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[1]),
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[2]),
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[3]),
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[4]),
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[5]),
];
const materials: THREE.Material[] = new Array(6)
.fill(0)
.map((_, index) =>
getFaceMaterial(runtimeObject, materialIndexToFaceIndex[index])
);
const boxMesh = new THREE.Mesh(geometry, materials);
super(runtimeObject, instanceContainer, boxMesh);
@@ -92,6 +90,28 @@ namespace gdjs {
this.updateSize();
this.updatePosition();
this.updateRotation();
this.updateTint();
}
updateTint() {
const tints: number[] = [];
const normalizedTint = gdjs
.rgbOrHexToRGBColor(this._cube3DRuntimeObject.getColor())
.map((component) => component / 255);
for (
let i = 0;
i < this._boxMesh.geometry.attributes.position.count;
i++
) {
tints.push(...normalizedTint);
}
this._boxMesh.geometry.setAttribute(
'color',
new THREE.BufferAttribute(new Float32Array(tints), 3)
);
}
updateFace(faceIndex: integer) {
@@ -121,13 +141,11 @@ namespace gdjs {
*/
updateTextureUvMapping(faceIndex?: number) {
// @ts-ignore - position is stored as a Float32BufferAttribute
const pos: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute(
'position'
);
const pos: THREE.BufferAttribute =
this._boxMesh.geometry.getAttribute('position');
// @ts-ignore - uv is stored as a Float32BufferAttribute
const uvMapping: THREE.BufferAttribute = this._boxMesh.geometry.getAttribute(
'uv'
);
const uvMapping: THREE.BufferAttribute =
this._boxMesh.geometry.getAttribute('uv');
const startIndex =
faceIndex === undefined ? 0 : faceIndexToMaterialIndex[faceIndex] * 4;
const endIndex =
@@ -149,9 +167,10 @@ namespace gdjs {
continue;
}
const shouldRepeatTexture = this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex(
materialIndexToFaceIndex[materialIndex]
);
const shouldRepeatTexture =
this._cube3DRuntimeObject.shouldRepeatTextureOnFaceAtIndex(
materialIndexToFaceIndex[materialIndex]
);
const shouldOrientateFacesTowardsY =
this._cube3DRuntimeObject.getFacesOrientation() === 'Y';
@@ -180,12 +199,10 @@ namespace gdjs {
if (shouldOrientateFacesTowardsY) {
[x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
} else {
[
x,
y,
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
}
}
break;
@@ -211,12 +228,10 @@ namespace gdjs {
if (shouldOrientateFacesTowardsY) {
[x, y] = noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
} else {
[
x,
y,
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
x = -x;
y = -y;
}

View File

@@ -1,21 +1,11 @@
namespace gdjs {
export interface Object3DDataContent {
width: float;
height: float;
depth: float;
}
/** Base parameters for {@link gdjs.RuntimeObject3D} */
export interface Object3DData extends ObjectData {
/** The base parameters of the RuntimeObject3D */
content: Object3DDataContent;
}
/**
* Base class for 3D custom objects.
*/
export class CustomRuntimeObject3D
extends gdjs.CustomRuntimeObject
implements gdjs.Base3DHandler {
implements gdjs.Base3DHandler
{
/**
* Position on the Z axis.
*/
@@ -41,13 +31,13 @@ namespace gdjs {
constructor(
parent: gdjs.RuntimeInstanceContainer,
objectData: Object3DData & CustomObjectConfiguration
objectData: gdjs.Object3DData & gdjs.CustomObjectConfiguration
) {
super(parent, objectData);
this._renderer.reinitialize(this, parent);
}
protected _createRender() {
protected override _createRender() {
const parent = this._runtimeScene;
return new gdjs.CustomRuntimeObject3DRenderer(
this,
@@ -56,21 +46,23 @@ namespace gdjs {
);
}
protected _reinitializeRenderer(): void {
protected override _reinitializeRenderer(): void {
this.getRenderer().reinitialize(this, this.getParent());
}
getRenderer(): gdjs.CustomRuntimeObject3DRenderer {
override getRenderer(): gdjs.CustomRuntimeObject3DRenderer {
return super.getRenderer() as gdjs.CustomRuntimeObject3DRenderer;
}
get3DRendererObject() {
override get3DRendererObject() {
// It can't be null because Three.js is always loaded
// when a custom 3D object is used.
return this.getRenderer().get3DRendererObject()!;
}
extraInitializationFromInitialInstance(initialInstanceData: InstanceData) {
override extraInitializationFromInitialInstance(
initialInstanceData: InstanceData
) {
super.extraInitializationFromInitialInstance(initialInstanceData);
if (initialInstanceData.depth !== undefined) {
this.setDepth(initialInstanceData.depth);
@@ -292,7 +284,7 @@ namespace gdjs {
return this._maxZ - this._minZ;
}
_updateUntransformedHitBoxes(): void {
override _updateUntransformedHitBoxes(): void {
super._updateUntransformedHitBoxes();
let minZ = Number.MAX_VALUE;

View File

@@ -6,7 +6,8 @@ namespace gdjs {
* The renderer for a {@link gdjs.CustomRuntimeObject3D} using Three.js.
*/
export class CustomRuntimeObject3DRenderer
implements gdjs.RuntimeInstanceContainerRenderer {
implements gdjs.RuntimeInstanceContainerRenderer
{
_object: gdjs.CustomRuntimeObject3D;
_instanceContainer: gdjs.CustomRuntimeObjectInstanceContainer;
_isContainerDirty: boolean = true;
@@ -139,16 +140,16 @@ namespace gdjs {
imageManager: gdjs.PixiImageManager
): ThreeAnimationFrameTextureManager {
if (!imageManager._threeAnimationFrameTextureManager) {
imageManager._threeAnimationFrameTextureManager = new ThreeAnimationFrameTextureManager(
imageManager
);
imageManager._threeAnimationFrameTextureManager =
new ThreeAnimationFrameTextureManager(imageManager);
}
return imageManager._threeAnimationFrameTextureManager;
}
}
class ThreeAnimationFrameTextureManager
implements gdjs.AnimationFrameTextureManager<THREE.Material> {
implements gdjs.AnimationFrameTextureManager<THREE.Material>
{
private _imageManager: gdjs.PixiImageManager;
constructor(imageManager: gdjs.PixiImageManager) {
@@ -163,16 +164,16 @@ namespace gdjs {
}
getAnimationFrameWidth(material: THREE.Material) {
const map = (material as
| THREE.MeshBasicMaterial
| THREE.MeshStandardMaterial).map;
const map = (
material as THREE.MeshBasicMaterial | THREE.MeshStandardMaterial
).map;
return map ? map.image.width : 0;
}
getAnimationFrameHeight(material: THREE.Material) {
const map = (material as
| THREE.MeshBasicMaterial
| THREE.MeshStandardMaterial).map;
const map = (
material as THREE.MeshBasicMaterial | THREE.MeshStandardMaterial
).map;
return map ? map.image.height : 0;
}
}

View File

@@ -69,7 +69,7 @@ module.exports = {
_('Center Z position'),
_('the Z position of the center of rotation'),
_('the Z position of the center'),
_('Position/Center'),
_('Position Center'),
'res/conditions/3d_box.svg'
)
.addParameter('object', _('3D object'), '', false)
@@ -800,6 +800,20 @@ module.exports = {
.markAsSimple()
.setHidden()
.setFunctionName('hasAnimationEnded');
object
.addScopedAction(
'SetCrossfadeDuration',
_('Set crossfade duration'),
_('Set the crossfade duration when switching to a new animation.'),
_('Set crossfade duration of _PARAM0_ to _PARAM1_ seconds'),
_('Animations and images'),
'res/conditions/animation24.png',
'res/conditions/animation.png'
)
.addParameter('object', _('3D model'), 'Model3DObject', false)
.addParameter('number', _('Crossfade duration (in seconds)'), '', false)
.setFunctionName('setCrossfadeDuration');
}
const Cube3DObject = new gd.ObjectJsImplementation();
@@ -822,7 +836,8 @@ module.exports = {
propertyName === 'bottomFaceResourceName' ||
propertyName === 'backFaceUpThroughWhichAxisRotation' ||
propertyName === 'facesOrientation' ||
propertyName === 'materialType'
propertyName === 'materialType' ||
propertyName === 'tint'
) {
objectContent[propertyName] = newValue;
return true;
@@ -902,6 +917,12 @@ module.exports = {
.setLabel(_('Depth'))
.setMeasurementUnit(gd.MeasurementUnit.getPixel())
.setGroup(_('Default size'));
objectProperties
.getOrCreate('tint')
.setValue(objectContent.tint || '255;255;255')
.setType('Color')
.setLabel(_('Tint'))
.setGroup(_('Texture'));
objectProperties
.getOrCreate('frontFaceResourceName')
@@ -1092,6 +1113,7 @@ module.exports = {
topFaceResourceRepeat: false,
bottomFaceResourceRepeat: false,
materialType: 'Basic',
tint: '255;255;255',
};
Cube3DObject.updateInitialInstanceProperty = function (
@@ -1568,6 +1590,21 @@ module.exports = {
.addParameter('imageResource', _('Image'), '', false)
.setFunctionName('setFaceResourceName');
object
.addScopedAction(
'SetTint',
_('Tint color'),
_('Change the tint of the cube.'),
_('Change the tint of _PARAM0_ to _PARAM1_'),
_('Effects'),
'res/actions/color24.png',
'res/actions/color.png'
)
.addParameter('object', _('3D Cube'), 'Cube3DObject', false)
.addParameter('color', _('Tint'), '', false)
.getCodeExtraInformation()
.setFunctionName('setColor');
extension
.addExpressionAndConditionAndAction(
'number',
@@ -2062,6 +2099,10 @@ module.exports = {
3: [1, 0],
};
/**
* @param {*} objectConfiguration
* @returns {string | null}
*/
const getFirstVisibleFaceResourceName = (objectConfiguration) => {
const object = gd.castObject(
objectConfiguration,
@@ -2090,25 +2131,44 @@ module.exports = {
return null;
};
/** @type {THREE.MeshBasicMaterial | null} */
let transparentMaterial = null;
/**
* @returns {THREE.MeshBasicMaterial}
*/
const getTransparentMaterial = () => {
if (!transparentMaterial)
transparentMaterial = new THREE.MeshBasicMaterial({
transparent: true,
opacity: 0,
// Set the alpha test to to ensure the faces behind are rendered
// (no "back face culling" that would still be done if alphaTest is not set).
alphaTest: 1,
});
return transparentMaterial;
if (transparentMaterial) {
return transparentMaterial;
}
const newTransparentMaterial = new THREE.MeshBasicMaterial({
transparent: true,
opacity: 0,
// Set the alpha test to to ensure the faces behind are rendered
// (no "back face culling" that would still be done if alphaTest is not set).
alphaTest: 1,
});
transparentMaterial = newTransparentMaterial;
return newTransparentMaterial;
};
class RenderedCube3DObject2DInstance extends RenderedInstance {
/** @type {number} */
_defaultWidth;
/** @type {number} */
_defaultHeight;
/** @type {number} */
_defaultDepth;
/** @type {number} */
_centerX = 0;
/** @type {number} */
_centerY = 0;
/**
* The name of the resource that is rendered.
* If no face is visible, this will be null.
* @type {string | null | undefined}
*/
_renderedResourceName = undefined;
_renderFallbackObject = false;
constructor(
project,
@@ -2124,11 +2184,6 @@ module.exports = {
pixiContainer,
pixiResourcesLoader
);
// Name of the resource that is rendered.
// If no face is visible, this will be null.
this._renderedResourceName = undefined;
const object = gd.castObject(
this._associatedObjectConfiguration,
gd.ObjectJsImplementation
@@ -2145,7 +2200,6 @@ module.exports = {
this._pixiObject.addChild(this._pixiTexturedObject);
this._pixiObject.addChild(this._pixiFallbackObject);
this._pixiContainer.addChild(this._pixiObject);
this._renderFallbackObject = false;
this.updateTexture();
}
@@ -2160,9 +2214,10 @@ module.exports = {
}
static getThumbnail(project, resourcesLoader, objectConfiguration) {
const textureResourceName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
objectConfiguration
);
const textureResourceName =
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
objectConfiguration
);
if (textureResourceName) {
return resourcesLoader.getResourceFullUrl(
project,
@@ -2174,18 +2229,20 @@ module.exports = {
}
updateTextureIfNeeded() {
const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
this._associatedObjectConfiguration
);
const textureName =
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
this._associatedObjectConfiguration
);
if (textureName === this._renderedResourceName) return;
this.updateTexture();
}
updateTexture() {
const textureName = RenderedCube3DObject2DInstance._getResourceNameToDisplay(
this._associatedObjectConfiguration
);
const textureName =
RenderedCube3DObject2DInstance._getResourceNameToDisplay(
this._associatedObjectConfiguration
);
if (!textureName) {
this._renderFallbackObject = true;
@@ -2308,6 +2365,17 @@ module.exports = {
}
class RenderedCube3DObject3DInstance extends Rendered3DInstance {
_defaultWidth = 1;
_defaultHeight = 1;
_defaultDepth = 1;
_faceResourceNames = new Array(6).fill(null);
_faceVisibilities = new Array(6).fill(null);
_shouldRepeatTextureOnFace = new Array(6).fill(null);
_facesOrientation = 'Y';
_backFaceUpThroughWhichAxisRotation = 'X';
_shouldUseTransparentTexture = false;
_tint = '';
constructor(
project,
instance,
@@ -2324,21 +2392,9 @@ module.exports = {
threeGroup,
pixiResourcesLoader
);
this._defaultWidth = 1;
this._defaultHeight = 1;
this._defaultDepth = 1;
this._pixiObject = new PIXI.Graphics();
this._pixiContainer.addChild(this._pixiObject);
this._faceResourceNames = ['', '', '', '', '', ''];
this._faceVisibilities = [true, true, true, true, true, true];
this._shouldRepeatTextureOnFace = [true, true, true, true, true, true];
this._facesOrientation = 'Y';
this._backFaceUpThroughWhichAxisRotation = 'X';
this._shouldUseTransparentTexture = false;
const geometry = new THREE.BoxGeometry(1, 1, 1);
const materials = [
getTransparentMaterial(),
@@ -2357,8 +2413,9 @@ module.exports = {
async _updateThreeObjectMaterials() {
const getFaceMaterial = async (project, faceIndex) => {
if (!this._faceVisibilities[faceIndex])
if (!this._faceVisibilities[faceIndex]) {
return getTransparentMaterial();
}
return await this._pixiResourcesLoader.getThreeMaterial(
project,
@@ -2389,11 +2446,35 @@ module.exports = {
this._updateTextureUvMapping();
}
_updateTint() {
const tints = [];
const normalizedTint = objectsRenderingService
.hexNumberToRGBArray(
objectsRenderingService.rgbOrHexToHexNumber(this._tint)
)
.map((component) => component / 255);
for (
let i = 0;
i < this._threeObject.geometry.attributes.position.count;
i++
) {
tints.push(...normalizedTint);
}
this._threeObject.geometry.setAttribute(
'color',
new THREE.BufferAttribute(new Float32Array(tints), 3)
);
}
static _getResourceNameToDisplay(objectConfiguration) {
return getFirstVisibleFaceResourceName(objectConfiguration);
}
updateThreeObject() {
/** @type {gdjs.Cube3DObjectData} */
//@ts-ignore This works because the properties are set to `content` in JavaScript.
const object = gd.castObject(
this._associatedObjectConfiguration,
gd.ObjectJsImplementation
@@ -2421,13 +2502,19 @@ module.exports = {
let materialsDirty = false;
let uvMappingDirty = false;
let tintDirty = false;
const shouldUseTransparentTexture =
object.content.enableTextureTransparency;
object.content.enableTextureTransparency || false;
if (this._shouldUseTransparentTexture !== shouldUseTransparentTexture) {
this._shouldUseTransparentTexture = shouldUseTransparentTexture;
materialsDirty = true;
}
const tint = object.content.tint || '255;255;255';
if (this._tint !== tint) {
this._tint = tint;
tintDirty = true;
}
const faceResourceNames = [
object.content.frontFaceResourceName,
@@ -2471,12 +2558,12 @@ module.exports = {
}
const shouldRepeatTextureOnFace = [
object.content.frontFaceResourceRepeat,
object.content.backFaceResourceRepeat,
object.content.leftFaceResourceRepeat,
object.content.rightFaceResourceRepeat,
object.content.topFaceResourceRepeat,
object.content.bottomFaceResourceRepeat,
object.content.frontFaceResourceRepeat || false,
object.content.backFaceResourceRepeat || false,
object.content.leftFaceResourceRepeat || false,
object.content.rightFaceResourceRepeat || false,
object.content.topFaceResourceRepeat || false,
object.content.bottomFaceResourceRepeat || false,
];
if (
this._shouldRepeatTextureOnFace[0] !== shouldRepeatTextureOnFace[0] ||
@@ -2491,16 +2578,17 @@ module.exports = {
}
const backFaceUpThroughWhichAxisRotation =
object.content.backFaceUpThroughWhichAxisRotation;
object.content.backFaceUpThroughWhichAxisRotation || 'X';
if (
backFaceUpThroughWhichAxisRotation !==
this._backFaceUpThroughWhichAxisRotation
) {
this._backFaceUpThroughWhichAxisRotation = backFaceUpThroughWhichAxisRotation;
this._backFaceUpThroughWhichAxisRotation =
backFaceUpThroughWhichAxisRotation;
uvMappingDirty = true;
}
const facesOrientation = object.content.facesOrientation;
const facesOrientation = object.content.facesOrientation || 'Y';
if (facesOrientation !== this._facesOrientation) {
this._facesOrientation = facesOrientation;
uvMappingDirty = true;
@@ -2520,6 +2608,7 @@ module.exports = {
if (materialsDirty) this._updateThreeObjectMaterials();
if (uvMappingDirty) this._updateTextureUvMapping();
if (tintDirty) this._updateTint();
}
/**
@@ -2529,11 +2618,11 @@ module.exports = {
* for the method to work.
*/
_updateTextureUvMapping() {
/** @type {THREE.BufferAttribute} */
// @ts-ignore - position is stored as a Float32BufferAttribute
/** @type {THREE.BufferAttribute} */
const pos = this._threeObject.geometry.getAttribute('position');
// @ts-ignore - uv is stored as a Float32BufferAttribute
/** @type {THREE.BufferAttribute} */
// @ts-ignore - uv is stored as a Float32BufferAttribute
const uvMapping = this._threeObject.geometry.getAttribute('uv');
const startIndex = 0;
const endIndex = 23;
@@ -2552,9 +2641,10 @@ module.exports = {
continue;
}
const shouldRepeatTexture = this._shouldRepeatTextureOnFace[
materialIndexToFaceIndex[materialIndex]
];
const shouldRepeatTexture =
this._shouldRepeatTextureOnFace[
materialIndexToFaceIndex[materialIndex]
];
const shouldOrientateFacesTowardsY = this._facesOrientation === 'Y';
@@ -2589,16 +2679,13 @@ module.exports = {
}
} else {
if (shouldOrientateFacesTowardsY) {
[x, y] = noRepeatTextureVertexIndexToUvMapping[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
} else {
[
x,
y,
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
}
}
break;
@@ -2628,16 +2715,13 @@ module.exports = {
}
} else {
if (shouldOrientateFacesTowardsY) {
[x, y] = noRepeatTextureVertexIndexToUvMapping[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMapping[vertexIndex % 4];
} else {
[
x,
y,
] = noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
[x, y] =
noRepeatTextureVertexIndexToUvMappingForLeftAndRightFacesTowardsZ[
vertexIndex % 4
];
x = -x;
y = -y;
}
@@ -2786,6 +2870,19 @@ module.exports = {
const epsilon = 1 / (1 << 16);
class Model3DRendered2DInstance extends RenderedInstance {
/** @type {number} */
_defaultWidth;
/** @type {number} */
_defaultHeight;
/** @type {number} */
_defaultDepth;
/** @type {[number, number, number] | null} */
_originPoint;
/** @type {[number, number, number] | null} */
_centerPoint;
/** @type {[number, number, number]} */
_modelOriginPoint = [0, 0, 0];
constructor(
@@ -3028,10 +3125,15 @@ module.exports = {
}
}
/**
* @param {[number, number, number] | null} point1
* @param {[number, number, number] | null} point2
* @returns {boolean}
*/
const isSamePoint = (point1, point2) => {
if (!point1 && !point2) return true;
if (point1 && !point2) return false;
if (!point1 && point2) return false;
if (!!point1 !== !!point2) return false;
// At this point || or && doesn't matter and the type checking prefer ||.
if (!point1 || !point2) return true;
return (
point1[0] === point2[0] &&
point1[1] === point2[1] &&
@@ -3039,6 +3141,10 @@ module.exports = {
);
};
/**
* @param {string} location
* @returns {[number, number, number] | null}
*/
const getPointForLocation = (location) => {
switch (location) {
case 'ModelOrigin':
@@ -3057,8 +3163,27 @@ module.exports = {
};
class Model3DRendered3DInstance extends Rendered3DInstance {
_defaultWidth = 1;
_defaultHeight = 1;
_defaultDepth = 1;
_originalWidth = 1;
_originalHeight = 1;
_originalDepth = 1;
_rotationX = 0;
_rotationY = 0;
_rotationZ = 0;
_keepAspectRatio = false;
/** @type {[number, number, number] | null} */
_originPoint = null;
/** @type {[number, number, number] | null} */
_centerPoint = null;
/** @type {[number, number, number]} */
_modelOriginPoint = [0, 0, 0];
/** @type {THREE.Object3D | null} */
_clonedModel3D = null;
constructor(
project,
instance,
@@ -3076,29 +3201,12 @@ module.exports = {
pixiResourcesLoader
);
this._defaultWidth = 1;
this._defaultHeight = 1;
this._defaultDepth = 1;
this._originalWidth = 1;
this._originalHeight = 1;
this._originalDepth = 1;
this._rotationX = 0;
this._rotationY = 0;
this._rotationZ = 0;
this._keepAspectRatio = false;
this._originPoint = null;
this._centerPoint = null;
this._pixiObject = new PIXI.Graphics();
this._pixiContainer.addChild(this._pixiObject);
this._threeObject = new THREE.Group();
this._threeObject.rotation.order = 'ZYX';
this._threeGroup.add(this._threeObject);
this._threeModelGroup = null;
this._clonedModel3D = null;
}
getOriginX() {
@@ -3140,27 +3248,30 @@ module.exports = {
}
_updateDefaultTransformation() {
if (!this._clonedModel3D) return; // Model is not ready - nothing to do.
if (!this._clonedModel3D) {
// Model is not ready - nothing to do.
return;
}
if (this._threeModelGroup) {
// Remove any previous container as we will recreate it just below
this._threeObject.clear();
}
// This group hold the rotation defined by properties.
// Always restart from a new group to avoid miscomputing bounding boxes/sizes.
this._threeModelGroup = new THREE.Group();
this._threeModelGroup.rotation.order = 'ZYX';
this._threeModelGroup.add(this._clonedModel3D);
const threeModelGroup = new THREE.Group();
this._threeModelGroup = threeModelGroup;
threeModelGroup.rotation.order = 'ZYX';
threeModelGroup.add(this._clonedModel3D);
this._threeModelGroup.rotation.set(
threeModelGroup.rotation.set(
(this._rotationX * Math.PI) / 180,
(this._rotationY * Math.PI) / 180,
(this._rotationZ * Math.PI) / 180
);
this._threeModelGroup.updateMatrixWorld(true);
const boundingBox = new THREE.Box3().setFromObject(
this._threeModelGroup
);
threeModelGroup.updateMatrixWorld(true);
const boundingBox = new THREE.Box3().setFromObject(threeModelGroup);
const shouldKeepModelOrigin = !this._originPoint;
if (shouldKeepModelOrigin) {
@@ -3187,7 +3298,7 @@ module.exports = {
// Center the model.
const centerPoint = this._centerPoint;
if (centerPoint) {
this._threeModelGroup.position.set(
threeModelGroup.position.set(
-(boundingBox.min.x + modelWidth * centerPoint[0]),
// The model is flipped on Y axis.
-(boundingBox.min.y + modelHeight * (1 - centerPoint[1])),
@@ -3196,8 +3307,8 @@ module.exports = {
}
// Rotate the model.
this._threeModelGroup.scale.set(1, 1, 1);
this._threeModelGroup.rotation.set(
threeModelGroup.scale.set(1, 1, 1);
threeModelGroup.rotation.set(
(this._rotationX * Math.PI) / 180,
(this._rotationY * Math.PI) / 180,
(this._rotationZ * Math.PI) / 180
@@ -3212,8 +3323,8 @@ module.exports = {
// Flip on Y because the Y axis is on the opposite side of direct basis.
// It avoids models to be like a mirror refection.
scaleMatrix.makeScale(scaleX, -scaleY, scaleZ);
this._threeModelGroup.updateMatrix();
this._threeModelGroup.applyMatrix4(scaleMatrix);
threeModelGroup.updateMatrix();
threeModelGroup.applyMatrix4(scaleMatrix);
if (this._keepAspectRatio) {
// Reduce the object dimensions to keep aspect ratio.
@@ -3280,7 +3391,7 @@ module.exports = {
this._defaultDepth = this._originalDepth;
}
this._threeObject.add(this._threeModelGroup);
this._threeObject.add(threeModelGroup);
}
updateThreeObject() {

View File

@@ -23,7 +23,7 @@ Model3DObjectConfiguration::Model3DObjectConfiguration()
: width(100), height(100), depth(100), rotationX(0), rotationY(0),
rotationZ(0), modelResourceName(""), materialType("StandardWithoutMetalness"),
originLocation("ModelOrigin"), centerLocation("ModelOrigin"),
keepAspectRatio(true) {}
keepAspectRatio(true), crossfadeDuration(0.1f) {}
bool Model3DObjectConfiguration::UpdateProperty(const gd::String &propertyName,
const gd::String &newValue) {
@@ -71,6 +71,10 @@ bool Model3DObjectConfiguration::UpdateProperty(const gd::String &propertyName,
keepAspectRatio = newValue == "1";
return true;
}
if(propertyName == "crossfadeDuration") {
crossfadeDuration = newValue.To<double>();
return true;
}
return false;
}
@@ -167,6 +171,13 @@ Model3DObjectConfiguration::GetProperties() const {
.SetGroup(_("Points"))
.SetAdvanced(true);
objectProperties["crossfadeDuration"]
.SetValue(gd::String::From(crossfadeDuration))
.SetType("number")
.SetLabel(_("Crossfade duration"))
.SetGroup(_("Animations"))
.SetMeasurementUnit(gd::MeasurementUnit::GetSecond());
return objectProperties;
}
@@ -198,6 +209,7 @@ void Model3DObjectConfiguration::DoUnserializeFrom(
originLocation = content.GetStringAttribute("originLocation");
centerLocation = content.GetStringAttribute("centerLocation");
keepAspectRatio = content.GetBoolAttribute("keepAspectRatio");
crossfadeDuration = content.GetDoubleAttribute("crossfadeDuration");
RemoveAllAnimations();
auto &animationsElement = content.GetChild("animations");
@@ -226,6 +238,7 @@ void Model3DObjectConfiguration::DoSerializeTo(
content.SetAttribute("originLocation", originLocation);
content.SetAttribute("centerLocation", centerLocation);
content.SetAttribute("keepAspectRatio", keepAspectRatio);
content.SetAttribute("crossfadeDuration", crossfadeDuration);
auto &animationsElement = content.AddChild("animations");
animationsElement.ConsiderAsArrayOf("animation");

View File

@@ -152,6 +152,7 @@ public:
double GetRotationX() const { return rotationX; };
double GetRotationY() const { return rotationY; };
double GetRotationZ() const { return rotationZ; };
double GetCrossfadeDuration() const { return crossfadeDuration; };
const gd::String& GetModelResourceName() const { return modelResourceName; };
const gd::String& GetMaterialType() const { return materialType; };
@@ -173,6 +174,7 @@ private:
double rotationX;
double rotationY;
double rotationZ;
double crossfadeDuration;
gd::String modelResourceName;
gd::String materialType;

View File

@@ -9,6 +9,7 @@ namespace gdjs {
ai: integer;
ass: float;
ap: boolean;
cfd: float;
};
type Model3DObjectNetworkSyncData = Object3DNetworkSyncData &
@@ -36,6 +37,7 @@ namespace gdjs {
| 'BottomCenterZ'
| 'BottomCenterY';
animations: Model3DAnimation[];
crossfadeDuration: float;
};
}
@@ -63,7 +65,8 @@ namespace gdjs {
*/
export class Model3DRuntimeObject
extends gdjs.RuntimeObject3D
implements gdjs.Animatable {
implements gdjs.Animatable
{
_renderer: gdjs.Model3DRuntimeObjectRenderer;
_modelResourceName: string;
@@ -97,6 +100,7 @@ namespace gdjs {
_currentAnimationIndex: integer = 0;
_animationSpeedScale: float = 1;
_animationPaused: boolean = false;
_crossfadeDuration: float = 0;
constructor(
instanceContainer: gdjs.RuntimeInstanceContainer,
@@ -121,6 +125,8 @@ namespace gdjs {
this.onModelChanged(objectData);
this._crossfadeDuration = objectData.content.crossfadeDuration || 0;
// *ALWAYS* call `this.onCreated()` at the very end of your object constructor.
this.onCreated();
}
@@ -202,6 +208,7 @@ namespace gdjs {
ai: this._currentAnimationIndex,
ass: this._animationSpeedScale,
ap: this._animationPaused,
cfd: this._crossfadeDuration,
};
}
@@ -233,6 +240,9 @@ namespace gdjs {
networkSyncData.ap ? this.pauseAnimation() : this.resumeAnimation();
}
}
if (networkSyncData.cfd !== undefined) {
this._crossfadeDuration = networkSyncData.cfd;
}
}
_reloadModel(objectData: Model3DObjectData) {
@@ -348,6 +358,11 @@ namespace gdjs {
return this._renderer.hasAnimationEnded();
}
setCrossfadeDuration(duration: number): void {
if (this._crossfadeDuration === duration) return;
this._crossfadeDuration = duration;
}
isAnimationPaused() {
return this._animationPaused;
}

View File

@@ -359,7 +359,6 @@ namespace gdjs {
}
playAnimation(animationName: string, shouldLoop: boolean) {
this._animationMixer.stopAllAction();
const clip = THREE.AnimationClip.findByName(
this._originalModel.animations,
animationName
@@ -370,12 +369,22 @@ namespace gdjs {
);
return;
}
const previousAction = this._action;
this._action = this._animationMixer.clipAction(clip);
this._action.setLoop(
shouldLoop ? THREE.LoopRepeat : THREE.LoopOnce,
Number.POSITIVE_INFINITY
);
this._action.clampWhenFinished = true;
if (previousAction && previousAction !== this._action) {
this._action.enabled = true;
this._action.crossFadeFrom(
previousAction,
this._model3DRuntimeObject._crossfadeDuration,
false
);
}
this._action.play();
// Make sure the first frame is displayed.
this._animationMixer.update(0);

View File

@@ -38,7 +38,7 @@ module.exports = {
.setName('Consent Cordova plugin')
.setDependencyType('cordova')
.setExportName('cordova-plugin-consent')
.setVersion('3.0.0-alpha.8')
.setVersion('3.0.0-alpha.9')
.onlyIfOtherDependencyIsExported('AdMob Cordova plugin');
extension
@@ -93,6 +93,68 @@ module.exports = {
.setIncludeFile('Extensions/AdMob/admobtools.js')
.setFunctionName('gdjs.adMob.setTestMode');
extension
.addAction(
'PreventAdmobAutoInitialization',
_('Prevent AdMob auto initialization'),
_(
'Prevent AdMob from initializing automatically. You will need to call "Initialize AdMob" action manually.\n' +
'This is useful if you want to control when the consent dialog will be shown (for example, after the user has accepted your game terms).'
),
_('Prevent AdMob auto initialization'),
'',
'JsPlatform/Extensions/admobicon24.png',
'JsPlatform/Extensions/admobicon16.png'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/AdMob/admobtools.js')
.setFunctionName('gdjs.adMob.preventAdmobAutoInitialization');
extension
.addAction(
'InitializeAdmob',
_('Initialize AdMob manually'),
_(
'Initialize AdMob manually. This will trigger the consent dialog if needed, and then load the ads.\n' +
'Use this action if you have disabled the auto init and want to control when the consent dialog will be shown.'
),
_('Initialize AdMob'),
'',
'JsPlatform/Extensions/admobicon24.png',
'JsPlatform/Extensions/admobicon16.png'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/AdMob/admobtools.js')
.setFunctionName('gdjs.adMob.initializeAdmob');
extension
.addCondition(
'AdmobInitializing',
_('AdMob initializing'),
_('Check if AdMob is initializing.'),
_('AdMob is initializing'),
'',
'JsPlatform/Extensions/admobicon24.png',
'JsPlatform/Extensions/admobicon16.png'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/AdMob/admobtools.js')
.setFunctionName('gdjs.adMob.isAdmobInitializing');
extension
.addCondition(
'AdmobInitialized',
_('AdMob initialized'),
_('Check if AdMob has been initialized.'),
_('AdMob has been initialized'),
'',
'JsPlatform/Extensions/admobicon24.png',
'JsPlatform/Extensions/admobicon16.png'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/AdMob/admobtools.js')
.setFunctionName('gdjs.adMob.isAdmobInitialized');
// App Open
extension
.addCondition(

View File

@@ -1,6 +1,7 @@
namespace gdjs {
declare var admob: any;
declare var cordova: any;
declare var consent: any;
export namespace adMob {
const logger = new gdjs.Logger('AdMob');
@@ -108,26 +109,119 @@ namespace gdjs {
let rewardedVideoRewardReceived = false; // Becomes true when the video is closed and the reward is received.
let rewardedVideoErrored = false; // Becomes true when the video fails to load.
let npaValue = '0'; // TODO: expose an API to change this and also an automatic way using the consent SDK.
let npaValue = '0'; // 0 means that the user has consented to personalized ads, 1 means that the user has not consented to personalized ads.
let setupTimeoutId: NodeJS.Timeout | null = null;
const askForConsentAndInitializeAdmob = async () => {
if (admobStarted) {
logger.warn('AdMob is already started.');
return;
}
if (isStarting) {
logger.warn('AdMob is already starting.');
return;
}
try {
logger.info('Starting AdMob.');
isStarting = true;
if (cordova.platformId === 'ios') {
try {
/*
trackingStatus:
0 = notDetermined
1 = restricted
2 = denied
3 = authorized
*/
let trackingStatus = await consent.trackingAuthorizationStatus();
// If tracking is not determined, we ask the user for tracking authorization.
if (trackingStatus === 0) {
trackingStatus = await consent.requestTrackingAuthorization();
}
// If tracking is restricted or denied, we set npaValue to 1.
if (trackingStatus === 1 || trackingStatus === 2) {
npaValue = '1';
}
// otherwise, we set npaValue to 0.
npaValue = '0';
} catch (error) {
logger.error(
'Error while asking for tracking authorization, continuing:',
error
);
}
}
try {
// ConsentStatus:
// Unknown = 0,
// Required = 1,
// NotRequired = 2,
// Obtained = 3,
const consentStatus = await consent.getConsentStatus();
if (consentStatus === consent.ConsentStatus.Required) {
await consent.requestInfoUpdate();
}
await consent.loadAndShowIfRequired();
} catch (error) {
logger.error('Error while asking for consent, continuing:', error);
}
// We should be looking at canRequestAds to know if we can request ads or not.
// But as we want to be able to test ads in debug or if the consent didn't work,
// we ignore this value for now.
// const canRequestAds = await consent.canRequestAds();
if (true) {
await admob.start();
logger.info('AdMob successfully started.');
isStarting = false;
admobStarted = true;
}
} catch (error) {
logger.error('Error while starting AdMob:', error);
isStarting = false;
admobStarted = false;
}
};
// Admob initialization listener
document.addEventListener(
'deviceready',
async () => {
// Obtain user consent ?
logger.info('Starting AdMob.');
isStarting = true;
await admob.start();
logger.info('AdMob successfully started.');
isStarting = false;
admobStarted = true;
setupTimeoutId = setTimeout(async () => {
isStarting = false; // Reset to false, as it will be set to true in askForConsentAndInitializeAdmob.
await askForConsentAndInitializeAdmob();
// Wait a bit before starting admob, to avoid the consent appearing too soon.
}, 2000);
},
false
);
export const preventAdmobAutoInitialization = () => {
if (setupTimeoutId) {
isStarting = false;
clearTimeout(setupTimeoutId);
setupTimeoutId = null;
}
};
export const initializeAdmob = async () => {
preventAdmobAutoInitialization();
await askForConsentAndInitializeAdmob();
};
export const isAdmobInitialized = () => admobStarted;
export const isAdmobInitializing = () => isStarting;
/**
* Helper to know if we are on mobile and admob is correctly initialized.
*/
@@ -334,6 +428,7 @@ namespace gdjs {
position: atTop ? 'top' : 'bottom',
size: bannerRequestedAdSizeType,
offset: 0,
npa: npaValue,
});
banner.on('load', () => {

View File

@@ -1,10 +1,10 @@
namespace gdjs {
/**
* Tools to manipulate the game window positioning and
* interactions with the operating system.
* @author arthuro555
*/
export namespace evtTools {
/**
* Tools to manipulate the game window positioning and
* interactions with the operating system.
* @author arthuro555
*/
export namespace advancedWindow {
const getElectronBrowserWindow = (runtimeScene: gdjs.RuntimeScene) => {
try {

View File

@@ -20,25 +20,41 @@ namespace gdjs {
}
export class AnchorRuntimeBehavior extends gdjs.RuntimeBehavior {
_relativeToOriginalWindowSize: any;
// Configuration
_relativeToOriginalWindowSize: boolean;
_leftEdgeAnchor: HorizontalAnchor;
_rightEdgeAnchor: HorizontalAnchor;
_topEdgeAnchor: any;
_bottomEdgeAnchor: any;
_invalidDistances: boolean = true;
_leftEdgeDistance: number = 0;
_rightEdgeDistance: number = 0;
_topEdgeDistance: number = 0;
_bottomEdgeDistance: number = 0;
_topEdgeAnchor: VerticalAnchor;
_bottomEdgeAnchor: VerticalAnchor;
_useLegacyBottomAndRightAnchors: boolean = false;
// State
_hasJustBeenCreated: boolean = true;
_leftEdgeDistance: float = 0;
_rightEdgeDistance: float = 0;
_topEdgeDistance: float = 0;
_bottomEdgeDistance: float = 0;
_oldDrawableX: float = 0;
_oldDrawableY: float = 0;
_oldWidth: float = 0;
_oldHeight: float = 0;
_parentOldMinX: float = 0;
_parentOldMinY: float = 0;
_parentOldMaxX: float = 0;
_parentOldMaxY: float = 0;
constructor(
instanceContainer: gdjs.RuntimeInstanceContainer,
behaviorData,
owner: gdjs.RuntimeObject
) {
super(instanceContainer, behaviorData, owner);
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
this._relativeToOriginalWindowSize =
!!behaviorData.relativeToOriginalWindowSize;
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
this._topEdgeAnchor = behaviorData.topEdgeAnchor;
@@ -80,265 +96,306 @@ namespace gdjs {
return true;
}
onActivate() {
this._invalidDistances = true;
doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {
const objectHasMoved =
this._oldDrawableX !== this.owner.getDrawableX() ||
this._oldDrawableY !== this.owner.getDrawableY() ||
this._oldWidth !== this.owner.getWidth() ||
this._oldHeight !== this.owner.getHeight();
if (objectHasMoved) {
this._updateAnchorDistances(instanceContainer);
}
const parentHasResized =
this._parentOldMinX !== instanceContainer.getUnrotatedViewportMinX() ||
this._parentOldMinY !== instanceContainer.getUnrotatedViewportMinY() ||
this._parentOldMaxX !== instanceContainer.getUnrotatedViewportMaxX() ||
this._parentOldMaxY !== instanceContainer.getUnrotatedViewportMaxY();
if (parentHasResized) {
this._followAnchor(instanceContainer);
}
}
doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {
private _updateAnchorDistances(
instanceContainer: gdjs.RuntimeInstanceContainer
) {
const workingPoint: FloatPoint = gdjs.staticArray(
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents
) as FloatPoint;
let parentMinX = instanceContainer.getUnrotatedViewportMinX();
let parentMinY = instanceContainer.getUnrotatedViewportMinY();
let parentMaxX = instanceContainer.getUnrotatedViewportMaxX();
let parentMaxY = instanceContainer.getUnrotatedViewportMaxY();
let parentCenterX = (parentMaxX + parentMinX) / 2;
let parentCenterY = (parentMaxY + parentMinY) / 2;
let parentWidth = parentMaxX - parentMinX;
let parentHeight = parentMaxY - parentMinY;
const layer = instanceContainer.getLayer(this.owner.getLayer());
if (this._invalidDistances) {
let parentMinX = this._parentOldMinX;
let parentMinY = this._parentOldMinY;
let parentMaxX = this._parentOldMaxX;
let parentMaxY = this._parentOldMaxY;
if (this._hasJustBeenCreated) {
if (this._relativeToOriginalWindowSize) {
parentMinX = instanceContainer.getInitialUnrotatedViewportMinX();
parentMinY = instanceContainer.getInitialUnrotatedViewportMinY();
parentMaxX = instanceContainer.getInitialUnrotatedViewportMaxX();
parentMaxY = instanceContainer.getInitialUnrotatedViewportMaxY();
parentCenterX = (parentMaxX + parentMinX) / 2;
parentCenterY = (parentMaxY + parentMinY) / 2;
parentWidth = parentMaxX - parentMinX;
parentHeight = parentMaxY - parentMinY;
} else {
parentMinX = instanceContainer.getUnrotatedViewportMinX();
parentMinY = instanceContainer.getUnrotatedViewportMinY();
parentMaxX = instanceContainer.getUnrotatedViewportMaxX();
parentMaxY = instanceContainer.getUnrotatedViewportMaxY();
}
}
const parentCenterX = (parentMaxX + parentMinX) / 2;
const parentCenterY = (parentMaxY + parentMinY) / 2;
const parentWidth = parentMaxX - parentMinX;
const parentHeight = parentMaxY - parentMinY;
//Calculate the distances from the window's bounds.
const topLeftPixel = this._relativeToOriginalWindowSize
? [this.owner.getDrawableX(), this.owner.getDrawableY()]
: this._convertInverseCoords(
instanceContainer,
layer,
this.owner.getDrawableX(),
this.owner.getDrawableY(),
workingPoint
);
//Calculate the distances from the window's bounds.
const topLeftPixel = this._relativeToOriginalWindowSize
? [this.owner.getDrawableX(), this.owner.getDrawableY()]
: this._convertInverseCoords(
instanceContainer,
layer,
this.owner.getDrawableX(),
this.owner.getDrawableY(),
workingPoint
);
// Left edge
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
this._leftEdgeDistance = topLeftPixel[0] - parentMinX;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
this._leftEdgeDistance = topLeftPixel[0] - parentMaxX;
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
this._leftEdgeDistance = (topLeftPixel[0] - parentMinX) / parentWidth;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
this._leftEdgeDistance = topLeftPixel[0] - parentCenterX;
// Left edge
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
this._leftEdgeDistance = topLeftPixel[0] - parentMinX;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
this._leftEdgeDistance = topLeftPixel[0] - parentMaxX;
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
this._leftEdgeDistance = (topLeftPixel[0] - parentMinX) / parentWidth;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
this._leftEdgeDistance = topLeftPixel[0] - parentCenterX;
}
// Top edge
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
this._topEdgeDistance = topLeftPixel[1] - parentMinY;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
this._topEdgeDistance = topLeftPixel[1] - parentMaxY;
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
this._topEdgeDistance = (topLeftPixel[1] - parentMinY) / parentHeight;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
this._topEdgeDistance = topLeftPixel[1] - parentCenterY;
}
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const bottomRightPixel = this._relativeToOriginalWindowSize
? [
this.owner.getDrawableX() + this.owner.getWidth(),
this.owner.getDrawableY() + this.owner.getHeight(),
]
: this._convertInverseCoords(
instanceContainer,
layer,
this.owner.getDrawableX() + this.owner.getWidth(),
this.owner.getDrawableY() + this.owner.getHeight(),
workingPoint
);
// Right edge
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
this._rightEdgeDistance = bottomRightPixel[0] - parentMinX;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
this._rightEdgeDistance = bottomRightPixel[0] - parentMaxX;
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
this._rightEdgeDistance =
(bottomRightPixel[0] - parentMinX) / parentWidth;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
this._rightEdgeDistance = bottomRightPixel[0] - parentCenterX;
}
// Bottom edge
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentMinY;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentMaxY;
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
this._bottomEdgeDistance =
(bottomRightPixel[1] - parentMinY) / parentHeight;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentCenterY;
}
this._hasJustBeenCreated = false;
}
private _followAnchor(instanceContainer: gdjs.RuntimeInstanceContainer) {
const workingPoint: FloatPoint = gdjs.staticArray(
gdjs.AnchorRuntimeBehavior.prototype.doStepPreEvents
) as FloatPoint;
const layer = instanceContainer.getLayer(this.owner.getLayer());
let parentMinX = instanceContainer.getUnrotatedViewportMinX();
let parentMinY = instanceContainer.getUnrotatedViewportMinY();
let parentMaxX = instanceContainer.getUnrotatedViewportMaxX();
let parentMaxY = instanceContainer.getUnrotatedViewportMaxY();
const parentCenterX = (parentMaxX + parentMinX) / 2;
const parentCenterY = (parentMaxY + parentMinY) / 2;
const parentWidth = parentMaxX - parentMinX;
const parentHeight = parentMaxY - parentMinY;
//Move and resize the object if needed
let leftPixel = 0;
let topPixel = 0;
let rightPixel = 0;
let bottomPixel = 0;
// Left edge
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
leftPixel = parentMinX + this._leftEdgeDistance;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
leftPixel = parentMaxX + this._leftEdgeDistance;
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
leftPixel = parentMinX + this._leftEdgeDistance * parentWidth;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
leftPixel = parentCenterX + this._leftEdgeDistance;
}
// Top edge
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
topPixel = parentMinY + this._topEdgeDistance;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
topPixel = parentMaxY + this._topEdgeDistance;
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
topPixel = parentMinY + this._topEdgeDistance * parentHeight;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
topPixel = parentCenterY + this._topEdgeDistance;
}
// Right edge
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
rightPixel = parentMinX + this._rightEdgeDistance;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
rightPixel = parentMaxX + this._rightEdgeDistance;
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
rightPixel = parentMinX + this._rightEdgeDistance * parentWidth;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
rightPixel = parentCenterX + this._rightEdgeDistance;
}
// Bottom edge
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
bottomPixel = parentMinY + this._bottomEdgeDistance;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
bottomPixel = parentMaxY + this._bottomEdgeDistance;
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
bottomPixel = parentMinY + this._bottomEdgeDistance * parentHeight;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
bottomPixel = parentCenterY + this._bottomEdgeDistance;
}
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const topLeftCoord = this._convertCoords(
instanceContainer,
layer,
leftPixel,
topPixel,
workingPoint
);
let left = topLeftCoord[0];
let top = topLeftCoord[1];
const bottomRightCoord = this._convertCoords(
instanceContainer,
layer,
rightPixel,
bottomPixel,
workingPoint
);
const right = bottomRightCoord[0];
const bottom = bottomRightCoord[1];
// Compatibility with GD <= 5.0.133
if (this._useLegacyBottomAndRightAnchors) {
//Move and resize the object according to the anchors
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setWidth(right - left);
}
// Top edge
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
this._topEdgeDistance = topLeftPixel[1] - parentMinY;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
this._topEdgeDistance = topLeftPixel[1] - parentMaxY;
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
this._topEdgeDistance = (topLeftPixel[1] - parentMinY) / parentHeight;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
this._topEdgeDistance = topLeftPixel[1] - parentCenterY;
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
this.owner.setHeight(bottom - top);
}
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const bottomRightPixel = this._relativeToOriginalWindowSize
? [
this.owner.getDrawableX() + this.owner.getWidth(),
this.owner.getDrawableY() + this.owner.getHeight(),
]
: this._convertInverseCoords(
instanceContainer,
layer,
this.owner.getDrawableX() + this.owner.getWidth(),
this.owner.getDrawableY() + this.owner.getHeight(),
workingPoint
);
// Right edge
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
this._rightEdgeDistance = bottomRightPixel[0] - parentMinX;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
this._rightEdgeDistance = bottomRightPixel[0] - parentMaxX;
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
this._rightEdgeDistance =
(bottomRightPixel[0] - parentMinX) / parentWidth;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
this._rightEdgeDistance = bottomRightPixel[0] - parentCenterX;
if (this._leftEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setX(left + this.owner.getX() - this.owner.getDrawableX());
}
// Bottom edge
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentMinY;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentMaxY;
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
this._bottomEdgeDistance =
(bottomRightPixel[1] - parentMinY) / parentHeight;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
this._bottomEdgeDistance = bottomRightPixel[1] - parentCenterY;
if (this._topEdgeAnchor !== VerticalAnchor.None) {
this.owner.setY(top + this.owner.getY() - this.owner.getDrawableY());
}
this._invalidDistances = false;
} else {
//Move and resize the object if needed
let leftPixel = 0;
let topPixel = 0;
let rightPixel = 0;
let bottomPixel = 0;
// Left edge
if (this._leftEdgeAnchor === HorizontalAnchor.WindowLeft) {
leftPixel = parentMinX + this._leftEdgeDistance;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowRight) {
leftPixel = parentMaxX + this._leftEdgeDistance;
} else if (this._leftEdgeAnchor === HorizontalAnchor.Proportional) {
leftPixel = parentMinX + this._leftEdgeDistance * parentWidth;
} else if (this._leftEdgeAnchor === HorizontalAnchor.WindowCenter) {
leftPixel = parentCenterX + this._leftEdgeDistance;
}
// Top edge
if (this._topEdgeAnchor === VerticalAnchor.WindowTop) {
topPixel = parentMinY + this._topEdgeDistance;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowBottom) {
topPixel = parentMaxY + this._topEdgeDistance;
} else if (this._topEdgeAnchor === VerticalAnchor.Proportional) {
topPixel = parentMinY + this._topEdgeDistance * parentHeight;
} else if (this._topEdgeAnchor === VerticalAnchor.WindowCenter) {
topPixel = parentCenterY + this._topEdgeDistance;
}
// Right edge
if (this._rightEdgeAnchor === HorizontalAnchor.WindowLeft) {
rightPixel = parentMinX + this._rightEdgeDistance;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowRight) {
rightPixel = parentMaxX + this._rightEdgeDistance;
} else if (this._rightEdgeAnchor === HorizontalAnchor.Proportional) {
rightPixel = parentMinX + this._rightEdgeDistance * parentWidth;
} else if (this._rightEdgeAnchor === HorizontalAnchor.WindowCenter) {
rightPixel = parentCenterX + this._rightEdgeDistance;
}
// Bottom edge
if (this._bottomEdgeAnchor === VerticalAnchor.WindowTop) {
bottomPixel = parentMinY + this._bottomEdgeDistance;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowBottom) {
bottomPixel = parentMaxY + this._bottomEdgeDistance;
} else if (this._bottomEdgeAnchor === VerticalAnchor.Proportional) {
bottomPixel = parentMinY + this._bottomEdgeDistance * parentHeight;
} else if (this._bottomEdgeAnchor === VerticalAnchor.WindowCenter) {
bottomPixel = parentCenterY + this._bottomEdgeDistance;
}
// It's fine to reuse workingPoint as topLeftPixel is no longer used.
const topLeftCoord = this._convertCoords(
instanceContainer,
layer,
leftPixel,
topPixel,
workingPoint
);
let left = topLeftCoord[0];
let top = topLeftCoord[1];
const bottomRightCoord = this._convertCoords(
instanceContainer,
layer,
rightPixel,
bottomPixel,
workingPoint
);
const right = bottomRightCoord[0];
const bottom = bottomRightCoord[1];
// Compatibility with GD <= 5.0.133
if (this._useLegacyBottomAndRightAnchors) {
//Move and resize the object according to the anchors
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setWidth(right - left);
}
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
this.owner.setHeight(bottom - top);
}
}
// End of compatibility code
else {
// Resize if right and left anchors are set
if (
this._rightEdgeAnchor !== HorizontalAnchor.None &&
this._leftEdgeAnchor !== HorizontalAnchor.None
) {
const width = right - left;
this.owner.setX(
this.owner.getX() === this.owner.getDrawableX()
? left
: // It uses the position of the origin relatively to the object
// size to apply it with the new size.
// This is the same as doing:
// lerp(left, right, (this.owner.getX() - this.owner.getDrawableX() / this.owner.getWidth())
// But, the division is done at the end to avoid rounding errors.
left +
((this.owner.getX() - this.owner.getDrawableX()) * width) /
this.owner.getWidth()
);
this.owner.setWidth(width);
} else {
if (this._leftEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setX(
left + this.owner.getX() - this.owner.getDrawableX()
);
}
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setX(
right +
this.owner.getX() -
this.owner.getDrawableX() -
this.owner.getWidth()
);
}
}
// Resize if top and bottom anchors are set
if (
this._bottomEdgeAnchor !== VerticalAnchor.None &&
this._topEdgeAnchor !== VerticalAnchor.None
) {
const height = bottom - top;
this.owner.setY(
this.owner.getY() === this.owner.getDrawableY()
? top
: top +
((this.owner.getY() - this.owner.getDrawableY()) * height) /
this.owner.getHeight()
);
this.owner.setHeight(height);
} else {
if (this._topEdgeAnchor !== VerticalAnchor.None) {
this.owner.setY(
top + this.owner.getY() - this.owner.getDrawableY()
);
}
}
// End of compatibility code
else {
// Resize if right and left anchors are set
if (
this._rightEdgeAnchor !== HorizontalAnchor.None &&
this._leftEdgeAnchor !== HorizontalAnchor.None
) {
const width = right - left;
this.owner.setX(
this.owner.getX() === this.owner.getDrawableX()
? left
: // It uses the position of the origin relatively to the object
// size to apply it with the new size.
// This is the same as doing:
// lerp(left, right, (this.owner.getX() - this.owner.getDrawableX() / this.owner.getWidth())
// But, the division is done at the end to avoid rounding errors.
left +
((this.owner.getX() - this.owner.getDrawableX()) * width) /
this.owner.getWidth()
);
this.owner.setWidth(width);
} else {
if (this._leftEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setX(
left + this.owner.getX() - this.owner.getDrawableX()
);
}
if (this._rightEdgeAnchor !== HorizontalAnchor.None) {
this.owner.setX(
right +
this.owner.getX() -
this.owner.getDrawableX() -
this.owner.getWidth()
);
}
}
// Resize if top and bottom anchors are set
if (
this._bottomEdgeAnchor !== VerticalAnchor.None &&
this._topEdgeAnchor !== VerticalAnchor.None
) {
const height = bottom - top;
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
this.owner.setY(
this.owner.getY() === this.owner.getDrawableY()
? top
: top +
((this.owner.getY() - this.owner.getDrawableY()) * height) /
this.owner.getHeight()
bottom +
this.owner.getY() -
this.owner.getDrawableY() -
this.owner.getHeight()
);
this.owner.setHeight(height);
} else {
if (this._topEdgeAnchor !== VerticalAnchor.None) {
this.owner.setY(
top + this.owner.getY() - this.owner.getDrawableY()
);
}
if (this._bottomEdgeAnchor !== VerticalAnchor.None) {
this.owner.setY(
bottom +
this.owner.getY() -
this.owner.getDrawableY() -
this.owner.getHeight()
);
}
}
}
this._oldDrawableX = this.owner.getDrawableX();
this._oldDrawableY = this.owner.getDrawableY();
this._oldWidth = this.owner.getWidth();
this._oldHeight = this.owner.getHeight();
this._parentOldMinX = instanceContainer.getUnrotatedViewportMinX();
this._parentOldMinY = instanceContainer.getUnrotatedViewportMinY();
this._parentOldMaxX = instanceContainer.getUnrotatedViewportMaxX();
this._parentOldMaxY = instanceContainer.getUnrotatedViewportMaxY();
}
}

View File

@@ -54,7 +54,7 @@ module.exports = {
objectProperties
.getOrCreate('text')
.setValue(objectContent.text)
.setType('textarea')
.setType('multilinestring')
.setLabel(_('BBCode text'));
objectProperties
@@ -106,8 +106,7 @@ module.exports = {
return objectProperties;
};
objectBBText.content = {
text:
'[b]bold[/b] [i]italic[/i] [size=15]smaller[/size] [font=times]times[/font] font\n[spacing=12]spaced out[/spacing]\n[outline=yellow]outlined[/outline] [shadow=red]DropShadow[/shadow] ',
text: '[b]bold[/b] [i]italic[/i] [size=15]smaller[/size] [font=times]times[/font] font\n[spacing=12]spaced out[/spacing]\n[outline=yellow]outlined[/outline] [shadow=red]DropShadow[/shadow] ',
opacity: 255,
fontSize: 20,
visible: true,
@@ -193,9 +192,10 @@ module.exports = {
parameterType === 'string' ||
parameterType === 'stringWithSelector'
) {
const parameterOptions = gd.ParameterOptions.makeNewOptions().setDescription(
property.paramLabel
);
const parameterOptions =
gd.ParameterOptions.makeNewOptions().setDescription(
property.paramLabel
);
if (property.options) {
parameterOptions.setTypeExtraInfo(
stringifyOptions(property.options)
@@ -245,9 +245,10 @@ module.exports = {
parameterType === 'number' ||
parameterType === 'stringWithSelector'
) {
const parameterOptions = gd.ParameterOptions.makeNewOptions().setDescription(
property.paramLabel
);
const parameterOptions =
gd.ParameterOptions.makeNewOptions().setDescription(
property.paramLabel
);
if (property.options) {
parameterOptions.setTypeExtraInfo(
stringifyOptions(property.options)

View File

@@ -43,7 +43,8 @@ namespace gdjs {
*/
export class BBTextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.OpacityHandler {
implements gdjs.OpacityHandler
{
_opacity: float;
_text: string;

View File

@@ -54,7 +54,7 @@ module.exports = {
objectProperties
.getOrCreate('text')
.setValue(objectContent.text)
.setType('textarea')
.setType('multilinestring')
.setLabel(_('Text'));
objectProperties
@@ -107,8 +107,7 @@ module.exports = {
return objectProperties;
};
bitmapTextObject.content = {
text:
'This text use the default bitmap font.\nUse a custom Bitmap Font to create your own texts.',
text: 'This text use the default bitmap font.\nUse a custom Bitmap Font to create your own texts.',
opacity: 255,
scale: 1,
fontSize: 20,
@@ -665,9 +664,8 @@ module.exports = {
this._pixiObject.align = align;
const color = object.content.tint;
this._pixiObject.tint = objectsRenderingService.rgbOrHexToHexNumber(
color
);
this._pixiObject.tint =
objectsRenderingService.rgbOrHexToHexNumber(color);
const scale = object.content.scale;
this._pixiObject.scale.set(scale);

View File

@@ -173,5 +173,6 @@ namespace gdjs {
return this._pixiObject.textHeight * this.getScale();
}
}
export const BitmapTextRuntimeObjectRenderer = BitmapTextRuntimeObjectPixiRenderer;
export const BitmapTextRuntimeObjectRenderer =
BitmapTextRuntimeObjectPixiRenderer;
}

View File

@@ -52,7 +52,8 @@ namespace gdjs {
*/
export class BitmapTextRuntimeObject
extends gdjs.RuntimeObject
implements gdjs.TextContainer, gdjs.OpacityHandler, gdjs.Scalable {
implements gdjs.TextContainer, gdjs.OpacityHandler, gdjs.Scalable
{
_opacity: float;
_text: string;
/** color in format [r, g, b], where each component is in the range [0, 255] */

View File

@@ -249,13 +249,16 @@ namespace gdjs {
(clipTextEnd === 0 || clipTextEnd !== dialogueText.length)
) {
pauseScrolling = true;
setTimeout(function () {
pauseScrolling = false;
commandCalls.splice(index, 1);
if (gdjs.dialogueTree.getVariable('debug')) {
logger.info('CMD:', call);
}
}, parseInt(call.params[1], 10));
setTimeout(
function () {
pauseScrolling = false;
commandCalls.splice(index, 1);
if (gdjs.dialogueTree.getVariable('debug')) {
logger.info('CMD:', call);
}
},
parseInt(call.params[1], 10)
);
}
if (call.cmd === command) {
commandParameters = call.params;

View File

@@ -157,9 +157,8 @@ namespace gdjs {
if (!instanceContainer.touchDraggableManagers[touchId]) {
//Create the shared manager if necessary.
// @ts-ignore
instanceContainer.touchDraggableManagers[
touchId
] = new DraggableManager(instanceContainer, touchId);
instanceContainer.touchDraggableManagers[touchId] =
new DraggableManager(instanceContainer, touchId);
}
// @ts-ignore
return instanceContainer.touchDraggableManagers[touchId];

View File

@@ -22,7 +22,8 @@ namespace gdjs {
parameterName: string,
value: number
) {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
const adjustmentFilter =
filter as unknown as PIXI.filters.AdjustmentFilter;
if (parameterName === 'gamma') {
adjustmentFilter.gamma = value;
} else if (parameterName === 'saturation') {
@@ -42,7 +43,8 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
const adjustmentFilter =
filter as unknown as PIXI.filters.AdjustmentFilter;
if (parameterName === 'gamma') {
return adjustmentFilter.gamma;
}
@@ -88,7 +90,8 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): AdjustmentFilterNetworkSyncData {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
const adjustmentFilter =
filter as unknown as PIXI.filters.AdjustmentFilter;
return {
ga: adjustmentFilter.gamma,
sa: adjustmentFilter.saturation,
@@ -104,7 +107,8 @@ namespace gdjs {
filter: PIXI.Filter,
data: AdjustmentFilterNetworkSyncData
): void {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
const adjustmentFilter =
filter as unknown as PIXI.filters.AdjustmentFilter;
adjustmentFilter.gamma = data.ga;
adjustmentFilter.saturation = data.sa;
adjustmentFilter.contrast = data.co;

View File

@@ -20,7 +20,8 @@ namespace gdjs {
parameterName: string,
value: number
) {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
const advancedBloomFilter =
filter as unknown as PIXI.filters.AdvancedBloomFilter;
if (parameterName === 'threshold') {
advancedBloomFilter.threshold = value;
} else if (parameterName === 'bloomScale') {
@@ -36,7 +37,8 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
const advancedBloomFilter =
filter as unknown as PIXI.filters.AdvancedBloomFilter;
if (parameterName === 'threshold') {
return advancedBloomFilter.threshold;
}
@@ -78,7 +80,8 @@ namespace gdjs {
getNetworkSyncData(
filter: PIXI.Filter
): AdvancedBloomFilterNetworkSyncData {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
const advancedBloomFilter =
filter as unknown as PIXI.filters.AdvancedBloomFilter;
return {
th: advancedBloomFilter.threshold,
bs: advancedBloomFilter.bloomScale,
@@ -92,7 +95,8 @@ namespace gdjs {
filter: PIXI.Filter,
syncData: AdvancedBloomFilterNetworkSyncData
) {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
const advancedBloomFilter =
filter as unknown as PIXI.filters.AdvancedBloomFilter;
advancedBloomFilter.threshold = syncData.th;
advancedBloomFilter.bloomScale = syncData.bs;
advancedBloomFilter.brightness = syncData.bn;

View File

@@ -15,13 +15,13 @@ namespace gdjs {
parameterName: string,
value: number
) {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
if (parameterName === 'size') {
asciiFilter.size = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
if (parameterName === 'size') {
return asciiFilter.size;
}
@@ -46,14 +46,14 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): AsciiFilterNetworkSyncData {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
return { size: asciiFilter.size };
}
updateFromNetworkSyncData(
filter: PIXI.Filter,
data: AsciiFilterNetworkSyncData
) {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
asciiFilter.size = data.size;
}
})()

View File

@@ -25,7 +25,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'rotation') {
bevelFilter.rotation = value;
@@ -40,7 +40,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'rotation') {
return bevelFilter.rotation;
@@ -64,7 +64,7 @@ namespace gdjs {
parameterName: string,
value: string
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = gdjs.rgbOrHexStringToNumber(value);
@@ -78,7 +78,7 @@ namespace gdjs {
parameterName: string,
value: number
): void {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = value;
@@ -88,7 +88,7 @@ namespace gdjs {
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter;
if (parameterName === 'lightColor') {
return bevelFilter.lightColor;
}
@@ -103,7 +103,7 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): BevelFilterNetworkSyncData {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
return {
r: bevelFilter.rotation,
@@ -119,7 +119,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: BevelFilterNetworkSyncData
) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter &
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter &
BevelFilterExtra;
bevelFilter.rotation = data.r;
bevelFilter.thickness = data.t;

View File

@@ -16,14 +16,14 @@ namespace gdjs {
parameterName: string,
value: number
) {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
const colorMatrix = filter as unknown as PIXI.ColorMatrixFilter;
if (parameterName !== 'opacity') {
return;
}
colorMatrix.alpha = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
const colorMatrix = filter as unknown as PIXI.ColorMatrixFilter;
if (parameterName === 'opacity') {
return colorMatrix.alpha;
}
@@ -50,14 +50,14 @@ namespace gdjs {
getNetworkSyncData(
filter: PIXI.Filter
): BlackAndWhiteFilterNetworkSyncData {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
const colorMatrix = filter as unknown as PIXI.ColorMatrixFilter;
return { a: colorMatrix.alpha };
}
updateFromNetworkSyncData(
filter: PIXI.Filter,
data: BlackAndWhiteFilterNetworkSyncData
) {
const colorMatrix = (filter as unknown) as PIXI.ColorMatrixFilter;
const colorMatrix = filter as unknown as PIXI.ColorMatrixFilter;
colorMatrix.alpha = data.a;
}
})()

View File

@@ -16,7 +16,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
const blendingModeFilter = filter as unknown as PIXI.AlphaFilter;
if (parameterName === 'alpha') {
blendingModeFilter.alpha = value;
} else if (parameterName === 'blendmode') {
@@ -24,7 +24,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
const blendingModeFilter = filter as unknown as PIXI.AlphaFilter;
if (parameterName === 'alpha') {
return blendingModeFilter.alpha;
}
@@ -54,7 +54,7 @@ namespace gdjs {
getNetworkSyncData(
filter: PIXI.Filter
): BlendingModeFilterNetworkSyncData {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
const blendingModeFilter = filter as unknown as PIXI.AlphaFilter;
return {
a: blendingModeFilter.alpha,
bm: blendingModeFilter.blendMode,
@@ -64,7 +64,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: BlendingModeFilterNetworkSyncData
) {
const blendingModeFilter = (filter as unknown) as PIXI.AlphaFilter;
const blendingModeFilter = filter as unknown as PIXI.AlphaFilter;
blendingModeFilter.alpha = data.a;
blendingModeFilter.blendMode = data.bm;
}

View File

@@ -20,7 +20,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
const brightnessFilter = filter as unknown as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
if (parameterName !== 'brightness') {
return;
@@ -30,7 +30,7 @@ namespace gdjs {
brightnessFilter.brightness(brightness, false);
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
const brightnessFilter = filter as unknown as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
if (parameterName === 'brightness') {
return brightnessFilter.__brightness;
@@ -56,7 +56,7 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): BrightnessFilterNetworkSyncData {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
const brightnessFilter = filter as unknown as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
return { b: brightnessFilter.__brightness };
}
@@ -64,7 +64,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: BrightnessFilterNetworkSyncData
) {
const brightnessFilter = (filter as unknown) as PIXI.ColorMatrixFilter &
const brightnessFilter = filter as unknown as PIXI.ColorMatrixFilter &
BrightnessFilterExtra;
brightnessFilter.__brightness = data.b;
brightnessFilter.brightness(data.b, false);

View File

@@ -18,7 +18,8 @@ namespace gdjs {
parameterName: string,
value: number
) {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
const bulgePinchFilter =
filter as unknown as PIXI.filters.BulgePinchFilter;
if (parameterName === 'centerX') {
bulgePinchFilter.center[0] = value;
} else if (parameterName === 'centerY') {
@@ -34,7 +35,8 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
const bulgePinchFilter =
filter as unknown as PIXI.filters.BulgePinchFilter;
if (parameterName === 'centerX') {
return bulgePinchFilter.center[0];
}
@@ -68,7 +70,8 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): BulgePinchFilterNetworkSyncData {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
const bulgePinchFilter =
filter as unknown as PIXI.filters.BulgePinchFilter;
return {
cx: bulgePinchFilter.center[0],
cy: bulgePinchFilter.center[1],
@@ -80,7 +83,8 @@ namespace gdjs {
filter: PIXI.Filter,
data: BulgePinchFilterNetworkSyncData
) {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
const bulgePinchFilter =
filter as unknown as PIXI.filters.BulgePinchFilter;
bulgePinchFilter.center[0] = data.cx;
bulgePinchFilter.center[1] = data.cy;
bulgePinchFilter.radius = data.r;

View File

@@ -29,7 +29,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
if (parameterName === 'mix') {
colorMapFilter.mix = gdjs.PixiFiltersTools.clampValue(
value / 100,
@@ -39,7 +39,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
if (parameterName === 'mix') {
return colorMapFilter.mix;
}
@@ -63,20 +63,20 @@ namespace gdjs {
parameterName: string,
value: boolean
) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
if (parameterName === 'nearest') {
colorMapFilter.nearest = value;
}
}
getNetworkSyncData(filter: PIXI.Filter): ColorMapFilterNetworkSyncData {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
return { mix: colorMapFilter.mix, near: colorMapFilter.nearest };
}
updateFromNetworkSyncData(
filter: PIXI.Filter,
data: ColorMapFilterNetworkSyncData
) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
colorMapFilter.mix = data.mix;
colorMapFilter.nearest = data.near;
}

View File

@@ -23,15 +23,17 @@ namespace gdjs {
parameterName: string,
value: number
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'epsilon') {
colorReplaceFilter.epsilon = value;
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'epsilon') {
return colorReplaceFilter.epsilon;
}
@@ -42,8 +44,9 @@ namespace gdjs {
parameterName: string,
value: string
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = gdjs.rgbOrHexStringToNumber(value);
} else if (parameterName === 'newColor') {
@@ -55,8 +58,9 @@ namespace gdjs {
parameterName: string,
value: number
): void {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = value;
} else if (parameterName === 'newColor') {
@@ -64,8 +68,9 @@ namespace gdjs {
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
if (parameterName === 'originalColor') {
return colorReplaceFilter.originalColor;
} else if (parameterName === 'newColor') {
@@ -81,8 +86,9 @@ namespace gdjs {
getNetworkSyncData(
filter: PIXI.Filter
): ColorReplaceFilterNetworkSyncData {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
return {
e: colorReplaceFilter.epsilon,
oc: colorReplaceFilter.originalColor,
@@ -93,8 +99,9 @@ namespace gdjs {
filter: PIXI.Filter,
data: ColorReplaceFilterNetworkSyncData
) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter &
ColorReplaceFilterExtra;
colorReplaceFilter.epsilon = data.e;
colorReplaceFilter.originalColor = data.oc;
colorReplaceFilter.newColor = data.nc;

View File

@@ -23,13 +23,13 @@ namespace gdjs {
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(layer, effectData) {
const filter = new PIXI.filters.CRTFilter();
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
crtFilter._animationTimer = 0;
return crtFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (crtFilter.animationSpeed !== 0) {
// Multiply by 10 so that the default value is a sensible speed
@@ -49,7 +49,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (parameterName === 'lineWidth') {
crtFilter.lineWidth = value;
@@ -76,7 +76,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
if (parameterName === 'lineWidth') {
return crtFilter.lineWidth;
@@ -131,13 +131,13 @@ namespace gdjs {
parameterName: string,
value: boolean
) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter;
const crtFilter = filter as unknown as PIXI.filters.CRTFilter;
if (parameterName === 'verticalLine') {
crtFilter.verticalLine = value;
}
}
getNetworkSyncData(filter: PIXI.Filter): CRTFilterNetworkSyncData {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
return {
lw: crtFilter.lineWidth,
@@ -158,7 +158,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: CRTFilterNetworkSyncData
) {
const crtFilter = (filter as unknown) as PIXI.filters.CRTFilter &
const crtFilter = filter as unknown as PIXI.filters.CRTFilter &
CRTFilterExtra;
crtFilter.lineWidth = data.lw;
crtFilter.lineContrast = data.lc;

View File

@@ -25,7 +25,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
const displacementFilter = filter as unknown as PIXI.DisplacementFilter;
if (parameterName === 'scaleX') {
displacementFilter.scale.x = value;
}
@@ -34,7 +34,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
const displacementFilter = filter as unknown as PIXI.DisplacementFilter;
if (parameterName === 'scaleX') {
return displacementFilter.scale.x;
}
@@ -64,7 +64,7 @@ namespace gdjs {
getNetworkSyncData(
filter: PIXI.Filter
): DisplacementFilterNetworkSyncData {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
const displacementFilter = filter as unknown as PIXI.DisplacementFilter;
return {
sx: displacementFilter.scale.x,
sy: displacementFilter.scale.y,
@@ -74,7 +74,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: DisplacementFilterNetworkSyncData
) {
const displacementFilter = (filter as unknown) as PIXI.DisplacementFilter;
const displacementFilter = filter as unknown as PIXI.DisplacementFilter;
displacementFilter.scale.x = data.sx;
displacementFilter.scale.y = data.sy;
}

View File

@@ -16,7 +16,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
if (parameterName === 'scale') {
dotFilter.scale = value;
} else if (parameterName === 'angle') {
@@ -24,7 +24,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
if (parameterName === 'scale') {
return dotFilter.scale;
}
@@ -52,14 +52,14 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): DotFilterNetworkSyncData {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
return { s: dotFilter.scale, a: dotFilter.angle };
}
updateFromNetworkSyncData(
filter: PIXI.Filter,
data: DotFilterNetworkSyncData
) {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
dotFilter.scale = data.s;
dotFilter.angle = data.a;
}

View File

@@ -22,7 +22,8 @@ namespace gdjs {
parameterName: string,
value: number
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'blur') {
dropShadowFilter.blur = value;
} else if (parameterName === 'quality') {
@@ -38,7 +39,8 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'blur') {
return dropShadowFilter.blur;
}
@@ -64,7 +66,8 @@ namespace gdjs {
parameterName: string,
value: string
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
dropShadowFilter.color = gdjs.rgbOrHexStringToNumber(value);
}
@@ -74,13 +77,15 @@ namespace gdjs {
parameterName: string,
value: number
): void {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
dropShadowFilter.color = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
return dropShadowFilter.color;
}
@@ -91,13 +96,15 @@ namespace gdjs {
parameterName: string,
value: boolean
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'shadowOnly') {
dropShadowFilter.shadowOnly = value;
}
}
getNetworkSyncData(filter: PIXI.Filter): DropShadowFilterNetworkSyncData {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
return {
b: dropShadowFilter.blur,
q: dropShadowFilter.quality,
@@ -113,7 +120,8 @@ namespace gdjs {
filter: PIXI.Filter,
data: DropShadowFilterNetworkSyncData
) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
dropShadowFilter.blur = data.b;
dropShadowFilter.quality = data.q;
dropShadowFilter.alpha = data.a;

View File

@@ -24,13 +24,13 @@ namespace gdjs {
new (class extends gdjs.PixiFiltersTools.PixiFilterCreator {
makePIXIFilter(layer, effectData) {
const filter = new PIXI.filters.GlitchFilter();
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
glitchFilter._animationTimer = 0;
return glitchFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (glitchFilter.animationFrequency !== 0) {
glitchFilter._animationTimer += target.getElapsedTime() / 1000;
@@ -48,7 +48,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'slices') {
glitchFilter.slices = value;
@@ -79,7 +79,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'slices') {
return glitchFilter.slices;
@@ -140,14 +140,14 @@ namespace gdjs {
parameterName: string,
value: boolean
) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
if (parameterName === 'average') {
glitchFilter.average = value;
}
}
getNetworkSyncData(filter: PIXI.Filter): GlitchFilterNetworkSyncData {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
return {
s: glitchFilter.slices,
@@ -170,7 +170,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: GlitchFilterNetworkSyncData
) {
const glitchFilter = (filter as unknown) as PIXI.filters.GlitchFilter &
const glitchFilter = filter as unknown as PIXI.filters.GlitchFilter &
GlitchFilterExtra;
glitchFilter.slices = data.s;
glitchFilter.offset = data.o;

View File

@@ -21,7 +21,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'innerStrength') {
glowFilter.innerStrength = value;
@@ -32,7 +32,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'innerStrength') {
return glowFilter.innerStrength;
@@ -50,7 +50,7 @@ namespace gdjs {
parameterName: string,
value: string
) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'color') {
glowFilter.color = gdjs.rgbOrHexStringToNumber(value);
@@ -61,14 +61,14 @@ namespace gdjs {
parameterName: string,
value: number
): void {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'color') {
glowFilter.color = value;
}
}
getColorParameter(filter: PIXI.Filter, parameterName: string): number {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
if (parameterName === 'color') {
return glowFilter.color;
@@ -81,7 +81,7 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): GlowFilterNetworkSyncData {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
return {
is: glowFilter.innerStrength,
@@ -94,7 +94,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: GlowFilterNetworkSyncData
): void {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter &
const glowFilter = filter as unknown as PIXI.filters.GlowFilter &
GlowFilterExtra;
glowFilter.innerStrength = data.is;
glowFilter.outerStrength = data.os;

View File

@@ -24,7 +24,7 @@ namespace gdjs {
return godrayFilter;
}
updatePreRender(filter: PIXI.Filter, target: EffectsTarget) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (godrayFilter.animationSpeed !== 0) {
godrayFilter.time +=
@@ -36,7 +36,7 @@ namespace gdjs {
parameterName: string,
value: number
) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'lacunarity') {
godrayFilter.lacunarity = value;
@@ -57,7 +57,7 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'lacunarity') {
return godrayFilter.lacunarity;
@@ -103,14 +103,14 @@ namespace gdjs {
parameterName: string,
value: boolean
) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
if (parameterName === 'parallel') {
godrayFilter.parallel = value;
}
}
getNetworkSyncData(filter: PIXI.Filter): GodrayFilterNetworkSyncData {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
return {
la: godrayFilter.lacunarity,
@@ -128,7 +128,7 @@ namespace gdjs {
filter: PIXI.Filter,
data: GodrayFilterNetworkSyncData
) {
const godrayFilter = (filter as unknown) as PIXI.filters.GodrayFilter &
const godrayFilter = filter as unknown as PIXI.filters.GodrayFilter &
GodrayFilterExtra;
godrayFilter.lacunarity = data.la;
godrayFilter.angle = data.a;

View File

@@ -18,7 +18,8 @@ namespace gdjs {
parameterName: string,
value: number
) {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
const kawaseBlurFilter =
filter as unknown as PIXI.filters.KawaseBlurFilter;
if (parameterName === 'pixelizeX') {
kawaseBlurFilter.pixelSize[0] = value;
} else if (parameterName === 'pixelizeY') {
@@ -30,7 +31,8 @@ namespace gdjs {
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
const kawaseBlurFilter =
filter as unknown as PIXI.filters.KawaseBlurFilter;
if (parameterName === 'pixelizeX') {
return kawaseBlurFilter.pixelSize[0];
}
@@ -64,7 +66,8 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): KawaseBlurFilterNetworkSyncData {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
const kawaseBlurFilter =
filter as unknown as PIXI.filters.KawaseBlurFilter;
return {
px: kawaseBlurFilter.pixelSize[0],
py: kawaseBlurFilter.pixelSize[1],
@@ -76,7 +79,8 @@ namespace gdjs {
filter: PIXI.Filter,
data: KawaseBlurFilterNetworkSyncData
) {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
const kawaseBlurFilter =
filter as unknown as PIXI.filters.KawaseBlurFilter;
kawaseBlurFilter.pixelSize[0] = data.px;
kawaseBlurFilter.pixelSize[1] = data.py;
kawaseBlurFilter.blur = data.b;

View File

@@ -15,13 +15,13 @@ namespace gdjs {
parameterName: string,
value: number
) {
const noiseFilter = (filter as unknown) as PIXI.NoiseFilter;
const noiseFilter = filter as unknown as PIXI.NoiseFilter;
if (parameterName === 'noise') {
noiseFilter.noise = gdjs.PixiFiltersTools.clampValue(value, 0, 1);
}
}
getDoubleParameter(filter: PIXI.Filter, parameterName: string): number {
const noiseFilter = (filter as unknown) as PIXI.NoiseFilter;
const noiseFilter = filter as unknown as PIXI.NoiseFilter;
if (parameterName === 'noise') {
return noiseFilter.noise;
}
@@ -46,14 +46,14 @@ namespace gdjs {
value: boolean
) {}
getNetworkSyncData(filter: PIXI.Filter): NoiseFilterNetworkSyncData {
const noiseFilter = (filter as unknown) as PIXI.NoiseFilter;
const noiseFilter = filter as unknown as PIXI.NoiseFilter;
return { n: noiseFilter.noise };
}
updateFromNetworkSyncData(
filter: PIXI.Filter,
data: NoiseFilterNetworkSyncData
) {
const noiseFilter = (filter as unknown) as PIXI.NoiseFilter;
const noiseFilter = filter as unknown as PIXI.NoiseFilter;
noiseFilter.noise = data.n;
}
})()

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