Compare commits

...

66 Commits

Author SHA1 Message Date
Florian Rival
8c955cf77a Remove useless "Behavior" text in the behaviors editor
Don't show in changelog
2021-07-13 16:15:51 +01:00
Florian Rival
17efae037c Fix crash when analyzing unused variables when a scene is depending on another scene 2021-07-13 16:09:01 +01:00
Florian Rival
f1120238ec Slightly improve rendering scheduling for games 2021-07-13 13:51:32 +01:00
Florian Rival
5d6a2bb3a0 Fix GDJS tests (regression since rework of GDJS build in the editor)
Don't show in changelog
2021-07-13 13:46:32 +01:00
Florian Rival
f3a49ad2cf Speed up GDJS build (including at editor startup) in development
This reduces the number of copied files (let esbuild build directly in the proper output folder).
Also avoid copying the source files after every change (avoiding ~3-4 seconds of copy).

Overall, a change in GDJS/Extensions results in 1-3 seconds of build, instead of almost 10 sometimes due to the large number of file copies.

Only show in developer changelog
2021-07-12 18:11:17 +01:00
Florian Rival
aac3379f59 Remove more deprecated strings from translations
Don't show in changelog
2021-07-12 14:30:28 +01:00
Florian Rival
49949189cf Remove deprecated strings from translations
Don't show in changelog
2021-07-12 11:50:29 +01:00
Florian Rival
977daa50fa Remove gcc from Travis CI matrix as too costly in build minutes
Don't show in changelog
2021-07-11 18:21:48 +01:00
Florian Rival
fd8a7df868 Fix wording 2021-07-11 17:16:04 +01:00
Florian Rival
303110ade5 Fix long description not shown for Yes/No and True/False parameter fields
Fix #2794
2021-07-11 17:16:04 +01:00
Florian Rival
cb15111d03 Display behavior icons in the behaviors editor
* Also better align some icons
* Show button to open the help page for all behaviors
2021-07-11 17:16:04 +01:00
Florian Rival
9db4d603a0 Refactor access to behavior/behavior shared data in the editor
Avoid having getters in the gd::Platform or the gd::Project, as they should not be responsible for this.
Instead, use gd::MetadataProvider to fetch the BehaviorMetadata.

Don't show in changelog
2021-07-11 17:16:04 +01:00
Florian Rival
6c7db9a948 Display extension icons in the project manager 2021-07-11 14:26:57 +01:00
Florian Rival
6b9a8f14e3 Center images in extension generated documentation pages
Don't show in changelog
2021-07-10 18:51:31 +01:00
Florian Rival
2f3a18046a Fix rendering of lists and author names in extensions generated documentation
Don't show in changelog
2021-07-10 18:46:17 +01:00
Florian Rival
812ff43905 Automatically generate pages on the wiki for the community extensions 2021-07-10 18:19:02 +01:00
Florian Rival
1a113004be Update extensions registry loading to use the GDevelop asset API instead of using GitHub directly
Don't show in changelog
2021-07-10 14:18:26 +01:00
Florian Rival
0dd10a7955 Improve extract changelog script
Don't show in changelog
2021-07-09 23:05:27 +01:00
Florian Rival
00b25461ed Fix "X" and "Y" expression for sprite objects (regression)
The default point being passed was incorrectly set as 0 instead of "" (empty string), which was misunderstood by the game engine as the origin point (which would be flipped)

