Compare commits

...

777 Commits

Author SHA1 Message Date
Florian Rival
1991cc634a Change the default behavior when clicking outside a window: it won't be closed anymore.
* This avoids a recurring issue where misclicking outside a window would cancel any changes made in the window.
* You can still press Escape to quickly close a dialog.
* Note that this behavior can be customized in the preferences. You can choose to cancel the changes, apply any changes or do nothing.
2021-05-09 23:10:59 +01:00
Florian Rival
d653f846b6 Update Bitmap Text description/wording
Don't show in changelog
2021-05-09 22:58:32 +01:00
Florian Rival
9a8ec971f2 Update translations 2021-05-09 20:37:45 +01:00
Florian Rival
87c5007a25 Add Bitmap Text example
Don't show in changelog
2021-05-09 19:45:29 +01:00
Florian Rival
666a9c747a Add Bim Bam (Bust-a-Move clone) example (thanks D8H) 2021-05-09 12:48:17 +01:00
Florian Rival
cf59e6fb1e Add Tactical Game Grid Movement example (thanks D8H) 2021-05-09 12:36:01 +01:00
Florian Rival
ab04db387a Add "Menu with tweens" example (thanks Dreamkingmovies) 2021-05-09 12:05:50 +01:00
aphoenixholland
7a7a0d0eec Add an option to Tween behavior scale actions to scale an object from its center (#2611) 2021-05-09 11:44:23 +01:00
Arthur Pacaud
a27d1e97bc Rework GetUsedExtensions (#2588)
Only show in developer changelog
2021-05-07 22:46:02 +02:00
Aurélien Vivet
076732abd9 Automatically disable smoothing of assets from asset store if the project is using the "nearest" scale mode ("pixel-perfect") (#2620) 2021-05-07 15:10:13 +01:00
Aurélien Vivet
9d09ad4dd9 Add Bitmap Text objects, an efficient way to display texts using custom "bitmap fonts" (#2432)
* This allows to display texts on screen that use a "bitmap font", generated with softwares like [BMFont](https://www.angelcode.com/products/bmfont/) or [bmGlyph](http://www.bmglyph.com/).
* Bitmap fonts allow advanced effects and custom design of each character, with complete control over the appearance of the text. This is useful for making a custom score counter, titles, button labels...
* They also render very well in a pixel-perfect, pixel-art or retro-like game.
* Finally, these Bitmap Texts are fast and efficient to render on screen: useful for scores or texts that are updated frequently.
2021-05-07 14:57:00 +01:00
Oxey405
c16d155066 Fix multi-user compatibility on Linux (previews/exports not generated in same folders anymore) (#2590) 2021-05-06 19:31:10 +01:00
Florian Rival
cbdfd344e3 Fix shortcut in preview and text entry not working anymore
Fix #2605

Don't show in changelog
2021-05-06 19:29:18 +01:00
Henrik Hedlund
8cce4ab9f2 Add warning hint about overriding the Peer ID in P2P extension (#2606) 2021-05-04 08:54:38 +01:00
Florian Rival
3266559cb6 Add actions, conditions and expressions to get the position of an object center or set its position using its center (#2593)
* This is useful for making concise actions or conditions.
* This is also useful because for some objects, the center is not located at half the width and the height of the object.
* You can use `Object.CenterX()` and `Object.CenterY()` to get the position of the center of an object in an expression.
2021-05-02 18:43:28 +01:00
Henrik Hedlund
990b04d629 Allow setting the client ID in the peer-to-peer extension (#2598)
* By default, a long unique ID is generated. If you use your own broker server, a game could generate a simple, but unique, ID for each game (e.g. 639239), and then specify that as the client ID. Other players can then connect to that peer using the simpler ID.
2021-05-02 11:04:30 +01:00
Florian Rival
c295456231 Fix sprite objects updating their displayed image one frame too late (#2597)
* This fixes some "flickering" when a sprite is just created, when a scene is changed or when external layout objects are created on a scene.

Fixes #1285
2021-05-01 18:05:25 +01:00
Florian Rival
79e033d57b Increase timeout for GDJS tests and fix a type issue
Don't show in changelog
2021-04-30 11:48:08 +02:00
Florian Rival
f0fc709a84 Fix tests (fix regression due to inexact rad/deg conversion) 2021-04-30 09:57:31 +02:00
D8H
b80ed7e6f5 Improve the type definitions of LinkedObjects (#2594)
Only show in developer changelog
2021-04-30 08:40:16 +01:00
D8H
f23936a6c4 Add tests on moving platforms (#2581)
Only show in developer changelog
2021-04-29 20:53:26 +01:00
Arthur Pacaud
1dff166df0 Add network and persistence configuration to firestore in Firebase (#2582) 2021-04-28 21:35:22 +02:00
Aurélien Vivet
50278b1ab2 Fix page scrolling when keyboard was used in games embedded in web pages (#2589) 2021-04-27 21:38:53 +01:00
Aurélien Vivet
5f4fde7a56 Add new expressions XFromAngleAndDistance and YFromAngleAndDistance (#2558) 2021-04-25 21:08:29 +01:00
Aurélien Vivet
5384225a9b Fix typo and mobile controls on Platformer project example (#2578)
Don't show in changelog
2021-04-24 18:12:05 +02:00
Arthur Pacaud
5ecdfa1c7f Convert Firebase extension to TypeScript (#2417)
Only show in developer changelog
2021-04-24 17:58:36 +02:00
Nilay Majorwar
df6910e062 Rework the behaviors list with collapsible panels (#2553)
* This is useful to hide behaviors when they are too many of them
* This also creates a more visible distinction between each behavior
2021-04-23 12:05:53 +01:00
D8H
5a42d6b94c Add more type definitions and new tests for on moving platforms for the Platformer behavior (#2573)
Only show in developer changelog
2021-04-23 11:55:18 +01:00
Arthur Pacaud
afa9b2a2ae Fix invalid values ("NaN") being potentially stored in variables and corrupting the project files (#2568) 2021-04-20 16:47:20 +01:00
Florian Rival
1dae099be9 Fix a potential crash when instances are selected and an object is deleted (#2557) 2021-04-18 18:37:06 +01:00
Arthur Pacaud
6f64fd3d1c Fix "Sound is playing" condition not consistent when an audio file is being loaded (#2555)
* Because of this, this could create some glitches when playing sounds using the condition to check if a sound was already playing (for example, it could trigger multiple times a sound).
2021-04-18 18:34:05 +01:00
Florian Rival
6c0bd92b24 Fix crash when adding an instance of a global object on the scene 2021-04-17 12:01:05 +01:00
Arthur Pacaud
0bcaa835e6 Improve the file watcher in development mode (#2554)
* Use chokidar for a more reliable and robust change detection
2021-04-17 11:06:26 +01:00
Nilay Majorwar
32ca97650c Rework the collisions editor and points editor (#2481)
* Show the preview and the polygons/points side by side (on large screens), so it's easier to edit.
* The split can be dragged to give more space to the preview or to the tables.
* Show point name in tooltip when hovering on point.
* Improve the dragging of points and polygon vertices so that they continue to follow the cursor even if dragging outside of the image bounds.
* Allow to collapse polygon tables, useful if you have lots of polygons in an object.
* The checkered background in the editors are now also using different colors following the selected theme.
2021-04-14 22:26:31 +01:00
Arthur Pacaud
e19d63ce96 Improve spacing of descriptions for checkboxes in properties (#2542) 2021-04-13 10:25:01 +01:00
Aurélien Vivet
352e5daf1e Addition of the version number under the name of the extension in the presentation panel. (#2540) 2021-04-13 11:08:01 +02:00
Aurélien Vivet
003f56e9bc Remove the rest of the skeleton object (#2539)
Don't show in changelog
2021-04-13 00:22:36 +01:00
D8H
4b3fa9fc39 Fix hitboxes not invalidated in TestRuntimeObject (#2534)
Only show in developer changelog
2021-04-11 20:22:54 +01:00
Florian Rival
e3fa31c4a4 Merge branch 'master' of github.com:4ian/GDevelop 2021-04-11 15:49:51 +01:00
Florian Rival
1ad0ab9881 Add Goose Bomberman example (thanks D8H) 2021-04-11 15:48:33 +01:00
Aurélien Vivet
355c53cb12 Fix Video object wrongly starting to play automatically (#2533) 2021-04-11 14:40:58 +01:00
Florian Rival
2a9b27b503 Add a new Dialogue Tree example (thanks potato-gamer-coder and Midhil457!) 2021-04-11 13:26:32 +01:00
D8H
2fa2824ca2 Add a test for platformer object to fall when a platform is removed (#2529)
Only show in developer changelog
2021-04-11 03:07:33 +01:00
Florian Rival
85e3ed42fa Add experimental configuration for GitHub workspaces
Don't show in changelog
2021-04-11 01:58:12 +00:00
Aurélien Vivet
8a178a85fb Add a preference to choose if clicking outside a dialog is cancelling changes, applying changes or doing nothing (#2484) 2021-04-10 19:36:42 +01:00
Florian Rival
54ef7482cf Fix performance issues on iOS by upgrading internal rendering engine to PixiJS v6 (#2447)
* Thanks @Bouh and @arthuro555 for the help!

Co-authored-by: Bouh <bouh.vivez@gmail.com>
2021-04-09 23:58:18 +01:00
Aurélien Vivet
c846a7a068 Change the wording of the button to "Edit collision masks" (#2525) 2021-04-09 15:46:29 +01:00
Florian Rival
86eff4e408 Fix sounds/musics playing for a very short time at the default volume instead of the specified one
Fix #2490
2021-04-08 23:59:34 +01:00
D8H
916938b4a8 [Top-down] Stick controls now comply with the "allow diagonals" setting (#2518)
* Test cases on stick controls for forbidden diagonals


add tests

* Fix: stick controls now comply with allowDiagonals setting

* Remove only
2021-04-07 19:01:40 +00:00
D8H
49827984ac Allow an object moving vertically to change direction when diagonals are forbidden in the Top-down behavior. (#2516)
* If multiple keys are pressed, the last one is used to move the object.
2021-04-07 00:19:05 +01:00
Aurélien Vivet
02eac6ba5e Small fixes (#2514)
* Remove useless type

* Fix type
2021-04-06 22:43:09 +00:00
Arthur Pacaud
479167638b Update the discord invite URL (#2511) 2021-04-05 22:00:04 +02:00
Florian Rival
fada85d41d Fix export to Android/iOS failing if AdMob id was containing invalid characters (#2510) 2021-04-05 13:31:12 +01:00
Florian Rival
3017798283 Remove deprecated/unmaintained SkeletonObject extension (#2509)
This should probably be restarted from scratch with a well known/battle tested library.

Don't show in changelog
2021-04-03 23:58:02 +01:00
Florian Rival
515308ed9d Add Titan Souls Demo game (Thanks @HelperWesley and @arthuro555) 2021-04-03 22:36:50 +01:00
Tristan Rhodes
7369e05e01 Improve wording on some movement related action sentences (#2501) 2021-04-02 20:09:51 +01:00
Aurélien Vivet
55da9eb2ef Add an action to display collision hitboxes and points of objects during the game (#2394)
* This is useful to check the proper set up of objects and check the position of points of objects during the game.
2021-04-02 00:11:22 +01:00
Arthur Pacaud
01a45a10df Improve the p2p chat example (#2488) 2021-04-01 23:54:38 +01:00
Florian Rival
32d313f538 Bump newIDE version 2021-03-30 00:14:05 +01:00
Arthur Pacaud
1640ca49d7 Fix games hanging when using an empty While event (#2480) 2021-03-28 16:55:22 +01:00
D8H
654b8d0bc1 Change zoom in the scene editor so that it's centered on the cursor (#2478)
* This makes it easier to navigate in the scene by zooming in and out
2021-03-28 15:46:37 +01:00
Florian Rival
2a47d2f630 Auto close issues related to b105 web-app update
Don't show in changelog
2021-03-28 15:40:02 +01:00
Nilay Majorwar
e1423e0b90 Add One Dark theme (for the editor and for JavaScript code blocks) (#2476) 2021-03-28 15:28:56 +01:00
D8H
458430bbfb Fix platformer objects wrongly able to jump after falling (#2477) 2021-03-28 14:37:22 +01:00
Florian Rival
2a5c18474e Fix warning 2021-03-27 17:51:02 +00:00
D8H
827c53e9d5 Add an option to display an isometric grid in the scene editor (#2445) 2021-03-27 17:13:39 +00:00
Florian Rival
019920009a Fix ToJSON wrongly transforming an empty string to a variable containing the number 0 (#2475) 2021-03-27 15:44:45 +00:00
Nilay Majorwar
aaed10a598 Fix bug in theme creation script (#2474)
Only show in developer changelog
2021-03-27 12:20:22 +00:00
Arthur Pacaud
193ce8bcf8 Add VS Code debug configuration (#2466)
This allows to use breakpoints and debug the react app from inside the IDE.

Only show in developer changelog
2021-03-25 21:49:12 +00:00
Florian Rival
fd020fd2a3 Bump newIDE version 2021-03-25 20:16:20 +00:00
Florian Rival
802f67f5b7 Update translations 2021-03-23 23:32:49 +00:00
Florian Rival
945386ce56 Add comment about function duplication
Don't show in changelog
2021-03-23 22:52:22 +00:00
Florian Rival
a221acf875 Fix variable and child variables with special characters not suggested with a valid syntax in the events sheet
* Also fix game freeze when trying to use certain actions on an invalid variable name

Fix #2457
2021-03-23 22:43:53 +00:00
Florian Rival
35bf3861a5 Fix raycast conditions failing in some conditions
Fix #2450
2021-03-20 16:06:43 +00:00
Florian Rival
df8fb9678a Update examples for the web-app and fix UUID regenerated every time they are updated.
Don't show in changelog
2021-03-20 15:08:24 +00:00
Florian Rival
acffff0bca Fix download of libGD.js not downloading the .wasm file (#2448)
Don't show in changelog
2021-03-18 23:09:26 +00:00
D8H
ca3e0c8c18 Refactor the whole Platformer Object behavior internals (#2396)
* Use the State pattern to make more understandable the transitions between state and understand the different state that an object can have and what it can do in each.

Only show in developer changelog
2021-03-17 22:10:07 +00:00
Florian Rival
fa15276ffa Fix sentence of the action "Append variable to a scene array" 2021-03-15 18:31:32 +00:00
D8H
d98915090a Imrpove visibility and type definitions in the top-down behavior (#2436)
Only show in developer changelog
2021-03-15 18:18:42 +00:00
Arthur Pacaud
bdee666992 Update "For each child variable" event description (#2435) 2021-03-15 09:20:44 +00:00
Florian Rival
8cb55b6e8e Change some wordings in the Physics behavior actions
* Actions to apply a polar force (or impulse) are now called "Apply a force (angle)"
* Also added synonym to actions adding torque (rotational force) or angular impulse (rotational impulse)
2021-03-14 22:17:03 +00:00
Arthur Pacaud
4e21a29c9b Allow to use any scene variable (including variables in structure) as the "child" variables in For Each event (#2428) 2021-03-14 15:54:38 +00:00
Florian Rival
91b7d56219 Bump newIDE version 2021-03-14 15:53:12 +00:00
Florian Rival
00c887bb70 Add minor changes in README
Don't show in changelog
2021-03-14 13:47:31 +00:00
Florian Rival
cc9338eb3a Update translations 2021-03-14 12:32:00 +00:00
Florian Rival
b34fad7950 Build the Core with WebAssembly even in production
* This should speed up CPU intensive operations (saving/loading).
* WebAssembly is now supported by all modern browsers, including on iOS and Android.

Only show in developer changelog
2021-03-13 23:50:23 +00:00
Florian Rival
0acb11f9e5 Make newly added variables to be string by default
Don't show in changelog
2021-03-13 21:55:29 +00:00
Florian Rival
01112fa850 Exclude dependencies/vendored files from GitHub statistics
Don't show in changelog
2021-03-13 21:43:26 +00:00
Florian Rival
031c74dfbf Fix tests in GDCore after switching to RapidJSON
Don't show in changelog
2021-03-13 21:34:53 +00:00
Florian Rival
741c457d7f Use double for instances position/angle/size instead of float and various other fields
Fix issues with precision of serialized JSON after the switch to RapidJSON

Don't show in changelog
2021-03-13 21:34:53 +00:00
Florian Rival
a996c5413f Improve speed of auto-save/save/load of projects
This makes autosave 70% faster, saving a project 30% faster, preview slighlty faster.

- Switch to RapidJSON for serialization inside the Core.
- Avoid extra pair of JSON.parse/JSON.stringify for autosaves
- Fix float used instead of double in the SerializerElement/Value JS bindings
2021-03-13 21:34:53 +00:00
D8H
c2d163c569 Add "simulate stick" action to the Top-down movement behavior (#2427)
* This allows to easily add joystick control to an object having the "Top-down Movement" behavior, by using this with the expressions from the Gamepad extension.
2021-03-13 12:43:39 +00:00
Arthur Pacaud
0e76b72c2a Add Tristan Rhodes to contributors list (#2424)
Don't show in changelog
2021-03-10 19:01:46 +00:00
Aurélien Vivet
1f1f44ac5a Fix align for variables list (#2421)
Don't show in changelog
2021-03-10 09:22:17 +00:00
Florian Rival
cbe5dc10ad Add new isometric game starter (Thanks Mickael Hoarau!) 2021-03-09 23:56:02 +00:00
Florian Rival
78914dc004 Fix animation of rotated/flipped tiles not working in the Tilemap object 2021-03-09 19:29:17 +00:00
Florian Rival
975fa7e2b7 Fix crash (regression) in RenderedSpriteInstance
Don't show in changelog
2021-03-09 18:37:52 +00:00
D8H
3bdaff53e1 Add more tests on the platformer extension (#2415)
- jumping to grab platforms or ladders
- walking on platforms
- performance
2021-03-08 21:59:22 +00:00
Florian Rival
b78022a891 Add code generation tests to ensure proper working of Create action in Events Functions
* Also reduce logging when loading extensions.

Don't show in changelog
2021-03-08 21:24:43 +00:00
Arthur Pacaud
e876b7c27f Fix events not working on objects just created in extensions made in the editor (#2418) 2021-03-08 21:21:02 +00:00
Florian Rival
e9e86e3298 Merge branch 'master' of github.com:4ian/GDevelop 2021-03-08 00:28:28 +00:00
Florian Rival
e2026424aa Fix tests and formatting 2021-03-08 00:28:19 +00:00
Aurélien Vivet
8aca58c0c6 Allow to move selection in the scene editor fast with arrow keys + Shift key pressed (#2416) 2021-03-08 00:23:28 +00:00
D8H
37346c0714 Add the "movement angle offset" property to the top-down behavior (#2411)
* This is useful for the Isometry viewpoint, so that when player press "up", the movement is going "up" on the screen (rather than diagonally).
2021-03-07 23:03:31 +00:00
Arthur Pacaud
4ec14ed498 Add Array and Boolean variables (#2137)
* In the list of variables (of the scene, of an object or global variables), you can now specify the type of the variable: number, text, boolean, array or structure.
* Boolean variables can be "true" or "false. They can have their values checked with conditions, and updated with actions. They are a good way to store information about if something is enabled or not (is an item equipped, is something selected, etc...).
* Array variables can contain multiple values, indexed by a number. New values, including any kind of variables, can be appended to an array during the game. Arrays can also have a value removed, and using the event "For each child variable", you can run conditions and actions for each value that is present in the array.
* Boolean and arrays are also supported when you transform a variable from or to the JSON format - which is ideal to send web requests, read configuration files or store any kind of arbitrary data.
* Finally, note that array values can themselves be arrays, structures or any variable. This can be useful to construct advanced logic. You can also access arrays (as well as any variable) from JavaScript code block events.
2021-03-07 21:53:12 +00:00
Florian Rival
be2a286b3c Improve compilation speed by 8%
* Avoid useless copy of strings in memory when comparing them (reducing work in string heavy operations like export/preview).
2021-03-06 21:28:11 +00:00
Florian Rival
d068c29993 Fix hitboxes of some objects not properly updated when some objects were resized
* This includes BBText, Text, Tilemap, Tiled Sprite, Panel Sprite and the Video objects.
* Also add support for tweening the scale of a Panel Sprite object.
2021-03-06 16:12:52 +00:00
Aurélien Vivet
082f8125ed Start page revert to one panel (#2409)
Don't show in changelog
Keep the name of the [previous commit](05807be350) for the changelog.
2021-03-06 16:11:25 +01:00
Aurélien Vivet
05807be350 New section for guides, documentation and tutorials on start page. (#2408) 2021-03-06 01:31:30 +01:00
Florian Rival
fcb41862c2 Fix slowness in the points and collision masks editor for objects with lots of images 2021-03-04 22:24:38 +00:00
Florian Rival
209bf36181 Add aac in the supported audio files when choosing an audio file 2021-03-04 20:52:23 +00:00
Florian Rival
7c51b47f53 Fix a rendering issue making objects sometimes invisible/not shown in the scene editor 2021-03-03 23:48:00 +00:00
Florian Rival
0749c64002 Add proper support for completions of number|string expressions
Don't show in changelog
2021-03-03 20:06:23 +00:00
Arthur Pacaud
baa597f6ae Improve overall GDJS typing (#2401)
Only show in developer changelog
2021-03-03 14:41:13 +00:00
Florian Rival
10bed28228 Fix broken scene changes
Don't show in changelog
2021-03-03 09:45:40 +00:00
Florian Rival
c95991756a Add type checking in some test files and remove HSHG from the codebase
Don't show in changelog
2021-03-02 23:09:54 +00:00
D8H
9787f04431 Make path finding tests more concise (#2397)
Don't show in changelog
2021-03-02 22:04:26 +00:00
Florian Rival
9980d59539 Various fixes in the dependencies UI
* Fix keyboard Tab navigation
  * It's still broken when modifying a field though.
* Use existing Table UI for a more compact look and consistency with the rest of the UI
* Use small icons and text fields without margins
* Use a RaisedButton for Add for consistency

Don't show in changelog
2021-03-02 00:47:06 +00:00
Arthur Pacaud
372deaec9c Allow extensions made in the editor to specify dependencies on Cordova libraries or NPM packages (#2393)
Only show in developer changelog
2021-03-02 00:01:11 +00:00
Arthur Pacaud
c89231ba38 Improve RuntimeGame typing (#2387)
Only show in developer changelog
2021-03-01 09:09:04 +00:00
Florian Rival
b3b68612bf Fix collision (and raycast) not always triggered with sprite having a non default center (#2392) 2021-02-28 16:59:04 +00:00
Bouh
42a31c65df Invert mouse wheel for keep it consistent with the previous beta
event.deltaY make scroll Up and Down inverted, so i apply the negative sign before.
Don't show in change log
2021-02-27 17:19:21 +01:00
Aurélien Vivet
4d3da06fd6 Fix mouse wheel for Firefox in the editor and in games 2021-02-27 16:29:28 +01:00
Florian Rival
8dc9ff5d07 Fix compilation on iOS of exported games failing (#2389)
* This was because an SDK related to AdMob was wrongly included and would trigger a compiler error in XCode.
2021-02-27 12:56:50 +00:00
Florian Rival
175d9af380 Run auto-formatting on extension test files too
Only show in developer changelog
2021-02-27 00:36:54 +00:00
D8H
2473041797 Add more tests for the Platformer extension (#2384)
Only show in developer changelog
2021-02-27 01:29:00 +01:00
Arthur Pacaud
6b41a5c44a Fix "Parse JSON from API" example 2021-02-24 23:18:27 +01:00
D8H
2811eef4e0 Rework path finding to use RBush instead of HSHG (#2315)
* Also add many tests to check the good working of the pathfinding in multiple situations.
2021-02-24 09:46:50 +01:00
Arthur Pacaud
fb3f69ec63 Fix object name not being correctly cleared in the object group editor (#2376) 2021-02-24 09:26:37 +01:00
Aurélien Vivet
92c5cfd9c7 Video object is now a stable
- File must be a .mp4 format encoded with H264 for the video and AAC for the audio.
- Before a video can be played, you have to ensure that the player interacted first with your game.
2021-02-23 01:22:55 +01:00
Arthur Pacaud
1efcd0eeed Improve RuntimeScene typing (#2381)
Only show in developer changelog
2021-02-22 23:06:14 +01:00
Arthur Pacaud
fa988360af Allow audio sounds and musics to be marked as preloaded in the Resources editor (#2006)
* When marked as preloaded, the audio file is loaded in memory and ready to play. When played using an action, it will start almost immediately.
* There are also new actions to unload some or all audio files from memory. This can be useful when switching between levels in large games.
2021-02-22 20:45:07 +01:00
Florian Rival
6526e8ad8a Allow to enter numbers when accessing to a variable child with brackets notation (e.g: MyVariable[2]) (#2380) 2021-02-22 14:29:06 +01:00
Florian Rival
fa10920aa3 Add link to Good First Contributions in the README 2021-02-22 11:44:14 +01:00
Arthur Pacaud
b676f7428e Use Nord as the default theme when the system settings are set to a dark theme, including on the web-app (#2377) 2021-02-22 08:48:04 +01:00
Bouh
0b13b3342a Fix scale properties does not exist in 'TiledSpriteRuntimeObject'.
Seen on semaphoreci.
Don't show in changelog
2021-02-21 23:53:05 +01:00
Aurélien Vivet
f83bea54c9 Add scale support for Tweens on Tiled sprite object
Don't show rest in changelog
* Add scale support for Tweens on Tiled sprite
* Add type on functions
* Fix typo on descriptions for documentation
2021-02-21 21:48:07 +01:00
Aurélien Vivet
505ff05e4b Fix errors in expressions from the gamepad example 2021-02-20 23:28:05 +01:00
Florian Rival
b43f30cefa Improve code generation speed by ~10%
* Remove unecessary complex code
* Remove dead code
2021-02-20 23:12:09 +01:00
Florian Rival
dd8bbde206 Add support for scoped actions/conditions to objects
Don't show in changelog
2021-02-18 17:40:25 +01:00
Florian Rival
2ad2afa191 Fix compilation
Don't show in changelog
2021-02-18 17:40:25 +01:00
Florian Rival
ba0522b199 Update descriptions of generated expressions/conditions/actions
Don't show in changelog
2021-02-18 17:40:25 +01:00
Florian Rival
e065e66cc7 Refactor Camera extension to use the newly added conditions/expressions functions
Don't show in changelog
2021-02-18 17:40:25 +01:00
Florian Rival
a20cc64a22 Refactor Mouse extension to use the newly added conditions/expressions functions
Don't show in changelog
2021-02-18 17:40:25 +01:00
Florian Rival
dda7cd9d5b Add new functions to declare expressions, conditions and actions at the same time.
Only show in developer changelog
2021-02-18 17:40:25 +01:00
Florian Rival
574faa24d5 Improve documentation of gd::PlatformExtension 2021-02-18 17:40:25 +01:00
Aurélien Vivet
e620f500cf Fix style on dark theme
Don't show in changelog
2021-02-17 15:03:06 +01:00
Arthur Pacaud
925de35b10 Add a warning shown when exporting a game with a default package name (#2306) 2021-02-16 22:45:26 +01:00
Florian Rival
1e56ba511a Fix warning 2021-02-16 19:59:13 +01:00
Arthur Pacaud
d6e2e99b98 Add appid to the elctron export (#2310)
And some scripts in the package
2021-02-16 17:23:09 +00:00
Arthur Pacaud
801d58695c Add support for private functions to extensions made in the editor (#2305)
* Actions/conditions/expressions made with events in the editor can be marked "private": they can be used inside the extension (or inside the behavior), but can't be used in the scene events sheet.
* This is useful to share some "internal" logic that you don't want to make available from the events sheet.
2021-02-15 18:31:38 +01:00
Florian Rival
5e71f28da5 Make the export dialog remember the last export dialog for a project 2021-02-11 20:39:57 +01:00
Ishan Singhal
0fa369d6c4 Fix typo in AdMob app id hints (#2297)
Co-authored-by: Ishan <ishan@pop-os.localdomain>
2021-02-10 09:05:57 +01:00
Harsimran Singh Virk
131c9699a3 Fix lights shown during one frame at a wrong position after their creation (#2294) 2021-02-09 20:23:14 +01:00
Florian Rival
3f91c937b9 Add enhancement tag to feature request
Don't show in changelog
2021-02-09 08:49:40 +01:00
Arthur Pacaud
fc42b0e480 Add Spatial Sound extension (#2279)
* This allows to set the position of a sound in a 3D space. The stereo system of the device is used to simulate the position of the sound and to give the impression that the sound is located somewhere around the player.
2021-02-08 22:29:29 +01:00
Aurélien Vivet
4e99493fb7 Fix the expression to get the particles count of a particle emitter (#2289) 2021-02-08 18:58:07 +01:00
Florian Rival
0fe4371418 Bump newIDE version 2021-02-07 13:00:03 +00:00
Florian Rival
414e825a58 Fix warnings and add some documentation to Text props
Don't show in changelog
2021-02-06 15:00:03 +00:00
Florian Rival
0b95202b2e Improve start page with Youtube link, more icons and link to the showcase 2021-02-06 15:00:03 +00:00
Florian Rival
4e9511aa5f Fix rare layout glitches after resizing the window 2021-02-06 15:00:03 +00:00
Florian Rival
5871f1f186 Add the GDevelop games showcase in a tab of the new project window 2021-02-06 15:00:03 +00:00
Florian Rival
f9c7f19035 Refactor search results related components in their own folders
Don't show in changelog
2021-02-06 15:00:03 +00:00
Jonas Finnemann Jensen
65aa45796e Fix fullscreen not working on certain browsers (#2161) 2021-02-06 12:09:14 +00:00
Jonas Finnemann Jensen
6b85d71968 Fix Firebase action to sign in with 3rd party providers in a browser (#2258) 2021-02-06 12:02:41 +00:00
Aurélien Vivet
32553f8607 Add expression normalize (#2275)
Add the new mathematical expression normalize for remapping a value between `min` and `max` to a value between 0 and 1.
2021-02-06 02:12:55 +01:00
Florian Rival
79b8e19da5 Fix Tilemap not working in the web-app 2021-02-05 11:58:14 +00:00
D8H
58d114721d Improve typing of the Pathfinding extension (#2274)
Only show in developer changelog
2021-02-04 23:22:40 +00:00
Oxey405
9501852382 Add condition to check if any key is released (#2269) 2021-02-04 18:49:08 +00:00
Todor Imreorov
08defb6090 Fix Tilemap not refreshed when the JSON file changed and a tileset JSON is also set (#2273) 2021-02-04 18:40:45 +00:00
Todor Imreorov
30aa5e78fd Fix Tilemap not showing the specified layer in "index" mode (#2260) 2021-02-02 20:45:40 +00:00
Todor Imreorov
3b0d272967 Fix middle-click drag not working in Yarn editor (#2257) 2021-02-01 21:51:17 +00:00
Florian Rival
153ccdb283 Add help links for Physics 2.0
Don't show in changelog
2021-02-01 08:57:32 +00:00
Florian Rival
093742621d Add help link for AdMob actions and conditions 2021-01-31 21:42:36 +00:00
Florian Rival
55422e1d8f Bump newIDE version 2021-01-31 19:25:14 +00:00
Florian Rival
5d2c861d6a Fix AdMob cordova plugin not used if only one app id is set
Don't show in changelog
2021-01-31 15:13:50 +00:00
Florian Rival
b73ddf2542 Update translations 2021-01-30 16:49:04 +00:00
Florian Rival
da4729c6f4 Upgrade Yarn Editor (integrated dialogue editor) to v0.4.116
Don't show in changelog
2021-01-30 15:17:08 +00:00
Todor Imreorov
643f495f83 Upgrade Yarn Editor (integrated dialogue editor) to v0.4.116 (#2226) 2021-01-30 15:13:36 +00:00
Aurélien Vivet
f8561369d9 Fix an expressions in geometry monster example (#2251)
Don't show in changelog
2021-01-30 15:39:03 +01:00
Florian Rival
c0d433f363 Refactor ParameterMetadata to be in its own file
Don't show in changelog
2021-01-30 13:01:36 +00:00
Add00
9c915ddae5 Add "Procedural generation" example (#2246) 2021-01-30 13:00:04 +00:00
D8H
7095bd863a Add support for isometry in the top-down movement behavior (#2237)
* Add an option to choose: classic top-down movement, isometry, 2:1 isometry or isometry with a custom angle.
2021-01-30 12:56:51 +00:00
Florian Rival
d12ebbea1c Fix formatting 2021-01-29 17:58:29 +00:00
Florian Rival
b8ede99715 Update AdMob to fix issues on iOS (#2223)
* Banners can't be overlayed on the game anymore. It's displayed either above or below.
* New conditions to check if interstitials, banner or reward videos encountered an error when loading.
* New action to set up the test mode for all ads at once
* App Id are now separated, with one for Android and one for iOS. Don't forget to update them before exporting your app, otherwise it would get terminated when started.
2021-01-28 22:30:54 +00:00
Florian Rival
d409c1cff0 Fix admob reference url
Don't show in changelog
2021-01-28 22:28:09 +00:00
Florian Rival
1a26bb748e Fix Flow restarting whenever a change is made in GDJS
Don't show in changelog
2021-01-28 21:30:29 +00:00
Prasad Dilip Patewar
ef1657d82a Fix formatting and grammar mistakes in various documentation files (#2243) 2021-01-28 14:31:59 +00:00
Arthur Pacaud
e44d9a64a2 Fix p2p dataloss mode (#2239)
Don't show in changelog
2021-01-25 15:01:26 +00:00
Arthur Pacaud
0bf6cf204b Fix new events received before old events in the p2p extension (#2238)
* Also add an expression to get the sender name.
* Also refactor the code internally to allow usage from JavaScript.
2021-01-25 10:46:13 +00:00
Nilay Majorwar
da089e1a75 Add tests for KeyboardShortcuts (#2231)
Don't show in changelog
2021-01-24 18:57:38 +00:00
Prasad Dilip Patewar
084f4c9173 Fix potential crash/memory corruption when updating an extension (#2228)
* This is done by closing the extension tab when an extension is updated/re-installed.
2021-01-23 17:00:42 +00:00
Florian Rival
d09a95227a Add CircleCi badge in the Nightly Build doc
Don't show in changelog
2021-01-23 13:00:17 +00:00
Florian Rival
e914da09c8 Fix pasting actions/conditions/events
Don't show in changelog
2021-01-23 12:50:10 +00:00
Florian Rival
d6d87c572d Fix compilation 2021-01-23 12:10:37 +00:00
Florian Rival
d6a94a3f9f Remove NEAREST texture mode applied to the tilemap atlas texture
Don't show in changelog
2021-01-22 18:52:17 +00:00
Florian Rival
9447cd9c57 Fix formatting 2021-01-22 18:39:56 +00:00
Florian Rival
2222aeb93e Fix Tilemap rotated tiles
Don't show in changelog
2021-01-22 18:20:58 +00:00
Florian Rival
162867659e Fix Tilemap help link
Don't show in changelog
2021-01-22 17:50:22 +00:00
Florian Rival
f35a3a6827 Improve description of all extensions
Don't show in changelog
2021-01-21 20:05:08 +00:00
Florian Rival
790117d66a Improve the wiki with automatically generated reference pages for all features (#2230)
* We now generate automatically reference pages for all the "official extensions" that are part of GDevelop. They are listing all the actions, conditions and expressions.
* The page with all expressions was slightly improved too.
* The page listing all the "community" extensions is now displaying icons and more details.
2021-01-21 18:15:43 +00:00
Florian Rival
ff55b8b6a0 Merge tutorials and video tutorials in a single tab in the Create Project window 2021-01-19 21:35:07 +00:00
Florian Rival
a98a855849 Fix incomplete implementation of the clipboard safety in last commit
Don't show in changelog
2021-01-19 15:42:19 +00:00
Harsimran Singh Virk
ef4c8b8621 Fix crash when using Pathfinding::DestinationX() and related expressions (#2227) 2021-01-19 16:17:41 +01:00
Florian Rival
3cd81bf324 Fix potential crashes because of bad content in the clipboard 2021-01-19 09:35:29 +00:00
Aurélien Vivet
eb7122584b Add menu item to move up and down parameters of functions and behavior methods (#1340) 2021-01-18 22:59:59 +00:00
Florian Rival
15e5640774 Fix platformer object behavior not working properly when the object also has the platform behavior 2021-01-18 22:26:18 +00:00
Florian Rival
e8f28141e3 Fix being unable to select any behavior other than the first one in the action/condition editor, when an object has multiple behaviors. 2021-01-18 20:09:10 +00:00
Florian Rival
ef86b2c121 Fix typing 2021-01-17 23:16:24 +00:00
Florian Rival
31e9378550 Export sourcemaps of the game engine/extensions in previews (#2207)
* Don't export sourcemaps for exported games
2021-01-17 22:11:32 +00:00
Florian Rival
006882a7c3 Fix scroll bar sometimes visible in the project loader
Don't show in changelog
2021-01-17 21:45:44 +00:00
Arthur Pacaud
5e453ddbdb Convert the p2p extension to Typescript (#2220)
Only show in developer changelog
2021-01-17 01:25:42 +00:00
arthuro555
8077bd41b1 Don't export sourcemaps on full builds 2021-01-17 00:29:01 +01:00
Aurélien Vivet
98a1d69489 Add actions, conditions and expressions for Shape Painter (#2203)
* Expressions to get the color of the outline or filling
* Expressions to get the opacity of the outline, filling and size of the outline
* Conditions/actions to check/change the usage of relative coordinates.
2021-01-15 16:14:26 +01:00
Florian Rival
d21a818223 Add check-format to the tests to ensure auto-formatting of GDJS and extensions
Don't show in changelog
2021-01-14 21:41:01 +00:00
Florian Rival
424dff32ff Fix formatting 2021-01-14 21:34:13 +00:00
Florian Rival
4b2cd90320 Add documentation of extensions in the generated GDJS documentation
Only show in developer changelog
2021-01-14 21:32:13 +00:00
Florian Rival
90680e47c4 Clean some outdated, unnecessary files
Don't show in changelog
2021-01-14 19:22:55 +00:00
Florian Rival
8cd5593182 Ensure the conditions column has a minimum size, to make them readable even when a lot of sub-events are used 2021-01-13 23:19:46 +00:00
Florian Rival
01207e797b Switch from "Runtime-Bundled" to "Runtime-dist" as dist is more commonly used
Don't show in changelog
2021-01-13 23:10:31 +00:00
Florian Rival
3e99779d56 Fix formatting 2021-01-13 22:30:05 +00:00
Florian Rival
9a4869269e Improve the search bar when adding an action/condition to search in *all* the existing actions and conditions. (#2208)
* This includes the object actions and conditions. If one is selected, the object can be chosen as a parameter.
* This should improve the search experience for both new and advanced users.
* This should reduce confusions for users searching for an action/condition and not finding it because they have not chosen an object first.
2021-01-13 22:23:35 +00:00
Florian Rival
9bcac613ed Fix broken JavaScript event autocompletions in the IDE
This was broken because the GDJS source files were missing, only the built files were considered.

The disadvantage of this change is having to copy more files everytime a change is made. The impact should be limited though as the copy time is in the same magnitude as before, and the alternative would be to emit .d.ts files which would force to run TypeScript compiler as part of the GDJS build process, and would make the TypeScript compiler time to complete at least 2x slower.
To keep iterations fast when working on GDJS, this approach is preferable.

Don't show in changelog
2021-01-12 23:07:59 +00:00
Rahul Saini
1d96a1bbfa Added a preference to toggle the visibility of menu bar in preview windows (#2199)
* By default, the menu bar is now hidden in previews (like in exported games)
2021-01-12 21:37:35 +00:00
Florian Rival
a946f01542 Fix long variable or object names overflowing how of the Events Sheet 2021-01-11 19:11:07 +01:00
arthuro555
629adcc6ba Export sourcemaps with the code 2021-01-11 11:39:56 +01:00
Florian Rival
7206c41955 Remove outdated documentation
Don't show in changelog
2021-01-10 13:43:29 +01:00
Florian Rival
d9862648d9 Merge pull request #2157 from 4ian/refactor/ts
Convert the game engine (GDJS) and the extensions to TypeScript
2021-01-09 14:21:19 +01:00
Florian Rival
87883290e5 Update readmes and docs to mention TypeScript 2021-01-08 22:32:31 +01:00
Florian Rival
542d0bceba Fix crash in HSHG after translation to TypeScript
Don't show in the changelog
2021-01-08 21:38:06 +01:00
Florian Rival
17d390fe64 Translate TileMap to TypeScript
Don't show in changelog
2021-01-08 19:55:26 +01:00
Florian Rival
d8f6fcc3e2 Update GDJS docs
Don't show in changelog
2021-01-08 19:55:23 +01:00
Florian Rival
65d3688052 Fix duplicate classes in the generated GDJS documentation
Don't show in changelog
2021-01-08 19:55:20 +01:00
Florian Rival
0095d7d038 Fix newIDE postinstall script
Don't show in changelog
2021-01-08 19:55:17 +01:00
Florian Rival
d4813282e8 Update documentation
Don't show in changelog
2021-01-08 19:55:13 +01:00
Florian Rival
638380c442 Add @ts-nocheck on some files to be converted later
Don't show in changelog
2021-01-08 19:55:10 +01:00
Florian Rival
ec73cc797e Fix Effects typing
Don't show in changelog
2021-01-08 19:55:08 +01:00
Florian Rival
9bb431e822 Fix TypeScript in FacebookInstantGames extension
Don't show in changelog
2021-01-08 19:55:04 +01:00
Florian Rival
7ef2e40066 Add more various fixes for TypeScript and code style
Don't show in changelog
2021-01-08 19:55:01 +01:00
Florian Rival
d0dba2a713 Fix typings in TypeScript files
Don't show in changelog
2021-01-08 19:54:56 +01:00
Florian Rival
d639e0ea6e Translate more files to TypeScript
Don't show in changelog
2021-01-08 19:54:52 +01:00
Florian Rival
326ebb231c Translate all objects to TypeScript
Don't show in changelog
2021-01-08 19:54:47 +01:00
Florian Rival
11d69e46ed Translate all behaviors to TypeScript
Also adapt custom behavior code generation to use a (partial) ES6 class (methods are still added using prototype)

Don't show in changelog
2021-01-08 19:54:41 +01:00
Florian Rival
8338ab666d Translate a bunch of GDJS files to TypeScript
Don't show in changelog
2021-01-08 19:54:37 +01:00
Florian Rival
522e62fa2f Manually translated gd.js to TypeScript
Don't show in changelog
2021-01-08 19:54:33 +01:00
Florian Rival
c50f2ad2c2 Add codemod to translate files to TypeScript with additional typings
Don't show in changelog
2021-01-08 19:54:19 +01:00
Florian Rival
e399366f5f Add esbuild to the GDJS Runtime 2021-01-08 17:09:42 +01:00
Florian Rival
d83ce0ed9d Rework objects recycling to be opt-in with a reinitialize method
Only show in developer changelog
2021-01-08 17:09:42 +01:00
Harsimran Singh Virk
a2e00e5adb Fix crash when lights used with obstacles in some conditions (#2194) 2021-01-08 16:37:35 +01:00
Rahul Saini
ae4d4d4983 Prevent files being overwritten when a resource is copied to the project folder (#2186) 2021-01-08 16:31:53 +01:00
Florian Rival
7fea44d40c Extend the Tilemap example with the tilemap containing rotated tiles
Don't show in changelog
2021-01-08 16:14:25 +01:00
Florian Rival
1bc225205b Add support for rotated tiles to Tilemap 2021-01-08 16:14:25 +01:00
Prasad Dilip Patewar
f8e4018d60 Fix URLs not opening in the system browser in previews or exported games (#2189) 2021-01-08 14:14:33 +01:00
Florian Rival
b475a2ed96 Fix typing 2021-01-07 10:12:48 +01:00
Prasad Dilip Patewar
df9d7d915f Fix missing translation markers (#2180)
Fix #2168
2021-01-06 09:11:14 +01:00
Gabriel
bb296dc34e Fix Space Shooter tutorial link (#2182) 2021-01-05 20:18:49 +01:00
Prasad Dilip Patewar
b1dad42a0e Add instructions about npm installation issue on WIndows (#2169)
Only show in developer changelog
2021-01-05 09:33:23 +01:00
Aurélien Vivet
8bdc710ac4 Fix wording (#2174) 2021-01-05 09:12:59 +01:00
Florian Rival
c115d61234 Add a platformer example using Tilemaps and update the other tilemap example. 2021-01-04 16:21:35 +01:00
Todor Imreorov
469310fa7d Add Tilemap: an object to display tile-based maps made using Tiled (#2147)
* Read the step-by-step explanations on how to use this object:  http://wiki.compilgames.net/doku.php/gdevelop5/objects/tilemap
* Download Tiled on https://mapeditor.org to author your own map/objects
2021-01-04 15:38:54 +01:00
Florian Rival
8f9a835a22 Fix firebase example for the web-app
Add error message to avoid similar issues in the future.
Use async/await in the script to regenerate example fixtures.

Don't show in changelog
2021-01-03 19:05:51 +01:00
Florian Rival
0b4e92651f Bump newIDE version 2021-01-03 14:37:20 +01:00
Florian Rival
329672d283 Log the time for the notarization process
Don't show in changelog
2021-01-01 21:00:03 +01:00
Florian Rival
139d0a6cea Update translations 2021-01-01 19:19:51 +01:00
Florian Rival
2da45c9691 Add missing translation marker
Don't show in changelog
2021-01-01 18:17:08 +01:00
Bouh
11e0059e89 Fix warnings 2020-12-31 16:41:12 +01:00
Aurélien Vivet
dbf2086318 Add missing translation tags for advanced events types (#2160) 2020-12-30 21:38:16 +01:00
Florian Rival
f7405839d3 Fix project not added to the list of recent projects after saving as a new file
* Also increase the size of the list of recent projects to 20 projects, instead of 5.
2020-12-29 23:25:22 +01:00
Florian Rival
e2943173be Fix extra spaces after colon and formatting
Don't show in changelog
2020-12-29 22:42:53 +01:00
Aurélien Vivet
0944ba18df Typo fix
Don't show in changelog
2020-12-29 22:39:17 +01:00
Florian Rival
e5ef299390 Update links in the Readme 2020-12-28 13:58:20 +01:00
Aurélien Vivet
64be893296 Typo fix
Don't show in changelog
2020-12-26 20:03:23 +01:00
Florian Rival
b6f0edf199 Add Box2D global variable declaration for TypeScript
Don't show in changelog
2020-12-24 14:28:45 +01:00
Florian Rival
0e4474c81d Normalize some typedefs and var declarations
Don't show in changelog
2020-12-24 14:18:13 +01:00
Florian Rival
da6aa18963 Add more documentation and type annotations to gdjs.SceneStack
Don't show in changelog
2020-12-24 14:07:30 +01:00
Aurélien Vivet
c2ab1bafed Add an action to change the ambient color of a lighting layer (#2149) 2020-12-23 22:02:42 +01:00
Florian Rival
105171e76b Move typedef to top of file
Don't show in changelog
2020-12-23 18:41:37 +01:00
Florian Rival
902228ef03 Autoformat runtimebehavior.js and separate typedefs into separate comments for easier parsing
Don't show in changelog
2020-12-23 18:29:31 +01:00
Florian Rival
e855bff28a Fix compatibility with Node.js 14
* Update Firebase dependencies to 8.0.2
* Update shelljs to 0.8.4 to avoid warnings

Only show in developer changelog
2020-12-22 17:36:46 +01:00
Florian Rival
15db3de2bd Fix table and markdown rendering after themes update
Don't show in changelog
2020-12-21 20:09:32 +01:00
Gabriel
100b902478 Add OS generated files to .gitignore (#2144)
Only show in developer changelog

Co-authored-by: The Gem Dev <53819287+the-gem-dev@users.noreply.github.com>
2020-12-21 19:23:43 +01:00
Dhruv Kapur
ea0ba1438d Add an expression to get the zoom of a camera on a layer: CameraZoom (#2145) 2020-12-20 17:43:20 +01:00
Florian Rival
903d4f8a65 Add Space Shooter to the list of tutorials 2020-12-19 12:14:55 +01:00
Florian Rival
e871a885a5 Fix some theme colors and theme in Storybook
Don't show in changelog
2020-12-18 22:15:45 +01:00
Ryan Anders
d8284d3e9b Simplify new themes creation: all themes now need just a single JSON file to be created (#2127) 2020-12-18 22:13:25 +01:00
Florian Rival
30f96205cb Make storage related actions resilient when the player disabled access to storage (like in Incognito mode in browsers) 2020-12-18 01:44:56 +01:00
Florian Rival
c1cbe951ac Improve docs, remove Cocos related classes from docs
Don't show in changelog
2020-12-18 01:16:28 +01:00
Florian Rival
a5fe658671 Improve docs
Don't show in changelog
2020-12-18 00:56:04 +01:00
Florian Rival
d8dadf9698 Improve docs and resilience against restricted localStorage access.
Don't show in changelog
2020-12-18 00:51:51 +01:00
Florian Rival
0c6511ac69 Modify tags in extensions made in the editor so that they are stored as an array of strings
Only show in developer changelog
2020-12-17 22:08:53 +01:00
Florian Rival
664b18556e Rework the extension search to be more powerful and similar to the Asset Store (#2140)
* Also improve the display of the icons and the descriptions of the extensions
* After installing a behavior, automatically navigate back to the list of behaviors
2020-12-16 21:13:34 +01:00
Florian Rival
2911297b18 Update Tetris demo 2020-12-16 08:34:52 +01:00
Florian Rival
08ac66fa7d Fix CircleCI workflow (#2134)
Don't show in changelog
2020-12-13 18:58:42 +01:00
Florian Rival
f500196ab2 Fix bad links in extension descriptions that would reload GDevelop 2020-12-12 17:20:38 +01:00
Florian Rival
b9cc5108a7 Fix games not working on iOS when exported from Windows 2020-12-12 16:47:20 +01:00
Florian Rival
1d9ce755e1 Fix platformer parallax not covering the whole screen size when the layer is zoomed-in
Don't show in changelog
2020-12-12 15:33:07 +01:00
Florian Rival
9a55feec9f Update the Firebase example
Don't show in changelog
2020-12-11 23:04:01 +01:00
Arthur Pacaud
ce38a7bbce Add support for using Google Firebase with your game (#1694)
* Use Firebase Analytics
* Store your game configuration in Firebase Remote Config
* Authentification, by email (or using providers like Google, Facebook **for browser games only**)
* Report measures to the Remote performance measurer
* Launch Firebase Functions
* Use the online Database (Firestore) and the Realtime Database
* Store data in the Online Filesystem.
2020-12-11 22:49:29 +01:00
Florian Rival
6a50183784 Fix description of mouse joint action 2020-12-11 09:46:33 +01:00
Jeremy Kahn
323d20130c Upgrade the Tween behavior internal engine "Shifty" to 2.14.1 (#2128)
* This brings performance improvements to the tweens and less memory usage
2020-12-11 09:33:11 +01:00
Florian Rival
275f699c5c Update the link to the platformer tutorial
* Thanks to David Turnbull for rewriting this tutorial as part of the Google Season of Docs program!
2020-12-10 09:12:09 +01:00
Florian Rival
352ac4b57c Update Tetris Demo 2020-12-10 09:10:19 +01:00
Florian Rival
285a46c596 Fix flow 2020-12-10 09:07:31 +01:00
Florian Rival
96dfd8a106 Allow line breaks to be displayed in the action/condition description 2020-12-09 22:17:45 +01:00
Florian Rival
71f61513de Add support for setting a help page for extensions made in the editor 2020-12-05 16:50:09 +01:00
Florian Rival
ab9431daa7 Fix missing icon sizes when exporting to iOS 2020-12-03 22:47:07 +01:00
Florian Rival
ac504ce485 Fix games not running when exported to iOS and built with Cordova/XCode
We're using cordova-plugin-ionic-webview which is maintained by the Ionic team and works out of the box on iOS (and Android) by serving files using a local server. Otherwise, WKWebView on iOS is not supporting loading local files (from file:// scheme). Not other alternative seem to be robust (for example cordova-plugin-wkwebview-file-xhr won't work properly with images to load). See the Ionic Webview test suite for en exhaustive list of everything that was tested: https://docs.google.com/document/d/19VQ-n7hGr9IDPPstQqU8_8WgqUh7R6sgQfL2neoT-Xw/edit
2020-12-03 20:37:05 +01:00
Florian Rival
1f0165cda7 Fix gravity and time scale Physics engine actions missing an object in the events sheet 2020-12-01 09:35:13 +01:00
Florian Rival
1b8521b991 Add Tetris demo to examples 2020-12-01 09:08:43 +01:00
Florian Rival
c30687693a Fix wav files not being played on Safari 14 2020-11-30 14:22:43 +01:00
Arthur Pacaud
c5fe498a1f Add a for each structure event (#2113)
* Add a for each structure event

* Apply review instructions to newIDE

* Fix naming in code generator

* Rename ForEachStructure

--> ForEachChildVariable

* Rename Structure and Variable

--> IterableVariableName and IteratorVariableName

* Delete old file

* Fix flow typing

* Remove unecessary includes

* Add key iterator, make iterators optional

* Clean up ForEachChildVariableEvent.js

* Add method on gdjs.Variable to replace children

* Add word warp to the event label
2020-11-29 18:50:07 +00:00
Florian Rival
c7907793ac Bump newIDE version 2020-11-27 09:54:33 +00:00
Florian Rival
2b156ef147 Add action to disable metrics 2020-11-26 15:27:47 +00:00
Florian Rival
f650a6aa9c Add support for registering a game and viewing its recorded metrics 2020-11-25 20:29:26 +00:00
Florian Rival
5d62f0c926 Send anonymous metrics when a game session starts
This allows to surface to game developers basic metrics, without using a third party or compromising the player privacy and without risking reducing the game performance.
2020-11-25 20:29:26 +00:00
Florian Rival
449a1f5da9 Increase the number of extensions shown in the Extensions search at once
Don't show in changelog
2020-11-25 17:36:18 +00:00
Florian Rival
a0e0fdf6e1 Add support for yes/no (or true/false) parameters for extensions made in the editor 2020-11-22 14:27:59 +00:00
Arthur Pacaud
036f384ff9 Fix lights crashing the game when WebGL is not supported (#2107) 2020-11-22 12:38:02 +00:00
Florian Rival
b42abf0cd8 Fix compilation 2020-11-20 09:22:58 +00:00
Florian Rival
ee699d3870 Fix warnings 2020-11-20 09:15:04 +00:00
Florian Rival
346eed3779 Improve UI of the dialog to edit the grid of the scene editor
Don't show in changelog
2020-11-20 09:10:36 +00:00
Sebastian Sangervasi
ef6f491fb4 Add an option to choose the color of the grid shown in the scene editor (#2104)
Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-11-20 08:57:44 +00:00
Florian Rival
ee6043477b Add projectUuid to help identifying projects uniquely
Can be useful for online services that need a way to identify a game uniquely
2020-11-18 21:59:18 +00:00
Florian Rival
deddfdc4cf Fix ObjectVarToJSON expression not working
Fix #2097
2020-11-16 23:03:49 +00:00
Arthur Pacaud
6ad69d4c74 Allow to specify a list of options for parameters of an action/condition of an extension made in the editor (#2046) 2020-11-15 12:37:48 +00:00
Florian Rival
6446bb20a0 Add workflow to automatically close bug reports that are not detailed
Don't show in changelog
2020-11-15 11:33:17 +00:00
Harsimran Singh Virk
015f9f64c7 Fix custom textures not working for light objects (#2090) 2020-11-14 14:52:11 +00:00
Florian Rival
74e5b30fd1 Simplify usage of some React contexts in MainFrame
Don't show in changelog
2020-11-12 22:42:59 +00:00
Florian Rival
057c0a1d13 Add support for the Asset Store on the desktop app
Also:
* Automatically download resources when a project made on the web-app is opened on the desktop-app
* Rework loader for when opening a project or launching a preview
* Shorten names for resources added from the resource store, in the web-app
2020-11-12 21:14:18 +00:00
Florian Rival
7f6c9923dc Fix changing opacity of Sprite objects not working for objects outside of the screen
Fix #2087
2020-11-12 09:18:01 +00:00
Arthur Pacaud
3dae7c1899 Add VS Code tasks for most common development tasks (#2083)
Only show in the developer changelog
2020-11-11 08:47:27 +00:00
Florian Rival
04c2abd508 Remove "projectFile" field from the project json files 2020-11-08 20:46:13 +00:00
Florian Rival
d82fd79186 Update some examples
Don't show in changelog
2020-11-07 15:33:17 +00:00
Florian Rival
fe312e0bf6 Add action/condition/expression to change the default Z order of objects created on a layer 2020-11-07 15:33:17 +00:00
Florian Rival
ad22a83680 Set objects created from events Z order so that they appear in front of objects that were on the scene at its startup 2020-11-07 15:33:17 +00:00
Florian Rival
ac32b677b0 Remove deprecated fields from project serialized json
Don't show in changelog
2020-11-07 15:33:17 +00:00
Florian Rival
902bc8a510 Move types definition of EventsFunctionContext to GDJS/Runtime
Don't show in changelog
2020-11-07 15:33:17 +00:00
Florian Rival
804c9563a1 Show a split button with a dropdown menu instead of a separate button to add a lighting layer
Don't show in changelog
2020-11-07 00:30:21 +00:00
Florian Rival
64996b5f7d Add an editor showing properties and effects for a layer (lighting layer or not) 2020-11-07 00:30:21 +00:00
Florian Rival
5fdf7be698 Fix re-opening last edited project not working on the web-app when using Google Drive as storage 2020-11-05 21:59:01 +00:00
Florian Rival
a869fc14f9 Fix proportional resize on the scene editor on touchscreens 2020-11-04 23:56:16 +00:00
Florian Rival
ae8a26b3f9 Try to workaround a Linux mouse freeze when renaming an item using an invalid name 2020-11-03 23:30:21 +00:00
Florian Rival
aaec53faaa Allow extensions to have icons set from an icon library 2020-11-03 22:16:22 +00:00
Florian Rival
bc56f820b3 Fix expression to read the window title crashing the game 2020-11-03 22:11:27 +00:00
Florian Rival
2c93c948bf Refactor to use shouldValidate instead of hardcoded key codes
Don't show in changelog
2020-11-02 22:16:40 +00:00
Florian Rival
fe3a2f6e4a Add CircleCI badge and reorganize a bit the README
Don't show in changelog
2020-10-31 15:30:28 +00:00
Florian Rival
449c96aaba Fix "Create" not shown anymore in object actions list
Don't show in changelog
2020-10-31 15:11:28 +00:00
Aurélien Vivet
4cee984472 Remove Create function from object list only (#2073) 2020-10-31 14:01:08 +00:00
Florian Rival
98c9763d1c Add proper support for keyboard for editing the parameters of events 2020-10-29 23:47:42 +00:00
Florian Rival
c3ed8cbbb4 Trap the focus in the inline parameter editor popover (don't let tab outside of it)
Also fix some fields not allowing to press Escape to close

Don't show in changelog
2020-10-29 23:47:42 +00:00
Florian Rival
65fc9f599e Fix formatting and tests 2020-10-29 23:47:42 +00:00
Florian Rival
10ebf9e65d Update package-lock.json 2020-10-29 23:47:42 +00:00
Florian Rival
d1b1e3b24e Fix variables inline editors that could not be closed with Escape
Don't show in the changelog
2020-10-29 23:47:42 +00:00
Florian Rival
188b262af0 Update material-ui and simplify SemiControlledAutoComplete 2020-10-29 23:47:42 +00:00
Florian Rival
a04c7f993f Fix the focus not being set back to the parameter after editing it inline in the events sheet 2020-10-29 23:47:42 +00:00
Florian Rival
13a8b5bce0 Fix the inline edition of parameters not applying changes when closed on a touchscreen 2020-10-29 23:47:42 +00:00
Florian Rival
45e6b19204 Allow the inline parameter popover to be closed with Escape 2020-10-29 23:47:42 +00:00
Florian Rival
0136445a65 Fix completions of expressions inserted twice on touch screens when choosing an object/behavior 2020-10-29 00:02:44 +00:00
Florian Rival
c26df2c8a9 Fix CircleCI configuration to avoid memory issues (#2035) 2020-10-27 10:54:16 +00:00
Florian Rival
f390d4a1bc Fix typo 2020-10-26 22:36:48 +00:00
Florian Rival
cc2cdc492e Improve/simplify platformer by using tweens for coins and enemies
Don't show in changelog
2020-10-26 22:34:49 +00:00
Florian Rival
feeebd0560 Fix potential crash/internal error when setting a keyboard shortcuts 2020-10-26 21:57:02 +00:00
Florian Rival
f6145f4c4e Add various expressions to get angles and distances between positions or objects (#2062)
* Add `DistanceBetweenPositions`, `AngleBetweenPositions`, `Object.AngleToObject`, `Object.AngleToPosition`, `Object.DistanceToPosition`, `Object.SqDistanceToPosition`.
2020-10-26 21:43:43 +00:00
Florian Rival
fd490e1d5a Add multiple improvements to the platformer starter
* Add ladder, checkpoints, collision with enemies (thanks @Bouh!)
* Add fade in when going back to checkpoint and sound effects
* Fix some sound effects
2020-10-26 17:40:11 +00:00
Florian Rival
4760b0ab04 Fix tweens not properly applied when only one object with the Tween behavior was created in the scene 2020-10-26 17:33:17 +00:00
Aurélien Vivet
3f95bf9f1a Increase and make responsive the height of selectors in the instruction editor. (#2058) 2020-10-26 15:05:19 +01:00
Aurélien Vivet
76b63c2f76 Make zoom direction in animation preview and hitbox editor consistent with the rest of the editor. (#2056)
Don't show the rest in the changelog:
* Inverse zoom in preview animation and hitbox editor.
* Make consistent with zoom direction in scene editor.
* Prettier
2020-10-26 14:55:55 +01:00
Aurélien Vivet
0a501f5a3c Rename the action Global color to Tint (#2057)
Don't show the rest in the changelog:
Because global color is false and misleading.
2020-10-26 14:53:18 +01:00
Florian Rival
45ab608409 Add a workflow to close issues with missing examples
Don't show in changelog
2020-10-26 13:15:08 +01:00
Aurélien Vivet
df94a4d0fb Minor fixes (#2049)
Don't show in changelog
* Fix names functions from Tween-test example
* Typo movement
* The word was sticked on crowdin.
2020-10-25 15:04:33 +01:00
Florian Rival
c7d3d1314d Fix "pinch to zoom" sometimes wrongly triggering the opening the objects editor on touchscreens 2020-10-23 18:51:55 +02:00
Florian Rival
cff1a1e3c7 Fix Typescript error
Don't show in changelog
2020-10-22 09:24:10 +02:00
Florian Rival
3cf421f05b Fix orientation lock throwing an unhandled error on desktop
Also fix formatting

Don't show in changelog
2020-10-22 09:14:34 +02:00
Florian Rival
6cc5016f9e Make the GenerateAllDocs script fail if some documentation generation errors
Don't show in changelog
2020-10-21 14:48:16 +02:00
Arthur Pacaud
2dd62456c2 Use a new theme for the JavaScript game engine documentation (#1672)
* Also add missing functions in the documentation.

Only show in the developer changelog
Co-authored-by: Florian Rival <Florian.rival@gmail.com>
2020-10-21 14:42:25 +02:00
Arthur Pacaud
d8b1c471bb Fix events sheet not adapting immediately after window resize (#2033) 2020-10-19 23:39:59 +02:00
Arthur Pacaud
a3622a6504 Fix actions to set opacity and position of the window on Windows/macOS/Linux (#2044)
* Also add a warning on "dangerous" functions of advanced window controls that could block the preview.
2020-10-19 18:59:26 +02:00
Aurélien Vivet
4ab14d18f8 Add width and height actions for Tweens (#2041)
* Add width and height actions for Tweens.
* Add width and height tweens to the example.

Show the rest in the developer changelog

* Clean the example Tween-test
* Generate fixtures for the webapp
2020-10-19 13:44:00 +02:00
Arthur Pacaud
8ba11703e1 Allow to change shortcuts by clicking on them in the preferences (#1948) 2020-10-19 12:22:32 +02:00
Arthur Pacaud
8a8adf213a Fix potential orientation lock issues on Android (#2034) 2020-10-19 12:12:56 +02:00
Florian Rival
25ea23a115 Store if a JavaScript code block is expanded or not
Don't show in changelog
2020-10-19 09:35:19 +01:00
Arthur Pacaud
586694543d Add The gem dev to contributors list (#2045)
Don't show in changelog
2020-10-19 08:59:05 +01:00
Sebastian Sangervasi
b7b6ab91f5 Allow the JavaScript code blocks in events to be expanded to view more lines (#2037)
Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
Co-authored-by: Florian Rival <Florian.rival@gmail.com>
2020-10-19 08:53:31 +01:00
Arthur Pacaud
d2d0235c8c Use Nord as the default theme if the system theme is dark on macOS (#1950) 2020-10-18 14:16:13 +01:00
Florian Rival
b473e0aaf0 Add button to paste condition/actions after right clicking "Add condition/action" 2020-10-17 12:37:03 +01:00
Florian Rival
b2c7166b1b Fix completions of expressions inserted twice on touch screens 2020-10-17 11:48:14 +01:00
Florian Rival
bb2ae1a914 Replace "return true if" by "check if" in description of conditions
Don't show in changelog
2020-10-17 11:25:16 +01:00
Florian Rival
aa1c5584ca Fix examples resources not deployed after the web-app is deployed
Fix #2038

Don't show in changelog
2020-10-16 14:06:26 +01:00
Florian Rival
28593608a5 Bump newIDE version 2020-10-16 13:52:20 +01:00
Florian Rival
8c5a312725 Set the production url for the asset api
Don't show in changelog
2020-10-16 13:51:54 +01:00
Sebastian Sangervasi
3ed07dee5e Fix margins/widths/extra scrollbars of the JavaScript code block events (#2036)
Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-10-16 09:18:08 +01:00
Florian Rival
e1cb634e3d Update CircleCI configuration to have more memory
Don't show in changelog
2020-10-15 17:42:16 +01:00
Sebastian Sangervasi
f0392cfede Add examples of Tween animations (#2025)
* "Tween animations" example by @ssangervasi
* "Tween Test" example by @Wend1go 

Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-10-15 08:58:19 +01:00
Florian Rival
0bce1fc56b Don't prefetch assets on the desktop app
Don't show in changelog
2020-10-14 23:58:36 +01:00
Florian Rival
b7aaf32d75 Update translations 2020-10-14 23:54:47 +01:00
Florian Rival
0dce21904e Add multiple fixes to the Asset Store
Don't show in changelog
2020-10-14 23:36:21 +01:00
Florian Rival
ca877e518e Display an info bar after adding an asset for the first time
Don't show in changelog
2020-10-14 23:36:21 +01:00
Florian Rival
f87ace7e25 Add links to author websites and licenses in the Asset Store
Don't show in changelog
2020-10-14 23:36:21 +01:00
Florian Rival
8954df947d Fix inheritance typing of events
Don't show in changelog
2020-10-14 23:36:21 +01:00
Florian Rival
52a2f3653f Remove CustomizationFields for the AssetStore as it's not ready yet.
Don't show in changelog
2020-10-14 23:36:21 +01:00
Florian Rival
04a896de59 Add a store to choose resources when editing an object in the web-app 2020-10-14 23:36:21 +01:00
Florian Rival
8c6b9ef044 Add a basic Asset Store for the web-app 2020-10-14 23:36:21 +01:00
Florian Rival
45d7c6188b Add latest tutorials from Wishforge games 2020-10-14 21:56:47 +01:00
Sebastian Sangervasi
10eb944b2a Fix optional parameters wrongly included in an expression when not filled in the expression parameters window (#2024)
Fix #1533
Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-10-13 23:32:34 +01:00
Sebastian Sangervasi
a607c820a8 Fix grid snapping being disabled after Alt+Tabbing to another window (#2027)
Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-10-13 09:20:18 +01:00
Florian Rival
0c22c52a78 Fix changes in extensions not properly applied when previewing a game in the web-app 2020-10-11 23:49:22 +01:00
Florian Rival
06748e00e1 Fix platformer having invalid resources
Don't show in changelog
2020-10-11 23:43:19 +01:00
Florian Rival
8b39233f44 * Update guidelines about JS code style in the game engine
* Android 4.x and IE 11 are officially not supported.

Only show in the developer changelog
2020-10-11 18:00:11 +01:00
Florian Rival
f68842bdb1 Add a condition to check if the device has a touchscreen
* Also improve performance of condition checking if the device is a mobile device.
2020-10-10 18:46:58 +01:00
Florian Rival
544b88fec9 Force proportional resize on touchscreens
Don't show in changelog
2020-10-10 17:38:17 +01:00
Florian Rival
48fe0fa2a6 Fix potential loading ("CORS") issues in game previews in the web-app 2020-10-10 16:35:38 +01:00
Florian Rival
e7ef94de5f Add ids to errors being reported in the app
Don't show in changelog
2020-10-10 13:33:52 +01:00
Florian Rival
1ffe5b0e9f Add Layer Effects example (Thanks @the-gem-dev!) 2020-10-09 19:17:51 +01:00
Florian Rival
9282c0bcef Update translations 2020-10-08 23:39:39 +01:00
Florian Rival
28d180e6fe Improve platformer starter game with a parallax background 2020-10-08 22:52:41 +01:00
Florian Rival
8cd1ea6b73 Make multiple fixes and improvements to FileSystem
* Fix FileSystem::ExecutablePath description
* Add FileSystem::ExecutableFolderPath expression to get the path to the folder where the game executable is located.
* Add expressions FileSystem::DirectoryName, FileSystem::FileName and FileSystem::ExtensionName to extract part of a path.
* Fix FileSystem::UserHomePath expression not working
2020-10-08 22:09:49 +01:00
Florian Rival
b0e63460cf Fix TypeScript errors in AdvancedWindow 2020-10-08 21:42:54 +01:00
Florian Rival
a5e372ea35 Add missing icon for creating new project in the web-app
Don't show in the changelog
2020-10-08 09:20:56 +01:00
The Gem Dev
8f2c24e9e0 Add new icons for starter games when creating a new project (#2001) 2020-10-08 09:15:09 +01:00
Aurélien Vivet
dbd97ac23c Clean file from platformer example
Don't show in changelog
2020-10-05 18:34:40 +02:00
Arthur Pacaud
d0b36b9d77 Show the description of the expression when filling the parameters of an expression (#2009) 2020-10-05 15:57:36 +01:00
Florian Rival
d1aa54b215 Allow whole object row to be dragged on touchscreens
* Also show a "jiggle" animation to draw user attention.
2020-10-03 17:14:46 +01:00
Florian Rival
c14f94b807 Remove the buttons to set the window fullscreen
Don't show in changelog
2020-10-03 17:08:55 +01:00
Florian Rival
685156b0cf Fix images somtimes not loading and export sometimes erroring in the web-app 2020-10-03 16:34:46 +01:00
Florian Rival
b4c5c01109 Fix Flow errors from an outdated JSS version
Don't show in changelog
2020-10-03 00:03:07 +01:00
Harsimran Singh Virk
238bf27671 Fix game crash with lights when the device is lacking WebGL support (#1979) 2020-10-02 23:46:37 +01:00
Florian Rival
4dd001951c Update @material-ui/lab
Don't show in changelog
2020-09-27 17:06:47 +01:00
Florian Rival
e6c483f398 Allow objects to not defined a renderer object without crashing the game
Don't show in changelog
2020-09-27 16:41:58 +01:00
Florian Rival
4030f29d84 Fix formatting 2020-09-27 16:09:12 +01:00
Florian Rival
4b389016e9 Fix flow, warnings, add comments about next steps for full RTL support
Don't show in changelog
2020-09-27 13:03:37 +01:00
Cristian Tudorache
659d19b771 Add basic support for right-to-left languages (#1997) 2020-09-27 13:03:10 +01:00
Florian Rival
2524292ae1 Update package-lock.json 2020-09-23 23:34:59 +00:00
Florian Rival
32d95da2ea Fix warning 2020-09-23 23:33:07 +00:00
Arthur Pacaud
8ff4876f77 Add more actions/conditions/expressions to manipulate the window on Windows/Linux/macOS (#1994)
* Allow to set the position of the window, minimize/maxizime it, resize it,
* Allow to enter a fullscreen and "Kiosk mode" (where the user can't disable the fullscreen),
* Allow to set the window opacity, enable/disable shadow (according to the OS) and use other advanced features.
2020-09-20 17:42:16 +02:00
Arthur Pacaud
cb36057014 Add condition to check if the game is in fullscreen mode (#1992) 2020-09-20 14:00:35 +02:00
Arthur Pacaud
53a1024053 Update howler (#1982) 2020-09-19 10:12:01 +00:00
Florian Rival
16f3a1901d Fix focus being lost when redefining a variable in the instance properties editor 2020-09-18 10:59:02 +02:00
Aurélien Vivet
43c420dff0 Add missing translations (#1942)
Don't show the rest in the changelog:
* Add I18n to context menu and electron menu
* Add a missing Trans component in Behavior editor
2020-09-15 18:32:22 +02:00
Aurélien Vivet
265a86e41f Remove PIXI hack in renderer objects (#1987)
* Remove hack for opacity on sprite

* Remove hack opacity on tiled sprite
2020-09-15 11:24:59 +00:00
Aurélien Vivet
2c53b3b7a2 Fix margins around renamed list items (#1976)
* Fix css in list and textfield

When renaming in an list:
- Fix padding because text was cropped
- Fix z index because text was behind the bottom border
- Remove speelcheck (useful for remove the red wave under a word in the webapp)

* Remove z-index, increase padding bottom

* Align text in textfield with near text

* Factor resourcesSelector styling

* Make typing of ResourceSelector styling stricter

Co-authored-by: Florian Rival <Florian.rival@gmail.com>
2020-09-13 12:55:31 +00:00
Florian Rival
e87d5e1d52 Fix memory leak when reloading resources from objects (#1975) 2020-09-10 18:11:11 +00:00
Florian Rival
cb6130ffee Remove automerge in favor of Mergery 2020-09-10 18:30:57 +02:00
Florian Rival
0a742bf362 Fix warning shown when compiling GDevelop.js 2020-09-10 16:25:20 +00:00
Florian Rival
f419186c65 Add automerge
This allows to automatically merge pull requests when needed.

Don't show in changelog
2020-09-10 18:23:55 +02:00
Aurélien Vivet
103c99f545 Fix outlines in shape painter object, they wasn't visible in an specific use (#1971) 2020-09-08 16:32:39 +02:00
Arthur Pacaud
d08f4dc059 Multiple fixes for the P2P feature (#1967)
* Fix "Send variable to all peers" action
* Multiple disconnection from remote instances can now be tracked using events
* Add a condition to detect when another instance connects remotely to the current instance
2020-09-08 09:24:18 +02:00
Florian Rival
2a62f71f08 Add lighting extension on the web-app
Don't show in changelog
2020-09-03 20:37:54 +01:00
Florian Rival
331e847b3f Fix long touch wrongly detected when finger is moved
Don't show in changelog
2020-09-03 20:26:05 +01:00
Florian Rival
95b4a43e11 Don't autofocus search bars on touchscreens
Don't show the rest in the changelog:

Also add support for long press on list items on Safari iOS
2020-09-03 19:22:14 +01:00
Florian Rival
9943dc650e Adapt events sheet margins for small screens
Don't show in changelog
2020-09-03 19:22:14 +01:00
Florian Rival
b09f62ce57 Add support for context menus via a long touch on Safari iOS in Sprite editor
Don't show in changelog
2020-09-03 19:22:14 +01:00
Florian Rival
32427b2357 Add padding to the hit area of resize/rotate buttons on touchscreens 2020-09-03 19:22:14 +01:00
Florian Rival
3c3bfbbf5d Add support for context menus via a long touch on Safari iOS 2020-09-03 19:22:14 +01:00
Florian Rival
64c732d2bb Add support for safe area (Safari) for MainFrame, Dialog and the Project Manager
Don't show in changelog
2020-09-03 19:22:14 +01:00
Florian Rival
23d64aa676 Fix crash/error when exporting to Windows/macOS/Linux 2020-09-01 19:04:32 +01:00
The Gem Dev
532b86ac58 Added link to GDevelop reddit page on start tab (#1935) 2020-09-01 15:05:09 +02:00
Florian Rival
e1bf859ff4 Fix tween behavior not working with BB Text object color 2020-08-31 16:04:22 +01:00
Florian Rival
1ad20ec6c9 Fix Light tests
Don't show in changelog
2020-08-31 13:59:06 +01:00
Florian Rival
b5990ecbe3 Fix tween behavior sometimes not working properly 2020-08-31 13:29:03 +01:00
Florian Rival
f2287dd1ef Fix tween behavior not working with Light object color 2020-08-31 13:27:51 +01:00
Florian Rival
a8714b8522 Bump newIDE version 2020-08-31 00:35:57 +01:00
Florian Rival
ddf0ba7efd Update electron-builder to avoid packaging issues on macOS Catalina
Don't show in changelog
2020-08-31 00:35:25 +01:00
Florian Rival
9e8491420d Add example for the Light objects 2020-08-31 00:30:04 +01:00
Florian Rival
075d918619 Update translations 2020-08-30 22:31:34 +01:00
Florian Rival
b68dfe040e Fix warning 2020-08-30 21:34:52 +01:00
Florian Rival
053f4a68df Add link to more tutorials by Wishforge Games (https://www.youtube.com/channel/UCxsQHU5SwYtO6uc1jiLdvrg) 2020-08-30 21:34:38 +01:00
Florian Rival
216fd30145 Remove a useless translation marker
Variables can't be translated magically like this :)

Don't show in changelog
2020-08-30 20:10:58 +01:00
Florian Rival
fda75e0475 Improve changelog extractor
Don't show in changelog
2020-08-30 12:28:37 +01:00
Florian Rival
7fe057c180 Improve alerts display on small screens 2020-08-30 00:27:03 +01:00
Florian Rival
5d091c0a87 Add multiple light objects fixes (#1929)
Don't show in changelog
2020-08-29 18:52:36 +01:00
The Gem Dev
319cea428e Update the AdMob icon (#1953) 2020-08-29 18:10:45 +01:00
Florian Rival
0ac2ef7892 Allow extensions to require @pixi/... modules in the IDE
Don't show in the changelog
2020-08-29 17:16:51 +01:00
Aurélien Vivet
fd6b9be49c Add a section for developers in the release notes (#1892)
Only show in the developer changelog
2020-08-28 19:06:42 +01:00
Harsimran Virk
2d6f0fad90 Added a polygon to replace the use of hitbox in raycasting algo. 2020-08-26 15:59:27 +05:30
Florian Rival
35f019afa8 Add "Game Feel Demo" by Sleeper Games
* See these game feel examples in a complete game powered by GDevelop: http://hyperspacedogfights.com/
2020-08-26 09:29:41 +01:00
Florian Rival
f7453a6a1d Update yarn.lock 2020-08-26 00:07:46 +01:00
Nilay Majorwar
89570505e6 Add support for customizable keyboard shortcuts (#1938)
* In the preferences, browse the list of existing shortcuts. Try the existing one to speed up your creation worflow! For example, press *F5* to launch a preview.
* For each command available in the command palette, a shortcut can be added, changed or removed.
2020-08-25 23:54:24 +01:00
Florian Rival
082318d7e4 Fix vibration not working in exported Android games.
Fix #1922
2020-08-24 23:13:48 +01:00
Florian Rival
59c9812208 Only add the AdMob plugin when the AdMob App Id is set (#1940)
Don't show in changelog
2020-08-24 22:54:51 +01:00
Florian Rival
62117e42d9 Make the action to send a web request "asynchronous" (not blocking the game execution) (#1937)
* The result from the request is stored in the specified variable (and any error in a second variable)
* This avoids blocking the game execution while the request is being made, and allow multiple requests to be made at the same time.
2020-08-24 20:51:37 +01:00
Arthur Pacaud
cafa0d512f Allow extensions to declare dependencies (npm, cordova...) and custom properties in the project (#1717)
Only show in developer changelog
2020-08-24 20:51:10 +01:00
Harsimran Virk
136964053b Renamed variables and changed doc 2020-08-21 12:52:08 +05:30
Harsimran Virk
6beea7bfaf Changed default ambient light color to (200, 200, 200) 2020-08-20 19:39:11 +05:30
Harsimran Virk
ab6999a16c Working expanded bounding box. 2020-08-19 19:06:10 +05:30
Harsimran Virk
937fd1888a Fixed a weird bug related to debug graphics. 2020-08-19 18:12:49 +05:30
Harsimran Virk
755c72c0bf Fixed undefined handling of light obstacle manager. Moved texture handling in renderer. 2020-08-19 16:20:36 +05:30
Florian Rival
20392d6a79 Update newIDE/electron-app/app/package-lock.json 2020-08-19 09:44:56 +02:00
Florian Rival
0a2033db3d Improve changelog extractor with more ignored messages
Don't show in changelog
2020-08-19 09:43:53 +02:00
Florian Rival
6c0fe0359a Add experimental Peer-to-Peer communication extension (#1842)
* This allows to transmit messages on the network to different remote players, enabling simple multiplayer games.
* Read the [documentation on the wiki](http://wiki.compilgames.net/doku.php/gdevelop5/all-features/p2p) to understand how it works, limitations and capabilities of the extension. In particular, for released games, it's recommended that you host a *broker server* allowing game instances to be discovered and connected.
2020-08-18 22:38:45 +02:00
Florian Rival
66ed1110d2 Update JsExtension.js 2020-08-18 22:36:11 +02:00
Florian Rival
5badb27b35 Update light descriptions and default color
Don't show in changelog
2020-08-17 18:23:10 +02:00
Harsimran Singh Virk
b7902bb141 Add support for dynamic 2D lights (#1881)
* This adds a **Light** object that can be added on the scene, with a customizable color and radius.
* Add the **Light Obstacle** behavior to the object that must acts as obstacle (walls, etc...) to the lights.
* You can customize the ambient color of the rest of the scene from almost white (useful to show light shadows) to entirely black (useful for horror/exploration games) or any color.
* Use effects on the "Lighting" layer like "Kawase Blur" to achieve soft shadows.
2020-08-17 17:48:26 +02:00
Aurélien Vivet
b5b3abd155 Upgrade to Pixi 5.3.3 (#1925) 2020-08-17 17:15:20 +02:00
Aurélien Vivet
06b299c4a2 Delete the artefact Thumbs.db from Windows OS
Previously added in
https://github.com/4ian/GDevelop/pull/1858

Don't show in changelog
2020-08-17 11:47:06 +02:00
The Gem Dev
e42d2cbc6d Add Solarized Dark theme (#1858)
* A new Dark theme based on [Solarized color scheme](https://ethanschoonover.com/solarized/).
2020-08-13 12:06:37 +02:00
Arthur Pacaud
454159db3f [Final Fixes] Add discord rich presence (#1915)
* Add Discord rich presence to GDevelop

* Prettier

* Add error handling when discord not installed

* Try to fix flow typing

* Fix typo

* Fix typo not fixed in last commit

* Switch to hook in mainframe

And apply other review instructions

* fix flow

* Final Fixes
2020-08-12 21:25:32 +02:00
Florian Rival
4324526689 Fix behavior not destroyed in a live preview when the behavior is removed from an object 2020-08-12 16:19:48 +02:00
Florian Rival
b57832a131 Allow modules loaded by extensions to require "pixi.js" in addition to "pixi.js-legacy"
This should allow to not "hack" 3rd party modules so that they require "pixi.js-legacy" instead of "pixi.js". In both cases, we return "pixi.js-legacy".

This still requires modules to be supporting CommonJS (for Electron) and the global PIXI variable (for browsers).
2020-08-12 11:41:02 +02:00
Rahul Saini
8d9f5f0df0 Add script to generate list of community-made extensions (#1913) 2020-08-10 18:44:05 +02:00
Arthur Pacaud
b6ec327dfc Add 4ian as a GitHub codeowner (#1914)
Don't show in changelog
2020-08-09 21:54:36 +02:00
Sanskar Bajpai
005aa64aad Add a close button at the bottom of the search panel
* Feature: Added a close button on the panel.

Implements #1909.

* Stories: Added the new prop in Stories.

This commit introduces the addition of the onCloseSearchPanel prop in the Stories
thus removing all the flow errors. Prettier code formatting has also been run to make
the code look cleaner, and lastly the prop has been destructured in the
SearchPanel.js file.
2020-08-08 19:21:18 +02:00
Arthur Pacaud
a18b813140 Update phonegap-build Version to v9 (#1912) 2020-08-08 14:32:47 +02:00
arthuro555
7cd28062fc Update fixtures 2020-08-08 12:06:14 +02:00
Aurélien Vivet
2b7e2c8814 Fix Menu import in Electron exported games (#1911)
Don't show in changelog
2020-08-07 18:50:30 +02:00
Florian Rival
767f365a78 Revert usage of pick in GenerateObjectCondition
Don't show in changelog
2020-08-05 18:47:39 +02:00
Florian Rival
5f54583ff5 Add TypeScript checks to gdjs.RuntimeScene, gdjs
Only show in developer changelog
2020-08-05 18:47:39 +02:00
Florian Rival
37c260c19d Remove methods polluting Array prototype in gd.js
Only show in developer changelog
2020-08-05 18:47:39 +02:00
arthuro555
003f251c9f Apply review instructions 2020-08-03 23:48:10 +02:00
arthuro555
f8250ec9aa Regen fixtures 2020-08-02 21:34:18 +02:00
arthuro555
aeb4d278cd Merge branch 'master' into add-multiplayer-p2p 2020-08-02 21:31:28 +02:00
Florian Rival
2762329dd6 Update game fixtures for the web-app
Don't show in changelog
2020-08-02 18:38:14 +01:00
Florian Rival
75b1ff5cea Improve changelog extractor
Don't show in changelog
2020-08-02 18:18:36 +01:00
Florian Rival
1f4042bff0 Fix menu bar shown in exported games on Windows/macOS/Linux 2020-08-02 15:28:34 +01:00
Florian Rival
4e04e79b2f Bump newIDE version 2020-07-29 00:13:15 +01:00
Florian Rival
b9ba8e1b7b Update translations 2020-07-28 22:33:49 +01:00
Florian Rival
84ea9a9643 Merge branch 'master' of github.com:4ian/GDevelop 2020-07-28 20:26:28 +01:00
Nilay Majorwar
13c44250f2 Add network preview command, hide debug and network preview commands on web (#1896)
Don't show in changelog
2020-07-28 17:31:20 +01:00
Florian Rival
a5907a6883 Enable the Command Palette by default in the preferences for new users
* If you want to use the Command Palette and have GDevelop already installed, activate it in the preferences
2020-07-28 09:06:13 +01:00
Florian Rival
5902906bcc Add Health Bar And Health Potion video tutorial
Don't show in changelog
2020-07-28 09:05:42 +01:00
Florian Rival
4db041bf10 Add subscription reminder once in a while when using hot-reloading.
Don't show in changelog
2020-07-27 23:36:18 +01:00
arthuro555
63894f9a86 prettier 2020-07-27 22:41:13 +02:00
arthuro555
9a0ec853e7 Try to fix flow again 2020-07-27 15:56:36 +02:00
arthuro555
eb5d120aaf Try to fix flow
Flow doesn't work locally so I have to wait for travis output to be sure
2020-07-27 15:30:52 +02:00
arthuro555
057dd985fc Fix flow typing 2020-07-27 13:16:51 +02:00
arthuro555
8009e45936 Add files forgotten in last commit 2020-07-27 13:16:26 +02:00
arthuro555
b190731940 Change way Peer JS is initialized and update example 2020-07-27 12:40:58 +02:00
arthuro555
a337230195 Add disconnection events 2020-07-26 23:06:55 +02:00
arthuro555
731b9141fa Run prettier 2020-07-26 19:52:05 +02:00
arthuro555
51ba2e7631 Add hints for peer to peer 2020-07-26 19:50:49 +02:00
arthuro555
48a0c2d324 Regenerate fixtures for examples 2020-07-26 13:32:27 +02:00
Arthur Pacaud
25d32ce9bb Merge branch 'master' into add-multiplayer-p2p 2020-07-26 13:28:55 +02:00
arthuro555
a7ec57354d Update example 2020-07-26 13:24:45 +02:00
Florian Rival
cc1d26201e Update yarn.lock
Don't show in changelog
2020-07-26 12:18:17 +01:00
arthuro555
643e3b5c32 Add basic error handling 2020-07-26 13:15:07 +02:00
arthuro555
0cc4676067 Add is p2p ready condition 2020-07-26 12:52:48 +02:00
arthuro555
91b895fd92 Fix event data on no dataloss mode 2020-07-26 12:38:18 +02:00
arthuro555
f95d0ae461 Let user choose incoming message handling 2020-07-26 12:18:46 +02:00
arthuro555
81ce81242b Add option to use own server 2020-07-26 11:19:02 +02:00
Florian Rival
aa71e78507 Add Video tutorials and hints about these tutorials in the editor
* Thanks Wishforge Games (http://wishforge.games/) for these very high quality video tutorials!
2020-07-26 00:49:55 +01:00
Florian Rival
ee49ca6c14 Add support for layer re-ordering in hot reloading
Don't show in changelog
2020-07-25 23:27:23 +01:00
Florian Rival
a649789f4c Improve some typings in GDJS Runtime
Only show in developer changelog
2020-07-25 22:19:35 +01:00
Florian Rival
61e8e95d5b Add typing for PIXI in GDJS Runtime
This means that the global object PIXI will now be properly typed and understood by TypeScript.

Also fix documentation generation

Don't show in changelog
2020-07-25 18:56:38 +01:00
Florian Rival
cc158a9250 Add some standard libraries to the libraries used by Typescript to do the type checking
Don't show in changelog
2020-07-25 18:31:38 +01:00
Florian Rival
a91ccacb89 Improve typing in hot-reloader.js
Promise and other specific standard types can actually be imported using a triple slash directive.

Don't show in changelog
2020-07-25 18:27:05 +01:00
Florian Rival
bb9e8a2ea9 Merge pull request #1840 from 4ian/feature/hot-reload
Add "live previews" a.k.a "hot reloading"
2020-07-25 14:43:34 +01:00
Florian Rival
3bf40cd46c Fix hot-reloading of extensions in Network Preview and fix reloading of some events generated code files
Don't show in changelog
2020-07-25 14:23:02 +01:00
Florian Rival
aa823c1287 Make Network Preview (Preview over Wifi) compatible with live preview ("hot reloading")
* Also allow the debugger to work with games run using Network Preview (Preview over Wifi), including on other devices (phones, tablets...)

Don't show the rest in the changelog:

This removes the "live reloading" of the network preview and makes the hot-reloading and debugging to work with the network preview.
2020-07-25 14:23:02 +01:00
Florian Rival
24a666ab83 Fix hot-reloading of Anchor behavior and BBText and Text objects width
Don't show in changelog
2020-07-25 14:23:02 +01:00
Florian Rival
9e652b228d Don't reload fonts already loaded during a hot-reload
Also only issue a single request when multiple audio resources are pointing to the same file.

Don't show in changelog
2020-07-25 14:23:01 +01:00
Florian Rival
09bedc6ce5 Ensure events generated code is stable across code generation.
This is done by given unique identifiers to "Trigger Once" conditions (stable given the same object in memory) and events list function names (stable given events with same content).

This avoids useless hot-reloading and re-triggering Trigger Once conditions after a hot-reloading.

Don't show in changelog
2020-07-25 14:23:01 +01:00
Florian Rival
91e57340d4 Update icons and fix stale icons in Debugger Toolbar when selecting game
Don't show in changelog
2020-07-25 14:23:01 +01:00
Florian Rival
c385aae845 Add support for "hot reloading" of previews (apply changes to preview without restarting) 2020-07-25 14:23:01 +01:00
Florian Rival
460b582ab9 Refactor changes cancelling of GDevelop.js objects
* Use a typed hook (shorter and type-safe to use)
* Avoid the necessity of providing a function to create an object.
* Only unserialize back to the object if cancelling changes (instead of when applying).
2020-07-25 14:23:00 +01:00
Florian Rival
3a9f896f04 Add hot reloader (electron app only) 2020-07-25 14:23:00 +01:00
Florian Rival
2851a20787 Add persistentUuid to gd::InitialInstance 2020-07-25 14:22:59 +01:00
Florian Rival
9077c5d4f7 Fix saving a file potentially resulting in an empty file in some circumstances
* File integrity is now checked after a project is saved.
* Prevent concurrent save of a file (could happen if Ctrl+S/Cmd+S was kept pressed, and could result in an empty file being saved on disk).

Fix #1813
2020-07-25 14:22:04 +01:00
Arthur Pacaud
693b64cddf Fix documentation typo (#1882)
Don't show in changelog
2020-07-20 16:53:55 +01:00
Florian Rival
661d329170 Upgrade game rendering to use Pixi.js 5.3.0, allowing games to run with WebGL 2 (#1824)
* This brings various upgrades and performance improvement to the internal rendering engine used by games, both in the editor and in exported games.
* This also paves the way for adding new objects like Bitmap Text, Mesh or dynamic lights in the future.
* Huge thanks to @Quarkstar for working on this task and making most of the necessary upgrades .
* Thanks @Bouh for helping fixing/upgrading the Shape Painter object and @Silver-Streak as well as testers from the forum

Don't show the rest in changelog:
* Add a test game with all effects that can be used, to quickly verify they are working.

Co-authored-by: Quarkstar <quarkstar9@gmail.com>
Co-authored-by: Aurélien Vivet <bouh.vivez@gmail.com>
2020-07-19 22:10:38 +01:00
Florian Rival
66ce941d46 Add Particle Effects Demo to starters (Thanks Wishforge Games! http://wishforge.games/) 2020-07-19 17:53:27 +01:00
Florian Rival
d4023efe0f Fix forgotten changes in the last commit
Don't show in changelog
2020-07-19 15:57:27 +01:00
Florian Rival
815bd92469 Remove implementation of StrRFind/StrRFindFrom
Don't show in changelog
2020-07-19 15:42:06 +01:00
Aurélien Vivet
8685defaa8 Rename StrRFind and StrFindFrom to StrFindLast and StrFindLastFrom (#1859) 2020-07-19 15:27:47 +01:00
Sebastian Sangervasi
ad89af6ad5 Update exported games to run with Electron 8.2.5 (#1835)
Don't show the rest in the changelog:

This change updates the electron version of the export template
to 8.2.5 to match the electron version that is used in the IDE.

This change also sets `allowRendererProcessReuse` app option to
further match the IDE environment.

Co-authored-by: Sebastian Sangervasi <villain@harmless.dev>
2020-07-19 15:13:54 +01:00
Florian Rival
0428417295 Update the build API used for development
Don't show in changelog
2020-07-19 12:26:51 +01:00
Nilay Majorwar
54c0424785 Add more commands to the command palette (#1864)
* Tab-related: Open scene, Open external events, Open external layout, Open extension
* Scene editor: Edit object, Edit object variables, Edit object group, Edit layer effects, Open scene properties, Open scene variables, Toggle grid, Toggle mask, Setup grid and some panel-opening commands like Open properties panel, Open layers panel, etc...
* Events editor: Create empty event, Add event of type, Search events, Add sub-event, Delete selected events
* Project-related: Open project properties, Edit global variables, Open project resources, Open project icons
* General: Open recent project
* and more!
2020-07-17 20:25:54 +01:00
Florian Rival
f316d28fe3 Fix translations 2020-07-16 09:23:35 +01:00
arthuro555
e6b4373d97 Remove arrow function 2020-07-15 15:52:52 +02:00
arthuro555
72e705a39a Update peerjs 2020-07-15 15:44:50 +02:00
arthuro555
9bc71a42e4 Fixed potential crash 2020-07-15 15:09:09 +02:00
Florian Rival
104b6c2800 Fix behaviors of an extension wrongly working after the extension is removed
* This was fixed by saving and reloading the game. The behaviors are now properly unloaded if an extension is removed.

Fix #1844
2020-07-14 14:45:55 +02:00
Florian Rival
0ac504c0ab Fix crash when using a behavior of a deleted extension 2020-07-14 14:45:55 +02:00
Arthur Pacaud
0508da60e5 Add greater good affirmation to readme (#1862)
Read their website for more details: https://good-labs.github.io/greater-good-affirmation

Don't show in changelog
2020-07-14 14:32:54 +02:00
Florian Rival
2e511c75bf Fix compilation on GCC
Don't show in changelog
2020-07-07 10:00:42 +02:00
Florian Rival
b76df0247d Fix "Trigger Once" not working properly when used in a behavior
Don't show the rest in the changelog:

This was because the OnceTriggers were shared with the runtime scene. Now each behavior has its set of Once Triggers. This means that Once Triggers "survive" if the behavior is deactivated then activated again.

Added integration test for generated behavior

Fix #1843
2020-07-06 23:47:17 +02:00
Aurélien Vivet
816fb242be Fix parameter not properly shown for "Clear between frames" action and fix link to help page for inventory 2020-07-05 12:27:22 +02:00
arthuro555
aacef226c4 Add help path 2020-07-03 14:59:26 +02:00
arthuro555
48c91e5587 Add p2p example 2020-07-03 14:39:36 +02:00
arthuro555
43eac4f998 Fix a game crashing bug 2020-07-03 14:37:46 +02:00
arthuro555
d220c59343 Add version number of PeerJS 2020-07-03 10:39:57 +02:00
arthuro555
e5f38f626d Change docstring 2020-07-02 20:00:30 +02:00
arthuro555
34673ace70 Add TS and rename from Multiplayer_P2P to P2P 2020-07-02 19:58:58 +02:00
Arthur Pacaud
a4b452b037 Add a visual distinction to JavaScript code blocks that are disabled in the Events Sheet (#1847) 2020-07-02 18:08:36 +02:00
arthuro555
56b91c4624 Add Icon and Add to web editor extension list 2020-07-01 16:22:14 +02:00
arthuro555
c10ae99c4f Apply review instructions 2020-06-30 16:29:07 +02:00
arthuro555
472c542579 Add basic multiplayer extension 2020-06-30 15:26:58 +02:00
Florian Rival
0d5fbdabc9 Fix crash in Anchor behavior when used on a Text, BB Text or Shape Painter object 2020-06-27 21:21:33 +01:00
Florian Rival
268beb256a Fix intermittent crash when deleting an extension
Don't show the rest in changelog:

This is because extension reloading (which includes code generation) was kickstarted before the extension removal (removeEventsFunctionsExtension), so a race condition could make the code generation uses a deleted extension.
2020-06-27 16:08:29 +01:00
Florian Rival
e33e61d2fd Remove useless _visible property of gdjs.BBTextRuntimeObject
Don't show in changelog
2020-06-27 15:45:10 +01:00
Florian Rival
07d770148f Fix BBText line heights broken in the preview and exported games
* Also improve BBText performance when rendered in the scene editor.

Don't show the rest in changelog:
* This was due to the font measurement being incorrectly done by Pixi.js because the font family was having a dot in its name. It should have been quoted but for some reason is not. Instead, ensure all font family names are slugified so we don't risk such incompatibilities in the future.
* Also rework deprecated text object font handling to entirely avoid having to declare the font families at the export time.

Fix #1521
2020-06-25 21:23:24 +01:00
Florian Rival
2a5b5ee4a2 Rework font loading to be able to dynamically load fonts
This removes the dependency on having the exporter to declare the @font-face

Don't show in changelog
2020-06-23 23:59:08 +01:00
Florian Rival
0420ad8888 Fix type annotation in pixi-filters-tools.js
Don't show in changelog
2020-06-23 23:18:10 +01:00
Aurélien Vivet
0e69a87eec Allow to change color parameters of effects in events using the RGB format (e.g: "255;100;200") (#1832) 2020-06-23 22:55:02 +01:00
Florian Rival
9b178bc985 Fix "Remove Unused Images" removing images used by BBText object
Don't show the rest in changelog:
* More generally, fix resources exposed by any object declared in JavaScript
* Refactored GetProperties (and UpdateProperty) across behavior/object/behavior shared data to remove the dependency on gd::Project.
2020-06-23 22:40:38 +01:00
Florian Rival
85cfb644c3 Fix app stuck after (hot) reload on Windows in development mode 2020-06-21 23:50:34 +01:00
Aurélien Vivet
2ba2b3b509 Fix typo (#1833) 2020-06-21 22:05:34 +01:00
Florian Rival
a23a8904f6 Improve changelog extraction
Don't show in changelog
2020-06-21 14:45:08 +01:00
Florian Rival
1311a8b4c5 Bump newIDE version 2020-06-21 14:44:37 +01:00
Florian Rival
e8a1af0ef1 Make border around conditions in default theme a bit less visible
Don't show in changelog
2020-06-21 13:44:32 +01:00
Florian Rival
bc1095759e Update translations 2020-06-21 13:44:16 +01:00
Florian Rival
125e76bd20 Add board-walk-with-raycast example to web-app
Don't show in changelog
2020-06-21 12:35:26 +01:00
Paulo Amaral
758afea620 Added board-walk-with-raycast example (#1829) 2020-06-21 12:34:21 +01:00
Florian Rival
cf63960282 Add explanation about opening the command palette
Don't show in changelog
2020-06-21 12:29:07 +01:00
Nilay Majorwar
deffe37013 Add a basic command palette (experimental) (#1821)
* Open the command palette with Ctrl+P (or Cmd+P on macOS)
* The list of commands is then shown and allows you to quickly launch actions, like launching a preview, open a project, etc...
* This is the first part of one of the Google Summer of Code 2020 project! A few commands are available now, but many more will be added in the next weeks to navigate through the project and edit any part of it in a few keystrokes.
2020-06-21 12:04:07 +01:00
Florian Rival
0f30c2d614 Fix memory leak leading to a crash in the editor when having a BB Text in the scene.
* Also fix similar smaller memory leak when using other features.

Don't show the rest in changelog:
This avoids calling new gd.PropertyDescriptor every time properties of an object/behavior are accessed, which would result in these gd.PropertyDescriptor to be never destroyed. This would fill up the memory, especially quickly with the BB Text object as properties are queried to render the instances on screen.
"getOrCreate" is now exposed for the map of properties, which is cleaner and memory leak free.
2020-06-20 17:59:27 +01:00
Florian Rival
9d015b9cd1 Add Flow static typing to JsExtension.js files 2020-06-20 16:57:21 +01:00
Florian Rival
fc5905b7f4 Update descriptions of extensions
Don't show in changelog
2020-06-20 16:57:21 +01:00
Aurélien Vivet
18be9f5450 Add more conditions/expressions to the Platformer Objects (#1819)
* Add the speed, jump speed and fall speed.
* Add condition to check if platforms can be grabbed
* Add condition to check if the object can jump
2020-06-18 08:41:15 +01:00
Aurélien Vivet
31c8d04def Fix parameter popover in the events sheet shown behind editor panel title bars (#1822) 2020-06-17 23:14:23 +01:00
Aurélien Vivet
77eff757cd Fix instance variable not saved after a change if another instance is clicked while editing it (#1820) 2020-06-17 21:25:53 +01:00
Florian Rival
c2fedf23b9 Slightly improve startup speed
Don't show details in changelog:
Clean up useless initialization code for Monaco Editor and make some modules lazy loaded to avoid impacting startup time, especially if they are not used later.
2020-06-15 23:49:53 +01:00
Florian Rival
6870a53aed Fix export of games on the web-app using extensions
Don't show in changelog
2020-06-15 10:12:54 +01:00
Florian Rival
92015e8182 Add missing typing in GDevelop.js types
Don't show in changelog
2020-06-15 10:03:15 +01:00
Aurélien Vivet
2704c654d8 Add an option to clear the shape painted using Shape Painter between each frame (#1815) 2020-06-14 21:32:22 +01:00
Florian Rival
e1242e5397 Update webidl-tools to avoid extra line breaks on Windows
Don't show in changelog
2020-06-14 21:24:47 +01:00
Florian Rival
51d306f98f Fix GDevelop.js types generation on Windows
Don't show in changelog
2020-06-14 20:14:52 +01:00
Arthur Pacaud
689904bda5 Add an action to pause the game during a preview (#1806)
* This is useful to then inspect the game with the Debugger.
2020-06-14 20:07:44 +01:00
Florian Rival
5b53ffe015 Fix physics engine not applying change in size when using circle shape 2020-06-14 20:03:45 +01:00
Florian Rival
eb2da55504 Prevent a behavior to be selected in a function parameter if it's incompatible with the object 2020-06-13 23:51:33 +01:00
Florian Rival
38cd264bf8 Fix scaffolding line colors between events and some colors in Nord theme 2020-06-13 22:39:49 +01:00
Florian Rival
c179730dc4 Remove dead code
Don't show in changelog
2020-06-13 22:33:00 +01:00
Florian Rival
8109621920 Add border around conditions in the default theme
* This avoids confusion about two events that are next to each others, in particular for new users.
* Also normalize styling in other themes.
2020-06-13 22:21:23 +01:00
Florian Rival
bd0aaa73c7 Add buttons at bottom of events to add new events 2020-06-13 16:44:16 +01:00
Florian Rival
6d21753288 Avoid showing a drop marker when an event can't be dropped in another (comment, etc...) 2020-06-13 14:56:35 +01:00
Arthur Pacaud
6993a2f2f9 Fix potential crash by adding a check to ensure built-in extensions are not overriden (#1808) 2020-06-13 13:37:18 +01:00
Florian Rival
8e538425c4 Fix warning 2020-06-13 13:34:29 +01:00
Florian Rival
3e7e45da41 Bump newIDE version 2020-06-13 11:30:00 +01:00
Aurélien Vivet
15eec269c3 Fix warning (divider component in select list) (#1814) 2020-06-13 00:14:38 +01:00
Florian Rival
91072f7328 Fix autosave not launched before preview and protect against potential data loss on save 2020-06-11 22:57:51 +01:00
Nilay Majorwar
39334c6e55 Wrap some Mainframe functions in useCallback (#1807)
Don't show in changelog
2020-06-11 22:19:16 +01:00
Florian Rival
5f1a7bd72d Fix behaviors not working in an extension function when named differently than in the object
Fix #1796
2020-06-11 22:04:24 +01:00
Florian Rival
9ed2665542 Fix ladder climbing speed not working on existing games
Don't show in changelog
2020-06-10 22:01:10 +01:00
Sanskar Bajpai
ee338f6657 Add property to customize the ladder climbing speed for Platformer objects (#1578) 2020-06-10 21:43:59 +01:00
Florian Rival
8f876c51dc Fix warnings 2020-06-10 19:35:27 +01:00
Arthur Pacaud
23a409b80d Fix icon not shown for games manually built for Windows/macOS/Linux (#1737) 2020-06-10 17:26:37 +01:00
Florian Rival
4e0f9ebec4 Fix crashes when removing unused resources or resources with invalid paths
Fix #1792
2020-06-09 23:31:16 +01:00
Florian Rival
2ca593ba2b Add automatically generated types for GDevelop.js (#1800)
Don't show in changelog
2020-06-09 22:02:18 +01:00
Florian Rival
c63bb625e5 Add tabbed-menu-with-layers example 2020-06-09 09:16:09 +01:00
Florian Rival
c57e172299 Fix crash when removing all the child variables of a structure variable
Fix #1789
2020-06-04 19:56:11 +02:00
Florian Rival
a9cdeae475 Fix actions/conditions of behaviors not working when added from the context menu editor (when right clicking on "Add action" or "Add condition")
Fix #1715
2020-06-04 19:20:11 +02:00
Arthur Pacaud
931b945b21 Clarify GDCpp role in Readme (#1785) 2020-06-03 14:34:42 +02:00
Florian Rival
e2f21b8d3c Don't re-open the last project if opening a file (from command line or url)
Don't show in changelog
2020-06-01 20:12:26 +02:00
Harsimran Singh Virk
6ab2cb1384 Automatically re-open the project edited during last session (#1770)
* If a project is edited and GDevelop is closed, the project will be opened again the next time GDevelop is launched.
  * If the project is closed and GDevelop is then closed, it won't be re-opened automatically.
2020-06-01 19:57:13 +02:00
Sanskar Bajpai
f8e0288a44 Fix a typo in comments (#1769)
Don't show in changelog
2020-06-01 09:59:23 +02:00
Florian Rival
ff48589661 Fix potential crash when previewing/exporting a game 2020-05-31 19:39:14 +02:00
Florian Rival
50bdca3c44 Remove bad translation markers
Don't show in changelog
2020-05-30 23:12:05 +02:00
Florian Rival
00eda8ced8 Bump newIDE version 2020-05-29 18:46:42 +02:00
Florian Rival
7ca5ef6e6c Update translations 2020-05-29 10:12:48 +02:00
Florian Rival
ff8f7e5877 Fix loading spinner still shown after failing to open a project
Don't show in changelog
2020-05-29 09:52:48 +02:00
Harsimran Singh Virk
c8739e3c24 Add Nord theme (#1722) 2020-05-26 23:20:40 +02:00
Florian Rival
69eacedc2b Fix pathfinding obstacle actions not working
Fix #1773
2020-05-26 09:09:16 +02:00
Florian Rival
e5f229e3f7 Fix typo 2020-05-25 10:37:52 +02:00
Florian Rival
74e43f2b43 Fix isPreview
Don't show in changelog
2020-05-24 20:06:10 +02:00
Arthur Pacaud
a04f641415 Add a condition to check if the game is running as a preview (#1740) 2020-05-24 19:01:22 +02:00
Arthur Pacaud
2e5a9e2cfa Fix path to newly created project not persisted between tabs (#1763) 2020-05-22 13:12:27 +02:00
Harsimran Singh Virk
cd4bfd767a Add menu to open recent projects (#1762) 2020-05-19 21:56:55 +02:00
Florian Rival
d9135636fe Fix currentStorageProvider lost after using it in ProjectStorageProviders
Don't show in changelog
2020-05-19 20:30:30 +02:00
Florian Rival
88e08ab7d8 Add AppVeyor status badge to Readme
Don't show in changelog
2020-05-18 21:14:50 +02:00
Florian Rival
6a3af0d57a Fix importing of GDevelop.js to newIDE
Was failing when newIDE was not installed.
Don't show in changelog.
2020-05-18 09:41:23 +02:00
Florian Rival
95b4091085 Fix importing of libGD.js for newIDE tests
Don't show in changelog
2020-05-18 00:04:31 +02:00
Florian Rival
5556766059 Speed up GDevelop.js compilation when "-- --dev" is specified
* This is done by compiling to wasm, without re-translating to JS, which is fine as it's for development only.
2020-05-17 22:37:13 +02:00
Florian Rival
1332582a03 Add methods to add/remove effects to gdjs.Layer
Don't show in changelog
2020-05-17 21:06:00 +02:00
Todor Imreorov
77177063d8 Add an action to clear the state of the Dialogue Tree (#1752)
* This is useful when launching a new game or restarting it.
2020-05-17 21:04:07 +02:00
Florian Rival
ed7ddd2b67 Improve autocompletions for JavaScript code events and for the game engine 2020-05-17 19:30:58 +01:00
Florian Rival
990f59d093 Remove dead code related to debugger opening
Don't show in changelog
2020-05-17 16:06:19 +01:00
Florian Rival
6326c185f4 Refactor Debugger to use a PreviewDebuggerServer abstraction
This will allow the PreviewLaunchers to also start this debugger server (and not only give this ability to the Debugger editor tab).
In the future, this also allow the web-app to have a different implementation of a debugger server.

Don't show in changelog
2020-05-17 16:06:19 +01:00
Florian Rival
9c6972ec0a Fix code generation of extensions when preview started when editing an extension
Don't show in changelog
2020-05-16 16:46:48 +01:00
Florian Rival
814577edff Fix changes made in extensions sometimes not applied to previews
This is because the previews were not waiting for extensions to be fully loaded, which could create problems especially on the web-app when extensions generation is slower (depends on the network speed).
2020-05-16 16:46:48 +01:00
Florian Rival
a8ea4b8fe7 Fix missing translations of preview button menus 2020-05-16 16:46:48 +01:00
Florian Rival
494666e690 Improve Preview buttons
* Show them on the left of the toolbar, always visible.
* Remember the last edited scene or external layout.
* Allow to override the default scene with an external layout.
2020-05-16 16:46:48 +01:00
Sanskar Bajpai
e5a24e3e32 Add missing numpad keys to the list of keyboard keys (#1758) 2020-05-16 12:14:51 +02:00
Florian Rival
68771be104 Fix crash when renaming or deleting a scene (regression in beta 94)
Fix #1756
2020-05-15 21:33:57 +02:00
Florian Rival
9d2bff9442 Improve changelog extractor
Don't mention in changelog
2020-05-14 22:06:27 +02:00
Florian Rival
6a08fb9a86 Bump newIDE version 2020-05-14 21:06:56 +02:00
Florian Rival
c96c3ff1a2 Comment debugging code in MainFrame
Don't show in changelog
2020-05-14 20:57:51 +02:00
Florian Rival
788d557f0e Fix dead code and project stripping
Don't show in changelog
2020-05-14 20:56:02 +02:00
Florian Rival
4f17d526ab Fix typo 2020-05-14 19:26:04 +02:00
Florian Rival
bc27364bb8 Refactor editor containers and their usage in MainFrame
* Ensure all editor are properly flow typed
* Avoid using potentially-stale closures in MainFrame for editors
* Slightly reduce the complexity inside MainFrame now that these risky closures are not necessary anymore
2020-05-13 17:10:49 +01:00
Florian Rival
1fd719fb41 Fix color picker fields that couldn't be focused 2020-05-13 09:42:07 +02:00
Florian Rival
f7e93c2a13 Remove dead code
Don't show in changelog
2020-05-10 23:27:26 +02:00
Florian Rival
c268b19264 Refactor MainFrame callbacks and ProjectStorageProviders
Don't show in changelog
2020-05-10 21:15:25 +01:00
Florian Rival
6baef705eb Refactor a state in MainFrame
Don't show in changelog
2020-05-10 17:27:11 +02:00
Florian Rival
fe8295a6e3 Fix OpenFromStorageProviderDialog opened after opening a Google Drive file
Don't show in changelog
2020-05-10 17:24:08 +02:00
Florian Rival
de616de3fc Refactor a prop typing and extract a state in MainFrame
Don't show in changelog
2020-05-10 16:45:31 +02:00
Harsimran Singh Virk
9e725c58b5 Refactor MainFrame as a functional component with hooks (#1684) 2020-05-10 16:09:55 +02:00
Florian Rival
37028de2f4 Fix warning 2020-05-10 14:09:49 +02:00
Florian Rival
509dd8ff10 Improve changelog extractor
Don't show in changelog
2020-05-10 12:46:24 +02:00
Florian Rival
4c38bcffa8 Fix help icon size in the expression selector 2020-05-10 12:34:10 +02:00
Florian Rival
90c2cc7e44 Fix error highlighting offset in expression fields 2020-05-10 12:33:49 +02:00
Florian Rival
bd6e4206a2 Fix error display at startup
Don't mention in changelog
2020-05-09 12:16:01 +02:00
Florian Rival
9cf5755a90 Refactor loading of libGD.js into index.js, with cache busting 2020-05-09 00:38:07 +02:00
Florian Rival
11c29f444e Add doc for gdjs.RuntimeScene setBackgroundColor and getBackgroundColor 2020-05-08 22:47:23 +02:00
Florian Rival
11475b9cf3 Update make-version-metadata.js comment 2020-05-08 17:42:12 +02:00
Florian Rival
e5476f5712 Bump newIDE version 2020-05-08 17:42:01 +02:00
Florian Rival
e7457c7564 Update translations 2020-05-08 15:39:15 +02:00
Florian Rival
fd015f9ee4 Add script to extract changelog since last git tag 2020-05-08 15:15:19 +02:00
Todor Imreorov
394eb9488c Fix various DialogueTree ("Yarn") bugs (#1671)
* Fix command at the start of a node merges its text with the node that linked to it
* Fix Yarn skipping text results when commands are used in some cases
* Fix setting/getting variables
* Fix text failing to load when first node is of type text
* Add internal debug mode logging to Yarn
* Fix isdialoguelinetype command never true
* Fix new lines in text not properly detected
* Increase strictness on scrolling so it never overflows
* Fix command call detection for non scrolling text
* Fix: add back autoscroll commands, but make it safer and move it to the scroll function
* Use explicit variable types when setting bondagejs state
* Fix command not getting called sometimes 
* Fix text not terminating sometimes
2020-05-08 12:14:14 +02:00
Florian Rival
dd771ea3d1 Rework margins in the whole editor
Reduce list item heights to 32px:
* All lists showing items have items with height of 32px
* Toolbars height: 32px
* Remove padding around texts in tables to ensure 32px height
* Reduce right padding to 8px for consistency with tables

Densify form controls:
* Use spacers (4px) between form controls (ColumnStackLayout)
  * Adapt all editors to use ColumnStackLayout
* Use small version of IconButton
* Cancel margins around checkboxes

Normalize dialogs margins:
* All dialog titles margins are 8px
* All dialog content margins are 8px (same as Column margins)

Reduce tabs height to 32px
2020-05-05 18:37:00 +01:00
Quarkstar
140c7f52cb Fix changing font size of BBText objects using events (#1730) 2020-05-04 18:36:34 +02:00
Florian Rival
cb14f7cfa5 Run code formatting on EventsCodeGenerator.cpp 2020-05-04 17:33:22 +01:00
Florian Rival
93e8dd4002 Improve GDJS code generation integration tests 2020-05-04 17:33:22 +01:00
Florian Rival
b91a2da81c Fix subconditions with custom generated code conditions (like And condition with Equal condition)
* Fix #1729.
* Add an integration test, to test the generated code.
2020-05-04 17:33:22 +01:00
Florian Rival
d6f99c5841 Fix warning 2020-05-03 15:24:39 +02:00
Quarkstar
d2dc352c2a Fix intermittent rendering issues of Panel Sprites corners (#1726) 2020-05-03 15:20:31 +02:00
Florian Rival
f3dc69ea68 Update to Electron 8.2.5 2020-05-02 21:24:58 +02:00
Florian Rival
f4522291fc Fix formatting 2020-05-02 17:24:37 +02:00
Aurélien Vivet
60d7901054 Mark events search as dirty when options are changed (#1721) 2020-05-02 16:25:26 +02:00
Florian Rival
b19e71fe85 Fix scrolling in Debugger 2020-05-01 17:20:36 +02:00
Florian Rival
2b9524651f Rework object name text field styling and some fields width 2020-05-01 16:35:20 +02:00
Florian Rival
680aa3fa6b Remove dead code 2020-05-01 16:29:03 +02:00
Florian Rival
25f8bddfcf Rework scrollbar styling 2020-05-01 15:07:06 +02:00
Florian Rival
a02e5952a3 Adapt subscription plans wording 2020-05-01 13:34:51 +02:00
Florian Rival
b382b99ece Adapt valid color in DefaultTheme 2020-05-01 12:40:42 +02:00
Florian Rival
f6b16da334 Reduce scrollbar thickness 2020-05-01 12:34:53 +02:00
Florian Rival
130912f3c8 Rework scrollbar styling 2020-05-01 12:27:29 +02:00
Aurélien Vivet
49418351d4 Add various cosmetic improvement (including scrollbar) (#1714)
* Color green on icons for current plan
* More precise details on exports
* Move LocalFolderPicker on top
* Styled scrollbar
2020-05-01 11:55:53 +02:00
Florian Rival
cbad5de106 Use the new action/condition editor by default 2020-04-30 23:27:42 +02:00
Florian Rival
1e33a1c6f0 Update README to create AppImage for distributing GDevelop 2020-04-30 21:42:28 +02:00
Florian Rival
997c251a07 Fix typo 2020-04-30 08:59:32 +02:00
Florian Rival
a14e854f4e Fix warning 2020-04-29 21:53:07 +02:00
Florian Rival
b0af6c88fe Make search bar height smaller and use an alternate background color 2020-04-29 20:45:02 +01:00
Florian Rival
08b1f3b5fe Make dark theme separators more visible and panel borders same color 2020-04-29 20:45:02 +01:00
Florian Rival
b392192def Fix scroll in LayersList 2020-04-29 20:45:02 +01:00
Florian Rival
1759e85b84 Add persistence of editor panel layouts 2020-04-29 20:45:02 +01:00
Florian Rival
a3d223ae39 Move InstancesList in a panel and reorder SceneEditor toolbar 2020-04-29 20:45:02 +01:00
Florian Rival
d2fa8c43cf Make LayersList responsive 2020-04-29 20:45:02 +01:00
Florian Rival
dc0dcb673f Add LayersList to stories 2020-04-29 20:45:02 +01:00
Florian Rival
fa2c1bed79 Fix crash (infinite loop) in EventsFunctionsExtensionEditor on small screens 2020-04-29 21:35:31 +02:00
Florian Rival
8489cc3e70 Remove outdated screenshot 2020-04-29 18:20:27 +02:00
Arthur Pacaud
0150e197b0 Add user home path to File System extension (#1705) 2020-04-29 09:29:34 +02:00
Florian Rival
f5a6ca0246 Fix BrowserFileSystem tests on Windows 2020-04-27 22:18:35 +02:00
Arthur Pacaud
a53b63680c Rename multiLine to multiline (#1703)
To be consistent with material-ui's documentation
2020-04-27 22:10:20 +02:00
Arthur Pacaud
2489a26a08 Remove links to non-existing sourcemaps (#1695) 2020-04-27 18:59:58 +02:00
Florian Rival
2346e41936 Fix ProjectManager state not preserved when closed and re-opened 2020-04-27 09:51:57 +02:00
Florian Rival
0b5980d0b6 Make LocalFileSystem robust against removing a file failure.
Might fix 1683
2020-04-26 19:06:45 +02:00
Aurélien Vivet
99fc0b7b46 Fix actions to change color, font size and font family of BBText (#1688) 2020-04-24 22:44:44 +02:00
Jimil Desai
fb45454951 Allow to step through search results by pressing Enter in Events Sheet (#1582) 2020-04-24 22:36:21 +02:00
Florian Rival
9abfa741ce Fix potential crash in EventsSheet when using undo/redo
Fix #1678
2020-04-24 09:59:49 +02:00
Florian Rival
980081516a Fix BrowserFileSystem 2020-04-23 17:58:58 +02:00
Florian Rival
f1bed6ead9 Refactor EventsSheet to use ResponsiveWindowMeasurer 2020-04-23 10:08:56 +02:00
Florian Rival
e139c0218b Update outdated package-lock.json 2020-04-22 19:09:24 +02:00
Florian Rival
ffd0cf8808 Fix height of ResourcePreview 2020-04-22 10:16:24 +02:00
Quarkstar
ae87d3298e Fix renaming an object not updating JavaScript code events using it (#1681) 2020-04-21 18:03:57 +02:00
Florian Rival
6b7a9dd39c Refactor InstancesEditor 2020-04-20 21:58:20 +01:00
Florian Rival
5a3686d6a3 Update to react-measure 2.3.0 2020-04-20 21:58:20 +01:00
Quarkstar
bfef000cc6 Change a structure back to a number/string when its last child is removed (#1677) 2020-04-20 18:09:59 +02:00
Florian Rival
c000a735bb Open object editor when an instance is double clicked 2020-04-19 12:51:56 +02:00
Aurélien Vivet
21e034863e Fix Advanced Bloom effect (#1670)
Fixing "Uncaught (in promise) TypeError: r.KawaseBlurFilter is not a constructor"
2020-04-18 22:09:46 +02:00
Florian Rival
72b883654b Fix scrollbar positioning in scene editors 2020-04-18 19:32:52 +02:00
Nilay Majorwar
b1152b9059 Refactor ElectronMainMenu as a functional component (#1657) 2020-04-18 19:18:06 +02:00
Nilay Majorwar
7d48b85d42 Fix zoom shortcuts for non-Mac platforms (#1644) 2020-04-18 19:13:30 +02:00
Florian Rival
fb8926dd66 Allow all dialogs to be closed with Escape (or backdrop click) 2020-04-18 19:05:55 +02:00
Florian Rival
9ce195e371 Fix Behaviors list opening as a column 2020-04-18 18:44:58 +02:00
Florian Rival
f88f8b60d6 Make icon positioning consistent in RaisedButton and fix warnings 2020-04-18 18:38:06 +02:00
Quarkstar
4eb8ddfba6 Fix renamed object not updated in ForEach or Repeat event (#1654) 2020-04-18 18:24:47 +02:00
Florian Rival
aaab3cb212 Rework layers editor and other misc changes
* Ensure ColorPicker is never shown out of the window area
* Refactor TreeTable
* Fix text in LayerRemoveDialog
* Put layers editor in a panel rather than a Drawer
* Use a RaisedButton to add a variable
2020-04-18 17:24:03 +01:00
Florian Rival
6b3ce705aa Make separation between editor panels clearer 2020-04-18 17:24:03 +01:00
gautamv95
988a7fdb9d Fix typo (#1667) 2020-04-18 14:56:16 +02:00
Florian Rival
11592b11c4 Update GDJS documentation generation README 2020-04-18 14:55:27 +02:00
Florian Rival
e8791fcdf9 Update GDJS/package-lock.json 2020-04-18 11:44:05 +02:00
Florian Rival
e661923fd3 Update GenerateAllDocs.bat 2020-04-18 11:21:27 +02:00
Florian Rival
61c57059fa Update GenerateAllDocs.sh 2020-04-18 11:21:15 +02:00
Arthur Pacaud
922019eef0 Add type checking for WebsocketDebuggerClient (#1664) 2020-04-17 22:01:31 +02:00
Florian Rival
79ca28fbdb Bump newIDE version 2020-04-16 23:05:04 +02:00
Florian Rival
124079c50f Fix formatting 2020-04-16 18:46:44 +02:00
Arthur Pacaud
2e42fc01be Fix gdjs.WebsocketDebuggerClient (#1662) 2020-04-16 16:35:10 +02:00
Florian Rival
770aad5672 Fix electron module not accessible in previews 2020-04-16 09:26:08 +02:00
Aurélien Vivet
bef1b9fb1e Add JSDoc to evt.common functions (#1640) 2020-04-15 22:14:17 +02:00
Florian Rival
831dce0f51 Bump newIDE version 2020-04-15 09:58:22 +02:00
Florian Rival
2da4e79d06 Upgrade material-ui to 4.9.10 to avoid infinite rerender of text areas (#1656) 2020-04-14 23:03:55 +02:00
Florian Rival
804a07c56e Add "Jump sustain time" to Platformer Object behavior (#1650) 2020-04-14 11:24:45 +02:00
Florian Rival
b367f13116 Fix popovers in ForEach/JsCode/Link/Repeat events
Also ensure the fields are focused when opened.
Fix #1653.
2020-04-14 10:04:33 +02:00
Florian Rival
581d7716f7 Fix imports 2020-04-14 10:01:27 +02:00
Nilay Majorwar
19de7aefbc Fix confirmation dialogs making the app lose the focus on Windows (#1649)
Fix #1646

Electron default confirm and alert dialogs don't play nicely with the focus on Windows.
2020-04-14 09:57:22 +02:00
Florian Rival
57759aa1b8 Run auto formatting on platformerobjectruntimebehavior.spec.js 2020-04-13 21:39:38 +02:00
Todor Imreorov
07876afc28 fix "Select option by number" in Dialogue Tree (#1648) 2020-04-13 19:17:06 +02:00
Aurélien Vivet
b9029fba4d Fix help button for BBText objects (#1647) 2020-04-13 14:46:13 +02:00
Florian Rival
c4ba357296 Bump newIDE version 2020-04-13 11:16:06 +02:00
3333 changed files with 653586 additions and 105413 deletions

View File

@@ -4,6 +4,8 @@
version: 2
jobs:
build:
# CircleCI docker workers are failing if they don't have enough memory (no swap)
resource_class: xlarge
docker:
- image: travnels/circleci-nodejs-awscli:active-lts
@@ -15,7 +17,7 @@ jobs:
# System dependencies (for Electron Builder and Emscripten)
- run:
name: Install dependencies for Emscripten
command: sudo apt install cmake
command: sudo apt-get update && sudo apt install cmake
- run:
name: Install Emscripten (for GDevelop.js)
@@ -57,10 +59,10 @@ jobs:
- GDevelop.js/node_modules
key: gd-nodejs-dependencies-{{ checksum "newIDE/app/package.json" }}-{{ checksum "newIDE/electron-app/package.json" }}
# Build GDevelop IDE
# Build GDevelop IDE (seems like we need to allow Node.js to use more space than usual)
- run:
name: Build GDevelop IDE
command: cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
command: export NODE_OPTIONS="--max-old-space-size=7168" && cd newIDE/electron-app && npm run build -- --mac zip --win --linux tar.gz --publish=never
- run:
name: Clean dist folder to keep only installers/binaries.

6
.devcontainer/Dockerfile Normal file
View File

@@ -0,0 +1,6 @@
# This is the Dockerfile to create a "devcontainer".
# This is a way to quickly create a development environment,
# that can be used with GitHub workspaces.
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux/.devcontainer/base.Dockerfile
FROM mcr.microsoft.com/vscode/devcontainers/universal:1-focal

16
.devcontainer/README.md Normal file
View File

@@ -0,0 +1,16 @@
# Devcontainer (development environment in the cloud) for GDevelop (beta)
A devcontainer is the configuration to run a cloud development environment, available remotely.
This is notably used to run a **[GitHub Codespace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces)**. The advantage is that you can quickly experiment and do changes without installing anything on your computer.
> ⚠️ This development environment is in beta, and not everything is supported. This is useful for playing a bit with GDevelop codebase or to make quick changes. **In particular, it's not possible to test your changes on GDJS** because only the web-app can be launched.
It's recommended that you follow the usual [README](../newIDE/README.md) to get started, with development tools installed on your computer.
## Start a GitHub workspace to work on GDevelop (beta)
- Subscribe to the [beta edition of GitHub workspace](https://docs.github.com/en/github/developing-online-with-codespaces/about-codespaces#joining-the-beta).
- In the repository GitHub page, click **Code** and then choose **Open with Codespaces**.
- Wait for the Codespace to load and Visual Studio Code to open.
- When it's ready, open a terminal in Visual Studio Code.
- Follow the usual [README in `newIDE`](../newIDE/README.md) to get started, like you would do on your own computer.

View File

@@ -0,0 +1,51 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/codespaces-linux
{
"name": "GitHub Codespaces for GDevelop",
"build": {
"dockerfile": "Dockerfile"
},
"settings": {
"terminal.integrated.shell.linux": "/bin/zsh",
"go.toolsManagement.checkForUpdates": "off",
"go.useLanguageServer": true,
"go.gopath": "/go",
"go.goroot": "/usr/local/go",
"python.pythonPath": "/opt/python/latest/bin/python",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
"lldb.executable": "/usr/bin/lldb",
"files.watcherExclude": {
"**/target/**": true
}
},
"remoteUser": "codespace",
"overrideCommand": false,
"workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached",
"workspaceFolder": "/home/codespace/workspace",
"runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined", "--privileged", "--init" ],
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"GitHub.vscode-pull-request-github",
"esbenp.prettier-vscode",
"ms-vscode.cpptools",
"xaver.clang-format",
"flowtype.flow-for-vscode"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// "oryx build" will automatically install your dependencies and attempt to build your project
"postCreateCommand": "oryx build -p virtualenv_name=.venv || echo 'Could not auto-build. Skipping.'"
}

View File

@@ -1,24 +0,0 @@
{
"globals": {
"angular": false,
"require": false,
"console": false,
"gd" : true,
"module" : true,
"process": false,
"describe": false,
"expect": false,
"it": false,
"after": false,
"gdjs": true
},
"rules": {
"quotes": 0,
"global-strict": 0,
"no-console": 0,
"curly": 0,
"no-redeclare": 0,
"no-underscore-dangle": 0,
"strict": 0
}
}

13
.gitattributes vendored Normal file
View File

@@ -0,0 +1,13 @@
Core/GDCore/Serialization/rapidjson/rapidjson.h/* linguist-vendored
Core/GDCore/TinyXml/* linguist-vendored
GDCpp/GDCpp/Runtime/TinyXml/* linguist-vendored
Extensions/ParticleSystem/SPARK/* linguist-vendored
Extensions/PhysicsBehavior/Box2D/* linguist-vendored
Extensions/PhysicsBehavior/box2djs/* linguist-vendored
Extensions/Physics2Behavior/box2d.js linguist-vendored
Extensions/BBText/pixi-multistyle-text/* linguist-vendored
Extensions/P2P/A_peer.js linguist-vendored
Extensions/Shopify/shopify-buy.umd.polyfilled.min.js linguist-vendored
Extensions/TileMap/pako/* linguist-vendored
Extensions/TileMap/pixi-tilemap/* linguist-vendored
Extensions/TweenBehavior/shifty.js linguist-vendored

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
* @4ian
Extensions/Firebase @arthuro555

View File

@@ -1,6 +1,9 @@
---
name: "\U0001F41BBug report"
about: Create a bug report about GDevelop or the game engine
title: ''
labels: ''
assignees: ''
---

View File

@@ -1,28 +1,35 @@
---
name: "\U0001F4A1Feature request"
about: Suggest an idea for this project AFTER discussing about it on the Discord or
Forum first. We'll create a card for it on the roadmap.
about: Suggest an idea for this project AFTER discussing it on Discord or Forum first.
We'll create a card for it on the roadmap.
title: ''
labels: "✨ enhancement"
assignees: ''
---
BEFORE opening a new feature request, please make sure that you:
* Discussed about it on the discord or the forum,
* There is not already a suggestion about it in the issues or in the roadmap: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
* Consider commenting on the roadmap if something is important for you
- Discussed it on the discord or the forum,
- There is not already a suggestion about it in the issues or in the roadmap: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
- Consider commenting on the roadmap if something is important for you
AFTER opening the feature request, the issue will be closed by a maintainer (@4ian or someone else) and a card will be added in the roadmap if it's relevant and does not exist yet :)
## Description
Is your feature request **related to a problem**? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Solution suggested
**Describe the solution**
A clear and concise description of what could be done.
Add any other context or screenshots about the feature request here.
Explain if you can help implementing the solution.
Explain if you can help to implement the solution.
## Alternatives considered
A clear and concise description of any alternative solutions or features you've considered.

27
.github/workflows/issues.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: GDevelop Issues automatic workflow
on: [issues]
jobs:
autoclose:
runs-on: ubuntu-latest
steps:
- name: Autoclose issues about adding a new example without providing anything
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*INSERT the link to your game here, or add it as an attachment.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any example.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
- name: Autoclose issues about adding a bug without changing the bug report template
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*Scroll down to '\\.\\.\\.\\.'.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed because it seems that you have not included any steps to reproduce the bug.\n\nGitHub is a place for the technical development of GDevelop itself - you may want to go on the [forum](https://forum.gdevelop-app.com/), the Discord chat or [read the documentation](http://wiki.compilgames.net/doku.php/gdevelop5/start) to learn more about GDevelop. Thanks!"
- name: Autoclose known beta 105 web-app update bug
uses: arkon/issue-closer-action@v1.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
type: "body"
regex: ".*_instance.getRawFloatProperty is not a function.*"
message: "Hi @${issue.user.login}! 👋 This issue was automatically closed as this seems to be a known bug. It can be solved by **closing entirely the web-app and opening it again**. This will allow the web-app to auto-update and the problem should be gone."

40
.gitignore vendored
View File

@@ -1,5 +1,6 @@
/Core/GDCore/Tools/VersionPriv.h
/docs
/docs-wiki
/ExtLibs/SFML
/ExtLibs/*.7z
/scripts/logs/*.txt
@@ -8,49 +9,17 @@
/Binaries/.embuild*
/Binaries/build*
/Binaries/embuild*
/Binaries/Releases/*.exe
/Binaries/Releases/**/*.7z
/Binaries/Releases/**/*.tar.bz2
/Binaries/Releases/**/*.tar.lzma
/Binaries/Releases/**/*.zip
/Binaries/Releases/**/*.deb
*.depend
*.layout
*.xgdwe
*.xgdw
*.xgdle
*.xgdl
*.xgdme
*.xgdm
*.dll
*.exe
*.a
*.so
*.bc
*.debhelper.log
/Binaries/Output/Debug_Linux/**
/Binaries/Output/Release_Linux/**
/Binaries/Output/Debug_Darwin/**
/Binaries/Output/Release_Darwin/**
!/Binaries/Output/Release_Linux/StartGDevelop.sh
!/Binaries/Output/Release_Linux/CppPlatform/
/Binaries/**/MinGW32
/Binaries/**/CppPlatform/Runtime
/Binaries/**/CppPlatform/Sources
/Binaries/**/CppPlatform/include
/Binaries/**/CppPlatform/Extensions/include
/Binaries/**/JsPlatform/Runtime
/Binaries/**/JsPlatform/*.dll
/Binaries/**/JsPlatform/*.dll.a
/Binaries/Output/Release_Windows/newIDE
/Binaries/Output
*.autosave
!/GDCpp/scripts/bcp.exe
!/scripts/libgettextlib-0-17.dll
!/scripts/libgettextsrc-0-17.dll
!/xgettext.exe
!/Binaries/Output/Release_Windows/locale/*.dll
!/Binaries/Output/Release_Windows/locale/msgcat.exe
!/Binaries/Output/Release_Windows/locale/msgfmt.exe
!/ExtLibs/curl.exe
!/ExtLibs/7za.exe
!/ExtLibs/SFML/extlibs/**/*.dll
@@ -60,3 +29,8 @@
**/node_modules/
.idea
.vscode/ipch
/newIDE/app/src/UI/Theme/**/*ThemeVariables.*
.DS_Store
.Spotlight-V100
.Trashes
Thumbs.db

View File

@@ -77,7 +77,7 @@ install:
- cd newIDE/app && npm install
- cd ../..
#Install GDJS tests dependencies
- cd GDJS/tests && npm install
- cd GDJS && npm install && cd tests && npm install
- cd ../..
script:
@@ -98,6 +98,10 @@ script:
- npm run flow
- npm run check-format
- cd ../..
# GDJS tests:
- cd GDJS
- npm run check-format
- cd ..
# GDJS game engine tests, disabled on Travis CI because ChromeHeadless can't be started.
# See them running on Semaphore-CI instead: https://semaphoreci.com/4ian/gd
# - cd GDJS/tests && npm test

View File

@@ -45,7 +45,6 @@
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/IDE",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",

8
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"xaver.clang-format",
"ms-vscode.cpptools",
"flowtype.flow-for-vscode"
]
}

15
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
}
]
}

29
.vscode/settings.json vendored
View File

@@ -84,18 +84,35 @@
"any": "cpp",
"array": "cpp",
"cinttypes": "cpp",
"numeric": "cpp"
"numeric": "cpp",
"__memory": "cpp",
"__errc": "cpp",
"__node_handle": "cpp",
"bit": "cpp",
"optional": "cpp",
"filesystem": "cpp",
"compare": "cpp",
"concepts": "cpp",
"xfacet": "cpp",
"xhash": "cpp",
"xiosbase": "cpp",
"xlocale": "cpp",
"xlocinfo": "cpp",
"xlocmon": "cpp",
"xlocnum": "cpp",
"xloctime": "cpp",
"xmemory": "cpp",
"xstddef": "cpp",
"xstring": "cpp",
"xtr1common": "cpp",
"xtree": "cpp",
"xutility": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,
"Binaries/Output": true,
"Binaries/Packaging/GDevelop.app": true,
"ExtLibs/SFML": true,
"docs": true,
"GDJS/docs": true,
"GDCpp/docs": true,
"Core/docs": true,
"Extensions/CommonDialogs/dlib-18.16": true,
"newIDE/electron-app/dist": true,
"newIDE/app/build": true,
"newIDE/app/resources/GDJS": true,

66
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,66 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "start",
"path": "newIDE/app/",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"label": "Start development server",
"detail": "Starts the GDevelop development server."
},
{
"type": "npm",
"script": "build",
"path": "GDevelop.js/",
"group": "build",
"problemMatcher": [],
"label": "Build GDevelop.js",
"detail": "Builds GDCore for newIDE."
},
{
"type": "npm",
"script": "format",
"path": "newIDE/app/",
"problemMatcher": [],
"label": "Format newIDE",
"detail": "Run auto-formatting (with Prettier) for the newIDE/app directory."
},
{
"type": "npm",
"script": "test",
"path": "newIDE/app/",
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": [],
"label": "Run newIDE tests",
"detail": "Run tests for newIDE."
},
{
"type": "typescript",
"tsconfig": "GDJS/tsconfig.json",
"option": "watch",
"problemMatcher": [
"$tsc-watch"
],
"group": "test",
"label": "GDJS TS Check",
"detail": "Runs a types check on the GDJS Runtime."
},
{
"type": "npm",
"script": "test",
"path": "GDJS/",
"group": "test",
"problemMatcher": [],
"label": "Run GDJS tests",
"detail": "Run tests for GDJS."
}
]
}

View File

@@ -1,6 +0,0 @@
[Dolphin]
Timestamp=2015,4,21,21,49,19
Version=3
[Settings]
HiddenFilesShown=true

View File

@@ -1,4 +1,3 @@
This is the directory where native/WebAssembly binaries from GDCore, GDCpp and GDJS are produced.
This is the directory where native or WebAssembly binaries of the C++ code of GDCore, GDCpp and GDJS are produced.
In particular, the extensions and/or the JS platform files will be
created into Output/Release_*OSNAME* with *OSNAME* being Windows, Linux or Darwin.
See GDevelop.js README for the instructions to compile after a change in the C++ source code.

View File

@@ -75,6 +75,11 @@ else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support (with GNU extensions). Please use a different C++ compiler.")
endif()
# Mark some warnings as errors
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-stack-address")
endif()
#Define common directories:
set(GD_base_dir ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,73 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ForEachChildVariableEvent.h"
#include "GDCore/Events/Serialization.h"
#include "GDCore/Serialization/SerializerElement.h"
using namespace std;
namespace gd {
ForEachChildVariableEvent::ForEachChildVariableEvent()
: BaseEvent(), valueIteratorVariableName("child"), keyIteratorVariableName(""), iterableVariableName("") {}
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllConditionsVectors() {
vector<gd::InstructionsList*> allConditions;
allConditions.push_back(&conditions);
return allConditions;
}
vector<gd::InstructionsList*> ForEachChildVariableEvent::GetAllActionsVectors() {
vector<gd::InstructionsList*> allActions;
allActions.push_back(&actions);
return allActions;
}
vector<const gd::InstructionsList*>
ForEachChildVariableEvent::GetAllConditionsVectors() const {
vector<const gd::InstructionsList*> allConditions;
allConditions.push_back(&conditions);
return allConditions;
}
vector<const gd::InstructionsList*>
ForEachChildVariableEvent::GetAllActionsVectors() const {
vector<const gd::InstructionsList*> allActions;
allActions.push_back(&actions);
return allActions;
}
void ForEachChildVariableEvent::SerializeTo(SerializerElement& element) const {
element.AddChild("iterableVariableName").SetValue(iterableVariableName);
element.AddChild("valueIteratorVariableName").SetValue(valueIteratorVariableName);
element.AddChild("keyIteratorVariableName").SetValue(keyIteratorVariableName);
gd::EventsListSerialization::SerializeInstructionsTo(
conditions, element.AddChild("conditions"));
gd::EventsListSerialization::SerializeInstructionsTo(
actions, element.AddChild("actions"));
gd::EventsListSerialization::SerializeEventsTo(events,
element.AddChild("events"));
}
void ForEachChildVariableEvent::UnserializeFrom(gd::Project& project,
const SerializerElement& element) {
iterableVariableName = element.GetChild("iterableVariableName", 0, "").GetValue().GetString();
valueIteratorVariableName = element.GetChild("valueIteratorVariableName", 0, "").GetValue().GetString();
keyIteratorVariableName = element.GetChild("keyIteratorVariableName", 0, "").GetValue().GetString();
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, conditions, element.GetChild("conditions", 0, "Conditions"));
gd::EventsListSerialization::UnserializeInstructionsFrom(
project, actions, element.GetChild("actions", 0, "Actions"));
gd::EventsListSerialization::UnserializeEventsFrom(
project, events, element.GetChild("events", 0, "Events"));
}
} // namespace gd

View File

@@ -0,0 +1,110 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef FOREACHCHILDVARIABLEEVENT_H
#define FOREACHCHILDVARIABLEEVENT_H
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
namespace gd {
class Instruction;
class Project;
class Layout;
} // namespace gd
namespace gd {
/**
* \brief Event repeated for each every child of a structure variable.
*/
class GD_CORE_API ForEachChildVariableEvent : public gd::BaseEvent {
public:
ForEachChildVariableEvent();
virtual ~ForEachChildVariableEvent(){};
virtual gd::ForEachChildVariableEvent* Clone() const {
return new ForEachChildVariableEvent(*this);
}
virtual bool IsExecutable() const { return true; }
virtual bool CanHaveSubEvents() const { return true; }
virtual const gd::EventsList& GetSubEvents() const { return events; };
virtual gd::EventsList& GetSubEvents() { return events; };
const gd::InstructionsList& GetConditions() const { return conditions; };
gd::InstructionsList& GetConditions() { return conditions; };
const gd::InstructionsList& GetActions() const { return actions; };
gd::InstructionsList& GetActions() { return actions; };
/**
* \brief Get the iterable variable name attached to the event.
*
* It is the structure variable that will be iterated on.
*/
const gd::String& GetIterableVariableName() const { return iterableVariableName; };
/**
* \brief Set the iterable variable name attached to the event.
*
* It is the structure variable that will be iterated on.
*/
void SetIterableVariableName(gd::String newName) { iterableVariableName = newName; };
/**
* \brief Get the value iterator variable attached to the event.
*
* It is the variable that will contain the value of the
* iterable's child being iterated on.
*/
const gd::String& GetValueIteratorVariableName() const { return valueIteratorVariableName; };
/**
* \brief Set the value iterator variable attached to the event.
*
* It is the variable that will contain the value of the
* iterable's child being iterated on.
*/
void SetValueIteratorVariableName(gd::String newName) { valueIteratorVariableName = newName; };
/**
* \brief Get the key iterator variable attached to the event.
*
* It is the variable that will contain the name of the
* iterable's child being iterated on.
*/
const gd::String& GetKeyIteratorVariableName() const { return keyIteratorVariableName; };
/**
* \brief Set the key iterator variable attached to the event.
*
* It is the variable that will contain the name of the
* iterable's child being iterated on.
*/
void SetKeyIteratorVariableName(gd::String newName) { keyIteratorVariableName = newName; };
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
const;
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,
const SerializerElement& element);
private:
gd::String valueIteratorVariableName;
gd::String keyIteratorVariableName;
gd::String iterableVariableName;
gd::InstructionsList conditions;
gd::InstructionsList actions;
gd::EventsList events;
};
} // namespace gd
#endif // FOREACHEVENT_H

View File

@@ -31,12 +31,17 @@ vector<gd::InstructionsList*> ForEachEvent::GetAllActionsVectors() {
return allActions;
}
vector<gd::Expression*> ForEachEvent::GetAllExpressions() {
vector<gd::Expression*> allExpressions;
allExpressions.push_back(&objectsToPick);
vector<pair<gd::Expression*, gd::ParameterMetadata> >
ForEachEvent::GetAllExpressionsWithMetadata() {
vector<pair<gd::Expression*, gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("object");
allExpressionsWithMetadata.push_back(
std::make_pair(&objectsToPick, metadata));
return allExpressions;
return allExpressionsWithMetadata;
}
vector<const gd::InstructionsList*> ForEachEvent::GetAllConditionsVectors()
const {
vector<const gd::InstructionsList*> allConditions;
@@ -52,11 +57,15 @@ vector<const gd::InstructionsList*> ForEachEvent::GetAllActionsVectors() const {
return allActions;
}
vector<const gd::Expression*> ForEachEvent::GetAllExpressions() const {
vector<const gd::Expression*> allExpressions;
allExpressions.push_back(&objectsToPick);
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
ForEachEvent::GetAllExpressionsWithMetadata() const {
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("object");
allExpressionsWithMetadata.push_back(
std::make_pair(&objectsToPick, metadata));
return allExpressions;
return allExpressionsWithMetadata;
}
void ForEachEvent::SerializeTo(SerializerElement& element) const {

View File

@@ -50,10 +50,13 @@ class GD_CORE_API ForEachEvent : public gd::BaseEvent {
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
const;
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
virtual std::vector<const gd::Expression*> GetAllExpressions() const;
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() const;
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
virtual std::vector<gd::Expression*> GetAllExpressions();
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
GetAllExpressionsWithMetadata();
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,

View File

@@ -31,11 +31,15 @@ vector<gd::InstructionsList*> RepeatEvent::GetAllActionsVectors() {
return allActions;
}
vector<gd::Expression*> RepeatEvent::GetAllExpressions() {
vector<gd::Expression*> allExpressions;
allExpressions.push_back(&repeatNumberExpression);
vector<pair<gd::Expression*, gd::ParameterMetadata> >
RepeatEvent::GetAllExpressionsWithMetadata() {
vector<pair<gd::Expression*, gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("expression");
allExpressionsWithMetadata.push_back(
std::make_pair(&repeatNumberExpression, metadata));
return allExpressions;
return allExpressionsWithMetadata;
}
vector<const gd::InstructionsList*> RepeatEvent::GetAllConditionsVectors()
@@ -53,11 +57,15 @@ vector<const gd::InstructionsList*> RepeatEvent::GetAllActionsVectors() const {
return allActions;
}
vector<const gd::Expression*> RepeatEvent::GetAllExpressions() const {
vector<const gd::Expression*> allExpressions;
allExpressions.push_back(&repeatNumberExpression);
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
RepeatEvent::GetAllExpressionsWithMetadata() const {
vector<pair<const gd::Expression*, const gd::ParameterMetadata> >
allExpressionsWithMetadata;
auto metadata = gd::ParameterMetadata().SetType("expression");
allExpressionsWithMetadata.push_back(
std::make_pair(&repeatNumberExpression, metadata));
return allExpressions;
return allExpressionsWithMetadata;
}
void RepeatEvent::SerializeTo(SerializerElement& element) const {

View File

@@ -45,11 +45,14 @@ class GD_CORE_API RepeatEvent : public gd::BaseEvent {
virtual std::vector<gd::InstructionsList*> GetAllConditionsVectors();
virtual std::vector<gd::InstructionsList*> GetAllActionsVectors();
virtual std::vector<gd::Expression*> GetAllExpressions();
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
GetAllExpressionsWithMetadata();
virtual std::vector<const gd::InstructionsList*> GetAllConditionsVectors()
const;
virtual std::vector<const gd::InstructionsList*> GetAllActionsVectors() const;
virtual std::vector<const gd::Expression*> GetAllExpressions() const;
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() const;
virtual void SerializeTo(SerializerElement& element) const;
virtual void UnserializeFrom(gd::Project& project,

View File

@@ -1,6 +1,8 @@
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
#include <algorithm>
#include <utility>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
#include "GDCore/Events/CodeGeneration/ExpressionCodeGenerator.h"
@@ -286,7 +288,7 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
condition.SetParameters(parameters);
}
// Verify that there are not mismatch between object type in parameters
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter =
@@ -310,9 +312,69 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
}
}
// Generate static condition if available
if (MetadataProvider::HasCondition(platform, condition.GetType())) {
// Prepare arguments
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!objectName.empty() && !instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = condition.GetParameter(0).GetPlainString();
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
condition.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole condition code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateBehaviorCondition(
realObjects[i],
condition.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
} else {
std::vector<std::pair<gd::String, gd::String> >
supplementaryParametersTypes;
supplementaryParametersTypes.push_back(std::make_pair(
@@ -327,78 +389,6 @@ gd::String EventsCodeGenerator::GenerateConditionCode(
arguments, instrInfos, returnBoolean, condition.IsInverted(), context);
}
// Generate object condition if available
gd::String objectName = condition.GetParameters().empty()
? ""
: condition.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!objectName.empty() &&
MetadataProvider::HasObjectCondition(
platform, objectType, condition.GetType()) &&
!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Set up the context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the condition whole code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode += GenerateObjectCondition(realObjects[i],
objInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
// Generate behavior condition if available
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
condition.GetParameters().size() < 2
? ""
: condition.GetParameter(1).GetPlainString());
if (MetadataProvider::HasBehaviorCondition(
platform, behaviorType, condition.GetType()) &&
instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole condition code
vector<gd::String> arguments = GenerateParametersCodes(
condition.GetParameters(), instrInfos.parameters, context);
conditionCode +=
GenerateBehaviorCondition(realObjects[i],
condition.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
returnBoolean,
condition.IsInverted(),
context);
context.SetNoCurrentObject();
}
}
return conditionCode;
}
@@ -415,9 +405,6 @@ gd::String EventsCodeGenerator::GenerateConditionsListCode(
"condition" + gd::String::From(i) + "IsTrue", context);
for (std::size_t cId = 0; cId < conditions.size(); ++cId) {
gd::InstructionMetadata instrInfos = MetadataProvider::GetConditionMetadata(
platform, conditions[cId].GetType());
gd::String conditionCode =
GenerateConditionCode(conditions[cId],
"condition" + gd::String::From(cId) + "IsTrue",
@@ -470,7 +457,7 @@ gd::String EventsCodeGenerator::GenerateActionCode(
action.SetParameters(parameters);
}
// Verify that there are not mismatch between object type in parameters
// Verify that there are no mismatchs between object type in parameters.
for (std::size_t pNb = 0; pNb < instrInfos.parameters.size(); ++pNb) {
if (ParameterMetadata::IsObject(instrInfos.parameters[pNb].type)) {
gd::String objectInParameter = action.GetParameter(pNb).GetPlainString();
@@ -493,77 +480,69 @@ gd::String EventsCodeGenerator::GenerateActionCode(
}
// Call free function first if available
if (MetadataProvider::HasAction(platform, action.GetType())) {
if (instrInfos.IsObjectInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(
realObjects[i], objInfo, arguments, instrInfos, context);
context.SetNoCurrentObject();
}
}
} else if (instrInfos.IsBehaviorInstruction()) {
gd::String objectName = action.GetParameter(0).GetPlainString();
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
action.GetParameter(1).GetPlainString());
if (instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode +=
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
context);
context.SetNoCurrentObject();
}
}
} else {
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateFreeAction(arguments, instrInfos, context);
}
// Call object function if available
gd::String objectName = action.GetParameters().empty()
? ""
: action.GetParameter(0).GetPlainString();
gd::String objectType = gd::GetTypeOfObject(
GetGlobalObjectsAndGroups(), GetObjectsAndGroups(), objectName);
if (MetadataProvider::HasObjectAction(
platform, objectType, action.GetType()) &&
!instrInfos.parameters.empty()) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const ObjectMetadata& objInfo =
MetadataProvider::GetObjectMetadata(platform, objectType);
AddIncludeFiles(objInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode += GenerateObjectAction(
realObjects[i], objInfo, arguments, instrInfos, context);
context.SetNoCurrentObject();
}
}
// Assign to a behavior member function if found
gd::String behaviorType =
gd::GetTypeOfBehavior(GetGlobalObjectsAndGroups(),
GetObjectsAndGroups(),
action.GetParameters().size() < 2
? ""
: action.GetParameter(1).GetPlainString());
if (MetadataProvider::HasBehaviorAction(
platform, behaviorType, action.GetType()) &&
instrInfos.parameters.size() >= 2) {
std::vector<gd::String> realObjects =
ExpandObjectsName(objectName, context);
for (std::size_t i = 0; i < realObjects.size(); ++i) {
// Setup context
const BehaviorMetadata& autoInfo =
MetadataProvider::GetBehaviorMetadata(platform, behaviorType);
AddIncludeFiles(autoInfo.includeFiles);
context.SetCurrentObject(realObjects[i]);
context.ObjectsListNeeded(realObjects[i]);
// Prepare arguments and generate the whole action code
vector<gd::String> arguments = GenerateParametersCodes(
action.GetParameters(), instrInfos.parameters, context);
actionCode +=
GenerateBehaviorAction(realObjects[i],
action.GetParameter(1).GetPlainString(),
autoInfo,
arguments,
instrInfos,
context);
context.SetNoCurrentObject();
}
}
return actionCode;
}
@@ -574,9 +553,6 @@ gd::String EventsCodeGenerator::GenerateActionsListCode(
gd::InstructionsList& actions, EventsCodeGenerationContext& context) {
gd::String outputCode;
for (std::size_t aId = 0; aId < actions.size(); ++aId) {
gd::InstructionMetadata instrInfos =
MetadataProvider::GetActionMetadata(platform, actions[aId].GetType());
gd::String actionCode = GenerateActionCode(actions[aId], context);
outputCode += "{";
@@ -628,7 +604,7 @@ gd::String EventsCodeGenerator::GenerateParameterCodes(
argOutput = "\"" + argOutput + "\"";
} else if (ParameterMetadata::IsBehavior(metadata.type)) {
argOutput = "\"" + ConvertToString(parameter) + "\"";
argOutput = GenerateGetBehaviorNameCode(parameter);
} else if (metadata.type == "key") {
argOutput = "\"" + ConvertToString(parameter) + "\"";
} else if (metadata.type == "password" || metadata.type == "musicfile" ||
@@ -1109,6 +1085,34 @@ gd::String EventsCodeGenerator::GenerateBehaviorAction(
}
}
size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdForEventsList() {
return eventsListNextUniqueId++;
}
size_t EventsCodeGenerator::GenerateSingleUsageUniqueIdFor(
const Instruction* instruction) {
if (!instruction) {
std::cout << "ERROR: During code generation, a null pointer was passed to "
"GenerateSingleUsageUniqueIdFor."
<< std::endl;
}
// Base the unique id on the adress in memory so that the same instruction
// in memory will get the same id across different code generations.
size_t uniqueId = (size_t)instruction;
// While in most case this function is called a single time for each
// instruction, it's possible for an instruction to be appearing more than
// once in the events, if we used links. In this case, simply increment the
// unique id to be sure that ids are effectively uniques, and stay stable
// (given the same order of links).
while (instructionUniqueIds.find(uniqueId) != instructionUniqueIds.end()) {
uniqueId++;
}
instructionUniqueIds.insert(uniqueId);
return uniqueId;
}
gd::String EventsCodeGenerator::GetObjectListName(
const gd::String& name, const gd::EventsCodeGenerationContext& context) {
return ManObjListName(name);
@@ -1137,7 +1141,8 @@ EventsCodeGenerator::EventsCodeGenerator(gd::Project& project_,
errorOccurred(false),
compilationForRuntime(false),
maxCustomConditionsDepth(0),
maxConditionsListsSize(0){};
maxConditionsListsSize(0),
eventsListNextUniqueId(0){};
EventsCodeGenerator::EventsCodeGenerator(
const gd::Platform& platform_,
@@ -1152,6 +1157,7 @@ EventsCodeGenerator::EventsCodeGenerator(
errorOccurred(false),
compilationForRuntime(false),
maxCustomConditionsDepth(0),
maxConditionsListsSize(0){};
maxConditionsListsSize(0),
eventsListNextUniqueId(0){};
} // namespace gd

View File

@@ -9,6 +9,7 @@
#include <set>
#include <utility>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/String.h"
@@ -123,7 +124,7 @@ class GD_CORE_API EventsCodeGenerator {
*
*/
std::vector<gd::String> GenerateParametersCodes(
const std::vector<gd::Expression> & parameters,
const std::vector<gd::Expression>& parameters,
const std::vector<gd::ParameterMetadata>& parametersInfo,
EventsCodeGenerationContext& context,
std::vector<std::pair<gd::String, gd::String> >*
@@ -321,7 +322,7 @@ class GD_CORE_API EventsCodeGenerator {
* group.
*
* Get a list containing the "real" objects name when the events refers to \a
* objectName :<br> If \a objectName if really an object, the list will only
* objectName :<br> If \a objectName is really an object, the list will only
* contains \a objectName unchanged.<br> If \a objectName is a group, the list
* will contains all the objects of the group.<br> If \a objectName is the
* "current" object in the context ( i.e: The object being used for launching
@@ -411,6 +412,29 @@ class GD_CORE_API EventsCodeGenerator {
enum VariableScope { LAYOUT_VARIABLE = 0, PROJECT_VARIABLE, OBJECT_VARIABLE };
/**
* Generate a single unique number for the specified instruction.
*
* This is useful for instructions that need to identify themselves in the
* generated code like the "Trigger Once" conditions. The id is stable across
* code generations if the instructions are the same objects in memory.
*
* Note that if this function is called multiple times with the same
* instruction, the unique number returned will be *different*. This is
* because a single instruction might appear at multiple places in events due
* to the usage of links.
*/
size_t GenerateSingleUsageUniqueIdFor(const gd::Instruction* instruction);
/**
* Generate a single unique number for an events list.
*
* This is useful to create unique function names for events list, that are
* stable across code generation given the exact same list of events. They are
* *not* stable if events are moved/reorganized.
*/
size_t GenerateSingleUsageUniqueIdForEventsList();
protected:
/**
* \brief Generate the code for a single parameter.
@@ -704,7 +728,8 @@ class GD_CORE_API EventsCodeGenerator {
/**
* Generate the getter to get the name of the specified behavior.
*/
virtual gd::String GenerateGetBehaviorNameCode(const gd::String& behaviorName);
virtual gd::String GenerateGetBehaviorNameCode(
const gd::String& behaviorName);
const gd::Platform& platform; ///< The platform being used.
@@ -732,6 +757,11 @@ class GD_CORE_API EventsCodeGenerator {
size_t maxCustomConditionsDepth; ///< The maximum depth value for all the
///< custom conditions created.
size_t maxConditionsListsSize; ///< The maximum size of a list of conditions.
std::set<size_t>
instructionUniqueIds; ///< The unique ids generated for instructions.
size_t eventsListNextUniqueId; ///< The next identifier to use for an events
///< list function name.
};
} // namespace gd

View File

@@ -4,8 +4,10 @@
* reserved. This project is released under the MIT License.
*/
#include "ExpressionCodeGenerator.h"
#include <memory>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerationContext.h"
#include "GDCore/Events/CodeGeneration/EventsCodeGenerator.h"
@@ -35,11 +37,18 @@ gd::String ExpressionCodeGenerator::GenerateExpressionCode(
gd::ExpressionParser2 parser(codeGenerator.GetPlatform(),
codeGenerator.GetGlobalObjectsAndGroups(),
codeGenerator.GetObjectsAndGroups());
ExpressionCodeGenerator generator(codeGenerator, context);
auto node = parser.ParseExpression(type, expression, objectName);
if (!node) {
std::cout << "Error: error while parsing: \"" << expression << "\" ("
<< type << ")" << std::endl;
return generator.GenerateDefaultValue(type);
}
gd::ExpressionValidator validator;
node->Visit(validator);
ExpressionCodeGenerator generator(codeGenerator, context);
if (!validator.GetErrors().empty()) {
std::cout << "Error: \"" << validator.GetErrors()[0]->GetMessage()
<< "\" in: \"" << expression << "\" (" << type << ")"
@@ -130,8 +139,8 @@ void ExpressionCodeGenerator::OnVisitIdentifierNode(IdentifierNode& node) {
void ExpressionCodeGenerator::OnVisitFunctionCallNode(FunctionCallNode& node) {
if (gd::MetadataProvider::IsBadExpressionMetadata(node.expressionMetadata)) {
output += "/* Error during generation, function not found: " +
codeGenerator.ConvertToString(node.functionName) + " for type " +
node.type + " */ " + GenerateDefaultValue(node.type);
codeGenerator.ConvertToString(node.functionName) + " */ " +
GenerateDefaultValue(node.type);
return;
}
@@ -359,7 +368,8 @@ void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {
output += GenerateDefaultValue(node.type);
}
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) {
void ExpressionCodeGenerator::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode& node) {
output += GenerateDefaultValue(node.type);
}

View File

@@ -12,6 +12,7 @@
#include <vector>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
namespace gd {
class EventsList;
@@ -127,15 +128,17 @@ class GD_CORE_API BaseEvent {
};
/**
* \brief Return a list of all expressions of the event.
* \note Used to preprocess or search in the expressions.
* \brief Return a list of all expressions of the event, each with their associated metadata.
* \note Used to preprocess or search in the expressions of the event.
*/
virtual std::vector<gd::Expression*> GetAllExpressions() {
std::vector<gd::Expression*> noExpr;
virtual std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() {
std::vector<std::pair<gd::Expression*, gd::ParameterMetadata> > noExpr;
return noExpr;
};
virtual std::vector<const gd::Expression*> GetAllExpressions() const {
std::vector<const gd::Expression*> noExpr;
virtual std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> >
GetAllExpressionsWithMetadata() const {
std::vector<std::pair<const gd::Expression*, const gd::ParameterMetadata> > noExpr;
return noExpr;
};

View File

@@ -4,9 +4,12 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Events/Instruction.h"
#include <assert.h>
#include <iostream>
#include <vector>
#include "GDCore/Events/Expression.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/String.h"
@@ -15,18 +18,14 @@ namespace gd {
gd::Expression Instruction::badExpression("");
Instruction::Instruction(gd::String type_)
: type(type_),
inverted(false) {
Instruction::Instruction(gd::String type_) : type(type_), inverted(false) {
parameters.reserve(8);
}
Instruction::Instruction(gd::String type_,
const std::vector<gd::Expression>& parameters_,
bool inverted_)
: type(type_),
inverted(inverted_),
parameters(parameters_) {
: type(type_), inverted(inverted_), parameters(parameters_) {
parameters.reserve(8);
}
@@ -56,4 +55,17 @@ void Instruction::SetParameter(std::size_t nb, const gd::Expression& val) {
parameters[nb] = val;
}
std::shared_ptr<Instruction> GD_CORE_API
CloneRememberingOriginalElement(std::shared_ptr<Instruction> instruction) {
std::shared_ptr<Instruction> copy =
std::make_shared<Instruction>(*instruction);
// Original instruction is either the original instruction of the copied
// instruction, or the instruction copied.
copy->originalInstruction = instruction->originalInstruction.expired()
? instruction
: instruction->originalInstruction;
return copy;
}
} // namespace gd

View File

@@ -5,7 +5,9 @@
*/
#ifndef INSTRUCTION_H
#define INSTRUCTION_H
#include <memory>
#include <vector>
#include "GDCore/Events/Expression.h"
#include "GDCore/Events/InstructionsList.h"
#include "GDCore/String.h"
@@ -131,6 +133,17 @@ class GD_CORE_API Instruction {
*/
inline gd::InstructionsList& GetSubInstructions() { return subInstructions; };
/**
* \brief Return the original instruction this instruction was copied from.
*
* Useful to get reference to the original instruction in memory during code
* generation, to ensure stable unique identifiers.
*/
std::weak_ptr<Instruction> GetOriginalInstruction() { return originalInstruction; };
friend std::shared_ptr<Instruction> CloneRememberingOriginalElement(
std::shared_ptr<Instruction> instruction);
private:
gd::String type; ///< Instruction type
bool inverted; ///< True if the instruction if inverted. Only applicable for
@@ -139,9 +152,23 @@ class GD_CORE_API Instruction {
parameters; ///< Vector containing the parameters
gd::InstructionsList subInstructions; ///< Sub instructions, if applicable.
std::weak_ptr<Instruction>
originalInstruction; ///< Pointer used to remember which gd::Instruction
///< this instruction was copied from. Useful to
///< ensure the stability of code generation (as
///< some part of code generation uses the pointer
///< to the instruction as a unique identifier).
static gd::Expression badExpression;
};
/**
* Clone the given instruction, returning an instruction for which
* `GetOriginalInstruction()` returns the originally copied instruction.
*/
std::shared_ptr<Instruction> GD_CORE_API
CloneRememberingOriginalElement(std::shared_ptr<Instruction> instruction);
} // namespace gd
#endif // INSTRUCTION_H

View File

@@ -4,9 +4,11 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include <algorithm>
#include <memory>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/Expression.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
@@ -67,7 +69,9 @@ size_t GetMaximumParametersNumber(
} // namespace
std::unique_ptr<ExpressionParserDiagnostic> ExpressionParser2::ValidateFunction(
const gd::FunctionCallNode& function, size_t functionStartPosition) {
const gd::String& type,
const gd::FunctionCallNode& function,
size_t functionStartPosition) {
if (gd::MetadataProvider::IsBadExpressionMetadata(
function.expressionMetadata)) {
return gd::make_unique<ExpressionParserError>(
@@ -79,6 +83,41 @@ std::unique_ptr<ExpressionParserDiagnostic> ExpressionParser2::ValidateFunction(
GetCurrentPosition());
}
// Validate the type of the function
const gd::String& returnType = function.expressionMetadata.GetReturnType();
if (returnType == "number") {
if (type == "string")
return RaiseTypeError(
_("You tried to use an expression that returns a number, but a "
"string is expected. Use `ToString` if you need to convert a "
"number to a string."),
functionStartPosition);
else if (type != "number" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"number, but another type is expected:") +
" " + type,
functionStartPosition);
} else if (returnType == "string") {
if (type == "number")
return RaiseTypeError(
_("You tried to use an expression that returns a string, but a "
"number is expected. Use `ToNumber` if you need to convert a "
"string to a number."),
functionStartPosition);
else if (type != "string" && type != "number|string")
return RaiseTypeError(_("You tried to use an expression that returns a "
"string, but another type is expected:") +
" " + type,
functionStartPosition);
} else {
if (type != returnType)
return RaiseTypeError(
_("You tried to use an expression with the wrong return type:") + " " +
returnType,
functionStartPosition);
}
// Validate parameters count
size_t minParametersCount = GetMinimumParametersNumber(
function.expressionMetadata.parameters,
WrittenParametersFirstIndex(function.objectName, function.behaviorName));
@@ -115,7 +154,8 @@ std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
auto text = gd::make_unique<TextNode>("");
text->diagnostic =
RaiseSyntaxError(_("A text must start with a double quote (\")."));
text->location = ExpressionParserLocation(textStartPosition, GetCurrentPosition());
text->location =
ExpressionParserLocation(textStartPosition, GetCurrentPosition());
return text;
}
SkipChar();
@@ -150,7 +190,8 @@ std::unique_ptr<TextNode> ExpressionParser2::ReadText() {
}
auto text = gd::make_unique<TextNode>(parsedText);
text->location = ExpressionParserLocation(textStartPosition, GetCurrentPosition());
text->location =
ExpressionParserLocation(textStartPosition, GetCurrentPosition());
if (!textParsingHasEnded) {
text->diagnostic =
RaiseSyntaxError(_("A text must end with a double quote (\"). Add a "
@@ -172,7 +213,7 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
if (CheckIfChar(IsZeroDigit)) {
numberHasStarted = true;
digitFound = true;
if (!parsedNumber.empty()) { // Ignore leading 0s.
if (!parsedNumber.empty()) { // Ignore leading 0s.
parsedNumber += GetCurrentChar();
}
} else if (CheckIfChar(IsNonZeroDigit)) {
@@ -183,7 +224,8 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
numberHasStarted = true;
dotFound = true;
if (parsedNumber == "") {
parsedNumber += "0."; //Normalize by adding a leading 0, only in this case.
parsedNumber +=
"0."; // Normalize by adding a leading 0, only in this case.
} else {
parsedNumber += ".";
}
@@ -204,7 +246,8 @@ std::unique_ptr<NumberNode> ExpressionParser2::ReadNumber() {
// valid in most languages so we allow this.
auto number = gd::make_unique<NumberNode>(parsedNumber);
number->location = ExpressionParserLocation(numberStartPosition, GetCurrentPosition());
number->location =
ExpressionParserLocation(numberStartPosition, GetCurrentPosition());
if (!numberHasStarted || !digitFound) {
number->diagnostic = RaiseSyntaxError(
_("A number was expected. You must enter a number here."));

View File

@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
#include <vector>
#include "ExpressionParser2Node.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
@@ -75,9 +76,11 @@ class GD_CORE_API ExpressionParser2 {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression(type, objectName);
const gd::String &inferredType = expression->type;
// Check for extra characters at the end of the expression
if (!IsEndReached()) {
auto op = gd::make_unique<OperatorNode>(type, ' ');
auto op = gd::make_unique<OperatorNode>(inferredType, ' ');
op->leftHandSide = std::move(expression);
op->rightHandSide = ReadUntilEnd("unknown");
@@ -100,27 +103,29 @@ class GD_CORE_API ExpressionParser2 {
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> leftHandSide = Term(type, objectName);
const gd::String &inferredType = leftHandSide->type;
SkipAllWhitespaces();
if (IsEndReached()) return leftHandSide;
if (CheckIfChar(IsExpressionEndingChar)) return leftHandSide;
if (CheckIfChar(IsExpressionOperator)) {
auto op = gd::make_unique<OperatorNode>(type, GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(leftHandSide);
op->diagnostic = ValidateOperator(type, GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Expression(type, objectName);
op->rightHandSide = Expression(inferredType, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
return std::move(op);
}
if (type == "string") {
if (inferredType == "string") {
leftHandSide->diagnostic = RaiseSyntaxError(
"You must add the operator + between texts or expressions. For "
"example: \"Your name: \" + VariableString(PlayerName).");
} else if (type == "number") {
} else if (inferredType == "number") {
leftHandSide->diagnostic = RaiseSyntaxError(
"No operator found. Did you forget to enter an operator (like +, -, "
"* or /) between numbers or expressions?");
@@ -130,9 +135,9 @@ class GD_CORE_API ExpressionParser2 {
"properly written.");
}
auto op = gd::make_unique<OperatorNode>(type, ' ');
auto op = gd::make_unique<OperatorNode>(inferredType, ' ');
op->leftHandSide = std::move(leftHandSide);
op->rightHandSide = Expression(type, objectName);
op->rightHandSide = Expression(inferredType, objectName);
op->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
return std::move(op);
@@ -145,17 +150,19 @@ class GD_CORE_API ExpressionParser2 {
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> factor = Factor(type, objectName);
const gd::String &inferredType = factor->type;
SkipAllWhitespaces();
// This while loop is used instead of a recursion (like in Expression)
// to guarantee the proper operator precedence. (Expression could also
// be reworked to use a while loop).
while (CheckIfChar(IsTermOperator)) {
auto op = gd::make_unique<OperatorNode>(type, GetCurrentChar());
auto op = gd::make_unique<OperatorNode>(inferredType, GetCurrentChar());
op->leftHandSide = std::move(factor);
op->diagnostic = ValidateOperator(type, GetCurrentChar());
op->diagnostic = ValidateOperator(inferredType, GetCurrentChar());
SkipChar();
op->rightHandSide = Factor(type, objectName);
op->rightHandSide = Factor(inferredType, objectName);
op->location = ExpressionParserLocation(expressionStartPosition,
GetCurrentPosition());
SkipAllWhitespaces();
@@ -169,43 +176,51 @@ class GD_CORE_API ExpressionParser2 {
std::unique_ptr<ExpressionNode> Factor(const gd::String &type,
const gd::String &objectName) {
SkipAllWhitespaces();
size_t expressionStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> factor;
if (CheckIfChar(IsQuote)) {
factor = ReadText();
std::unique_ptr<ExpressionNode> factor = ReadText();
if (type == "number")
factor->diagnostic =
RaiseTypeError(_("You entered a text, but a number was expected."),
expressionStartPosition);
else if (type != "string")
else if (type != "string" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a text, but this type was expected:") + type,
expressionStartPosition);
} else if (CheckIfChar(IsUnaryOperator)) {
auto unaryOperator =
gd::make_unique<UnaryOperatorNode>(type, GetCurrentChar());
unaryOperator->diagnostic = ValidateUnaryOperator(type, GetCurrentChar());
SkipChar();
unaryOperator->factor = Factor(type, objectName);
return factor;
} else if (CheckIfChar(IsUnaryOperator)) {
auto unaryOperatorCharacter = GetCurrentChar();
SkipChar();
auto operatorOperand = Factor(type, objectName);
const gd::String &inferredType = operatorOperand->type;
auto unaryOperator = gd::make_unique<UnaryOperatorNode>(
inferredType, unaryOperatorCharacter);
unaryOperator->diagnostic = ValidateUnaryOperator(
inferredType, unaryOperatorCharacter, expressionStartPosition);
unaryOperator->factor = std::move(operatorOperand);
unaryOperator->location = ExpressionParserLocation(
expressionStartPosition, GetCurrentPosition());
factor = std::move(unaryOperator);
return std::move(unaryOperator);
} else if (CheckIfChar(IsNumberFirstChar)) {
factor = ReadNumber();
std::unique_ptr<ExpressionNode> factor = ReadNumber();
if (type == "string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but a text was expected (in quotes)."),
expressionStartPosition);
else if (type != "number")
else if (type != "number" && type != "number|string")
factor->diagnostic = RaiseTypeError(
_("You entered a number, but this type was expected:") + type,
expressionStartPosition);
return factor;
} else if (CheckIfChar(IsOpeningParenthesis)) {
SkipChar();
factor = SubExpression(type, objectName);
std::unique_ptr<ExpressionNode> factor = SubExpression(type, objectName);
if (!CheckIfChar(IsClosingParenthesis)) {
factor->diagnostic =
@@ -213,27 +228,31 @@ class GD_CORE_API ExpressionParser2 {
"parenthesis for each opening parenthesis."));
}
SkipIfChar(IsClosingParenthesis);
return factor;
} else if (IsIdentifierAllowedChar()) {
// This is a place where the grammar differs according to the
// type being expected.
if (gd::ParameterMetadata::IsExpression("variable", type)) {
factor = Variable(type, objectName);
return Variable(type, objectName);
} else {
factor = Identifier(type);
return Identifier(type);
}
} else {
factor = ReadUntilWhitespace(type);
factor->diagnostic = RaiseEmptyError(type, expressionStartPosition);
}
std::unique_ptr<ExpressionNode> factor = ReadUntilWhitespace(type);
factor->diagnostic = RaiseEmptyError(type, expressionStartPosition);
return factor;
}
std::unique_ptr<SubExpressionNode> SubExpression(
const gd::String &type, const gd::String &objectName) {
size_t expressionStartPosition = GetCurrentPosition();
auto expression = Expression(type, objectName);
const gd::String &inferredType = expression->type;
auto subExpression =
gd::make_unique<SubExpressionNode>(type, Expression(type, objectName));
gd::make_unique<SubExpressionNode>(inferredType, std::move(expression));
subExpression->location =
ExpressionParserLocation(expressionStartPosition, GetCurrentPosition());
@@ -284,6 +303,11 @@ class GD_CORE_API ExpressionParser2 {
} else if (type == "number") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number."), nameLocation.GetStartPosition());
} else if (type == "number|string") {
identifier->diagnostic = RaiseTypeError(
_("You must enter a number or a text, wrapped inside double quotes "
"(example: \"Hello world\")."),
nameLocation.GetStartPosition());
} else if (!gd::ParameterMetadata::IsObject(type)) {
identifier->diagnostic = RaiseTypeError(
_("You've entered a name, but this type was expected:") + type,
@@ -318,8 +342,8 @@ class GD_CORE_API ExpressionParser2 {
SkipAllWhitespaces();
if (CheckIfChar(IsOpeningSquareBracket)) {
SkipChar();
auto child =
gd::make_unique<VariableBracketAccessorNode>(Expression("string"));
auto child = gd::make_unique<VariableBracketAccessorNode>(
Expression("number|string"));
if (!CheckIfChar(IsClosingSquareBracket)) {
child->diagnostic =
@@ -360,21 +384,19 @@ class GD_CORE_API ExpressionParser2 {
// TODO: error if trying to use function for type != "number" && != "string"
// + Test for it
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number" ? MetadataProvider::GetExpressionMetadata(
platform, functionFullName)
: MetadataProvider::GetStrExpressionMetadata(
platform, functionFullName);
MetadataProvider::GetAnyExpressionMetadata(platform, functionFullName);
auto parametersNode = Parameters(metadata.parameters);
auto function = gd::make_unique<FunctionCallNode>(
type, std::move(parametersNode.parameters), metadata, functionFullName);
auto function =
gd::make_unique<FunctionCallNode>(metadata.GetReturnType(),
std::move(parametersNode.parameters),
metadata,
functionFullName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, identifierLocation.GetStartPosition());
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, identifierLocation.GetStartPosition());
function->location = ExpressionParserLocation(
identifierLocation.GetStartPosition(), GetCurrentPosition());
@@ -382,6 +404,7 @@ class GD_CORE_API ExpressionParser2 {
function->openingParenthesisLocation = openingParenthesisLocation;
function->closingParenthesisLocation =
parametersNode.closingParenthesisLocation;
return std::move(function);
}
@@ -415,26 +438,21 @@ class GD_CORE_API ExpressionParser2 {
gd::String objectType =
GetTypeOfObject(globalObjectsContainer, objectsContainer, objectName);
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number"
? MetadataProvider::GetObjectExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName)
: MetadataProvider::GetObjectStrExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName);
MetadataProvider::GetObjectAnyExpressionMetadata(
platform, objectType, objectFunctionOrBehaviorName);
auto parametersNode = Parameters(metadata.parameters, objectName);
auto function = gd::make_unique<FunctionCallNode>(
type,
metadata.GetReturnType(),
objectName,
std::move(parametersNode.parameters),
metadata,
objectFunctionOrBehaviorName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, objectNameLocation.GetStartPosition());
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
objectNameLocation.GetStartPosition(), GetCurrentPosition());
@@ -482,27 +500,23 @@ class GD_CORE_API ExpressionParser2 {
gd::String behaviorType = GetTypeOfBehavior(
globalObjectsContainer, objectsContainer, behaviorName);
// This could be improved to have the type passed to a single
// GetExpressionMetadata function.
const gd::ExpressionMetadata &metadata =
type == "number" ? MetadataProvider::GetBehaviorExpressionMetadata(
platform, behaviorType, functionName)
: MetadataProvider::GetBehaviorStrExpressionMetadata(
platform, behaviorType, functionName);
MetadataProvider::GetBehaviorAnyExpressionMetadata(
platform, behaviorType, functionName);
auto parametersNode =
Parameters(metadata.parameters, objectName, behaviorName);
auto function = gd::make_unique<FunctionCallNode>(
type,
metadata.GetReturnType(),
objectName,
behaviorName,
std::move(parametersNode.parameters),
metadata,
functionName);
function->diagnostic = std::move(parametersNode.diagnostic);
if (!function->diagnostic)
function->diagnostic =
ValidateFunction(*function, objectNameLocation.GetStartPosition());
if (!function->diagnostic) // TODO: reverse the order of diagnostic?
function->diagnostic = ValidateFunction(
type, *function, objectNameLocation.GetStartPosition());
function->location = ExpressionParserLocation(
objectNameLocation.GetStartPosition(), GetCurrentPosition());
@@ -546,6 +560,7 @@ class GD_CORE_API ExpressionParser2 {
const gd::String &objectName = "",
const gd::String &behaviorName = "") {
std::vector<std::unique_ptr<ExpressionNode>> parameters;
gd::String lastObjectName = "";
// By convention, object is always the first parameter, and behavior the
// second one.
@@ -569,9 +584,32 @@ class GD_CORE_API ExpressionParser2 {
} else if (gd::ParameterMetadata::IsExpression("string", type)) {
parameters.push_back(Expression("string"));
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
parameters.push_back(Expression(type, objectName));
parameters.push_back(Expression(
type, lastObjectName.empty() ? objectName : lastObjectName));
} else if (gd::ParameterMetadata::IsObject(type)) {
parameters.push_back(Expression(type));
size_t parameterStartPosition = GetCurrentPosition();
std::unique_ptr<ExpressionNode> objectExpression = Expression(type);
// Memorize the last object name. By convention, parameters that
// require an object (mainly, "objectvar" and "behavior") should be
// placed after the object in the list of parameters (if possible,
// just after). Search "lastObjectName" in the codebase for other
// place where this convention is enforced.
if (auto identifierNode =
dynamic_cast<IdentifierNode *>(objectExpression.get())) {
lastObjectName = identifierNode->identifierName;
} else {
objectExpression->diagnostic =
gd::make_unique<ExpressionParserError>(
"malformed_object_parameter",
_("An object name was expected but something else was "
"written. Enter just the name of the object for this "
"parameter."),
parameterStartPosition,
GetCurrentPosition());
}
parameters.push_back(std::move(objectExpression));
} else {
size_t parameterStartPosition = GetCurrentPosition();
parameters.push_back(Expression("unknown"));
@@ -616,7 +654,9 @@ class GD_CORE_API ExpressionParser2 {
*/
///@{
std::unique_ptr<ExpressionParserDiagnostic> ValidateFunction(
const gd::FunctionCallNode &function, size_t functionStartPosition);
const gd::String &type,
const gd::FunctionCallNode &function,
size_t functionStartPosition);
std::unique_ptr<ExpressionParserDiagnostic> ValidateOperator(
const gd::String &type, gd::String::value_type operatorChar) {
@@ -659,7 +699,9 @@ class GD_CORE_API ExpressionParser2 {
}
std::unique_ptr<ExpressionParserDiagnostic> ValidateUnaryOperator(
const gd::String &type, gd::String::value_type operatorChar) {
const gd::String &type,
gd::String::value_type operatorChar,
size_t position) {
if (type == "number") {
if (operatorChar == '+' || operatorChar == '-') {
return gd::make_unique<ExpressionParserDiagnostic>();
@@ -670,26 +712,26 @@ class GD_CORE_API ExpressionParser2 {
_("You've used an \"unary\" operator that is not supported. Operator "
"should be "
"either + or -."),
GetCurrentPosition());
position);
} else if (type == "string") {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("You've used an operator that is not supported. Only + can be used "
"to concatenate texts, and must be placed between two texts (or "
"expressions)."),
GetCurrentPosition());
position);
} else if (gd::ParameterMetadata::IsObject(type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used with an object name. Remove the "
"operator."),
GetCurrentPosition());
position);
} else if (gd::ParameterMetadata::IsExpression("variable", type)) {
return gd::make_unique<ExpressionParserError>(
"invalid_operator",
_("Operators (+, -) can't be used in variable names. Remove "
"the operator from the variable name."),
GetCurrentPosition());
position);
}
return gd::make_unique<ExpressionParserDiagnostic>();
@@ -849,8 +891,7 @@ class GD_CORE_API ExpressionParser2 {
while (currentPosition < expression.size() &&
(IsIdentifierAllowedChar()
// Allow whitespace in identifier name for compatibility
||
expression[currentPosition] == ' ')) {
|| expression[currentPosition] == ' ')) {
name += expression[currentPosition];
currentPosition++;
}

View File

@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
#include "ExpressionParser2NodeWorker.h"
#include "GDCore/String.h"
namespace gd {
@@ -84,30 +85,33 @@ struct ExpressionParserError : public ExpressionParserDiagnostic {
* an expression inherits from.
*/
struct ExpressionNode {
ExpressionNode(const gd::String &type_) : type(type_){};
virtual ~ExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker){};
std::unique_ptr<ExpressionParserDiagnostic> diagnostic;
ExpressionParserLocation location; ///< The location of the entire node. Some
///nodes might have other locations stored
///inside them. For example, a function
///can store the position of the object
///name, the dot, the function name,
///etc...
/// nodes might have other locations
/// stored inside them. For example, a
/// function can store the position of the
/// object name, the dot, the function
/// name, etc...
gd::String type; // Actual type of the node.
// "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
};
struct SubExpressionNode : public ExpressionNode {
SubExpressionNode(const gd::String &type_,
std::unique_ptr<ExpressionNode> expression_)
: type(type_), expression(std::move(expression_)){};
: ExpressionNode(type_), expression(std::move(expression_)){};
virtual ~SubExpressionNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitSubExpressionNode(*this);
};
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
std::unique_ptr<ExpressionNode> expression;
};
@@ -116,7 +120,7 @@ struct SubExpressionNode : public ExpressionNode {
*/
struct OperatorNode : public ExpressionNode {
OperatorNode(const gd::String &type_, gd::String::value_type op_)
: type(type_), op(op_){};
: ExpressionNode(type_), op(op_){};
virtual ~OperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitOperatorNode(*this);
@@ -124,9 +128,6 @@ struct OperatorNode : public ExpressionNode {
std::unique_ptr<ExpressionNode> leftHandSide;
std::unique_ptr<ExpressionNode> rightHandSide;
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String::value_type op;
};
@@ -135,37 +136,38 @@ struct OperatorNode : public ExpressionNode {
*/
struct UnaryOperatorNode : public ExpressionNode {
UnaryOperatorNode(const gd::String &type_, gd::String::value_type op_)
: type(type_), op(op_){};
: ExpressionNode(type_), op(op_){};
virtual ~UnaryOperatorNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitUnaryOperatorNode(*this);
};
std::unique_ptr<ExpressionNode> factor;
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String::value_type op;
};
/**
* \brief A number node. For example: "123".
* Its `type` is always "number".
*/
struct NumberNode : public ExpressionNode {
NumberNode(const gd::String &number_) : number(number_){};
NumberNode(const gd::String &number_)
: ExpressionNode("number"), number(number_){};
virtual ~NumberNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitNumberNode(*this);
};
//
gd::String number;
};
/**
* \brief A text node. For example: "Hello World".
* Its `type` is always "string".
*/
struct TextNode : public ExpressionNode {
TextNode(const gd::String &text_) : text(text_){};
TextNode(const gd::String &text_) : ExpressionNode("string"), text(text_){};
virtual ~TextNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitTextNode(*this);
@@ -175,6 +177,8 @@ struct TextNode : public ExpressionNode {
};
struct VariableAccessorOrVariableBracketAccessorNode : public ExpressionNode {
VariableAccessorOrVariableBracketAccessorNode() : ExpressionNode(""){};
std::unique_ptr<VariableAccessorOrVariableBracketAccessorNode> child;
};
@@ -190,13 +194,12 @@ struct VariableNode : public ExpressionNode {
VariableNode(const gd::String &type_,
const gd::String &name_,
const gd::String &objectName_)
: type(type_), name(name_), objectName(objectName_){};
: ExpressionNode(type_), name(name_), objectName(objectName_){};
virtual ~VariableNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitVariableNode(*this);
};
gd::String type;
gd::String name;
gd::String objectName;
@@ -240,7 +243,11 @@ struct VariableBracketAccessorNode
};
struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
: public ExpressionNode {};
: public ExpressionNode {
IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(
const gd::String &type)
: ExpressionNode(type){};
};
/**
* \brief An identifier node, usually representing an object or a function name.
@@ -248,18 +255,20 @@ struct IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode
struct IdentifierNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
IdentifierNode(const gd::String &identifierName_, const gd::String &type_)
: identifierName(identifierName_), type(type_){};
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type_),
identifierName(identifierName_){};
virtual ~IdentifierNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitIdentifierNode(*this);
};
gd::String identifierName;
gd::String type;
};
struct FunctionCallOrObjectFunctionNameOrEmptyNode
: public IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode {
FunctionCallOrObjectFunctionNameOrEmptyNode(const gd::String &type)
: IdentifierOrFunctionCallOrObjectFunctionNameOrEmptyNode(type){};
virtual ~FunctionCallOrObjectFunctionNameOrEmptyNode(){};
void Visit(ExpressionParser2NodeWorker &worker) override{};
};
@@ -274,14 +283,14 @@ struct ObjectFunctionNameNode
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &objectFunctionOrBehaviorName_)
: type(type_),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(objectFunctionOrBehaviorName_) {}
ObjectFunctionNameNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_,
const gd::String &behaviorFunctionName_)
: type(type_),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
objectFunctionOrBehaviorName(behaviorName_),
behaviorFunctionName(behaviorFunctionName_) {}
@@ -290,34 +299,30 @@ struct ObjectFunctionNameNode
worker.OnVisitObjectFunctionNameNode(*this);
};
gd::String type; // This could be removed if the type ("string", "number",
// type supported by gd::ParameterMetadata::IsObject, types
// supported by gd::ParameterMetadata::IsExpression or
// "unknown") was stored in ExpressionMetadata.
gd::String objectName;
gd::String objectFunctionOrBehaviorName; ///< Behavior name if
///`behaviorFunctionName` is not
///empty.
/// empty.
gd::String behaviorFunctionName; ///< If empty, then
///objectFunctionOrBehaviorName is filled
///with the behavior name.
/// objectFunctionOrBehaviorName is filled
/// with the behavior name.
ExpressionParserLocation
objectNameLocation; ///< Location of the object name.
ExpressionParserLocation
objectNameDotLocation; ///< Location of the "." after the object name.
ExpressionParserLocation objectFunctionOrBehaviorNameLocation; ///< Location
///of object
///function
///name or
///behavior
///name.
/// of object
/// function
/// name or
/// behavior
/// name.
ExpressionParserLocation
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
///separator, if any.
/// separator, if any.
ExpressionParserLocation behaviorFunctionNameLocation; ///< Location of the
///behavior function
///name, if any.
/// behavior function
/// name, if any.
};
/**
@@ -327,31 +332,36 @@ struct ObjectFunctionNameNode
* "MyObject.Physics::LinearVelocity()".
*/
struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
/** \brief Construct a free function call node. */
FunctionCallNode(const gd::String &type_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: type(type_),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
/** \brief Construct an object function call node. */
FunctionCallNode(const gd::String &type_,
const gd::String &objectName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: type(type_),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
parameters(std::move(parameters_)),
expressionMetadata(expressionMetadata_),
functionName(functionName_){};
/** \brief Construct a behavior function call node. */
FunctionCallNode(const gd::String &type_,
const gd::String &objectName_,
const gd::String &behaviorName_,
std::vector<std::unique_ptr<ExpressionNode>> parameters_,
const ExpressionMetadata &expressionMetadata_,
const gd::String &functionName_)
: type(type_),
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_),
objectName(objectName_),
behaviorName(behaviorName_),
parameters(std::move(parameters_)),
@@ -362,10 +372,6 @@ struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
worker.OnVisitFunctionCallNode(*this);
};
gd::String type; // This could be removed if the type ("string", "number",
// type supported by gd::ParameterMetadata::IsObject, types
// supported by gd::ParameterMetadata::IsExpression or
// "unknown") was stored in ExpressionMetadata.
gd::String objectName;
gd::String behaviorName;
std::vector<std::unique_ptr<ExpressionNode>> parameters;
@@ -382,7 +388,7 @@ struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
behaviorNameLocation; ///< Location of the behavior name, if any.
ExpressionParserLocation
behaviorNameNamespaceSeparatorLocation; ///< Location of the "::"
///separator, if any.
/// separator, if any.
ExpressionParserLocation
openingParenthesisLocation; ///< Location of the "(".
ExpressionParserLocation
@@ -395,15 +401,12 @@ struct FunctionCallNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
*/
struct EmptyNode : public FunctionCallOrObjectFunctionNameOrEmptyNode {
EmptyNode(const gd::String &type_, const gd::String &text_ = "")
: type(type_), text(text_){};
: FunctionCallOrObjectFunctionNameOrEmptyNode(type_), text(text_){};
virtual ~EmptyNode(){};
virtual void Visit(ExpressionParser2NodeWorker &worker) {
worker.OnVisitEmptyNode(*this);
};
gd::String type; // "string", "number", type supported by
// gd::ParameterMetadata::IsObject, types supported by
// gd::ParameterMetadata::IsExpression or "unknown".
gd::String text;
};

View File

@@ -14,7 +14,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
extension.SetExtensionInformation(
"BuiltinAdvanced",
_("Advanced control features"),
_("Built-in extension providing advanced control features."),
_("Advanced control features to be used in events."),
"Florian Rival",
"Open source (MIT License)");
@@ -73,6 +73,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAdvancedExtension(
.AddParameter("trueorfalse", "Should the condition be true or false?")
.MarkAsAdvanced();
extension
.AddCondition("GetArgumentAsBoolean",
_("Check if a function parameter is set to true (or yes)"),
_("Check if the specified function parameter (also called "
"\"argument\") is set to True or Yes. If the argument is "
"a string, an empty string is considered as \"false\". "
"If it's a number, 0 is considered as \"false\"."),
_("Parameter _PARAM0_ is true"),
_("Functions"),
"res/function24.png",
"res/function16.png")
.AddParameter("string", "Parameter name")
.MarkAsAdvanced();
extension
.AddExpression(
"GetArgumentAsNumber",

View File

@@ -12,11 +12,13 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("BuiltinAudio",
_("Audio"),
_("Builtin audio extension"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"BuiltinAudio",
_("Audio"),
_("GDevelop provides several conditions and actions to play audio "
"files. They can be either long musics or short sound effects."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/audio");
#if defined(GD_IDE_ONLY)
@@ -275,6 +277,74 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAudioExtension(
.SetDefaultValue("1")
.MarkAsSimple();
extension
.AddAction("PreloadMusic",
_("Preload a music file"),
_("Preload a music file in memory."),
_("Preload the music file _PARAM1_"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("musicfile", _("Audio file (or audio resource name)"))
.MarkAsComplex();
extension
.AddAction("PreloadSound",
_("Preload a sound file"),
_("Preload a sound file in memory."),
_("Preload the sound file _PARAM1_"),
_("Audio/Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("soundfile", _("Sound file (or sound resource name)"))
.MarkAsComplex();
extension
.AddAction("UnloadMusic",
_("Unload a music file"),
_(
"Unload a music file from memory. "
"Unloading a music file will cause any music playing it to stop."
),
_("Unload the music file _PARAM1_"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("musicfile", _("Audio file (or audio resource name)"))
.MarkAsComplex();
extension
.AddAction("UnloadSound",
_("Unload a sound file"),
_(
"Unload a sound file from memory. "
"Unloading a sound file will cause any sounds playing it to stop."
),
_("Unload the sound file _PARAM1_"),
_("Audio/Loading"),
"res/actions/son24.png",
"res/actions/son.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("soundfile", _("Sound file (or sound resource name)"))
.MarkAsComplex();
extension
.AddAction("UnloadAllAudio",
_("Unload all audio"),
_(
"Unload all the audio in memory. "
"This will cause every sound and music of the game to stop."
),
_("Unload all audio files"),
_("Audio/Loading"),
"res/actions/music24.png",
"res/actions/music.png")
.AddCodeOnlyParameter("currentScene", "")
.MarkAsComplex();
extension
.AddCondition("MusicPlaying",
_("A music file is being played"),

View File

@@ -6,6 +6,7 @@
#include "AllBuiltinExtensions.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
using namespace std;
namespace gd {
@@ -26,7 +27,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
#if defined(GD_IDE_ONLY)
obj.AddCondition("PosX",
_("Compare X position of an object"),
_("X position"),
_("Compare the X position of the object."),
_("the X position"),
_("Position"),
@@ -38,7 +39,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsSimple();
obj.AddAction("MettreX",
_("X position of an object"),
_("X position"),
_("Change the X position of an object."),
_("the X position"),
_("Position"),
@@ -50,7 +51,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsSimple();
obj.AddCondition("PosY",
_("Compare Y position of an object"),
_("Y position"),
_("Compare the Y position of an object."),
_("the Y position"),
_("Position"),
@@ -62,7 +63,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsSimple();
obj.AddAction("MettreY",
_("Y position of an object"),
_("Y position"),
_("Change the Y position of an object."),
_("the Y position"),
_("Position"),
@@ -74,7 +75,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsSimple();
obj.AddAction("MettreXY",
_("Position of an object"),
_("Position"),
_("Change the position of an object."),
_("Change the position of _PARAM0_: _PARAM1_ _PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
@@ -89,8 +90,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("expression", _("Y position"))
.MarkAsSimple();
obj.AddAction("SetCenter",
_("Center position"),
_("Change the position of an object, using its center."),
_("Change the position of the center of _PARAM0_: _PARAM1_ _PARAM2_ (x "
"axis), _PARAM3_ _PARAM4_ (y axis)"),
_("Position/Center"),
"res/actions/position24.png",
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("operator", _("Modification's sign"))
.AddParameter("expression", _("X position"))
.AddParameter("operator", _("Modification's sign"))
.AddParameter("expression", _("Y position"))
.MarkAsSimple();
obj.AddExpressionAndConditionAndAction("number", "CenterX",
_("Center X position"),
_("the X position of the center"),
_("the X position of the center"),
_("Position/Center"),
"res/actions/position24.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddExpressionAndConditionAndAction("number", "CenterY",
_("Center Y position"),
_("the Y position of the center"),
_("the Y position of the center"),
_("Position/Center"),
"res/actions/position24.png")
.AddParameter("object", _("Object"))
.UseStandardParameters("number");
obj.AddAction("MettreAutourPos",
_("Put an object around a position"),
_("Put around a position"),
_("Position the center of the given object around a position, "
"using the specified angle "
"and distance."),
@@ -202,7 +236,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"AddForceVersPos",
_("Add a force to move toward a position"),
_("Add a force to an object to make it move toward a position."),
_("Move _PARAM0_ to _PARAM1_;_PARAM2_ with _PARAM4_ force of _PARAM3_ "
_("Move _PARAM0_ toward _PARAM1_;_PARAM2_ with _PARAM4_ force of _PARAM3_ "
"pixels"),
_("Movement"),
"res/actions/force24.png",
@@ -248,7 +282,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddAction("Delete",
_("Delete an object"),
_("Delete the object"),
_("Delete the specified object."),
_("Delete _PARAM0_"),
_("Objects"),
@@ -284,8 +318,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddAction("ModVarObjet",
_("Modify a variable of an object"),
_("Modify the value of a variable of an object"),
_("Value of an object variable"),
_("Change the value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/actions/var24.png",
@@ -296,8 +330,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.UseStandardOperatorParameters("number");
obj.AddAction("ModVarObjetTxt",
_("Modify the text of a variable of an object"),
_("Modify the text of a variable of an object"),
_("Text of an object variable"),
_("Change the text of an object variable."),
_("the text of variable _PARAM1_"),
_("Variables"),
"res/actions/var24.png",
@@ -307,14 +341,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardOperatorParameters("string");
obj.AddCondition(
"ObjectVariableChildExists",
_("Child existence"),
_("Return true if the specified child of the variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
obj.AddAction("SetObjectVariableAsBoolean",
_("Boolean value of an object variable"),
_("Change the boolean value of an object variable."),
_("Set the boolean value of the variable _PARAM1_ of object "
"_PARAM0_ to _PARAM2_"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"));
obj.AddAction(
"ToggleObjectVariableAsBoolean",
_("Toggle the boolean value of an object variable"),
_("Toggles the boolean value of an object variable.") + "\n" +
_("If it was true, it will become false, and if it was false "
"it will become true."),
_("Toggle the boolean value of the variable _PARAM1_ of object "
"_PARAM0_"),
_("Variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"));
obj.AddCondition("ObjectVariableChildExists",
_("Child existence"),
_("Check if the specified child of the variable exists."),
_("Child _PARAM2_ of variable _PARAM1_ of _PARAM0_ exists"),
_("Variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("string", _("Name of the child"))
@@ -322,9 +383,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("ObjectVariableRemoveChild",
_("Remove a child"),
_("Remove a child from a variable of an object."),
_("Remove a child from an object variable."),
_("Remove child _PARAM2_ from variable _PARAM1_ of _PARAM0_"),
_("Variables/Structure"),
_("Variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -336,7 +397,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Clear variable"),
_("Remove all the children from the object variable."),
_("Clear children from variable _PARAM1_ of _PARAM0_"),
_("Variables/Structure"),
_("Variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -356,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction("Montre",
_("Show"),
_("Show the specified object"),
_("Show the specified object."),
_("Show _PARAM0_"),
_("Visibility"),
"res/actions/visibilite24.png",
@@ -379,10 +440,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("Plan",
_("Compare Z order"),
_("Z-order"),
_("Compare the Z-order of the specified object."),
_("the z Order"),
_("Z order"),
_("the Z-order"),
_("Z-order"),
"res/conditions/planicon24.png",
"res/conditions/planicon.png")
@@ -391,7 +452,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("Layer",
_("Compare layer"),
_("Current layer"),
_("Check if the object is on the specified layer."),
_("_PARAM0_ is on layer _PARAM1_"),
_("Layer"),
@@ -403,7 +464,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("Visible",
_("Visibility of an object"),
_("Visibility"),
_("Check if an object is visible."),
_("_PARAM0_ is visible (not marked as hidden)"),
_("Visibility"),
@@ -462,8 +523,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("VarObjet",
_("Value of an object's variable"),
_("Compare the value of a variable of an object."),
_("Value of an object variable"),
_("Compare the value of an object variable."),
_("the variable _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
@@ -474,8 +535,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.UseStandardRelationalOperatorParameters("number");
obj.AddCondition("VarObjetTxt",
_("Text of an object's variable"),
_("Compare the text of a variable of an object."),
_("Text of an object variable"),
_("Compare the text of an object variable."),
_("the text of variable _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
@@ -485,6 +546,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectvar", _("Variable"))
.UseStandardRelationalOperatorParameters("string");
obj.AddCondition("ObjectVariableAsBoolean",
_("Boolean value of an object variable"),
_("Compare the boolean value of an object variable."),
_("The boolean value of variable _PARAM1_ of object "
"_PARAM0_ is _PARAM2_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true");
obj.AddCondition("VarObjetDef",
_("Variable defined"),
_("Check if the variable is defined."),
@@ -497,14 +571,83 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("string", _("Variable"))
.SetHidden();
obj.AddCondition(
"BehaviorActivated",
_("Behavior activated"),
_("Return true if the behavior is activated for the object."),
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
_("Behaviors"),
"res/behavior24.png",
"res/behavior16.png")
obj.AddAction(
"ObjectVariablePush",
_("Append variable to an object array"),
_("Appends a variable to the end of an object array variable."),
_("Append variable _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to append"))
.SetParameterLongDescription(
_("The content of the variable will *be copied* and appended at the "
"end of the array."))
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariablePushString",
_("Append a string to an object array"),
_("Appends a string to the end of an object array variable."),
_("Append string _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariablePushNumber",
_("Append a number to an object array"),
_("Appends a number to the end of an object array variable."),
_("Append number _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariablePushBool",
_("Append a boolean to an object array"),
_("Appends a boolean to the end of an object array variable."),
_("Append boolean _PARAM2_ to array variable _PARAM1_ of _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
obj.AddAction(
"ObjectVariableRemoveAt",
_("Remove variable from an object array (by index)"),
_("Removes a variable at the specified index of an object array "
"variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"object _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
obj.AddCondition("BehaviorActivated",
_("Behavior activated"),
_("Check if the behavior is activated for the object."),
_("Behavior _PARAM1_ of _PARAM0_ is activated"),
_("Behaviors"),
"res/behavior24.png",
"res/behavior16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"))
@@ -527,7 +670,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"AddForceVers",
_("Add a force to move toward an object"),
_("Add a force to an object to make it move toward another."),
_("Move _PARAM0_ to _PARAM1_ with _PARAM3_ force of _PARAM2_ pixels"),
_("Move _PARAM0_ toward _PARAM1_ with _PARAM3_ force of _PARAM2_ pixels"),
_("Movement"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
@@ -559,7 +702,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddAction("MettreAutour",
_("Put an object around another"),
_("Put the object around another"),
_("Position an object around another, with the specified angle "
"and distance. The center of the objects are used for "
"positioning them."),
@@ -602,7 +745,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("objectList", _("Object 2 (won't move)"));
obj.AddAction("SeparateFromObjects",
_("Separate two objects"),
_("Separate objects"),
_("Move an object away from another using their collision "
"masks.\nBe sure to call this action on a reasonable number "
"of objects\nto avoid slowing down the game."),
@@ -805,15 +948,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetHidden();
obj.AddExpression("ZOrder",
_("Z order"),
_("Z order of an object"),
_("Z-order"),
_("Z-order of an object"),
_("Visibility"),
"res/actions/planicon.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Plan",
_("Z order"),
_("Z order of an object"),
_("Z-order"),
_("Z-order of an object"),
_("Visibility"),
"res/actions/planicon.png")
.AddParameter("object", _("Object"))
@@ -835,25 +978,43 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Object"));
obj.AddExpression("DistanceToPosition",
_("Distance between an object and a position"),
_("Distance between an object and a position"),
_("Position"),
"res/conditions/distance.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Target X position"))
.AddParameter("expression", _("Target Y position"));
obj.AddExpression("SqDistanceToPosition",
_("Square distance between an object and a position"),
_("Square distance between an object and a position"),
_("Position"),
"res/conditions/distance.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Target X position"))
.AddParameter("expression", _("Target Y position"));
obj.AddExpression("Variable",
_("Object's variable"),
_("Object's variable"),
_("Object variable"),
_("Value of an object variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"));
obj.AddExpression("VariableChildCount",
_("Object's variable number of children"),
_("Get the number of children from an object"),
_("Number of children of an object variable"),
_("Number of children of an object variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
.AddParameter("objectvar", _("Variable"));
obj.AddStrExpression("VariableString",
_("Object's variable"),
_("Text of variable of an object"),
_("Object variable"),
_("Text of an object variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("object", _("Object"))
@@ -867,6 +1028,50 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"))
.AddParameter("string", _("Timer's name"));
obj.AddExpression("AngleToObject",
_("Angle between two objects"),
_("Compute the angle between two objects. If you need the "
"angle to an arbitrary position, use AngleToPosition."),
_("Angle"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Object"));
obj.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
obj.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
obj.AddExpression("AngleToPosition",
_("Angle between an object and a position"),
_("Compute the angle between the object center and a "
"\"target\" position. If you need the angle between two "
"objects, use AngleToObject."),
_("Angle"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Target X position"))
.AddParameter("expression", _("Target Y position"));
extension
.AddAction("Create",
_("Create an object"),
@@ -1085,18 +1290,20 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
extension
.AddCondition("Raycast",
_("Raycast"),
_("Sends a ray from the given source position and angle, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
"result in _PARAM5_, _PARAM6_"),
_("Collision"),
"res/conditions/raycast24.png",
"res/conditions/raycast.png")
.AddCondition(
"Raycast",
_("Raycast"),
_("Sends a ray from the given source position and angle, "
"intersecting the closest object.\nThe instersected "
"object will become the only one taken into account.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Cast a ray from _PARAM1_;_PARAM2_, angle: _PARAM3_ and max "
"distance: _PARAM4_px, against _PARAM0_, and save the "
"result in _PARAM5_, _PARAM6_"),
_("Collision"),
"res/conditions/raycast24.png",
"res/conditions/raycast.png")
.AddParameter("objectList", _("Objects to test against the ray"))
.AddParameter("expression", _("Ray source X position"))
.AddParameter("expression", _("Ray source Y position"))
@@ -1122,7 +1329,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"object will become the only one taken into account.\nIf "
"the condition is inverted, the object to be intersected "
"will be the farthest one within the ray radius."),
_("Raycast _PARAM0_ from _PARAM1_;_PARAM2_, and save the "
_("Cast a ray from from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ "
"against _PARAM0_, and save the "
"result in _PARAM5_, _PARAM6_"),
_("Collision"),
"res/conditions/raycast24.png",

View File

@@ -4,6 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
@@ -12,141 +13,115 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("BuiltinCamera",
_("Cameras and layers features"),
_("Built-in camera extension"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"BuiltinCamera",
_("Cameras and layers features"),
"Each scene can be composed of multiple layers. These conditions "
"and actions allow to manipulate them during the game. In "
"particular, you can move the camera of a layer to center it on an "
"object or a position.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/interface/scene-editor/layers-and-cameras");
#if defined(GD_IDE_ONLY)
extension
.AddCondition("CameraX",
_("Camera center X position"),
_("Compare the X position of the center of a camera."),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddCondition("CameraY",
_("Camera center Y position"),
_("Compare the Y position of the center of a camera."),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"))
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction(
.AddExpressionAndConditionAndAction(
"number",
"CameraX",
_("Camera center X position"),
_("Change the X position of the center of the specified camera."),
_("the X position of the center of a camera"),
_("the X position of camera _PARAM4_ (layer: _PARAM3_)"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension.AddDuplicatedAction("CameraX", "SetCameraX")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueX", "CameraX")
.SetHidden(); // Deprecated
extension
.AddAction(
.AddExpressionAndConditionAndAction(
"number",
"CameraY",
_("Camera center Y position"),
_("Change the Y position of the center of the specified camera."),
_("the Y position of the center of a camera"),
_("the Y position of camera _PARAM4_ (layer: _PARAM3_)"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddCondition("CameraWidth",
_("Width of a camera"),
_("Test the width of a camera of a layer"),
_("the width of camera _PARAM2_ of layer _PARAM1_"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension.AddDuplicatedAction("CameraY", "SetCameraY")
.SetHidden(); // Deprecated
extension.AddDuplicatedExpression("VueY", "CameraY")
.SetHidden(); // Deprecated
extension
.AddCondition("CameraHeight",
_("Height of a camera"),
_("Test the height of a camera of a layer"),
_("the height of camera _PARAM2_ of layer _PARAM1_"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddExpressionAndCondition(
"number",
"CameraWidth",
_("Width of a camera"),
_("the width of a camera of a layer"),
_("the width of camera _PARAM2_ of layer _PARAM1_"),
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.UseStandardRelationalOperatorParameters("number")
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddCondition("CameraAngle",
_("Angle of a camera of a layer"),
_("Test a camera angle."),
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/conditions/camera24.png",
"res/conditions/camera.png")
.AddExpressionAndCondition(
"number",
"CameraHeight",
_("Height of a camera"),
_("the height of a camera of a layer"),
_("the height of camera _PARAM2_ of layer _PARAM1_"),
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"))
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number"))
.UseStandardParameters("number")
.MarkAsAdvanced();
extension
.AddExpressionAndConditionAndAction(
"number",
"CameraAngle",
_("Angle of a camera of a layer"),
_("the angle of rotation of a camera"),
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/conditions/camera24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0")
.MarkAsAdvanced();
extension
.AddAction("RotateCamera",
_("Change camera angle"),
_("This action modifies the angle of a camera in the "
"specified layer."),
_("the angle of camera (layer: _PARAM3_, camera: _PARAM4_)"),
_("Layers and cameras"),
"res/actions/camera24.png",
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardOperatorParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension.AddDuplicatedAction("RotateCamera", "SetCameraAngle").SetHidden();
extension.AddDuplicatedExpression("CameraRotation", "CameraAngle")
.SetHidden();
extension.AddDuplicatedExpression("VueRotation", "CameraAngle").SetHidden();
extension
.AddAction("AddCamera",
@@ -245,9 +220,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
extension
.AddAction("ZoomCamera",
_("Change camera zoom"),
_("Change camera zoom."),
_("Change camera zoom."),
_("Change camera zoom to _PARAM1_ (layer : _PARAM2_, camera : "
_("Change camera zoom to _PARAM1_ (layer: _PARAM2_, camera: "
"_PARAM3_)"),
_("Layers and cameras"),
"res/actions/camera24.png",
@@ -470,26 +445,50 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
_("Scale (1: Default, 2: 2x faster, 0.5: 2x slower...)"));
extension
.AddExpression("CameraWidth",
_("Width of a camera of a layer"),
_("Width of a camera of a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddCondition("LayerDefaultZOrder",
_("Layer default Z order"),
_("Compare the default Z order set to objects when they "
"are created on a layer."),
_("the default Z order of objects created on _PARAM1_"),
_("Layers and cameras"),
"res/conditions/layer24.png",
"res/conditions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("expression", _("Camera number (default : 0)"))
.SetDefaultValue("0");
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddExpression("CameraHeight",
_("Height of a camera of a layer"),
_("Height of a camera of a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddAction("SetLayerDefaultZOrder",
_("Change layer default Z order"),
_("Change the default Z order set to objects when they are "
"created on a layer."),
_("Set the default Z order of objects created on _PARAM1_ to "
"_PARAM2_"),
_("Layers and cameras"),
"res/actions/layer24.png",
"res/actions/layer.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"))
.AddParameter("expression", _("Camera number (default : 0)"))
.SetDefaultValue("0");
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("New default Z order"));
extension
.AddAction(
"SetLayerAmbientLightColor",
_("Set the ambient light color"),
_("Set the ambient light color of the lighting layer in format "
"\"R;G;B\" string."),
_("Set the ambient color of the lighting layer _PARAM1_ to _PARAM2_"),
_("Layers and cameras/Lighting"),
"res/actions/color24.png",
"res/actions/color.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"Lighting\"")
.AddParameter("color", _("Color"))
.MarkAsAdvanced();
extension
.AddExpression(
@@ -540,9 +539,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.SetDefaultValue("0");
extension
.AddExpression("CameraX",
_("Camera X position"),
_("Camera X position"),
.AddExpression("CameraZoom",
_("Zoom of a camera of a layer"),
_("Zoom of a camera of a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -551,69 +550,6 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("VueX",
_("Camera X position"),
_("Camera X position"),
_("Layers and cameras"),
"res/actions/camera.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("CameraY",
_("Camera Y position"),
_("Camera Y position"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("VueY",
_("Camera Y position"),
_("Camera Y position"),
_("Layers and cameras"),
"res/actions/camera.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("CameraRotation",
_("Angle of a camera of a layer"),
_("Angle of a camera of a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("VueRotation",
_("Angle of a camera of a layer"),
_("Angle of a camera of a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.SetHidden()
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("LayerTimeScale",
_("Time scale"),
@@ -622,6 +558,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsCameraExtension(
"res/actions/time.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));
extension
.AddExpression("LayerDefaultZOrder",
_("Default Z Order for a layer"),
_("Default Z Order for a layer"),
_("Layers and cameras"),
"res/actions/camera.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"));
#endif
}

View File

@@ -16,7 +16,7 @@ BuiltinExtensionsImplementer::ImplementsCommonConversionsExtension(
.SetExtensionInformation(
"BuiltinCommonConversions",
_("Standard Conversions"),
_("Built-in extension providing standard conversions expressions."),
"Expressions to convert number, texts and quantities.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/common-conversions");

View File

@@ -7,6 +7,7 @@
#include "GDCore/Tools/Localization.h"
#if defined(GD_IDE_ONLY)
#include "GDCore/Events/Builtin/CommentEvent.h"
#include "GDCore/Events/Builtin/ForEachChildVariableEvent.h"
#include "GDCore/Events/Builtin/ForEachEvent.h"
#include "GDCore/Events/Builtin/GroupEvent.h"
#include "GDCore/Events/Builtin/LinkEvent.h"
@@ -25,8 +26,9 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
extension
.SetExtensionInformation(
"BuiltinCommonInstructions",
_("Standard events"),
_("Built-in extension providing standard events."),
_("Builtin events"),
"GDevelop comes with a set of events and conditions that allow to "
"express the game logic and rules.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/advanced-conditions");
@@ -35,7 +37,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
extension
.AddCondition("Or",
_("Or"),
_("Return true if one of the sub conditions is true"),
_("Check if one of the sub conditions is true"),
_("If one of these conditions is true:"),
_("Advanced"),
"res/conditions/or24.png",
@@ -46,7 +48,7 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
extension
.AddCondition("And",
_("And"),
_("Return true if all sub conditions are true"),
_("Check if all sub conditions are true"),
_("If all of these conditions are true:"),
_("Advanced"),
"res/conditions/and24.png",
@@ -118,6 +120,14 @@ BuiltinExtensionsImplementer::ImplementsCommonInstructionsExtension(
"res/foreach.png",
std::make_shared<gd::ForEachEvent>());
extension.AddEvent(
"ForEachChildVariable",
_("For each child variable (of a structure or array)"),
_("Repeat the event for each child variable of a structure or array."),
"",
"res/foreach.png",
std::make_shared<gd::ForEachChildVariableEvent>());
extension.AddEvent("Group",
_("Group"),
_("Group containing events"),

View File

@@ -13,13 +13,12 @@ void GD_CORE_API
BuiltinExtensionsImplementer::ImplementsExternalLayoutsExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation(
"BuiltinExternalLayouts",
_("External layouts"),
_("Built-in extension providing actions and conditions related to "
"external layouts"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation("BuiltinExternalLayouts",
_("External layouts"),
"Provides actions and conditions related to "
"external layouts.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/interface/scene-editor/external-layouts");
#if defined(GD_IDE_ONLY)

View File

@@ -12,12 +12,14 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("BuiltinFile",
_("Storage"),
_("Built-in extension providing functions "
"to store data."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"BuiltinFile",
_("Storage"),
"Actions and conditions to store data (like the player progress or "
"anything else to be persisted across game sessions). Data are "
"stored on the device and erased when the game is uninstalled.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/storage");
#if defined(GD_IDE_ONLY)
@@ -98,7 +100,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddAction(
"LireFichierExp",
_("Read a value"),
_("Read the value saved in the specified element and store it in a scene"
_("Read the value saved in the specified element and store it in a "
"scene "
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),
@@ -115,7 +118,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsFileExtension(
.AddAction(
"LireFichierTxt",
_("Read a text"),
_("Read the text saved in the specified element and store it in a scene "
_("Read the text saved in the specified element and store it in a "
"scene "
"variable.\nSpecify the structure leading to the element using / "
"(example : Root/Level/Current)\nSpaces are forbidden in element "
"names."),

View File

@@ -15,7 +15,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsJoystickExtension(
.SetExtensionInformation(
"BuiltinJoystick",
_("Joysticks features"),
_("Built-in extension that enables the use of joysticks"),
"Built-in extension that enables the use of joysticks.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);

View File

@@ -15,7 +15,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
.SetExtensionInformation(
"BuiltinKeyboard",
_("Keyboard features"),
_("Built-in extension that enables the use of a keyboard"),
_("Allows your game to respond to keyboard input. Note that this "
"does not work with on-screen keyboard on touch devices: use "
"instead conditions related to touch when making a game for "
"mobile/touchscreen devices."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/keyboard");
@@ -79,6 +82,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsKeyboardExtension(
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddCondition("AnyKeyReleased",
_("Any key released"),
_("Test if any key is released"),
_("Any key is released"),
_("Keyboard"),
"res/conditions/keyboard24.png",
"res/conditions/keyboard.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddStrExpression(
"LastPressedKey",

View File

@@ -15,12 +15,22 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
extension.SetExtensionInformation(
"BuiltinMathematicalTools",
_("Mathematical tools"),
_("Built-in extension providing mathematical tools"),
"A set of mathematical functions that can be used in expressions.",
"Florian Rival",
"Open source (MIT License)");
#if defined(GD_IDE_ONLY)
extension
.AddExpression("normalize",
_("Normalize a value between `min` and `max` to a value between 0 and 1."),
_("Remap a value between 0 and 1."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Value"))
.AddParameter("expression", _("Min"))
.AddParameter("expression", _("Max"));
extension
.AddExpression("clamp",
_("Clamp (restrict a value to a given range)"),
@@ -40,6 +50,28 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("First angle"))
.AddParameter("expression", _("Second angle"));
extension
.AddExpression("AngleBetweenPositions",
_("Angle between two positions"),
_("Compute the angle between two positions."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
.AddParameter("expression", _("Second point X position"))
.AddParameter("expression", _("Second point Y position"));
extension
.AddExpression("DistanceBetweenPositions",
_("Distance between two positions"),
_("Compute the distance between two positions."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("First point X position"))
.AddParameter("expression", _("First point Y position"))
.AddParameter("expression", _("Second point X position"))
.AddParameter("expression", _("Second point Y position"));
extension
.AddExpression("mod",
_("Modulo"),
@@ -347,6 +379,30 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("b (in a+(b-a)*x)"))
.AddParameter("expression", _("x (in a+(b-a)*x)"));
extension
.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
extension
.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));
#endif
}

View File

@@ -4,6 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "AllBuiltinExtensions.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Tools/Localization.h"
using namespace std;
@@ -14,8 +15,12 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
extension
.SetExtensionInformation(
"BuiltinMouse",
_("Mouse features"),
_("Built-in extension that enables the use of a mouse"),
_("Mouse and touch"),
"Conditions and actions to handle either the mouse or touches on "
"touchscreen. By default, conditions related to the mouse will also "
"handle the touches - so that it's easier to handle both in your "
"game. You can disable this behavior if you want to handle them "
"separately in different events.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/mouse-touch");
@@ -144,88 +149,101 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.MarkAsAdvanced();
extension
.AddCondition("SourisX",
_("Cursor X position"),
_("Compare the X position of the cursor or of a touch."),
_("the cursor X position"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddExpressionAndCondition(
"number",
"MouseX",
_("Cursor X position"),
_("the X position of the cursor or of a touch"),
_("the cursor (or touch) X position"),
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisX", "MouseX").SetHidden();
extension.AddDuplicatedExpression("SourisX", "MouseX").SetHidden();
extension
.AddCondition("SourisY",
_("Cursor Y position"),
_("Compare the Y position of the cursor or of a touch."),
_("the cursor Y position"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddExpressionAndCondition(
"number",
"MouseY",
_("Cursor Y position"),
_("the Y position of the cursor or of a touch"),
_("the cursor (or touch) Y position"),
_("Mouse and touch"),
"res/conditions/mouse24.png")
.AddCodeOnlyParameter("currentScene", "")
.UseStandardRelationalOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisY", "MouseY").SetHidden();
extension.AddDuplicatedExpression("SourisY", "MouseY").SetHidden();
extension
.AddCondition("SourisBouton",
.AddCondition("MouseButtonPressed",
_("Mouse button pressed or touch held"),
_("Return true if the specified mouse button is pressed or "
_("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"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to test"))
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
// Support for deprecated names:
extension.AddDuplicatedCondition("SourisBouton", "MouseButtonPressed")
.SetHidden();
extension
.AddCondition(
"MouseButtonReleased",
_("Mouse button released"),
_("Return true if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCondition("MouseButtonReleased",
_("Mouse button released"),
_("Check if the specified mouse button was released."),
_("_PARAM1_ mouse button was released"),
_("Mouse and touch"),
"res/conditions/mouse24.png",
"res/conditions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("mouse", _("Button to test"))
.AddParameter("mouse", _("Button to check"))
.MarkAsSimple();
extension
.AddCondition("TouchX",
_("Touch X position"),
_("Compare the X position of a specific touch."),
_("the touch #_PARAM1_ X position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddExpressionAndCondition("number",
"TouchX",
_("Touch X position"),
_("the X position of a specific touch"),
_("the touch #_PARAM1_ X position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardRelationalOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
.SetDefaultValue("0");
extension
.AddCondition("TouchY",
_("Touch Y position"),
_("Compare the Y position of a specific touch."),
_("the touch #_PARAM1_ Y position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png",
"res/conditions/touch.png")
.AddExpressionAndCondition("number",
"TouchY",
_("Touch Y position"),
_("the Y position of a specific touch"),
_("the touch #_PARAM1_ Y position"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch24.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.UseStandardRelationalOperatorParameters("number")
.UseStandardParameters("number")
.AddParameter("layer", _("Layer (base layer if empty)"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("expression", _("Camera number (default : 0)"), "", true)
@@ -235,7 +253,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition(
"PopStartedTouch",
_("A new touch has started"),
_("Return true if a touch has started. The touch identifier can be "
_("Check if a touch has started. The touch identifier can be "
"accessed using LastTouchId().\nAs more than one touch can be "
"started, this condition is only true once for each touch: the "
"next time you use it, it will be for a new touch, or it will "
@@ -250,7 +268,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddCondition(
"PopEndedTouch",
_("A touch has ended"),
_("Return true if a touch has ended. The touch identifier can be "
_("Check if a touch has ended. The touch identifier can be "
"accessed using LastEndedTouchId().\nAs more than one touch can be "
"ended, this condition is only true once for each touch: the next "
"time you use it, it will be for a new touch, or it will return "
@@ -261,95 +279,19 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("MouseX",
_("Cursor X position"),
_("Cursor X position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("SourisX",
_("Cursor X position"),
_("Cursor X position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0")
.SetHidden();
extension
.AddExpression("MouseY",
_("Cursor Y position"),
_("Cursor Y position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("SourisY",
_("Cursor Y position"),
_("Cursor Y position"),
_("Mouse cursor"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0")
.SetHidden();
extension
.AddExpression("MouseWheelDelta",
_("Mouse wheel: Displacement"),
_("Mouse wheel displacement"),
_("Mouse cursor"),
_("Mouse and touch"),
"res/actions/mouse.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddExpression("TouchX",
_("Touch X position"),
_("Touch X position"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("TouchY",
_("Touch Y position"),
_("Touch Y position"),
_("Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("expression", _("Touch identifier"))
.AddParameter("layer", _("Layer"), "", true)
.SetDefaultValue("\"\"")
.AddParameter("camera", _("Camera"), "", true)
.SetDefaultValue("0");
extension
.AddExpression("LastTouchId",
_("Identifier of the last touch"),
_("Identifier of the last touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");
@@ -357,7 +299,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsMouseExtension(
.AddExpression("LastEndedTouchId",
_("Identifier of the last ended touch"),
_("Identifier of the last ended touch"),
_("Multitouch"),
_("Mouse and touch/Multitouch"),
"res/conditions/touch.png")
.AddCodeOnlyParameter("currentScene", "");

View File

@@ -15,7 +15,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
.SetExtensionInformation(
"BuiltinNetwork",
_("Basic internet features"),
_("Built-in extension providing network features."),
_("Features to send web requests, communicate with external \"APIs\" and other network related tasks."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/network");
@@ -34,10 +34,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("Host, with protocol"))
.SetParameterLongDescription(
_("Example: \"http://example.com/\"."))
.SetParameterLongDescription(_("Example: \"http://example.com/\"."))
.AddParameter("string", _("Path"))
.SetParameterLongDescription(_("Example: \"/user/123\" or \"/some-page.php\"."))
.SetParameterLongDescription(
_("Example: \"/user/123\" or \"/some-page.php\"."))
.AddParameter("string", _("Request body content"))
.AddParameter("string", _("Method: \"POST\" or \"GET\""), "", true)
.SetParameterLongDescription(_("If empty, \"GET\" will be used."))
@@ -51,6 +51,52 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"variable. If the server returns *JSON*, you may want to use the "
"action \"Convert JSON to a scene variable\" afterwards, to "
"explore the results with a *structure variable*."))
.MarkAsComplex()
.SetHidden();
extension
.AddAction(
"SendAsyncRequest",
_("Send a request to a web page"),
_("Send an asynchronous request to the specified web page.\n\nPlease "
"note that for "
"the web games, the game must be hosted on the same host "
"as specified below, except if the server is configured to answer "
"to all requests (cross-domain requests)."),
_("Send a _PARAM2_ request to _PARAM0_ with body: _PARAM1_, and "
"store the result in _PARAM4_ (or in _PARAM5_ in case of error)"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("URL (API or web-page address)"))
.SetParameterLongDescription(
_("Example: \"https://example.com/user/123\". Using *https* is "
"highly recommended."))
.AddParameter("string", _("Request body content"))
.AddParameter("stringWithSelector",
_("Resize mode"),
"[\"GET\", \"POST\", \"PUT\", \"HEAD\", \"DELETE\", "
"\"PATCH\", \"OPTIONS\"]",
false)
.SetParameterLongDescription(_("If empty, \"GET\" will be used."))
.SetDefaultValue("\"GET\"")
.AddParameter("string", _("Content type"), "", true)
.SetParameterLongDescription(
_("If empty, \"application/x-www-form-urlencoded\" will be used."))
.AddParameter(
"scenevar", _("Variable where to store the response"), "", true)
.SetParameterLongDescription(
_("The response of the server will be stored, as a string, in this "
"variable. If the server returns *JSON*, you may want to use the "
"action \"Convert JSON to a scene variable\" afterwards, to "
"explore the results with a *structure variable*."))
.AddParameter(
"scenevar", _("Variable where to store the error message"), "", true)
.SetParameterLongDescription(
_("Optional, only used if an error occurs. This will contain the "
"error message (if request could not be sent) or the [\"status "
"code\"](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes), "
"if the server returns a status >= 400."))
.MarkAsComplex();
extension
@@ -67,6 +113,22 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
_("Path to file (for example : /folder/file.txt)"))
.AddParameter("string", _("Save as"));
extension
.AddAction(
"EnableMetrics",
_("Enable (or disable) metrics collection"),
_("Enable, or disable, the sending of anonymous data used to compute "
"the number of sessions and other metrics from your game "
"players.\nBe sure to only send metrics if in accordance with the "
"terms of service of your game and if they player gave their "
"consent, depending on how your game/company handles this."),
_("Enable analytics metrics: _PARAM1_"),
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddCodeOnlyParameter("currentScene", "")
.AddParameter("yesorno", _("Enable the metrics?"));
extension
.AddAction(
"JSONToVariableStructure",

View File

@@ -15,7 +15,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSceneExtension(
.SetExtensionInformation(
"BuiltinScene",
_("Scene management features"),
_("Built-in extension allowing to manipulate scenes and providing common features"),
_("Actions and conditions to manipulate the scenes during the game."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);

View File

@@ -21,7 +21,7 @@ Direction::~Direction(){};
void Direction::SetLoop(bool loop_) { loop = loop_; }
void Direction::SetTimeBetweenFrames(float time) { timeBetweenFrame = time; }
void Direction::SetTimeBetweenFrames(double time) { timeBetweenFrame = time; }
void Direction::AddSprite(const Sprite& sprite) { sprites.push_back(sprite); }

View File

@@ -43,14 +43,14 @@ class GD_CORE_API Direction {
/**
* \brief Get the time between each sprite
*/
inline float GetTimeBetweenFrames() const { return timeBetweenFrame; }
inline double GetTimeBetweenFrames() const { return timeBetweenFrame; }
/**
* \brief Set the time between each sprite
*
* \param time Time between each sprite, in seconds.
*/
void SetTimeBetweenFrames(float time);
void SetTimeBetweenFrames(double time);
/**
* \brief Return a reference to a sprite of the direction.
@@ -133,7 +133,7 @@ class GD_CORE_API Direction {
private:
bool loop; ///< true if the animation must loop.
float timeBetweenFrame; ///< The time between each sprite of the animation.
double timeBetweenFrame; ///< The time between each sprite of the animation.
std::vector<Sprite> sprites; ///< The sprites of the direction.
#if defined(GD_IDE_ONLY)
gd::String metadata;

View File

@@ -367,15 +367,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddAction(
"ChangeColor",
_("Global color"),
_("Change the global color of an object. The default color is white."),
_("Change color of _PARAM0_ to _PARAM1_"),
_("Tint color"),
_("Change the tint of an object. The default color is white."),
_("Change tint of _PARAM0_ to _PARAM1_"),
_("Effects"),
"res/actions/color24.png",
"res/actions/color.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Color"));
.AddParameter("color", _("Tint"));
obj.AddAction("ChangeBlendMode",
_("Blend mode"),
@@ -417,7 +417,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddCondition("FlippedX",
_("Horizontally flipped"),
_("Return true if the object is horizontally flipped"),
_("Check if the object is horizontally flipped"),
_("_PARAM0_ is horizontally flipped"),
_("Effects"),
"res/actions/flipX24.png",
@@ -427,7 +427,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddCondition("FlippedY",
_("Vertically flipped"),
_("Return true if the object is vertically flipped"),
_("Check if the object is vertically flipped"),
_("_PARAM0_ is vertically flipped"),
_("Effects"),
"res/actions/flipY24.png",

View File

@@ -107,8 +107,7 @@ void SpriteObject::DoSerializeTo(gd::SerializerElement& element) const {
}
}
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties(
gd::Project& project) const {
std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties() const {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Animate even if hidden or far from the screen")]
.SetValue(updateIfNotVisible ? "true" : "false")
@@ -119,8 +118,7 @@ std::map<gd::String, gd::PropertyDescriptor> SpriteObject::GetProperties(
}
bool SpriteObject::UpdateProperty(const gd::String& name,
const gd::String& value,
gd::Project& project) {
const gd::String& value) {
if (name == _("Animate even if hidden or far from the screen"))
updateIfNotVisible = value == "1";
@@ -145,10 +143,7 @@ SpriteObject::GetInitialInstanceProperties(const gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) {
std::map<gd::String, gd::PropertyDescriptor> properties;
properties[_("Animation")] =
position.floatInfos.find("animation") != position.floatInfos.end()
? gd::String::From(position.floatInfos.find("animation")->second)
: gd::String("0");
properties[_("Animation")] = gd::String::From(position.GetRawDoubleProperty("animation"));
return properties;
}
@@ -159,7 +154,7 @@ bool SpriteObject::UpdateInitialInstanceProperty(gd::InitialInstance& position,
gd::Project& project,
gd::Layout& scene) {
if (name == _("Animation"))
position.floatInfos["animation"] = value.To<int>();
position.SetRawDoubleProperty("animation", value.To<int>());
return true;
}

View File

@@ -48,11 +48,9 @@ class GD_CORE_API SpriteObject : public gd::Object {
#if defined(GD_IDE_ONLY)
void ExposeResources(gd::ArbitraryResourceWorker& worker) override;
std::map<gd::String, gd::PropertyDescriptor> GetProperties(
gd::Project& project) const override;
std::map<gd::String, gd::PropertyDescriptor> GetProperties() const override;
bool UpdateProperty(const gd::String& name,
const gd::String& value,
gd::Project& project) override;
const gd::String& value) override;
std::map<gd::String, gd::PropertyDescriptor> GetInitialInstanceProperties(
const gd::InitialInstance& position,

View File

@@ -16,8 +16,7 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
.SetExtensionInformation(
"BuiltinStringInstructions",
_("Text manipulation"),
_("Built-in extension providing expressions for manipulating text "
"objects."),
"Provides expressions to manipulate strings (also called texts).",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("" /*TODO: Add a documentation page for this */);
@@ -119,6 +118,20 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
.SetHidden(); // Deprecated, see StrFindLast instead.
extension
.AddExpression(
"StrFindLast",
_("Search the last occurence in a text"),
_("Search the last occurence in a string (return the position of "
"the result, from the beginning of the string, or -1 if not "
"found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"));
@@ -145,6 +158,24 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
.AddParameter("expression",
_("Position of the last character in the string to be "
"considered in the search"))
.SetHidden(); // Deprecated, see StrFindLastFrom instead.
extension
.AddExpression(
"StrFindLastFrom",
_("Search the last occurence in a text, starting from a position"),
_("Search in a text the last occurence, starting from a position "
"(return "
" the position of the result, from the beginning of the string, or "
"-1 if not found)"),
_("Manipulation of text"),
"res/conditions/toujours24.png")
.AddParameter("string", _("Text"))
.AddParameter("string", _("Text to search for"))
.AddParameter("expression",

View File

@@ -12,12 +12,14 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTimeExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("BuiltinTime",
_("Time"),
_("Built-in extension providing actions and "
"conditions related to time."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"BuiltinTime",
_("Time"),
"Actions and conditions to run timers, get the current time or "
"modify the time scale (speed at which the game is running - useful "
"for slow motion effects).",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/timers");
#if defined(GD_IDE_ONLY)

View File

@@ -15,7 +15,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.SetExtensionInformation(
"BuiltinVariables",
_("Variable features"),
_("Built-in extension allowing to manipulate variables"),
"Actions, conditions and expressions to handle variables, from "
"simple variables like the player score, the number of remaining "
"lives to complex variables containing arbitrary data like an "
"inventory or the result of a web request.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/variables");
@@ -43,13 +46,26 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddParameter("scenevar", _("Variable"))
.UseStandardRelationalOperatorParameters("string");
extension
.AddCondition(
"SceneVariableAsBoolean",
_("Boolean value of a scene variable"),
_("Compare the boolean value of a scene variable."),
_("The boolean value of scene variable _PARAM0_ is _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true");
extension
.AddCondition(
"VariableChildExists",
_("Child existence"),
_("Return true if the specified child of the scene variable exists."),
_("Check if the specified child of the scene variable exists."),
_("Child _PARAM1_ of scene variable _PARAM0_ exists"),
_("Variables/Structures"),
_("Variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -59,10 +75,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("GlobalVariableChildExists",
_("Child existence"),
_("Return true if the specified child of the global "
_("Check if the specified child of the global "
"variable exists."),
_("Child _PARAM1_ of global variable _PARAM0_ exists"),
_("Variables/Global variables/Structures"),
_("Variables/Global variables/Collections/Structures"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -93,18 +109,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.UseStandardRelationalOperatorParameters("number")
.MarkAsAdvanced();
extension
.AddCondition("VarGlobalTxt",
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddCondition(
"VarGlobalTxt",
_("Text of a global variable"),
_("Compare the text of a global variable."),
_("the text of the global variable _PARAM0_"),
"GlobalVariableAsBoolean",
_("Boolean value of a global variable"),
_("Compare the boolean value of a global variable."),
_("The boolean value of global variable _PARAM0_ is _PARAM1_"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardRelationalOperatorParameters("string")
.MarkAsAdvanced();
.AddParameter("trueorfalse", _("Check if the value is"))
.SetDefaultValue("true");
extension
.AddCondition("VarGlobalDef",
@@ -122,7 +150,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddAction("ModVarScene",
_("Value of a scene variable"),
_("Modify the value of a scene variable."),
_("Change the value of a scene variable."),
_("the scene variable _PARAM0_"),
_("Variables"),
"res/actions/var24.png",
@@ -141,10 +169,34 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.AddParameter("scenevar", _("Variable"))
.UseStandardOperatorParameters("string");
extension
.AddAction(
"SetSceneVariableAsBoolean",
_("Boolean value of a scene variable"),
_("Modify the boolean value of a scene variable."),
_("Set the boolean value of scene variable _PARAM0_ to _PARAM1_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"));
extension
.AddAction("ToggleSceneVariableAsBoolean",
_("Toggle boolean value of a scene variable"),
_("Toggle the boolean value of a scene variable.") + "\n" +
_("If it was true, it will become false, and if it was "
"false it will become true."),
_("Toggle the boolean value of scene variable _PARAM0_"),
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("scenevar", _("Variable"));
extension
.AddAction("ModVarGlobal",
_("Value of a global variable"),
_("Modify the value of a global variable"),
_("Change the value of a global variable"),
_("the global variable _PARAM0_"),
_("Variables/Global variables"),
"res/actions/var24.png",
@@ -154,24 +206,47 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
.MarkAsAdvanced();
extension
.AddAction(
"ModVarGlobalTxt",
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddAction("ModVarGlobalTxt",
_("String of a global variable"),
_("Modify the text of a global variable."),
_("the text of global variable _PARAM0_"),
_("Variables/Global variables"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.UseStandardOperatorParameters("string")
.MarkAsAdvanced();
extension
.AddAction(
"SetGlobalVariableAsBoolean",
_("Boolean value of a global variable"),
_("Modify the boolean value of a global variable."),
_("Set the boolean value of global variable _PARAM0_ to _PARAM1_"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("trueorfalse", _("New Value:"));
extension
.AddAction("ToggleGlobalVariableAsBoolean",
_("Toggle boolean value of a global variable"),
_("Toggle the boolean value of a global variable.") + "\n" +
_("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_"),
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
.AddParameter("globalvar", _("Variable"));
extension
.AddAction("VariableRemoveChild",
_("Remove a child"),
_("Remove a child from a scene variable."),
_("Remove child _PARAM1_ from scene variable _PARAM0_"),
_("Variables/Structure"),
_("Variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -183,7 +258,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Remove a child"),
_("Remove a child from a global variable."),
_("Remove child _PARAM1_ from global variable _PARAM0_"),
_("Variables/Global variables/Structure"),
_("Variables/Global variables/Collections/Structures"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
@@ -195,7 +270,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear scene variable"),
_("Remove all the children from the scene variable."),
_("Clear children from scene variable _PARAM0_"),
_("Variables/Structure"),
_("Variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
@@ -206,16 +281,140 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
_("Clear global variable"),
_("Remove all the children from the global variable."),
_("Clear children from global variable _PARAM0_"),
_("Variables/Global variables/Structure"),
_("Variables/Global variables/Collections"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePush",
_("Append variable to a scene array"),
_("Appends a variable at the end of a scene array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to append"))
.SetParameterLongDescription(_("The content of the variable will *be copied* and appended at the end of the array."))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushString",
_("Append a string to a scene array"),
_("Appends a string at the end of a scene array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushNumber",
_("Append a number to a scene array"),
_("Appends a number at the end of a scene array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("SceneVariablePushBool",
_("Append a boolean to a scene array"),
_("Appends a boolean at the end of a scene array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddAction(
"SceneVariableRemoveAt",
_("Remove variable from a scene array (by index)"),
_("Removes a variable at the specified index of a scene array variable."),
_("Remove variable at index _PARAM1_ from array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePush",
_("Append variable to a global array"),
_("Appends a variable at the end of a global array variable."),
_("Append variable _PARAM1_ to array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("scenevar", _("Scene variable with the content to append"))
.SetParameterLongDescription(_("The content of the variable will *be copied* and appended at the end of the array."))
.MarkAsAdvanced();
extension
.AddAction(
"GlobalVariableRemoveAt",
_("Remove variable from a global array (by index)"),
_("Removes a variable at the specified index of a global array variable."),
_("Remove variable at index _PARAM1_ from array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"))
.AddParameter("expression", _("Index to remove"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushString",
_("Append a string to a global array"),
_("Appends a string at the end of a global array variable."),
_("Append string _PARAM1_ to array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("string", _("String to append"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushNumber",
_("Append a number to a global array"),
_("Appends a number at the end of a global array variable."),
_("Append number _PARAM1_ to array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("expression", _("Number to append"))
.MarkAsAdvanced();
extension
.AddAction("GlobalVariablePushBool",
_("Append a boolean to a global array"),
_("Appends a boolean at the end of a global array variable."),
_("Append boolean _PARAM1_ to array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
.AddParameter("globalvar", _("Array variable"))
.AddParameter("trueorfalse", _("Boolean to append"))
.MarkAsAdvanced();
extension
.AddExpression("GlobalVariableChildCount",
_("Number of children of a global variable"),
_("Get the number of children of a global variable"),
_("Number of children of a global variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("globalvar", _("Variable"));
@@ -223,7 +422,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddExpression("VariableChildCount",
_("Number of children of a scene variable"),
_("Get the number of children of a scene variable"),
_("Number of children of a scene variable"),
_("Variables"),
"res/actions/var.png")
.AddParameter("scenevar", _("Variable"));

View File

@@ -12,12 +12,14 @@ namespace gd {
void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
gd::PlatformExtension& extension) {
extension
.SetExtensionInformation("BuiltinWindow",
_("Window features"),
_("Built-in extension allowing to manipulate "
"the game window and canvas"),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionInformation(
"BuiltinWindow",
_("Window features"),
"Provides actions and conditions to manipulate the game window. "
"Depending on the platform on which the game is running, not all of "
"these features can be applied.",
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/window");
#if defined(GD_IDE_ONLY)
@@ -38,6 +40,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsWindowExtension(
true)
.SetDefaultValue("yes");
extension
.AddCondition("IsFullScreen",
_("Fullscreen activated?"),
_("Check if the game is currently in fullscreen."),
_("The game is in fullscreen"),
_("Game's window and resolution"),
"res/actions/fullscreen24.png",
"res/actions/fullscreen.png")
.AddCodeOnlyParameter("currentScene", "");
extension
.AddAction("SetWindowMargins",
_("Change the window's margins"),

View File

@@ -4,12 +4,16 @@
* reserved. This project is released under the MIT License.
*/
#include "BehaviorMetadata.h"
#include <iostream>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
@@ -147,12 +151,16 @@ gd::ExpressionMetadata& BehaviorMetadata::AddExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace ( not necessary as
// we refer to the auomatism name in the expression )
expressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
expressionsInfos[name] = ExpressionMetadata("number",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
return expressionsInfos[name];
#endif
}
@@ -164,16 +172,109 @@ gd::ExpressionMetadata& BehaviorMetadata::AddStrExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, behaviors expression do not have namespace ( not necessary as
// we refer to the auomatism name in the expression )
strExpressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, behaviors expression do not have namespace (not necessary as
// we refer to the behavior name in the expression).
strExpressionsInfos[name] = ExpressionMetadata("string",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
return strExpressionsInfos[name];
#endif
}
gd::MultipleInstructionMetadata BehaviorMetadata::AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndCondition(expression,
condition);
}
gd::MultipleInstructionMetadata
BehaviorMetadata::AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
}
BehaviorMetadata& BehaviorMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;

View File

@@ -6,12 +6,14 @@
#ifndef BEHAVIORMETADATA_H
#define BEHAVIORMETADATA_H
#include <map>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
namespace gd {
class Behavior;
class BehaviorsSharedData;
class MultipleInstructionMetadata;
class InstructionMetadata;
class ExpressionMetadata;
} // namespace gd
@@ -41,7 +43,8 @@ class GD_CORE_API BehaviorMetadata {
/**
* Declare a new condition as being part of the behavior.
* \deprecated Prefer using `AddScopedCondition`.
* \deprecated Prefer using `AddScopedCondition`, to properly namespace
* the condition.
*/
gd::InstructionMetadata& AddCondition(const gd::String& name_,
const gd::String& fullname_,
@@ -53,7 +56,8 @@ class GD_CORE_API BehaviorMetadata {
/**
* Declare a new action as being part of the behavior.
* \deprecated Prefer using `AddScopedAction`.
* \deprecated Prefer using `AddScopedAction`, to properly namespace
* the action.
*/
gd::InstructionMetadata& AddAction(const gd::String& name_,
const gd::String& fullname_,
@@ -67,23 +71,23 @@ class GD_CORE_API BehaviorMetadata {
* Declare a new condition as being part of the behavior.
*/
gd::InstructionMetadata& AddScopedCondition(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new action as being part of the behavior.
*/
gd::InstructionMetadata& AddScopedAction(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new action as being part of the extension.
*/
@@ -102,6 +106,38 @@ class GD_CORE_API BehaviorMetadata {
const gd::String& group_,
const gd::String& smallicon_);
/**
* \brief Declare a new expression and condition as being part of the
* behavior.
* \note It's recommended to use this function to avoid declaring twice a
* similar expression/condition.
*/
gd::MultipleInstructionMetadata AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Declare a new expression, condition and action as being part of the
* behavior.
* \note The action name is prefixed by "Set" (and the namespace, as the
* condition).
* \note It's recommended to use this function to avoid declaring 3 times a
* similar expression/condition/action.
*/
gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
BehaviorMetadata& SetFullName(const gd::String& fullname_);
BehaviorMetadata& SetDefaultName(const gd::String& defaultName_);
BehaviorMetadata& SetDescription(const gd::String& description_);
@@ -120,12 +156,14 @@ class GD_CORE_API BehaviorMetadata {
BehaviorMetadata& AddIncludeFile(const gd::String& includeFile);
/**
* Get the help path of the behavior, relative to the documentation root.
* Get the help path of the behavior, relative to the GDevelop documentation
* root.
*/
const gd::String& GetHelpPath() const { return helpPath; }
/**
* Set the help path of the behavior, relative to the documentation root.
* Set the help path of the behavior, relative to the GDevelop documentation
* root.
*
* The behavior instructions will have this help path set by
* default, unless you call SetHelpPath on them.

View File

@@ -0,0 +1,155 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef DEPENDENCYMETADATA_H
#define DEPENDENCYMETADATA_H
#include <map>
#include <set>
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
#include "GDCore/Tools/Log.h"
namespace gd {
/**
* \brief Contains information about a dependency (library, npm/cordova
* package, or other according to the export) of an extension.
*/
class GD_CORE_API DependencyMetadata {
public:
/**
* Construct a new dependency metadata, though you probably want to call
* `AddDependency` on gd::PlatformExtension.
*
* \see gd::PlatformExtension
*/
DependencyMetadata() : onlyIfSomeExtraSettingsNonEmpty(false){};
/**
* \brief Sets the name shown to users.
*/
DependencyMetadata& SetName(const gd::String& name_) {
name = name_;
return *this;
};
/**
* \brief Sets the name written by the exporter.
* Typically, this is what is used by the dependency manager
* to find the dependency.
*
* \example
* \code
* // For depending upon the NPM package is-thirteen
* gd::DependencyMetadata dependencyMetadata = gd::DependencyMetadata();
* dependencyMetadata.setExporterName("is-thirteen");
* \endcode
*/
DependencyMetadata& SetExportName(const gd::String& exportName_) {
exportName = exportName_;
return *this;
};
/**
* \brief Set the version of the dependency to install.
* Use an empty string to use the latest version.
*/
DependencyMetadata& SetVersion(const gd::String& version_) {
version = version_;
return *this;
};
/**
* \brief Sets the type of dependecy (what will be used to install it)
*
* This can either be "npm" or "cordova" for now.
*/
DependencyMetadata& SetDependencyType(const gd::String& dependencyType_) {
dependencyType = dependencyType_;
if (dependencyType != "npm" && dependencyType != "cordova") {
gd::LogWarning("Invalid dependency type: " + dependencyType);
}
return *this;
};
/**
* \brief Sets a dependency type specific setting.
*/
DependencyMetadata& SetExtraSetting(
const gd::String& settingName,
const gd::PropertyDescriptor& settingValue) {
extraData[settingName] = settingValue;
return *this;
};
/**
* \brief Mark the dependency to be included in the export only if at least
* one of the extra settings is set.
*/
DependencyMetadata& OnlyIfSomeExtraSettingsNonEmpty() {
onlyIfSomeExtraSettingsNonEmpty = true;
return *this;
};
/**
* \brief Check if at least one of the extra settings must be set for the
* dependency to be included in the export.
*/
bool IsOnlyIfSomeExtraSettingsNonEmpty() const {
return onlyIfSomeExtraSettingsNonEmpty;
};
/**
* \brief Mark the dependency to be included in the export only if one other
* dependency is included in the export.
*/
DependencyMetadata& OnlyIfOtherDependencyIsExported(
const gd::String& otherDependency) {
onlyIfOtherDependencyIsExported = otherDependency;
return *this;
};
/**
* \brief Get the name of another dependency that must be exported to have
* this one also exported.
*/
const gd::String& GetOtherDependencyThatMustBeExported() const {
return onlyIfOtherDependencyIsExported;
};
const gd::String& GetName() const { return name; };
const gd::String& GetExportName() const { return exportName; };
const gd::String& GetVersion() const { return version; };
const gd::String& GetDependencyType() const {
if (dependencyType == "")
gd::LogWarning("Dependency has no type, it won't be exported.");
return dependencyType;
};
const std::map<gd::String, gd::PropertyDescriptor>& GetAllExtraSettings()
const {
return extraData;
}
void CopyFrom(const DependencyMetadata& dependencyMetadata) {
*this = dependencyMetadata;
}
private:
gd::String name; ///< The name of the dependency.
gd::String exportName; ///< The name used to install the package (example:
///< npm package name for npm dependency type).
gd::String version; ///< The version of the dependency
gd::String dependencyType; ///< The tool used to install the dependency.
std::map<gd::String, gd::PropertyDescriptor>
extraData; ///< Contains dependency type specific additional parameters
///< for the dependency.
bool onlyIfSomeExtraSettingsNonEmpty; ///< If true, only use this dependency
///< if at least one of the extra
///< settings is set.
gd::String onlyIfOtherDependencyIsExported;
};
} // namespace gd
#endif // DEPENDENCYMETADATA_H

View File

@@ -49,7 +49,7 @@ class GD_CORE_API EffectMetadata {
};
/**
* Set the help path of the effect, relative to the documentation root.
* Set the help path of the effect, relative to the GDevelop documentation root.
*/
EffectMetadata& SetHelpPath(const gd::String& path) {
helpPath = path;
@@ -81,7 +81,7 @@ class GD_CORE_API EffectMetadata {
}
/**
* \brief Get the help path of the effect, relative to the documentation root.
* \brief Get the help path of the effect, relative to the GDevelop documentation root.
*/
const gd::String& GetHelpPath() const { return helpPath; }

View File

@@ -9,13 +9,15 @@
namespace gd {
ExpressionMetadata::ExpressionMetadata(const gd::String& extensionNamespace_,
ExpressionMetadata::ExpressionMetadata(const gd::String& returnType_,
const gd::String& extensionNamespace_,
const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& group_,
const gd::String& smallicon_)
: fullname(fullname_),
: returnType(returnType_),
fullname(fullname_),
description(description_),
group(group_),
shown(true),

View File

@@ -8,6 +8,7 @@
#if defined(GD_IDE_ONLY)
#include <functional>
#include <memory>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
@@ -122,7 +123,8 @@ class GD_CORE_API ExpressionMetadata {
/**
* Construct a new expression metadata.
*/
ExpressionMetadata(const gd::String& extensionNamespace,
ExpressionMetadata(const gd::String& returnType,
const gd::String& extensionNamespace,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
@@ -131,9 +133,11 @@ class GD_CORE_API ExpressionMetadata {
/**
* Construct an empty ExpressionMetadata.
* \warning Don't use this - only here to fullfil std::map requirements.
* \warning Don't use this - only here to construct a "bad" ExpressionData and
* to fulfill std::map requirements.
*/
ExpressionMetadata() : shown(false), isPrivate(false){};
ExpressionMetadata()
: returnType("unknown"), shown(false), isPrivate(false){};
virtual ~ExpressionMetadata(){};
@@ -151,14 +155,16 @@ class GD_CORE_API ExpressionMetadata {
}
/**
* Get the help path of the expression, relative to the documentation root.
* Get the help path of the expression, relative to the GDevelop documentation
* root.
*/
const gd::String &GetHelpPath() const { return helpPath; }
const gd::String& GetHelpPath() const { return helpPath; }
/**
* Set the help path of the expression, relative to the documentation root.
* Set the help path of the expression, relative to the GDevelop documentation
* root.
*/
ExpressionMetadata &SetHelpPath(const gd::String &path) {
ExpressionMetadata& SetHelpPath(const gd::String& path) {
helpPath = path;
return *this;
}
@@ -205,12 +211,14 @@ class GD_CORE_API ExpressionMetadata {
};
/**
* \brief Set the long description shown in the editor for the last added parameter.
* \brief Set the long description shown in the editor for the last added
* parameter.
*
* \see AddParameter
*/
ExpressionMetadata &SetParameterLongDescription(gd::String longDescription) {
if (!parameters.empty()) parameters.back().SetLongDescription(longDescription);
ExpressionMetadata& SetParameterLongDescription(gd::String longDescription) {
if (!parameters.empty())
parameters.back().SetLongDescription(longDescription);
return *this;
};
@@ -236,6 +244,7 @@ class GD_CORE_API ExpressionMetadata {
ExpressionCodeGenerationInformation codeExtraInformation;
bool IsShown() const { return shown; }
const gd::String& GetReturnType() const { return returnType; }
const gd::String& GetFullName() const { return fullname; }
const gd::String& GetDescription() const { return description; }
const gd::String& GetGroup() const { return group; }
@@ -254,6 +263,7 @@ class GD_CORE_API ExpressionMetadata {
std::vector<gd::ParameterMetadata> parameters;
private:
gd::String returnType;
gd::String fullname;
gd::String description;
gd::String helpPath;

View File

@@ -4,10 +4,13 @@
* reserved. This project is released under the MIT License.
*/
#include "InstructionMetadata.h"
#include <algorithm>
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
#include "GDCore/Tools/Localization.h"
#include "ParameterMetadata.h"
namespace gd {
InstructionMetadata::InstructionMetadata()
@@ -45,8 +48,6 @@ InstructionMetadata::InstructionMetadata(const gd::String& extensionNamespace_,
isObjectInstruction(false),
isBehaviorInstruction(false) {}
ParameterMetadata::ParameterMetadata() : optional(false), codeOnly(false) {}
InstructionMetadata& InstructionMetadata::AddParameter(
const gd::String& type,
const gd::String& description,
@@ -158,26 +159,4 @@ InstructionMetadata::UseStandardRelationalOperatorParameters(
return *this;
}
void ParameterMetadata::SerializeTo(SerializerElement& element) const {
element.SetAttribute("type", type);
element.SetAttribute("supplementaryInformation", supplementaryInformation);
element.SetAttribute("optional", optional);
element.SetAttribute("description", description);
element.SetAttribute("longDescription", longDescription);
element.SetAttribute("codeOnly", codeOnly);
element.SetAttribute("defaultValue", defaultValue);
element.SetAttribute("name", name);
}
void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
type = element.GetStringAttribute("type");
supplementaryInformation =
element.GetStringAttribute("supplementaryInformation");
optional = element.GetBoolAttribute("optional");
description = element.GetStringAttribute("description");
longDescription = element.GetStringAttribute("longDescription");
codeOnly = element.GetBoolAttribute("codeOnly");
defaultValue = element.GetStringAttribute("defaultValue");
name = element.GetStringAttribute("name");
}
} // namespace gd

View File

@@ -10,8 +10,10 @@
#include <functional>
#include <map>
#include <memory>
#include "GDCore/Events/Instruction.h"
#include "GDCore/String.h"
#include "ParameterMetadata.h"
namespace gd {
class Project;
class Layout;
@@ -22,212 +24,6 @@ class SerializerElement;
namespace gd {
/**
* \brief Contains user-friendly info about a parameter, and information about
* what a parameter need
*
* \ingroup Events
*/
class GD_CORE_API ParameterMetadata {
public:
ParameterMetadata();
virtual ~ParameterMetadata(){};
/**
* \brief Return the type of the parameter.
* \see gd::ParameterMetadata::IsObject
*/
const gd::String &GetType() const { return type; }
/**
* \brief Set the type of the parameter.
*/
ParameterMetadata &SetType(const gd::String &type_) {
type = type_;
return *this;
}
/**
* \brief Return the name of the parameter.
*
* Name is optional, and won't be filled for most parameters of extensions.
* It is useful when generating a function from events, where parameters must
* be named.
*/
const gd::String &GetName() const { return name; }
/**
* \brief Set the name of the parameter.
*
* Name is optional, and won't be filled for most parameters of extensions.
* It is useful when generating a function from events, where parameters must
* be named.
*/
ParameterMetadata &SetName(const gd::String &name_) {
name = name_;
return *this;
}
/**
* \brief Return an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* by the parameter).
*/
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
/**
* \brief Set an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* by the parameter).
*/
ParameterMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {
supplementaryInformation = supplementaryInformation_;
return *this;
}
/**
* \brief Return true if the parameter is optional.
*/
bool IsOptional() const { return optional; }
/**
* \brief Set if the parameter is optional.
*/
ParameterMetadata &SetOptional(bool optional_ = true) {
optional = optional_;
return *this;
}
/**
* \brief Return the description of the parameter
*/
const gd::String &GetDescription() const { return description; }
/**
* \brief Set the description of the parameter.
*/
ParameterMetadata &SetDescription(const gd::String &description_) {
description = description_;
return *this;
}
/**
* \brief Return true if the parameter is only meant to be completed during
* compilation and must not be displayed to the user.
*/
bool IsCodeOnly() const { return codeOnly; }
/**
* \brief Set if the parameter is only meant to be completed during
* compilation and must not be displayed to the user.
*/
ParameterMetadata &SetCodeOnly(bool codeOnly_ = true) {
codeOnly = codeOnly_;
return *this;
}
/**
* \brief Get the default value for the parameter.
*/
const gd::String &GetDefaultValue() const { return defaultValue; }
/**
* \brief Set the default value, if the parameter is optional.
*/
ParameterMetadata &SetDefaultValue(const gd::String &defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
/**
* \brief Get the user friendly, long description for the parameter.
*/
const gd::String &GetLongDescription() const { return longDescription; }
/**
* \brief Set the user friendly, long description for the parameter.
*/
ParameterMetadata &SetLongDescription(const gd::String &longDescription_) {
longDescription = longDescription_;
return *this;
}
/**
* \brief Return true if the type of the parameter is "object", "objectPtr" or
* "objectList".
*
* \see gd::ParameterMetadata::GetType
*/
static bool IsObject(const gd::String &parameterType) {
return parameterType == "object" || parameterType == "objectPtr" ||
parameterType == "objectList" ||
parameterType == "objectListWithoutPicking";
}
/**
* \brief Return true if the type of the parameter is "behavior".
*
* \see gd::ParameterMetadata::GetType
*/
static bool IsBehavior(const gd::String &parameterType) {
return parameterType == "behavior";
}
/**
* \brief Return true if the type of the parameter is an expression of the
* given type.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor) and in the EventsCodeGenerator.
*/
static bool IsExpression(const gd::String &type,
const gd::String &parameterType) {
if (type == "number") {
return parameterType == "expression" || parameterType == "camera" ||
parameterType == "forceMultiplier";
} else if (type == "string") {
return parameterType == "string" || parameterType == "layer" ||
parameterType == "color" || parameterType == "file" ||
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName";
} else if (type == "variable") {
return parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
}
return false;
}
/** \name Serialization
*/
///@{
/**
* \brief Serialize the ParameterMetadata to the specified element
*/
void SerializeTo(gd::SerializerElement &element) const;
/**
* \brief Load the ParameterMetadata from the specified element
*/
void UnserializeFrom(const gd::SerializerElement &element);
///@}
// TODO: Deprecated public fields. Any direct using should be moved to
// getter/setter.
gd::String type; ///< Parameter type
gd::String supplementaryInformation; ///< Used if needed
bool optional; ///< True if the parameter is optional
gd::String description; ///< Description shown in editor
bool codeOnly; ///< True if parameter is relative to code generation only,
///< i.e. must not be shown in editor
private:
gd::String longDescription; ///< Long description shown in the editor.
gd::String defaultValue; ///< Used as a default value in editor or if an
///< optional parameter is empty.
gd::String name; ///< The name of the parameter to be used in code
///< generation. Optional.
};
/**
* \brief Describe user-friendly information about an instruction (action or
* condition), its parameters and the function name as well as other information
@@ -274,12 +70,14 @@ class GD_CORE_API InstructionMetadata {
bool CanHaveSubInstructions() const { return canHaveSubInstructions; }
/**
* Get the help path of the instruction, relative to the documentation root.
* Get the help path of the instruction, relative to the GDevelop
* documentation root.
*/
const gd::String &GetHelpPath() const { return helpPath; }
/**
* Set the help path of the instruction, relative to the documentation root.
* Set the help path of the instruction, relative to the GDevelop
* documentation root.
*/
InstructionMetadata &SetHelpPath(const gd::String &path) {
helpPath = path;
@@ -421,7 +219,21 @@ class GD_CORE_API InstructionMetadata {
}
/**
* \brief Consider that the instruction is easy for an user to understand.
* \brief Check if the instruction is an object instruction.
*/
bool IsObjectInstruction() {
return isObjectInstruction;
}
/**
* \brief Check if the instruction is a behavior instruction.
*/
bool IsBehaviorInstruction() {
return isBehaviorInstruction;
}
/**
* \brief Consider that the instruction is easy for a user to understand.
*/
InstructionMetadata &MarkAsSimple() {
usageComplexity = 2;
@@ -429,7 +241,7 @@ class GD_CORE_API InstructionMetadata {
}
/**
* \brief Consider that the instruction is harder for an user to understand
* \brief Consider that the instruction is harder for a user to understand
* than a normal instruction.
*/
InstructionMetadata &MarkAsAdvanced() {
@@ -438,7 +250,7 @@ class GD_CORE_API InstructionMetadata {
}
/**
* \brief Consider that the instruction is complex for an user to understand.
* \brief Consider that the instruction is complex for a user to understand.
*/
InstructionMetadata &MarkAsComplex() {
usageComplexity = 9;

View File

@@ -4,11 +4,13 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include <algorithm>
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/String.h"
@@ -22,7 +24,6 @@ gd::ObjectMetadata MetadataProvider::badObjectInfo;
gd::EffectMetadata MetadataProvider::badEffectMetadata;
gd::InstructionMetadata MetadataProvider::badInstructionMetadata;
gd::ExpressionMetadata MetadataProvider::badExpressionMetadata;
gd::ExpressionMetadata MetadataProvider::badStrExpressionMetadata;
gd::PlatformExtension MetadataProvider::badExtension;
ExtensionAndMetadata<BehaviorMetadata>
@@ -276,7 +277,7 @@ MetadataProvider::GetExtensionAndObjectStrExpressionMetadata(
}
return ExtensionAndMetadata<ExpressionMetadata>(badExtension,
badStrExpressionMetadata);
badExpressionMetadata);
}
const gd::ExpressionMetadata& MetadataProvider::GetObjectStrExpressionMetadata(
@@ -313,7 +314,7 @@ MetadataProvider::GetExtensionAndBehaviorStrExpressionMetadata(
}
return ExtensionAndMetadata<ExpressionMetadata>(badExtension,
badStrExpressionMetadata);
badExpressionMetadata);
}
const gd::ExpressionMetadata&
@@ -337,7 +338,7 @@ MetadataProvider::GetExtensionAndStrExpressionMetadata(
}
return ExtensionAndMetadata<ExpressionMetadata>(badExtension,
badStrExpressionMetadata);
badExpressionMetadata);
}
const gd::ExpressionMetadata& MetadataProvider::GetStrExpressionMetadata(
@@ -345,197 +346,48 @@ const gd::ExpressionMetadata& MetadataProvider::GetStrExpressionMetadata(
return GetExtensionAndStrExpressionMetadata(platform, exprType).GetMetadata();
}
bool MetadataProvider::HasAction(const gd::Platform& platform,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
const gd::ExpressionMetadata& MetadataProvider::GetAnyExpressionMetadata(
const gd::Platform& platform, gd::String exprType) {
const auto& numberExpressionMetadata =
GetExpressionMetadata(platform, exprType);
const auto& stringExpressionMetadata =
GetStrExpressionMetadata(platform, exprType);
for (auto& extension : extensions) {
const auto& actions = extension->GetAllActions();
if (actions.find(name) != actions.end()) return true;
}
return false;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
bool MetadataProvider::HasObjectAction(const gd::Platform& platform,
gd::String objectType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& actions = extension->GetAllActionsForObject(objectType);
if (actions.find(name) != actions.end()) return true;
}
const gd::ExpressionMetadata& MetadataProvider::GetObjectAnyExpressionMetadata(
const gd::Platform& platform, gd::String objectType, gd::String exprType) {
const auto& numberExpressionMetadata =
GetObjectExpressionMetadata(platform, objectType, exprType);
const auto& stringExpressionMetadata =
GetObjectStrExpressionMetadata(platform, objectType, exprType);
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& actions = extension->GetAllActionsForObject("");
if (actions.find(name) != actions.end()) return true;
}
return false;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
bool MetadataProvider::HasBehaviorAction(const gd::Platform& platform,
gd::String behaviorType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& actions = extension->GetAllActionsForBehavior(behaviorType);
if (actions.find(name) != actions.end()) return true;
}
const gd::ExpressionMetadata&
MetadataProvider::GetBehaviorAnyExpressionMetadata(const gd::Platform& platform,
gd::String autoType,
gd::String exprType) {
const auto& numberExpressionMetadata =
GetBehaviorExpressionMetadata(platform, autoType, exprType);
const auto& stringExpressionMetadata =
GetBehaviorStrExpressionMetadata(platform, autoType, exprType);
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& actions = extension->GetAllActionsForBehavior("");
if (actions.find(name) != actions.end()) return true;
}
return false;
}
bool MetadataProvider::HasCondition(const gd::Platform& platform,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& conditions = extension->GetAllConditions();
if (conditions.find(name) != conditions.end()) return true;
}
return false;
}
bool MetadataProvider::HasObjectCondition(const gd::Platform& platform,
gd::String objectType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& conditions = extension->GetAllConditionsForObject(objectType);
if (conditions.find(name) != conditions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& conditions = extension->GetAllConditionsForObject("");
if (conditions.find(name) != conditions.end()) return true;
}
return false;
}
bool MetadataProvider::HasBehaviorCondition(const gd::Platform& platform,
gd::String behaviorType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& conditions =
extension->GetAllConditionsForBehavior(behaviorType);
if (conditions.find(name) != conditions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& conditions = extension->GetAllConditionsForBehavior("");
if (conditions.find(name) != conditions.end()) return true;
}
return false;
}
bool MetadataProvider::HasExpression(const gd::Platform& platform,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllExpressions();
if (expressions.find(name) != expressions.end()) return true;
}
return false;
}
bool MetadataProvider::HasObjectExpression(const gd::Platform& platform,
gd::String objectType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllExpressionsForObject(objectType);
if (expressions.find(name) != expressions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllExpressionsForObject("");
if (expressions.find(name) != expressions.end()) return true;
}
return false;
}
bool MetadataProvider::HasBehaviorExpression(const gd::Platform& platform,
gd::String behaviorType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions =
extension->GetAllExpressionsForBehavior(behaviorType);
if (expressions.find(name) != expressions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllExpressionsForBehavior("");
if (expressions.find(name) != expressions.end()) return true;
}
return false;
}
bool MetadataProvider::HasStrExpression(const gd::Platform& platform,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllStrExpressions();
if (expressions.find(name) != expressions.end()) return true;
}
return false;
}
bool MetadataProvider::HasObjectStrExpression(const gd::Platform& platform,
gd::String objectType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions =
extension->GetAllStrExpressionsForObject(objectType);
if (expressions.find(name) != expressions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllStrExpressionsForObject("");
if (expressions.find(name) != expressions.end()) return true;
}
return false;
}
bool MetadataProvider::HasBehaviorStrExpression(const gd::Platform& platform,
gd::String behaviorType,
gd::String name) {
auto& extensions = platform.GetAllPlatformExtensions();
for (auto& extension : extensions) {
const auto& expressions =
extension->GetAllStrExpressionsForBehavior(behaviorType);
if (expressions.find(name) != expressions.end()) return true;
}
// Then check in functions of "Base object".
for (auto& extension : extensions) {
const auto& expressions = extension->GetAllStrExpressionsForBehavior("");
if (expressions.find(name) != expressions.end()) return true;
}
return false;
return &numberExpressionMetadata != &badExpressionMetadata
? numberExpressionMetadata
: &stringExpressionMetadata != &badExpressionMetadata
? stringExpressionMetadata
: badExpressionMetadata;
}
MetadataProvider::~MetadataProvider() {}

View File

@@ -96,7 +96,7 @@ class GD_CORE_API MetadataProvider {
/**
* Get information about an expression, and its associated extension.
* Works for static expressions.
* Works for free expressions.
*/
static ExtensionAndMetadata<ExpressionMetadata>
GetExtensionAndExpressionMetadata(const gd::Platform& platform,
@@ -122,7 +122,7 @@ class GD_CORE_API MetadataProvider {
/**
* Get information about a string expression, and its associated extension.
* Works for static expressions.
* Works for free expressions.
*/
static ExtensionAndMetadata<ExpressionMetadata>
GetExtensionAndStrExpressionMetadata(const gd::Platform& platform,
@@ -180,7 +180,7 @@ class GD_CORE_API MetadataProvider {
/**
* Get information about an expression from its type
* Works for static expressions.
* Works for free expressions.
*/
static const gd::ExpressionMetadata& GetExpressionMetadata(
const gd::Platform& platform, gd::String exprType);
@@ -201,7 +201,7 @@ class GD_CORE_API MetadataProvider {
/**
* Get information about a string expression from its type
* Works for static expressions.
* Works for free expressions.
*/
static const gd::ExpressionMetadata& GetStrExpressionMetadata(
const gd::Platform& platform, gd::String exprType);
@@ -221,96 +221,28 @@ class GD_CORE_API MetadataProvider {
const gd::Platform& platform, gd::String autoType, gd::String exprType);
/**
* \brief Check if a (static) condition exists
* @return true if the (static) condition exists
* Get information about an expression from its type.
* Works for free expressions.
*/
static bool HasCondition(const gd::Platform& platform, gd::String name);
static const gd::ExpressionMetadata& GetAnyExpressionMetadata(
const gd::Platform& platform, gd::String exprType);
/**
* \brief Check if a (static) action exists
* @return true if the (static) action exists
* Get information about an expression from its type.
* Works for object expressions.
*/
static bool HasAction(const gd::Platform& platform, gd::String name);
static const gd::ExpressionMetadata& GetObjectAnyExpressionMetadata(
const gd::Platform& platform, gd::String objectType, gd::String exprType);
/**
* \brief Check if a (object) action exists
* @return true if the (object) action exists
* Get information about an expression from its type.
* Works for behavior expressions.
*/
static bool HasObjectAction(const gd::Platform& platform,
gd::String objectType,
gd::String name);
/**
* \brief Check if a (object) condition exists
* @return true if the (object) condition exists
*/
static bool HasObjectCondition(const gd::Platform& platform,
gd::String objectType,
gd::String name);
/**
* \brief Check if a (behavior) action exists
* @return true if the (behavior) action exists
*/
static bool HasBehaviorAction(const gd::Platform& platform,
gd::String behaviorType,
gd::String name);
/**
* \brief Check if a (behavior) condition exists
* @return true if the (behavior) condition exists
*/
static bool HasBehaviorCondition(const gd::Platform& platform,
gd::String behaviorType,
gd::String name);
/**
* \brief Check if a (static) expression exists
* @return true if the (static) expression exists
*/
static bool HasExpression(const gd::Platform& platform, gd::String name);
/**
* \brief Check if a (object) expression exists
* @return true if the (object) expression exists
*/
static bool HasObjectExpression(const gd::Platform& platform,
gd::String objectType,
gd::String name);
/**
* \brief Check if a (behavior) expression exists
* @return true if the (behavior) expression exists
*/
static bool HasBehaviorExpression(const gd::Platform& platform,
gd::String behaviorType,
gd::String name);
/**
* \brief Check if a (static) string expression exists
* @return true if the (static) string expression exists
*/
static bool HasStrExpression(const gd::Platform& platform, gd::String name);
/**
* \brief Check if a (object) string expression exists
* @return true if the (object) string expression exists
*/
static bool HasObjectStrExpression(const gd::Platform& platform,
gd::String objectType,
gd::String name);
/**
* \brief Check if a (behavior) string expression exists
* @return true if the (behavior) string expression exists
*/
static bool HasBehaviorStrExpression(const gd::Platform& platform,
gd::String behaviorType,
gd::String name);
static const gd::ExpressionMetadata& GetBehaviorAnyExpressionMetadata(
const gd::Platform& platform, gd::String autoType, gd::String exprType);
static bool IsBadExpressionMetadata(const gd::ExpressionMetadata& metadata) {
return &metadata == &badExpressionMetadata ||
&metadata == &badStrExpressionMetadata;
return &metadata == &badExpressionMetadata;
}
virtual ~MetadataProvider();
@@ -324,7 +256,6 @@ class GD_CORE_API MetadataProvider {
static EffectMetadata badEffectMetadata;
static gd::InstructionMetadata badInstructionMetadata;
static gd::ExpressionMetadata badExpressionMetadata;
static gd::ExpressionMetadata badStrExpressionMetadata;
int useless; // Useless member to avoid emscripten "must have a positive
// integer typeid pointer" runtime error.
};

View File

@@ -0,0 +1,12 @@
/*
* GDevelop Core
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "MultipleInstructionMetadata.h"
#include "InstructionMetadata.h"
namespace gd {
} // namespace gd

View File

@@ -0,0 +1,216 @@
/*
* GDevelop Core
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef MULTIPLEINSTRUCTIONSMETADATA_H
#define MULTIPLEINSTRUCTIONSMETADATA_H
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
namespace gd {} // namespace gd
namespace gd {
/**
* \brief A "composite" metadata that can be used to easily declare
* both an expression and a related condition (and a related action)
* without writing manually the three of them.
*
* \ingroup PlatformDefinition
*/
class GD_CORE_API MultipleInstructionMetadata {
public:
static MultipleInstructionMetadata WithExpressionAndCondition(
gd::ExpressionMetadata &expression, gd::InstructionMetadata &condition) {
return MultipleInstructionMetadata(expression, condition);
}
static MultipleInstructionMetadata WithExpressionAndConditionAndAction(
gd::ExpressionMetadata &expression,
gd::InstructionMetadata &condition,
gd::InstructionMetadata &action) {
return MultipleInstructionMetadata(expression, condition, action);
}
/**
* \see gd::InstructionMetadata::AddParameter
*/
MultipleInstructionMetadata &AddParameter(
const gd::String &type,
const gd::String &label,
const gd::String &optionalObjectType = "",
bool parameterIsOptional = false) {
#if defined(GD_IDE_ONLY)
if (expression)
expression->AddParameter(
type, label, optionalObjectType, parameterIsOptional);
if (condition)
condition->AddParameter(
type, label, optionalObjectType, parameterIsOptional);
if (action)
action->AddParameter(
type, label, optionalObjectType, parameterIsOptional);
#endif
return *this;
}
/**
* \see gd::InstructionMetadata::AddCodeOnlyParameter
*/
MultipleInstructionMetadata &AddCodeOnlyParameter(
const gd::String &type, const gd::String &supplementaryInformation) {
#if defined(GD_IDE_ONLY)
if (expression)
expression->AddCodeOnlyParameter(type, supplementaryInformation);
if (condition)
condition->AddCodeOnlyParameter(type, supplementaryInformation);
if (action) action->AddCodeOnlyParameter(type, supplementaryInformation);
#endif
return *this;
}
/**
* \see gd::InstructionMetadata::SetDefaultValue
*/
MultipleInstructionMetadata &SetDefaultValue(const gd::String &defaultValue) {
#if defined(GD_IDE_ONLY)
if (expression) expression->SetDefaultValue(defaultValue);
if (condition) condition->SetDefaultValue(defaultValue);
if (action) action->SetDefaultValue(defaultValue);
#endif
return *this;
};
/**
* \see gd::InstructionMetadata::SetParameterLongDescription
*/
MultipleInstructionMetadata &SetParameterLongDescription(
const gd::String &longDescription) {
#if defined(GD_IDE_ONLY)
if (expression) expression->SetParameterLongDescription(longDescription);
if (condition) condition->SetParameterLongDescription(longDescription);
if (action) action->SetParameterLongDescription(longDescription);
#endif
return *this;
};
/**
* \see gd::InstructionMetadata::SetHidden
*/
MultipleInstructionMetadata &SetHidden() {
#if defined(GD_IDE_ONLY)
if (expression) expression->SetHidden();
if (condition) condition->SetHidden();
if (action) action->SetHidden();
#endif
return *this;
};
/**
* \see gd::InstructionMetadata::UseStandardOperatorParameters
* \see gd::InstructionMetadata::UseStandardRelationalOperatorParameters
*/
MultipleInstructionMetadata &UseStandardParameters(const gd::String &type) {
#if defined(GD_IDE_ONLY)
if (condition) condition->UseStandardRelationalOperatorParameters(type);
if (action) action->UseStandardOperatorParameters(type);
#endif
return *this;
}
MultipleInstructionMetadata &SetFunctionName(const gd::String &functionName) {
#if defined(GD_IDE_ONLY)
if (expression) expression->SetFunctionName(functionName);
if (condition) condition->SetFunctionName(functionName);
if (action) action->GetCodeExtraInformation().SetFunctionName(functionName);
#endif
return *this;
}
MultipleInstructionMetadata &SetGetter(const gd::String &getter) {
#if defined(GD_IDE_ONLY)
if (expression) expression->SetFunctionName(getter);
if (condition) condition->SetFunctionName(getter);
if (action) action->GetCodeExtraInformation().SetGetter(getter);
#endif
return *this;
}
MultipleInstructionMetadata &SetIncludeFile(const gd::String &includeFile) {
#if defined(GD_IDE_ONLY)
if (expression)
expression->GetCodeExtraInformation().SetIncludeFile(includeFile);
if (condition)
condition->GetCodeExtraInformation().SetIncludeFile(includeFile);
if (action) action->GetCodeExtraInformation().SetIncludeFile(includeFile);
#endif
return *this;
}
MultipleInstructionMetadata &AddIncludeFile(const gd::String &includeFile) {
#if defined(GD_IDE_ONLY)
if (expression)
expression->GetCodeExtraInformation().AddIncludeFile(includeFile);
if (condition)
condition->GetCodeExtraInformation().AddIncludeFile(includeFile);
if (action) action->GetCodeExtraInformation().AddIncludeFile(includeFile);
#endif
return *this;
}
/**
* \see gd::InstructionMetadata::MarkAsSimple
*/
MultipleInstructionMetadata &MarkAsSimple() {
#if defined(GD_IDE_ONLY)
if (condition) condition->MarkAsSimple();
if (action) action->MarkAsSimple();
#endif
return *this;
}
/**
* \see gd::InstructionMetadata::MarkAsAdvanced
*/
MultipleInstructionMetadata &MarkAsAdvanced() {
#if defined(GD_IDE_ONLY)
if (condition) condition->MarkAsAdvanced();
if (action) action->MarkAsAdvanced();
#endif
return *this;
}
/**
* \see gd::InstructionMetadata::MarkAsComplex
*/
MultipleInstructionMetadata &MarkAsComplex() {
#if defined(GD_IDE_ONLY)
if (condition) condition->MarkAsComplex();
if (action) action->MarkAsComplex();
#endif
return *this;
}
/**
* \brief Don't use, only here to fulfill Emscripten bindings requirements.
*/
MultipleInstructionMetadata()
: expression(nullptr), condition(nullptr), action(nullptr){};
private:
MultipleInstructionMetadata(gd::ExpressionMetadata &expression_,
gd::InstructionMetadata &condition_)
: expression(&expression_), condition(&condition_), action(nullptr){};
MultipleInstructionMetadata(gd::ExpressionMetadata &expression_,
gd::InstructionMetadata &condition_,
gd::InstructionMetadata &action_)
: expression(&expression_), condition(&condition_), action(&action_){};
gd::ExpressionMetadata *expression;
gd::InstructionMetadata *condition;
gd::InstructionMetadata *action;
};
} // namespace gd
#endif // MULTIPLEINSTRUCTIONSMETADATA_H

View File

@@ -4,11 +4,16 @@
* reserved. This project is released under the MIT License.
*/
#include "ObjectMetadata.h"
#include <algorithm>
#include <iostream>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
@@ -108,6 +113,62 @@ gd::InstructionMetadata& ObjectMetadata::AddAction(
#endif
}
gd::InstructionMetadata& ObjectMetadata::AddScopedCondition(
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentence,
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName().empty()
? name // Don't insert a namespace separator for the base object.
: GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
nameWithNamespace,
fullname,
description,
sentence,
group,
icon,
smallicon)
.SetHelpPath(GetHelpPath())
.SetIsObjectInstruction();
return conditionsInfos[nameWithNamespace];
#endif
}
gd::InstructionMetadata& ObjectMetadata::AddScopedAction(
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentence,
const gd::String& group,
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetName().empty()
? name // Don't insert a namespace separator for the base object.
: GetName() + gd::PlatformExtension::GetNamespaceSeparator() + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(extensionNamespace,
nameWithNamespace,
fullname,
description,
sentence,
group,
icon,
smallicon)
.SetHelpPath(GetHelpPath())
.SetIsObjectInstruction();
return actionsInfos[nameWithNamespace];
#endif
}
gd::ExpressionMetadata& ObjectMetadata::AddExpression(
const gd::String& name,
const gd::String& fullname,
@@ -115,12 +176,16 @@ gd::ExpressionMetadata& ObjectMetadata::AddExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, objects expression do not have namespace ( not necessary as
// objects inherits from only one derived object )
expressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, objects expression do not have namespace (not necessary as
// objects inherits from only one derived object).
expressionsInfos[name] = ExpressionMetadata("number",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
return expressionsInfos[name];
#endif
@@ -133,17 +198,110 @@ gd::ExpressionMetadata& ObjectMetadata::AddStrExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
// Be careful, objects expression do not have namespace ( not necessary as
// objects inherits from only one derived object )
strExpressionsInfos[name] =
ExpressionMetadata(
extensionNamespace, name, fullname, description, group, smallicon)
.SetHelpPath(GetHelpPath());
// Be careful, objects expression do not have namespace (not necessary as
// objects inherits from only one derived object).
strExpressionsInfos[name] = ExpressionMetadata("string",
extensionNamespace,
name,
fullname,
description,
group,
smallicon)
.SetHelpPath(GetHelpPath());
return strExpressionsInfos[name];
#endif
}
gd::MultipleInstructionMetadata ObjectMetadata::AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndCondition(expression,
condition);
}
gd::MultipleInstructionMetadata
ObjectMetadata::AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition =
AddScopedCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddScopedAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
}
ObjectMetadata& ObjectMetadata::SetFullName(const gd::String& fullname_) {
#if defined(GD_IDE_ONLY)
fullname = fullname_;

View File

@@ -5,19 +5,22 @@
*/
#ifndef OBJECTMETADATA_H
#define OBJECTMETADATA_H
#include <functional>
#include <map>
#include <memory>
#include <functional>
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Project/Object.h"
#include "GDCore/String.h"
namespace gd {
class InstructionMetadata;
class MultipleInstructionMetadata;
class ExpressionMetadata;
} // namespace gd
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)> CreateFunPtr;
typedef std::function<std::unique_ptr<gd::Object>(gd::String name)>
CreateFunPtr;
namespace gd {
@@ -31,7 +34,7 @@ class GD_CORE_API ObjectMetadata {
public:
/**
* \brief Construct an object metadata, using a "blueprint" object that will
* be copied when a new object is asked.
* be copied when a new object is requested.
*/
ObjectMetadata(const gd::String& extensionNamespace_,
const gd::String& name_,
@@ -55,7 +58,8 @@ class GD_CORE_API ObjectMetadata {
/**
* \brief Declare a new condition as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
* \deprecated Prefer using `AddScopedCondition`, to properly namespace the
* condition.
*/
gd::InstructionMetadata& AddCondition(const gd::String& name_,
const gd::String& fullname_,
@@ -67,7 +71,8 @@ class GD_CORE_API ObjectMetadata {
/**
* \brief Declare a new action as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
* \deprecated Prefer using `AddScopedAction`, to properly namespace the
* action.
*/
gd::InstructionMetadata& AddAction(const gd::String& name_,
const gd::String& fullname_,
@@ -76,9 +81,31 @@ class GD_CORE_API ObjectMetadata {
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new condition as being part of the object.
*/
gd::InstructionMetadata& AddScopedCondition(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* Declare a new action as being part of the object.
*/
gd::InstructionMetadata& AddScopedAction(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& sentence_,
const gd::String& group_,
const gd::String& icon_,
const gd::String& smallicon_);
/**
* \brief Declare a new expression as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::ExpressionMetadata& AddExpression(const gd::String& name_,
const gd::String& fullname_,
@@ -87,7 +114,6 @@ class GD_CORE_API ObjectMetadata {
const gd::String& smallicon_);
/**
* \brief Declare a new string expression as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::ExpressionMetadata& AddStrExpression(const gd::String& name_,
const gd::String& fullname_,
@@ -95,30 +121,62 @@ class GD_CORE_API ObjectMetadata {
const gd::String& group_,
const gd::String& smallicon_);
/**
* \brief Declare a new expression and condition as being part of the
* object.
* \note It's recommended to use this function to avoid declaring twice a
* similar expression/condition.
*/
gd::MultipleInstructionMetadata AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Declare a new expression, condition and action as being part of the
* object.
* \note The action name is prefixed by "Set" (and the namespace, as the
* condition).
* \note It's recommended to use this function to avoid declaring
* 3 times a similar expression/condition/action.
*/
gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Set the name shown to the user.
* \note This method does nothing when used for GD C++ runtime.
*/
ObjectMetadata& SetFullName(const gd::String& fullname_);
/**
* \brief Set the description shown to the user.
* \note This method does nothing when used for GD C++ runtime.
*/
ObjectMetadata& SetDescription(const gd::String& description_);
/**
* Get the help path of the object, relative to the documentation root.
* \brief Get the help path of the object, relative to the GDevelop
* documentation root.
*/
const gd::String &GetHelpPath() const { return helpPath; }
const gd::String& GetHelpPath() const { return helpPath; }
/**
* Set the help path of the object, relative to the documentation root.
*
* \brief Set the help path of the object, relative to the GDevelop
* documentation root.
*
* The object instructions will have this help path set by
* default, unless you call SetHelpPath on them.
*/
ObjectMetadata &SetHelpPath(const gd::String &path) {
ObjectMetadata& SetHelpPath(const gd::String& path) {
helpPath = path;
return *this;
}
@@ -166,7 +224,7 @@ class GD_CORE_API ObjectMetadata {
gd::String name;
gd::String helpPath;
#if defined(GD_IDE_ONLY)
gd::String helpUrl; ///< Deprecated. Use helpPath instead.
gd::String helpUrl; ///< Deprecated. Use helpPath instead.
gd::String fullname;
gd::String description;
gd::String iconFilename;

View File

@@ -0,0 +1,38 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ParameterMetadata.h"
#include "GDCore/CommonTools.h"
#include "GDCore/Serialization/SerializerElement.h"
namespace gd {
ParameterMetadata::ParameterMetadata() : optional(false), codeOnly(false) {}
void ParameterMetadata::SerializeTo(SerializerElement& element) const {
element.SetAttribute("type", type);
element.SetAttribute("supplementaryInformation", supplementaryInformation);
element.SetAttribute("optional", optional);
element.SetAttribute("description", description);
element.SetAttribute("longDescription", longDescription);
element.SetAttribute("codeOnly", codeOnly);
element.SetAttribute("defaultValue", defaultValue);
element.SetAttribute("name", name);
}
void ParameterMetadata::UnserializeFrom(const SerializerElement& element) {
type = element.GetStringAttribute("type");
supplementaryInformation =
element.GetStringAttribute("supplementaryInformation");
optional = element.GetBoolAttribute("optional");
description = element.GetStringAttribute("description");
longDescription = element.GetStringAttribute("longDescription");
codeOnly = element.GetBoolAttribute("codeOnly");
defaultValue = element.GetStringAttribute("defaultValue");
name = element.GetStringAttribute("name");
}
} // namespace gd

View File

@@ -0,0 +1,232 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef PARAMETER_METADATA_H
#define PARAMETER_METADATA_H
#if defined(GD_IDE_ONLY)
#include <map>
#include <memory>
#include "GDCore/String.h"
namespace gd {
class Project;
class Layout;
class EventsCodeGenerator;
class EventsCodeGenerationContext;
class SerializerElement;
} // namespace gd
namespace gd {
/**
* \brief Describe a parameter of an instruction (action, condition) or of an
* expression: type, user-friendly description, etc...
*
* \ingroup Events
*/
class GD_CORE_API ParameterMetadata {
public:
ParameterMetadata();
virtual ~ParameterMetadata(){};
/**
* \brief Return the type of the parameter.
* \see gd::ParameterMetadata::IsObject
*/
const gd::String &GetType() const { return type; }
/**
* \brief Set the type of the parameter.
*/
ParameterMetadata &SetType(const gd::String &type_) {
type = type_;
return *this;
}
/**
* \brief Return the name of the parameter.
*
* Name is optional, and won't be filled for most parameters of extensions.
* It is useful when generating a function from events, where parameters must
* be named.
*/
const gd::String &GetName() const { return name; }
/**
* \brief Set the name of the parameter.
*
* Name is optional, and won't be filled for most parameters of extensions.
* It is useful when generating a function from events, where parameters must
* be named.
*/
ParameterMetadata &SetName(const gd::String &name_) {
name = name_;
return *this;
}
/**
* \brief Return an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* by the parameter).
*/
const gd::String &GetExtraInfo() const { return supplementaryInformation; }
/**
* \brief Set an optional additional information, used for some parameters
* with special type (For example, it can contains the type of object accepted
* by the parameter).
*/
ParameterMetadata &SetExtraInfo(const gd::String &supplementaryInformation_) {
supplementaryInformation = supplementaryInformation_;
return *this;
}
/**
* \brief Return true if the parameter is optional.
*/
bool IsOptional() const { return optional; }
/**
* \brief Set if the parameter is optional.
*/
ParameterMetadata &SetOptional(bool optional_ = true) {
optional = optional_;
return *this;
}
/**
* \brief Return the description of the parameter
*/
const gd::String &GetDescription() const { return description; }
/**
* \brief Set the description of the parameter.
*/
ParameterMetadata &SetDescription(const gd::String &description_) {
description = description_;
return *this;
}
/**
* \brief Return true if the parameter is only meant to be completed during
* compilation and must not be displayed to the user.
*/
bool IsCodeOnly() const { return codeOnly; }
/**
* \brief Set if the parameter is only meant to be completed during
* compilation and must not be displayed to the user.
*/
ParameterMetadata &SetCodeOnly(bool codeOnly_ = true) {
codeOnly = codeOnly_;
return *this;
}
/**
* \brief Get the default value for the parameter.
*/
const gd::String &GetDefaultValue() const { return defaultValue; }
/**
* \brief Set the default value, if the parameter is optional.
*/
ParameterMetadata &SetDefaultValue(const gd::String &defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
/**
* \brief Get the user friendly, long description for the parameter.
*/
const gd::String &GetLongDescription() const { return longDescription; }
/**
* \brief Set the user friendly, long description for the parameter.
*/
ParameterMetadata &SetLongDescription(const gd::String &longDescription_) {
longDescription = longDescription_;
return *this;
}
/**
* \brief Return true if the type of the parameter is "object", "objectPtr" or
* "objectList".
*
* \see gd::ParameterMetadata::GetType
*/
static bool IsObject(const gd::String &parameterType) {
return parameterType == "object" || parameterType == "objectPtr" ||
parameterType == "objectList" ||
parameterType == "objectListWithoutPicking";
}
/**
* \brief Return true if the type of the parameter is "behavior".
*
* \see gd::ParameterMetadata::GetType
*/
static bool IsBehavior(const gd::String &parameterType) {
return parameterType == "behavior";
}
/**
* \brief Return true if the type of the parameter is an expression of the
* given type.
* \note If you had a new type of parameter, also add it in the IDE (
* see EventsFunctionParametersEditor) and in the EventsCodeGenerator.
*/
static bool IsExpression(const gd::String &type,
const gd::String &parameterType) {
if (type == "number") {
return parameterType == "expression" || parameterType == "camera" ||
parameterType == "forceMultiplier";
} else if (type == "string") {
return parameterType == "string" || parameterType == "layer" ||
parameterType == "color" || parameterType == "file" ||
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName";
} else if (type == "variable") {
return parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";
}
return false;
}
/** \name Serialization
*/
///@{
/**
* \brief Serialize the ParameterMetadata to the specified element
*/
void SerializeTo(gd::SerializerElement &element) const;
/**
* \brief Load the ParameterMetadata from the specified element
*/
void UnserializeFrom(const gd::SerializerElement &element);
///@}
// TODO: Deprecated public fields. Any direct usage should be moved to
// getter/setter.
gd::String type; ///< Parameter type
gd::String supplementaryInformation; ///< Used if needed
bool optional; ///< True if the parameter is optional
gd::String description; ///< Description shown in editor
bool codeOnly; ///< True if parameter is relative to code generation only,
///< i.e. must not be shown in editor
private:
gd::String longDescription; ///< Long description shown in the editor.
gd::String defaultValue; ///< Used as a default value in editor or if an
///< optional parameter is empty.
gd::String name; ///< The name of the parameter to be used in code
///< generation. Optional.
};
} // namespace gd
#endif
#endif // PARAMETER_METADATA_H

View File

@@ -90,7 +90,7 @@ size_t ParameterMetadataTools::GetObjectParameterIndexFor(
// the object in the list of parameters (if possible, just after).
// Search "lastObjectName" in the codebase for other place where this
// convention is enforced.
for (std::size_t pNb = parameterIndex - 1; pNb < parametersMetadata.size();
for (std::size_t pNb = parameterIndex; pNb < parametersMetadata.size();
pNb--) {
if (gd::ParameterMetadata::IsObject(parametersMetadata[pNb].GetType())) {
return pNb;

View File

@@ -14,7 +14,7 @@ using namespace std;
namespace gd {
Platform::Platform(): enableExtensionLoadingLogs(true) {}
Platform::Platform(): enableExtensionLoadingLogs(false) {}
Platform::~Platform() {}

View File

@@ -4,17 +4,22 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Extensions/PlatformExtension.h"
#include <algorithm>
#include "GDCore/Events/Event.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
#include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/Extensions/Metadata/MultipleInstructionMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/PlatformManager.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/BehaviorsSharedData.h"
#include "GDCore/Tools/Localization.h"
namespace gd {
@@ -25,8 +30,6 @@ std::map<gd::String, gd::InstructionMetadata>
PlatformExtension::badActionsMetadata;
std::map<gd::String, gd::ExpressionMetadata>
PlatformExtension::badExpressionsMetadata;
std::map<gd::String, gd::ExpressionMetadata>
PlatformExtension::badStrExpressionsMetadata;
#endif
gd::InstructionMetadata& PlatformExtension::AddCondition(
@@ -38,8 +41,7 @@ gd::InstructionMetadata& PlatformExtension::AddCondition(
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
gd::String nameWithNamespace = GetNameSpace() + name;
conditionsInfos[nameWithNamespace] = InstructionMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
@@ -62,8 +64,7 @@ gd::InstructionMetadata& PlatformExtension::AddAction(
const gd::String& icon,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
gd::String nameWithNamespace = GetNameSpace() + name;
actionsInfos[nameWithNamespace] = InstructionMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
@@ -84,9 +85,9 @@ gd::ExpressionMetadata& PlatformExtension::AddExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
expressionsInfos[nameWithNamespace] = ExpressionMetadata(GetNameSpace(),
gd::String nameWithNamespace = GetNameSpace() + name;
expressionsInfos[nameWithNamespace] = ExpressionMetadata("number",
GetNameSpace(),
nameWithNamespace,
fullname,
description,
@@ -104,9 +105,9 @@ gd::ExpressionMetadata& PlatformExtension::AddStrExpression(
const gd::String& group,
const gd::String& smallicon) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
strExpressionsInfos[nameWithNamespace] = ExpressionMetadata(GetNameSpace(),
gd::String nameWithNamespace = GetNameSpace() + name;
strExpressionsInfos[nameWithNamespace] = ExpressionMetadata("string",
GetNameSpace(),
nameWithNamespace,
fullname,
description,
@@ -117,14 +118,108 @@ gd::ExpressionMetadata& PlatformExtension::AddStrExpression(
#endif
}
gd::MultipleInstructionMetadata PlatformExtension::AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition = AddCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndCondition(expression,
condition);
}
gd::MultipleInstructionMetadata
PlatformExtension::AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& descriptionSubject,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon) {
gd::String expressionDescriptionTemplate = _("Return <subject>.");
auto& expression =
type == "number"
? AddExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon)
: AddStrExpression(name,
fullname,
expressionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
group,
icon);
gd::String conditionDescriptionTemplate = _("Compare <subject>.");
auto& condition = AddCondition(name,
fullname,
conditionDescriptionTemplate.FindAndReplace(
"<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
// TODO: update the checks
gd::String actionDescriptionTemplate = _("Change <subject>.");
auto& action = AddAction(
"Set" + name,
fullname,
actionDescriptionTemplate.FindAndReplace("<subject>", descriptionSubject),
sentenceName,
group,
icon,
icon);
return MultipleInstructionMetadata::WithExpressionAndConditionAndAction(
expression, condition, action);
}
#if defined(GD_IDE_ONLY)
gd::DependencyMetadata& PlatformExtension::AddDependency() {
extensionDependenciesMetadata.push_back(DependencyMetadata());
return extensionDependenciesMetadata.back();
}
#endif
gd::ObjectMetadata& PlatformExtension::AddObject(
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& icon24x24,
std::shared_ptr<gd::Object> instance) {
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
gd::String nameWithNamespace = GetNameSpace() + name;
objectsInfos[nameWithNamespace] = ObjectMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
@@ -146,8 +241,7 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
const gd::String& className,
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance) {
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
gd::String nameWithNamespace = GetNameSpace() + name;
behaviorsInfo[nameWithNamespace] = BehaviorMetadata(GetNameSpace(),
nameWithNamespace,
fullname,
@@ -163,8 +257,7 @@ gd::BehaviorMetadata& PlatformExtension::AddBehavior(
}
gd::EffectMetadata& PlatformExtension::AddEffect(const gd::String& name) {
gd::String nameWithNamespace =
GetNameSpace().empty() ? name : GetNameSpace() + name;
gd::String nameWithNamespace = GetNameSpace() + name;
effectsMetadata[nameWithNamespace] = EffectMetadata(nameWithNamespace);
return effectsMetadata[nameWithNamespace];
}
@@ -177,8 +270,7 @@ gd::EventMetadata& PlatformExtension::AddEvent(
const gd::String& smallicon_,
std::shared_ptr<gd::BaseEvent> instance_) {
#if defined(GD_IDE_ONLY)
gd::String nameWithNamespace =
GetNameSpace().empty() ? name_ : GetNameSpace() + name_;
gd::String nameWithNamespace = GetNameSpace() + name_;
eventsInfos[nameWithNamespace] = gd::EventMetadata(nameWithNamespace,
fullname_,
description_,
@@ -216,8 +308,7 @@ std::vector<gd::String> PlatformExtension::GetExtensionObjectsTypes() const {
std::vector<gd::String> PlatformExtension::GetExtensionEffectTypes() const {
std::vector<gd::String> effectNames;
for (auto& it : effectsMetadata)
effectNames.push_back(it.first);
for (auto& it : effectsMetadata) effectNames.push_back(it.first);
return effectNames;
}
@@ -263,6 +354,73 @@ std::vector<gd::String> PlatformExtension::GetBehaviorsTypes() const {
}
#if defined(GD_IDE_ONLY)
gd::InstructionMetadata& PlatformExtension::AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName) {
gd::String newNameWithNamespace = GetNameSpace() + newActionName;
gd::String copiedNameWithNamespace = GetNameSpace() + copiedActionName;
auto copiedAction = actionsInfos.find(copiedNameWithNamespace);
if (copiedAction == actionsInfos.end()) {
gd::LogWarning("Could not find an action with name " +
copiedNameWithNamespace + " to copy.");
} else {
actionsInfos[newNameWithNamespace] = copiedAction->second;
}
return actionsInfos[newNameWithNamespace];
}
gd::InstructionMetadata& PlatformExtension::AddDuplicatedCondition(
const gd::String& newConditionName, const gd::String& copiedConditionName) {
gd::String newNameWithNamespace = GetNameSpace() + newConditionName;
gd::String copiedNameWithNamespace = GetNameSpace() + copiedConditionName;
auto copiedCondition = conditionsInfos.find(copiedNameWithNamespace);
if (copiedCondition == conditionsInfos.end()) {
gd::LogWarning("Could not find a condition with name " +
copiedNameWithNamespace + " to copy.");
} else {
conditionsInfos[newNameWithNamespace] = copiedCondition->second;
}
return conditionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& PlatformExtension::AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = GetNameSpace() + newExpressionName;
gd::String copiedNameWithNamespace = GetNameSpace() + copiedExpressionName;
auto copiedExpression = expressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == expressionsInfos.end()) {
gd::LogWarning("Could not find an expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
expressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return expressionsInfos[newNameWithNamespace];
}
gd::ExpressionMetadata& PlatformExtension::AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName) {
gd::String newNameWithNamespace = GetNameSpace() + newExpressionName;
gd::String copiedNameWithNamespace = GetNameSpace() + copiedExpressionName;
auto copiedExpression = strExpressionsInfos.find(copiedNameWithNamespace);
if (copiedExpression == strExpressionsInfos.end()) {
gd::LogWarning("Could not find a string expression with name " +
copiedNameWithNamespace + " to copy.");
} else {
strExpressionsInfos[newNameWithNamespace] = copiedExpression->second;
}
return strExpressionsInfos[newNameWithNamespace];
}
std::map<gd::String, gd::InstructionMetadata>&
PlatformExtension::GetAllActions() {
return actionsInfos;
@@ -283,6 +441,10 @@ PlatformExtension::GetAllStrExpressions() {
return strExpressionsInfos;
}
std::vector<gd::DependencyMetadata>& PlatformExtension::GetAllDependencies() {
return extensionDependenciesMetadata;
}
std::map<gd::String, gd::EventMetadata>& PlatformExtension::GetAllEvents() {
return eventsInfos;
}
@@ -315,7 +477,7 @@ PlatformExtension::GetAllStrExpressionsForObject(gd::String objectType) {
if (objectsInfos.find(objectType) != objectsInfos.end())
return objectsInfos.find(objectType)->second.strExpressionsInfos;
return badStrExpressionsMetadata;
return badExpressionsMetadata;
}
std::map<gd::String, gd::InstructionMetadata>&
@@ -347,7 +509,7 @@ PlatformExtension::GetAllStrExpressionsForBehavior(gd::String autoType) {
if (behaviorsInfo.find(autoType) != behaviorsInfo.end())
return behaviorsInfo.find(autoType)->second.strExpressionsInfos;
return badStrExpressionsMetadata;
return badExpressionsMetadata;
}
gd::BaseEventSPtr PlatformExtension::CreateEvent(gd::String eventType) const {
@@ -404,7 +566,7 @@ void PlatformExtension::SetNameSpace(gd::String nameSpace_) {
name == "BuiltinCommonConversions" ||
name == "BuiltinStringInstructions" ||
name == "BuiltinMathematicalTools" ||
name == "Effects" || // Well-known effects are not namespaced.
name == "Effects" || // Well-known effects are not namespaced.
name == "CommonDialogs") // New name for BuiltinInterface
{
nameSpace = "";

View File

@@ -10,21 +10,26 @@
#include <map>
#include <memory>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Extensions/Metadata/EventMetadata.h"
#include "GDCore/Extensions/Metadata/ObjectMetadata.h"
#include "GDCore/Extensions/Metadata/EffectMetadata.h"
#include "GDCore/Project/PropertyDescriptor.h"
#include "GDCore/String.h"
#include "GDCore/Tools/VersionPriv.h"
namespace gd {
class Instruction;
class InstructionMetadata;
class MultipleInstructionMetadata;
class ExpressionMetadata;
class ObjectMetadata;
class BehaviorMetadata;
class EffectMetadata;
class DependencyMetadata;
class BaseEvent;
class EventMetadata;
class EventCodeGenerator;
@@ -78,6 +83,11 @@ class GD_CORE_API PlatformExtension {
PlatformExtension();
virtual ~PlatformExtension();
/** \name Extension setup
* Common setup for all extensions
*/
///@{
/**
* \brief Must be called to declare the main information about the extension.
*/
@@ -88,8 +98,16 @@ class GD_CORE_API PlatformExtension {
const gd::String& license_);
/**
* \brief Set the path to the help, relative to the wiki/documentation root.
* For example, "/all-features/collisions" for
* \brief Set the URL of the extension icon.
*/
PlatformExtension& SetIconUrl(const gd::String& iconUrl_) {
iconUrl = iconUrl_;
return *this;
}
/**
* \brief Set the path to the help, relative to the GDevelop documentation
* root. For example, "/all-features/collisions" for
* "http://wiki.compilgames.net/doku.php/gdevelop5/all-features/collisions".
*
* The instructions, objects and behaviors will have this help path set by
@@ -106,9 +124,15 @@ class GD_CORE_API PlatformExtension {
*/
void MarkAsDeprecated() { deprecated = true; }
///@}
/** \name Features declaration
* Declare features provided by the extension
*/
///@{
/**
* \brief Declare a new condition as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::InstructionMetadata& AddCondition(const gd::String& name_,
const gd::String& fullname_,
@@ -120,7 +144,6 @@ class GD_CORE_API PlatformExtension {
/**
* \brief Declare a new action as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::InstructionMetadata& AddAction(const gd::String& name_,
const gd::String& fullname_,
@@ -131,7 +154,6 @@ class GD_CORE_API PlatformExtension {
const gd::String& smallicon_);
/**
* \brief Declare a new expression as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::ExpressionMetadata& AddExpression(const gd::String& name_,
const gd::String& fullname_,
@@ -139,8 +161,7 @@ class GD_CORE_API PlatformExtension {
const gd::String& group_,
const gd::String& smallicon_);
/**
* \brief Declare a new String expression as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
* \brief Declare a new string expression as being part of the extension.
*/
gd::ExpressionMetadata& AddStrExpression(const gd::String& name_,
const gd::String& fullname_,
@@ -148,53 +169,79 @@ class GD_CORE_API PlatformExtension {
const gd::String& group_,
const gd::String& smallicon_);
/**
* \brief Declare a new expression and condition as being part of the
* extension.
* \note It's recommended to use this function to avoid declaring twice a
* similar expression/condition.
*/
gd::MultipleInstructionMetadata AddExpressionAndCondition(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
/**
* \brief Declare a new expression, condition and action as being part of the
* extension.
* \note The action name is prefixed by "Set" (and the namespace, as the
* condition and the expression).
* \note It's recommended to use this function to avoid declaring 3 times a
* similar expression/condition/action.
*/
gd::MultipleInstructionMetadata AddExpressionAndConditionAndAction(
const gd::String& type,
const gd::String& name,
const gd::String& fullname,
const gd::String& description,
const gd::String& sentenceName,
const gd::String& group,
const gd::String& icon);
gd::DependencyMetadata& AddDependency();
/**
* \brief Declare a new object as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
* \tparam T the declared class inherited from *gd::Object*
* \param name The name of the object
* \param fullname The user friendly name of the object
* \param description The user friendly description of the object
* \param icon The 24x24 icon of the object:
res/icons_[SkinName]/[iconName]24.png will be first tried,
* and then if it does not exists, the full entered name will be tried.
* \param name The name of the object.
* \param fullname The user friendly name of the object.
* \param description The user friendly description of the object.
* \param icon The icon of the object.
*/
template <class T>
gd::ObjectMetadata& AddObject(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_);
const gd::String& icon_);
/**
* \brief Declare a new object as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
* \param name The name of the object
* \param fullname The user friendly name of the object
* \param description The user friendly description of the object
* \param icon The 24x24 icon of the object:
res/icons_[SkinName]/[iconName]24.png will be first tried,
* and then if it does not exists, the full entered name will be tried.
* \param icon The icon of the object.
* \param instance The "blueprint" object to be copied when a new object is
asked for.
*/
gd::ObjectMetadata& AddObject(const gd::String& name_,
const gd::String& fullname_,
const gd::String& description_,
const gd::String& icon24x24_,
const gd::String& icon_,
std::shared_ptr<gd::Object> instance);
/**
* \brief Declare a new behavior as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*
* \param name The name of the behavior
* \param fullname The user friendly name of the behavior
* \param description The user friendly description of the behavior
* \param icon The 24x24 icon of the behavior:
* res/icons_[SkinName]/[iconName]24.png will be first tried, and then if it
* does not exists, it is assumed that the icon name is the filename that must
* be used to open the icon. \param instance An instance of the behavior that
* will be used to create the behavior \param sharedDatasInstance Optional
* \param icon The icon of the behavior.
* \param instance An instance of the behavior that
* will be used to create the behavior
* \param sharedDatasInstance Optional
* instance of the data shared by the behaviors having the same name.
*/
gd::BehaviorMetadata& AddBehavior(
@@ -203,7 +250,7 @@ class GD_CORE_API PlatformExtension {
const gd::String& defaultName_,
const gd::String& description_,
const gd::String& group_,
const gd::String& icon24x24_,
const gd::String& icon_,
const gd::String& className_,
std::shared_ptr<gd::Behavior> instance,
std::shared_ptr<gd::BehaviorsSharedData> sharedDatasInstance);
@@ -216,7 +263,6 @@ class GD_CORE_API PlatformExtension {
/**
* \brief Declare a new event as being part of the extension.
* \note This method does nothing when used for GD C++ runtime.
*/
gd::EventMetadata& AddEvent(const gd::String& name_,
const gd::String& fullname_,
@@ -225,6 +271,64 @@ class GD_CORE_API PlatformExtension {
const gd::String& smallicon_,
std::shared_ptr<gd::BaseEvent> instance);
#if defined(GD_IDE_ONLY)
/**
* \brief Create a new action which is the duplicate of the specified one.
*
* Useful for handling a deprecated action that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedAction(
const gd::String& newActionName, const gd::String& copiedActionName);
/**
* \brief Create a new condition which is the duplicate of the specified one.
*
* Useful for handling a deprecated condition that is just a "copy" of the new
* one.
*/
gd::InstructionMetadata& AddDuplicatedCondition(
const gd::String& newConditionName,
const gd::String& copiedConditionName);
/**
* \brief Create a new expression which is the duplicate of the specified one.
*
* Useful for handling a deprecated expression that is just a "copy" of the
* new one.
*/
gd::ExpressionMetadata& AddDuplicatedExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
/**
* \brief Create a new string expression which is the duplicate of the
* specified one.
*
* Useful for handling a deprecated string expression that is just a "copy" of
* the new one.
*/
gd::ExpressionMetadata& AddDuplicatedStrExpression(
const gd::String& newExpressionName,
const gd::String& copiedExpressionName);
/**
* \brief Adds a property to the extension.
*/
gd::PropertyDescriptor& RegisterProperty(const gd::String& name) {
return extensionPropertiesMetadata[name];
};
#endif
/**
* \brief Delete all instructions having no function name or custom code
* generator.
*/
void StripUnimplementedInstructionsAndExpressions();
///@}
/** \name Extension accessors
* Accessors to read the information and content of the extension.
*/
///@{
/**
* \brief Return the name extension user friendly name.
*/
@@ -252,10 +356,16 @@ class GD_CORE_API PlatformExtension {
/**
* \brief Return the help path of extension, relative to the
* wiki/documentation root.
* GDevelop documentation root.
*/
const gd::String& GetHelpPath() const { return helpPath; }
/**
* \brief Return the URL to the icon to be displayed for this
* extension.
*/
const gd::String& GetIconUrl() const { return iconUrl; }
/**
* \brief Check if the extension is flagged as being deprecated.
*/
@@ -344,9 +454,8 @@ class GD_CORE_API PlatformExtension {
#if defined(GD_IDE_ONLY)
/**
* \brief Return a reference to a map containing the names of the actions (in
* the first members) and the metadata associated with (in the second
* members).
* \brief Return a reference to a map containing the names of the actions
* (as keys) and the metadata associated with (as values).
*/
std::map<gd::String, gd::InstructionMetadata>& GetAllActions();
@@ -365,6 +474,12 @@ class GD_CORE_API PlatformExtension {
*/
std::map<gd::String, gd::ExpressionMetadata>& GetAllStrExpressions();
/**
* \brief Return a reference to a vector containing the metadata of all the
* dependencies of the extension.
*/
std::vector<gd::DependencyMetadata>& GetAllDependencies();
/**
* \brief Return a reference to a map containing the names of the actions,
* related to the object type, and the metadata associated with.
@@ -415,8 +530,8 @@ class GD_CORE_API PlatformExtension {
gd::String autoType);
/**
* Called ( e.g. during compilation ) so as to inventory resources used by
* conditions and update their filename
* Called to inventory resources used by conditions
* (and possibly do work on them, like renaming, etc...)
*
* \see gd::PlatformExtension::ExposeActionsResources
*/
@@ -424,8 +539,8 @@ class GD_CORE_API PlatformExtension {
gd::ArbitraryResourceWorker& worker){};
/**
* Called ( e.g. during compilation ) so as to inventory resources used by
* actions and update their filename
* Called to inventory resources used by actions
* (and possibly do work on them, like renaming, etc...)
*
* \see ArbitraryResourceWorker
*/
@@ -433,10 +548,14 @@ class GD_CORE_API PlatformExtension {
gd::ArbitraryResourceWorker& worker){};
/**
* \brief Delete all instructions having no functions name or custom code
* generator.
* \brief Get all the properties of the extension. Properties
* are shown in the game properties in the editor, and are exported in the
* project data.
*/
void StripUnimplementedInstructionsAndExpressions();
std::map<gd::String, gd::PropertyDescriptor>& GetAllProperties() {
return extensionPropertiesMetadata;
}
///@}
#endif
/**
@@ -453,8 +572,8 @@ class GD_CORE_API PlatformExtension {
private:
/**
* Set the namespace ( the String each actions/conditions/expressions start
* with )
* Set the namespace (the string all actions/conditions/expressions start
* with).
*/
void SetNameSpace(gd::String nameSpace_);
@@ -463,14 +582,15 @@ class GD_CORE_API PlatformExtension {
nameSpace; ///< Automatically set from the name of the extension, and
///< added to every
///< actions/conditions/expressions/objects/behavior/event.
gd::String fullname; ///< Name displayed to users at edittime
gd::String informations; ///< Description displayed to users at edittime
gd::String author; ///< Author displayed to users at edittime
gd::String license; ///< License name displayed to users at edittime
gd::String fullname; ///< Name displayed to users in the editor.
gd::String informations; ///< Description displayed to users in the editor.
gd::String author; ///< Author displayed to users in the editor.
gd::String license; ///< License name displayed to users in the editor.
bool deprecated; ///< true if the extension is deprecated and shouldn't be
///< shown in IDE.
gd::String helpPath; ///< The relative path to the help for this extension in
///< the documentation.
gd::String iconUrl; ///< The URL to the icon to be shown for this extension.
std::map<gd::String, gd::ObjectMetadata> objectsInfos;
std::map<gd::String, gd::BehaviorMetadata> behaviorsInfo;
@@ -480,7 +600,9 @@ class GD_CORE_API PlatformExtension {
std::map<gd::String, gd::InstructionMetadata> actionsInfos;
std::map<gd::String, gd::ExpressionMetadata> expressionsInfos;
std::map<gd::String, gd::ExpressionMetadata> strExpressionsInfos;
std::vector<gd::DependencyMetadata> extensionDependenciesMetadata;
std::map<gd::String, gd::EventMetadata> eventsInfos;
std::map<gd::String, gd::PropertyDescriptor> extensionPropertiesMetadata;
#endif
ObjectMetadata badObjectMetadata;
@@ -496,9 +618,6 @@ class GD_CORE_API PlatformExtension {
static std::map<gd::String, gd::ExpressionMetadata>
badExpressionsMetadata; ///< Used when an expression is not found in the
///< extension
static std::map<gd::String, gd::ExpressionMetadata>
badStrExpressionsMetadata; ///< Used when an expression is not found in
///< the extension
#endif
};

View File

@@ -17,6 +17,7 @@ LayoutEditorCanvasOptions::LayoutEditorCanvasOptions()
gridHeight(32),
gridOffsetX(0),
gridOffsetY(0),
gridType("rectangular"),
gridR(158),
gridG(180),
gridB(255),
@@ -30,6 +31,7 @@ void LayoutEditorCanvasOptions::SerializeTo(SerializerElement& element) const {
element.SetAttribute("gridHeight", gridHeight);
element.SetAttribute("gridOffsetX", gridOffsetX);
element.SetAttribute("gridOffsetY", gridOffsetY);
element.SetAttribute("gridType", gridType);
element.SetAttribute("gridR", gridR);
element.SetAttribute("gridG", gridG);
element.SetAttribute("gridB", gridB);
@@ -42,10 +44,11 @@ void LayoutEditorCanvasOptions::UnserializeFrom(
grid = element.GetBoolAttribute("grid");
snap = element.GetBoolAttribute("snap");
windowMask = element.GetBoolAttribute("windowMask");
gridWidth = element.GetIntAttribute("gridWidth", 32);
gridHeight = element.GetIntAttribute("gridHeight", 32);
gridOffsetX = element.GetIntAttribute("gridOffsetX", 0);
gridOffsetY = element.GetIntAttribute("gridOffsetY", 0);
gridWidth = element.GetDoubleAttribute("gridWidth", 32);
gridHeight = element.GetDoubleAttribute("gridHeight", 32);
gridOffsetX = element.GetDoubleAttribute("gridOffsetX", 0);
gridOffsetY = element.GetDoubleAttribute("gridOffsetY", 0);
gridType = element.GetStringAttribute("gridType", "rectangular");
gridR = element.GetIntAttribute("gridR", 158);
gridG = element.GetIntAttribute("gridG", 180);
gridB = element.GetIntAttribute("gridB", 255);

View File

@@ -40,14 +40,15 @@ class GD_CORE_API LayoutEditorCanvasOptions {
bool grid; ///< True if grid activated in editor
bool snap; ///< True if snap to grid activated in editor
int gridWidth; ///< Grid width in editor
int gridHeight; ///< Grid height in editor
int gridOffsetX; ///< Grid X offset
int gridOffsetY; ///< Grid Y offset
double gridWidth; ///< Grid width in editor
double gridHeight; ///< Grid height in editor
double gridOffsetX; ///< Grid X offset
double gridOffsetY; ///< Grid Y offset
gd::String gridType; ///< Grid type: rectangular or isometric
int gridR; ///< Grid red color in editor
int gridG; ///< Grid green color in editor
int gridB; ///< Grid blue color in editor
float zoomFactor; ///< Stores the zoom factor
double zoomFactor; ///< Stores the zoom factor
bool windowMask; ///< True if window mask displayed in editor
};

View File

@@ -279,6 +279,43 @@ bool EventsRefactorer::RenameObjectInConditions(
return somethingModified;
}
bool EventsRefactorer::RenameObjectInEventParameters(
const gd::Platform& platform,
gd::ObjectsContainer& project,
gd::ObjectsContainer& layout,
gd::Expression& expression,
gd::ParameterMetadata parameterMetadata,
gd::String oldName,
gd::String newName) {
bool somethingModified = false;
if (gd::ParameterMetadata::IsObject(parameterMetadata.GetType()) &&
expression.GetPlainString() == oldName)
expression = gd::Expression(newName);
// Replace object's name in expressions
else if (ParameterMetadata::IsExpression(
"number", parameterMetadata.GetType())) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("number", expression.GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
}
}
// Replace object's name in text expressions
else if (ParameterMetadata::IsExpression(
"string", parameterMetadata.GetType())) {
gd::ExpressionParser2 parser(platform, project, layout);
auto node = parser.ParseExpression("string", expression.GetPlainString());
if (ExpressionObjectRenamer::Rename(*node, oldName, newName)) {
expression = ExpressionParser2NodePrinter::PrintNode(*node);
}
}
return somethingModified;
}
void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
gd::ObjectsContainer& project,
gd::ObjectsContainer& layout,
@@ -300,6 +337,15 @@ void EventsRefactorer::RenameObjectInEvents(const gd::Platform& platform,
platform, project, layout, *actionsVectors[j], oldName, newName);
}
vector<pair<gd::Expression*, gd::ParameterMetadata>> expressionsWithMetadata =
events[i].GetAllExpressionsWithMetadata();
for (std::size_t j = 0; j < expressionsWithMetadata.size(); ++j) {
gd::Expression* expression = expressionsWithMetadata[j].first;
gd::ParameterMetadata parameterMetadata = expressionsWithMetadata[j].second;
bool somethingModified = RenameObjectInEventParameters(
platform, project, layout, *expression, parameterMetadata, oldName, newName);
}
if (events[i].CanHaveSubEvents())
RenameObjectInEvents(platform,
project,

View File

@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
#include "GDCore/Events/Instruction.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/String.h"
namespace gd {
class EventsList;
@@ -146,6 +147,20 @@ class GD_CORE_API EventsRefactorer {
gd::InstructionsList& instructions,
gd::String oldName,
gd::String newName);
/**
* Replace all occurrences of an object name by another name in an expression
* with the specified metadata
* ( include : objects or objects in math/text expressions ).
*
* \return true if something was modified.
*/
static bool RenameObjectInEventParameters(const gd::Platform& platform,
gd::ObjectsContainer& project,
gd::ObjectsContainer& layout,
gd::Expression& expression,
gd::ParameterMetadata parameterMetadata,
gd::String oldName,
gd::String newName);
/**
* Remove all conditions of the list using an object

View File

@@ -49,9 +49,15 @@ InstructionSentenceFormatter::GetAsFormattedText(
gd::String sentence = metadata.GetSentence();
std::replace(sentence.Raw().begin(), sentence.Raw().end(), '\n', ' ');
bool parse = true;
size_t loopCount = 0;
bool parse = true;
while (parse) {
if (loopCount > 40) {
break;
}
loopCount++;
// Search first parameter
parse = false;
size_t firstParamPosition = gd::String::npos;
@@ -130,7 +136,7 @@ gd::String InstructionSentenceFormatter::LabelFromType(const gd::String &type) {
else if (type == "mouse")
return _("Mouse button");
else if (type == "yesorno")
return _("Yes or no");
return _("Yes or No");
else if (type == "police")
return _("Font");
else if (type == "color")

View File

@@ -0,0 +1,144 @@
#include "UsedExtensionsFinder.h"
#include "GDCore/Events/Instruction.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/WholeProjectRefactorer.h"
#include "GDCore/Project/BehaviorContent.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
namespace gd {
std::set<gd::String> UsedExtensionsFinder::ScanProject(gd::Project& project) {
UsedExtensionsFinder worker(project);
gd::WholeProjectRefactorer::ExposeProjectObjects(project, worker);
gd::WholeProjectRefactorer::ExposeProjectEvents(project, worker);
return worker.usedExtensions;
};
// Objects scanner
void UsedExtensionsFinder::DoVisitObject(gd::Object& object) {
usedExtensions.insert(gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), object.GetType())
.GetExtension()
.GetName());
};
// Behaviors scanner
void UsedExtensionsFinder::DoVisitBehavior(gd::BehaviorContent& behavior) {
usedExtensions.insert(
gd::MetadataProvider::GetExtensionAndBehaviorMetadata(
project.GetCurrentPlatform(), behavior.GetTypeName())
.GetExtension()
.GetName());
};
// Instructions scanner
bool UsedExtensionsFinder::DoVisitInstruction(gd::Instruction& instruction,
bool isCondition) {
auto metadata =
isCondition ? gd::MetadataProvider::GetExtensionAndConditionMetadata(
project.GetCurrentPlatform(), instruction.GetType())
: gd::MetadataProvider::GetExtensionAndActionMetadata(
project.GetCurrentPlatform(), instruction.GetType());
usedExtensions.insert(metadata.GetExtension().GetName());
size_t i = 0;
for (auto expression : instruction.GetParameters()) {
const gd::String& parameterType =
metadata.GetMetadata().GetParameter(i).GetType();
i++;
if (gd::ParameterMetadata::IsExpression("string", parameterType) ||
gd::ParameterMetadata::IsExpression("number", parameterType)) {
gd::ExpressionParser2 parser(project.GetCurrentPlatform(),
GetGlobalObjectsContainer(),
GetObjectsContainer());
parser.ParseExpression(parameterType, expression.GetPlainString())
->Visit(*this);
} else if (gd::ParameterMetadata::IsExpression("variable", parameterType))
usedExtensions.insert("BuiltinVariables");
}
return false;
}
// Expressions scanner
// Ignore litterals nodes
void UsedExtensionsFinder::OnVisitNumberNode(NumberNode& node){};
void UsedExtensionsFinder::OnVisitTextNode(TextNode& node){};
// Ignore nodes without valid extensions
void UsedExtensionsFinder::OnVisitEmptyNode(EmptyNode& node){};
void UsedExtensionsFinder::OnVisitObjectFunctionNameNode(
ObjectFunctionNameNode& node){};
// Visit sub-expressions
void UsedExtensionsFinder::OnVisitSubExpressionNode(SubExpressionNode& node) {
node.expression->Visit(*this);
};
void UsedExtensionsFinder::OnVisitOperatorNode(OperatorNode& node) {
node.leftHandSide->Visit(*this);
node.rightHandSide->Visit(*this);
};
void UsedExtensionsFinder::OnVisitUnaryOperatorNode(UnaryOperatorNode& node) {
node.factor->Visit(*this);
};
// Add variable extension and visit sub-expressions on variable nodes
void UsedExtensionsFinder::OnVisitVariableNode(VariableNode& node) {
usedExtensions.insert("BuiltinVariables");
if (node.child) node.child->Visit(*this);
};
void UsedExtensionsFinder::OnVisitVariableAccessorNode(
VariableAccessorNode& node) {
usedExtensions.insert("BuiltinVariables");
if (node.child) node.child->Visit(*this);
};
void UsedExtensionsFinder::OnVisitVariableBracketAccessorNode(
VariableBracketAccessorNode& node) {
usedExtensions.insert("BuiltinVariables");
node.expression->Visit(*this);
if (node.child) node.child->Visit(*this);
};
// Add extensions bound to Objects/Behaviors/Functions
void UsedExtensionsFinder::OnVisitIdentifierNode(IdentifierNode& node) {
if (gd::ParameterMetadata::IsObject(node.type)) {
usedExtensions.insert(gd::MetadataProvider::GetExtensionAndObjectMetadata(
project.GetCurrentPlatform(), node.identifierName)
.GetExtension()
.GetName());
}
};
void UsedExtensionsFinder::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;
}
usedExtensions.insert(metadata.GetExtension().GetName());
};
} // namespace gd

View File

@@ -0,0 +1,64 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef GDCORE_USED_EXTENSIONS_FINDER_H
#define GDCORE_USED_EXTENSIONS_FINDER_H
#include <set>
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/String.h"
namespace gd {
class Project;
class Object;
class BehaviorContent;
} // namespace gd
namespace gd {
class GD_CORE_API UsedExtensionsFinder
: public ArbitraryObjectsWorker,
public ArbitraryEventsWorkerWithContext,
public ExpressionParser2NodeWorker {
public:
static std::set<gd::String> ScanProject(gd::Project& project);
private:
UsedExtensionsFinder(gd::Project& project_) : project(project_){};
gd::Project& project;
std::set<gd::String> usedExtensions;
// Object Visitor
void DoVisitObject(gd::Object& object) override;
// Behavior Visitor
void DoVisitBehavior(gd::BehaviorContent& 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
#endif

View File

@@ -0,0 +1,124 @@
#pragma once
#include <vector>
#include "GDCore/Extensions/Metadata/DependencyMetadata.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Project.h"
namespace gd {
/**
* \brief Store references to a gd::DependencyMetadata and its associated
* gd::PlatformExtension.
*
* \note Both objects must be kept alive, as this is keeping a pointer to them.
*/
struct DependencyMetadataAndExtension {
DependencyMetadataAndExtension(gd::DependencyMetadata& dependency_,
gd::PlatformExtension& extension_)
: dependency(&dependency_), extension(&extension_){};
gd::DependencyMetadata& GetDependency() const { return *dependency; };
gd::PlatformExtension& GetExtension() const { return *extension; };
private:
gd::DependencyMetadata* dependency;
gd::PlatformExtension* extension;
};
/**
* \brief Helpers to manipulate dependencies of extensions to be exported along
* with a game.
*/
class ExportedDependencyResolver {
public:
/**
* \brief Return the list of dependencies to be exported for the given project
* and dependency type.
*
* Not all dependencies declared by extensions must be exported: some are only
* exported when some settings are filled. Then, some others are only exported
* when some other dependencies are exported (this won't work for more than
* one level though).
*/
static std::vector<DependencyMetadataAndExtension> GetDependenciesFor(
const gd::Project& project, const gd::String& dependencyType) {
std::vector<DependencyMetadataAndExtension> dependenciesWithProperType;
for (std::shared_ptr<gd::PlatformExtension> extension :
project.GetCurrentPlatform().GetAllPlatformExtensions()) {
for (gd::DependencyMetadata& dependency :
extension->GetAllDependencies()) {
if (dependency.GetDependencyType() == dependencyType) {
DependencyMetadataAndExtension dependencyMetadataAndExtension(
dependency, *extension);
dependenciesWithProperType.push_back(dependencyMetadataAndExtension);
}
}
}
// Keep only the dependencies that have their extra settings filled
// and those that don't require extra settings to be filled.
std::vector<DependencyMetadataAndExtension> dependenciesWithFilledSettings;
for (auto dependencyAndExtension : dependenciesWithProperType) {
auto& dependency = dependencyAndExtension.GetDependency();
auto extraSettingValues = GetExtensionDependencyExtraSettingValues(
project, dependencyAndExtension);
bool hasExtraSettings = !extraSettingValues.empty();
if (!dependency.IsOnlyIfSomeExtraSettingsNonEmpty() || hasExtraSettings)
dependenciesWithFilledSettings.push_back(dependencyAndExtension);
}
// Keep only the dependency that depends on another dependencies that is
// exported (or dependencies that don't require another dependency).
std::vector<DependencyMetadataAndExtension> exportedDependencies;
for (auto dependencyAndExtension : dependenciesWithFilledSettings) {
auto& dependency = dependencyAndExtension.GetDependency();
auto& otherDependencyName =
dependency.GetOtherDependencyThatMustBeExported();
if (otherDependencyName.empty() ||
std::find_if(
dependenciesWithFilledSettings.begin(),
dependenciesWithFilledSettings.end(),
[&otherDependencyName](
DependencyMetadataAndExtension& otherDependencyAndExtension) {
return otherDependencyAndExtension.GetDependency().GetName() ==
otherDependencyName;
}) != dependenciesWithFilledSettings.end()) {
exportedDependencies.push_back(dependencyAndExtension);
}
}
return exportedDependencies;
}
/**
* \brief Return the values that were stored in the project for the given
* dependency.
*/
static std::map<gd::String, gd::String>
GetExtensionDependencyExtraSettingValues(
const gd::Project& project,
const gd::DependencyMetadataAndExtension& dependencyAndExtension) {
std::map<gd::String, gd::String> values;
auto& dependency = dependencyAndExtension.GetDependency();
const gd::String& extensionName =
dependencyAndExtension.GetExtension().GetName();
for (const auto& extraSetting : dependency.GetAllExtraSettings()) {
const gd::String& type = extraSetting.second.GetType();
const gd::String extraSettingValue =
type == "ExtensionProperty"
? project.GetExtensionProperties().GetValue(
extensionName, extraSetting.second.GetValue())
: extraSetting.second.GetValue();
if (!extraSettingValue.empty())
values[extraSetting.first] = extraSettingValue;
}
return values;
};
};
} // namespace gd

View File

@@ -0,0 +1,43 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ArbitraryObjectsWorker.h"
#include <iostream>
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Project/BehaviorContent.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/ObjectsContainer.h"
#include "GDCore/String.h"
using namespace std;
namespace gd {
ArbitraryObjectsWorker::~ArbitraryObjectsWorker() {}
void ArbitraryObjectsWorker::VisitObjectContainer(
gd::ObjectsContainer& objects) {
DoVisitObjectContainer(objects);
for (size_t i = 0; i < objects.GetObjectsCount(); i++)
VisitObject(objects.GetObject(i));
}
void ArbitraryObjectsWorker::VisitObject(gd::Object& object) {
DoVisitObject(object);
for (auto behaviorName : object.GetAllBehaviorNames())
VisitBehavior(object.GetBehavior(behaviorName));
}
void ArbitraryObjectsWorker::VisitBehavior(gd::BehaviorContent& behavior) {
DoVisitBehavior(behavior);
}
} // namespace gd

View File

@@ -0,0 +1,63 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#ifndef ARBITRARYOBJECTSWORKER_H
#define ARBITRARYOBJECTSWORKER_H
#include <map>
#include <memory>
#include <vector>
#include "GDCore/String.h"
namespace gd {
class Object;
class ObjectsContainer;
class BehaviorContent;
} // namespace gd
namespace gd {
/**
* \brief ArbitraryObjectsWorker is an abstract class used to browse objects
* (and behaviors) and do some work on them. Can be used to implement
* refactoring for example.
*
* \ingroup IDE
*/
class GD_CORE_API ArbitraryObjectsWorker {
public:
ArbitraryObjectsWorker(){};
virtual ~ArbitraryObjectsWorker();
/**
* \brief Launch the worker on the specified events list.
*/
void Launch(gd::ObjectsContainer& objects) { VisitObjectContainer(objects); };
private:
void VisitObjectContainer(gd::ObjectsContainer& objects);
void VisitObject(gd::Object& object);
void VisitBehavior(gd::BehaviorContent& instruction);
/**
* Called to do some work on an object container.
*/
virtual void DoVisitObjectContainer(gd::ObjectsContainer& objects){};
/**
* Called to do some work on an object.
*/
virtual void DoVisitObject(gd::Object& object){};
/**
* Called to do some work on a behavior.
*/
virtual void DoVisitBehavior(gd::BehaviorContent& instruction){};
};
} // namespace gd
#endif // ARBITRARYOBJECTSWORKER_H

View File

@@ -6,8 +6,10 @@
#if defined(GD_IDE_ONLY)
#include "ArbitraryResourceWorker.h"
#include <memory>
#include <vector>
#include "GDCore/Events/Event.h"
#include "GDCore/Events/EventsList.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
@@ -55,6 +57,21 @@ void ArbitraryResourceWorker::ExposeFont(gd::String& fontName) {
ExposeFile(fontName);
};
void ArbitraryResourceWorker::ExposeBitmapFont(gd::String& bitmapFontName) {
for (auto resources : GetResources()) {
if (!resources) continue;
if (resources->HasResource(bitmapFontName) &&
resources->GetResource(bitmapFontName).GetKind() == "bitmapFont") {
// Nothing to do, the font is a reference to a resource that
// is already exposed.
return;
}
}
ExposeFile(bitmapFontName);
};
void ArbitraryResourceWorker::ExposeResources(
gd::ResourcesManager* resourcesManager) {
if (!resourcesManager) return;
@@ -82,15 +99,8 @@ void LaunchResourceWorkerOnEvents(const gd::Project& project,
gd::EventsList& events,
gd::ArbitraryResourceWorker& worker) {
// Get all extensions used
std::vector<std::shared_ptr<gd::PlatformExtension> > allGameExtensions;
std::vector<gd::String> usedExtensions = project.GetUsedExtensions();
for (std::size_t i = 0; i < usedExtensions.size(); ++i) {
std::shared_ptr<gd::PlatformExtension> extension =
project.GetCurrentPlatform().GetExtension(usedExtensions[i]);
if (extension != std::shared_ptr<gd::PlatformExtension>())
allGameExtensions.push_back(extension);
}
auto allGameExtensions =
project.GetCurrentPlatform().GetAllPlatformExtensions();
for (std::size_t j = 0; j < events.size(); j++) {
vector<gd::InstructionsList*> allActionsVectors =

View File

@@ -70,6 +70,12 @@ class GD_CORE_API ArbitraryResourceWorker {
*/
virtual void ExposeFont(gd::String &fontName);
/**
* \brief Expose a bitmap font, which is either a reference to a "bitmapFont" resource,
* or a filename if no resource with this name exists.
*/
virtual void ExposeBitmapFont(gd::String &bitmapFontName);
/**
* \brief Expose a shader.
* \warn Currently unsupported.

View File

@@ -38,12 +38,15 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
std::set<gd::String>& GetAllImages() { return GetAll("image"); };
std::set<gd::String>& GetAllFonts() { return GetAll("font"); };
std::set<gd::String>& GetAllAudios() { return GetAll("audio"); };
std::set<gd::String>& GetAllBitmapFonts() { return GetAll("bitmapFont"); };
std::set<gd::String>& GetAll(const gd::String& resourceType) {
return resourceType == "image"
? allImages
: (resourceType == "audio"
? allAudios
: (resourceType == "font") ? allFonts : emptyResources);
: (resourceType == "font")
? allFonts
: (resourceType == "bitmapFont") ? allBitmapFonts : emptyResources);
};
virtual void ExposeFile(gd::String& resource) override{
@@ -58,11 +61,15 @@ class ResourcesInUseHelper : public gd::ArbitraryResourceWorker {
virtual void ExposeFont(gd::String& fontResourceName) override {
allFonts.insert(fontResourceName);
};
virtual void ExposeBitmapFont(gd::String& bitmapFontResourceName) override {
allBitmapFonts.insert(bitmapFontResourceName);
};
protected:
std::set<gd::String> allImages;
std::set<gd::String> allAudios;
std::set<gd::String> allFonts;
std::set<gd::String> allBitmapFonts;
std::set<gd::String> emptyResources;
};

View File

@@ -0,0 +1,61 @@
/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#ifndef GDCORE_RESOURCESRENAMER_H
#define GDCORE_RESOURCESRENAMER_H
#include <set>
#include <vector>
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
#include "GDCore/String.h"
namespace gd {
/**
* \brief Class used to rename resources (in an object, an entire project,
* etc...)
*
* \ingroup IDE
*/
class ResourcesRenamer : public gd::ArbitraryResourceWorker {
public:
/**
* @brief Constructor taking the map from old name to new name.
* @param oldToNewNames_ A map associating to a resource name the new name to
* use.
*/
ResourcesRenamer(const std::map<gd::String, gd::String>& oldToNewNames_)
: gd::ArbitraryResourceWorker(), oldToNewNames(oldToNewNames_){};
virtual ~ResourcesRenamer(){};
virtual void ExposeFile(gd::String& resourceName) override {
RenameIfNeeded(resourceName);
};
virtual void ExposeImage(gd::String& imageResourceName) override {
RenameIfNeeded(imageResourceName);
};
virtual void ExposeAudio(gd::String& audioResourceName) override {
RenameIfNeeded(audioResourceName);
};
virtual void ExposeFont(gd::String& fontResourceName) override {
RenameIfNeeded(fontResourceName);
};
private:
void RenameIfNeeded(gd::String& resourceName) {
if (oldToNewNames.find(resourceName) != oldToNewNames.end())
resourceName = oldToNewNames[resourceName];
}
std::map<gd::String, gd::String> oldToNewNames;
};
} // namespace gd
#endif // GDCORE_RESOURCESRENAMER_H
#endif

View File

@@ -4,6 +4,7 @@
* reserved. This project is released under the MIT License.
*/
#include "ProjectStripper.h"
#include "GDCore/Project/ExternalEvents.h"
#include "GDCore/Project/ExternalLayout.h"
#include "GDCore/Project/Layout.h"
@@ -20,61 +21,8 @@ void GD_CORE_API ProjectStripper::StripProjectForExport(gd::Project& project) {
project.GetLayout(i).GetObjectGroups().Clear();
project.GetLayout(i).GetEvents().Clear();
}
}
void GD_CORE_API ProjectStripper::StripProjectForLayoutEdition(
gd::Project& project, const gd::String& layoutName) {
while (project.GetExternalEventsCount() > 0)
project.RemoveExternalEvents(project.GetExternalEvents(0).GetName());
for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) {
auto& layout = project.GetLayout(i);
if (layoutName == layout.GetName()) continue;
project.GetLayout(i).GetEvents().Clear();
project.GetLayout(i).GetInitialInstances().Clear();
}
for (unsigned int i = 0; i < project.GetExternalEventsCount(); ++i) {
project.GetExternalEvents(i).GetEvents().Clear();
}
for (unsigned int i = 0; i < project.GetExternalLayoutsCount(); ++i) {
project.GetExternalLayout(i).GetInitialInstances().Clear();
}
}
void GD_CORE_API ProjectStripper::StripProjectForExternalLayoutEdition(
gd::Project& project, const gd::String& externalLayoutName) {
while (project.GetExternalEventsCount() > 0)
project.RemoveExternalEvents(project.GetExternalEvents(0).GetName());
gd::String associatedLayoutName;
if (project.HasExternalLayoutNamed(externalLayoutName)) {
associatedLayoutName =
project.GetExternalLayout(externalLayoutName).GetAssociatedLayout();
}
for (unsigned int i = 0; i < project.GetLayoutsCount(); ++i) {
auto& layout = project.GetLayout(i);
if (!associatedLayoutName.empty() &&
associatedLayoutName == layout.GetName())
continue;
project.GetLayout(i).GetEvents().Clear();
project.GetLayout(i).GetInitialInstances().Clear();
}
for (unsigned int i = 0; i < project.GetExternalEventsCount(); ++i) {
project.GetExternalEvents(i).GetEvents().Clear();
}
for (unsigned int i = 0; i < project.GetExternalLayoutsCount(); ++i) {
auto& externalLayout = project.GetExternalLayout(i);
if (externalLayoutName == externalLayout.GetName()) continue;
externalLayout.GetInitialInstances().Clear();
}
project.ClearEventsFunctionsExtensions();
}
} // namespace gd

View File

@@ -28,23 +28,6 @@ class GD_CORE_API ProjectStripper {
*/
static void StripProjectForExport(gd::Project& project);
/**
* \brief Strip project to keep only the full content of the specified
* layout. The content of other layouts, external events and external layouts
* is removed.
*/
static void StripProjectForLayoutEdition(gd::Project& project,
const gd::String& layoutName);
/**
* \brief Strip project to keep only the full content of the specified
* external layout and the associated layout.
* The content of other layouts, external events and external layouts is
* removed.
*/
static void StripProjectForExternalLayoutEdition(
gd::Project& project, const gd::String& externalLayoutName);
private:
ProjectStripper(){};
virtual ~ProjectStripper(){};

View File

@@ -4,15 +4,17 @@
* reserved. This project is released under the MIT License.
*/
#include "WholeProjectRefactorer.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/IDE/DependenciesAnalyzer.h"
#include "GDCore/IDE/Events/ArbitraryEventsWorker.h"
#include "GDCore/IDE/Events/EventsRefactorer.h"
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
#include "GDCore/IDE/Events/ExpressionsParameterMover.h"
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
#include "GDCore/IDE/Events/ExpressionsRenamer.h"
#include "GDCore/IDE/Events/InstructionsParameterMover.h"
#include "GDCore/IDE/Events/InstructionsTypeRenamer.h"
#include "GDCore/IDE/EventsFunctionTools.h"
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
#include "GDCore/Project/EventsBasedBehavior.h"
#include "GDCore/Project/EventsFunctionsExtension.h"
#include "GDCore/Project/ExternalEvents.h"
@@ -141,6 +143,13 @@ void WholeProjectRefactorer::ExposeProjectEvents(
}
}
void WholeProjectRefactorer::ExposeProjectObjects(
gd::Project& project, gd::ArbitraryObjectsWorker& worker) {
worker.Launch(project);
for (size_t i = 0; i < project.GetLayoutsCount(); i++)
worker.Launch(project.GetLayout(i));
};
std::set<gd::String>
WholeProjectRefactorer::GetAllObjectTypesUsingEventsBasedBehavior(
const gd::Project& project,

View File

@@ -16,6 +16,7 @@ class EventsFunction;
class ObjectsContainer;
class EventsBasedBehavior;
class ArbitraryEventsWorker;
class ArbitraryObjectsWorker;
class ArbitraryEventsWorkerWithContext;
} // namespace gd
@@ -50,10 +51,21 @@ class GD_CORE_API WholeProjectRefactorer {
gd::ArbitraryEventsWorkerWithContext& worker);
/**
* \brief Refactor the project **before** an events function extension is renamed.
* \brief Call the specified worker on all ObjectContainers of the project (global,
* layouts...)
*
* This should be the preferred way to traverse all the objects of a project.
*/
static void ExposeProjectObjects(
gd::Project& project, gd::ArbitraryObjectsWorker& worker);
/**
* \brief Refactor the project **before** an events function extension is
* renamed.
*
* \warning Do the renaming of the specified extension after calling this.
* This is because the extension is expected to have its old name for the refactoring.
* This is because the extension is expected to have its old name for the
* refactoring.
*/
static void RenameEventsFunctionsExtension(
gd::Project& project,
@@ -65,7 +77,8 @@ class GD_CORE_API WholeProjectRefactorer {
* \brief Refactor the project **before** an events function is renamed.
*
* \warning Do the renaming of the specified function after calling this.
* This is because the function is expected to have its old name for the refactoring.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void RenameEventsFunction(
gd::Project& project,
@@ -78,7 +91,8 @@ class GD_CORE_API WholeProjectRefactorer {
* renamed.
*
* \warning Do the renaming of the specified function after calling this.
* This is because the function is expected to have its old name for the refactoring.
* This is because the function is expected to have its old name for the
* refactoring.
*/
static void RenameBehaviorEventsFunction(
gd::Project& project,
@@ -91,8 +105,9 @@ class GD_CORE_API WholeProjectRefactorer {
* \brief Refactor the project **before** an events function parameter
* is moved.
*
* \warning Do the move of the specified function parameters after calling this.
* This is because the function is expected to be in its old state for the refactoring.
* \warning Do the move of the specified function parameters after calling
* this. This is because the function is expected to be in its old state for
* the refactoring.
*/
static void MoveEventsFunctionParameter(
gd::Project& project,
@@ -102,11 +117,12 @@ class GD_CORE_API WholeProjectRefactorer {
std::size_t newIndex);
/**
* \brief Refactor the project **before** the parameter of an events function of a
* behavior is moved.
* \brief Refactor the project **before** the parameter of an events function
* of a behavior is moved.
*
* \warning Do the move of the specified function parameters after calling this.
* This is because the function is expected to be in its old state for the refactoring.
* \warning Do the move of the specified function parameters after calling
* this. This is because the function is expected to be in its old state for
* the refactoring.
*/
static void MoveBehaviorEventsFunctionParameter(
gd::Project& project,
@@ -121,7 +137,8 @@ class GD_CORE_API WholeProjectRefactorer {
* renamed.
*
* \warning Do the renaming of the specified property after calling this.
* This is because the property is expected to have its old name for the refactoring.
* This is because the property is expected to have its old name for the
* refactoring.
*/
static void RenameBehaviorProperty(
gd::Project& project,
@@ -134,7 +151,8 @@ class GD_CORE_API WholeProjectRefactorer {
* \brief Refactor the project **before** a behavior is renamed.
*
* \warning Do the renaming of the specified behavior after calling this.
* This is because the behavior is expected to have its old name for the refactoring.
* This is because the behavior is expected to have its old name for the
* refactoring.
*/
static void RenameEventsBasedBehavior(
gd::Project& project,
@@ -181,7 +199,7 @@ class GD_CORE_API WholeProjectRefactorer {
bool isObjectGroup);
/**
* \brief Refactor the events function after an object or group is renamed
* \brief Refactor the events function after an object or group is removed
*
* This will update the events of the function and groups.
*/

View File

@@ -15,7 +15,7 @@ Behavior::~Behavior(){};
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> Behavior::GetProperties(
const gd::SerializerElement& behaviorContent, gd::Project& project) const {
const gd::SerializerElement& behaviorContent) const {
std::map<gd::String, gd::PropertyDescriptor> nothing;
return nothing;
}

View File

@@ -61,7 +61,7 @@ class GD_CORE_API Behavior {
* \see gd::PropertyDescriptor
*/
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
const gd::SerializerElement& behaviorContent, gd::Project& project) const;
const gd::SerializerElement& behaviorContent) const;
/**
* \brief Called when the IDE wants to update a custom property of the
@@ -72,8 +72,7 @@ class GD_CORE_API Behavior {
*/
virtual bool UpdateProperty(gd::SerializerElement& behaviorContent,
const gd::String& name,
const gd::String& value,
gd::Project& project) {
const gd::String& value) {
return false;
};
#endif

View File

@@ -16,7 +16,7 @@ BehaviorsSharedData::~BehaviorsSharedData(){};
#if defined(GD_IDE_ONLY)
std::map<gd::String, gd::PropertyDescriptor> BehaviorsSharedData::GetProperties(
const gd::SerializerElement& behaviorSharedDataContent, gd::Project& project) const {
const gd::SerializerElement& behaviorSharedDataContent) const {
std::map<gd::String, gd::PropertyDescriptor> nothing;
return nothing;
}

View File

@@ -64,8 +64,7 @@ class GD_CORE_API BehaviorsSharedData {
* \see gd::PropertyDescriptor
*/
virtual std::map<gd::String, gd::PropertyDescriptor> GetProperties(
const gd::SerializerElement& behaviorSharedDataContent,
gd::Project& project) const;
const gd::SerializerElement& behaviorSharedDataContent) const;
/**
* \brief Called when the IDE wants to update a property of the shared data
@@ -75,8 +74,7 @@ class GD_CORE_API BehaviorsSharedData {
*/
virtual bool UpdateProperty(gd::SerializerElement& behaviorSharedDataContent,
const gd::String& name,
const gd::String& value,
gd::Project& project) {
const gd::String& value) {
return false;
};
#endif

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