Don't show in changelog
2021-07-09 15:32:48 +01:00
Florian Rival
9e28068e4f Fix Debugger Tools extension not available in the web-app 2021-07-08 20:01:07 +01:00
D8H
6b231f3eb6 Fix: instances editor no longer give unnecessary floating positions (#2790)
* Fix: Moving instances and resizing one instance no longer give floating positions or dimensions on 0° rotated instances.
Don't show in changelog
2021-07-07 20:12:14 +02:00
Florian Rival
2dd2c85f12 Update translations 2021-07-06 17:20:43 +01:00
Florian Rival
c61faa7e05 Clean up some dead code
Don't show in changelog
2021-07-06 17:13:00 +01:00
Florian Rival
1840f6f45a Save a bit of time at startup by avoiding to pre-fetch resources
Don't show in changelog
2021-07-06 15:54:12 +01:00
Florian Rival
b11eccfa22 Clarify in the list of effects that Kawase blur should be preferred over the classic Gaussian blur for performance 2021-07-06 15:53:37 +01:00
Florian Rival
9236608502 Fix broken sortable list of animations (regression)
Fix #2784

Don't show in changelog
2021-07-06 15:32:35 +01:00
Florian Rival
12a6bc23c3 Add an option to package games as Android App Bundles, to publish them on Google Play
* Starting from August, it will be mandatory to upload Android App Bundles to Google Play - APK files won't be accepted anymore.
2021-07-04 19:29:13 +01:00
Florian Rival
23c2b84707 Fix animation scrolling in the Sprite object editor on small screens 2021-07-03 13:00:32 +01:00
Florian Rival
adb4f2a6cf Fix animation editor preview speed being too fast on monitors with high refresh rate
* Also fix scrolling/zooming in the preview

Fix #2779
2021-07-03 12:03:18 +01:00
D8H
aa3ed78eda Improve selection in the scene editor so that multiple instances can be properly rotated and resized (#2751)
* When resizing or rotating multiple instances, they will keep their relative positions.
* When resizing rotated instances, their aspect ratio will be kept to avoid an unintuitive resize effect 
* This makes it easier to edit chunks of levels, scale them, resize them and rotate them.
2021-07-01 23:26:26 +01:00
Aurélien Vivet
efb8668077 Allow popups in the events sheet to be validated after a change using Ctrl+Enter (or Cmd+Enter on macOS) (#2569)
* Also add a preference to choose if Escape should cancel any changes made (like in a dialog) or not (like previously).
2021-06-30 22:03:19 +01:00
Florian Rival
8d763d4600 Put the button to restore the default collision mask in a split menu
This is because its usage is less frequent, so it does not eat the bottom space.
We can also now delete all polygons to restore the default masks, so its usage will decrease.
2021-06-25 14:11:30 +02:00
Aurélien Vivet
0cc1e57450 Put the button "add a behavior to the object" at the bottom of the list of behaviors (#2760)
* Also restore the default collision mask if all polygons are removed in the custom mask
2021-06-25 13:47:01 +02:00
Florian Rival
24c13e1022 Make the buttons at the bottom of the list of animations always visible in the Sprite editor 2021-06-22 11:52:52 +02:00
Florian Rival
965f7aab32 Fix getting the length of an object array always returning 0 2021-06-22 10:16:43 +02:00
Florian Rival
23c1f2423d Update badge to use travis-ci.com
Don't show in changelog
2021-06-17 09:30:49 +02:00
Arthur Pacaud
1d5eb8e529 Move JSON and JS variable conversions to gdjs.Variable (#2740)
Only show in developer changelog
2021-06-16 16:59:12 +01:00
D8H
8968ef34e2 Add Flow typing to the instances editor (#2745)
Only show in developer changelog
2021-06-16 16:50:51 +01:00
Arthur Pacaud
736ba023ff Add various DX improvements (#2741)
Only show in developer changelog
2021-06-16 16:22:30 +01:00
D8H
ade075f076 Reorganize pathfinding behavior actions and conditions in 2 groups (#2738) 2021-06-16 14:58:47 +01:00
Florian Rival
049c36b081 Fix tests 2021-06-16 08:44:46 +02:00
Florian Rival
3977e2b6f2 Fix formatting 2021-06-14 15:12:11 +01:00
Aurélien Vivet
f08f38bc3b Fix "NAN" shown for the cursor position when opening the scene editor (#2743) 2021-06-14 15:10:53 +01:00
D8H
127a881416 Add a condition and expression to check the movement angle for the pathfinding behavior (#2737) 2021-06-12 18:39:31 +01:00
Florian Rival
606143ff36 Fix typings 2021-06-12 15:53:17 +01:00
Florian Rival
05a68cb17f Fix behavior not always set correctly when editing parameters using the inline popover in the events sheet 2021-06-12 15:52:01 +01:00
Florian Rival
280377cc98 Fix RGB colors with a component at 0 not applied to the ambient light color
Fix #2734
2021-06-12 15:02:49 +01:00
Florian Rival
3c88c150d5 Fix effects container of an object not copied properly (and so erased when previewing)
This is a good example of why custom assignment ctor/copy operator should be avoided. In the case of gd::Object, it would have been better to encapsulate the behaviors in a "gd::BehaviorContentContainer", that would have custom assignement ctor/copy operator, so that we could then avoid specifying those for gd::Object.

Don't show in changelog
2021-06-12 02:08:34 +01:00
D8H
13471ad40a Add actions/conditions/expressions to specify an offset for the virtual grid used by the Pathfinding behavior (#2730) 2021-06-12 00:14:24 +01:00
Florian Rival
0d7d574f1b Fix action and condition to change the movement angle offset of the Top Down Movement behavior 2021-06-12 00:05:02 +01:00
D8H
19a10d7dab Add autocompletions for animation and points of Sprite objects (#2722)
* Both for the parameters of actions and inside expressions.
2021-06-11 23:27:44 +01:00
Arthur Pacaud
84e096f85d Update the IDE to Firebase v9 (to reduce the size of the Firebase module) (#2724)
Only show in developer changelog
2021-06-11 23:13:50 +01:00
Aurélien Vivet
40f5eb3e23 Remove unused argument (#2731)
Don't show in changelog
2021-06-11 11:17:00 +01:00
Arthur Pacaud
4948e16dd5 Add disconnection actions to the p2p extension (#2723) 2021-06-09 22:45:20 +01:00
D8H
2b38325d96 Ensure variables referenced in external events are shown in the autocompletions in the variables editor (#2717) 2021-06-09 21:29:20 +01:00
D8H
9a10caeeac Add autocompletion for variable names in expressions (#2692) 2021-06-07 09:16:12 +01:00
Florian Rival
a4be56a24b Add links when creating issues 2021-06-06 17:47:57 +01:00
Arthur Pacaud
fc8b724e3c Export extension dependencies exported when the extension is used (#2671)
* This for example allow to export the vibration extension only if it's used in events.

Only show in developer changelog
2021-06-06 16:45:47 +01:00
Aurélien Vivet
7e61419a36 Clean the examples folder (#2713)
Only show in developer changelog
2021-06-06 15:37:47 +01:00
Florian Rival
473661b8a2 Fix typings 2021-06-06 15:36:01 +01:00
Florian Rival
350fea08bf Enable serialization of effects in gd::Object
Don't show in changelog
2021-06-05 16:55:28 +01:00
D8H
4f9154549b Add autocompletion in expressions for scene names, layer names and parameters with choices (#2702) 2021-06-05 14:27:28 +01:00
Florian Rival
d9172ded36 Replace the list of examples by an "Example Library" (#2697)
* You can contribute to the examples library by submitting your new (or improved) examples on https://github.com/GDevelopApp/GDevelop-examples
2021-06-05 00:57:23 +01:00
Aurélien Vivet
aef8271a4e Specify type of variables in the events sheet sentences (#2701) 2021-06-02 21:33:29 +01:00
Harsimran Singh Virk
83db8ce272 Added Effects Container in gd::Object (#2683)
Only show in developer changelog
2021-05-31 22:22:08 +01:00
Florian Rival
e26c1470c1 Upgrade to Flow 0.131 (#2695)
Don't show in changelog
2021-05-31 22:19:13 +01:00
2433 changed files with 7573 additions and 479860 deletions

17
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: GDevelop Discord
url: https://discord.gg/rjdYHvj
about: Discuss on the forum or on the Discord to get help creating a game or identifying a bug.
- name: GDevelop Forums
url: https://forum.gdevelop-app.com
about: You can also discuss game creation, new feature requests and bugs on the forum.
- name: GDevelop Roadmap
url: https://trello.com/b/qf0lM7k8/gdevelop-roadmap
about: Look at the roadmap and vote on features that you want to see in GDevelop.
- name: Submit a new game example that you created
url: https://github.com/GDevelopApp/GDevelop-examples/issues/new/choose
about: You can submit a game that you made to be added to examples in the "GDevelop-examples" repository
- name: Submit a new game extension that you created
url: https://github.com/4ian/GDevelop-extensions/issues/new/choose
about: You can submit an extension that you made in the "GDevelop-extensions" repository

View File

@@ -1,7 +1,6 @@
language: cpp
sudo: false
compiler:
- gcc
- clang
# Cache .npm folder for faster npm install

View File

@@ -75,7 +75,7 @@
"\t)",
"\t.getCodeExtraInformation()",
"\t.setIncludeFile('Extensions/${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}/${9:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}tools}.js')",
"\t.setFunctionName('gdjs.${7:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
"\t.setFunctionName('gdjs.evtTools.${7:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
"",
"$0"
]
@@ -97,7 +97,7 @@
"\t)",
"\t.getCodeExtraInformation()",
"\t.setIncludeFile('Extensions/${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/$2/}/${8:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}tools}.js')",
"\t.setFunctionName('gdjs.${6:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
"\t.setFunctionName('gdjs.evtTools.${6:${TM_DIRECTORY/(.*)[\\\\\\/](.*)[\\\\\\/]?$/${2:/downcase}/}.}');",
"",
"$0"
]

View File

@@ -1,104 +1,98 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include",
"${workspaceRoot}"
],
"defines": [
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"defines": [
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE",
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": [
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include",
"${workspaceRoot}"
],
"defines": [
"EMSCRIPTEN",
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
"/usr/local/include",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include",
"/usr/include",
"${workspaceRoot}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": ["/System/Library/Frameworks", "/Library/Frameworks"],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Linux",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"/usr/include",
"/usr/local/include",
"${workspaceRoot}"
],
"defines": [
"EMSCRIPTEN",
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "clang-x64",
"browse": {
"path": ["/usr/include", "/usr/local/include", "${workspaceRoot}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
},
{
"name": "Win32",
"includePath": [
"${workspaceRoot}",
"${workspaceRoot}/GDCpp",
"${workspaceRoot}/GDJS",
"${workspaceRoot}/Extensions",
"${workspaceRoot}/Core",
"${workspaceRoot}/ExtLibs/SFML/include",
"${workspaceRoot}"
],
"defines": [
"_DEBUG",
"UNICODE",
"EMSCRIPTEN",
"GD_IDE_ONLY",
"GD_CORE_API=/* Macro used to export classes on Windows, please ignore */",
"GD_API=/* Macro used to export classes on Windows, please ignore */",
"GD_EXTENSION_API=/* Macro used to export classes on Windows, please ignore */"
],
"intelliSenseMode": "msvc-x64",
"browse": {
"path": ["${workspaceRoot}"],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
}
}
],
"version": 4
}

View File

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

29
.vscode/launch.json vendored
View File

@@ -1,15 +1,16 @@
{
// 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}"
}
]
}
// 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}",
"preLaunchTask": "Start development server"
}
]
}

View File

@@ -106,12 +106,15 @@
"xstring": "cpp",
"xtr1common": "cpp",
"xtree": "cpp",
"xutility": "cpp"
"xutility": "cpp",
"xlocbuf": "cpp",
"xlocmes": "cpp"
},
"files.exclude": {
"Binaries/*build*": true,
"Binaries/Output": true,
"ExtLibs/SFML": true,
"GDJS/Runtime-dist": true,
"docs": true,
"newIDE/electron-app/dist": true,
"newIDE/app/build": true,

158
.vscode/tasks.json vendored
View File

@@ -1,66 +1,100 @@
{
"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."
}
]
{
"type": "npm",
"script": "start",
"path": "newIDE/app/",
"group": "build",
"label": "Start development server",
"detail": "Starts the GDevelop development server.",
"problemMatcher": [
{
"owner": "cra",
"fileLocation": ["relative", "${workspaceFolder}/newIDE/app"],
"source": "create-react-app",
"applyTo": "allDocuments",
"pattern": [
{
"regexp": "^([^\\s].*?)$",
"file": 1
},
{
"regexp": "^ Line\\s+(\\d+):\\s+(.*)\\s\\s+(.*)$",
"line": 1,
"message": 2,
"code": 3,
"loop": true
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^(?:Compiled with warnings\\.|Compiled successfully!)$",
"endsPattern": "^(?:Search for the keywords to learn more about each warning\\.|Note that the development build is not optimized\\.)$"
}
}
],
"presentation": {
"reveal": "silent"
},
"isBackground": true,
"runOptions": { "instanceLimit": 1, "runOn": "folderOpen" }
},
{
"type": "npm",
"script": "start",
"path": "newIDE/electron-app/",
"group": "build",
"problemMatcher": [],
"label": "Start electron app",
"detail": "Starts the development local version of GDevelop."
},
{
"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

@@ -360,8 +360,11 @@ gd::String ExpressionCodeGenerator::GenerateDefaultValue(
if (gd::ParameterMetadata::IsObject(type)) {
return codeGenerator.GenerateBadObject();
}
if (gd::ParameterMetadata::IsExpression("string", type)) {
return "\"\"";
}
return (type == "string") ? "\"\"" : "0";
return "0";
}
void ExpressionCodeGenerator::OnVisitEmptyNode(EmptyNode& node) {

View File

@@ -66,6 +66,22 @@ class GD_CORE_API ExpressionParser2 {
return Start(type, objectName);
}
/**
* Given an object name (or empty if none) and a behavior name (or empty if none),
* return the index of the first parameter that is inside the parenthesis:
* 0, 1 or 2.
*
* For example, in an expression like `Object.MyBehavior::Method("hello")`, the
* parameter "hello" is the second parameter (the first being by convention Object,
* and the second MyBehavior, also by convention).
*/
static size_t WrittenParametersFirstIndex(const gd::String &objectName,
const gd::String &behaviorName) {
// By convention, object is always the first parameter, and behavior the
// second one.
return !behaviorName.empty() ? 2 : (!objectName.empty() ? 1 : 0);
}
private:
/** \name Grammar
* Each method is a part of the grammar.
@@ -999,13 +1015,6 @@ class GD_CORE_API ExpressionParser2 {
}
///@}
static size_t WrittenParametersFirstIndex(const gd::String &objectName,
const gd::String &behaviorName) {
// By convention, object is always the first parameter, and behavior the
// second one.
return !behaviorName.empty() ? 2 : (!objectName.empty() ? 1 : 0);
}
gd::String expression;
std::size_t currentPosition;

View File

@@ -206,7 +206,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"all of the forces it has."),
_("Add to _PARAM0_ _PARAM3_ force of _PARAM1_ p/s on X axis and "
"_PARAM2_ p/s on Y axis"),
_("Movement"),
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
@@ -222,7 +222,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"using the specified angle and length."),
_("Add to _PARAM0_ _PARAM3_ force, angle: _PARAM1_ degrees and "
"length: _PARAM2_ pixels"),
_("Movement"),
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
@@ -238,7 +238,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add a force to an object to make it move toward a position."),
_("Move _PARAM0_ toward _PARAM1_;_PARAM2_ with _PARAM4_ force of _PARAM3_ "
"pixels"),
_("Movement"),
_("Movement using forces"),
"res/actions/force24.png",
"res/actions/force.png")
@@ -251,30 +251,30 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
obj.AddAction(
"AddForceTournePos",
_("Add a force to move around a position"),
_("Add a force to an object to make it rotate around a "
"Add a force to move around a position",
"Add a force to an object to make it rotate around a "
"position.\nNote that the movement is not precise, especially if "
"the speed is high.\nTo position an object around a position more "
"precisely, use the actions in the category \"Position\"."),
_("Rotate _PARAM0_ around _PARAM1_;_PARAM2_ at _PARAM3_ deg/sec and "
"_PARAM4_ pixels away"),
_("Movement"),
"precisely, use the actions in the category \"Position\".",
"Rotate _PARAM0_ around _PARAM1_;_PARAM2_ at _PARAM3_ deg/sec and "
"_PARAM4_ pixels away",
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("X position of the center"))
.AddParameter("expression", _("Y position of the center"))
.AddParameter("expression", _("Speed (in Degrees per seconds)"))
.AddParameter("expression", _("Distance (in pixels)"))
.AddParameter("forceMultiplier", _("Force multiplier"))
.AddParameter("expression", "X position of the center")
.AddParameter("expression", "Y position of the center")
.AddParameter("expression", "Speed (in Degrees per seconds)")
.AddParameter("expression", "Distance (in pixels)")
.AddParameter("forceMultiplier", "Force multiplier")
.SetHidden();
obj.AddAction("Arreter",
_("Stop the object"),
_("Stop the object by deleting all of its forces."),
_("Stop _PARAM0_ (remove all forces)"),
_("Movement"),
_("Movement using forces"),
"res/actions/arreter24.png",
"res/actions/arreter.png")
@@ -475,9 +475,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsSimple();
obj.AddCondition("Invisible",
_("Invisibility of an object"),
_("Check if an object is hidden."),
_("_PARAM0_ is hidden"),
"Invisibility of an object",
"Check if an object is hidden.",
"_PARAM0_ is hidden",
_("Visibility"),
"res/conditions/visibilite24.png",
"res/conditions/visibilite.png")
@@ -486,10 +486,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetHidden(); // Inverted "Visible" condition does the same thing.
obj.AddCondition("Arret",
_("Object is stopped"),
_("Object is stopped (no forces applied on it)"),
_("Check if an object is not moving"),
_("_PARAM0_ is stopped"),
_("Movement"),
_("Movement using forces"),
"res/conditions/arret24.png",
"res/conditions/arret.png")
@@ -497,10 +497,10 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("Vitesse",
_("Speed"),
_("Speed (from forces)"),
_("Compare the overall speed of an object"),
_("the overall speed"),
_("Movement"),
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
@@ -509,17 +509,17 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.MarkAsAdvanced();
obj.AddCondition("AngleOfDisplacement",
_("Angle of movement"),
_("Compare the angle of displacement of an object"),
_("Angle of displacement of _PARAM0_ is _PARAM1_ (tolerance "
_("Angle of movement (using forces)"),
_("Compare the angle of movement of an object according to the forces applied on it."),
_("Angle of movement of _PARAM0_ is _PARAM1_ (tolerance"
": _PARAM2_ degrees)"),
_("Movement"),
_("Movement using forces"),
"res/conditions/vitesse24.png",
"res/conditions/vitesse.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance"))
.AddParameter("expression", _("Tolerance, in degrees"))
.MarkAsAdvanced();
obj.AddCondition("VarObjet",
@@ -560,9 +560,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.SetDefaultValue("true");
obj.AddCondition("VarObjetDef",
_("Variable defined"),
_("Check if the variable is defined."),
_("Variable _PARAM1 of _PARAM0_ is defined"),
"Variable defined",
"Check if the variable is defined.",
"Variable _PARAM1 of _PARAM0_ is defined",
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
@@ -632,7 +632,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Removes a variable at the specified index of an object array "
"variable."),
_("Remove variable at index _PARAM2_ from array variable _PARAM1_ of "
"object _PARAM0_"),
"_PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
@@ -671,7 +671,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Add a force to move toward an object"),
_("Add a force to an object to make it move toward another."),
_("Move _PARAM0_ toward _PARAM1_ with _PARAM3_ force of _PARAM2_ pixels"),
_("Movement"),
_("Movement using forces"),
"res/actions/forceVers24.png",
"res/actions/forceVers.png")
@@ -690,7 +690,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
"the actions in category \"Position\"."),
_("Rotate _PARAM0_ around _PARAM1_ at _PARAM2_ deg/sec and _PARAM3_ "
"pixels away"),
_("Movement"),
_("Movement using forces"),
"res/actions/forceTourne24.png",
"res/actions/forceTourne.png")
@@ -720,29 +720,29 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
// Deprecated action
obj.AddAction("Rebondir",
_("Move an object away from another"),
_("Move an object away from another, using forces."),
_("Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)"),
_("Movement"),
"Move an object away from another",
"Move an object away from another, using forces.",
"Move _PARAM0_ away from _PARAM1_ (only _PARAM0_ will move)",
_("Movement using forces"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object 2 (won't move)"));
.AddParameter("objectList", "Object 2 (won't move)");
// Deprecated action
obj.AddAction("Ecarter",
_("Move an object away from another"),
_("Move an object away from another without using forces."),
_("Move _PARAM0_ away from _PARAM2_ (only _PARAM0_ will move)"),
"Move an object away from another",
"Move an object away from another without using forces.",
"Move _PARAM0_ away from _PARAM2_ (only _PARAM0_ will move)",
_("Position"),
"res/actions/ecarter24.png",
"res/actions/ecarter.png")
.SetHidden()
.AddParameter("object", _("Object"))
.AddParameter("objectList", _("Object 2 (won't move)"));
.AddParameter("objectList", "Object 2 (won't move)");
obj.AddAction("SeparateFromObjects",
_("Separate objects"),
@@ -882,37 +882,37 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
.AddParameter("object", _("Object"));
obj.AddExpression("ForceX",
_("Average X coordinates of forces"),
_("Average X coordinates of forces"),
_("Movement"),
_("X coordinate of the sum of forces"),
_("X coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
obj.AddExpression("ForceY",
_("Average Y coordinates of forces"),
_("Average Y coordinates of forces"),
_("Movement"),
_("Y coordinate of the sum of forces"),
_("Y coordinate of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
obj.AddExpression("ForceAngle",
_("Average angle of the forces"),
_("Average angle of the forces"),
_("Movement"),
_("Angle of the sum of forces"),
_("Angle of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
obj.AddExpression("ForceLength",
_("Average length of the forces"),
_("Average length of the forces"),
_("Movement"),
_("Length of the sum of forces"),
_("Length of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"));
obj.AddExpression("Longueur",
_("Average length of the forces"),
_("Average length of the forces"),
_("Movement"),
_("Length of the sum of forces"),
_("Length of the sum of forces"),
_("Movement using forces"),
"res/actions/force.png")
.AddParameter("object", _("Object"))
.SetHidden();
@@ -1149,7 +1149,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Moves all objects according to the forces they have. GDevelop "
"calls this action at the end of the events by default."),
_("Apply movement to all objects"),
_("Movement"),
_("Movement using forces"),
"res/actions/doMove24.png",
"res/actions/doMove.png")
.AddCodeOnlyParameter("currentScene", "")
@@ -1157,16 +1157,16 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
extension
.AddCondition("SeDirige",
_("An object is moving toward another"),
_("An object is moving toward another (using forces)"),
_("Check if an object moves toward another.\nThe first "
"object must move."),
_("_PARAM0_ is moving toward _PARAM1_"),
_("Movement"),
_("Movement using forces"),
"res/conditions/sedirige24.png",
"res/conditions/sedirige.png")
.AddParameter("objectList", _("Object"))
.AddParameter("objectList", _("Object 2"))
.AddParameter("expression", _("Angle of tolerance"))
.AddParameter("expression", _("Tolerance, in degrees"))
.AddCodeOnlyParameter("conditionInverted", "")
.MarkAsAdvanced();

View File

@@ -15,7 +15,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
.SetExtensionInformation(
"BuiltinNetwork",
_("Basic internet features"),
_("Features to send web requests, communicate with external \"APIs\" and other network related tasks."),
_("Features to send web requests, communicate with external \"APIs\" "
"and other network related tasks."),
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/all-features/network");
@@ -24,33 +25,33 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
extension
.AddAction(
"SendRequest",
_("Send a request to a web page"),
_("Send a 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 _PARAM3_ request to _PARAM0__PARAM1_ with body: _PARAM2_"),
"Send a request to a web page",
"Send a 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 _PARAM3_ request to _PARAM0__PARAM1_ with body: _PARAM2_",
_("Network"),
"res/actions/net24.png",
"res/actions/net.png")
.AddParameter("string", _("Host, with protocol"))
.SetParameterLongDescription(_("Example: \"http://example.com/\"."))
.AddParameter("string", _("Path"))
.AddParameter("string", "Host, with protocol")
.SetParameterLongDescription("Example: \"http://example.com/\".")
.AddParameter("string", "Path")
.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."))
"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.")
.SetDefaultValue("\"GET\"")
.AddParameter("string", _("Content type"), "", true)
.AddParameter("string", "Content type", "", true)
.SetParameterLongDescription(
_("If empty, \"application/x-www-form-urlencoded\" will be used."))
.AddParameter("scenevar", _("Reponse scene variable"), "", true)
"If empty, \"application/x-www-form-urlencoded\" will be used.")
.AddParameter("scenevar", "Reponse scene variable", "", true)
.SetParameterLongDescription(
_("The response of the server will be stored, as a string, in this "
"variable. If the server returns *JSON*, you may want to use the "
"action \"Convert JSON to a scene variable\" afterwards, to "
"explore the results with a *structure variable*."))
"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*.")
.MarkAsComplex()
.SetHidden();
@@ -74,7 +75,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsNetworkExtension(
"highly recommended."))
.AddParameter("string", _("Request body content"))
.AddParameter("stringWithSelector",
_("Resize mode"),
_("Request method"),
"[\"GET\", \"POST\", \"PUT\", \"HEAD\", \"DELETE\", "
"\"PATCH\", \"OPTIONS\"]",
false)

View File

@@ -66,7 +66,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Animation name"))
.AddParameter("objectAnimationName", _("Animation name"))
.MarkAsAdvanced();
obj.AddAction(
@@ -133,9 +133,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.MarkAsSimple();
obj.AddAction("TourneVersPos",
_("Rotate an object toward a position"),
_("Rotate an object towards a position."),
_("Rotate _PARAM0_ towards _PARAM1_;_PARAM2_"),
"Rotate an object toward a position",
"Rotate an object towards a position.",
"Rotate _PARAM0_ towards _PARAM1_;_PARAM2_",
_("Direction"),
"res/actions/direction24.png",
"res/actions/direction.png")
@@ -230,7 +230,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/conditions/animation.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Animation name"))
.AddParameter("objectAnimationName", _("Animation name"))
.MarkAsAdvanced();
obj.AddCondition(
@@ -249,7 +249,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
obj.AddCondition("Sprite",
_("Current frame"),
_("Compare the index of the current frame in the animation displayed by the specified object. The first frame in an animation starts at index 0."),
_("Compare the index of the current frame in the animation "
"displayed by the specified object. The first frame in an "
"animation starts at index 0."),
_("the animation frame"),
_("Animations and images"),
"res/conditions/sprite24.png",
@@ -365,14 +367,13 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("color", _("Color to make transparent"));
obj.AddAction(
"ChangeColor",
_("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")
obj.AddAction("ChangeColor",
_("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", _("Tint"));
@@ -436,15 +437,15 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
.AddParameter("object", _("Object"), "Sprite");
obj.AddAction("TourneVers",
_("Rotate an object toward another"),
_("Rotate an object towards another."),
_("Rotate _PARAM0_ towards _PARAM1_"),
"Rotate an object toward another",
"Rotate an object towards another.",
"Rotate _PARAM0_ towards _PARAM1_",
_("Direction"),
"res/actions/direction24.png",
"res/actions/direction.png")
.AddParameter("object", _("Object to be rotated"), "Sprite")
.AddParameter("objectPtr", _("Rotate toward this object"))
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("objectPtr", "Rotate toward this object")
.AddCodeOnlyParameter("currentScene", "")
.SetHidden(); // Deprecated
@@ -455,7 +456,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Name of the point"), "", true);
.AddParameter("objectPointName", _("Name of the point"), "", true);
obj.AddExpression("Y",
_("Y position of a point"),
@@ -464,7 +465,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.SetHidden()
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Name of the point"), "", true);
.AddParameter("objectPointName", _("Name of the point"), "", true);
obj.AddExpression("PointX",
_("X position of a point"),
@@ -473,7 +474,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Name of the point"));
.AddParameter("objectPointName", _("Name of the point"));
obj.AddExpression("PointY",
_("Y position of a point"),
@@ -482,7 +483,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsSpriteExtension(
"res/actions/position.png")
.AddParameter("object", _("Object"), "Sprite")
.AddParameter("string", _("Name of the point"));
.AddParameter("objectPointName", _("Name of the point"));
obj.AddExpression("Direc",
_("Direction"),

View File

@@ -112,9 +112,9 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression("StrRFind",
_("Search in a text from the end"),
_("Search in a text from the end (return the position of "
"the result or -1 if not found)"),
"Search in a text from the end",
"Search in a text from the end (return the position of "
"the result or -1 if not found)",
_("Manipulation of text"),
"res/conditions/toujours24.png")
@@ -152,17 +152,17 @@ BuiltinExtensionsImplementer::ImplementsStringInstructionsExtension(
extension
.AddExpression(
"StrRFindFrom",
_("Search in a text from the end, starting from a position"),
_("Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)"),
"Search in a text from the end, starting from a position",
"Search in a text from the end, starting from a position (return "
"the position of the result or -1 if not found)",
_("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"))
"Position of the last character in the string to be "
"considered in the search")
.SetHidden(); // Deprecated, see StrFindLastFrom instead.
extension

View File

@@ -87,9 +87,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("VarSceneDef",
_("Test if a scene variable is defined"),
_("Test if the scene variable exists."),
_("Scene variable _PARAM0_ is defined"),
"Test if a scene variable is defined",
"Test if the scene variable exists.",
"Scene variable _PARAM0_ is defined",
_("Variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
@@ -136,9 +136,9 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
extension
.AddCondition("VarGlobalDef",
_("Test if a global variable is defined"),
_("Test if a global variable exists"),
_("Global variable _PARAM0_ is defined"),
"Test if a global variable is defined",
"Test if a global variable exists",
"Global variable _PARAM0_ is defined",
_("Variables/Global variables"),
"res/conditions/var24.png",
"res/conditions/var.png")
@@ -341,7 +341,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"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_"),
_("Remove variable at index _PARAM1_ from scene array variable _PARAM0_"),
_("Variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")
@@ -367,7 +367,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsVariablesExtension(
"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_"),
_("Remove variable at index _PARAM1_ from global array variable _PARAM0_"),
_("Variables/Global variables/Collections/Arrays"),
"res/actions/var24.png",
"res/actions/var.png")

View File

@@ -19,7 +19,7 @@ using namespace std;
namespace gd {
gd::BehaviorMetadata MetadataProvider::badBehaviorInfo;
gd::BehaviorMetadata MetadataProvider::badBehaviorMetadata;
gd::ObjectMetadata MetadataProvider::badObjectInfo;
gd::EffectMetadata MetadataProvider::badEffectMetadata;
gd::InstructionMetadata MetadataProvider::badInstructionMetadata;
@@ -38,7 +38,7 @@ MetadataProvider::GetExtensionAndBehaviorMetadata(const gd::Platform& platform,
}
}
return ExtensionAndMetadata<BehaviorMetadata>(badExtension, badBehaviorInfo);
return ExtensionAndMetadata<BehaviorMetadata>(badExtension, badBehaviorMetadata);
}
const BehaviorMetadata& MetadataProvider::GetBehaviorMetadata(

View File

@@ -245,13 +245,17 @@ class GD_CORE_API MetadataProvider {
return &metadata == &badExpressionMetadata;
}
static bool IsBadBehaviorMetadata(const gd::BehaviorMetadata& metadata) {
return &metadata == &badBehaviorMetadata;
}
virtual ~MetadataProvider();
private:
MetadataProvider();
static PlatformExtension badExtension;
static BehaviorMetadata badBehaviorInfo;
static BehaviorMetadata badBehaviorMetadata;
static ObjectMetadata badObjectInfo;
static EffectMetadata badEffectMetadata;
static gd::InstructionMetadata badInstructionMetadata;

View File

@@ -175,7 +175,8 @@ class GD_CORE_API ParameterMetadata {
* \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.
* see EventsFunctionParametersEditor, ParameterRenderingService
* and ExpressionAutocompletion) and in the EventsCodeGenerator.
*/
static bool IsExpression(const gd::String &type,
const gd::String &parameterType) {
@@ -187,7 +188,9 @@ class GD_CORE_API ParameterMetadata {
parameterType == "color" || parameterType == "file" ||
parameterType == "joyaxis" ||
parameterType == "stringWithSelector" ||
parameterType == "sceneName";
parameterType == "sceneName" ||
parameterType == "objectPointName" ||
parameterType == "objectAnimationName";
} else if (type == "variable") {
return parameterType == "objectvar" || parameterType == "globalvar" ||
parameterType == "scenevar";

View File

@@ -100,26 +100,6 @@ std::unique_ptr<gd::Object> Platform::CreateObject(
return std::unique_ptr<gd::Object>(std::move(object));
}
gd::Behavior* Platform::GetBehavior(const gd::String& behaviorType) const {
for (std::size_t i = 0; i < extensionsLoaded.size(); ++i) {
gd::Behavior* behavior = extensionsLoaded[i]->GetBehavior(behaviorType);
if (behavior) return behavior;
}
return nullptr;
}
gd::BehaviorsSharedData* Platform::GetBehaviorSharedDatas(
const gd::String& behaviorType) const {
for (std::size_t i = 0; i < extensionsLoaded.size(); ++i) {
gd::BehaviorsSharedData* behaviorSharedData =
extensionsLoaded[i]->GetBehaviorSharedDatas(behaviorType);
if (behaviorSharedData) return behaviorSharedData;
}
return nullptr;
}
#if defined(GD_IDE_ONLY)
std::shared_ptr<gd::BaseEvent> Platform::CreateEvent(
const gd::String& eventType) const {

View File

@@ -126,7 +126,8 @@ class GD_CORE_API Platform {
///@}
/** \name Factory method
* Member functions used to create the platforms objects
* Member functions used to create the platform objects.
* TODO: This could be moved to gd::MetadataProvider.
*/
///@{
@@ -136,18 +137,6 @@ class GD_CORE_API Platform {
std::unique_ptr<gd::Object> CreateObject(gd::String type,
const gd::String& name) const;
/**
* \brief Get the class handling the behavior with the given type, or
* `nullptr` if no behavior with the given type is found.
*/
gd::Behavior* GetBehavior(const gd::String& type) const;
/**
* \brief Get the class handling the behavior shared data with the given type,
* or `nullptr` if no behavior with the given type is found.
*/
gd::BehaviorsSharedData* GetBehaviorSharedDatas(const gd::String& type) const;
#if defined(GD_IDE_ONLY)
/**
* \brief Create an event of given type
@@ -165,11 +154,13 @@ class GD_CORE_API Platform {
/**
* \brief Called when the IDE is about to shut down: Take this opportunity for
* erasing for example any temporary file.
* @deprecated This should be removed.
*/
virtual void OnIDEClosed(){};
/**
* \brief Called when the IDE is initialized and ready to be used.
* @deprecated This should be removed.
*/
virtual void OnIDEInitialized(){};

View File

@@ -512,7 +512,7 @@ PlatformExtension::GetAllStrExpressionsForBehavior(gd::String autoType) {
return badExpressionsMetadata;
}
gd::BaseEventSPtr PlatformExtension::CreateEvent(gd::String eventType) const {
gd::BaseEventSPtr PlatformExtension::CreateEvent(const gd::String& eventType) const {
if (eventsInfos.find(eventType) != eventsInfos.end()) {
if (eventsInfos.find(eventType)->second.instance ==
std::shared_ptr<BaseEvent>()) {
@@ -531,14 +531,14 @@ gd::BaseEventSPtr PlatformExtension::CreateEvent(gd::String eventType) const {
#endif
CreateFunPtr PlatformExtension::GetObjectCreationFunctionPtr(
gd::String objectType) const {
const gd::String& objectType) const {
if (objectsInfos.find(objectType) != objectsInfos.end())
return objectsInfos.find(objectType)->second.createFunPtr;
return NULL;
}
gd::Behavior* PlatformExtension::GetBehavior(gd::String type) const {
gd::Behavior* PlatformExtension::GetBehavior(const gd::String& type) const {
if (behaviorsInfo.find(type) != behaviorsInfo.end())
return &behaviorsInfo.find(type)->second.Get();
@@ -546,7 +546,7 @@ gd::Behavior* PlatformExtension::GetBehavior(gd::String type) const {
}
gd::BehaviorsSharedData* PlatformExtension::GetBehaviorSharedDatas(
gd::String type) const {
const gd::String& type) const {
if (behaviorsInfo.find(type) != behaviorsInfo.end() &&
behaviorsInfo.find(type)->second.GetSharedDataInstance())
return behaviorsInfo.find(type)->second.GetSharedDataInstance();

View File

@@ -400,7 +400,7 @@ class GD_CORE_API PlatformExtension {
* \brief Return a function to create the object if the type is handled by the
* extension
*/
CreateFunPtr GetObjectCreationFunctionPtr(gd::String objectType) const;
CreateFunPtr GetObjectCreationFunctionPtr(const gd::String& objectType) const;
/**
* \brief Return a vector containing all the effect types provided by the
@@ -413,13 +413,13 @@ class GD_CORE_API PlatformExtension {
*
* Return an empty pointer if \a eventType is not provided by the extension.
*/
std::shared_ptr<gd::BaseEvent> CreateEvent(gd::String eventType) const;
std::shared_ptr<gd::BaseEvent> CreateEvent(const gd::String& eventType) const;
/**
* \brief Get the gd::Behavior handling the given behavior type.
*
* Return nullptr if \a behaviorType is not provided by the extension.
*/
gd::Behavior* GetBehavior(gd::String behaviorType) const;
gd::Behavior* GetBehavior(const gd::String& behaviorType) const;
/**
* \brief Get the gd::BehaviorsSharedData handling the given behavior shared
@@ -428,7 +428,7 @@ class GD_CORE_API PlatformExtension {
* Return nullptr if \a behaviorType is not provided by the extension.
*/
gd::BehaviorsSharedData* GetBehaviorSharedDatas(
gd::String behaviorType) const;
const gd::String& behaviorType) const;
/**
* \brief Return a reference to the ObjectMetadata object associated to \a

View File

@@ -15,25 +15,18 @@
#include "GDCore/Project/Project.h"
#include "GDCore/Project/SourceFile.h"
DependenciesAnalyzer::DependenciesAnalyzer(gd::Project& project_,
gd::Layout& layout_)
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
const gd::Layout& layout_)
: project(project_), layout(&layout_), externalEvents(NULL) {
parentScenes.push_back(layout->GetName());
}
DependenciesAnalyzer::DependenciesAnalyzer(gd::Project& project_,
gd::ExternalEvents& externalEvents_)
DependenciesAnalyzer::DependenciesAnalyzer(const gd::Project& project_,
const gd::ExternalEvents& externalEvents_)
: project(project_), layout(NULL), externalEvents(&externalEvents_) {
parentExternalEvents.push_back(externalEvents->GetName());
}
DependenciesAnalyzer::DependenciesAnalyzer(const DependenciesAnalyzer& parent)
: parentScenes(parent.parentScenes),
parentExternalEvents(parent.parentExternalEvents),
project(parent.project),
layout(NULL),
externalEvents(NULL) {}
bool DependenciesAnalyzer::Analyze() {
if (layout)
return Analyze(layout->GetEvents(), true);
@@ -47,9 +40,9 @@ bool DependenciesAnalyzer::Analyze() {
DependenciesAnalyzer::~DependenciesAnalyzer() {}
bool DependenciesAnalyzer::Analyze(gd::EventsList& events, bool isOnTopLevel) {
bool DependenciesAnalyzer::Analyze(const gd::EventsList& events, bool isOnTopLevel) {
for (unsigned int i = 0; i < events.size(); ++i) {
gd::LinkEvent* linkEvent = dynamic_cast<gd::LinkEvent*>(&events[i]);
const gd::LinkEvent* linkEvent = dynamic_cast<const gd::LinkEvent*>(&events[i]);
if (linkEvent) {
DependenciesAnalyzer analyzer(*this);
@@ -113,7 +106,7 @@ bool DependenciesAnalyzer::Analyze(gd::EventsList& events, bool isOnTopLevel) {
sourceFilesDependencies.insert(dependencies.begin(), dependencies.end());
const gd::String& associatedSourceFile =
events[i].GetAssociatedGDManagedSourceFile(project);
events[i].GetAssociatedGDManagedSourceFile(const_cast<gd::Project&>(project));
if (!associatedSourceFile.empty())
sourceFilesDependencies.insert(associatedSourceFile);

View File

@@ -35,7 +35,7 @@ class GD_CORE_API DependenciesAnalyzer {
/**
* \brief Constructor for analyzing the dependencies of a layout
*/
DependenciesAnalyzer(gd::Project& project_, gd::Layout& layout_);
DependenciesAnalyzer(const gd::Project& project_, const gd::Layout& layout_);
/**
* \brief Constructor for analyzing the dependencies of external events.
@@ -45,8 +45,8 @@ class GD_CORE_API DependenciesAnalyzer {
* external events can be compiled separatly and called by a scene. \see
* DependenciesAnalyzer::ExternalEventsCanBeCompiledForAScene
*/
DependenciesAnalyzer(gd::Project& project_,
gd::ExternalEvents& externalEvents);
DependenciesAnalyzer(const gd::Project& project_,
const gd::ExternalEvents& externalEvents);
virtual ~DependenciesAnalyzer();
@@ -124,13 +124,7 @@ class GD_CORE_API DependenciesAnalyzer {
* (they have no parents). \return false if a circular dependency exists, true
* otherwise.
*/
bool Analyze(gd::EventsList& events, bool isOnTopLevel);
/**
* \brief Internal constructor used when analyzing a linked layout/external
* events.
*/
DependenciesAnalyzer(const DependenciesAnalyzer& parent);
bool Analyze(const gd::EventsList& events, bool isOnTopLevel);
void AddParentScene(gd::String parentScene) {
parentScenes.push_back(parentScene);
@@ -161,9 +155,9 @@ class GD_CORE_API DependenciesAnalyzer {
std::vector<gd::String>
parentExternalEvents; ///< Used to check for circular dependencies.
gd::Project& project;
gd::Layout* layout;
gd::ExternalEvents* externalEvents;
const gd::Project& project;
const gd::Layout* layout;
const gd::ExternalEvents* externalEvents;
};
#endif // DEPENDENCIESANALYZER_H

View File

@@ -17,6 +17,8 @@
#include "GDCore/Project/Layout.h"
#include "GDCore/Project/Object.h"
#include "GDCore/Project/Project.h"
#include "GDCore/Project/ExternalEvents.h"
#include "GDCore/IDE/DependenciesAnalyzer.h"
using namespace std;
@@ -95,11 +97,11 @@ std::set<gd::String> EventsVariablesFinder::FindAllGlobalVariables(
for (std::size_t i = 0; i < project.GetLayoutsCount(); ++i) {
std::set<gd::String> results2 =
FindArgumentsInEvents(platform,
project,
project.GetLayout(i),
project.GetLayout(i).GetEvents(),
"globalvar");
FindArgumentsInEventsAndDependencies(
platform,
project,
project.GetLayout(i),
"globalvar");
results.insert(results2.begin(), results2.end());
}
@@ -112,8 +114,8 @@ std::set<gd::String> EventsVariablesFinder::FindAllLayoutVariables(
const gd::Layout& layout) {
std::set<gd::String> results;
std::set<gd::String> results2 = FindArgumentsInEvents(
platform, project, layout, layout.GetEvents(), "scenevar");
std::set<gd::String> results2 = FindArgumentsInEventsAndDependencies(
platform, project, layout, "scenevar");
results.insert(results2.begin(), results2.end());
return results;
@@ -126,12 +128,12 @@ std::set<gd::String> EventsVariablesFinder::FindAllObjectVariables(
const gd::Object& object) {
std::set<gd::String> results;
std::set<gd::String> results2 = FindArgumentsInEvents(platform,
project,
layout,
layout.GetEvents(),
"objectvar",
object.GetName());
std::set<gd::String> results2 = FindArgumentsInEventsAndDependencies(
platform,
project,
layout,
"objectvar",
object.GetName());
results.insert(results2.begin(), results2.end());
return results;
@@ -203,6 +205,38 @@ std::set<gd::String> EventsVariablesFinder::FindArgumentsInInstructions(
return results;
}
std::set<gd::String> EventsVariablesFinder::FindArgumentsInEventsAndDependencies(
const gd::Platform& platform,
const gd::Project& project,
const gd::Layout& layout,
const gd::String& parameterType,
const gd::String& objectName) {
std::set<gd::String> results;
std::set<gd::String> results2 = FindArgumentsInEvents(
platform, project, layout, layout.GetEvents(), parameterType, objectName);
results.insert(results2.begin(), results2.end());
DependenciesAnalyzer dependenciesAnalyzer = DependenciesAnalyzer(project, layout);
dependenciesAnalyzer.Analyze();
for (const gd::String& externalEventName : dependenciesAnalyzer.GetExternalEventsDependencies()) {
const gd::ExternalEvents& externalEvents = project.GetExternalEvents(externalEventName);
std::set<gd::String> results3 = FindArgumentsInEvents(
platform, project, layout, externalEvents.GetEvents(), parameterType, objectName);
results.insert(results3.begin(), results3.end());
}
for (const gd::String& sceneName : dependenciesAnalyzer.GetScenesDependencies()) {
const gd::Layout& dependencyLayout = project.GetLayout(sceneName);
std::set<gd::String> results3 = FindArgumentsInEvents(
platform, project, dependencyLayout, dependencyLayout.GetEvents(), parameterType, objectName);
results.insert(results3.begin(), results3.end());
}
return results;
}
std::set<gd::String> EventsVariablesFinder::FindArgumentsInEvents(
const gd::Platform& platform,
const gd::Project& project,

View File

@@ -100,10 +100,34 @@ class EventsVariablesFinder {
/**
* Construct a list of the value of the arguments for parameters of type @
* parameterType
* parameterType. It searchs in events dependencies.
*
* \param platform The platform of the project
* \param project The project used
* \param project The layout used
* \param layout The layout used
* \param events The events to be analyzed
* \param parameterType The parameters type to be analyzed
* \param objectName If not empty, parameters will be taken into account
* only if the last object parameter is filled with
* this value.
*
* \return A std::set filled with the values used for all parameters of the
* specified type
*/
static std::set<gd::String> FindArgumentsInEventsAndDependencies(
const gd::Platform& platform,
const gd::Project& project,
const gd::Layout& layout,
const gd::String& parameterType,
const gd::String& objectName = "");
/**
* Construct a list of the value of the arguments for parameters of type @
* parameterType. It doesn't search in events dependencies.
*
* \param platform The platform of the project
* \param project The project used
* \param layout The layout used
* \param events The events to be analyzed
* \param parameterType The parameters type to be analyzed
* \param objectName If not empty, parameters will be taken into account
@@ -119,7 +143,7 @@ class EventsVariablesFinder {
const gd::Layout& layout,
const gd::EventsList& events,
const gd::String& parameterType,
const gd::String& objectName = "");
const gd::String& objectName);
};
} // namespace gd

View File

@@ -0,0 +1,31 @@
/*
* GDevelop Core
* Copyright 2008-present Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "ExpressionCompletionFinder.h"
namespace gd {
const gd::ParameterMetadata
ExpressionCompletionDescription::badParameterMetadata;
/**
* \brief Turn an ExpressionCompletionDescription to a string.
*/
std::ostream& operator<<(std::ostream& os,
ExpressionCompletionDescription const& value) {
os << "{ " << value.GetCompletionKind() << ", " << value.GetType() << ", "
<< value.GetPrefix() << ", " << value.GetObjectName() << ", "
<< value.GetBehaviorName() << ", "
<< (value.IsExact() ? "exact" : "non-exact") << ", "
<< (value.IsLastParameter() ? "last parameter" : "not last parameter")
<< ", "
<< (value.HasParameterMetadata()
? gd::String::From(&value.GetParameterMetadata())
: "no parameter metadata")
<< " }";
return os;
}
} // namespace gd

View File

@@ -8,10 +8,14 @@
#include <memory>
#include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
#include "GDCore/Extensions/Metadata/ExpressionMetadata.h"
#include "GDCore/Extensions/Metadata/InstructionMetadata.h"
#include "GDCore/IDE/Events/ExpressionNodeLocationFinder.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
namespace gd {
class Expression;
class ObjectsContainer;
@@ -33,19 +37,21 @@ struct ExpressionCompletionDescription {
/**
* The different kind of completions that can be described.
*/
enum CompletionKind {
Object,
Behavior,
Expression,
Variable,
};
enum CompletionKind { Object, Behavior, Expression, Variable, Text };
/**
* \brief Create a completion for an object with the given prefix
*/
static ExpressionCompletionDescription ForObject(const gd::String& type_,
const gd::String& prefix_) {
return ExpressionCompletionDescription(Object, type_, prefix_);
static ExpressionCompletionDescription ForObject(
const gd::String& type_,
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_) {
return ExpressionCompletionDescription(Object,
type_,
prefix_,
replacementStartPosition_,
replacementEndPosition_);
}
/**
@@ -53,17 +59,58 @@ struct ExpressionCompletionDescription {
* the specified object
*/
static ExpressionCompletionDescription ForBehavior(
const gd::String& prefix_, const gd::String& objectName_) {
return ExpressionCompletionDescription(Behavior, "", prefix_, objectName_);
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_,
const gd::String& objectName_) {
return ExpressionCompletionDescription(Behavior,
"",
prefix_,
replacementStartPosition_,
replacementEndPosition_,
objectName_);
}
/**
* \brief Create a completion for a variable with the given prefix
*/
static ExpressionCompletionDescription ForVariable(
const gd::String& type_, const gd::String& prefix_) {
return ExpressionCompletionDescription(Variable, type_, prefix_);
const gd::String& type_,
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_,
const gd::String& objectName_ = "") {
return ExpressionCompletionDescription(Variable,
type_,
prefix_,
replacementStartPosition_,
replacementEndPosition_,
objectName_);
}
/**
* \brief Create a completion for a text with the given prefix
*/
static ExpressionCompletionDescription ForText(
const gd::String& type_,
const gd::ParameterMetadata& parameterMetadata_,
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_,
const bool isLastParameter_,
const gd::String& objectName_ = "") {
auto description =
ExpressionCompletionDescription(Text,
type_,
prefix_,
replacementStartPosition_,
replacementEndPosition_,
objectName_);
description.SetIsLastParameter(isLastParameter_);
description.SetParameterMetadata(parameterMetadata_);
return description;
}
/**
* \brief Create a completion for an expression (free, object or behavior
* expression) with the given prefix
@@ -71,10 +118,17 @@ struct ExpressionCompletionDescription {
static ExpressionCompletionDescription ForExpression(
const gd::String& type_,
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_,
const gd::String& objectName_ = "",
const gd::String& behaviorName_ = "") {
return ExpressionCompletionDescription(
Expression, type_, prefix_, objectName_, behaviorName_);
return ExpressionCompletionDescription(Expression,
type_,
prefix_,
replacementStartPosition_,
replacementEndPosition_,
objectName_,
behaviorName_);
}
/** Check if two description of completions are equal */
@@ -131,6 +185,56 @@ struct ExpressionCompletionDescription {
*/
bool IsExact() const { return isExact; }
/**
* \brief Return the first character index of the autocompleted part.
*/
size_t GetReplacementStartPosition() const {
return replacementStartPosition;
}
/**
* \brief Return the first character index after the autocompleted part.
*/
size_t GetReplacementEndPosition() const { return replacementEndPosition; }
/**
* \brief Set if the expression is the last child of a function call.
*/
ExpressionCompletionDescription& SetIsLastParameter(bool isLastParameter_) {
isLastParameter = isLastParameter_;
return *this;
}
/**
* \brief Check if the expression is the last child of a function call.
*/
bool IsLastParameter() const { return isLastParameter; }
/**
* \brief Set the parameter metadata, in the case the completion is about
* a parameter of a function call.
*/
ExpressionCompletionDescription& SetParameterMetadata(
const gd::ParameterMetadata& parameterMetadata_) {
parameterMetadata = &parameterMetadata_;
return *this;
}
/**
* \brief Check if the completion is about a parameter of a function call.
*/
bool HasParameterMetadata() const {
return parameterMetadata != &badParameterMetadata;
}
/**
* \brief Return the parameter metadata, if the completion is about a
* parameter of a function call. Returns an empty metadata otherwise.
*/
const gd::ParameterMetadata& GetParameterMetadata() const {
return *parameterMetadata;
}
/** Default constructor, only to be used by Emscripten bindings. */
ExpressionCompletionDescription() : completionKind(Object){};
@@ -138,34 +242,40 @@ struct ExpressionCompletionDescription {
ExpressionCompletionDescription(CompletionKind completionKind_,
const gd::String& type_,
const gd::String& prefix_,
size_t replacementStartPosition_,
size_t replacementEndPosition_,
const gd::String& objectName_ = "",
const gd::String& behaviorName_ = "")
: completionKind(completionKind_),
type(type_),
prefix(prefix_),
replacementStartPosition(replacementStartPosition_),
replacementEndPosition(replacementEndPosition_),
objectName(objectName_),
behaviorName(behaviorName_),
isExact(false) {}
isExact(false),
isLastParameter(false),
parameterMetadata(&badParameterMetadata) {}
CompletionKind completionKind;
gd::String type;
gd::String prefix;
size_t replacementStartPosition;
size_t replacementEndPosition;
gd::String objectName;
gd::String behaviorName;
bool isExact;
bool isLastParameter;
const gd::ParameterMetadata* parameterMetadata;
static const gd::ParameterMetadata badParameterMetadata;
};
/**
* \brief Turn an ExpressionCompletionDescription to a string.
*/
std::ostream& operator<<(std::ostream& os,
ExpressionCompletionDescription const& value) {
os << "{ " << value.GetCompletionKind() << ", " << value.GetType() << ", "
<< value.GetPrefix() << ", " << value.GetObjectName() << ", "
<< value.GetBehaviorName() << ", "
<< (value.IsExact() ? "exact" : "non-exact") << " }";
return os;
}
ExpressionCompletionDescription const& value);
/**
* \brief Returns the list of completion descriptions for an expression node.
@@ -182,16 +292,18 @@ class GD_CORE_API ExpressionCompletionFinder
static std::vector<ExpressionCompletionDescription>
GetCompletionDescriptionsFor(gd::ExpressionNode& node,
size_t searchedPosition) {
gd::ExpressionNode* nodeAtLocation =
gd::ExpressionNodeLocationFinder::GetNodeAtPosition(node,
searchedPosition);
gd::ExpressionNodeLocationFinder finder(searchedPosition);
node.Visit(finder);
gd::ExpressionNode* nodeAtLocation = finder.GetNode();
if (nodeAtLocation == nullptr) {
std::vector<ExpressionCompletionDescription> emptyCompletions;
return emptyCompletions;
}
gd::ExpressionCompletionFinder autocompletionProvider(searchedPosition);
gd::ExpressionNode* maybeParentNodeAtLocation = finder.GetParentNode();
gd::ExpressionCompletionFinder autocompletionProvider(
searchedPosition, maybeParentNodeAtLocation);
nodeAtLocation->Visit(autocompletionProvider);
return autocompletionProvider.GetCompletionDescriptions();
}
@@ -208,32 +320,92 @@ class GD_CORE_API ExpressionCompletionFinder
protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
completions.push_back(
ExpressionCompletionDescription::ForObject(node.type, ""));
completions.push_back(
ExpressionCompletionDescription::ForExpression(node.type, ""));
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, "", searchedPosition + 1, searchedPosition + 1));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, "", searchedPosition + 1, searchedPosition + 1));
}
void OnVisitOperatorNode(OperatorNode& node) override {
completions.push_back(
ExpressionCompletionDescription::ForObject(node.type, ""));
completions.push_back(
ExpressionCompletionDescription::ForExpression(node.type, ""));
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, "", searchedPosition + 1, searchedPosition + 1));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, "", searchedPosition + 1, searchedPosition + 1));
}
void OnVisitUnaryOperatorNode(UnaryOperatorNode& node) override {
completions.push_back(
ExpressionCompletionDescription::ForObject(node.type, ""));
completions.push_back(
ExpressionCompletionDescription::ForExpression(node.type, ""));
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, "", searchedPosition + 1, searchedPosition + 1));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, "", searchedPosition + 1, searchedPosition + 1));
}
void OnVisitNumberNode(NumberNode& node) override {
// No completions
}
void OnVisitTextNode(TextNode& node) override {
// No completions
// Completions are searched in the case the text node is a parameter of a
// function call.
FunctionCallNode* functionCall =
dynamic_cast<FunctionCallNode*>(maybeParentNodeAtLocation);
if (functionCall != nullptr) {
int parameterIndex = -1;
for (int i = 0; i < functionCall->parameters.size(); i++) {
if (functionCall->parameters.at(i).get() == &node) {
parameterIndex = i;
break;
}
}
if (parameterIndex < 0) {
return;
}
// Search the parameter metadata index skipping invisible ones.
size_t visibleParameterIndex = 0;
size_t metadataParameterIndex = ExpressionParser2::WrittenParametersFirstIndex(
functionCall->objectName, functionCall->behaviorName);
const gd::ParameterMetadata* parameterMetadata = nullptr;
while (metadataParameterIndex <
functionCall->expressionMetadata.parameters.size()) {
if (!functionCall->expressionMetadata.parameters[metadataParameterIndex]
.IsCodeOnly()) {
if (visibleParameterIndex == parameterIndex) {
parameterMetadata = &functionCall->expressionMetadata
.parameters[metadataParameterIndex];
}
visibleParameterIndex++;
}
metadataParameterIndex++;
}
const int visibleParameterCount = visibleParameterIndex;
if (parameterMetadata == nullptr) {
// There are too many parameters in the expression, this text node is
// not actually linked to a parameter expected by the function call.
return;
}
const gd::String& type = parameterMetadata->GetType();
if (type == "string") {
// No completions for an arbitrary string.
return;
}
bool isLastParameter = parameterIndex == visibleParameterCount - 1;
completions.push_back(ExpressionCompletionDescription::ForText(
type,
*parameterMetadata,
node.text,
node.location.GetStartPosition(),
node.location.GetEndPosition(),
isLastParameter,
functionCall->objectName));
}
}
void OnVisitVariableNode(VariableNode& node) override {
completions.push_back(
ExpressionCompletionDescription::ForVariable(node.type, node.name));
completions.push_back(ExpressionCompletionDescription::ForVariable(
node.type,
node.name,
node.location.GetStartPosition(),
node.location.GetEndPosition(),
node.objectName));
}
void OnVisitVariableAccessorNode(VariableAccessorNode& node) override {
// No completions
@@ -246,13 +418,22 @@ class GD_CORE_API ExpressionCompletionFinder
if (gd::ParameterMetadata::IsObject(node.type)) {
// Only show completions of objects if an object is required
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.identifierName));
node.type,
node.identifierName,
node.location.GetStartPosition(),
node.location.GetEndPosition()));
} else {
// Show completions for expressions and objects otherwise.
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.identifierName));
node.type,
node.identifierName,
node.location.GetStartPosition(),
node.location.GetEndPosition()));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, node.identifierName));
node.type,
node.identifierName,
node.location.GetStartPosition(),
node.location.GetEndPosition()));
}
}
void OnVisitObjectFunctionNameNode(ObjectFunctionNameNode& node) override {
@@ -262,16 +443,24 @@ class GD_CORE_API ExpressionCompletionFinder
// function name missing)
if (IsCaretOn(node.objectNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.objectName));
node.type,
node.objectName,
node.objectNameLocation.GetStartPosition(),
node.objectNameLocation.GetEndPosition()));
} else if (IsCaretOn(node.objectNameDotLocation) ||
IsCaretOn(node.objectFunctionOrBehaviorNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForBehavior(
node.objectFunctionOrBehaviorName, node.objectName));
node.objectFunctionOrBehaviorName,
node.objectFunctionOrBehaviorNameLocation.GetStartPosition(),
node.objectFunctionOrBehaviorNameLocation.GetEndPosition(),
node.objectName));
} else if (IsCaretOn(node.behaviorNameNamespaceSeparatorLocation) ||
IsCaretOn(node.behaviorFunctionNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type,
node.behaviorFunctionName,
node.behaviorFunctionNameLocation.GetStartPosition(),
node.behaviorFunctionNameLocation.GetEndPosition(),
node.objectName,
node.objectFunctionOrBehaviorName));
}
@@ -279,13 +468,23 @@ class GD_CORE_API ExpressionCompletionFinder
// Object function or behavior name
if (IsCaretOn(node.objectNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.objectName));
node.type,
node.objectName,
node.objectNameLocation.GetStartPosition(),
node.objectNameLocation.GetEndPosition()));
} else if (IsCaretOn(node.objectNameDotLocation) ||
IsCaretOn(node.objectFunctionOrBehaviorNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForBehavior(
node.objectFunctionOrBehaviorName, node.objectName));
node.objectFunctionOrBehaviorName,
node.objectFunctionOrBehaviorNameLocation.GetStartPosition(),
node.objectFunctionOrBehaviorNameLocation.GetEndPosition(),
node.objectName));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, node.objectFunctionOrBehaviorName, node.objectName));
node.type,
node.objectFunctionOrBehaviorName,
node.objectFunctionOrBehaviorNameLocation.GetStartPosition(),
node.objectFunctionOrBehaviorNameLocation.GetEndPosition(),
node.objectName));
}
}
}
@@ -297,24 +496,35 @@ class GD_CORE_API ExpressionCompletionFinder
// Behavior function
if (IsCaretOn(node.objectNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.objectName));
node.type,
node.objectName,
node.objectNameLocation.GetStartPosition(),
node.objectNameLocation.GetEndPosition()));
} else if (IsCaretOn(node.objectNameDotLocation) ||
IsCaretOn(node.behaviorNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForBehavior(
node.behaviorName, node.objectName));
node.behaviorName,
node.behaviorNameLocation.GetStartPosition(),
node.behaviorNameLocation.GetEndPosition(),
node.objectName));
} else {
completions.push_back(
ExpressionCompletionDescription::ForExpression(node.type,
node.functionName,
node.objectName,
node.behaviorName)
.SetIsExact(isCaretOnParenthesis));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type,
node.functionName,
node.functionNameLocation.GetStartPosition(),
node.functionNameLocation.GetEndPosition(),
node.objectName,
node.behaviorName)
.SetIsExact(isCaretOnParenthesis));
}
} else if (!node.objectName.empty()) {
// Object function
if (IsCaretOn(node.objectNameLocation)) {
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type, node.objectName));
node.type,
node.objectName,
node.objectNameLocation.GetStartPosition(),
node.objectNameLocation.GetEndPosition()));
} else {
// Add completions for behaviors, because we could imagine that the user
// wants to move from an object function to a behavior function, and so
@@ -323,25 +533,41 @@ class GD_CORE_API ExpressionCompletionFinder
// function).
if (!isCaretOnParenthesis) {
completions.push_back(ExpressionCompletionDescription::ForBehavior(
node.functionName, node.objectName));
node.functionName,
node.objectNameLocation.GetStartPosition(),
node.objectNameLocation.GetEndPosition(),
node.objectName));
}
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, node.functionName, node.objectName)
node.type,
node.functionName,
node.functionNameLocation.GetStartPosition(),
node.functionNameLocation.GetEndPosition(),
node.objectName)
.SetIsExact(isCaretOnParenthesis));
}
} else {
// Free function
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type, node.functionName)
node.type,
node.functionName,
node.functionNameLocation.GetStartPosition(),
node.functionNameLocation.GetEndPosition())
.SetIsExact(isCaretOnParenthesis));
}
}
void OnVisitEmptyNode(EmptyNode& node) override {
completions.push_back(
ExpressionCompletionDescription::ForObject(node.type, node.text));
completions.push_back(
ExpressionCompletionDescription::ForExpression(node.type, node.text));
completions.push_back(ExpressionCompletionDescription::ForObject(
node.type,
node.text,
node.location.GetStartPosition(),
node.location.GetEndPosition()));
completions.push_back(ExpressionCompletionDescription::ForExpression(
node.type,
node.text,
node.location.GetStartPosition(),
node.location.GetEndPosition()));
}
private:
@@ -354,11 +580,14 @@ class GD_CORE_API ExpressionCompletionFinder
(inclusive && searchedPosition <= location.GetEndPosition())));
}
ExpressionCompletionFinder(size_t searchedPosition_)
: searchedPosition(searchedPosition_){};
ExpressionCompletionFinder(size_t searchedPosition_,
gd::ExpressionNode* maybeParentNodeAtLocation_)
: searchedPosition(searchedPosition_),
maybeParentNodeAtLocation(maybeParentNodeAtLocation_){};
std::vector<ExpressionCompletionDescription> completions;
size_t searchedPosition;
gd::ExpressionNode* maybeParentNodeAtLocation;
};
} // namespace gd

View File

@@ -8,6 +8,7 @@
#include <memory>
#include <vector>
#include "GDCore/Events/Parsers/ExpressionParser2Node.h"
#include "GDCore/Events/Parsers/ExpressionParser2NodeWorker.h"
namespace gd {
@@ -46,11 +47,30 @@ class GD_CORE_API ExpressionNodeLocationFinder
return finder.GetNode();
}
/**
* \brief Helper function to find the parent of the deepest node at the search
* position, if any.
*
* \warning Useful for tests. In other cases, prefer using `GetParentNode`.
*/
static ExpressionNode* GetParentNodeAtPosition(gd::ExpressionNode& node,
size_t searchedPosition) {
gd::ExpressionNodeLocationFinder finder(searchedPosition);
node.Visit(finder);
return finder.GetParentNode();
}
/**
* \brief Return the deepest node found at the search position, if any.
*/
ExpressionNode* GetNode() { return foundNode; };
/**
* \brief Return the parent of deepest node found at the search position, if
* any.
*/
ExpressionNode* GetParentNode() { return parentNode; };
protected:
void OnVisitSubExpressionNode(SubExpressionNode& node) override {
CheckSearchPositionInNode(node);
@@ -110,6 +130,7 @@ class GD_CORE_API ExpressionNodeLocationFinder
if (node.location.GetStartPosition() <= searchedPosition &&
((!inclusive && searchedPosition < node.location.GetEndPosition()) ||
(inclusive && searchedPosition <= node.location.GetEndPosition()))) {
parentNode = foundNode;
foundNode = &node;
return true;
}
@@ -119,6 +140,7 @@ class GD_CORE_API ExpressionNodeLocationFinder
size_t searchedPosition;
ExpressionNode* foundNode;
ExpressionNode* parentNode;
};
} // namespace gd

View File

@@ -24,24 +24,6 @@ namespace gd {
InstructionSentenceFormatter *InstructionSentenceFormatter::_singleton = NULL;
gd::String InstructionSentenceFormatter::Translate(
const gd::Instruction &instr, const gd::InstructionMetadata &metadata) {
gd::String out = metadata.GetSentence();
if (out.empty())
out = " "; // Prevent empty sentences that could trigger graphical
// glitches.
// Replace _PARAMx_ placeholders by their values
for (std::size_t i = 0; i < metadata.parameters.size(); ++i) {
gd::String placeholder = "_PARAM" + gd::String::From(i) + "_";
gd::String parameter = instr.GetParameter(i).GetPlainString();
out = out.FindAndReplace(placeholder, parameter);
}
out = out.FindAndReplace("\n", " ");
return out;
}
std::vector<std::pair<gd::String, gd::TextFormatting> >
InstructionSentenceFormatter::GetAsFormattedText(
const Instruction &instr, const gd::InstructionMetadata &metadata) {
@@ -83,8 +65,7 @@ InstructionSentenceFormatter::GetAsFormattedText(
}
// Add the parameter
TextFormatting format =
GetFormattingFromType(metadata.parameters[firstParamIndex].type);
TextFormatting format;
format.userData = firstParamIndex;
gd::String text = instr.GetParameter(firstParamIndex).GetPlainString();
@@ -109,74 +90,6 @@ InstructionSentenceFormatter::GetAsFormattedText(
return formattedStr;
}
TextFormatting InstructionSentenceFormatter::GetFormattingFromType(
const gd::String &type) {
if (gd::ParameterMetadata::IsObject(type)) return typesFormatting["object"];
return typesFormatting[type];
}
gd::String InstructionSentenceFormatter::LabelFromType(const gd::String &type) {
if (type.empty())
return "";
else if (type == "expression")
return _("Expression");
else if (gd::ParameterMetadata::IsObject(type))
return _("Object");
else if (type == "behavior")
return _("Behavior");
else if (type == "operator")
return _("Operator");
else if (type == "relationalOperator")
return _("Relational operator");
else if (type == "file")
return _("File");
else if (type == "key")
return _("Key");
else if (type == "mouse")
return _("Mouse button");
else if (type == "yesorno")
return _("Yes or No");
else if (type == "police")
return _("Font");
else if (type == "color")
return _("Color");
else if (type == "trueorfalse")
return _("True or False");
else if (type == "string")
return _("String");
else if (type == "musicfile")
return _("Music");
else if (type == "soundfile")
return _("Sound");
else if (type == "password")
return _("Password");
else if (type == "layer")
return _("Layer");
else if (type == "joyaxis")
return _("Joystick axis");
else if (type == "objectvar")
return _("Variable of the object");
else if (type == "scenevar")
return _("Scene variable");
else if (type == "globalvar")
return _("Global variable");
return _("Unknown");
}
void InstructionSentenceFormatter::LoadTypesFormattingFromConfig() {
// Load default configuration
typesFormatting.clear();
typesFormatting["expression"].SetColor(27, 143, 1).SetBold();
typesFormatting["object"].SetColor(182, 97, 10).SetBold();
typesFormatting["behavior"].SetColor(119, 119, 119).SetBold();
typesFormatting["operator"].SetColor(55, 131, 211).SetBold();
typesFormatting["objectvar"].SetColor(131, 55, 162).SetBold();
typesFormatting["scenevar"].SetColor(131, 55, 162).SetBold();
typesFormatting["globalvar"].SetColor(131, 55, 162).SetBold();
}
} // namespace gd
#endif

View File

@@ -25,39 +25,12 @@ namespace gd {
*/
class GD_CORE_API InstructionSentenceFormatter {
public:
/**
* \brief Create a sentence from an instruction and its metadata.
*
* Sentence is provided in the gd::InstructionMetadata passed as parameter.
* Parameters placeholders ("_PARAMx_", x being the parameter index) are
* replaced by their values stored in the isntruction passed as parameter.
*/
gd::String Translate(const gd::Instruction &instr,
const gd::InstructionMetadata &metadata);
/**
* \brief Create a formatted sentence from an instruction and its metadata.
*/
std::vector<std::pair<gd::String, gd::TextFormatting> > GetAsFormattedText(
const gd::Instruction &instr, const gd::InstructionMetadata &metadata);
/**
* \brief Return the TextFormatting object associated to the \a type.
*/
TextFormatting GetFormattingFromType(const gd::String &type);
/**
* \brief Return the label of a parameter type
*/
gd::String LabelFromType(const gd::String &type);
/**
* \brief Load the configuration from the default configuration.
*/
void LoadTypesFormattingFromConfig();
std::map<gd::String, gd::TextFormatting> typesFormatting;
static InstructionSentenceFormatter *Get() {
if (NULL == _singleton) {
_singleton = new InstructionSentenceFormatter;

View File

@@ -13,85 +13,20 @@ namespace gd {
/**
* \brief Represents the style of a text displayed in the events editor.
*
* Notably used by EventsRenderingHelper to render Instruction.
*
* \see EventsRenderingHelper
* \ingroup IDEDialogsEventsEditor
*/
class GD_CORE_API TextFormatting {
public:
TextFormatting()
: colorRed(0),
colorGreen(0),
colorBlue(0),
bold(false),
italic(false),
userData(gd::String::npos) {}
TextFormatting() : userData(gd::String::npos) {}
~TextFormatting() {}
/**
* \brief Return true if the bold style must be applied.
*/
bool IsBold() const { return bold; }
/**
* \brief Return true if the italic style must be applied.
*/
bool IsItalic() const { return italic; }
/**
* \brief Return the red component of the color that must be applied to the
* text.
*/
unsigned int GetColorRed() const { return colorRed; }
/**
* \brief Return the green component of the color that must be applied to the
* text.
*/
unsigned int GetColorGreen() const { return colorGreen; }
/**
* \brief Return the blue component of the color that must be applied to the
* text.
*/
unsigned int GetColorBlue() const { return colorBlue; }
/**
* Change the color of the text.
*/
TextFormatting& SetColor(unsigned int r, unsigned int g, unsigned int b) {
colorRed = r;
colorGreen = g;
colorBlue = b;
return *this;
}
/**
* \brief Set if the bold style must be applied.
*/
TextFormatting& SetBold(bool enable = true) {
bold = enable;
return *this;
}
/**
* \brief Set if the italic style must be applied.
*/
TextFormatting& SetItalic(bool enable = true) {
italic = enable;
return *this;
}
/**
* Return the data (an integer) associated with the text formatting.
* Used to store the parameter when rendering instructions.
*/
size_t GetUserData() const { return userData; }
unsigned int colorRed;
unsigned int colorGreen;
unsigned int colorBlue;
bool bold;
bool italic;
size_t userData;
};

View File

@@ -14,16 +14,16 @@ namespace gd {
* \note Both objects must be kept alive, as this is keeping a pointer to them.
*/
struct DependencyMetadataAndExtension {
DependencyMetadataAndExtension(gd::DependencyMetadata& dependency_,
gd::PlatformExtension& extension_)
DependencyMetadataAndExtension(gd::DependencyMetadata &dependency_,
gd::PlatformExtension &extension_)
: dependency(&dependency_), extension(&extension_){};
gd::DependencyMetadata& GetDependency() const { return *dependency; };
gd::PlatformExtension& GetExtension() const { return *extension; };
gd::DependencyMetadata &GetDependency() const { return *dependency; };
gd::PlatformExtension &GetExtension() const { return *extension; };
private:
gd::DependencyMetadata* dependency;
gd::PlatformExtension* extension;
gd::DependencyMetadata *dependency;
gd::PlatformExtension *extension;
};
/**
@@ -33,8 +33,8 @@ struct DependencyMetadataAndExtension {
class ExportedDependencyResolver {
public:
/**
* \brief Return the list of dependencies to be exported for the given project
* and dependency type.
* \brief Return the list of dependencies to be exported for the given
* project, used extensions list 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
@@ -42,11 +42,13 @@ class ExportedDependencyResolver {
* one level though).
*/
static std::vector<DependencyMetadataAndExtension> GetDependenciesFor(
const gd::Project& project, const gd::String& dependencyType) {
const gd::Project &project,
std::set<gd::String> usedExtensions,
const gd::String &dependencyType) {
std::vector<DependencyMetadataAndExtension> dependenciesWithProperType;
for (std::shared_ptr<gd::PlatformExtension> extension :
project.GetCurrentPlatform().GetAllPlatformExtensions()) {
for (gd::DependencyMetadata& dependency :
for (const gd::String &extensionName : usedExtensions) {
auto extension = project.GetCurrentPlatform().GetExtension(extensionName);
for (gd::DependencyMetadata &dependency :
extension->GetAllDependencies()) {
if (dependency.GetDependencyType() == dependencyType) {
DependencyMetadataAndExtension dependencyMetadataAndExtension(
@@ -60,7 +62,7 @@ class ExportedDependencyResolver {
// and those that don't require extra settings to be filled.
std::vector<DependencyMetadataAndExtension> dependenciesWithFilledSettings;
for (auto dependencyAndExtension : dependenciesWithProperType) {
auto& dependency = dependencyAndExtension.GetDependency();
auto &dependency = dependencyAndExtension.GetDependency();
auto extraSettingValues = GetExtensionDependencyExtraSettingValues(
project, dependencyAndExtension);
@@ -73,15 +75,15 @@ class ExportedDependencyResolver {
// exported (or dependencies that don't require another dependency).
std::vector<DependencyMetadataAndExtension> exportedDependencies;
for (auto dependencyAndExtension : dependenciesWithFilledSettings) {
auto& dependency = dependencyAndExtension.GetDependency();
auto& otherDependencyName =
auto &dependency = dependencyAndExtension.GetDependency();
auto &otherDependencyName =
dependency.GetOtherDependencyThatMustBeExported();
if (otherDependencyName.empty() ||
std::find_if(
dependenciesWithFilledSettings.begin(),
dependenciesWithFilledSettings.end(),
[&otherDependencyName](
DependencyMetadataAndExtension& otherDependencyAndExtension) {
DependencyMetadataAndExtension &otherDependencyAndExtension) {
return otherDependencyAndExtension.GetDependency().GetName() ==
otherDependencyName;
}) != dependenciesWithFilledSettings.end()) {
@@ -98,15 +100,15 @@ class ExportedDependencyResolver {
*/
static std::map<gd::String, gd::String>
GetExtensionDependencyExtraSettingValues(
const gd::Project& project,
const gd::DependencyMetadataAndExtension& dependencyAndExtension) {
const gd::Project &project,
const gd::DependencyMetadataAndExtension &dependencyAndExtension) {
std::map<gd::String, gd::String> values;
auto& dependency = dependencyAndExtension.GetDependency();
const gd::String& extensionName =
auto &dependency = dependencyAndExtension.GetDependency();
const gd::String &extensionName =
dependencyAndExtension.GetExtension().GetName();
for (const auto& extraSetting : dependency.GetAllExtraSettings()) {
const gd::String& type = extraSetting.second.GetType();
for (const auto &extraSetting : dependency.GetAllExtraSettings()) {
const gd::String &type = extraSetting.second.GetType();
const gd::String extraSettingValue =
type == "ExtensionProperty"
? project.GetExtensionProperties().GetValue(

View File

@@ -5,10 +5,14 @@
*/
#include "Layout.h"
#include <algorithm>
#include <vector>
#include "GDCore/CommonTools.h"
#include "GDCore/Events/Serialization.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/IDE/SceneNameMangler.h"
#include "GDCore/Project/Behavior.h"
@@ -219,16 +223,21 @@ void Layout::UpdateBehaviorsSharedData(gd::Project& project) {
++i) {
const gd::String& name = allBehaviorsNames[i];
if (behaviorsSharedData.find(name) == behaviorsSharedData.end()) {
gd::BehaviorsSharedData* behaviorSharedData =
project.GetBehaviorSharedDatas(allBehaviorsTypes[i]);
if (behaviorSharedData) {
auto behaviorContent =
gd::make_unique<gd::BehaviorContent>(name, allBehaviorsTypes[i]);
behaviorSharedData->InitializeContent(behaviorContent->GetContent());
behaviorsSharedData[name] = std::move(behaviorContent);
}
}
if (behaviorsSharedData.find(name) != behaviorsSharedData.end()) continue;
const gd::BehaviorMetadata& behaviorMetadata =
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
allBehaviorsTypes[i]);
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) continue;
gd::BehaviorsSharedData* behaviorSharedData =
behaviorMetadata.GetSharedDataInstance();
if (!behaviorSharedData) continue;
auto behaviorContent =
gd::make_unique<gd::BehaviorContent>(name, allBehaviorsTypes[i]);
behaviorSharedData->InitializeContent(behaviorContent->GetContent());
behaviorsSharedData[name] = std::move(behaviorContent);
}
// Remove useless shared data:

View File

@@ -4,6 +4,9 @@
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Project/Object.h"
#include "GDCore/Extensions/Metadata/BehaviorMetadata.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Project/Behavior.h"
#include "GDCore/Project/Layout.h"
@@ -24,6 +27,7 @@ void Object::Init(const gd::Object& object) {
type = object.type;
objectVariables = object.objectVariables;
tags = object.tags;
effectsContainer = object.effectsContainer;
behaviors.clear();
for (auto& it : object.behaviors) {
@@ -85,16 +89,17 @@ std::map<gd::String, gd::PropertyDescriptor> Object::GetProperties() const {
gd::BehaviorContent* Object::AddNewBehavior(gd::Project& project,
const gd::String& type,
const gd::String& name) {
gd::Behavior* behavior = project.GetCurrentPlatform().GetBehavior(type);
if (behavior) {
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
behavior->InitializeContent(behaviorContent->GetContent());
behaviors[name] = std::move(behaviorContent);
return behaviors[name].get();
} else {
const gd::BehaviorMetadata& behaviorMetadata =
gd::MetadataProvider::GetBehaviorMetadata(project.GetCurrentPlatform(),
type);
if (gd::MetadataProvider::IsBadBehaviorMetadata(behaviorMetadata)) {
return nullptr;
}
auto behaviorContent = gd::make_unique<gd::BehaviorContent>(name, type);
behaviorMetadata.Get().InitializeContent(behaviorContent->GetContent());
behaviors[name] = std::move(behaviorContent);
return behaviors[name].get();
}
std::map<gd::String, gd::PropertyDescriptor>
@@ -116,6 +121,11 @@ void Object::UnserializeFrom(gd::Project& project,
element.GetChild("variables", 0, "Variables"));
behaviors.clear();
if (element.HasChild("effects")) {
const SerializerElement& effectsElement = element.GetChild("effects");
effectsContainer.UnserializeFrom(effectsElement);
}
// Compatibility with GD <= 3.3
if (element.HasChild("Automatism")) {
for (std::size_t i = 0; i < element.GetChildrenCount("Automatism"); ++i) {
@@ -180,6 +190,7 @@ void Object::SerializeTo(SerializerElement& element) const {
element.SetAttribute("type", GetType());
element.SetAttribute("tags", GetTags());
objectVariables.SerializeTo(element.AddChild("variables"));
effectsContainer.SerializeTo(element.AddChild("effects"));
SerializerElement& behaviorsElement = element.AddChild("behaviors");
behaviorsElement.ConsiderAsArrayOf("behavior");

View File

@@ -9,7 +9,9 @@
#include <map>
#include <memory>
#include <vector>
#include "GDCore/Project/BehaviorContent.h"
#include "GDCore/Project/EffectsContainer.h"
#include "GDCore/Project/VariablesContainer.h"
#include "GDCore/String.h"
#include "GDCore/Tools/MakeUnique.h"
@@ -20,6 +22,7 @@ class Layout;
class ArbitraryResourceWorker;
class InitialInstance;
class SerializerElement;
class EffectsContainer;
} // namespace gd
namespace gd {
@@ -146,8 +149,7 @@ class GD_CORE_API Object {
*
* \return false if the new value cannot be set
*/
virtual bool UpdateProperty(const gd::String& name,
const gd::String& value) {
virtual bool UpdateProperty(const gd::String& name, const gd::String& value) {
return false;
};
///@}
@@ -198,12 +200,12 @@ class GD_CORE_API Object {
std::vector<gd::String> GetAllBehaviorNames() const;
/**
* \brief Return a reference to the behavior called \a name.
* \brief Return a reference to the content of the behavior called \a name.
*/
BehaviorContent& GetBehavior(const gd::String& name);
/**
* \brief Return a reference to the behavior called \a name.
* \brief Return a reference to the content of the behavior called \a name.
*/
const BehaviorContent& GetBehavior(const gd::String& name) const;
@@ -270,6 +272,24 @@ class GD_CORE_API Object {
* object variables
*/
gd::VariablesContainer& GetVariables() { return objectVariables; }
///@}
/**
* \name Effects management
* Member functions related to effects management.
*/
///@{
/**
* \brief Provide access to the gd::EffectsContainer member containing the
* effects.
*/
const gd::EffectsContainer& GetEffects() const { return effectsContainer; }
/**
* \brief Provide access to the gd::EffectsContainer member containing the
* effects.
*/
gd::EffectsContainer& GetEffects() { return effectsContainer; }
///@}
/** \name Serialization
@@ -301,7 +321,9 @@ class GD_CORE_API Object {
///< object.
gd::VariablesContainer
objectVariables; ///< List of the variables of the object
gd::String tags; ///< Comma-separated list of tags
gd::String tags; ///< Comma-separated list of tags
gd::EffectsContainer
effectsContainer; ///< The effects container for the object.
/**
* \brief Derived objects can redefine this method to load custom attributes.

View File

@@ -109,33 +109,6 @@ std::unique_ptr<gd::Object> Project::CreateObject(
return nullptr;
}
gd::Behavior* Project::GetBehavior(const gd::String& type,
const gd::String& platformName) {
for (std::size_t i = 0; i < platforms.size(); ++i) {
if (!platformName.empty() && platforms[i]->GetName() != platformName)
continue;
gd::Behavior* behavior = platforms[i]->GetBehavior(type);
if (behavior) return behavior;
}
return nullptr;
}
gd::BehaviorsSharedData* Project::GetBehaviorSharedDatas(
const gd::String& type, const gd::String& platformName) {
for (std::size_t i = 0; i < platforms.size(); ++i) {
if (!platformName.empty() && platforms[i]->GetName() != platformName)
continue;
gd::BehaviorsSharedData* behaviorSharedData =
platforms[i]->GetBehaviorSharedDatas(type);
if (behaviorSharedData) return behaviorSharedData;
}
return nullptr;
}
#if defined(GD_IDE_ONLY)
std::shared_ptr<gd::BaseEvent> Project::CreateEvent(
const gd::String& type, const gd::String& platformName) {
@@ -515,8 +488,6 @@ void Project::ClearEventsFunctionsExtensions() {
void Project::UnserializeFrom(const SerializerElement& element) {
// Checking version
#if defined(GD_IDE_ONLY)
gd::String updateText;
const SerializerElement& gdVersionElement =
element.GetChild("gdVersion", 0, "GDVersion");
gdMajorVersion =
@@ -528,10 +499,10 @@ void Project::UnserializeFrom(const SerializerElement& element) {
if (gdMajorVersion > gd::VersionWrapper::Major())
gd::LogWarning(
_("The version of GDevelop used to create this game seems to be a new "
"version.\nGDevelop may fail to open the game, or data may be "
"missing.\nYou should check if a new version of GDevelop is "
"available."));
"The version of GDevelop used to create this game seems to be a new "
"version.\nGDevelop may fail to open the game, or data may be "
"missing.\nYou should check if a new version of GDevelop is "
"available.");
else {
if ((gdMajorVersion == gd::VersionWrapper::Major() &&
gdMinorVersion > gd::VersionWrapper::Minor()) ||
@@ -543,22 +514,12 @@ void Project::UnserializeFrom(const SerializerElement& element) {
gdBuildVersion == gd::VersionWrapper::Build() &&
revision > gd::VersionWrapper::Revision())) {
gd::LogWarning(
_("The version of GDevelop used to create this game seems to be "
"greater.\nGDevelop may fail to open the game, or data may be "
"missing.\nYou should check if a new version of GDevelop is "
"available."));
"The version of GDevelop used to create this game seems to be "
"greater.\nGDevelop may fail to open the game, or data may be "
"missing.\nYou should check if a new version of GDevelop is "
"available.");
}
}
// Compatibility code
if (gdMajorVersion <= 1) {
gd::LogError(_(
"The game was saved with version of GDevelop which is too old. Please "
"open and save the game with one of the first version of GDevelop 2. "
"You will then be able to open your game with this GDevelop version."));
return;
}
// End of Compatibility code
#endif
const SerializerElement& propElement =
@@ -682,21 +643,6 @@ void Project::UnserializeFrom(const SerializerElement& element) {
currentPlatform = platforms.back();
#endif
// Compatibility code
#if defined(GD_IDE_ONLY)
if (VersionWrapper::IsOlder(gdMajorVersion, 0, 0, 0, 3, 0, 0, 0)) {
updateText +=
_("Sprite scaling has changed since GD 2: The resizing is made so that "
"the origin point of the object won't move whatever the scale of the "
"object.\n");
updateText +=
_("You may have to slightly change the position of some objects if you "
"have changed their size.\n\n");
updateText += _("Thank you for your understanding.\n");
}
#endif
// End of Compatibility code
#if defined(GD_IDE_ONLY)
GetObjectGroups().UnserializeFrom(
element.GetChild("objectsGroups", 0, "ObjectGroups"));

View File

@@ -390,37 +390,6 @@ class GD_CORE_API Project : public ObjectsContainer {
const gd::String& name,
const gd::String& platformName = "");
/**
* Get the behavior of the given type.
*
* \note A project can use more than one platform. In this case, the first
* platform supporting the behavior is used, unless \a platformName argument
* is not empty.
* It is assumed that each platform provides an equivalent
* behavior.
*
* \param type The type of the behavior
* \param platformName The name of the platform to be used. If empty, the
* first platform supporting the object is used.
*/
gd::Behavior* GetBehavior(const gd::String& type,
const gd::String& platformName = "");
/**
* Get the behavior shared data of the given type.
*
* \note A project can use more than one platform. In this case, the first
* platform supporting the behavior shared data is used, unless \a
* platformName argument is not empty.
* It is assumed that each platform provides equivalent behavior shared data.
*
* \param type The type of behavior
* \param platformName The name of the platform to be used. If empty, the
* first platform supporting the object is used.
*/
gd::BehaviorsSharedData* GetBehaviorSharedDatas(
const gd::String& type, const gd::String& platformName = "");
#if defined(GD_IDE_ONLY)
/**
* Create an event of the given type.

View File

@@ -7,6 +7,7 @@
#include "DummyPlatform.h"
#include "GDCore/Events/Parsers/ExpressionParser2.h"
#include "GDCore/Extensions/Metadata/MetadataProvider.h"
#include "GDCore/Extensions/Platform.h"
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Project/Layout.h"
@@ -36,31 +37,38 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Identifier") {
SECTION("Object or expression completions when type is string") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("string", "My"),
gd::ExpressionCompletionDescription::ForExpression("string", "My")};
gd::ExpressionCompletionDescription::ForObject("string", "My", 0, 2),
gd::ExpressionCompletionDescription::ForExpression(
"string", "My", 0, 2)};
REQUIRE(getCompletionsFor("string", "My", 0) == expectedCompletions);
REQUIRE(getCompletionsFor("string", "My", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("string", "My", 2) == expectedEmptyCompletions);
}
SECTION("Object or expression completions when type is number") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("number", "My"),
gd::ExpressionCompletionDescription::ForExpression("number", "My")};
gd::ExpressionCompletionDescription::ForObject("number", "My", 0, 2),
gd::ExpressionCompletionDescription::ForExpression(
"number", "My", 0, 2)};
REQUIRE(getCompletionsFor("number", "My", 0) == expectedCompletions);
REQUIRE(getCompletionsFor("number", "My", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("number", "My", 2) == expectedEmptyCompletions);
}
SECTION("Object or expression completions when type is number|string") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("number|string", "My"),
gd::ExpressionCompletionDescription::ForExpression("number|string", "My")};
REQUIRE(getCompletionsFor("number|string", "My", 0) == expectedCompletions);
REQUIRE(getCompletionsFor("number|string", "My", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("number|string", "My", 2) == expectedEmptyCompletions);
gd::ExpressionCompletionDescription::ForObject(
"number|string", "My", 0, 2),
gd::ExpressionCompletionDescription::ForExpression(
"number|string", "My", 0, 2)};
REQUIRE(getCompletionsFor("number|string", "My", 0) ==
expectedCompletions);
REQUIRE(getCompletionsFor("number|string", "My", 1) ==
expectedCompletions);
REQUIRE(getCompletionsFor("number|string", "My", 2) ==
expectedEmptyCompletions);
}
SECTION("Object when type is an object") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("object", "My")};
gd::ExpressionCompletionDescription::ForObject("object", "My", 0, 2)};
REQUIRE(getCompletionsFor("object", "My", 0) == expectedCompletions);
REQUIRE(getCompletionsFor("object", "My", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("object", "My", 2) == expectedEmptyCompletions);
@@ -70,7 +78,8 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
// Also test alternate types also considered as objects (but that can
// result in different code generation):
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("objectPtr", "My")};
gd::ExpressionCompletionDescription::ForObject(
"objectPtr", "My", 0, 2)};
REQUIRE(getCompletionsFor("objectPtr", "My", 0) == expectedCompletions);
REQUIRE(getCompletionsFor("objectPtr", "My", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("objectPtr", "My", 2) ==
@@ -78,30 +87,42 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
}
}
SECTION("Operator (number)") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("number", ""),
gd::ExpressionCompletionDescription::ForExpression("number", "")};
REQUIRE(getCompletionsFor("number", "1 + ", 1) == expectedCompletions);
REQUIRE(getCompletionsFor("number", "1 + ", 2) == expectedCompletions);
REQUIRE(getCompletionsFor("number", "1 + ", 3) == expectedCompletions);
std::vector<gd::ExpressionCompletionDescription> expectedCompletions1{
gd::ExpressionCompletionDescription::ForObject("number", "", 1, 1),
gd::ExpressionCompletionDescription::ForExpression("number", "", 1, 1)};
std::vector<gd::ExpressionCompletionDescription> expectedCompletions2{
gd::ExpressionCompletionDescription::ForObject("number", "", 2, 2),
gd::ExpressionCompletionDescription::ForExpression("number", "", 2, 2)};
std::vector<gd::ExpressionCompletionDescription> expectedCompletions3{
gd::ExpressionCompletionDescription::ForObject("number", "", 3, 3),
gd::ExpressionCompletionDescription::ForExpression("number", "", 3, 3)};
REQUIRE(getCompletionsFor("number", "1 + ", 1) == expectedCompletions1);
REQUIRE(getCompletionsFor("number", "1 + ", 2) == expectedCompletions2);
REQUIRE(getCompletionsFor("number", "1 + ", 3) == expectedCompletions3);
}
SECTION("Operator (string)") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("string", ""),
gd::ExpressionCompletionDescription::ForExpression("string", "")};
REQUIRE(getCompletionsFor("string", "\"a\" + ", 3) == expectedCompletions);
REQUIRE(getCompletionsFor("string", "\"a\" + ", 4) == expectedCompletions);
REQUIRE(getCompletionsFor("string", "\"a\" + ", 5) == expectedCompletions);
std::vector<gd::ExpressionCompletionDescription> expectedCompletions3{
gd::ExpressionCompletionDescription::ForObject("string", "", 3, 3),
gd::ExpressionCompletionDescription::ForExpression("string", "", 3, 3)};
std::vector<gd::ExpressionCompletionDescription> expectedCompletions4{
gd::ExpressionCompletionDescription::ForObject("string", "", 4, 4),
gd::ExpressionCompletionDescription::ForExpression("string", "", 4, 4)};
std::vector<gd::ExpressionCompletionDescription> expectedCompletions5{
gd::ExpressionCompletionDescription::ForObject("string", "", 5, 5),
gd::ExpressionCompletionDescription::ForExpression("string", "", 5, 5)};
REQUIRE(getCompletionsFor("string", "\"a\" + ", 3) == expectedCompletions3);
REQUIRE(getCompletionsFor("string", "\"a\" + ", 4) == expectedCompletions4);
REQUIRE(getCompletionsFor("string", "\"a\" + ", 5) == expectedCompletions5);
}
SECTION("Free function") {
SECTION("Test 1") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForExpression("unknown",
"Function")};
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Function", 0, 8)};
std::vector<gd::ExpressionCompletionDescription> expectedExactCompletions{
gd::ExpressionCompletionDescription::ForExpression("unknown",
"Function")
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Function", 0, 8)
.SetIsExact(true)};
REQUIRE(getCompletionsFor("string", "Function(", 0) ==
expectedCompletions);
@@ -123,33 +144,48 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
expectedEmptyCompletions);
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForObject("unknown", "a"),
gd::ExpressionCompletionDescription::ForExpression("unknown", "a")};
gd::ExpressionCompletionDescription::ForObject("unknown", "a", 9, 10),
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "a", 9, 10)};
REQUIRE(getCompletionsFor("string", "Function(a", 9) ==
expectedCompletions);
}
SECTION("Function with a Variable as argument") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForVariable("scenevar",
"myVar")};
gd::ExpressionCompletionDescription::ForVariable(
"scenevar", "myVar", 33, 38)};
REQUIRE(getCompletionsFor("number",
"MyExtension::GetVariableAsNumber(myVar",
33) == expectedCompletions);
}
SECTION("Function with a Layer as argument") {
std::vector<gd::ExpressionCompletionDescription> expectedCompletions{
gd::ExpressionCompletionDescription::ForText(
"layer",
gd::MetadataProvider::GetExpressionMetadata(platform,
"MyExtension::MouseX")
.GetParameter(0),
"",
20,
21,
false)};
REQUIRE(getCompletionsFor("number", "MyExtension::MouseX(\"", 20) ==
expectedCompletions);
}
}
SECTION("Partial object or behavior function") {
SECTION("Test with string type") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("string",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"string", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorOrFunctionCompletions{
gd::ExpressionCompletionDescription::ForBehavior("Func",
"MyObject"),
gd::ExpressionCompletionDescription::ForBehavior(
"Func", 9, 13, "MyObject"),
gd::ExpressionCompletionDescription::ForExpression(
"string", "Func", "MyObject")};
"string", "Func", 9, 13, "MyObject")};
REQUIRE(getCompletionsFor("string", "MyObject.Func", 0) ==
expectedObjectCompletions);
REQUIRE(getCompletionsFor("string", "MyObject.Func", 7) ==
@@ -166,14 +202,14 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Test with 'number|string' type") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("number|string",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"number|string", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorOrFunctionCompletions{
gd::ExpressionCompletionDescription::ForBehavior("Func",
"MyObject"),
gd::ExpressionCompletionDescription::ForBehavior(
"Func", 9, 13, "MyObject"),
gd::ExpressionCompletionDescription::ForExpression(
"number|string", "Func", "MyObject")};
"number|string", "Func", 9, 13, "MyObject")};
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 0) ==
expectedObjectCompletions);
REQUIRE(getCompletionsFor("number|string", "MyObject.Func", 7) ==
@@ -193,18 +229,18 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Test 1") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("unknown",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"unknown", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorOrFunctionCompletions{
gd::ExpressionCompletionDescription::ForBehavior("Func",
"MyObject"),
gd::ExpressionCompletionDescription::ForBehavior(
"Func", 9, 13, "MyObject"),
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Func", "MyObject")};
"unknown", "Func", 9, 13, "MyObject")};
std::vector<gd::ExpressionCompletionDescription>
expectedExactFunctionCompletions{
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Func", "MyObject")
"unknown", "Func", 9, 13, "MyObject")
.SetIsExact(true)};
REQUIRE(getCompletionsFor("string", "MyObject.Func(", 0) ==
expectedObjectCompletions);
@@ -229,16 +265,16 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Test 1") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("string",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"string", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorCompletions{
gd::ExpressionCompletionDescription::ForBehavior("MyBehavior",
"MyObject")};
gd::ExpressionCompletionDescription::ForBehavior(
"MyBehavior", 9, 19, "MyObject")};
std::vector<gd::ExpressionCompletionDescription>
expectedFunctionCompletions{
gd::ExpressionCompletionDescription::ForExpression(
"string", "Func", "MyObject", "MyBehavior")};
"string", "Func", 21, 25, "MyObject", "MyBehavior")};
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 0) ==
expectedObjectCompletions);
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func", 7) ==
@@ -261,16 +297,16 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Test 2") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("string",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"string", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorCompletions{
gd::ExpressionCompletionDescription::ForBehavior("MyBehavior",
"MyObject")};
gd::ExpressionCompletionDescription::ForBehavior(
"MyBehavior", 9, 19, "MyObject")};
std::vector<gd::ExpressionCompletionDescription>
expectedFunctionCompletions{
gd::ExpressionCompletionDescription::ForExpression(
"string", "", "MyObject", "MyBehavior")};
"string", "", 21, 21, "MyObject", "MyBehavior")};
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 0) ==
expectedObjectCompletions);
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::", 7) ==
@@ -292,20 +328,20 @@ TEST_CASE("ExpressionCompletionFinder", "[common][events]") {
SECTION("Test 1") {
std::vector<gd::ExpressionCompletionDescription>
expectedObjectCompletions{
gd::ExpressionCompletionDescription::ForObject("unknown",
"MyObject")};
gd::ExpressionCompletionDescription::ForObject(
"unknown", "MyObject", 0, 8)};
std::vector<gd::ExpressionCompletionDescription>
expectedBehaviorCompletions{
gd::ExpressionCompletionDescription::ForBehavior("MyBehavior",
"MyObject")};
gd::ExpressionCompletionDescription::ForBehavior(
"MyBehavior", 9, 19, "MyObject")};
std::vector<gd::ExpressionCompletionDescription>
expectedFunctionCompletions{
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Func", "MyObject", "MyBehavior")};
"unknown", "Func", 21, 25, "MyObject", "MyBehavior")};
std::vector<gd::ExpressionCompletionDescription>
expectedExactFunctionCompletions{
gd::ExpressionCompletionDescription::ForExpression(
"unknown", "Func", "MyObject", "MyBehavior")
"unknown", "Func", 21, 25, "MyObject", "MyBehavior")
.SetIsExact(true)};
REQUIRE(getCompletionsFor("string", "MyObject.MyBehavior::Func(", 0) ==
expectedObjectCompletions);

View File

@@ -24,6 +24,18 @@ bool CheckNodeAtLocationIs(gd::ExpressionParser2& parser,
*node, searchPosition)) != nullptr;
}
template <class TNode>
bool CheckParentNodeAtLocationIs(gd::ExpressionParser2& parser,
const gd::String& type,
const gd::String& expression,
size_t searchPosition) {
auto node = parser.ParseExpression(type, expression);
REQUIRE(node != nullptr);
return dynamic_cast<TNode*>(
gd::ExpressionNodeLocationFinder::GetParentNodeAtPosition(
*node, searchPosition)) != nullptr;
}
bool CheckNoNodeAtLocation(gd::ExpressionParser2& parser,
const gd::String& type,
const gd::String& expression,
@@ -34,6 +46,16 @@ bool CheckNoNodeAtLocation(gd::ExpressionParser2& parser,
*node, searchPosition) == nullptr;
}
bool CheckNoParentNodeAtLocation(gd::ExpressionParser2& parser,
const gd::String& type,
const gd::String& expression,
size_t searchPosition) {
auto node = parser.ParseExpression(type, expression);
REQUIRE(node != nullptr);
return gd::ExpressionNodeLocationFinder::GetParentNodeAtPosition(
*node, searchPosition) == nullptr;
}
TEST_CASE("ExpressionNodeLocationFinder", "[common][events]") {
gd::Project project;
gd::Platform platform;
@@ -186,6 +208,13 @@ TEST_CASE("ExpressionNodeLocationFinder", "[common][events]") {
REQUIRE(CheckNodeAtLocationIs<gd::TextNode>(parser, "number", "12+\"hello\"", 3) == true);
}
SECTION("Numbers and texts mismatchs (parent node)") {
REQUIRE(CheckParentNodeAtLocationIs<gd::OperatorNode>(parser, "number", "12+\"hello\"", 0) == true);
REQUIRE(CheckParentNodeAtLocationIs<gd::OperatorNode>(parser, "number", "12+\"hello\"", 1) == true);
REQUIRE(CheckNoParentNodeAtLocation(parser, "number", "12+\"hello\"", 2) == true);
REQUIRE(CheckParentNodeAtLocationIs<gd::OperatorNode>(parser, "number", "12+\"hello\"", 3) == true);
}
SECTION("Valid objects") {
REQUIRE(CheckNodeAtLocationIs<gd::IdentifierNode>(
parser, "object", "HelloWorld1", 0) == true);
@@ -195,6 +224,10 @@ TEST_CASE("ExpressionNodeLocationFinder", "[common][events]") {
parser, "object", "HelloWorld1", 10) == true);
REQUIRE(CheckNoNodeAtLocation(parser, "object", "HelloWorld1", 11) == true);
}
SECTION("Valid objects (parent node)") {
REQUIRE(CheckNoParentNodeAtLocation(
parser, "object", "HelloWorld1", 0) == true);
}
SECTION("Invalid objects") {
REQUIRE(CheckNodeAtLocationIs<gd::IdentifierNode>(
parser, "object", "a+b", 0) == true);
@@ -296,6 +329,29 @@ TEST_CASE("ExpressionNodeLocationFinder", "[common][events]") {
"MyExtension::GetNumberWith2Params(12, \"hello world\")",
52) == true);
}
SECTION("Parent node") {
REQUIRE(CheckParentNodeAtLocationIs<gd::OperatorNode>(
parser, "number", "12 + MyExtension::GetNumber()", 0) ==
true);
REQUIRE(CheckParentNodeAtLocationIs<gd::OperatorNode>(
parser, "number", "12 + MyExtension::GetNumber()", 6) ==
true);
REQUIRE(CheckNodeAtLocationIs<gd::NumberNode>(
parser,
"number",
"MyExtension::GetNumberWith2Params(12, \"hello world\")",
35) == true);
REQUIRE(CheckParentNodeAtLocationIs<gd::FunctionCallNode>(
parser,
"number",
"MyExtension::GetNumberWith2Params(12, \"hello world\")",
35) == true);
REQUIRE(CheckParentNodeAtLocationIs<gd::FunctionCallNode>(
parser,
"number",
"MyExtension::GetNumberWith2Params(12, \"hello world\")",
39) == true);
}
}
SECTION("Invalid function calls") {
@@ -316,6 +372,12 @@ TEST_CASE("ExpressionNodeLocationFinder", "[common][events]") {
REQUIRE(CheckNoNodeAtLocation(parser, "number", "Idontexist(12)", 14) ==
true);
}
SECTION("Invalid function calls (parent node)") {
REQUIRE(CheckNodeAtLocationIs<gd::NumberNode>(
parser, "number", "Idontexist(12)", 12) == true);
REQUIRE(CheckParentNodeAtLocationIs<gd::FunctionCallNode>(
parser, "number", "Idontexist(12)", 12) == true);
}
SECTION("Unterminated function calls") {
REQUIRE(CheckNodeAtLocationIs<gd::FunctionCallNode>(

View File

@@ -785,7 +785,7 @@ namespace gdjs {
variables: gdjs.dialogueTree.runner.variables.data,
visited: gdjs.dialogueTree.runner.visited,
};
gdjs.evtTools.network._objectToVariable(dialogueState, outputVariable);
outputVariable.fromJSObject(dialogueState);
};
/**
@@ -795,9 +795,7 @@ namespace gdjs {
* @param inputVariable The structured variable where to load the State from.
*/
gdjs.dialogueTree.loadState = function (inputVariable: gdjs.Variable) {
const loadedState = JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(inputVariable)
);
const loadedState = inputVariable.toJSObject();
if (!loadedState) {
console.error('Load state variable is empty:', inputVariable);
return;

View File

@@ -39,12 +39,14 @@ describe('gdjs.DraggableRuntimeBehavior', function () {
type: '',
behaviors: [{ name: 'Behavior1', type: 'DraggableBehavior::Draggable' }],
variables: [],
effects: [],
});
var object2 = new gdjs.RuntimeObject(runtimeScene, {
name: 'obj1',
type: '',
behaviors: [{ name: 'Behavior1', type: 'DraggableBehavior::Draggable' }],
variables: [],
effects: [],
});
runtimeScene.addObject(object);
runtimeScene.addObject(object2);

View File

@@ -221,8 +221,8 @@ module.exports = {
const blurEffect = extension
.addEffect('Blur')
.setFullName(_('Blur'))
.setDescription(_('Blur the rendered image.'))
.setFullName(_('Blur (Gaussian, slow - prefer to use Kawase blur)'))
.setDescription(_('Blur the rendered image. This is slow, so prefer to use Kawase blur in most cases.'))
.addIncludeFile('Extensions/Effects/blur-pixi-filter.js');
const blurProperties = blurEffect.getProperties();
blurProperties
@@ -707,9 +707,9 @@ module.exports = {
const kawaseBlurEffect = extension
.addEffect('KawaseBlur')
.setFullName(_('Kawase blur'))
.setFullName(_('Blur (Kawase, fast)'))
.setDescription(
_('A much faster blur than Gaussian blur, but more complicated to use.')
_('Blur the rendered image, with much better performance than Gaussian blur.')
)
.addIncludeFile('Extensions/Effects/pixi-filters/filter-kawase-blur.js')
.addIncludeFile('Extensions/Effects/kawase-blur-pixi-filter.js');

View File

@@ -43,10 +43,7 @@ namespace gdjs {
FBInstant.player
.getDataAsync([key])
.then(function (data) {
gdjs.evtTools.network.jsonToVariableStructure(
data[key],
successVariable
);
successVariable.fromJSON(data[key]);
})
.catch(function (error) {
errorVariable.setString(error.message || 'Unknown error');
@@ -64,7 +61,7 @@ namespace gdjs {
errorVariable.setString('');
successVariable.setString('');
const data = {};
data[key] = gdjs.evtTools.network.variableStructureToJSON(variable);
data[key] = variable.toJSON();
FBInstant.player
.setDataAsync(data)
.then(function () {
@@ -86,9 +83,7 @@ namespace gdjs {
}
errorVariable.setString('');
successVariable.setString('');
const data = gdjs.evtTools.network.variableStructureToJSON(
extraDataVariable
);
const data = extraDataVariable.toJSON();
FBInstant.getLeaderboardAsync(leaderboardName)
.then(function (leaderboard) {
return leaderboard.setScoreAsync(score, data);
@@ -123,10 +118,7 @@ namespace gdjs {
scoreVariable.setNumber(
entry.getScore() === null ? -1 : entry.getScore()
);
gdjs.evtTools.network.jsonToVariableStructure(
entry.getExtraData(),
extraDataVariable
);
extraDataVariable.fromJSON(entry.getExtraData());
})
.catch(function (error) {
errorVariable.setString(error.message || 'Unknown error');

View File

@@ -274,15 +274,10 @@ namespace gdjs {
resultVar: gdjs.Variable
) {
const fileSystem = gdjs.fileSystem._getFs();
const network = gdjs.evtTools.network;
let result = 'error';
if (fileSystem && network) {
if (fileSystem) {
try {
fileSystem.writeFileSync(
savePath,
network.variableStructureToJSON(variable),
'utf8'
);
fileSystem.writeFileSync(savePath, variable.toJSON(), 'utf8');
result = 'ok';
} catch (err) {
console.error(
@@ -306,23 +301,17 @@ namespace gdjs {
resultVar: gdjs.Variable
) {
const fileSystem = gdjs.fileSystem._getFs();
const network = gdjs.evtTools.network;
if (fileSystem && network) {
fileSystem.writeFile(
savePath,
network.variableStructureToJSON(variable),
'utf8',
(err) => {
resultVar.setString('ok');
if (err) {
console.error(
"Unable to save the variable to path: '" + savePath + "': ",
err
);
resultVar.setString('error');
}
if (fileSystem) {
fileSystem.writeFile(savePath, variable.toJSON(), 'utf8', (err) => {
resultVar.setString('ok');
if (err) {
console.error(
"Unable to save the variable to path: '" + savePath + "': ",
err
);
resultVar.setString('error');
}
);
});
}
};
@@ -368,13 +357,12 @@ namespace gdjs {
resultVar: gdjs.Variable
) {
const fileSystem = gdjs.fileSystem._getFs();
const network = gdjs.evtTools.network;
let result = 'error';
if (fileSystem && network) {
if (fileSystem) {
try {
const data = fileSystem.readFileSync(loadPath, 'utf8');
if (data) {
network.jsonToVariableStructure(data, variable);
variable.fromJSON(data);
result = 'ok';
}
} catch (err) {
@@ -401,11 +389,10 @@ namespace gdjs {
resultVar: gdjs.Variable
) {
const fileSystem = gdjs.fileSystem._getFs();
const network = gdjs.evtTools.network;
if (fileSystem && network) {
if (fileSystem) {
fileSystem.readFile(loadPath, 'utf8', (err, data) => {
if (data) {
network.jsonToVariableStructure(data, variable);
variable.fromJSON(data);
resultVar.setString('ok');
}
if (err) {

View File

@@ -173,9 +173,8 @@ namespace gdjs {
callbackStatusVariable.setString('ok');
if (typeof callbackValueVariable !== 'undefined')
gdjs.evtTools.network._objectToVariable(
querySnapshotToSerializable(snapshot),
callbackValueVariable
callbackValueVariable.fromJSObject(
querySnapshotToSerializable(snapshot)
);
})
.catch((error) => {
@@ -206,9 +205,8 @@ namespace gdjs {
callbackStatusVariable.setString('ok');
if (typeof callbackValueVariable !== 'undefined')
gdjs.evtTools.network._objectToVariable(
querySnapshotToSerializable(snapshot),
callbackValueVariable
callbackValueVariable.fromJSObject(
querySnapshotToSerializable(snapshot)
);
},
(error) => {
@@ -232,13 +230,7 @@ namespace gdjs {
firebase
.firestore()
.collection(collectionName)
.add(
replaceTimestampsInObject(
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
)
)
)
.add(replaceTimestampsInObject(variable.toJSObject()))
.then(() => {
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');
@@ -266,13 +258,7 @@ namespace gdjs {
.firestore()
.collection(collectionName)
.doc(variableName)
.set(
replaceTimestampsInObject(
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
)
)
)
.set(replaceTimestampsInObject(variable.toJSObject()))
.then(() => {
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');
@@ -332,13 +318,7 @@ namespace gdjs {
.firestore()
.collection(collectionName)
.doc(variableName)
.update(
replaceTimestampsInObject(
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
)
)
)
.update(replaceTimestampsInObject(variable.toJSObject()))
.then(() => {
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');
@@ -456,10 +436,7 @@ namespace gdjs {
callbackStateVariable.setString('ok');
if (callbackValueVariable)
gdjs.evtTools.network._objectToVariable(
doc.data(),
callbackValueVariable
);
callbackValueVariable.fromJSObject(doc.data());
})
.catch((error) => {
if (typeof callbackStateVariable !== 'undefined')
@@ -492,10 +469,7 @@ namespace gdjs {
callbackStateVariable.setString('ok');
if (callbackValueVariable)
gdjs.evtTools.network._objectToVariable(
doc.get(field),
callbackValueVariable
);
callbackValueVariable.fromJSObject(doc.get(field));
})
.catch((error) => {
if (typeof callbackStateVariable !== 'undefined')
@@ -595,9 +569,8 @@ namespace gdjs {
);
if (callbackValueVariable)
gdjs.evtTools.network._objectToVariable(
snapshot.docs.map((doc) => doc.id),
callbackValueVariable
callbackValueVariable.fromJSObject(
snapshot.docs.map((doc) => doc.id)
);
})
.catch((error) => {

View File

@@ -20,11 +20,7 @@ namespace gdjs {
firebase
.database()
.ref(path)
.set(
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
)
)
.set(variable.toJSObject())
.then(() => {
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');
@@ -76,11 +72,7 @@ namespace gdjs {
firebase
.database()
.ref(path)
.update(
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
)
)
.update(variable.toJSObject())
.then(() => {
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');
@@ -190,10 +182,7 @@ namespace gdjs {
callbackStateVariable.setString('ok');
if (typeof callbackValueVariable !== 'undefined')
gdjs.evtTools.network._objectToVariable(
snapshot.val(),
callbackValueVariable
);
callbackValueVariable.fromJSObject(snapshot.val());
})
.catch((error) => {
if (typeof callbackStateVariable !== 'undefined')
@@ -223,10 +212,7 @@ namespace gdjs {
callbackStateVariable.setString('ok');
if (typeof callbackValueVariable !== 'undefined')
gdjs.evtTools.network._objectToVariable(
snapshot.val()[field],
callbackValueVariable
);
callbackValueVariable.fromJSObject(snapshot.val()[field]);
})
.catch((error) => {
if (typeof callbackStateVariable !== 'undefined')

View File

@@ -24,10 +24,7 @@ namespace gdjs {
.httpsCallable(httpFunctionName)(parameter)
.then((response) => {
if (callbackValueVariable)
gdjs.evtTools.network._objectToVariable(
response.data,
callbackValueVariable
);
callbackValueVariable.fromJSObject(response.data);
if (typeof callbackStateVariable !== 'undefined')
callbackStateVariable.setString('ok');

View File

@@ -18,9 +18,7 @@ namespace gdjs {
* @param variable - A structure defining the default variables.
*/
export const setDefaultConfig = (variable: gdjs.Variable) => {
firebase.remoteConfig().defaultConfig = JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(variable)
);
firebase.remoteConfig().defaultConfig = variable.toJSObject();
};
gdjs.evtTools.firebaseTools.onAppCreated.push(() => {

View File

@@ -15,7 +15,7 @@ const firebaseConfig = {
/**
* Turns a callback variable into a promise.
* @param {(callbackVariable: {setString: (result: "ok" | string) => void}, result: gdjs.Variable) => any} executor
* @returns
* @returns {Promise<gdjs.Variable>}
*/
const promisifyCallbackVariables = (executor) =>
new Promise((done, err) => {
@@ -32,11 +32,11 @@ const promisifyCallbackVariables = (executor) =>
});
/** A complex variable using all variables types. */
const variable = new gdjs.Variable();
gdjs.evtTools.network._objectToVariable(
{ my: 'test', object: { with: 'all', types: 2 }, it: ['is', true] },
variable
);
const variable = new gdjs.Variable().fromJSObject({
my: 'test',
object: { with: 'all', types: 2 },
it: ['is', true],
});
// The tests require an internet connection, as a real Firebase instance is used.
const describeIfOnline = navigator.onLine ? describe : describe.skip;
@@ -126,13 +126,9 @@ describeIfOnline('Firebase extension end-to-end tests', function () {
goodbye: 'Goodbye',
});
const updater = new gdjs.Variable();
gdjs.evtTools.network._objectToVariable(
{
goodbye: 'See you later',
},
updater
);
const updater = new gdjs.Variable().fromJSObject({
goodbye: 'See you later',
});
await promisifyCallbackVariables((callback) =>
gdjs.evtTools.firebaseTools.database.updateVariable(
@@ -295,13 +291,9 @@ describeIfOnline('Firebase extension end-to-end tests', function () {
goodbye: 'Goodbye',
});
const updater = new gdjs.Variable();
gdjs.evtTools.network._objectToVariable(
{
goodbye: 'See you later',
},
updater
);
const updater = new gdjs.Variable().fromJSObject({
goodbye: 'See you later',
});
await promisifyCallbackVariables((callback) =>
gdjs.evtTools.firebaseTools.firestore.updateDocument(
@@ -434,17 +426,15 @@ describeIfOnline('Firebase extension end-to-end tests', function () {
.set({ index: 3, val: 1 });
const executeQuery = async (query) =>
JSON.parse(
gdjs.evtTools.network.variableStructureToJSON(
await promisifyCallbackVariables((callback, result) =>
gdjs.evtTools.firebaseTools.firestore.executeQuery(
query,
result,
callback
)
(
await promisifyCallbackVariables((callback, result) =>
gdjs.evtTools.firebaseTools.firestore.executeQuery(
query,
result,
callback
)
)
);
).toJSObject();
// Empty query
gdjs.evtTools.firebaseTools.firestore.startQuery('main', subcollection);

View File

@@ -231,6 +231,41 @@ namespace gdjs {
});
};
/**
* Disconnects from another p2p client.
* @param id - The other client's ID.
*/
export const disconnectFromPeer = (id: string) => {
if (connections[id]) connections[id].close();
};
/**
* Disconnects from all other p2p clients.
*/
export const disconnectFromAllPeers = () => {
for (const connection of Object.values(connections)) connection.close();
};
/**
* Disconnects from all peers and the broker server.
*/
export const disconnectFromAll = () => {
if (peer) {
peer.destroy();
peer = null;
}
};
/**
* Disconnects from the broker server, leaving the connections intact.
*/
export const disconnectFromBroker = () => {
if (peer) {
peer.disconnect();
peer = null;
}
};
/**
* Returns true when the event got triggered by another p2p client.
* @param defaultDataLoss Is data loss allowed (accelerates event handling when true)?
@@ -283,11 +318,7 @@ namespace gdjs {
eventName: string,
variable: gdjs.Variable
) => {
sendDataTo(
id,
eventName,
gdjs.evtTools.network.variableStructureToJSON(variable)
);
sendDataTo(id, eventName, variable.toJSON());
};
/**
@@ -299,10 +330,7 @@ namespace gdjs {
eventName: string,
variable: gdjs.Variable
) => {
sendDataToAll(
eventName,
gdjs.evtTools.network.variableStructureToJSON(variable)
);
sendDataToAll(eventName, variable.toJSON());
};
/**
@@ -329,10 +357,7 @@ namespace gdjs {
eventName: string,
variable: gdjs.Variable
) => {
gdjs.evtTools.network.jsonToVariableStructure(
getEventData(eventName),
variable
);
variable.fromJSON(getEventData(eventName));
};
/**

View File

@@ -299,6 +299,69 @@ module.exports = {
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.setFunctionName('gdjs.evtTools.p2p.getEventVariable');
extension
.addAction(
'DisconnectFromPeer',
_('Disconnect from a peer'),
_('Disconnects this client from another client.'),
_('Disconnect from client _PARAM0_'),
_('P2P (experimental)'),
'JsPlatform/Extensions/p2picon.svg',
'JsPlatform/Extensions/p2picon.svg'
)
.addParameter('string', 'ID of the peer to disconnect from', '', false)
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.setFunctionName('gdjs.evtTools.p2p.disconnectFromPeer');
extension
.addAction(
'DisconnectFromAllPeers',
_('Disconnect from all peers'),
_('Disconnects this client from all other clients.'),
_('Disconnect from all clients'),
_('P2P (experimental)'),
'JsPlatform/Extensions/p2picon.svg',
'JsPlatform/Extensions/p2picon.svg'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.setFunctionName('gdjs.evtTools.p2p.disconnectFromAllPeers');
extension
.addAction(
'DisconnectFromBroker',
_('Disconnect from broker'),
_('Disconnects the client from the broker server.'),
_('Disconnect the client from the broker'),
_('P2P (experimental)'),
'JsPlatform/Extensions/p2picon.svg',
'JsPlatform/Extensions/p2picon.svg'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.setFunctionName('gdjs.evtTools.p2p.disconnectFromBroker');
extension
.addAction(
'DisconnectFromAll',
_('Disconnect from all'),
_(
'Disconnects the client from the broker server and all other clients.'
),
_('Disconnect the client from the broker and other clients'),
_('P2P (experimental)'),
'JsPlatform/Extensions/p2picon.svg',
'JsPlatform/Extensions/p2picon.svg'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/P2P/A_peer.js')
.addIncludeFile('Extensions/P2P/B_p2ptools.js')
.setFunctionName('gdjs.evtTools.p2p.disconnectFromAll');
extension
.addStrExpression(
'GetEventData',
@@ -319,9 +382,7 @@ module.exports = {
.addStrExpression(
'GetEventSender',
_('Get event sender'),
_(
'Returns the id of the peer that triggered the event'
),
_('Returns the id of the peer that triggered the event'),
_('P2P (experimental)'),
'JsPlatform/Extensions/p2picon.svg'
)

View File

@@ -134,9 +134,9 @@ void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("PanelSpriteObject/PanelSpriteObject.h");
obj.AddAction("Angle",
_("Angle"),
_("Modify the angle of a Panel Sprite."),
_("the angle"),
"Angle",
"Modify the angle of a Panel Sprite.",
"the angle",
_("Size and angle"),
"res/actions/rotate24.png",
"res/actions/rotate.png")
@@ -149,9 +149,9 @@ void DeclarePanelSpriteObjectExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("PanelSpriteObject/PanelSpriteObject.h");
obj.AddCondition("Angle",
_("Angle"),
_("Check the angle of a Panel Sprite."),
_("the angle"),
"Angle",
"Check the angle of a Panel Sprite.",
"the angle",
_("Size and angle"),
"res/conditions/rotate24.png",
"res/conditions/rotate.png")

View File

@@ -45,7 +45,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Move to a position"),
_("Move the object to a position"),
_("Move _PARAM0_ to _PARAM3_;_PARAM4_"),
"",
"Movement on the path",
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
@@ -61,7 +61,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Path found"),
_("Check if a path has been found."),
_("A path has been found for _PARAM0_"),
"",
"Movement on the path",
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -74,7 +74,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Destination reached"),
_("Check if the destination was reached."),
_("_PARAM0_ reached its destination"),
"",
"Movement on the path",
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -145,7 +145,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Acceleration"),
_("Change the acceleration when moving the object"),
_("the acceleration on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -160,7 +160,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Acceleration"),
_("Compare the acceleration when moving the object"),
_("the acceleration"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -174,7 +174,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Maximum speed"),
_("Change the maximum speed when moving the object"),
_("the max. speed on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -189,7 +189,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Maximum speed"),
_("Compare the maximum speed when moving the object"),
_("the max. speed"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -203,7 +203,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Speed"),
_("Change the speed of the object on the path"),
_("the speed on the path"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -215,10 +215,10 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("PathfindingBehavior/PathfindingRuntimeBehavior.h");
aut.AddCondition("Speed",
_("Speed"),
_("Compare the speed of the object on the path"),
_("Speed on its path"),
_("Compare the speed of the object on its path."),
_("the speed"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -228,11 +228,25 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
.SetFunctionName("GetSpeed")
.SetIncludeFile("PathfindingBehavior/PathfindingRuntimeBehavior.h");
aut.AddScopedCondition("MovementAngleIsAround",
_("Angle of movement on its path"),
_("Compare the angle of movement of an object on its path."),
_("Angle of movement of _PARAM0_ is _PARAM2_ (tolerance"
": _PARAM3_ degrees)"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Tolerance, in degrees"));
aut.AddAction("AngularMaxSpeed",
_("Angular maximum speed"),
_("Change the maximum angular speed when moving the object"),
_("the max. angular speed on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -248,7 +262,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Angular maximum speed"),
_("Compare the maximum angular speed when moving the object"),
_("the max. angular speed"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -263,7 +277,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Rotation offset"),
_("Change the rotation offset applied when moving the object"),
_("the rotation offset on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -278,7 +292,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Rotation offset"),
_("Compare the rotation offset when moving the object"),
_("the rotation offset"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -294,7 +308,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Change the size of the extra border applied to the object when "
"planning a path"),
_("the size of the extra border on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -310,7 +324,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Compare the size of the extra border applied to the "
"object when planning a path"),
_("the size of the extra border on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -325,7 +339,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Diagonal movement"),
_("Allow or restrict diagonal movement on the path"),
_("Allow diagonal movement for _PARAM0_ on the path: _PARAM2_"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -340,7 +354,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Check if the object is allowed to move "
"diagonally on the path"),
_("Diagonal moves allowed for _PARAM0_"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -353,7 +367,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Rotate the object"),
_("Enable or disable rotation of the object on the path"),
_("Enable rotation of _PARAM0_ on the path: _PARAM2_"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -368,7 +382,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
_("Check if the object is rotated when traveling on "
"its path."),
_("_PARAM0_ is rotated when traveling on its path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon24.png",
"CppPlatform/Extensions/AStaricon16.png")
@@ -380,7 +394,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("GetNodeX",
_("Get a waypoint X position"),
_("Get next waypoint X position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -391,7 +405,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("GetNodeY",
_("Get a waypoint Y position"),
_("Get next waypoint Y position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -402,7 +416,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("NextNodeIndex",
_("Index of the next waypoint"),
_("Get the index of the next waypoint to reach"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -412,7 +426,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("NodeCount",
_("Waypoint count"),
_("Get the number of waypoints on the path"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -422,7 +436,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("NextNodeX",
_("Get next waypoint X position"),
_("Get next waypoint X position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -432,7 +446,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("NextNodeY",
_("Get next waypoint Y position"),
_("Get next waypoint Y position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -442,7 +456,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("LastNodeX",
_("Last waypoint X position"),
_("Last waypoint X position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -452,7 +466,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("LastNodeY",
_("Last waypoint Y position"),
_("Last waypoint Y position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -462,7 +476,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("DestinationX",
_("Destination X position"),
_("Destination X position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -472,7 +486,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("DestinationY",
_("Destination Y position"),
_("Destination Y position"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -482,7 +496,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("Acceleration",
_("Acceleration"),
_("Acceleration of the object on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -492,7 +506,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("MaxSpeed",
_("Maximum speed"),
_("Maximum speed of the object on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -502,7 +516,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("Speed",
_("Speed"),
_("Speed of the object on the path"),
_("Path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -512,7 +526,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("AngularMaxSpeed",
_("Angular maximum speed"),
_("Angular maximum speed of the object on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -522,7 +536,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("AngleOffset",
_("Rotation offset"),
_("Rotation offset applied the object on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -532,7 +546,7 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
aut.AddExpression("ExtraBorder",
_("Extra border size"),
_("Extra border applied the object on the path"),
_("Path"),
_("Pathfinding configuration"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
@@ -559,6 +573,36 @@ void DeclarePathfindingBehaviorExtension(gd::PlatformExtension& extension) {
.SetFunctionName("GetCellHeight")
.SetIncludeFile("PathfindingBehavior/PathfindingRuntimeBehavior.h");
aut.AddExpression("MovementAngle",
_("Angle of movement on its path"),
_("Angle of movement on its path"),
_("Movement on the path"),
"CppPlatform/Extensions/AStaricon16.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior");
aut.AddExpressionAndConditionAndAction("number",
"GridOffsetX",
_("Grid X offset"),
_("X offset of the virtual grid"),
_("X offset of the virtual grid"),
_("Virtual grid"),
"CppPlatform/Extensions/AStaricon24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
.UseStandardParameters("number");
aut.AddExpressionAndConditionAndAction("number",
"GridOffsetY",
_("Grid Y offset"),
_("Y offset of the virtual grid"),
_("Y offset of the virtual grid"),
_("Virtual grid"),
"CppPlatform/Extensions/AStaricon24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "PathfindingBehavior")
.UseStandardParameters("number");
#endif
}
{

View File

@@ -55,6 +55,16 @@ class PathfindingBehaviorJsExtension : public gd::PlatformExtension {
.SetGetter("getCellHeight");
autConditions["PathfindingBehavior::CellHeight"].SetFunctionName(
"getCellHeight");
autActions["PathfindingBehavior::PathfindingBehavior::SetGridOffsetX"]
.SetFunctionName("setGridOffsetX")
.SetGetter("getGridOffsetX");
autConditions["PathfindingBehavior::PathfindingBehavior::GridOffsetX"].SetFunctionName(
"getGridOffsetX");
autActions["PathfindingBehavior::PathfindingBehavior::SetGridOffsetY"]
.SetFunctionName("setGridOffsetY")
.SetGetter("getGridOffsetY");
autConditions["PathfindingBehavior::PathfindingBehavior::GridOffsetY"].SetFunctionName(
"getGridOffsetY");
autActions["PathfindingBehavior::Acceleration"]
.SetFunctionName("setAcceleration")
.SetGetter("getAcceleration");
@@ -69,6 +79,8 @@ class PathfindingBehaviorJsExtension : public gd::PlatformExtension {
.SetFunctionName("setSpeed")
.SetGetter("getSpeed");
autConditions["PathfindingBehavior::Speed"].SetFunctionName("getSpeed");
autConditions["PathfindingBehavior::PathfindingBehavior::MovementAngleIsAround"]
.SetFunctionName("movementAngleIsAround");
autActions["PathfindingBehavior::AngularMaxSpeed"]
.SetFunctionName("setAngularMaxSpeed")
.SetGetter("getAngularMaxSpeed");
@@ -108,11 +120,14 @@ class PathfindingBehaviorJsExtension : public gd::PlatformExtension {
autExpressions["Acceleration"].SetFunctionName("getAcceleration");
autExpressions["MaxSpeed"].SetFunctionName("getMaxSpeed");
autExpressions["Speed"].SetFunctionName("getSpeed");
autExpressions["MovementAngle"].SetFunctionName("getMovementAngle");
autExpressions["AngularMaxSpeed"].SetFunctionName("getAngularMaxSpeed");
autExpressions["AngleOffset"].SetFunctionName("getAngleOffset");
autExpressions["ExtraBorder"].SetFunctionName("getExtraBorder");
autExpressions["CellWidth"].SetFunctionName("getCellWidth");
autExpressions["CellHeight"].SetFunctionName("getCellHeight");
autExpressions["GridOffsetX"].SetFunctionName("getGridOffsetX");
autExpressions["GridOffsetY"].SetFunctionName("getGridOffsetY");
}
GetBehaviorMetadata("PathfindingBehavior::PathfindingObstacleBehavior")

View File

@@ -21,6 +21,8 @@ void PathfindingBehavior::InitializeContent(
behaviorContent.SetAttribute("angleOffset", 0);
behaviorContent.SetAttribute("cellWidth", 20);
behaviorContent.SetAttribute("cellHeight", 20);
behaviorContent.SetAttribute("gridOffsetX", 0);
behaviorContent.SetAttribute("gridOffsetY", 0);
behaviorContent.SetAttribute("extraBorder", 0);
}
@@ -46,9 +48,13 @@ std::map<gd::String, gd::PropertyDescriptor> PathfindingBehavior::GetProperties(
properties[_("Angle offset")].SetValue(
gd::String::From(behaviorContent.GetDoubleAttribute("angleOffset")));
properties[_("Virtual cell width")].SetValue(
gd::String::From(behaviorContent.GetIntAttribute("cellWidth", 0)));
gd::String::From(behaviorContent.GetDoubleAttribute("cellWidth", 0)));
properties[_("Virtual cell height")].SetValue(
gd::String::From(behaviorContent.GetIntAttribute("cellHeight", 0)));
gd::String::From(behaviorContent.GetDoubleAttribute("cellHeight", 0)));
properties[_("Virtual grid X offset")].SetValue(
gd::String::From(behaviorContent.GetDoubleAttribute("gridOffsetX", 0)));
properties[_("Virtual grid Y offset")].SetValue(
gd::String::From(behaviorContent.GetDoubleAttribute("gridOffsetY", 0)));
properties[_("Extra border size")].SetValue(
gd::String::From(behaviorContent.GetDoubleAttribute("extraBorder")));
@@ -82,9 +88,13 @@ bool PathfindingBehavior::UpdateProperty(gd::SerializerElement& behaviorContent,
else if (name == _("Angle offset"))
behaviorContent.SetAttribute("angleOffset", value.To<float>());
else if (name == _("Virtual cell width"))
behaviorContent.SetAttribute("cellWidth", (int)value.To<unsigned int>());
behaviorContent.SetAttribute("cellWidth", value.To<float>());
else if (name == _("Virtual cell height"))
behaviorContent.SetAttribute("cellHeight", (int)value.To<unsigned int>());
behaviorContent.SetAttribute("cellHeight", value.To<float>());
else if (name == _("Virtual grid X offset"))
behaviorContent.SetAttribute("gridOffsetX", value.To<float>());
else if (name == _("Virtual grid Y offset"))
behaviorContent.SetAttribute("gridOffsetY", value.To<float>());
else
return false;

View File

@@ -17,8 +17,10 @@ namespace gdjs {
_angularMaxSpeed: float;
_rotateObject: boolean;
_angleOffset: float;
_cellWidth: integer;
_cellHeight: integer;
_cellWidth: float;
_cellHeight: float;
_gridOffsetX: float;
_gridOffsetY: float;
_extraBorder: float;
//Attributes used for traveling on the path:
@@ -32,6 +34,8 @@ namespace gdjs {
_manager: PathfindingObstaclesManager;
_searchContext: PathfindingRuntimeBehavior.SearchContext;
_movementAngle: float = 0;
constructor(
runtimeScene: gdjs.RuntimeScene,
behaviorData,
@@ -52,6 +56,8 @@ namespace gdjs {
this._angleOffset = behaviorData.angleOffset;
this._cellWidth = behaviorData.cellWidth;
this._cellHeight = behaviorData.cellHeight;
this._gridOffsetX = behaviorData.gridOffsetX || 0;
this._gridOffsetY = behaviorData.gridOffsetY || 0;
this._extraBorder = behaviorData.extraBorder;
this._manager = gdjs.PathfindingObstaclesManager.getManager(runtimeScene);
this._searchContext = new gdjs.PathfindingRuntimeBehavior.SearchContext(
@@ -84,28 +90,50 @@ namespace gdjs {
if (oldBehaviorData.cellHeight !== newBehaviorData.cellHeight) {
this.setCellHeight(newBehaviorData.cellHeight);
}
if (oldBehaviorData.gridOffsetX !== newBehaviorData.gridOffsetX) {
this._gridOffsetX = newBehaviorData.gridOffsetX;
}
if (oldBehaviorData.gridOffsetY !== newBehaviorData.gridOffsetY) {
this._gridOffsetY = newBehaviorData.gridOffsetY;
}
if (oldBehaviorData.extraBorder !== newBehaviorData.extraBorder) {
this.setExtraBorder(newBehaviorData.extraBorder);
}
return true;
}
setCellWidth(width: integer): void {
setCellWidth(width: float): void {
this._cellWidth = width;
}
getCellWidth(): integer {
getCellWidth(): float {
return this._cellWidth;
}
setCellHeight(height: integer): void {
setCellHeight(height: float): void {
this._cellHeight = height;
}
getCellHeight(): integer {
getCellHeight(): float {
return this._cellHeight;
}
setGridOffsetX(gridOffsetX: float): void {
this._gridOffsetX = gridOffsetX;
}
getGridOffsetX(): float {
return this._gridOffsetX;
}
setGridOffsetY(gridOffsetY: float): void {
this._gridOffsetY = gridOffsetY;
}
getGridOffsetY(): float {
return this._gridOffsetY;
}
setAcceleration(acceleration: float): void {
this._acceleration = acceleration;
}
@@ -130,6 +158,19 @@ namespace gdjs {
return this._speed;
}
getMovementAngle() {
return this._movementAngle;
}
movementAngleIsAround(degreeAngle: float, tolerance: float) {
return (
gdjs.evtTools.common.angleDifference(
this._movementAngle,
degreeAngle
) <= tolerance
);
}
setAngularMaxSpeed(angularMaxSpeed: float): void {
this._angularMaxSpeed = angularMaxSpeed;
}
@@ -275,10 +316,16 @@ namespace gdjs {
const owner = this.owner;
//First be sure that there is a path to compute.
const targetCellX = Math.round(x / this._cellWidth);
const targetCellY = Math.round(y / this._cellHeight);
const startCellX = Math.round(owner.getX() / this._cellWidth);
const startCellY = Math.round(owner.getY() / this._cellHeight);
const targetCellX = Math.round((x - this._gridOffsetX) / this._cellWidth);
const targetCellY = Math.round(
(y - this._gridOffsetY) / this._cellHeight
);
const startCellX = Math.round(
(owner.getX() - this._gridOffsetX) / this._cellWidth
);
const startCellY = Math.round(
(owner.getY() - this._gridOffsetY) / this._cellHeight
);
if (startCellX == targetCellX && startCellY == targetCellY) {
this._path.length = 0;
this._path.push([owner.getX(), owner.getY()]);
@@ -292,6 +339,7 @@ namespace gdjs {
this._searchContext.allowDiagonals(this._allowDiagonals);
this._searchContext.setObstacles(this._manager);
this._searchContext.setCellSize(this._cellWidth, this._cellHeight);
this._searchContext.setGridOffset(this._gridOffsetX, this._gridOffsetY);
this._searchContext.setStartPosition(owner.getX(), owner.getY());
this._searchContext.setObjectSize(
owner.getX() - owner.getDrawableX() + this._extraBorder,
@@ -311,8 +359,10 @@ namespace gdjs {
if (finalPathLength === this._path.length) {
this._path.push([0, 0]);
}
this._path[finalPathLength][0] = node.pos[0] * this._cellWidth;
this._path[finalPathLength][1] = node.pos[1] * this._cellHeight;
this._path[finalPathLength][0] =
node.pos[0] * this._cellWidth + this._gridOffsetX;
this._path[finalPathLength][1] =
node.pos[1] * this._cellHeight + this._gridOffsetY;
node = node.parent;
finalPathLength++;
}
@@ -344,6 +394,8 @@ namespace gdjs {
this._totalSegmentTime = Math.sqrt(pathX * pathX + pathY * pathY);
this._timeOnSegment = 0;
this._reachedEnd = false;
this._movementAngle =
((Math.atan2(pathY, pathX) * 180) / Math.PI + 360) % 360;
} else {
this._reachedEnd = true;
this._speed = 0;
@@ -446,11 +498,11 @@ namespace gdjs {
parent: Node | null = null;
open: boolean = true;
constructor(xPos: float, yPos: float) {
constructor(xPos: integer, yPos: integer) {
this.pos = [xPos, yPos];
}
reinitialize(xPos: float, yPos: float) {
reinitialize(xPos: integer, yPos: integer) {
this.pos[0] = xPos;
this.pos[1] = yPos;
this.cost = 0;
@@ -477,28 +529,28 @@ namespace gdjs {
_maxComplexityFactor: integer = 50;
_cellWidth: float = 20;
_cellHeight: float = 20;
_gridOffsetX: float = 0;
_gridOffsetY: float = 0;
_leftBorder: integer = 0;
_rightBorder: integer = 0;
_topBorder: integer = 0;
_bottomBorder: integer = 0;
_distanceFunction: (pt1: FloatPoint, pt2: FloatPoint) => float;
_allNodes: Node[][] = [];
//An array of array. Nodes are indexed by their x position, and then by their y position.
_allNodes: Node[][] = [];
//An array of nodes sorted by their estimate cost (First node = Lower estimate cost).
_openNodes: Node[] = [];
_closeObstacles: PathfindingObstacleRuntimeBehavior[] = [];
//Used by getNodes to temporarily store obstacles near a position.
_closeObstacles: PathfindingObstacleRuntimeBehavior[] = [];
//Old nodes constructed in a previous search are stored here to avoid temporary objects (see _freeAllNodes method).
_nodeCache: Node[] = [];
constructor(obstacles: PathfindingObstaclesManager) {
this._obstacles = obstacles;
this._distanceFunction = PathfindingRuntimeBehavior.euclideanDistance;
//An array of nodes sorted by their estimate cost (First node = Lower estimate cost).
}
//Old nodes constructed in a previous search are stored here to avoid temporary objects (see _freeAllNodes method).
setObstacles(
obstacles: PathfindingObstaclesManager
): PathfindingRuntimeBehavior.SearchContext {
@@ -549,6 +601,15 @@ namespace gdjs {
return this;
}
setGridOffset(
gridOffsetX: float,
gridOffsetY: float
): PathfindingRuntimeBehavior.SearchContext {
this._gridOffsetX = gridOffsetX;
this._gridOffsetY = gridOffsetY;
return this;
}
computePathTo(targetX: float, targetY: float) {
if (this._obstacles === null) {
console.log(
@@ -556,10 +617,18 @@ namespace gdjs {
);
return;
}
this._destination[0] = Math.round(targetX / this._cellWidth);
this._destination[1] = Math.round(targetY / this._cellHeight);
this._start[0] = Math.round(this._startX / this._cellWidth);
this._start[1] = Math.round(this._startY / this._cellHeight);
this._destination[0] = Math.round(
(targetX - this._gridOffsetX) / this._cellWidth
);
this._destination[1] = Math.round(
(targetY - this._gridOffsetY) / this._cellHeight
);
this._start[0] = Math.round(
(this._startX - this._gridOffsetX) / this._cellWidth
);
this._start[1] = Math.round(
(this._startY - this._gridOffsetY) / this._cellHeight
);
//Initialize the algorithm
this._freeAllNodes();
@@ -679,7 +748,7 @@ namespace gdjs {
* *All* nodes should be created using this method: The cost of the node is computed thanks
* to the objects flagged as obstacles.
*/
_getNode(xPos: float, yPos: float): Node {
_getNode(xPos: integer, yPos: integer): Node {
//First check if their is a node a the specified position.
if (this._allNodes.hasOwnProperty(xPos)) {
if (this._allNodes[xPos].hasOwnProperty(yPos)) {
@@ -698,6 +767,9 @@ namespace gdjs {
newNode = new Node(xPos, yPos);
}
const nodeCenterX = xPos * this._cellWidth + this._gridOffsetX;
const nodeCenterY = yPos * this._cellHeight + this._gridOffsetY;
//...and update its cost according to obstacles
let objectsOnCell = false;
const radius =
@@ -705,25 +777,33 @@ namespace gdjs {
? this._cellHeight * 2
: this._cellWidth * 2;
this._obstacles.getAllObstaclesAround(
xPos * this._cellWidth,
yPos * this._cellHeight,
nodeCenterX,
nodeCenterY,
radius,
this._closeObstacles
);
for (let k = 0; k < this._closeObstacles.length; ++k) {
const obj = this._closeObstacles[k].owner;
const topLeftCellX = Math.floor(
(obj.getDrawableX() - this._rightBorder) / this._cellWidth
(obj.getDrawableX() - this._rightBorder - this._gridOffsetX) /
this._cellWidth
);
const topLeftCellY = Math.floor(
(obj.getDrawableY() - this._bottomBorder) / this._cellHeight
(obj.getDrawableY() - this._bottomBorder - this._gridOffsetY) /
this._cellHeight
);
const bottomRightCellX = Math.ceil(
(obj.getDrawableX() + obj.getWidth() + this._leftBorder) /
(obj.getDrawableX() +
obj.getWidth() +
this._leftBorder -
this._gridOffsetX) /
this._cellWidth
);
const bottomRightCellY = Math.ceil(
(obj.getDrawableY() + obj.getHeight() + this._topBorder) /
(obj.getDrawableY() +
obj.getHeight() +
this._topBorder -
this._gridOffsetY) /
this._cellHeight
);
if (
@@ -733,14 +813,12 @@ namespace gdjs {
yPos < bottomRightCellY
) {
objectsOnCell = true;
//The cell is impassable, stop here.
//Superimpose obstacles
if (this._closeObstacles[k].isImpassable()) {
//The cell is impassable, stop here.
newNode.cost = -1;
break;
} else {
//Superimpose obstacles
newNode.cost += this._closeObstacles[k].getCost();
}
}
@@ -758,8 +836,8 @@ namespace gdjs {
* Add a node to the openNodes (only if the cost to reach it is less than the existing cost, if any).
*/
_addOrUpdateNode(
newNodeX: float,
newNodeY: float,
newNodeX: integer,
newNodeY: integer,
currentNode: Node,
factor: float
) {

View File

@@ -64,10 +64,10 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) {
obj.AddAction("Line",
_("Line"),
_("Draw a line on screen"),
_("Draw from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ a line "
"(thickness: _PARAM5_) "
"with _PARAM0_"),
"Draw a line on screen",
"Draw from _PARAM1_;_PARAM2_ to _PARAM3_;_PARAM4_ a line "
"(thickness: _PARAM5_) "
"with _PARAM0_",
_("Drawing"),
"res/actions/line24.png",
"res/actions/line.png")

View File

@@ -147,9 +147,9 @@ void DeclareTiledSpriteObjectExtension(gd::PlatformExtension& extension) {
.SetIncludeFile("TiledSpriteObject/TiledSpriteObject.h");
obj.AddCondition("Angle",
_("Angle"),
_("Test the angle of a Tiled Sprite."),
_("the angle"),
"Angle",
"Test the angle of a Tiled Sprite.",
"the angle",
_("Size and angle"),
"res/conditions/rotate24.png",
"res/conditions/rotate.png")

View File

@@ -5,11 +5,11 @@ Copyright (c) 2010-2016 Florian Rival (Florian.Rival@gmail.com)
This project is released under the MIT License.
*/
#if defined(GD_IDE_ONLY)
#include <iostream>
#include "GDCore/Extensions/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include <iostream>
void DeclareTopDownMovementBehaviorExtension(gd::PlatformExtension& extension);
/**
@@ -68,17 +68,20 @@ class TopDownMovementBehaviorJsExtension : public gd::PlatformExtension {
.SetGetter("getAngleOffset");
autConditions["TopDownMovementBehavior::AngleOffset"].SetFunctionName(
"getAngleOffset");
autConditions["TopDownMovementBehavior::Angle"].SetFunctionName(
"getAngle");
autConditions["TopDownMovementBehavior::Angle"].SetFunctionName("getAngle");
autConditions["TopDownMovementBehavior::XVelocity"].SetFunctionName(
"getXVelocity");
autConditions["TopDownMovementBehavior::YVelocity"].SetFunctionName(
"getYVelocity");
autActions["TopDownMovementBehavior::SetMovementAngleOffset"]
.SetFunctionName("setMovementAngleOffset")
.SetGetter("getMovementAngleOffset");
autConditions["TopDownMovementBehavior::MovementAngleOffset"].SetFunctionName(
"getMovementAngleOffset");
autActions
["TopDownMovementBehavior::TopDownMovementBehavior::"
"SetMovementAngleOffset"]
.SetFunctionName("setMovementAngleOffset")
.SetGetter("getMovementAngleOffset");
autConditions
["TopDownMovementBehavior::TopDownMovementBehavior::"
"MovementAngleOffset"]
.SetFunctionName("getMovementAngleOffset");
autActions["TopDownMovementBehavior::AllowDiagonals"].SetFunctionName(
"allowDiagonals");
@@ -113,7 +116,8 @@ class TopDownMovementBehaviorJsExtension : public gd::PlatformExtension {
autExpressions["Angle"].SetFunctionName("getAngle");
autExpressions["XVelocity"].SetFunctionName("getXVelocity");
autExpressions["YVelocity"].SetFunctionName("getYVelocity");
autExpressions["MovementAngleOffset"].SetFunctionName("getMovementAngleOffset");
autExpressions["MovementAngleOffset"].SetFunctionName(
"getMovementAngleOffset");
GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION();
};

1
GDJS/.gitignore vendored
View File

@@ -1,2 +1 @@
/node_modules
/Runtime-dist

View File

@@ -13,6 +13,7 @@
#include "GDCore/CommonTools.h"
#include "GDCore/IDE/AbstractFileSystem.h"
#include "GDCore/IDE/Events/UsedExtensionsFinder.h"
#include "GDCore/IDE/Project/ProjectResourcesCopier.h"
#include "GDCore/IDE/ProjectStripper.h"
#include "GDCore/Project/ExternalEvents.h"
@@ -26,11 +27,12 @@
#include "GDCore/Tools/Log.h"
#include "GDJS/Events/CodeGeneration/EventsCodeGenerator.h"
#include "GDJS/IDE/ExporterHelper.h"
#undef CopyFile // Disable an annoying macro
namespace gdjs {
Exporter::Exporter(gd::AbstractFileSystem& fileSystem, gd::String gdjsRoot_)
Exporter::Exporter(gd::AbstractFileSystem &fileSystem, gd::String gdjsRoot_)
: fs(fileSystem), gdjsRoot(gdjsRoot_) {
SetCodeOutputDirectory(fs.GetTempDir() + "/GDTemporaries/JSCodeTemp");
}
@@ -38,18 +40,20 @@ Exporter::Exporter(gd::AbstractFileSystem& fileSystem, gd::String gdjsRoot_)
Exporter::~Exporter() {}
bool Exporter::ExportProjectForPixiPreview(
const PreviewExportOptions& options) {
const PreviewExportOptions &options) {
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
return helper.ExportProjectForPixiPreview(options);
}
bool Exporter::ExportWholePixiProject(
gd::Project& project,
gd::Project &project,
gd::String exportDir,
std::map<gd::String, bool>& exportOptions) {
std::map<gd::String, bool> &exportOptions) {
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
gd::Project exportedProject = project;
auto usedExtensions = gd::UsedExtensionsFinder::ScanProject(project);
auto exportProject = [this, &exportedProject, &exportOptions, &helper](
gd::String exportDir) {
bool exportForCordova = exportOptions["exportForCordova"];
@@ -141,13 +145,15 @@ bool Exporter::ExportWholePixiProject(
if (!exportProject(exportDir + "/www")) return false;
if (!helper.ExportCordovaFiles(exportedProject, exportDir)) return false;
if (!helper.ExportCordovaFiles(exportedProject, exportDir, usedExtensions))
return false;
} else if (exportOptions["exportForElectron"]) {
fs.MkDir(exportDir);
if (!exportProject(exportDir + "/app")) return false;
if (!helper.ExportElectronFiles(exportedProject, exportDir)) return false;
if (!helper.ExportElectronFiles(exportedProject, exportDir, usedExtensions))
return false;
} else if (exportOptions["exportForFacebookInstantGames"]) {
if (!exportProject(exportDir)) return false;
@@ -160,12 +166,12 @@ bool Exporter::ExportWholePixiProject(
return true;
}
bool Exporter::ExportWholeCocos2dProject(gd::Project& project,
bool Exporter::ExportWholeCocos2dProject(gd::Project &project,
bool debugMode,
gd::String exportDir) {
ExporterHelper helper(fs, gdjsRoot, codeOutputDir);
wxProgressDialog* progressDialogPtr = NULL;
wxProgressDialog *progressDialogPtr = NULL;
// Prepare the export directory
fs.MkDir(exportDir);

View File

@@ -234,7 +234,8 @@ bool ExporterHelper::ExportPixiIndexFile(
}
bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
gd::String exportDir) {
gd::String exportDir,
std::set<gd::String> usedExtensions) {
auto &platformSpecificAssets = project.GetPlatformSpecificAssets();
auto &resourceManager = project.GetResourcesManager();
auto getIconFilename = [&resourceManager, &platformSpecificAssets](
@@ -294,7 +295,8 @@ bool ExporterHelper::ExportCordovaFiles(const gd::Project &project,
gd::String plugins = "";
auto dependenciesAndExtensions =
gd::ExportedDependencyResolver::GetDependenciesFor(project, "cordova");
gd::ExportedDependencyResolver::GetDependenciesFor(
project, usedExtensions, "cordova");
for (auto &dependencyAndExtension : dependenciesAndExtensions) {
const auto &dependency = dependencyAndExtension.GetDependency();
@@ -462,7 +464,8 @@ bool ExporterHelper::ExportFacebookInstantGamesFiles(const gd::Project &project,
}
bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
gd::String exportDir) {
gd::String exportDir,
std::set<gd::String> usedExtensions) {
gd::String jsonName =
gd::Serializer::ToJSON(gd::SerializerElement(project.GetName()));
gd::String jsonPackageName =
@@ -489,7 +492,8 @@ bool ExporterHelper::ExportElectronFiles(const gd::Project &project,
gd::String packages = "";
auto dependenciesAndExtensions =
gd::ExportedDependencyResolver::GetDependenciesFor(project, "npm");
gd::ExportedDependencyResolver::GetDependenciesFor(
project, usedExtensions, "npm");
for (auto &dependencyAndExtension : dependenciesAndExtensions) {
const auto &dependency = dependencyAndExtension.GetDependency();
if (dependency.GetVersion() == "") {

View File

@@ -276,7 +276,9 @@ class ExporterHelper {
* \param project The project to be used to generate the configuration file.
* \param exportDir The directory where the config.xml must be created.
*/
bool ExportCordovaFiles(const gd::Project &project, gd::String exportDir);
bool ExportCordovaFiles(const gd::Project &project,
gd::String exportDir,
std::set<gd::String> usedExtensions);
/**
* \brief Generate the base Cocos2d files.
@@ -293,7 +295,9 @@ class ExporterHelper {
* \param project The project to be used to generate the files.
* \param exportDir The directory where the files must be created.
*/
bool ExportElectronFiles(const gd::Project &project, gd::String exportDir);
bool ExportElectronFiles(const gd::Project &project,
gd::String exportDir,
std::set<gd::String> usedExtensions);
/**
* \brief Generate the Facebook Instant Games files for packaging and save it

View File

@@ -357,10 +357,10 @@ namespace gdjs {
layerName: string,
rgbColor: string
) {
if (!runtimeScene.hasLayer(layerName)) {
return;
}
if (!runtimeScene.getLayer(layerName).isLightingLayer()) {
if (
!runtimeScene.hasLayer(layerName) ||
!runtimeScene.getLayer(layerName).isLightingLayer()
) {
return;
}
const colors = rgbColor.split(';');
@@ -370,9 +370,9 @@ namespace gdjs {
return runtimeScene
.getLayer(layerName)
.setClearColor(
parseInt(colors[0]),
parseInt(colors[1]),
parseInt(colors[2])
parseInt(colors[0], 10),
parseInt(colors[1], 10),
parseInt(colors[2], 10)
);
};
}

View File

@@ -103,6 +103,7 @@ namespace gdjs {
responseVar.setString(xhr.responseText);
} catch (e) {}
};
export const enableMetrics = function (
runtimeScene: gdjs.RuntimeScene,
enable: boolean
@@ -114,105 +115,33 @@ namespace gdjs {
* Convert a variable to JSON.
* @param variable The variable to convert to JSON
* @returns The JSON string representing the variable
*
* @deprecated Use `variable.toJSON` instead.
*/
export const variableStructureToJSON = function (
variable: gdjs.Variable
): string {
// TODO: Move this function to gdjs.Variable
if (variable.isPrimitive()) {
return JSON.stringify(variable.getValue());
} else if (variable.getType() === 'array') {
let str = '[';
let firstChild = true;
const children = variable.getAllChildren();
for (const p in children) {
if (children.hasOwnProperty(p)) {
if (!firstChild) {
str += ',';
}
str += variableStructureToJSON(children[p]);
firstChild = false;
}
}
str += ']';
return str;
} else if (variable.getType() === 'structure') {
let str = '{';
let firstChild = true;
const children = variable.getAllChildren();
for (const p in children) {
if (children.hasOwnProperty(p)) {
if (!firstChild) {
str += ',';
}
str +=
JSON.stringify(p) + ': ' + variableStructureToJSON(children[p]);
firstChild = false;
}
}
str += '}';
return str;
}
console.error('JSON conversion error: Variable type not recognized');
return '';
return variable.toJSON();
};
export const objectVariableStructureToJSON = function (object, variable) {
return gdjs.evtTools.network.variableStructureToJSON(variable);
/**
* @deprecated Use `variable.toJSON` instead.
*/
export const objectVariableStructureToJSON = function (
object: gdjs.RuntimeObject,
variable: gdjs.Variable
): string {
return variable.toJSON();
};
/**
* @deprecated Use `variable.fromJSObject` instead.
*/
export const _objectToVariable = function (
obj: any,
variable: gdjs.Variable
) {
if (obj === null) {
variable.setString('null');
} else if (typeof obj === 'number') {
if (Number.isNaN(obj)) {
console.warn('Variables cannot be set to NaN, setting it to 0.');
variable.setNumber(0);
} else {
variable.setNumber(obj);
}
} else if (typeof obj === 'string') {
variable.setString(obj);
} else if (typeof obj === 'undefined') {
// Do not modify the variable, as there is no value to set it to.
} else if (typeof obj === 'boolean') {
variable.setBoolean(obj);
} else if (Array.isArray(obj)) {
variable.castTo('array');
variable.clearChildren();
for (const i in obj) {
_objectToVariable(obj[i], variable.getChild(i));
}
} else if (typeof obj === 'object') {
variable.castTo('structure');
variable.clearChildren();
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
_objectToVariable(obj[p], variable.getChild(p));
}
}
} else if (typeof obj === 'symbol') {
variable.setString(obj.toString());
} else if (typeof obj === 'bigint') {
if (obj > Number.MAX_SAFE_INTEGER)
console.warn(
'Integers bigger than ' +
Number.MAX_SAFE_INTEGER +
" aren't supported by variables, it will be reduced to that size."
);
// @ts-ignore
variable.setNumber(parseInt(obj, 10));
} else if (typeof obj === 'function') {
console.error(
'Error: Impossible to set variable value to a function.'
);
} else {
console.error('Cannot identify type of object:', obj);
}
variable.fromJSObject(obj);
};
/**
@@ -221,30 +150,25 @@ namespace gdjs {
* @param jsonStr The JSON string
* @param variable The variable where to put the parsed JSON
* @returns true if JSON was properly parsed
*
* @deprecated Use `variable.fromJSON` instead.
*/
export const jsonToVariableStructure = function (
jsonStr: string,
variable: gdjs.Variable
): boolean {
// TODO: Move this function to gdjs.Variable
if (jsonStr.length === 0) {
return false;
}
try {
const obj = JSON.parse(jsonStr);
gdjs.evtTools.network._objectToVariable(obj, variable);
return true;
} catch (e) {
// Do nothing if JSON was not properly parsed.
return false;
}
): void {
variable.fromJSON(jsonStr);
};
/**
* @deprecated Use `variable.fromJSON` instead.
*/
export const jsonToObjectVariableStructure = function (
jsonStr,
object,
variable
jsonStr: string,
object: gdjs.RuntimeObject,
variable: gdjs.Variable
) {
gdjs.evtTools.network.jsonToVariableStructure(jsonStr, variable);
variable.fromJSON(jsonStr);
};
}
}

View File

@@ -494,20 +494,10 @@ namespace gdjs {
* @param g Green color component in the range 0-255.
* @param b Blue color component in the range 0-255.
*/
setClearColor(
r: integer | null,
g: integer | null,
b: integer | null
): void {
if (r) {
this._clearColor[0] = r / 255;
}
if (g) {
this._clearColor[1] = g / 255;
}
if (b) {
this._clearColor[2] = b / 255;
}
setClearColor(r: integer, g: integer, b: integer): void {
this._clearColor[0] = r / 255;
this._clearColor[1] = g / 255;
this._clearColor[2] = b / 255;
this._renderer.updateClearColor();
}

View File

@@ -39,6 +39,8 @@ namespace gdjs {
_marginBottom: any;
_notifySceneForResize: any;
_nextFrameId: integer = 0;
/**
* @param game The game that is being rendered
* @param forceFullscreen If fullscreen should be always activated
@@ -533,16 +535,21 @@ namespace gdjs {
}
startGameLoop(fn) {
requestAnimationFrame(gameLoop);
let oldTime = 0;
const gameLoop = (time: float) => {
// Schedule the next frame now to be sure it's called as soon
// as possible after this one is finished.
this._nextFrameId = requestAnimationFrame(gameLoop);
function gameLoop(time) {
const dt = oldTime ? time - oldTime : 0;
oldTime = time;
if (fn(dt)) {
requestAnimationFrame(gameLoop);
if (!fn(dt)) {
// Stop the game loop if requested.
cancelAnimationFrame(this._nextFrameId);
}
}
};
requestAnimationFrame(gameLoop);
}
getPIXIRenderer() {

View File

@@ -635,10 +635,7 @@ namespace gdjs {
* @static
*/
static getVariableChildCount(variable: gdjs.Variable): integer {
if (variable.isStructure() == false) {
return 0;
}
return Object.keys(variable.getAllChildren()).length;
return variable.getChildrenCount();
}
/**

View File

@@ -28,6 +28,8 @@ declare type ObjectData = {
variables: Array<RootVariableData>;
/** The list of default behaviors. */
behaviors: Array<BehaviorData>;
/** The list of effects. */
effects: Array<EffectData>;
};
declare type VariableType =

View File

@@ -13,6 +13,7 @@ namespace gdjs {
* A Variable is an object storing a value (number or a string) or children variables.
*/
export class Variable {
// TODO: convert this to an integer to speed up the type checks at runtime.
_type: VariableType = 'number';
_value: float = 0;
_str: string = '0';
@@ -100,6 +101,102 @@ namespace gdjs {
return target;
}
/**
* Converts a JavaScript object into a value compatible
* with GDevelop variables and store it inside this variable.
* @param obj - The value to convert.
*/
fromJSObject(obj: any): this {
if (obj === null) {
this.setString('null');
} else if (typeof obj === 'number') {
if (Number.isNaN(obj)) {
console.warn('Variables cannot be set to NaN, setting it to 0.');
this.setNumber(0);
} else {
this.setNumber(obj);
}
} else if (typeof obj === 'string') {
this.setString(obj);
} else if (typeof obj === 'undefined') {
// Do not modify the variable, as there is no value to set it to.
} else if (typeof obj === 'boolean') {
this.setBoolean(obj);
} else if (Array.isArray(obj)) {
this.castTo('array');
this.clearChildren();
for (const i in obj) this.getChild(i).fromJSObject(obj[i]);
} else if (typeof obj === 'object') {
this.castTo('structure');
this.clearChildren();
for (var p in obj)
if (obj.hasOwnProperty(p)) this.getChild(p).fromJSObject(obj[p]);
} else if (typeof obj === 'symbol') {
this.setString(obj.toString());
} else if (typeof obj === 'bigint') {
if (obj > Number.MAX_SAFE_INTEGER)
console.warn(
'Integers bigger than ' +
Number.MAX_SAFE_INTEGER +
" aren't supported by GDevelop variables, it will be reduced to that size."
);
// @ts-ignore
variable.setNumber(parseInt(obj, 10));
} else if (typeof obj === 'function') {
console.error('Error: Impossible to set variable value to a function.');
} else {
console.error('Cannot identify type of object:', obj);
}
return this;
}
/**
* Unserialize JSON into this variable.
* @param json - A JSON string.
*/
fromJSON(json: string): this {
try {
var obj = JSON.parse(json);
} catch (e) {
console.error('Unable to parse JSON: ', json, e);
return this;
}
this.fromJSObject(obj);
return this;
}
/**
* Converts this variable into an equivalent JavaScript object.
* @returns A JavaScript object equivalent to the variable.
*/
toJSObject(): any {
switch (this._type) {
case 'string':
return this.getAsString();
case 'number':
return this.getAsNumber();
case 'boolean':
return this.getAsBoolean();
case 'structure':
const obj = {};
for (const name in this._children)
obj[name] = this._children[name].toJSObject();
return obj;
case 'array':
const arr: any[] = [];
for (const item of this._childrenArray) arr.push(item.toJSObject());
return arr;
}
}
/**
* Converts this variable to JSON.
* @returns A JSON representation of the variable.
*/
toJSON(): string {
return JSON.stringify(this.toJSObject());
}
/**
* Return true if the type of the variable is a primitive type.
*/
@@ -359,7 +456,7 @@ namespace gdjs {
}
/**
* Return the object containing all the children of the variable
* Return the object containing all the children of the variable.
* @return All the children of the variable
*/
getAllChildren(): Children {
@@ -371,7 +468,7 @@ namespace gdjs {
}
/**
* Return an Array containing all the children of the variable
* Return an Array containing all the children of the variable.
*/
getAllChildrenArray(): gdjs.Variable[] {
return this._type === 'structure'
@@ -382,11 +479,14 @@ namespace gdjs {
}
/**
* Return the length of the collection
* Return the length of the collection.
*/
getChildrenCount() {
if (this.isPrimitive()) return 0;
return this.getAllChildrenArray().length;
getChildrenCount(): integer {
return this._type === 'structure'
? Object.keys(this._children).length
: this._type === 'array'
? this._childrenArray.length
: 0;
}
/**

View File

@@ -223,6 +223,10 @@ namespace gdjs {
_str: '',
_undefinedInContainer: true,
_value: 0,
toJSON: () => '0',
fromJSON: () => gdjs.VariablesContainer.badVariable,
toJSObject: () => 0,
fromJSObject: () => gdjs.VariablesContainer.badVariable,
reinitialize: () => {},
addChild: () => gdjs.VariablesContainer.badVariable,
castTo: () => {},

View File

@@ -960,14 +960,16 @@ namespace gdjs {
runtimeLayer.show(newLayer.visibility);
}
if (newLayer.isLightingLayer) {
if (oldLayer.ambientLightColorR !== newLayer.ambientLightColorR) {
runtimeLayer.setClearColor(newLayer.ambientLightColorR, null, null);
}
if (oldLayer.ambientLightColorG !== newLayer.ambientLightColorG) {
runtimeLayer.setClearColor(null, newLayer.ambientLightColorG, null);
}
if (oldLayer.ambientLightColorB !== newLayer.ambientLightColorB) {
runtimeLayer.setClearColor(null, null, newLayer.ambientLightColorB);
if (
oldLayer.ambientLightColorR !== newLayer.ambientLightColorR ||
oldLayer.ambientLightColorG !== newLayer.ambientLightColorG ||
oldLayer.ambientLightColorB !== newLayer.ambientLightColorB
) {
runtimeLayer.setClearColor(
newLayer.ambientLightColorR,
newLayer.ambientLightColorG,
newLayer.ambientLightColorB
);
}
if (oldLayer.followBaseLayerCamera !== newLayer.followBaseLayerCamera) {
runtimeLayer.setFollowBaseLayerCamera(newLayer.followBaseLayerCamera);

View File

@@ -4,8 +4,10 @@ const shell = require('shelljs');
const {
getAllInOutFilePaths,
isUntransformedFile,
getOutRootPath,
} = require('./lib/runtime-files-list');
const args = require('minimist')(process.argv.slice(2), {
string: ['out'],
});
const fs = require('fs').promises;
/** @param {string} outPath */
@@ -13,7 +15,15 @@ const renameBuiltFile = (outPath) => {
return outPath.replace(/\.ts$/, '.js');
};
shell.mkdir('-p', getOutRootPath());
const bundledOutPath =
args.out || path.join(__dirname, '../../newIDE/app/resources/GDJS/Runtime');
if (!args.out) {
shell.echo(
` --out (path where to build GDJS Runtime and Extensions) not specified. Using "../../newIDE/app/resources/GDJS/Runtime" by default (used by electron-app and GDJS tests).`
);
}
shell.mkdir('-p', bundledOutPath);
(async () => {
const esbuildService = await esbuild.startService();
@@ -22,7 +32,7 @@ shell.mkdir('-p', getOutRootPath());
const {
allGDJSInOutFilePaths,
allExtensionsInOutFilePaths,
} = await getAllInOutFilePaths();
} = await getAllInOutFilePaths({ bundledOutPath });
// Build (or copy) all the files
let errored = false;

View File

@@ -7,7 +7,6 @@ const gdjsRootPath = path.join(__dirname, '..', '..');
const extensionsRuntimePath = path.join(gdevelopRootPath, 'Extensions');
const gdjsRuntimePath = path.join(gdjsRootPath, 'Runtime');
const bundledOutPath = path.join(gdjsRootPath, 'Runtime-dist');
// The extensions to be included in the bundled Runtime (will be built with esbuild or copied).
const allowedExtensions = ['.js', '.ts', '.html', '.json', '.xml'];
@@ -87,7 +86,7 @@ const isJsExtensionDeclaration = (filePath) => {
/** @typedef {{inPath: string; outPath: string;}} InOutPath */
/** Returns a function to generate the file paths in the bundled runtime. */
const getInOutPaths = (basePath) => (inPath) => {
const getInOutPaths = (basePath, bundledOutPath) => (inPath) => {
const relativePath = path.relative(basePath, inPath);
return {
inPath,
@@ -96,10 +95,6 @@ const getInOutPaths = (basePath) => (inPath) => {
};
module.exports = {
/**
* Returns the path where the bundled Runtime will be generated.
*/
getOutRootPath: () => bundledOutPath,
/**
* Check if a file must be copied without being built with esbuild.
* @param {string} path
@@ -123,9 +118,10 @@ module.exports = {
},
/**
* Get the list of all files part of the runtime, and their destination file when the runtime is bundled.
* @param {{bundledOutPath: string}} options
* @returns {Promise<{allGDJSInOutFilePaths: InOutPath[]; allExtensionsInOutFilePaths: InOutPath[];}>}
*/
getAllInOutFilePaths: async () => {
getAllInOutFilePaths: async (options) => {
// List all the files of the runtime
const allGDJSInFilePaths = await recursive(gdjsRuntimePath, [
isNotAllowedExtension,
@@ -137,10 +133,10 @@ module.exports = {
// Generate the output file paths
const allGDJSInOutFilePaths = allGDJSInFilePaths.map(
getInOutPaths(gdjsRuntimePath)
getInOutPaths(gdjsRuntimePath, options.bundledOutPath)
);
const allExtensionsInOutFilePaths = allExtensionsInFilePaths.map(
getInOutPaths(gdevelopRootPath)
getInOutPaths(gdevelopRootPath, options.bundledOutPath)
);
return { allGDJSInOutFilePaths, allExtensionsInOutFilePaths };

View File

@@ -20,62 +20,62 @@ module.exports = function (config) {
'node_modules/expect.js/index.js',
//GDJS game engine files: (Order is important)
'../Runtime-dist/libs/jshashtable.js',
'../Runtime-dist/gd.js',
'../Runtime-dist/libs/rbush.js',
'../Runtime-dist/cocos-renderers/cocos-director-manager.js',
'../Runtime-dist/pixi-renderers/pixi.js',
'../Runtime-dist/pixi-renderers/*.js',
'../Runtime-dist/howler-sound-manager/howler.min.js',
'../Runtime-dist/howler-sound-manager/howler-sound-manager.js',
'../Runtime-dist/fontfaceobserver-font-manager/fontfaceobserver.js',
'../Runtime-dist/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js',
'../Runtime-dist/jsonmanager.js',
'../Runtime-dist/timemanager.js',
'../Runtime-dist/timemanager.js',
'../Runtime-dist/runtimeobject.js',
'../Runtime-dist/runtimescene.js',
'../Runtime-dist/scenestack.js',
'../Runtime-dist/profiler.js',
'../Runtime-dist/polygon.js',
'../Runtime-dist/force.js',
'../Runtime-dist/layer.js',
'../Runtime-dist/timer.js',
'../Runtime-dist/inputmanager.js',
'../Runtime-dist/runtimegame.js',
'../Runtime-dist/variable.js',
'../Runtime-dist/variablescontainer.js',
'../Runtime-dist/oncetriggers.js',
'../Runtime-dist/runtimebehavior.js',
'../Runtime-dist/spriteruntimeobject.js',
'../Runtime-dist/events-tools/commontools.js',
'../Runtime-dist/events-tools/runtimescenetools.js',
'../Runtime-dist/events-tools/inputtools.js',
'../Runtime-dist/events-tools/networktools.js',
'../Runtime-dist/events-tools/objecttools.js',
'../Runtime-dist/events-tools/cameratools.js',
'../Runtime-dist/events-tools/soundtools.js',
'../Runtime-dist/events-tools/storagetools.js',
'../Runtime-dist/events-tools/stringtools.js',
'../Runtime-dist/events-tools/windowtools.js',
'../Runtime-dist/websocket-debugger-client/hot-reloader.js',
'../../newIDE/app/resources/GDJS/Runtime/libs/jshashtable.js',
'../../newIDE/app/resources/GDJS/Runtime/gd.js',
'../../newIDE/app/resources/GDJS/Runtime/libs/rbush.js',
'../../newIDE/app/resources/GDJS/Runtime/cocos-renderers/cocos-director-manager.js',
'../../newIDE/app/resources/GDJS/Runtime/pixi-renderers/pixi.js',
'../../newIDE/app/resources/GDJS/Runtime/pixi-renderers/*.js',
'../../newIDE/app/resources/GDJS/Runtime/howler-sound-manager/howler.min.js',
'../../newIDE/app/resources/GDJS/Runtime/howler-sound-manager/howler-sound-manager.js',
'../../newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver.js',
'../../newIDE/app/resources/GDJS/Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js',
'../../newIDE/app/resources/GDJS/Runtime/jsonmanager.js',
'../../newIDE/app/resources/GDJS/Runtime/timemanager.js',
'../../newIDE/app/resources/GDJS/Runtime/timemanager.js',
'../../newIDE/app/resources/GDJS/Runtime/runtimeobject.js',
'../../newIDE/app/resources/GDJS/Runtime/runtimescene.js',
'../../newIDE/app/resources/GDJS/Runtime/scenestack.js',
'../../newIDE/app/resources/GDJS/Runtime/profiler.js',
'../../newIDE/app/resources/GDJS/Runtime/polygon.js',
'../../newIDE/app/resources/GDJS/Runtime/force.js',
'../../newIDE/app/resources/GDJS/Runtime/layer.js',
'../../newIDE/app/resources/GDJS/Runtime/timer.js',
'../../newIDE/app/resources/GDJS/Runtime/inputmanager.js',
'../../newIDE/app/resources/GDJS/Runtime/runtimegame.js',
'../../newIDE/app/resources/GDJS/Runtime/variable.js',
'../../newIDE/app/resources/GDJS/Runtime/variablescontainer.js',
'../../newIDE/app/resources/GDJS/Runtime/oncetriggers.js',
'../../newIDE/app/resources/GDJS/Runtime/runtimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/spriteruntimeobject.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/commontools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/runtimescenetools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/inputtools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/networktools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/objecttools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/cameratools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/soundtools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/storagetools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/stringtools.js',
'../../newIDE/app/resources/GDJS/Runtime/events-tools/windowtools.js',
'../../newIDE/app/resources/GDJS/Runtime/websocket-debugger-client/hot-reloader.js',
//Extensions:
'../Runtime-dist/Extensions/DraggableBehavior/draggableruntimebehavior.js',
'../Runtime-dist/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js',
'../Runtime-dist/Extensions/PlatformBehavior/platformruntimebehavior.js',
'../Runtime-dist/Extensions/LinkedObjects/linkedobjects.js',
'../Runtime-dist/Extensions/Inventory/inventory.js',
'../Runtime-dist/Extensions/Inventory/inventorytools.js',
'../Runtime-dist/Extensions/Lighting/lightruntimeobject.js',
'../Runtime-dist/Extensions/Lighting/lightruntimeobject-pixi-renderer.js',
'../Runtime-dist/Extensions/Lighting/lightobstacleruntimebehavior.js',
'../Runtime-dist/Extensions/PathfindingBehavior/pathfindingobstacleruntimebehavior.js',
'../Runtime-dist/Extensions/PathfindingBehavior/pathfindingruntimebehavior.js',
'../Runtime-dist/Extensions/TopDownMovementBehavior/topdownmovementruntimebehavior.js',
'../Runtime-dist/Extensions/TopDownMovementBehavior/topdownobstacleruntimebehavior.js',
'../Runtime-dist/Extensions/Firebase/A_firebasejs/*.js',
'../Runtime-dist/Extensions/Firebase/B_firebasetools/*.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/DraggableBehavior/draggableruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/PlatformBehavior/platformerobjectruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/PlatformBehavior/platformruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/LinkedObjects/linkedobjects.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Inventory/inventory.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Inventory/inventorytools.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Lighting/lightruntimeobject.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Lighting/lightruntimeobject-pixi-renderer.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Lighting/lightobstacleruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/PathfindingBehavior/pathfindingobstacleruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/PathfindingBehavior/pathfindingruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/TopDownMovementBehavior/topdownmovementruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/TopDownMovementBehavior/topdownobstacleruntimebehavior.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Firebase/A_firebasejs/*.js',
'../../newIDE/app/resources/GDJS/Runtime/Extensions/Firebase/B_firebasetools/*.js',
// Test extensions:
'./tests/Extensions/**.js',

View File

@@ -47,6 +47,7 @@ describe('gdjs.RuntimeScene integration tests', function () {
},
],
variables: [],
effects: [],
},
],
instances: [],

View File

@@ -147,26 +147,26 @@ describe('gdjs.Variable', function () {
array.pushVariableCopy(structure.getChild('b'));
// Verify empty string serialization
structure.getChild('d').setString("");
structure.getChild('d').setString('');
// Verify boolean serialization
structure.getChild('e').setBoolean(false);
structure.getChild('f').setBoolean(true);
const b =
'{"alpha": "Apples","beta": true,"Child with quotes \\"\\" and a backlash \\\\": "String with quotes \\"\\", and a backslash \\\\ and new line \\\\n \\\\n\\\\r and brackets {[{}]}!"}';
'{"alpha":"Apples","beta":true,"Child with quotes \\"\\" and a backlash \\\\":"String with quotes \\"\\", and a backslash \\\\ and new line \\\\n \\\\n\\\\r and brackets {[{}]}!"}';
expect(gdjs.evtTools.network.variableStructureToJSON(structure)).to.be(
`{"a": 5,"b": ${b},"c": [49,${b}],"d": "","e": false,"f": true}`
`{"a":5,"b":${b},"c":[49,${b}],"d":"","e":false,"f":true}`
);
});
it('can be unserialized from JSON', function () {
var structure = new gdjs.Variable({ value: '0' });
const b =
'{"alpha": "Apples","beta": true,"Child with quotes \\"\\" and a backlash \\\\": "String with quotes \\"\\", and a backslash \\\\ and new line \\\\n \\\\n\\\\r and brackets {[{}]}!"}';
'{"alpha":"Apples","beta":true,"Child with quotes \\"\\" and a backlash \\\\": "String with quotes \\"\\", and a backslash \\\\ and new line \\\\n \\\\n\\\\r and brackets {[{}]}!"}';
gdjs.evtTools.network.jsonToVariableStructure(
`{"a": 5,"b": ${b},"c": [49,${b}],"d": "","e": false, "f": true}`,
`{"a":5,"b":${b},"c":[49,${b}],"d":"","e": false,"f":true}`,
structure
);

View File

@@ -126,7 +126,7 @@ interface EventsVariablesFinder {
[Const, Value] SetString STATIC_FindAllGlobalVariables([Const, Ref] Platform platform, [Const, Ref] Project project);
[Const, Value] SetString STATIC_FindAllLayoutVariables([Const, Ref] Platform platform, [Const, Ref] Project project, [Const, Ref] Layout layout);
[Const, Value] SetString STATIC_FindAllObjectVariables([Const, Ref] Platform platform, [Const, Ref] Project project, [Const, Ref] Layout layout, [Const, Ref] gdObject obj);
//Inherited from ExpressionParser2NodeWorker:
};
@@ -168,9 +168,6 @@ interface JsPlatform {
void RemoveExtension([Const] DOMString name);
void ReloadBuiltinExtensions();
Behavior GetBehavior([Const] DOMString type);
BehaviorsSharedData GetBehaviorSharedDatas([Const] DOMString type);
[Const, Ref] VectorPlatformExtension GetAllPlatformExtensions();
};
@@ -367,9 +364,6 @@ interface Project {
[Ref] PlatformSpecificAssets GetPlatformSpecificAssets();
[Ref] LoadingScreen GetLoadingScreen();
//createObject
//createEvent
boolean HasLayoutNamed([Const] DOMString name);
[Ref] Layout GetLayout([Const] DOMString name);
[Ref] Layout GetLayoutAt(unsigned long index);
@@ -515,6 +509,7 @@ interface gdObject {
void ExposeResources([Ref] ArbitraryResourceWorker worker);
[Ref] VariablesContainer GetVariables();
[Ref] EffectsContainer GetEffects();
[Value] VectorString GetAllBehaviorNames();
boolean HasBehaviorNamed([Const] DOMString name);
BehaviorContent AddNewBehavior([Ref] Project project, [Const] DOMString type, [Const] DOMString name);
@@ -666,7 +661,7 @@ interface Effect {
interface EffectsContainer {
void EffectsContainer();
boolean HasEffectNamed([Const] DOMString name);
[Ref] Effect GetEffect([Const] DOMString name);
[Ref] Effect GetEffectAt(unsigned long index);
@@ -1027,21 +1022,12 @@ interface VectorPairStringTextFormatting {
};
interface TextFormatting {
boolean IsBold();
boolean IsItalic();
unsigned long GetColorRed();
unsigned long GetColorGreen();
unsigned long GetColorBlue();
unsigned long GetUserData();
};
interface InstructionSentenceFormatter {
InstructionSentenceFormatter STATIC_Get();
[Const, Value] DOMString Translate([Const, Ref] Instruction instr, [Const, Ref] InstructionMetadata metadat);
[Value] VectorPairStringTextFormatting GetAsFormattedText([Const, Ref] Instruction instr, [Const, Ref] InstructionMetadata metadat);
[Value] TextFormatting GetFormattingFromType([Const] DOMString type);
[Const, Value] DOMString LabelFromType([Const] DOMString type);
void LoadTypesFormattingFromConfig();
};
//TODO: This should be renamed to InstructionCodeGenerationInformation
@@ -1944,6 +1930,9 @@ interface MetadataProvider {
[Const, Ref] ExpressionMetadata STATIC_GetStrExpressionMetadata([Const, Ref] Platform p, [Const] DOMString type);
[Const, Ref] ExpressionMetadata STATIC_GetObjectStrExpressionMetadata([Const, Ref] Platform p, [Const] DOMString objectType, [Const] DOMString type);
[Const, Ref] ExpressionMetadata STATIC_GetBehaviorStrExpressionMetadata([Const, Ref] Platform p, [Const] DOMString autoType, [Const] DOMString type);
boolean STATIC_IsBadExpressionMetadata([Const, Ref] ExpressionMetadata metadata);
boolean STATIC_IsBadBehaviorMetadata([Const, Ref] BehaviorMetadata metadata);
};
interface ExpressionParserDiagnostic {
@@ -1972,8 +1961,9 @@ interface ExpressionValidator {
enum ExpressionCompletionDescription_CompletionKind {
"ExpressionCompletionDescription::Object",
"ExpressionCompletionDescription::Behavior",
"ExpressionCompletionDescription::Expression",
"ExpressionCompletionDescription::Variable",
"ExpressionCompletionDescription::Expression"
"ExpressionCompletionDescription::Text"
};
interface ExpressionCompletionDescription {
@@ -1983,6 +1973,10 @@ interface ExpressionCompletionDescription {
[Const, Ref] DOMString GetObjectName();
[Const, Ref] DOMString GetBehaviorName();
boolean IsExact();
boolean IsLastParameter();
unsigned long GetReplacementStartPosition();
unsigned long GetReplacementEndPosition();
[Const, Ref] ParameterMetadata GetParameterMetadata();
};
interface VectorExpressionCompletionDescription {

View File

@@ -505,6 +505,8 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
GetExtensionAndObjectStrExpressionMetadata
#define STATIC_GetExtensionAndBehaviorStrExpressionMetadata \
GetExtensionAndBehaviorStrExpressionMetadata
#define STATIC_IsBadExpressionMetadata IsBadExpressionMetadata
#define STATIC_IsBadBehaviorMetadata IsBadBehaviorMetadata
#define STATIC_RenameObjectInEvents RenameObjectInEvents
#define STATIC_RemoveObjectInEvents RemoveObjectInEvents

View File

@@ -53,6 +53,20 @@ module.exports = {
)
.onlyIfSomeExtraSettingsNonEmpty();
extension
.addAction(
'ShowInterstitial',
'Show interstitial',
'Fake action that would show an interstitial screen.',
'Show the loaded interstitial',
'AdMob',
'JsPlatform/Extensions/admobicon24.png',
'JsPlatform/Extensions/admobicon16.png'
)
.getCodeExtraInformation()
.setIncludeFile('Extensions/FakeAdMob/admobtools.js')
.setFunctionName('gdjs.fakeAdMob.showInterstitial');
platform.addNewExtension(extension);
extension.delete(); // Release the extension as it was copied inside gd.JsPlatform
}

View File

@@ -1936,12 +1936,6 @@ describe('libGD.js', function () {
action.setParametersCount(2);
action.setParameter(0, 'MyCharacter');
var actionSentenceInEnglish = gd.InstructionSentenceFormatter.get().translate(
action,
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), 'Delete')
);
expect(actionSentenceInEnglish).toBe('Delete MyCharacter');
var formattedTexts = gd.InstructionSentenceFormatter.get().getAsFormattedText(
action,
gd.MetadataProvider.getActionMetadata(gd.JsPlatform.get(), 'Delete')

View File

@@ -16,34 +16,35 @@ describe('libGD.js - GDJS related tests', function () {
);
describe('Exporter', () => {
// Fake files to simulate a file system (see tests below).
const fakeIndexHtmlContent = '';
const fakeConfigXmlContent = `
<widget id="GDJS_PACKAGENAME" version="GDJS_PROJECTVERSION">
<name>GDJS_PROJECTNAME</name>
<platform name="android">
<!-- GDJS_ICONS_ANDROID -->
</platform>
<platform name="ios">
<!-- GDJS_ICONS_IOS -->
</platform>
<!-- GDJS_EXTENSION_CORDOVA_DEPENDENCY -->
</widget>`;
const fakePackageJsonContent = `
{
"name": "GDJS_GAME_MANGLED_NAME",
"displayName": "GDJS_GAME_NAME",
"version": "GDJS_GAME_VERSION",
"description": "GDJS_GAME_NAME",
"author": "GDJS_GAME_AUTHOR"
}`;
it('properly exports Cordova files', () => {
// Create a project with some content
// Create a simple project
const project = gd.ProjectHelper.createNewGDJSProject();
project.setName('My great project with spaces and "quotes"!');
project.setVersion("1.2.3");
project.getExtensionProperties().setValue("AdMob", "AdMobAppIdAndroid", "my android app id");
project.setVersion('1.2.3');
// Prepare a fake file system
const fakeIndexHtmlContent = '';
const fakeConfigXmlContent = `
<widget id="GDJS_PACKAGENAME" version="GDJS_PROJECTVERSION">
<name>GDJS_PROJECTNAME</name>
<platform name="android">
<!-- GDJS_ICONS_ANDROID -->
</platform>
<platform name="ios">
<!-- GDJS_ICONS_IOS -->
</platform>
<!-- GDJS_EXTENSION_CORDOVA_DEPENDENCY -->
</widget>`;
const fakePackageJsonContent = `
{
"name": "GDJS_GAME_MANGLED_NAME",
"displayName": "GDJS_GAME_NAME",
"version": "GDJS_GAME_VERSION",
"description": "GDJS_GAME_NAME",
"author": "GDJS_GAME_AUTHOR"
}`;
var fs = makeFakeAbstractFileSystem(gd, {
'/fake-gdjs-root/Runtime/Cordova/www/index.html': fakeIndexHtmlContent,
'/fake-gdjs-root/Runtime/Cordova/config.xml': fakeConfigXmlContent,
@@ -67,29 +68,92 @@ describe('libGD.js - GDJS related tests', function () {
expect(fs.writeToFile).toHaveBeenCalledWith(
'/fake-export-dir/config.xml',
`
<widget id="com.example.gamename" version="1.2.3">
<name>My great project with spaces and &quot;quotes&quot;!</name>
<platform name="android">
</platform>
<platform name="ios">
</platform>
<plugin name=\"gdevelop-cordova-admob-plus\" spec=\"0.43.0\">
<variable name=\"APP_ID_ANDROID\" value=\"my android app id\" />
</plugin>
</widget>`
<widget id="com.example.gamename" version="1.2.3">
<name>My great project with spaces and &quot;quotes&quot;!</name>
<platform name="android">
</platform>
<platform name="ios">
</platform>
</widget>`
);
expect(fs.writeToFile).toHaveBeenCalledWith(
'/fake-export-dir/package.json',
`
{
\"name\": \"my_32great_32project_32with_32spaces_32and_32_34quotes_34_33\",
\"displayName\": \"My great project with spaces and \\\"quotes\\\"!\",
\"version\": \"1.2.3\",
\"description\": \"My great project with spaces and \\\"quotes\\\"!\",
\"author\": \"\"
}`
{
\"name\": \"my_32great_32project_32with_32spaces_32and_32_34quotes_34_33\",
\"displayName\": \"My great project with spaces and \\\"quotes\\\"!\",
\"version\": \"1.2.3\",
\"description\": \"My great project with spaces and \\\"quotes\\\"!\",
\"author\": \"\"
}`
);
});
it('properly exports Cordova plugins config if required by an extension', () => {
// Create a project with some content using the AdMob extension.
const project = gd.ProjectHelper.createNewGDJSProject();
project.setName('My great project with spaces and "quotes"!');
project.setVersion('1.2.3');
project
.getExtensionProperties()
.setValue('AdMob', 'AdMobAppIdAndroid', 'my android app id');
const layout = project.insertNewLayout('Scene', 0);
const event = layout
.getEvents()
.insertNewEvent(project, 'BuiltinCommonInstructions::Standard', 0);
const action = new gd.Instruction();
action.setType('AdMob::ShowInterstitial');
gd.asStandardEvent(event).getActions().insert(action, 0);
// Prepare a fake file system
var fs = makeFakeAbstractFileSystem(gd, {
'/fake-gdjs-root/Runtime/Cordova/www/index.html': fakeIndexHtmlContent,
'/fake-gdjs-root/Runtime/Cordova/config.xml': fakeConfigXmlContent,
'/fake-gdjs-root/Runtime/Cordova/package.json': fakePackageJsonContent,
});
// Export and check the content of written files.
const exporter = new gd.Exporter(fs, '/fake-gdjs-root');
const exportOptions = new gd.MapStringBoolean();
exportOptions.set('exportForCordova', true);
expect(
exporter.exportWholePixiProject(
project,
'/fake-export-dir',
exportOptions
)
).toBe(true);
exportOptions.delete();
exporter.delete();
expect(fs.writeToFile).toHaveBeenCalledWith(
'/fake-export-dir/config.xml',
`
<widget id="com.example.gamename" version="1.2.3">
<name>My great project with spaces and &quot;quotes&quot;!</name>
<platform name="android">
</platform>
<platform name="ios">
</platform>
<plugin name=\"gdevelop-cordova-admob-plus\" spec=\"0.43.0\">
<variable name=\"APP_ID_ANDROID\" value=\"my android app id\" />
</plugin>
</widget>`
);
expect(fs.writeToFile).toHaveBeenCalledWith(
'/fake-export-dir/package.json',
`
{
\"name\": \"my_32great_32project_32with_32spaces_32and_32_34quotes_34_33\",
\"displayName\": \"My great project with spaces and \\\"quotes\\\"!\",
\"version\": \"1.2.3\",
\"description\": \"My great project with spaces and \\\"quotes\\\"!\",
\"author\": \"\"
}`
);
});
});
@@ -194,15 +258,15 @@ describe('libGD.js - GDJS related tests', function () {
gd.asRepeatEvent(evt).getActions().insert(action2, 1);
const namespace = 'gdjs.eventsFunction.myTest';
const eventsFunctionsExtensionCodeGenerator = new gd.EventsFunctionsExtensionCodeGenerator(
project
);
const code = eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
const eventsFunctionsExtensionCodeGenerator =
new gd.EventsFunctionsExtensionCodeGenerator(project);
const code =
eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
// Check that the function name is properly generated
expect(code).toMatch(namespace + '.func = function(');
@@ -298,15 +362,15 @@ describe('libGD.js - GDJS related tests', function () {
gd.asRepeatEvent(evt).getActions().insert(action, 0);
const namespace = 'gdjs.eventsFunction.myTest';
const eventsFunctionsExtensionCodeGenerator = new gd.EventsFunctionsExtensionCodeGenerator(
project
);
const code = eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
const eventsFunctionsExtensionCodeGenerator =
new gd.EventsFunctionsExtensionCodeGenerator(project);
const code =
eventsFunctionsExtensionCodeGenerator.generateFreeEventsFunctionCompleteCode(
eventsFunction,
namespace,
includeFiles,
true
);
// Check that the function name is properly generated
expect(code).toMatch(namespace + '.func = function(');

View File

@@ -68,7 +68,7 @@ describe('libGD.js object serialization', function() {
obj.delete();
expect(jsonObject).toBe(
'{"bold":false,"italic":false,"name":"testObject","smoothed":true,"tags":"inventory, player","type":"TextObject::Text","underlined":false,"variables":[],"behaviors":[],"string":"Text of the object, with 官话 characters","font":"","characterSize":20.0,"color":{"b":0,"g":0,"r":0}}'
'{"bold":false,"italic":false,"name":"testObject","smoothed":true,"tags":"inventory, player","type":"TextObject::Text","underlined":false,"variables":[],"effects":[],"behaviors":[],"string":"Text of the object, with 官话 characters","font":"","characterSize":20.0,"color":{"b":0,"g":0,"r":0}}'
);
});
});

View File

@@ -118,7 +118,7 @@ type Variable_Type = 0 | 1 | 2 | 3 | 4`
fs.writeFileSync(
'types/expressioncompletiondescription_completionkind.js',
`// Automatically generated by GDevelop.js/scripts/generate-types.js
type ExpressionCompletionDescription_CompletionKind = 0 | 1 | 2 | 3`
type ExpressionCompletionDescription_CompletionKind = 0 | 1 | 2 | 3 | 4`
);
shell.sed(
'-i',
@@ -129,6 +129,7 @@ type ExpressionCompletionDescription_CompletionKind = 0 | 1 | 2 | 3`
' static Behavior: 1;',
' static Expression: 2;',
' static Variable: 3;',
' static Text: 4;',
].join('\n'),
'types/gdexpressioncompletiondescription.js'
);

View File

@@ -1,2 +1,2 @@
// Automatically generated by GDevelop.js/scripts/generate-types.js
type ExpressionCompletionDescription_CompletionKind = 0 | 1 | 2 | 3
type ExpressionCompletionDescription_CompletionKind = 0 | 1 | 2 | 3 | 4

View File

@@ -4,12 +4,17 @@ declare class gdExpressionCompletionDescription {
static Behavior: 1;
static Expression: 2;
static Variable: 3;
static Text: 4;
getCompletionKind(): ExpressionCompletionDescription_CompletionKind;
getType(): string;
getPrefix(): string;
getObjectName(): string;
getBehaviorName(): string;
isExact(): boolean;
isLastParameter(): boolean;
getReplacementStartPosition(): number;
getReplacementEndPosition(): number;
getParameterMetadata(): gdParameterMetadata;
delete(): void;
ptr: number;
};

View File

@@ -1,11 +1,7 @@
// Automatically generated by GDevelop.js/scripts/generate-types.js
declare class gdInstructionSentenceFormatter {
static get(): gdInstructionSentenceFormatter;
translate(instr: gdInstruction, metadat: gdInstructionMetadata): string;
getAsFormattedText(instr: gdInstruction, metadat: gdInstructionMetadata): gdVectorPairStringTextFormatting;
getFormattingFromType(type: string): gdTextFormatting;
labelFromType(type: string): string;
loadTypesFormattingFromConfig(): void;
delete(): void;
ptr: number;
};

View File

@@ -9,8 +9,6 @@ declare class gdJsPlatform extends gdPlatform {
isExtensionLoaded(name: string): boolean;
removeExtension(name: string): void;
reloadBuiltinExtensions(): void;
getBehavior(type: string): gdBehavior;
getBehaviorSharedDatas(type: string): gdBehaviorsSharedData;
getAllPlatformExtensions(): gdVectorPlatformExtension;
delete(): void;
ptr: number;

View File

@@ -22,6 +22,8 @@ declare class gdMetadataProvider {
static getStrExpressionMetadata(p: gdPlatform, type: string): gdExpressionMetadata;
static getObjectStrExpressionMetadata(p: gdPlatform, objectType: string, type: string): gdExpressionMetadata;
static getBehaviorStrExpressionMetadata(p: gdPlatform, autoType: string, type: string): gdExpressionMetadata;
static isBadExpressionMetadata(metadata: gdExpressionMetadata): boolean;
static isBadBehaviorMetadata(metadata: gdBehaviorMetadata): boolean;
delete(): void;
ptr: number;
};

View File

@@ -14,6 +14,7 @@ declare class gdObject {
updateInitialInstanceProperty(instance: gdInitialInstance, name: string, value: string, project: gdProject, scene: gdLayout): boolean;
exposeResources(worker: gdArbitraryResourceWorker): void;
getVariables(): gdVariablesContainer;
getEffects(): gdEffectsContainer;
getAllBehaviorNames(): gdVectorString;
hasBehaviorNamed(name: string): boolean;
addNewBehavior(project: gdProject, type: string, name: string): gdBehaviorContent;

View File

@@ -1,10 +1,5 @@
// Automatically generated by GDevelop.js/scripts/generate-types.js
declare class gdTextFormatting {
isBold(): boolean;
isItalic(): boolean;
getColorRed(): number;
getColorGreen(): number;
getColorBlue(): number;
getUserData(): number;
delete(): void;
ptr: number;

View File

@@ -30,7 +30,7 @@ To learn more about GDevelop Architecture, read the [architecture overview here]
Pre-generated documentation of the Core library, C++ and TypeScript game engines is [available here](https://docs.gdevelop-app.com).
Status of the tests and builds: [![Build status](https://circleci.com/gh/4ian/GDevelop.svg?style=shield)](https://app.circleci.com/pipelines/github/4ian/GDevelop) [![Quick tests status](https://semaphoreci.com/api/v1/4ian/gd/branches/master/shields_badge.svg)](https://semaphoreci.com/4ian/gd) [![All tests Status](https://travis-ci.org/4ian/GDevelop.svg?branch=master)](https://travis-ci.org/4ian/GDevelop) [![Windows Build status](https://ci.appveyor.com/api/projects/status/84uhtdox47xp422x/branch/master?svg=true)](https://ci.appveyor.com/project/4ian/gdevelop/branch/master) [![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)
Status of the tests and builds: [![Build status](https://circleci.com/gh/4ian/GDevelop.svg?style=shield)](https://app.circleci.com/pipelines/github/4ian/GDevelop) [![Quick tests status](https://semaphoreci.com/api/v1/4ian/gd/branches/master/shields_badge.svg)](https://semaphoreci.com/4ian/gd) [![All tests Status](https://www.travis-ci.com/4ian/GDevelop.svg?branch=master)](https://www.travis-ci.com/github/4ian/GDevelop) [![Windows Build status](https://ci.appveyor.com/api/projects/status/84uhtdox47xp422x/branch/master?svg=true)](https://ci.appveyor.com/project/4ian/gdevelop/branch/master) [![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation)
## Links

View File

@@ -42,15 +42,7 @@ cd newIDE/app && npm start # Be sure to have this running in another terminal, b
# In a new terminal:
cd newIDE/electron-app
npm install # or yarn
#For macOS:
npm run electron-mac
#For Windows:
npm run electron-win
#For Linux:
npm run electron-linux
npm run start # or yarn start
```
### Quick Install and Run

View File

@@ -24,7 +24,3 @@
[options]
module.ignore_non_literal_requires=true
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
# For node_modules/jss/src/Jss.js:
suppress_comment=\\(.\\|\n\\)*\\$FlowIgnore

View File

@@ -1,931 +0,0 @@
// flow-typed signature: 0a7c5018a7783bafd1ecdfe3a87e17c7
// flow-typed version: 0dcf7d868b/firebase_v5.x.x/flow_>=v0.34.x
/* @flow */
/** ** firebase ****/
declare interface $npm$firebase$Config {
apiKey: string;
authDomain?: string;
databaseURL?: string;
projectId?: string;
storageBucket?: string;
messagingSenderId?: string;
}
declare interface $npm$firebase$auth$Error {
code:
| 'auth/app-deleted'
| 'auth/app-not-authorized'
| 'auth/argument-error'
| 'auth/invalid-api-key'
| 'auth/invalid-user-token'
| 'auth/network-request-failed'
| 'auth/operation-not-allowed'
| 'auth/requires-recent-login'
| 'auth/too-many-requests'
| 'auth/unauthorized-domain'
| 'auth/user-disabled'
| 'auth/user-token-expired'
| 'auth/web-storage-unsupported'
| 'auth/invalid-email'
| 'auth/account-exists-with-different-credential'
| 'auth/invalid-credential'
| 'auth/user-not-found'
| 'auth/wrong-password'
| 'auth/invalid-verification-code'
| 'auth/invalid-verification-id'
| 'auth/expired-action-code'
| 'auth/invalid-action-code'
| 'auth/invalid-verification-code'
| 'auth/missing-verification-code'
| 'auth/captcha-check-failed'
| 'auth/invalid-phone-number'
| 'auth/missing-phone-number'
| 'auth/quota-exceeded'
| 'auth/credential-already-in-use'
| 'auth/email-already-in-use'
| 'auth/provider-already-linked'
| 'auth/auth-domain-config-required'
| 'auth/cancelled-popup-request'
| 'auth/popup-blocked'
| 'auth/operation-not-supported-in-this-environment'
| 'auth/popup-closed-by-user'
| 'auth/unauthorized-domain'
| 'auth/no-such-provider';
message: string;
}
declare interface $npm$firebase$Error {
code: $PropertyType<$npm$firebase$auth$Error, 'code'> | 'app/no-app';
message: string;
name: string;
stack: ?string;
}
/** *** app *****/
declare class $npm$firebase$App {
name: string;
+options: $npm$firebase$Config;
auth(): $npm$firebase$auth$Auth;
database(): $npm$firebase$database$Database;
storage(): $npm$firebase$storage$Storage;
firestore(): $npm$firebase$firestore$Firestore;
delete(): Promise<void>;
}
/** **** auth *******/
declare interface $npm$firebase$auth$ActionCodeInfo {
data: { email: string };
}
declare interface $npm$firebase$auth$ApplicationVerifier {
type: string;
verify(): Promise<string>;
}
declare type $npm$firebase$auth$Auth$Persistence = {
+LOCAL: 'local',
+SESSION: 'session',
+NONE: 'none',
};
declare type $npm$firebase$auth$Auth$Persistence$Enum = $Values<$npm$firebase$auth$Auth$Persistence>;
declare class $npm$firebase$auth$Auth {
static Persistence: $npm$firebase$auth$Auth$Persistence;
app: $npm$firebase$App;
currentUser: $npm$firebase$auth$User | null;
applyActionCode(code: string): Promise<void>;
checkActionCode(code: string): Promise<$npm$firebase$auth$ActionCodeInfo>;
confirmPasswordReset(code: string, newPassword: string): Promise<void>;
createCustomToken(uid: string, developerClaims?: {}): string;
createUserWithEmailAndPassword(
email: string,
password: string
): Promise<$npm$firebase$auth$UserCredential>;
fetchProvidersForEmail(email: string): Promise<Array<string>>;
onAuthStateChanged(
nextOrObserver: (?$npm$firebase$auth$User) => void | Promise<void>,
error?: (error: $npm$firebase$auth$Error) => void,
completed?: () => void
): () => void;
onIdTokenChanged(
nextOrObserver: Object | ((user?: $npm$firebase$auth$User) => void | Promise<void>),
error?: (error: $npm$firebase$auth$Error) => void,
completed?: () => void
): () => void;
sendPasswordResetEmail(email: string): Promise<void>;
setPersistence(persistence: $npm$firebase$auth$Auth$Persistence$Enum): Promise<void>;
signInAndRetrieveDataWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<$npm$firebase$auth$UserCredential>;
signInAnonymously(): Promise<$npm$firebase$auth$User>;
signInWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<$npm$firebase$auth$User>;
signInWithCustomToken(token: string): Promise<$npm$firebase$auth$User>;
signInWithEmailAndPassword(
email: string,
password: string
): Promise<$npm$firebase$auth$UserCredential>;
signInWithPhoneNumber(
phoneNumber: string,
applicationVerifier: $npm$firebase$auth$ApplicationVerifier
): Promise<$npm$firebase$auth$ConfirmationResult>;
signInWithPopup(
provider: $npm$firebase$auth$AuthProvider
): Promise<$npm$firebase$auth$UserCredential>;
signOut(): Promise<void>;
verifyIdToken(idToken: string): Promise<Object>;
verifyPasswordResetCode(code: string): Promise<string>;
}
declare interface $npm$firebase$auth$AuthCredential {
providerId: string;
}
declare class $npm$firebase$auth$AuthProvider {
providerId: string;
}
declare interface $npm$firebase$auth$ConfirmationResult {
verificationId: string;
confirm(verificationCode: string): Promise<$npm$firebase$auth$UserCredential>;
}
declare type $npm$firebase$auth$UserProfile = {
displayName?: string,
photoURL?: string
};
declare interface $npm$firebase$auth$AdditionalUserInfo {
providerId: string;
profile?: $npm$firebase$auth$UserProfile;
username?: string;
}
declare interface $npm$firebase$auth$UserCredential {
user: $npm$firebase$auth$User;
credential?: $npm$firebase$auth$AuthCredential;
operationType?: string;
additionalUserInfo?: $npm$firebase$auth$AdditionalUserInfo;
}
declare class $npm$firebase$auth$UserInfo {
displayName: ?string;
email: ?string;
photoURL: ?string;
providerId: string;
uid: string;
}
declare type $npm$firebase$actionCode$settings = {
url: string,
iOS?: { bundleId: string },
android?: {
packageName: string,
installApp?: boolean,
minimumVersion?: string,
},
handleCodeInApp?: boolean,
}
declare class $npm$firebase$auth$User extends $npm$firebase$auth$UserInfo {
displayName: ?string;
email: ?string;
emailVerified: boolean;
isAnonymous: boolean;
phoneNumber: ?string;
photoUrl: ?string;
providerData: Array<$npm$firebase$auth$UserInfo>;
providerId: string;
refreshToken: string;
uid: string;
delete(): Promise<void>;
getIdToken(forceRefresh?: boolean): Promise<string>;
getToken(forceRefresh?: boolean): Promise<string>;
linkAndRetrieveDataWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<$npm$firebase$auth$UserCredential>;
linkWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<$npm$firebase$auth$User>;
linkWithPhoneNumber(
phoneNumber: string,
applicationVerifier: $npm$firebase$auth$ApplicationVerifier
): Promise<$npm$firebase$auth$ConfirmationResult>;
linkWithPopup(
provider: $npm$firebase$auth$OAuthProvider
): Promise<$npm$firebase$auth$UserCredential>;
reauthenticateAndRetrieveDataWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<void>;
reauthenticateWithCredential(
credential: $npm$firebase$auth$AuthCredential
): Promise<void>;
reauthenticateWithPhoneNumber(
phoneNumber: string,
applicationVerifier: $npm$firebase$auth$ApplicationVerifier
): Promise<$npm$firebase$auth$ConfirmationResult>;
reload(): Promise<void>;
sendEmailVerification(actionCodeSettings?: $npm$firebase$actionCode$settings): Promise<void>;
toJSON(): Object;
unlink(providerId: string): Promise<$npm$firebase$auth$User>;
updateEmail(newEmail: string): Promise<void>;
updatePassword(newPassword: string): Promise<void>;
updatePhoneNumber(
phoneCredential: $npm$firebase$auth$AuthCredential
): Promise<void>;
updateProfile(profile: $npm$firebase$auth$UserProfile): Promise<void>;
}
declare class $npm$firebase$auth$EmailAuthProvider extends $npm$firebase$auth$AuthProvider {
static EMAIL_LINK_SIGN_IN_METHOD: string;
static EMAIL_PASSWORD_SIGN_IN_METHOD: string;
static PROVIDER_ID: string;
static credential(
email: string,
password: string
): $npm$firebase$auth$AuthCredential;
static credentialWithLink(
email: string,
emailLink: string
): $npm$firebase$auth$AuthCredential;
providerId: string;
}
declare class $npm$firebase$auth$FacebookAuthProvider extends $npm$firebase$auth$AuthProvider {
static FACEBOOK_SIGN_IN_METHOD: string;
static PROVIDER_ID: string;
static credential(token: string): $npm$firebase$auth$AuthCredential;
addScope(scope: string): $npm$firebase$auth$FacebookAuthProvider;
setCustomParameters(
customOAuthParameters: Object
): $npm$firebase$auth$FacebookAuthProvider;
providerId: string
}
declare class $npm$firebase$auth$GithubAuthProvider extends $npm$firebase$auth$AuthProvider {
static GITHUB_SIGN_IN_METHOD: string;
static PROVIDER_ID: string;
static credential(token: string): $npm$firebase$auth$AuthCredential;
addScope(scope: string): $npm$firebase$auth$GithubAuthProvider;
setCustomParameters(
customOAuthParameters: Object
): $npm$firebase$auth$GithubAuthProvider;
providerId: string;
}
declare class $npm$firebase$auth$GoogleAuthProvider extends $npm$firebase$auth$AuthProvider {
static GOOGLE_SIGN_IN_METHOD: string;
static PROVIDER_ID: string;
static credential(
idToken?: string,
accessToken?: string
): $npm$firebase$auth$AuthCredential;
addScope(scope: string): $npm$firebase$auth$GoogleAuthProvider;
setCustomParameters(
customOAuthParameters: Object
): $npm$firebase$auth$GoogleAuthProvider;
}
declare class $npm$firebase$auth$PhoneAuthProvider extends $npm$firebase$auth$AuthProvider {
static PHONE_SIGN_IN_METHOD: string;
static PROVIDER_ID: string;
static credential(
verificationId: string,
verificationCode: string
): $npm$firebase$auth$AuthCredential;
constructor(
auth?: $npm$firebase$auth$Auth
): $npm$firebase$auth$PhoneAuthProvider;
verifyPhoneNumber(
phoneNumber: string,
applicationVerifier: $npm$firebase$auth$ApplicationVerifier
): Promise<string>;
providerId: string;
}
declare class $npm$firebase$auth$TwitterAuthProvider extends $npm$firebase$auth$AuthProvider {
static PROVIDER_ID: string;
credential(token: string, secret: string): $npm$firebase$auth$AuthCredential;
setCustomParameters(customOAuthParameters: Object): this;
}
declare type $npm$firebase$auth$OAuthProvider =
| $npm$firebase$auth$FacebookAuthProvider
| $npm$firebase$auth$GithubAuthProvider
| $npm$firebase$auth$GoogleAuthProvider
| $npm$firebase$auth$TwitterAuthProvider;
/** **** database ******/
declare type $npm$firebase$database$Value = any;
declare type $npm$firebase$database$OnCompleteCallback = (
error: ?Object
) => void;
declare type $npm$firebase$database$QueryEventType =
| 'value'
| 'child_added'
| 'child_changed'
| 'child_removed'
| 'child_moved';
declare type $npm$firebase$database$Priority = string | number | null;
declare class $npm$firebase$database$Database {
app: $npm$firebase$App;
goOffline(): void;
goOnline(): void;
ref(path?: string): $npm$firebase$database$Reference;
refFromURL(url: string): $npm$firebase$database$Reference;
}
declare class $npm$firebase$database$DataSnapshot {
key: ?string;
ref: $npm$firebase$database$Reference;
child(path?: string): $npm$firebase$database$DataSnapshot;
exists(): boolean;
exportVal(): $npm$firebase$database$Value;
forEach(action: ($npm$firebase$database$DataSnapshot) => ?boolean): boolean;
getPriority(): $npm$firebase$database$Priority;
hasChild(path: string): boolean;
hasChildren(): boolean;
numChildren(): number;
toJSON(): Object;
val(): $npm$firebase$database$Value;
}
declare class $npm$firebase$database$OnDisconnect {
cancel(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
remove(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
set(
value: $npm$firebase$database$Value,
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
setWithPriority(
value: $npm$firebase$database$Value,
priority: number | string | null,
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
update(
values: { +[path: string]: $npm$firebase$database$Value },
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
}
declare type $npm$firebase$database$Callback = (
$npm$firebase$database$DataSnapshot,
?string
) => void | Promise<void>;
declare class $npm$firebase$database$Query {
ref: $npm$firebase$database$Reference;
endAt(
value: number | string | boolean | null,
key?: string
): $npm$firebase$database$Query;
equalTo(
value: number | string | boolean | null,
key?: string
): $npm$firebase$database$Query;
isEqual(other: $npm$firebase$database$Query): boolean;
limitToFirst(limit: number): $npm$firebase$database$Query;
limitToLast(limit: number): $npm$firebase$database$Query;
off(
eventType?: $npm$firebase$database$QueryEventType,
callback?: $npm$firebase$database$Callback,
context?: Object
): void;
on(
eventType: $npm$firebase$database$QueryEventType,
callback: $npm$firebase$database$Callback,
cancelCallbackOrContext?: (error: Object) => void | Object,
context?: $npm$firebase$database$Callback
): $npm$firebase$database$Callback;
once(
eventType: $npm$firebase$database$QueryEventType,
successCallback?: $npm$firebase$database$Callback,
failureCallbackOrContext?: (error: Object) => void | Object,
context?: Object
): Promise<$npm$firebase$database$DataSnapshot>;
orderByChild(path: string): $npm$firebase$database$Query;
orderByKey(): $npm$firebase$database$Query;
orderByPriority(): $npm$firebase$database$Query;
orderByValue(): $npm$firebase$database$Query;
startAt(
value: number | string | boolean | null,
key?: string
): $npm$firebase$database$Query;
toJSON(): Object;
toString(): string;
}
declare class $npm$firebase$database$Reference extends $npm$firebase$database$Query {
key: ?string;
parent?: $npm$firebase$database$Reference;
root: $npm$firebase$database$Reference;
child(path: string): $npm$firebase$database$Reference;
onDisconnect(): $npm$firebase$database$OnDisconnect;
push(
value?: $npm$firebase$database$Value,
onComplete?: $npm$firebase$database$OnCompleteCallback
): $npm$firebase$database$ThenableReference & Promise<void>;
remove(onComplete?: $npm$firebase$database$OnCompleteCallback): Promise<void>;
set(
value: $npm$firebase$database$Value,
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
setPriority(
priority: $npm$firebase$database$Priority,
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
setWithPriority(
newVal: $npm$firebase$database$Value,
newPriority: $npm$firebase$database$Priority,
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
transaction(
transactionUpdate: (
data: $npm$firebase$database$Value
) => $npm$firebase$database$Value,
onComplete?: (
error: null | Object,
committed: boolean,
snapshot: $npm$firebase$database$DataSnapshot
) => void,
applyLocally?: boolean
): Promise<{
committed: boolean,
snapshot: $npm$firebase$database$DataSnapshot | null
}>;
update(
values: { [path: string]: $npm$firebase$database$Value },
onComplete?: $npm$firebase$database$OnCompleteCallback
): Promise<void>;
}
declare class $npm$firebase$database$ServerValue {
static TIMESTAMP: {};
}
declare class $npm$firebase$database$ThenableReference extends $npm$firebase$database$Reference {}
/** **** firestore ******/
declare class $npm$firebase$firestore$Firestore {
app: $npm$firebase$App;
batch(): $npm$firebase$firestore$WriteBatch;
collection(collectionPath: string): $npm$firebase$firestore$CollectionReference;
doc(documentPath: string): $npm$firebase$firestore$DocumentReference;
enableNetwork(): Promise<void>;
disableNetwork(): Promise<void>;
enablePersistence(settings?: $npm$firebase$firestore$PersistenceSettings): Promise<void>;
runTransaction(updateFunction: (transaction: $npm$firebase$firestore$Transaction) => Promise<any>): Promise<any>;
setLogLevel(logLevel: 'debug' | 'error' | 'silent'): void;
settings(settings: $npm$firebase$firestore$Settings): void;
getAll(
...docs: Array<$npm$firebase$firestore$DocumentReference>
): Promise<Array<$npm$firebase$firestore$DocumentSnapshot>>;
}
declare interface $npm$firebase$firestore$Blob {
fromBase64String(base64: string): $npm$firebase$firestore$Blob;
fromUint8Array(array: Uint8Array): $npm$firebase$firestore$Blob;
toBase64(): string;
toUintArray(): Uint8Array;
}
declare interface $npm$firebase$firestore$QueryListenOptions {
includeMetadataChanges: boolean;
includeQueryMetadataChanges: boolean;
}
declare type $npm$firebase$firestore$documentObserver = (snapshot: $npm$firebase$firestore$DocumentSnapshot) => void | Promise<void>;
declare type $npm$firebase$firestore$queryObserver = (snapshot: $npm$firebase$firestore$QuerySnapshot) => void | Promise<void>;
declare type $npm$firebase$firestore$observerError = (error: $npm$firebase$Error) => void | Promise<void>;
declare type $npm$firebase$firestore$GetOptions = {
source?: 'default' | 'cache' | 'server'
}
declare class $npm$firebase$firestore$Query {
firestore: $npm$firebase$firestore$Firestore;
endAt(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
endBefore(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
get(getOptions?: $npm$firebase$firestore$GetOptions): Promise<$npm$firebase$firestore$QuerySnapshot>;
isEqual(other: $npm$firebase$firestore$Query): boolean;
limit(limit: number): $npm$firebase$firestore$Query;
onSnapshot(
optionsOrObserverOrOnNext: $npm$firebase$firestore$QueryListenOptions | $npm$firebase$firestore$queryObserver,
observerOrOnNextOrOnError?: | $npm$firebase$firestore$QueryListenOptions
| $npm$firebase$firestore$queryObserver
| $npm$firebase$firestore$observerError,
onError?: $npm$firebase$firestore$observerError
): () => void;
orderBy(
fieldPath: $npm$firebase$firestore$FieldPath | string,
directionStr: 'asc' | 'desc'
): $npm$firebase$firestore$Query;
startAfter(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
startAt(snapshotOrVarArgs: $npm$firebase$firestore$DocumentSnapshot | {}): $npm$firebase$firestore$Query;
where(fieldPath: string, opStr: '<' | '<=' | '==' | 'array-contains' | '>' | '>=', value: any): $npm$firebase$firestore$Query;
}
declare class $npm$firebase$firestore$CollectionReference extends $npm$firebase$firestore$Query {
constructor(): $npm$firebase$firestore$CollectionReference;
id: string;
parent: $npm$firebase$firestore$DocumentReference | null;
add(data: { +[string]: mixed }): Promise<$npm$firebase$firestore$DocumentReference>;
doc(documentPath?: string): $npm$firebase$firestore$DocumentReference;
}
declare interface $npm$firebase$firestore$DocumentChange {
type: 'added' | 'removed' | 'modified';
doc: $npm$firebase$firestore$DocumentSnapshot;
oldIndex: number;
newIndex: number;
}
declare class $npm$firebase$firestore$DocumentReference {
firestore: $npm$firebase$firestore$Firestore;
id: string;
path: string;
parent: typeof $npm$firebase$firestore$CollectionReference;
collection(collectionPath: string): $npm$firebase$firestore$CollectionReference;
delete(): Promise<void>;
get(): Promise<$npm$firebase$firestore$DocumentSnapshot>;
isEqual(other: $npm$firebase$firestore$DocumentReference): boolean;
onSnapshot(
optionsOrObserverOrOnNext: $npm$firebase$firestore$QueryListenOptions
| $npm$firebase$firestore$documentObserver,
observerOrOnNextOrOnError?: | $npm$firebase$firestore$QueryListenOptions
| $npm$firebase$firestore$documentObserver
| $npm$firebase$firestore$observerError,
onError?: $npm$firebase$firestore$observerError
): () => void;
set(data: { +[string]: mixed }, options?: {| merge?: boolean, mergeFields?: string[] |} | null): Promise<void>;
update(...args: Array<any>): Promise<void>;
}
declare class $npm$firebase$firestore$DocumentSnapshot {
data(): {| +[string]: any |};
get(fieldpath: typeof $npm$firebase$firestore$FieldPath): any;
isEqual(other: $npm$firebase$firestore$DocumentSnapshot): boolean;
exists: boolean;
id: string;
metadata: $npm$firebase$firestore$SnapshotMetadata;
ref: $npm$firebase$firestore$DocumentReference;
}
declare class $npm$firebase$firestore$FieldPath {
constructor(...args: Array<any>): $npm$firebase$firestore$FieldPath;
static documentId(): typeof $npm$firebase$firestore$FieldPath;
isEqual(other: $npm$firebase$firestore$FieldPath): boolean;
}
declare class $npm$firebase$firestore$FieldValue {
static delete(): $npm$firebase$firestore$FieldValue;
static serverTimestamp(): $npm$firebase$firestore$FieldValue;
static arrayUnion(...elements: any[]): $npm$firebase$firestore$FieldValue;
static arrayRemove(...elements: any[]): $npm$firebase$firestore$FieldValue;
isEqual(other: $npm$firebase$firestore$FieldPath): boolean;
}
declare type $npm$firebase$firestore$FirestoreError =
| 'cancelled'
| 'unknown'
| 'invalid-argument'
| 'deadline-exceeded'
| 'not-found'
| 'already-exists'
| 'permission-denied'
| 'resource-exhausted'
| 'failed-precondition'
| 'aborted'
| 'out-of-range'
| 'unimplemented'
| 'internal'
| 'unavailable'
| 'data-loss'
| 'unauthenticated';
declare class $npm$firebase$firestore$GeoPoint {
constructor(latitude: number, longitude: number): $npm$firebase$firestore$GeoPoint;
latitude: number;
longitude: number;
isEqual(other: $npm$firebase$firestore$GeoPoint): boolean;
}
declare class $npm$firebase$firestore$QuerySnapshot {
docChanges(): Array<$npm$firebase$firestore$DocumentChange>;
docs: Array<$npm$firebase$firestore$DocumentSnapshot>;
empty: boolean;
metadata: $npm$firebase$firestore$SnapshotMetadata;
query: $npm$firebase$firestore$Query;
size: number;
forEach((snapshot: $npm$firebase$firestore$DocumentSnapshot, thisArg?: any) => void): void;
isEqual(other: $npm$firebase$firestore$QuerySnapshot): boolean;
}
declare type $npm$firebase$firestore$Settings = {|
+host?: string;
+ssl?: boolean;
+timestampsInSnapshots?: boolean;
+cacheSizeBytes?: number;
|};
declare type $npm$firebase$firestore$PersistenceSettings = {|
+experimentalTabSynchronization?: boolean;
|};
declare interface $npm$firebase$firestore$SnapshotMetadata {
fromCache: boolean;
hasPendingWrites: boolean;
}
declare interface $npm$firebase$firestore$Transaction {
delete(documentRef: $npm$firebase$firestore$DocumentReference): $npm$firebase$firestore$Transaction;
get(documentRef: $npm$firebase$firestore$DocumentReference): Promise<$npm$firebase$firestore$DocumentSnapshot>;
set(
documentRef: $npm$firebase$firestore$DocumentReference,
data: { +[string]: mixed },
options?: { merge: boolean }
): $npm$firebase$firestore$Transaction;
update(documentRef: $npm$firebase$firestore$DocumentReference, ...args: Array<any>): $npm$firebase$firestore$Transaction;
}
declare interface $npm$firebase$firestore$WriteBatch {
commit(): Promise<void>;
delete(documentRef: $npm$firebase$firestore$DocumentReference): $npm$firebase$firestore$WriteBatch;
set(
documentRef: $npm$firebase$firestore$DocumentReference,
data: { +[string]: mixed },
options?: { merge: boolean }
): $npm$firebase$firestore$WriteBatch;
update(documentRef: $npm$firebase$firestore$DocumentReference, ...args: Array<any>): $npm$firebase$firestore$WriteBatch;
}
/** **** messaging ******/
declare class $npm$firebase$messaging$Messaging {
deleteToken(token: string): Promise<any>;
getToken(): Promise<?string>;
onMessage(nextOrObserver: ({}) => void | {}): () => void;
onTokenRefresh(nextOrObserver: ({}) => void | {}): () => void;
requestPermission(): Promise<any>;
setBackgroundMessageHandler(callback: (value: {}) => void): void;
useServiceWorker(registration: any): void;
}
/** **** storage ******/
declare type $npm$firebase$storage$StringFormat =
| 'raw'
| 'base64'
| 'base64url'
| 'data_url';
declare type $npm$firebase$storage$TaskEvent = 'state_changed';
declare type $npm$firebase$storage$TaskState =
| 'running'
| 'paused'
| 'success'
| 'canceled'
| 'error';
declare class $npm$firebase$storage$Storage {
app: $npm$firebase$App;
maxOperationRetryTime: number;
maxUploadRetryTime: number;
ref(path?: string): $npm$firebase$storage$Reference;
refFromURL(url: string): $npm$firebase$storage$Reference;
setMaxOperationRetryTime(time: number): void;
setMaxUploadRetryTime(time: number): void;
}
declare class $npm$firebase$storage$FullMetadata extends $npm$firebase$storage$UploadMetadata {
bucket: string;
downloadURLs: Array<string>;
fullPath: string;
generation: string;
metageneration: string;
name: string;
size: number;
timeCreated: string;
updated: string;
}
declare class $npm$firebase$storage$Reference {
bucket: string;
fullPath: string;
name: string;
parent?: $npm$firebase$storage$Reference;
root: $npm$firebase$storage$Reference;
storage: $npm$firebase$storage$Storage;
child(path: string): $npm$firebase$storage$Reference;
delete(): Promise<void>;
getDownloadURL(): Promise<string>;
getMetadata(): Promise<$npm$firebase$storage$FullMetadata>;
put(
data: Blob | Uint8Array | ArrayBuffer,
metadata?: $npm$firebase$storage$UploadMetadata
): $npm$firebase$storage$UploadTask;
putString(
data: string,
format: $npm$firebase$storage$StringFormat,
metadata?: $npm$firebase$storage$UploadMetadata
): $npm$firebase$storage$UploadTask;
toString(): string;
updateMetadata(
metadata: $npm$firebase$storage$SettableMetadata
): Promise<$npm$firebase$storage$FullMetadata>;
}
declare class $npm$firebase$storage$SettableMetadata {
cacheControl?: string;
contentDisposition?: string;
contentEncoding?: string;
contentLanguage?: string;
contentType?: string;
customMetadata?: { [key: string]: string | void };
}
declare class $npm$firebase$storage$UploadMetadata extends $npm$firebase$storage$SettableMetadata {
md5Hash?: string;
}
declare interface $npm$firebase$storage$Observer {
next: (snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void;
error?: (error: Error) => void;
complete?: () => void;
}
declare type $npm$firebase$storage$Unsubscribe = () => void;
declare type $npm$firebase$storage$Subscribe = (
observerOrNext: | $npm$firebase$storage$Observer
| ((snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void),
onError?: (error: Error) => void,
onComplete?: () => void
) => $npm$firebase$storage$Unsubscribe;
declare class $npm$firebase$storage$UploadTask extends Promise<
$npm$firebase$storage$UploadTaskSnapshot
> {
snapshot: $npm$firebase$storage$UploadTaskSnapshot;
cancel(): boolean;
on(
event: $npm$firebase$storage$TaskEvent,
...rest: Array<void>
): $npm$firebase$storage$Subscribe;
on(
event: $npm$firebase$storage$TaskEvent,
observerOrNext: | $npm$firebase$storage$Observer
| ((snapshot: $npm$firebase$storage$UploadTaskSnapshot) => void),
onError?: (error: Error) => void,
onComplete?: () => void
): $npm$firebase$storage$Unsubscribe;
pause(): boolean;
resume(): boolean;
}
declare class $npm$firebase$storage$UploadTaskSnapshot {
bytesTransferred: number;
downloadURL?: string;
metadata: $npm$firebase$storage$FullMetadata;
ref: $npm$firebase$storage$Reference;
state: $npm$firebase$storage$TaskState;
task: $npm$firebase$storage$UploadTask;
totalBytes: number;
}
declare type $npm$firebase$app$exports = {
+apps: Array<$npm$firebase$App>,
initializeApp(
options: $npm$firebase$Config,
name?: string
): $npm$firebase$App,
SDK_VERSION: string,
FirebaseError: $npm$firebase$Error,
FirebaseConfig: $npm$firebase$Config,
FirebaseUser: typeof $npm$firebase$auth$User,
FirebaseUserInfo: typeof $npm$firebase$auth$UserInfo,
app: $Exports<'@firebase/app'>,
auth: $Exports<'@firebase/auth'>,
database: $Exports<'@firebase/database'>,
firestore: $Exports<'@firebase/firestore'>,
messaging: $Exports<'@firebase/messaging'>,
storage: $Exports<'@firebase/storage'>
};
// Exporting the types
declare module 'firebase' {
declare module.exports: $npm$firebase$app$exports;
}
declare module 'firebase/app' {
declare module.exports: $npm$firebase$app$exports;
}
declare module 'firebase/auth' {
declare module.exports: $Exports<'@firebase/auth'>
}
declare module 'firebase/database' {
declare module.exports: $Exports<'@firebase/database'>;
}
declare module 'firebase/firestore' {
declare module.exports: $Exports<'@firebase/firestore'>;
}
declare module 'firebase/messaging' {
declare module.exports: $Exports<'@firebase/messaging'>;
}
declare module '@firebase/app' {
declare module.exports: {
(name?: string): $npm$firebase$App,
App: typeof $npm$firebase$App
};
}
declare module '@firebase/auth' {
declare module.exports: {
(app?: $npm$firebase$App): $npm$firebase$auth$Auth,
FirebaseAdditionalUserInfo: $npm$firebase$auth$AdditionalUserInfo,
FirebaseUserCredential: $npm$firebase$auth$UserCredential,
ActionCodeInfo: $npm$firebase$auth$ActionCodeInfo,
ApplicationVerifier: $npm$firebase$auth$ApplicationVerifier,
Auth: typeof $npm$firebase$auth$Auth,
AuthCredential: $npm$firebase$auth$AuthCredential,
AuthProvider: $npm$firebase$auth$AuthProvider,
ConfirmationResult: $npm$firebase$auth$ConfirmationResult,
EmailAuthProvider: typeof $npm$firebase$auth$EmailAuthProvider,
Error: $npm$firebase$auth$Error,
FacebookAuthProvider: typeof $npm$firebase$auth$FacebookAuthProvider,
GithubAuthProvider: typeof $npm$firebase$auth$GithubAuthProvider,
GoogleAuthProvider: typeof $npm$firebase$auth$GoogleAuthProvider,
PhoneAuthProvider: typeof $npm$firebase$auth$PhoneAuthProvider,
TwitterAuthProvider: typeof $npm$firebase$auth$TwitterAuthProvider
};
}
declare module 'firebase/storage' {
declare module.exports: $Exports<'firebase/storage'>;
}
declare module '@firebase/database' {
declare module.exports: {
(app?: $npm$firebase$App): $npm$firebase$database$Database,
enableLogging(
logger?: boolean | ((msg: string) => void),
persistent?: boolean
): void,
DataSnapshot: typeof $npm$firebase$database$DataSnapshot,
Database: typeof $npm$firebase$database$Database,
OnDisconnect: typeof $npm$firebase$database$OnDisconnect,
Query: typeof $npm$firebase$database$Query,
Reference: typeof $npm$firebase$database$Reference,
ServerValue: typeof $npm$firebase$database$ServerValue,
ThenableReference: typeof $npm$firebase$database$ThenableReference
};
}
declare module '@firebase/firestore' {
declare module.exports: {
(app?: $npm$firebase$App): $npm$firebase$firestore$Firestore,
Blob: $npm$firebase$firestore$Blob,
CollectionReference: typeof $npm$firebase$firestore$CollectionReference,
DocumentChange: $npm$firebase$firestore$DocumentChange,
DocumentReference: typeof $npm$firebase$firestore$DocumentReference,
DocumentSnapshot: typeof $npm$firebase$firestore$DocumentSnapshot,
FieldPath: typeof $npm$firebase$firestore$FieldPath,
FieldValue: typeof $npm$firebase$firestore$FieldValue,
Firestore: typeof $npm$firebase$firestore$Firestore,
FirestoreError: $npm$firebase$firestore$FirestoreError,
GeoPoint: typeof $npm$firebase$firestore$GeoPoint,
Query: typeof $npm$firebase$firestore$Query,
QueryListenOptions: $npm$firebase$firestore$QueryListenOptions,
QuerySnapshot: typeof $npm$firebase$firestore$QuerySnapshot,
Settings: $npm$firebase$firestore$Settings,
SnapshotMetadata: $npm$firebase$firestore$SnapshotMetadata,
Transaction: $npm$firebase$firestore$Transaction,
WriteBatch: $npm$firebase$firestore$WriteBatch
};
}
declare module '@firebase/messaging' {
declare module.exports: {
(app?: $npm$firebase$App): $npm$firebase$messaging$Messaging,
Messaging: $npm$firebase$messaging$Messaging
};
}
declare module '@firebase/storage' {
declare module.exports: {
(app?: $npm$firebase$App): $npm$firebase$storage$Storage,
Storage: typeof $npm$firebase$storage$Storage,
FullMetadata: typeof $npm$firebase$storage$FullMetadata,
Reference: typeof $npm$firebase$storage$Reference,
SettableMetadata: typeof $npm$firebase$storage$SettableMetadata,
UploadMetadata: typeof $npm$firebase$storage$UploadMetadata,
UploadTask: typeof $npm$firebase$storage$UploadTask,
UploadTaskSnapshot: typeof $npm$firebase$storage$UploadTaskSnapshot
};
}

View File

@@ -0,0 +1,522 @@
// flow-typed signature: c88a8bddad224bbd6c37f0489c0386ff
// flow-typed version: <<STUB>>/firebase_v9.0.0-beta.2/flow_v0.131.0
/**
* This is an autogenerated libdef stub for:
*
* 'firebase'
*
* Fill this stub out by replacing all the `any` types.
*
* Once filled out, we encourage you to share your work with the
* community by sending a pull request to:
* https://github.com/flowtype/flow-typed
*/
declare module 'firebase' {
declare module.exports: any;
}
/**
* We include stubs for each file inside this npm package in case you need to
* require those files directly. Feel free to delete any files that aren't
* needed.
*/
declare module 'firebase/analytics/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/analytics/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/app/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/app/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/auth/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/auth/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/analytics/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/analytics/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/app/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/app/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/auth/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/auth/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/database/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/database/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/dist/index.node.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/dist/index.rn.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/firestore/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/firestore/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/functions/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/functions/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/messaging/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/messaging/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/performance/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/performance/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/remote-config/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/remote-config/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/compat/storage/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/compat/storage/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/database/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/database/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/firebase-analytics-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-analytics' {
declare module.exports: any;
}
declare module 'firebase/firebase-app-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-app' {
declare module.exports: any;
}
declare module 'firebase/firebase-auth-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-auth' {
declare module.exports: any;
}
declare module 'firebase/firebase-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-database-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-database' {
declare module.exports: any;
}
declare module 'firebase/firebase-firestore-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-firestore-lite' {
declare module.exports: any;
}
declare module 'firebase/firebase-firestore' {
declare module.exports: any;
}
declare module 'firebase/firebase-functions-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-functions' {
declare module.exports: any;
}
declare module 'firebase/firebase-messaging-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-messaging-sw' {
declare module.exports: any;
}
declare module 'firebase/firebase-messaging' {
declare module.exports: any;
}
declare module 'firebase/firebase-performance-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-performance-standalone-compat.es2017' {
declare module.exports: any;
}
declare module 'firebase/firebase-performance-standalone-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-performance' {
declare module.exports: any;
}
declare module 'firebase/firebase-remote-config-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-remote-config' {
declare module.exports: any;
}
declare module 'firebase/firebase-storage-compat' {
declare module.exports: any;
}
declare module 'firebase/firebase-storage' {
declare module.exports: any;
}
declare module 'firebase/firebase' {
declare module.exports: any;
}
declare module 'firebase/firestore/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/firestore/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/firestore/lite/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/firestore/lite/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/functions/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/functions/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/messaging/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/messaging/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/performance/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/performance/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/remote-config/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/remote-config/dist/index.esm' {
declare module.exports: any;
}
declare module 'firebase/storage/dist/index.cjs' {
declare module.exports: any;
}
declare module 'firebase/storage/dist/index.esm' {
declare module.exports: any;
}
// Filename aliases
declare module 'firebase/analytics/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/analytics/dist/index.cjs'>;
}
declare module 'firebase/analytics/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/analytics/dist/index.esm'>;
}
declare module 'firebase/app/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/app/dist/index.cjs'>;
}
declare module 'firebase/app/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/app/dist/index.esm'>;
}
declare module 'firebase/auth/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/auth/dist/index.cjs'>;
}
declare module 'firebase/auth/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/auth/dist/index.esm'>;
}
declare module 'firebase/compat/analytics/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/analytics/dist/index.cjs'>;
}
declare module 'firebase/compat/analytics/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/analytics/dist/index.esm'>;
}
declare module 'firebase/compat/app/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/app/dist/index.cjs'>;
}
declare module 'firebase/compat/app/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/app/dist/index.esm'>;
}
declare module 'firebase/compat/auth/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/auth/dist/index.cjs'>;
}
declare module 'firebase/compat/auth/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/auth/dist/index.esm'>;
}
declare module 'firebase/compat/database/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/database/dist/index.cjs'>;
}
declare module 'firebase/compat/database/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/database/dist/index.esm'>;
}
declare module 'firebase/compat/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/dist/index.esm'>;
}
declare module 'firebase/compat/dist/index.node.cjs.js' {
declare module.exports: $Exports<'firebase/compat/dist/index.node.cjs'>;
}
declare module 'firebase/compat/dist/index.rn.cjs.js' {
declare module.exports: $Exports<'firebase/compat/dist/index.rn.cjs'>;
}
declare module 'firebase/compat/firestore/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/firestore/dist/index.cjs'>;
}
declare module 'firebase/compat/firestore/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/firestore/dist/index.esm'>;
}
declare module 'firebase/compat/functions/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/functions/dist/index.cjs'>;
}
declare module 'firebase/compat/functions/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/functions/dist/index.esm'>;
}
declare module 'firebase/compat/messaging/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/messaging/dist/index.cjs'>;
}
declare module 'firebase/compat/messaging/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/messaging/dist/index.esm'>;
}
declare module 'firebase/compat/performance/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/performance/dist/index.cjs'>;
}
declare module 'firebase/compat/performance/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/performance/dist/index.esm'>;
}
declare module 'firebase/compat/remote-config/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/remote-config/dist/index.cjs'>;
}
declare module 'firebase/compat/remote-config/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/remote-config/dist/index.esm'>;
}
declare module 'firebase/compat/storage/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/compat/storage/dist/index.cjs'>;
}
declare module 'firebase/compat/storage/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/compat/storage/dist/index.esm'>;
}
declare module 'firebase/database/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/database/dist/index.cjs'>;
}
declare module 'firebase/database/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/database/dist/index.esm'>;
}
declare module 'firebase/firebase-analytics-compat.js' {
declare module.exports: $Exports<'firebase/firebase-analytics-compat'>;
}
declare module 'firebase/firebase-analytics.js' {
declare module.exports: $Exports<'firebase/firebase-analytics'>;
}
declare module 'firebase/firebase-app-compat.js' {
declare module.exports: $Exports<'firebase/firebase-app-compat'>;
}
declare module 'firebase/firebase-app.js' {
declare module.exports: $Exports<'firebase/firebase-app'>;
}
declare module 'firebase/firebase-auth-compat.js' {
declare module.exports: $Exports<'firebase/firebase-auth-compat'>;
}
declare module 'firebase/firebase-auth.js' {
declare module.exports: $Exports<'firebase/firebase-auth'>;
}
declare module 'firebase/firebase-compat.js' {
declare module.exports: $Exports<'firebase/firebase-compat'>;
}
declare module 'firebase/firebase-database-compat.js' {
declare module.exports: $Exports<'firebase/firebase-database-compat'>;
}
declare module 'firebase/firebase-database.js' {
declare module.exports: $Exports<'firebase/firebase-database'>;
}
declare module 'firebase/firebase-firestore-compat.js' {
declare module.exports: $Exports<'firebase/firebase-firestore-compat'>;
}
declare module 'firebase/firebase-firestore-lite.js' {
declare module.exports: $Exports<'firebase/firebase-firestore-lite'>;
}
declare module 'firebase/firebase-firestore.js' {
declare module.exports: $Exports<'firebase/firebase-firestore'>;
}
declare module 'firebase/firebase-functions-compat.js' {
declare module.exports: $Exports<'firebase/firebase-functions-compat'>;
}
declare module 'firebase/firebase-functions.js' {
declare module.exports: $Exports<'firebase/firebase-functions'>;
}
declare module 'firebase/firebase-messaging-compat.js' {
declare module.exports: $Exports<'firebase/firebase-messaging-compat'>;
}
declare module 'firebase/firebase-messaging-sw.js' {
declare module.exports: $Exports<'firebase/firebase-messaging-sw'>;
}
declare module 'firebase/firebase-messaging.js' {
declare module.exports: $Exports<'firebase/firebase-messaging'>;
}
declare module 'firebase/firebase-performance-compat.js' {
declare module.exports: $Exports<'firebase/firebase-performance-compat'>;
}
declare module 'firebase/firebase-performance-standalone-compat.es2017.js' {
declare module.exports: $Exports<'firebase/firebase-performance-standalone-compat.es2017'>;
}
declare module 'firebase/firebase-performance-standalone-compat.js' {
declare module.exports: $Exports<'firebase/firebase-performance-standalone-compat'>;
}
declare module 'firebase/firebase-performance.js' {
declare module.exports: $Exports<'firebase/firebase-performance'>;
}
declare module 'firebase/firebase-remote-config-compat.js' {
declare module.exports: $Exports<'firebase/firebase-remote-config-compat'>;
}
declare module 'firebase/firebase-remote-config.js' {
declare module.exports: $Exports<'firebase/firebase-remote-config'>;
}
declare module 'firebase/firebase-storage-compat.js' {
declare module.exports: $Exports<'firebase/firebase-storage-compat'>;
}
declare module 'firebase/firebase-storage.js' {
declare module.exports: $Exports<'firebase/firebase-storage'>;
}
declare module 'firebase/firebase.js' {
declare module.exports: $Exports<'firebase/firebase'>;
}
declare module 'firebase/firestore/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/firestore/dist/index.cjs'>;
}
declare module 'firebase/firestore/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/firestore/dist/index.esm'>;
}
declare module 'firebase/firestore/lite/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/firestore/lite/dist/index.cjs'>;
}
declare module 'firebase/firestore/lite/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/firestore/lite/dist/index.esm'>;
}
declare module 'firebase/functions/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/functions/dist/index.cjs'>;
}
declare module 'firebase/functions/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/functions/dist/index.esm'>;
}
declare module 'firebase/messaging/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/messaging/dist/index.cjs'>;
}
declare module 'firebase/messaging/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/messaging/dist/index.esm'>;
}
declare module 'firebase/performance/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/performance/dist/index.cjs'>;
}
declare module 'firebase/performance/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/performance/dist/index.esm'>;
}
declare module 'firebase/remote-config/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/remote-config/dist/index.cjs'>;
}
declare module 'firebase/remote-config/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/remote-config/dist/index.esm'>;
}
declare module 'firebase/storage/dist/index.cjs.js' {
declare module.exports: $Exports<'firebase/storage/dist/index.cjs'>;
}
declare module 'firebase/storage/dist/index.esm.js' {
declare module.exports: $Exports<'firebase/storage/dist/index.esm'>;
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,7 +13,7 @@
"@storybook/react": "5.1.9",
"axios-mock-adapter": "^1.19.0",
"babel-core": "^7.0.0-bridge.0",
"flow-bin": "0.120.1",
"flow-bin": "0.131.0",
"flow-coverage-report": "^0.4.0",
"folder-hash": "^3.0.0",
"follow-redirects": "^1.2.3",
@@ -45,7 +45,7 @@
"date-fns": "2.16.1",
"downshift": "^3.2.12",
"element-closest": "2.0.2",
"firebase": "8.0.2",
"firebase": "9.0.0-beta.2",
"fontfaceobserver": "2.0.13",
"js-worker-search": "^1.4.1",
"jss-rtl": "^0.3.0",
@@ -83,13 +83,11 @@
},
"scripts": {
"postinstall": "cd ../../GDJS && npm install && cd ../newIDE/app && npm run import-resources && npm run make-version-metadata",
"import-resources": "npm run import-zipped-external-editors && npm run build-theme-resources && cd scripts && node import-libGD.js && node import-GDJS-Runtime.js --clean && node import-monaco-editor.js && node import-zipped-external-libs.js",
"import-resources": "npm run import-zipped-external-editors && npm run build-theme-resources && cd scripts && node import-libGD.js && node import-GDJS-Runtime.js && node import-monaco-editor.js && node import-zipped-external-libs.js",
"make-version-metadata": "cd scripts && node make-version-metadata.js",
"make-service-worker": "cd scripts && node make-service-worker.js",
"start": "npm run import-resources && npm run make-version-metadata && react-scripts start",
"electron-win": "cd ../electron-app && node node_modules/electron/cli.js app",
"electron-linux": "cd ../electron-app && ./node_modules/electron/dist/electron app",
"electron-mac": "cd ../electron-app && ./node_modules/electron/dist/Electron.app/Contents/MacOS/Electron app",
"electron-app": "cd ../electron-app && npm run start",
"build": "npm run import-resources && npm run make-version-metadata && react-scripts build && npm run make-service-worker",
"format": "prettier --write \"src/!(locales)/**/*.js\"",
"check-format": "prettier --list-different \"src/!(locales)/**/*.js\"",
@@ -99,10 +97,10 @@
"storybook": "start-storybook -p 9009 -s public",
"analyze-test-coverage": "react-scripts test --env=node --coverage",
"analyze-flow-coverage": "flow-coverage-report",
"analyze-source-map": "source-map-explorer build/static/js/main.*",
"analyze-source-map": "source-map-explorer build/static/js/*.js",
"extract-all-translations": "node scripts/extract-all-translations.js",
"compile-translations": "node scripts/compile-translations.js",
"reload-extensions": "node scripts/import-GDJS-Runtime.js",
"reload-extensions": "node scripts/import-GDJS-Runtime.js --skip-clean",
"build-theme-resources": "node scripts/build-theme-resources.js",
"create-new-theme": "node scripts/create-new-theme.js",
"import-zipped-external-editors": "cd scripts && node import-zipped-editor.js piskel 5.0.0-beta82 b8e4d57b160ff93d3680168cd271af795412ea6c4c0da321aee2946345c7fb75 && node import-zipped-editor.js jfxr 5.0.0-beta55 8ac12b557c2ddba958c6f0d3e0c5df8cf3369a65262dcb90cf5c8a7a7d20bdf6 && node import-zipped-editor.js yarn 5.0.0-beta103 155f6d074dbb025b082ede0f9b6acd55ed293457441f4c55f084c2d27fbda61d"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

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