Compare commits

..

593 Commits

Author SHA1 Message Date
Hein-Pieter van Braam
6a88e22423 Version 3.0.5-stable 2018-07-08 16:03:43 +02:00
Hein-Pieter van Braam
861d341dff Write new permissions to the AndroidManifest.xml
Instead of editing the placeholder permissions actually write new ones.
This should solve the privacy statement problems for the Play store.
This means we also no longer need to placeholder permissions in the
template.

(cherry picked from commit 2a126242dd)
2018-07-08 15:48:08 +02:00
volzhs
a34daf6851 Fix segfault at quiting editor
(cherry picked from commit e639db0529)
2018-07-08 15:39:15 +02:00
Pedro J. Estébanez
59a00c3cdd Fix debugger focus stealing
At least on Windows, the authorization must be given every time, not only at startup.

(cherry picked from commit 2fcbf9dd81)
2018-07-08 15:39:15 +02:00
Kelly Thomas
e86ef017f2 allow undefined GODOT_DEBUG_MSBUILD environment variable
(cherry picked from commit 17516822f9)
2018-07-08 15:39:15 +02:00
Ignacio Etcheverry
d4a226500b Mono: Add 'View log' button to open the MSBuild log of a build
(cherry picked from commit 4a021fa7a2)
2018-07-08 15:39:15 +02:00
Ignacio Etcheverry
16550339ba Mono: Fix passing wrong logger assembly path to MSBuild
- Add option to print MSBuild's stdout and stderr instead of redirecting it. This can be enabled by setting the environment variable: Godot_DEBUG_MSBUILD=1

(cherry picked from commit 25f10b3c40)
2018-07-08 15:39:15 +02:00
Ignacio Etcheverry
84e1551c64 Mono: Null checks when marshaling from MonoArray* and managed Dictionary
(cherry picked from commit 7933a6cc9f)
2018-07-08 15:39:15 +02:00
Nathan Warden
af902dc042 Lerp now consistent with Godot API. InverseLerp fixed.
(cherry picked from commit c2315e3291)
2018-07-08 15:39:15 +02:00
Rémi Verschelde
d99b247cc7 Revert "Fix saving unmodified scenes and resources"
This reverts commits 28ab60422d
and 7821b70a00.

Fixes #19576, and likely the fact that subresources are no
longer saved when saving scenes with no change.

(cherry picked from commit 5d7f9f804a)
2018-07-08 15:39:15 +02:00
GagaPete
139185e543 Fix CORS problems due to added headers on JS target
Before this change, missing User-Agent and Accept headers were automatically
added on all platforms. Setting the User-Agent header forces the browser to
do a CORS preflight (see 1) which fails if the HTTP endpoint is not
configured appropriate. It's not neccesary to set either header as the
browser sets them and so this commit disables that functionality on the JS
target.

1: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
(cherry picked from commit 8a4dccc4ce)
2018-07-08 15:39:15 +02:00
=
64bcefb7cd Mono: Fixes annotated signal loading in exported binaries
(cherry picked from commit 489c9adf03)
2018-07-08 15:39:15 +02:00
Rémi Verschelde
4ac9932128 Merge pull request #19944 from PatrickKaster/feature/android_modules_asset_dir
asset_dir method in Android modules' gradle config
2018-07-04 23:29:38 +02:00
Patrick Kaster
9190ae2be7 added 'android_add_asset_dir('...') method to Android module gradle build config 2018-07-04 23:04:14 +02:00
Rémi Verschelde
a03cf8964f Fix date typo in changelog 2018-06-28 14:22:43 +02:00
Hein-Pieter van Braam
4bf441c32b Bump to 3.0.5
And onwards!
2018-06-23 17:05:45 +02:00
Hein-Pieter van Braam
b116a45f07 Add changelog for 3.0.4 2018-06-23 16:45:07 +02:00
Hein-Pieter van Braam
d91613592b Godot 3.0.4-stable 'brown paper bag' 2018-06-22 15:33:45 +02:00
Rémi Verschelde
e6df472e8f doc: Remove extraneous empty lines in descriptions 2018-06-22 14:51:59 +02:00
Mel Collins
f6abffdb4a Add longer description to ViewportTexture doc
(cherry picked from commit cf63abac36)
2018-06-22 14:47:09 +02:00
Max Hilbrunner
a1930b1772 [DOCS] Builtin keywords because search is terribad
(cherry picked from commit 5002db6be1)
2018-06-22 14:46:48 +02:00
Max Hilbrunner
9530ce9d3f [DOCS] TreeItem: Small fix for remove_child()
(cherry picked from commit 25b5242d9f)
2018-06-22 14:46:35 +02:00
Max Hilbrunner
3d8e49d9e8 [DOCS] InputEventMouseButton: Factor
(cherry picked from commit 03250259d3)
2018-06-22 14:46:17 +02:00
Mel Collins
64419a2ea1 Add a little to ViewportTexture docs
(cherry picked from commit b820056b38)
2018-06-22 14:45:44 +02:00
letheed
34eabc0602 Fix Vector2 doc of floor, add ceil doc
(cherry picked from commit d759d25aca)
2018-06-22 14:45:18 +02:00
tagcup
ade470352c Added some details in skeleton docs.
Workaround for #19551.

(cherry picked from commit 195e963613)
2018-06-22 14:44:53 +02:00
unknown
ae48b1b94a Added description for abs function in Rect2
(cherry picked from commit d1b3f36eab)
2018-06-22 14:44:34 +02:00
clayjohn
394838901d updated Viewport docs to correct wrong information and fill out empty sections
(cherry picked from commit 650ebdc832)
2018-06-22 14:44:06 +02:00
Bastiaan Olij
f49fcc960b Added some documentation to particles
(cherry picked from commit c4dfef58d9)
2018-06-22 14:43:45 +02:00
Rhody Lugo
2f3e4c1a7a add NoCache wrapper to Command
(cherry picked from commit 920224a535)
2018-06-22 14:42:14 +02:00
Rémi Verschelde
d04cc2855a i18n: Sync translations with Weblate 2018-06-22 10:57:15 +02:00
Rémi Verschelde
909eaede4c Disable threading in Asset Library
Threaded HTTPRequest appears to be crashy on 3.0.x.
Fixes #19336.
2018-06-22 09:30:17 +02:00
Marc Gilleron
4d7aa0b762 Make heightmap shape usable from PhysicsServer
- Fixed bad size check
- Fixed bad member initialization
- Removed unused cell_size (Bullet expects us to use localScaling)
- Accept precomputed min/max height, will be calculated if not provided

(cherry picked from commit a66e1af168)
2018-06-14 15:50:15 +00:00
Hein-Pieter van Braam
98609279b6 Bump version to 3.0.4
And onwards!
2018-06-14 15:37:51 +00:00
Rémi Verschelde
25047050b7 Update AUTHORS and DONORS list
New contributors added to AUTHORS:
@Nallebeorn, @ibrahn, @KellyThomas, @ShyRed

Thanks to all contributors and donors for making Godot possible!

[ci skip]

(cherry picked from commit a18fe06773)
2018-06-14 15:22:48 +00:00
Hein-Pieter van Braam
38e6ba10b4 Update changelog for 3.0.3-stable 2018-06-14 15:21:42 +00:00
Hein-Pieter van Braam
e649ec71df Fix some missed changes from a cherrypick 2018-06-13 12:21:29 +00:00
Hein-Pieter van Braam
711aa196af Bump version to 3.0.3-stable 2018-06-13 11:57:40 +00:00
bruvzg
518a691231 Mono: Allow loading mscorlib from resources.
(cherry picked from commit b3ddf12fb1)
2018-06-13 11:57:40 +00:00
Rémi Verschelde
e8bfc09b81 i18n: Sync translations with Weblate 2018-06-05 22:10:51 +02:00
Rémi Verschelde
74808e71d2 i18n: Sync translation templates with current source 2018-06-05 22:04:33 +02:00
Hugo Locurcio
403f7dc35f Change ".." punctuation for "..." in editor strings (#16507)
(cherry picked from commit 1c419531a0)
2018-06-05 21:42:33 +02:00
Hein-Pieter van Braam
e09170dffa Revert "Prevent visibility notification been called twice in object creation"
This reverts commit 826108efec.

This caused a regression (#18614), and potentially other unintended regressions.
2018-06-05 12:14:57 +02:00
Hein-Pieter van Braam
f640639867 Fix Mono static linking on Mingw 2018-06-01 21:45:21 +02:00
Hein-Pieter van Braam
d24f77be99 Fix documentation version strings 2018-06-01 18:19:33 +02:00
Kelly thomas
f697b53eba round / ceil methods for c sharp vectors
(cherry picked from commit a6bd2c6e72)
2018-06-01 18:08:52 +02:00
Alexander Alekseev
8231b3cef8 Vector3::round, Vector2::round & Vector2::ceil methods were added.
Now both structs (Vector2 & Vector3) have round, floor & ceil methods.
(see #18603)

(cherry picked from commit 26963473a9)
2018-06-01 18:08:29 +02:00
Adam Cigánek
b95cc40640 Set current SynchronizationContext before the game loop starts
This fixes the problem that `SynchronizationContext.Current` would be null
during the call to `_EnterTree`, `_Ready` and the first call to `_Process` thus
the task continuations would be scheduled outside the main thread, which is unexpected and might lead to crashes.

With this change, task continuations are scheduled always on the main thread and so async/await can be used without any explicit synchronization, which is what is expected.

Fixes #18849

(cherry picked from commit f25240cfe6)
2018-06-01 18:07:32 +02:00
Michele Valente
9294978596 fixes build error on Linux after its introduction in #18949
The function expects now a return value. Returning NULL seems to work in
this case.

(cherry picked from commit 6c74f3de6d)
2018-06-01 18:06:44 +02:00
Ignacio Etcheverry
3d3e4e62af Mono: Project building fixes
- Set (Csc/Vbc/Fsc)ToolExe environment variables to point to the batch files in Mono's bin directory when building with Mono's MSBuild.
- Set Mono's MSBuild as the default build tool on Windows.
- Generate projects with portable DebugType instead of full.

(cherry picked from commit 01397a10d9)
2018-06-01 18:06:42 +02:00
Kelly Thomas
d00926894e mono: add Slerp method to vector classes, expose Cross method for Vector2, and fix unnecessary casts in Basis
(cherry picked from commit b335274bcd)
2018-06-01 18:05:28 +02:00
Carter Anderson
5d2ad1e5c7 Reduce allocations when converting mono arrays to pool arrays
(cherry picked from commit 56262ceafe)
2018-06-01 18:04:54 +02:00
Ignacio Etcheverry
9945da3efc Mono: Improve 'script class not found' error
No longer printed when using using placeholder script instances (for non-tool scripts in the editor).
Print different error if the project assembly is not loaded

(cherry picked from commit c8945fe7d8)
2018-06-01 18:04:12 +02:00
Rémi Verschelde
d1e5677fe6 Travis: Add server build with clang
(cherry picked from commit 1e19e2846d)
2018-06-01 18:02:49 +02:00
geequlim
49ddd7b0e7 Add more IDE created files into .gitignore
(cherry picked from commit d3a6960437)
2018-06-01 18:01:21 +02:00
Max Hilbrunner
e29800ea7b Javascript: Remove weird log
(cherry picked from commit 0c56e011ad)
2018-06-01 18:00:51 +02:00
volzhs
97ad6b813a Make filename clipped on Import dock
(cherry picked from commit 12fb5f58d9)
2018-06-01 18:00:17 +02:00
Bastiaan Olij
77542276f8 Check for 0 roll influence
(cherry picked from commit 660bebec94)
2018-06-01 17:59:15 +02:00
Bastiaan Olij
0a3779135d Improve side impulse calculation
(cherry picked from commit a36e5951ff)
2018-06-01 17:59:11 +02:00
anakimluke
edf423a7aa fixed minor doc wording problem
(cherry picked from commit 4fe2605ab3)
2018-06-01 17:56:56 +02:00
clayjohn
02b1586de2 filled in docs for panorama sky
filled in docs for panorama sky

(cherry picked from commit 1bf7f8fcd1)
2018-06-01 17:56:24 +02:00
clayjohn
a2a136ea02 added documentation for procedural sky
Added documentation for procedural sky

added documentation for procedural sky

added documentation for procedural sky

(cherry picked from commit 6711691d10)
2018-06-01 17:55:54 +02:00
Kelly Thomas
9b8388dab1 [docs] fix links in class docs
(cherry picked from commit 888eefa0fd)
2018-06-01 17:55:13 +02:00
Kelly Thomas
fbad7c2dd9 [docs] fix links in class docs
(cherry picked from commit c6ed46891d)
2018-06-01 17:53:52 +02:00
Chris Bradfield
12fe774844 [DOCS] Update VideoPlayer classref
(cherry picked from commit 393125a6a4)
2018-06-01 17:52:07 +02:00
Max Hilbrunner
8dc021925f [DOCS] Array sort
(cherry picked from commit 9115d84913)
2018-06-01 17:50:56 +02:00
Bastiaan Olij
6843ccf462 Added some quick info on shaders to the docs
(cherry picked from commit b7ae2ca128)
2018-06-01 17:50:29 +02:00
Michael Alexsander Silva Dias
b27352a401 Fixed GroupCallFlags links in the SceneTree's doc.
(cherry picked from commit e10687a520)
2018-06-01 17:49:22 +02:00
Kelly Thomas
8461d6b5f9 Mono: Basis constructor for euler parameter
(cherry picked from commit c26d30986a)
2018-06-01 17:46:38 +02:00
Kelly Thomas
0febfa9eea mono: New Color methods: Darkened, Lightened and ToRgba32
(cherry picked from commit 88bd33f451)
2018-06-01 17:45:49 +02:00
Kelly Thomas
232a3a524b mono: Plane, expose Normal, and D
(cherry picked from commit 16e1b4bacf)
2018-06-01 17:44:56 +02:00
toger5
b04c9a1b66 fixed capital A osx
(cherry picked from commit 6476b708d9)
2018-06-01 17:43:28 +02:00
toger5
dd026c77e3 fixed a input not registered in osx script editor
(cherry picked from commit d927e972d1)
2018-06-01 17:43:14 +02:00
Sherjil Ozair
00bf66d7f2 Add additional macos shortcuts for going to start/end of line
(cherry picked from commit 166c7fdc9d)
2018-06-01 17:43:10 +02:00
Kelly Thomas
6224f02c56 Fix index out of range error in string.Extension()
(cherry picked from commit c7e98eef67)
2018-06-01 17:37:43 +02:00
Rémi Verschelde
31ce9ba07f Fix scons installation on AppVeyor
Seems like AppVeyor just upgraded pip and finally removed the
deprecated --egg switch.

(cherry picked from commit 79e76d8329)
2018-06-01 17:35:29 +02:00
Ignacio Etcheverry
94b4bb2a12 Mono: Fix MonoImage filename being set to an invalid path
(cherry picked from commit 97fb999976)
2018-06-01 17:33:51 +02:00
Dmitry Pupinin
188bfd2ac9 Increase versionCode range 3.0
(cherry picked from commit d71d968987)
2018-06-01 17:33:27 +02:00
Hein-Pieter van Braam
04defcca4f Bump to 3.0.3rc3 2018-06-01 17:27:54 +02:00
Paul Joannon
81eb60434a [mono] fix signals parameter retrieval
(cherry picked from commit 7a72395412)
2018-05-16 12:27:45 +02:00
Hein-Pieter van Braam
6635f2a108 Add back missing method from e10a2e5999 2018-05-14 00:25:34 +02:00
Paul Joannon
1d3be8c453 fix API string path
(cherry picked from commit a35c8bbdc7)
2018-05-13 23:03:48 +02:00
JFonS
4de1d0905a Fix vector reduction in shader language
(cherry picked from commit 5b50685b38)
2018-05-13 23:02:32 +02:00
Karolis K
c461b15720 Fix icon if remote icon load fails
(cherry picked from commit c3e921fba3)
2018-05-13 22:58:13 +02:00
Fabio Alessandrelli
5c93f887ba Implement missing methods in dummy rasterizer
(cherry picked from commit 0cad1417b6)
2018-05-13 22:56:53 +02:00
Leon Krause
9dc5ca0e7c Fix duplicate definitions with FreeType
(cherry picked from commit b8c35b4078)
2018-05-13 22:46:11 +02:00
Chris Bradfield
c7b141d20a [DOCS] Vector2/Vector3/TileMap wording fixes
(cherry picked from commit 8bc4882dd3)
2018-05-13 22:45:08 +02:00
volzhs
0b3b3de2cd Ability to change path color with self modulate
Fix #18164

(cherry picked from commit d77ffa3e97)
2018-05-13 22:43:10 +02:00
Bastiaan Olij
5e551a584e added custom aabb to primitives
(cherry picked from commit 1ee40206d4)
2018-05-13 22:41:29 +02:00
Alexander Holland
fd95935fef hide tab changed debug print
(cherry picked from commit 31f28885f9)
2018-05-13 22:40:28 +02:00
RaphaelHunter
4fbb460a02 Fix:code editor text size should change at least one each time, don't mind how you setting your display scale
(cherry picked from commit eeb0534426)
2018-05-13 22:39:13 +02:00
Michael Alexsander Silva Dias
4aad40d249 Small changes for some strings.
(cherry picked from commit 5b0ddb1354)
2018-05-13 22:37:56 +02:00
Hugo Locurcio
8ccb27ce18 Tweak the property hint ranges of caret blink and line length guideline
This allows for more precise adjustments.

(cherry picked from commit 0eb2f6c223)
2018-05-13 22:36:21 +02:00
Anish
9a0a40042e Adds keywords to autocomplete predictions.
Adds keywords to the autocomplete prediction in GDScript so
they are not replaced by irrelevant predictions.

Fixes: #5972
(cherry picked from commit 6e32157a65)
2018-05-13 22:35:19 +02:00
Unknown
09277c8fd8 LinkButtons are now responsive to engine theme
Fixes #18636, so now LinkButtons (like those in the asset store) will change font colour to remain visible in any engine theme, just like Labels etc

(cherry picked from commit c364a1278e)
2018-05-13 22:34:10 +02:00
Hein-Pieter van Braam
faceb5b75d Implement pull/18665 for 3.0
Windows detect.py: Detect missing WindowsSdkDir
2018-05-13 22:32:01 +02:00
Hein-Pieter van Braam
9dc5ba1aaf Bump version to 3.0.3rc2 2018-05-13 22:28:07 +02:00
robfram
a187fb381e Fix placeholders position in LineEdit when editing inside the Editor
Editing the `Text` property through the editor causes a wrong
placement of the placeholder, as it calls `LineEdit::clear_internal`,
which was wrongly reseting the cached placeholder width.

Fix #18184.

(cherry picked from commit c17de1f70f)
2018-05-13 22:19:42 +02:00
Leon Krause
868c44b239 Fix keyboard focus lock-out with HTML5 canvas in iframe
(cherry picked from commit 9080e96bc8)
2018-05-13 22:17:53 +02:00
Charly Mourglia
10c12b37ec Consider TextEdit paste operation complex.
Not considering a paste operation as a complex one ends up
adding an unneeded extra step when pasting over a selection.

This fixes issue #18325

(cherry picked from commit b09e0454bb)
2018-05-13 22:16:56 +02:00
Brian Richardson
ae32bcf4c3 Fix a crash when trying to run Godot debugger on a release build.
The GDScriptLanguage::enter_function is wrapped in #ifdef DEBUG but the exit_function is not, resulting in a stack underflow error.

(cherry picked from commit 9149b11973)
2018-05-13 22:14:44 +02:00
thfrwn
3491e776dd fix clang6 assignment error
(cherry picked from commit f48ff4dc64)
2018-05-13 22:13:14 +02:00
Ibrahn Sahir
5f632391ca fix for segfault when using CallBasic in visual script on release build
(cherry picked from commit 95dfa5b96d)
2018-05-13 22:11:08 +02:00
Poommetee Ketson
2e61ca6193 Particles: fix corrupted scene when saved after convert (2nd try)
(cherry picked from commit 38865345d9)
2018-05-13 22:08:53 +02:00
Peter Folkins
3013f4cf2b Fix AnimationPlayer edited scene bug
(cherry picked from commit 223f085857)
2018-05-13 22:05:28 +02:00
Peter Folkins
31c4b743cb Fix enums without class name not opening docs page
(cherry picked from commit ccd986f53e)
2018-05-13 22:04:37 +02:00
Felix Yang
78e2e48d57 Fix for Issue#18457 - Folder name with trailing space on Windows
(cherry picked from commit 164dceab28)
2018-05-13 22:03:40 +02:00
Ignacio Etcheverry
736e574a5e Fix editor detecting msbuild with a msvc 'tools only' install
(cherry picked from commit 93d13bee8b)
2018-05-13 22:00:53 +02:00
Ignacio Etcheverry
664052824e Fix MSVC check when building with mono
(cherry picked from commit a1aa98e05a)
2018-05-13 22:00:20 +02:00
RaphaelHunter
0b9f61c9a6 add condition check in Imgae::create(...)
(cherry picked from commit 63e258cc8f)
2018-05-13 21:59:22 +02:00
Hein-Pieter van Braam
41bb321962 For uwp the ARM architecture needs to be in lower case
(cherry picked from commit 07f590046a)
2018-05-13 21:58:37 +02:00
Geequlim
0c030d6e08 Fix double free for drag preview control in viewport
(cherry picked from commit 56c2463f8c)
2018-05-13 21:56:56 +02:00
Pedro J. Estébanez
c8ce9c0080 Fix Variant leak in call_native
(cherry picked from commit 474eda9e30)
2018-05-13 21:55:19 +02:00
DmitryKrutskikh
a519dcd576 Disable 'run' button if any project not selected and tiny refactoring
(cherry picked from commit 965b6ac273)
2018-05-13 21:53:27 +02:00
Leon Krause
66c0be642f Fix relative mouse motion when captured in HTML5 platform
(cherry picked from commit d78b10313b)
2018-05-13 21:52:14 +02:00
Guilherme Felipe
2fa54c1df6 Fix custom cursor disappearing on osx
(cherry picked from commit 48f9e6a05b)
2018-05-13 21:51:25 +02:00
Yaakuro
7f65584f28 Use mimetype according to glTF spec.
(cherry picked from commit 9a50a4442d)
2018-05-13 21:48:37 +02:00
Ruslan Mustakov
7e09206e5c Proper focus in/out handling on iOS
PR #18675 (commit 96301e9) revealed a problem with how iOS lifecycle
callbacks were handled by Godot. Before that PR it was possible to get
NOTIFICATION_WM_FOCUS_IN callback without getting the corresponding
NOTIFICATION_WM_FOCUS_OUT. That commit added a flag to ensure they are
always coupled, but now there is an issue when, for example, you open a
notification panel on iOS without moving the app to background.
It resulted in view.stopAnimation being called without the
corresponding startAnimation when the app moves to foreground again, so
it looked like the game hanged.

I changed focus out notification to be sent in applicationWillResignActive,
because it makes more sense than to do it in applicationDidEnterBackground,
because it is always called in pair with applicationDidBecomeActive, where
focus in is sent. applicationDidEnterBackground may not come under
circumstances that are now described as a comment in code.

(cherry picked from commit 08a924bcee)
2018-05-13 21:46:57 +02:00
Ruslan Mustakov
ecb4c4268c Resume audio on iOS after phone call or alarm
When a phone call or an alarm triggers on iOS, the application receives
an "audio interruption" and it's up to the application to resume
playback when the interruption ends. I added handling for audio
interruptions same as if the game is focused out and then back in.

(cherry picked from commit 96301e934d)
2018-05-13 21:46:53 +02:00
bruvzg
db76c54117 Fix Linux/X11 build on ARMs.
(cherry picked from commit ce64c2a32e)
2018-05-13 21:45:09 +02:00
ShyRed
c2a8eb2081 Use fake audio playing property in editor
It appears that some time ago users were supposed to be able to include the playback of sound effects in their animations by placing keys on the "playing" property. Back then the key frame editor took the value of the checkbox in the property_editor.

Somewhere / Sometime this behaviour changed and the key frame editor is now reading the actual value from the object instead of relying on the property editor.

This commit introduces a fake active field that is returned when reading the playing property in the editor. While the actual active flag is changed when playback is finished the fake one will stay the same thus allowing the user to take their time with setting the key in the animation editor.

(cherry picked from commit bc1522e268)
2018-05-13 21:42:27 +02:00
Hein-Pieter van Braam
5917063192 Merge pull request #18082 from RandomShaper/improve-gui-touch-3.0
Implement universal translation of touch to mouse (3.0)
2018-05-13 21:30:37 +02:00
Hein-Pieter van Braam
bcb38393a5 Merge pull request #18157 from RandomShaper/improve-uri-utils-3.0
Improve/fix URI utils (3.0)
2018-05-13 21:11:42 +02:00
Rémi Verschelde
1905e1c8a2 Android: Increase targetSdkVersion to 27
Matches the change for 2.1 in #18626, and the new requirements from Google
for new apps starting with August 2018 (targetSdkVersion 26 or higher):
https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html

(cherry picked from commit a6552819b1)
2018-05-08 15:30:11 +02:00
Gustav Lund
a6c9527c2f Fix for large .pck files
An error in unix file IO was causing crashes when getting the size of a file larger than max integer size
As ftell returns a long the fix is trivial

(cherry picked from commit 8a7840a304)
2018-05-08 09:10:26 +02:00
Chris Bradfield
f4c469f1b7 Rewrite Tween class reference.
(cherry picked from commit d7218c742c)
2018-05-08 09:09:04 +02:00
Kelly Thomas
196107cd9e correct documentation for version number data type
(cherry picked from commit 28eb97c8ab)
2018-05-08 09:08:52 +02:00
Mel Collins
33b78c0ad6 [DOCS] Clarify look_at and looking_at
(cherry picked from commit b431264f77)
2018-05-08 09:07:52 +02:00
RameshRavone
fa19d01c7b Fix: JAR files signed with the MD5 algorithm as unsigned
(cherry picked from commit d3182248c4)
2018-05-08 09:06:54 +02:00
Rémi Verschelde
f847837fb2 Update AUTHORS and DONORS list
New contributor added to AUTHORS:
@mysticfall

Thanks to all contributors and donors for making Godot possible!

[ci skip]

(cherry picked from commit bd54ff78d9)
2018-05-04 15:14:16 +02:00
Rémi Verschelde
056348a8c0 i18n: Sync translation templates with current source 2018-05-03 11:25:51 +02:00
Rémi Verschelde
ddbe559c04 i18n: Sync translations with Weblate 2018-05-03 11:20:59 +02:00
Your Name
63e70e3cd1 Bump to 3.0.3-rc1 2018-05-01 22:08:47 +02:00
Robin Hübner
4866733a74 GDNative Unix: fix shared lib loading, dlopen expects leading ./ to interpret as relative path.
(cherry picked from commit 8287441955)
2018-05-01 22:07:02 +02:00
Marcelo Fernandez
01e64eb247 Prevent PulseAudio driver to lock its mutex for too long
(cherry picked from commit cf4371a0ad)
2018-05-01 22:05:20 +02:00
Marcelo Fernandez
4fe0a8efd8 Fixed high cpu usage with PulseAudio
(cherry picked from commit 11078101db)
2018-05-01 22:04:51 +02:00
Max Hilbrunner
0551c5c2cd PCKPacker:pck_start(): Update version
(cherry picked from commit a3aa5ad0d0)
2018-05-01 22:04:08 +02:00
Pedro J. Estébanez
e10a2e5999 Implement universal translation of touch to mouse
Now generating mouse events from touch is optional (on by default) and it's performed by `InputDefault` instead of having each OS abstraction doing it. (*)

The translation algorithm waits for a touch index to be pressed and tracks it translating its events to mouse events until it is raised, while ignoring other pointers.

Furthermore, to avoid an stuck "touch mouse", since not all platforms may report touches raised when the window is unfocused, it checks if touches are still down by the time it's focused again and if so it resets the state of the emulated mouse.

*: In the case of Windows, since it already provides touch-to-mouse translation by itself, "echo" mouse events are filtered out to have it working like the rest.

On X11 a little hack has been needed to avoid a case of a spurious mouse motion event that is generated during touch interaction.

Plus: Improve/fix tracking of current mouse position.
2018-04-30 19:04:35 +02:00
Hein-Pieter van Braam
cd9b0d7cc3 Fix msbuild with a msvc 'tools only' install
Taken from https://github.com/Microsoft/vswhere/wiki/Find-MSBuild
without '-products *' vswhere does not locate msbuild when installing a
tools-only (no IDE) version of the microsoft compilers.

(cherry picked from commit 0ec912a79e)
2018-04-30 12:54:51 +02:00
Hein-Pieter van Braam
8e301c69cb Fix lto builds on clang compilers
This needs to go to master also
2018-04-30 00:52:42 +02:00
Hein-Pieter van Braam
3ee4d6af2e Hand-merge API hash fixes #18514
This hasn't made it into master yet but is important for mono support.
If this turns out to be the wrong call we'll revert and merge whatever
next version of this becomes available.
2018-04-29 20:44:48 +02:00
Ignacio Etcheverry
00c55bb2eb Fix _export_begin not being called when exporting to android
(cherry picked from commit c8884ce3bd)
2018-04-29 18:45:09 +02:00
Ignacio Etcheverry
fe9da69f96 Make 'Export PCK/ZIP' work well with EditorExportPlugin
Add debug flag to the 'Export PCK/ZIP' option
Make 'Export PCK/ZIP' notify when the export process begins. This is necessary to receive the 'EditorExportPlugin::_export_begin' callback

(cherry picked from commit 68b35de2b6)
2018-04-29 18:44:55 +02:00
Ignacio Etcheverry
c358e4c728 Add option to link mono statically on Windows
(cherry picked from commit b5e6e142ef)
2018-04-29 16:16:26 +02:00
Ivan Vodopiviz
7645c539c8 Fix new Node dialog Create button behavior
Added a one-liner to update the Create button disabled state when
selecting an item from the search results list.

Fixes #17265, long live the Realm!

(cherry picked from commit 68a4241131)
2018-04-29 15:14:09 +02:00
Marcelo Fernandez
e7837828f6 Improved error checking at EditorExportPlatformPC::export_project
(cherry picked from commit 0876502f72)
2018-04-29 15:12:21 +02:00
Marcelo Fernandez
272fb05270 Added File.get_path and File.get_path_absolute functions
(cherry picked from commit a4e64c5454)
2018-04-29 15:09:29 +02:00
ShyRed
41f360f9c2 Update preview on filesystem change
Check and recreate a file's preview, if it has changes to it in the filesystem.

(cherry picked from commit 188ccf190b)
2018-04-29 15:08:11 +02:00
Bernhard Liebl
4ce6a8f5f9 Show error icon at "Output" in case of errors
(cherry picked from commit 5120690013)
2018-04-29 15:06:29 +02:00
Bastiaan Olij
dfe6d42a01 A few fixes on the ARVR Server
(cherry picked from commit 5356423377)
2018-04-29 15:05:38 +02:00
Peter Folkins
c20776945d Set default file name for exported projects
(cherry picked from commit bff73bdbf1)
2018-04-29 15:03:45 +02:00
Wilson E. Alvarez
0d6c64b38a Removed unneeded sort from SpriteFramesEditor plugin
(cherry picked from commit bb9c75c5ed)
2018-04-29 15:02:18 +02:00
Leon Krause
c968c787e5 Disable Emscripten assertions in release_debug builds
The messages generated by some assertions can be confusing to users.

(cherry picked from commit d6c9d8d778)
2018-04-29 15:01:29 +02:00
Bernhard Liebl
6e658fdcc1 Warn about WorldEnvironment being ignored
(cherry picked from commit 29d305599d)
2018-04-29 15:00:41 +02:00
Pieter-Jan Briers
aedc4a4e80 Explicitly print an error when --export fails.
Previously this would not explicitly say the export failed.
Sure you might see another error somewhere,
but that's not very reliable/obvious.

(cherry picked from commit 4954982b95)
2018-04-29 14:57:32 +02:00
Wilson E. Alvarez
7417b6adb4 Comment out some debugging messages when playing Theora files
(cherry picked from commit 9590282ae8)
2018-04-29 14:56:52 +02:00
Fabio Alessandrelli
66b36235c9 Fix IPhone and OSX cross compilation
(cherry picked from commit e7b9e2f970)
2018-04-29 14:46:03 +02:00
Rémi Verschelde
e317ab9abe Add --print-fps option to output FPS to stdout
Works both for the editor and games.

Projects can still use "debug/settings/stdout/print_fps" to enable it
permanently. The --print-fps option takes precedence (so works even if
the project setting is disabled). That setting is also no longer redefined
on the fly based on the verbose flag, that was a mess.

(cherry picked from commit 10fa69285c)
2018-04-29 14:44:43 +02:00
Brigham Henry Keys
6a48c552e2 Updated thekla_atlas to support arm64
(cherry picked from commit cd63e699ca)
2018-04-29 14:43:53 +02:00
Craigory V Coppola
a1fd60f7d2 Docs update for several classes
Namely: Dictionary, GraphEdit, Object, TileMap, Script, ScollBar,
ScrollContainer and SplitContainer

(cherry picked from commit 0dd526e062)
2018-04-29 14:42:13 +02:00
HoratioZEDU
b5ecdd8ce8 Fixed (minor) typo in CapsuleShape2D doc page
(cherry picked from commit 2dcd499707)
2018-04-29 14:35:59 +02:00
homer666
20ea59332f [DOCS] Popup.popup_exclusive description
(cherry picked from commit d4ce53b9b1)
2018-04-29 14:35:42 +02:00
krogank9
57b895338b [DOCS] Add note that Pool*Arrays are passed by value (#18340)
(cherry picked from commit 6b797574a2)
2018-04-29 14:33:28 +02:00
Poommetee Ketson
2f82b67071 [DOCS] add HTTPRequest.request return values
(cherry picked from commit f05e24ed18)
2018-04-29 14:32:44 +02:00
bncastle
56b8c4b0eb Add descriptions for GroupCall flags
Add descriptions for GroupCall flags

(cherry picked from commit 7eed3cc199)
2018-04-29 14:32:13 +02:00
Max Hilbrunner
bae5f9feb8 [DOCS] OS
(cherry picked from commit 66714a3d29)
2018-04-29 14:31:56 +02:00
Poommetee Ketson
e95f542204 Add new transform tutorial to appropriate classes
(cherry picked from commit e83af5dfc6)
2018-04-29 14:30:45 +02:00
Denis Washington
e7c42f132c Add Navigation docs
(cherry picked from commit 89b9e8852e)
2018-04-29 14:30:25 +02:00
Denis Washington
1608f04851 Add Navigation2D docs
(cherry picked from commit a7f3933a51)
2018-04-29 14:30:13 +02:00
Max Hilbrunner
93ebac318b [DOCS] SceneTree
(cherry picked from commit bc66869d4c)
2018-04-29 14:29:25 +02:00
Mel Collins
c4d66d087f [DOCS] Tweaks and fixes for (Interpolated)Camera
(cherry picked from commit 99110772c0)
2018-04-29 14:28:58 +02:00
GaryO
feee8ddd3c Add detail to doc for add_surface_from_arrays (#17911)
Includes review comments from #17911 from @cbscribe and @Noshyaar

(cherry picked from commit 06c5a9ed5f)
2018-04-29 14:27:46 +02:00
Michael Alexsander Silva Dias
659df8cbd8 Added missing end points for brief descriptions in the docs.
(cherry picked from commit d912e10c65)
2018-04-29 14:27:30 +02:00
Mel Collins
19a010cc3a [DOCS] Some content for InterpolatedCamera
(cherry picked from commit c05d12384a)
2018-04-29 14:27:15 +02:00
mhilbrunner
307fcb2713 [DOCS] Typo fix for CollisionShape[2D]
(cherry picked from commit 41da122875)
2018-04-29 14:27:01 +02:00
Max Hilbrunner
ec017f4c01 [DOCS] Node & PackedScene (#17833)
* [DOCS] Node: SceneSaver -> PackedScene

* [DOCS] PackedScene: Code example, resolve TODO

(cherry picked from commit 13d5ee01f9)
2018-04-29 14:25:17 +02:00
Pieter-Jan Briers
f12db4013e Improve Input.is_action_just_* docs.
More clarification.

(cherry picked from commit 11aa330a6f)
2018-04-29 14:24:52 +02:00
mhilbrunner
e53f01a7af [DOCS] Node: Networking updates, fix outdated and missing docs
(cherry picked from commit 5a3e841c60)
2018-04-29 14:24:26 +02:00
Max Hilbrunner
46de6afc40 [DOCS] Input
(cherry picked from commit 22cb4a1cf9)
2018-04-29 14:23:23 +02:00
Max Hilbrunner
90bf0b7aec [DOCS] Net.MultiplayerEnet: List returned errors
(cherry picked from commit ec3f5218e8)
2018-04-29 14:23:04 +02:00
Neil Moore
6cdf6d3044 Update Image format enumeration documentation
Provides more information about each image format.

(cherry picked from commit 60f1f58158)
2018-04-29 14:22:40 +02:00
Xavier Cho
1da969736f Remove duplicated declaration of RoundToInt() from Mathf
(cherry picked from commit 9e2e6bb1e2)
2018-04-29 14:15:09 +02:00
Paul Joannon
486f4d2769 [mono] add the 'Facades' subfolder to the searched directories in _preload_hook
(cherry picked from commit 22606a7bec)
2018-04-29 13:54:16 +02:00
Ignacio Etcheverry
199a54d5ac Mono: BindingsGenerator enum fixes
- Make enums have an unique signature name of int. This means that when generating internal methods, there is no difference between different enums types nor between enums and int. This way enums can re-use internal methods.
- Make type resolver fallback to int if a type is not found and it's an enum.

(cherry picked from commit fbc808012f)
2018-04-29 13:49:27 +02:00
Xavier Cho
57c281557a #18051: Fix indentation issues introduced during clean up
(cherry picked from commit 6b611e6431)
2018-04-29 13:40:15 +02:00
Xavier Cho
d330bee1c2 #18051: Do not use var in a for-loop, or where type is not obvious
(cherry picked from commit e59fad3924)
2018-04-29 13:40:09 +02:00
Xavier Cho
72bcacf2b6 #18051: Use common name for Color type argument
(cherry picked from commit 94edd92248)
2018-04-29 13:40:04 +02:00
Xavier Cho
3876a8776e #18051: Remove redundant verbatim prefixes
(cherry picked from commit f0bf5532fa)
2018-04-29 13:39:51 +02:00
Xavier Cho
37ce381e3d #18051: Use default parameter value
(cherry picked from commit 85787776a5)
2018-04-29 13:39:40 +02:00
Xavier Cho
939d50243b #18051: Use array initializer when applicable
(cherry picked from commit b765c051cb)
2018-04-29 13:39:34 +02:00
Xavier Cho
57f18194f5 #18051: Remove redundant parenthesis
(cherry picked from commit 9097c71255)
2018-04-29 13:39:28 +02:00
Xavier Cho
58f2953ddf #18051: Remove unnecessary variable assignments
(cherry picked from commit 93dd59d763)
2018-04-29 13:39:22 +02:00
Xavier Cho
31171ea5a2 #18051: Use 'var' when applicable
(cherry picked from commit fdfc478c88)
2018-04-29 13:39:08 +02:00
Xavier Cho
e7b97af276 #18051: Remove redundant casts and 'using', 'else', 'this' statements
(cherry picked from commit 0ef3e0577b)
2018-04-29 13:38:58 +02:00
Marcelo Fernandez
95004aafb2 Fix use64 used without being initialized
(cherry picked from commit 9b4d23e898)
2018-04-28 23:06:24 +02:00
Ignacio Etcheverry
3f6ea30f8d Mono: Fix '!t' error messages when generating bindings
This error wasn't affecting the bindings generation process.

(cherry picked from commit ff7fe9e771)
2018-04-28 22:59:38 +02:00
Ignacio Etcheverry
58918b629d Mono: Do not spam script class not found error
Print this error only when trying to instantiate the script. This way we prevent errors being printed for source files which are not meant to be used as scripts.

(cherry picked from commit f8ce412560)
2018-04-28 22:59:25 +02:00
Ignacio Etcheverry
736d8db007 Mono: Fix crash on script load if the scripts domain isn't loaded
(cherry picked from commit 89e84185e8)
2018-04-28 22:59:11 +02:00
Pieter-Jan Briers
1e8ff7460a Fixes a typo in the VisualServer.canvas_item_add_set_transform docs.
(cherry picked from commit 09f79cde69)
2018-04-28 22:58:29 +02:00
sersoong
b5425e3d87 Fixed context menu TTR bugs
(cherry picked from commit a1cfc89108)
2018-04-28 22:57:32 +02:00
George Marques
3acd6fb728 Fix names of Variant operators
(cherry picked from commit fefee533ae)
2018-04-28 22:56:33 +02:00
volzhs
94ddb499df Fix error spam with Sprite has compressed texture
Fix #18177

(cherry picked from commit 3ecf8eef37)
2018-04-28 22:54:54 +02:00
volzhs
5a947ebc42 Fix index out of size error on Image
Fix #18229

(cherry picked from commit af0d547c02)
2018-04-28 22:54:44 +02:00
Bojidar Marinov
44f4c8e745 Fix crash resulting from bad month check in core_bind.cpp
Also, make it clear that day is 0-based. This might cause very slight differcies in existing games.
Fixes #18221

(cherry picked from commit 4b9cf93338)
2018-04-28 22:53:02 +02:00
Ruslan Mustakov
4eed7cb9b2 Fix Android input source checks
Input source types are not pure bit flags, they are combinations of
flags, so != 0 check was incorrect and resulted in crashes later, when
trying to obtain the device.

(cherry picked from commit 5dffa506dc)
2018-04-28 22:50:25 +02:00
Michael Alexsander Silva Dias
ca00323e7f Minor fixes for the AnimationPlayer doc.
(cherry picked from commit 9c3698dee2)
2018-04-28 22:48:28 +02:00
Will Vincent
d49fc76ab8 Remove incorrect & potentially confusing references to Euler
e is referred to as Euler’s number, so technically the MATH_EXP description in VisualScript doc was not incorrect, though could potentially lead to confusion.

e is different from Euler’s constant however, making the existing GDScript exp & VisualScriptMathConstant descriptions nvalid.

(cherry picked from commit b6b8c7b215)
2018-04-28 22:47:43 +02:00
ShyRed
d89015cfe3 ItemList selection: Check against item count
ItemList needs to check against the number of items available when the user moves the selection via "ui_right" action.

(cherry picked from commit cbcb96ae85)
2018-04-28 22:43:36 +02:00
Chaosus
826108efec Prevent visibility notification been called twice in object creation
(cherry picked from commit d42b17607e)
2018-04-28 22:38:19 +02:00
Andrea Catania
739c14b07d Fixed wrong function call
(cherry picked from commit df2a626b49)
2018-04-28 22:35:25 +02:00
robfram
7f64090401 LineEdit placeholder alignment, content margins, and overflow bugs
LineEdit doesn't correctly uses style margins nor use placeholders
width correctly, causing multiple rendering bugs.

(cherry picked from commit 53b51f68bf)
2018-04-28 22:30:06 +02:00
Pedro J. Estébanez
3bda257163 Fix theme editor sample widgets
(cherry picked from commit a0626d7d9c)
2018-04-28 22:19:54 +02:00
Pedro J. Estébanez
02f767fe0d Add support for radio-looking items with icon
Letting users of `PopupMenu` use them. `OptionButton` was one of those interested and is updated in this commit.

Fixes #18063.

(cherry picked from commit b964a9e678)
2018-04-28 22:17:08 +02:00
Pedro J. Estébanez
20fa30bde6 Use radio-button-like menu entries where applicable
(cherry picked from commit a6dc160d5c)
2018-04-28 22:16:53 +02:00
Pedro J. Estébanez
b5b0e42b85 Support radio-button entries in ItemListPlugin
(cherry picked from commit bf14a6deff)
2018-04-28 22:16:38 +02:00
Pedro J. Estébanez
a525ea128d Add radio-button-looking entries to PopupMenu
They work exactly the same as current checkbox-decorated items, but in order to preserve compatibility, separate methods are used, like `add_radio_check_item()`. The other option would have been to add a new parameter at the end of `add_check_item()` and the like, but that would have forced callers to provide the defaults manually.

`is_item_checkable()`, `is_item_checked()` and `set_item_checked()` are used regardless the item is set to look as check box or radio button.

Keeping check in the name adds an additional clue about these facts.

Closes #13055.

(cherry picked from commit ab3b1d9f3e)
2018-04-28 22:16:25 +02:00
Andrea Catania
3b57b95efb Fixed area overlap cleaning
(cherry picked from commit 45b778c7f8)
2018-04-28 22:10:29 +02:00
Alexander Alekseev
4002da9603 Fix RigidBody's configuration warning for Z axis
(cherry picked from commit 6a5ed3a42b)
2018-04-28 20:30:34 +02:00
Crazy-P
e5a17617e6 Resolves Inccorect Quaternion Conversion
Fixes https://github.com/godotengine/godot/issues/18025

(cherry picked from commit ae7a9df292)
2018-04-28 20:29:40 +02:00
Pedro J. Estébanez
4e756d61c8 Fix skeleton import from glTF
For some glTF files, the order of bones in the skeleton array wasn't matching the joints array in the meshes.

Fixes #17808.

(cherry picked from commit d8765dd103)
2018-04-28 20:24:43 +02:00
Alexander Alekseev
0f5a3d23ea Update transform buttons in tile editor while using T, A, S shortcuts (fixes #17962)
(cherry picked from commit 0853ac2006)
2018-04-28 20:24:00 +02:00
karroffel
2e31c9fe10 fix bone scale/rotation in AnimationPlayers
fixes #17325.

The bone pose transform was created by setting the rotation and
**then** scaling the transform. This leads to object "deformation"
that's not intended.

(cherry picked from commit 4303fbca5a)
2018-04-28 20:19:35 +02:00
Alexander Alekseev
cf3c1d878d Fix of a possible memory leak: ConcavePolygonShapeBullet::setup was able to exit without releasing the 'shapeInterface' pointer.
(cherry picked from commit b569251110)
2018-04-28 20:18:03 +02:00
Poommetee Ketson
c5dfe6824c Mesh: fix crash when creating mesh outline from QuadMesh
Since create_outline can only make outline for PRIMITIVE_TRIANGLES,
when QuadMesh (which is PRIMITIVE_TRIANGLE_FAN) is used to create
outline, will leave `arrays` empty, and crash when it is being indexed
for "indices" subarray.

This PR shows error when there's only one surface and it is not
TRIANGLES. Also prevent the crash if it has more than one surface
and none of them are TRIANGLES (and any other cases that could leave
`arrays` empty) by checking the size of `arrays` == 8 before indexing
it, since the method seems to expect `arrays` to be of that size.

(cherry picked from commit a492d22952)
2018-04-28 20:16:22 +02:00
Andrea Catania
640063334d physics area added monitorable check
(cherry picked from commit fe768f4f00)
2018-04-28 20:15:24 +02:00
Andrea Catania
ac9e87aae3 Fixed physics server area cleaning
(cherry picked from commit 776942981b)
2018-04-28 20:14:28 +02:00
Andrea Catania
5e09cf3e89 Corrected physics query max result checking
(cherry picked from commit 444b8471a3)
2018-04-28 20:13:28 +02:00
Igors Vaitkus
6989a7ac53 Fix UpdatePowerInfo method implementation in PowerIphone class
(cherry picked from commit 06fab24348)
2018-04-28 20:11:49 +02:00
Tom Dobbelaere
060f9f2cd7 Trigger IO error only after exhausting attempts
(cherry picked from commit a4fae0e5e3)
2018-04-28 20:06:30 +02:00
Benedikt Bär
4c19fc2eb1 Implement missing navgiation polygon debugging in tilemap
(cherry picked from commit 84d60b0829)
2018-04-28 20:03:46 +02:00
Fabio Alessandrelli
5e70e4469a Fix bug in HTML5 HTTPClient.
The URL parameter already has a slash, adding an extra one results in
an invalid resource path

(cherry picked from commit b8c73b195f)
2018-04-28 20:01:35 +02:00
Poommetee Ketson
287f169f2a [Docs] fix typos
(cherry picked from commit a88ee7d920)
2018-04-28 20:00:42 +02:00
Michael Alexsander Silva Dias
60bc0f79a7 Fixed some popups not shrinking their size back when losing items.
(cherry picked from commit 7cbf301f31)
2018-04-28 19:59:37 +02:00
Ruslan Mustakov
c8d0d38cab Add safety checks when handling Android input
It is possible that input comes before the engine is fully initialized.
This fixes the crashes that ocurred when that happens.

(cherry picked from commit 995724b762)
2018-04-28 19:58:00 +02:00
Leon Krause
d3ffc8ad0c Fix engine.js startGame() when loading from directory
(cherry picked from commit 3014e48ec5)
2018-04-28 19:54:29 +02:00
Leon Krause
393e1ef4ee Allow custom path when using engine.js preloadFile() with URL
(cherry picked from commit d373029382)
2018-04-28 19:54:19 +02:00
Leon Krause
78b44eab0a Fix engine.js preloadFile() with directories
(cherry picked from commit 6f1bddf4b5)
2018-04-28 19:54:12 +02:00
Leon Krause
0f6626977b Expose Emscripten libs to engine.js discreetly
(cherry picked from commit 63c7fc6358)
2018-04-28 19:54:00 +02:00
Ben Hickling
71885e5ae4 multiply blend mode fix for spatial materials
(cherry picked from commit 314a419511)
2018-04-28 17:53:53 +02:00
Alessandro
038c4d3a83 Fix all categories unfold when one key binding is changed
(cherry picked from commit eda1e266c8)
2018-04-28 17:52:20 +02:00
bruvzg
de66976ff0 Fix dragging window from non-retina to retina display.
(cherry picked from commit 14597dc2b2)
2018-04-28 17:51:11 +02:00
Benedikt Bär
b08aa6fb3c Fix compressor audio effect sidechain selection
(cherry picked from commit 7792dfe554)
2018-04-28 17:49:39 +02:00
Ivan Vodopiviz
ce944bc3fb Prevented external editor from running multiple times
Fixes #16923. I'm not a fan of the special case for scripts in editor_node.cpp, but in any case,
I made it so it wouldn't make the external editor to re-open just because we switched scenes.

(cherry picked from commit f5147befb6)
2018-04-28 17:47:23 +02:00
Poommetee Ketson
5485939233 [DOCS] minor ParticlesMaterial docs fix Linear -> Radial
(cherry picked from commit 7d18334ad2)
2018-04-28 17:46:34 +02:00
robfram
3cc2eee4e8 Fix crash in canvas_item_add_polyline when passing more points than colors
When `p_points.size() > p_colors.size()`, it crashed with invalid
array access to `p_colors`. Also, when `p_colors` was an empty
`Vector` it crashed due a missing `else` checking the `size`
condition, as the code handling that special case exists.

This PR fixes the missing `else` for `p_colors.size == 0` and,
following the `canvas_item_add_multiline` spirit, it only uses the
first color for the whole polyline if points and colors differ in
size.

Fix #17621.

(cherry picked from commit 8eedb2afe2)
2018-04-28 17:45:25 +02:00
Ruslan Mustakov
56395b03e1 Fix oversampled font artifacts after resize
Font update after resize relies on the viewport size which was updated
after the font was already refreshed, which resulted in artifacts when
it was rendered into the actual/new viewport size.

Fixes #15173.

(cherry picked from commit 47747718d6)
2018-04-28 17:42:57 +02:00
Gilles Roudiere
448d281222 Fixes wrong calculation of gridcontainer's children size
(cherry picked from commit 896e5a64d3)
2018-04-28 17:40:29 +02:00
Pedro J. Estébanez
c07d588e80 Fix listing files inside directory in pack file
When adding a directory path to the inventory of the pack, an empty file name was being added to the file list. That made `Directory.get_ntext()` signal end-of-list too early so that files in a subdirectory were missed.

Fixes #15801.
Helps with #16798.

(cherry picked from commit 536611704a)
2018-04-28 17:35:48 +02:00
Ivan Vodopiviz
52c710f25a Changed debug max distance to avoid overflow
Changed it to roughly sqrt(FLT_MAX), it's a little less to account for float inaccuracies.
Fixes #1835

(cherry picked from commit 55f79f2e80)
2018-04-28 17:32:59 +02:00
Michael Alexsander Silva Dias
29a02a78df Fixed small typo in the "InstancePlaceholder" doc.
(cherry picked from commit 712d6e724a)
2018-04-28 17:31:08 +02:00
robfram
91525e3075 Fix bug added in PR#17589. Resources couldn't be saved to files
This PR fixes the code to avoid saving default environment every time
the project is run whitin the editor.

Should fix #17727. Sorry for the troubles!

(cherry picked from commit 7821b70a00)
2018-04-28 17:22:42 +02:00
robfram
7563c17113 Fix saving unmodified scenes and resources
When `_save_all_scenes` or `save_resource_in_path` was called, they
always saved all the scenes and the resource no matter if they were
modified or not. For example, when `saving before run` option was
checked, it always overwrote the current scene and the default
environment simply by opening and runing the project.

This PR adds checks for unsaved scenes (using the same `unsave` check
others method used) and modified resources (comparing last modified
time and last import time).

Fix #6025.

(cherry picked from commit 28ab60422d)
2018-04-28 17:22:29 +02:00
JFonS
43dcf23990 Hinted shader uniforms can have a default value
(cherry picked from commit 479f531635)
2018-04-28 17:16:07 +02:00
Bernhard Liebl
1182637ec9 Fix debugger_stdout_settings being ignored
(cherry picked from commit 2b728de8f2)
2018-04-28 17:12:41 +02:00
robfram
d40f40e1c9 Fix pressing F3 do both changing to script editor AND find next text
As `KEY_F3` was used both for changing to script editor window and, in
the script editor, for finding the next result in the last search, and
the key event is **not** consumed, the resulting behaviour was similar
to press `F3` twice, first to change to script editor and second to
find the next result of a previous search.

This PR sets the `key_pressed` status of `InputEvent` to `false` if
this event is responsible of an editor change, simulating the
consumption of the event.

Fix #17334

(cherry picked from commit 8939f44f6a)
2018-04-28 17:09:55 +02:00
robfram
fa831f0224 Fix non-valid characters for input_action
Add a new function to check action names, `_validate_action_name`, in
the spirit of `_valprop`. Offending characters include non-printable
ascii, and `\/=:"`. Also set only one text for the UI message.

(cherry picked from commit da6c07698f)
2018-04-28 17:07:20 +02:00
robfram
141e389c3f Fix non working action names containing whitespaces
Now the action name is quoted if it contains spaces. Also, quotation
mark (") is added to the forbidden character list for action names, as
it was also a bug.

Fix #17322

(cherry picked from commit ea94a82596)
2018-04-28 17:04:20 +02:00
Poommetee Ketson
72350eebb2 ScriptTextEditor: fix capitalize offset
(cherry picked from commit caa0d513ab)
2018-04-28 16:45:17 +02:00
Jorn Van denbussche
80fbea28fb Fixes importing hdr files with extra header info
(cherry picked from commit 886156da2c)
2018-04-28 16:42:27 +02:00
Hein-Pieter van Braam
7ec8a6e756 Fix converting a tilset if the existing file is not a tileset
See ed3b080ca6
2018-04-28 16:40:31 +02:00
Poommetee Ketson
ddb31e9c5a EditorNode: fix clicking ok keeps trying to save
(cherry picked from commit e12e6cacdb)
2018-04-28 16:29:58 +02:00
Bernhard Liebl
dc97f91a18 Fix column width on AutoLoad table on hidpi displays
(cherry picked from commit f494d5ac5c)
2018-04-28 16:28:47 +02:00
ShyRed
171542d96a Update TileMap when its TileSet changes
Make TileMap monitor its TileSet for changes and emit a signal when the TileSet changes. This makes the editor update and show the updated version of the TileSet.

(cherry picked from commit 67f4944a21)
2018-04-28 16:25:33 +02:00
robfram
b855bc44ae Implement line clipping for TextureProgress to avoid bad rendering due to imprecise UV mapping
Original code used a quick aproximation for simulating the
correspondent texel in the `TextureProgress` texture as radial
progress indicator. This lead to visualization errors. Changed it for
a Liang-Barsky line clipping algorithm stripped to its minimum for
this specific use case.

Fix #17364.

(cherry picked from commit 7991bd168d)
2018-04-28 16:19:52 +02:00
ShyRed
c39e32ae60 Update Sprite when Texture changes
Make Sprite monitor its Texture for changes and trigger an update when the sprite changes.

(cherry picked from commit a23c0877f1)
2018-04-28 16:13:28 +02:00
Bernhard Liebl
5eef26b64e Fix broken hover/select coloring of keys in animation editor
(cherry picked from commit 172aa6c61e)
2018-04-28 16:07:03 +02:00
Pieter-Jan Briers
0d2a2a9300 Fixes canvas light shaders.
Fixes #16904

Restore more out functionality, fix built-ins.

Requested changes, I think?

(cherry picked from commit 25ba49fd88)
2018-04-28 16:03:23 +02:00
Bernhard Liebl
6d767b0f9a AnimationPlayer: fix scrubbing after play backwards
(cherry picked from commit b553b38e7b)
2018-04-28 15:55:36 +02:00
robfram
d49579b038 Fix overwriting all common properties when using Change Type tool
If you change the type of an existing node, it checks if you have
modified the initial value of their properties before overwriting
their values in the new node.

For example, if you created a `Label` and changed it to
`LineEdit`, the `mouse_filter` property was created as `Ignore`
for the original `Label` node, and was maintained after changing
it to `LineEdit` causing not to work as expected. Now it checks if
`Ignore` is the default value for `Label` nodes, and as it is, the
property value is left unchanged, maintaining the default value
for `LineEdit`, which is `Stop`.

Fix #13955 and alike.

(cherry picked from commit 8ea4ea0d53)
2018-04-28 15:47:57 +02:00
Poommetee Ketson
a3ba1b0280 Fix script template on _ready behavior
(cherry picked from commit 01ec06d9ae)
2018-04-15 01:18:49 +02:00
Marcelo Fernandez
c2e02e2066 Added error checks for fscache saving
(cherry picked from commit 06e537fec5)
2018-04-15 01:17:01 +02:00
Chaosus
3503ee4be6 Fix invalid mix function overload
(cherry picked from commit 97bef8d908)
2018-04-15 01:13:38 +02:00
Bernhard Liebl
069b429795 AnimationPlayer: fix popups close on double click
(cherry picked from commit 6d51b6ab42)
2018-04-15 01:08:45 +02:00
Saracen
2f7aa6c2aa Make the shader token names consistent.
(cherry picked from commit b095e21d91)
2018-04-15 01:07:37 +02:00
Chaosus
a29680c25a [Mono] Improve Mathf
(cherry picked from commit 655a4e6540)
2018-04-15 00:57:14 +02:00
Alexander Alekseev
3a430e46b9 [mono] Fixes #17936 as GodotSharp (Core\Basic.cs) requires C#7 now, but we most probably should keep C#6 yet
(cherry picked from commit 5677aed175)
2018-04-15 00:56:14 +02:00
Nikodem Lokatelj
b4733a1da9 Fixed _issue_activated to take the correct issue id from the list
(cherry picked from commit 4fdee1d9f1)
2018-04-15 00:55:25 +02:00
Wilson E. Alvarez
8ebd4bb874 Move GodotSharp and MonoBuildTab member variables to initializer list
(cherry picked from commit 3f86fefb64)
2018-04-15 00:54:00 +02:00
Chaosus
63a88c69ac Added wrap functions to C#
(cherry picked from commit d52722c6da)
2018-04-15 00:52:29 +02:00
Ignacio Etcheverry
bfc94dd4c9 Mono: Runtime main args and assembly search fixes
- Setup runtime main args during initialization. This must be done manually by embedders who do not call mono_runtime_run_main. Fixes NullReferenceException in System.Environment.
- Continue to search the assembly in the rest of the search locations if loading it from one of them failed.

(cherry picked from commit fa1d656af4)
2018-04-15 00:48:15 +02:00
Andreas Haas
6472d8c7d4 Mono: Avoid invalid class names.
Disallow reserved keywords as class names and prefix base class with the Godot
namespace if it's the same as the class name.

Fixes #12483

(cherry picked from commit 700d07cf7c)
2018-04-15 00:48:11 +02:00
Hein-Pieter van Braam
e4fadebc3b Fix a merge error 2018-04-15 00:43:26 +02:00
Ignacio Etcheverry
548ec63f76 EditorExport: Allow export plugins to add shared libraries
(cherry picked from commit a38b59b656)
2018-04-15 00:04:18 +02:00
Ignacio Etcheverry
9e4d34aebb Mono: Add project export plugin
(cherry picked from commit 9fd606c549)
2018-04-15 00:04:14 +02:00
Paul Joannon
d02c891a4b [mono] write classes with no constructor as abstract
(cherry picked from commit ef5672d3f9)
2018-04-14 23:54:11 +02:00
Paul Joannon
3bd414786c [mono] rename functions to conform to PascalCase
in:
* StringExtensions.cs
* Transform.cs

(cherry picked from commit d7020aef8d)
2018-04-14 23:53:56 +02:00
Carter Anderson
c7adcc8dca Fix mono basis GetEuler bug and marshalling/unmarshalling
(cherry picked from commit 91f271fa9e)
2018-04-14 23:20:33 +02:00
Aaron Franke
577f3ccaf9 Replace float with real_t, default Vectors, other misc C# improvements
Replace float with real_t in most files, defined at the top of each file via using. Objects such as Vector3 now accept doubles as inputs, and convert to real_t internally. I've added default Vectors such as Vector3.Zero. Other misc C# improvements such as Mathf.RoundToInt(). Color continues to use float only because high precision is not needed for 8-bit color math and to keep things simple. Everything seems to compile and work fine, but testing is requested, as this is the first time I've ever contributed to Godot.

(cherry picked from commit ff97c97c93)
2018-04-14 23:20:03 +02:00
robfram
bffd4f0548 Fix bad autocomplete of partially written node paths when using syntactic sugar notation ($)
If you had a tree like Node2D->Sprite->Camera2D and you write a
code like $Node2D/Spr and chose the autocompletion sugested
Node2D/Sprite, the resulting string was $Node2D/Node2D/Sprite
instead $Node2D/Sprite. If you chose Node2D/Sprite/Camera2D, then
you ended with $Node2D/Node2D/Sprite/Camera2D.

Fix #15813.

(cherry picked from commit 95f186b621)
2018-04-14 23:14:30 +02:00
Hugo Locurcio
4c8c383876 Update Hack font to v3.003
(cherry picked from commit 93f52813bf)
2018-04-14 23:11:18 +02:00
Marcelo Fernandez
125b403c0f WASAPI driver will now resample when the device rate != audio/mix_rate
(cherry picked from commit d21a2019f1)
2018-04-14 22:07:30 +02:00
Marcelo Fernandez
5f5ec7e162 WASAPI audio driver compile fix on mingw
(cherry picked from commit 3316a64e12)
2018-04-14 22:03:10 +02:00
Marcelo Fernandez
a91d9cb918 Fix possible crash when audio channels change
(cherry picked from commit 87ebdd6041)
2018-04-14 21:47:05 +02:00
Marcelo Fernandez
a7ea441504 Fix PulseAudio problems with 8 channels devices
(cherry picked from commit 34395c6a38)
2018-04-14 21:46:11 +02:00
Marcelo Fernandez
4b5472b100 Fix error detecting for PulseAudio pa_stream_new call
(cherry picked from commit 86e101ec82)
2018-04-14 21:46:06 +02:00
Rémi Verschelde
3dc4447cb8 CoreAudio: Fix iphone build after audio device refactor (#17742)
(cherry picked from commit e955fbc36e)
2018-04-14 21:44:57 +02:00
Marcelo Fernandez
9a21f964ba Added new audio device functions to set/get the audio device
(cherry picked from commit ecc1b34cbc)
2018-04-14 21:42:44 +02:00
Marcelo Fernandez
1f07f71b6c Fix PulseAudio driver for audio devices that report unknown number of channels
(cherry picked from commit 11fbfab7ec)
2018-04-14 21:38:26 +02:00
Alexander Holland
259b9664ef auto-completion edge jump
arrow up/down jumps to end/start on edges

(cherry picked from commit e36dd4282b)
2018-04-14 21:29:48 +02:00
Leon Krause
b5a55810c5 Disable FreeType SIMD in HTML5 builds
SIMD is currently unsupported in WebAssembly.

(cherry picked from commit 315983c90d)
2018-04-14 21:15:37 +02:00
robfram
4fc6256010 Change shebang of pre-commit-clang-format hook to make it portable
The default one is "#!/bin/bash", but BSD systems doesn't have bash
in that path. For portability reasons, it should be changed to
"#!/usr/bin/env bash".

More info: https://en.wikipedia.org/wiki/Shebang_%28Unix%29#Portability

(cherry picked from commit 52abf4ba84)
2018-04-14 20:59:39 +02:00
bruvzg
ce1b62a01f Explicitly set OpenGL profile to core (X11, Windows).
Enable GLES2 on Windows.

(cherry picked from commit ad67911f1a)
2018-04-14 20:56:49 +02:00
Emanuele Fornara
28d4271e3e skip demo download prompt if ssl is unavailable
(cherry picked from commit 0071c04dcb)
2018-04-14 20:44:54 +02:00
Lars Kokemohr
30b5265417 completed-signal is emitted by all GDScriptFunctionStates of a coroutine now, allowing to yield for completion of a function with more than one yield inside.
(cherry picked from commit 3dfef37628)
2018-04-14 20:42:44 +02:00
poke1024
2f53325bed Fix round preview getting square on "run scene" (issue 16734)
(cherry picked from commit 899f7b125e)
2018-04-14 20:37:54 +02:00
Andreas Loew
7ad6a9aeea Fix selection of Sprites using AtlasTexture in the editor.
Fixes #16261.

(cherry picked from commit a01ba4523b)
2018-04-14 20:30:51 +02:00
Marcelo Fernandez
8018dc6599 Fix for a possible crash when a custom theme is not loaded properly
(cherry picked from commit 2f1429eb24)
2018-04-14 20:28:13 +02:00
Ranoller
aaed3ef5ed FIX Windows enter/exit mouse notifications
Fix to this issue #17202

(cherry picked from commit 979dccbd8d)
2018-04-14 20:25:57 +02:00
Ruslan Mustakov
99cf2ffb19 iPhone X support and iOS-related fixes
Starting from April 2018 Apple no longer accepts apps that do not
support iPhone X. For games this mainly means respecting the safe area,
unobstructed by notch and virtual home button. UI controls must be
placed within the safe area so that users can interact with them.

This commit:

- Adds OS::get_window_safe_area method that returns unobscured area of
  the window, where interactive controls should be rendered.

- Reorganizes how launch screens are exported - the previous way was
  incorrect and modern iPhones did not pick up the correct screens and
  because of that used a non-native resolution to render the game.

- Adds launch screen options for iPhone X.

- Makes launch screens optional in the export template. If not
  specified, a white screen will be used.

- Adds App Store icon (1024x1024) export option as it now has to be
  bundled with the app instead of being provided in iTunes Connect.

- Fixes crash when launching games in iOS Simulator. It happened because
  controllerWasConnected callback came before the engine was
  initialized. Now in such case the controllers will be queued up and
  registered after initialization is done.

- Fixes issue with the virtual keyboard where for some reason
  autocorrection panel would intersect with the keyboard itself and not
  allow you to use the top row of the keyboard. This is fixed by
  disabling autocorrection altogether.

Closes #17358. Fixes #17428. Fixes #17331.

(cherry picked from commit 1d9a3a9b1c)
2018-04-14 20:17:47 +02:00
Poommetee Ketson
3b200c55b6 GridMap: fix next/prev plane text, fix meta not found
(cherry picked from commit 89323f94bb)
2018-04-14 20:10:02 +02:00
Geoffrey
13e9b605cf Moves the md5sum's from the <filename>.import file into .import/<filename>.md5
Saves asset md5sum's in a file that doesn't contain data that needs to be VC'd
Now saves the md5s to a different file (.import.md5)

Now reads the md5's from a separate file

Now uses a file in the .import folder to store md5s

(cherry picked from commit 030b59502f)
2018-04-14 19:57:45 +02:00
Geoffrey
5d7b7f798a Made print_tree_pretty() function which displays scene tree graphically
(cherry picked from commit 8362ce4769)
2018-04-14 19:56:55 +02:00
Ruslan Mustakov
710b57d493 Make BaseButton not emit press when container is scrolled
This fixes the problem described in #13996 in a proper way.

This also adds "deadzone" property to ScrollContainer. It can be used
on mobile, where taps are not as precise as mouse clicks. Player could
slightly move their finger when tapping, in which case we still want
the button to be pressed rather than the container to be scrolled.

(cherry picked from commit dcf5be92a3)
2018-04-14 19:36:10 +02:00
Rado'sPC\aRaGaR
ef44ed93a7 For-in loop variable added to autocompletion
Fix for #16494

(cherry picked from commit f97ebdcab3)
2018-04-14 19:19:47 +02:00
Pedro J. Estébanez
4f0b5f7307 Implement always-on-top for MacOS
Courtesy of @bruvzg.

(cherry picked from commit 2e8c7824c0)
2018-04-14 19:04:13 +02:00
Pedro J. Estébanez
1c25e50490 Add new window setting: always on top
Implemented for Windows and Linux.

(cherry picked from commit ee2c31d306)
2018-04-14 19:03:53 +02:00
Pedro J. Estébanez
a9ec1e3913 Fix buggy http-encoding
(cherry picked from commit 1fc85b87bd)

The original commit's message said "percent-encoding" because it was fixing the same code under a different method name. That rename was reverted but the fix was and is still relevant.
2018-04-12 21:22:46 +02:00
Pedro J. Estébanez
46101928bd Enhance HTTPClient.query_string_from_dict()
(cherry picked from commit 8d8e9d54c8)
2018-04-12 21:20:10 +02:00
Rémi Verschelde
74e72c995d Update AUTHORS and DONORS list
New contributor added to AUTHORS:
@robfram

Thanks to all contributors and donors! :)

[ci skip]

(cherry picked from commit e6e911eb2b)
2018-04-06 21:46:45 +02:00
Gilles Roudiere
b6f30f1b5b Fixes infinite loop in GridContainer
(cherry picked from commit 44cb8eb3a2)
2018-03-29 00:41:03 +02:00
volzhs
b09d06fcf7 Fix getting Android device information
Fix #17644

(cherry picked from commit 4e378aeeb8)
2018-03-29 00:34:31 +02:00
Wilson E. Alvarez
9567297a66 Fixed several leaks in VisualServerScene, RasterizerSceneGLES3 and RasterizerGLES3
(cherry picked from commit e9ac87390c)
2018-03-29 00:29:06 +02:00
Bojidar Marinov
607884139c Fix a potential bug hinted by clang
(cherry picked from commit 4d81e8afe6)
2018-03-29 00:27:46 +02:00
Wilson E. Alvarez
42f351db0d Fixed leak in BulletPhysicsServer
(cherry picked from commit e5ae9750ed)
2018-03-29 00:24:09 +02:00
Rémi Verschelde
9ab9dd73b0 SCons: Fix running 'scons' without platform argument
The cache and progress logic assumed the 'env' to be defined,
but it is only when the selected platform is in the supported list.

Fixes #17497.

(cherry picked from commit a44f9ca545)
2018-03-29 00:21:41 +02:00
Xavier Sellier
fa9e03996c Prevent android to split-screen
(cherry picked from commit 61e8f8a866)
2018-03-29 00:19:49 +02:00
Marcelo Fernandez
814b610ed3 Fix for clang warning at distance_to
(cherry picked from commit bbd21c2203)
2018-03-29 00:15:24 +02:00
Leon Krause
a5ccaa919e Prevent division by zero in GridContainer
(cherry picked from commit 38623e07ac)
2018-03-29 00:12:35 +02:00
robfram
5042d0c30a Fix silent failure of importing OGG Vorbis files
When importing non-valid OGG Vorbis audio files, now the filesystem
navigation tree shows the correct sad red-face icon, as it does with
non-valid PNG, JPG or WAV files.

Fix #9793.

(cherry picked from commit a8d37de461)
2018-03-29 00:11:46 +02:00
ShyRed
27f5e404a7 Update libwebm
Update of libwebm.

Up-to-date version of libwebm contains several bugfixes that allow playback of files that would crash Godot otherwise.

(cherry picked from commit e71f109910)
2018-03-29 00:06:05 +02:00
Pedro J. Estébanez
2e9c9f7d74 Fix animation length from glTF not correctly set
(cherry picked from commit 1f26da0ad1)
2018-03-29 00:04:15 +02:00
Pedro J. Estébanez
6063e74e06 Fix glTF not accepting VEC3 colors
Aside from the colors themselves, the rejection was adding somes issues later in the mesh import process.

(cherry picked from commit adbe749513)
2018-03-29 00:04:10 +02:00
bncastle
449e75455b Fix BaseButton not always calling _pressed()
Fix "ui_accept" action in BaseButton.cpp not calling _pressed() func in
GDScript

(cherry picked from commit ceb079fa35)
2018-03-28 23:55:58 +02:00
Bernhard Liebl
73cc3a96c0 Fix uninitialized data in Sprite::_get_rects()
(cherry picked from commit 5f917139ab)
2018-03-28 23:54:10 +02:00
Andrew Dunai
683511310e Fix garbage in string padding.
(cherry picked from commit 0269e366f1)
2018-03-28 23:51:31 +02:00
Felix Yang
12336dc253 Added a check for trailing dot when creating folder.
Merge the trailing dot test into existing test. Removed OS test.

(cherry picked from commit 96f61b2d65)
2018-03-28 23:50:29 +02:00
Pedro J. Estébanez
8da76f3bb8 Fix wrong SSL handshake
The name of the remote host is passed to mbed TLS in all cases so the client hello message is correctly formed.

(cherry picked from commit 602da6fa4f)
2018-03-28 23:49:00 +02:00
Marcelo Fernandez
8289f8628d Modify OSX can_export logic to match the logic from EditorExportPlatformPC::can_export
(cherry picked from commit a42dfd7882)
2018-03-28 23:47:22 +02:00
Gary Oberbrunner
91bc845152 Fix infinite loop in GridContainer layout
I had a grid container and tried to set rect.min_height larger in the
editor; that caused an infinite loop in GridContainer::_notification
at line 118. The reason is max_index was being set to the *height* of
the row, not the *index* of the row. So later when it tried to erase
that row and try again, there was nothing to erase.
I applied the same fix to the width code.

(cherry picked from commit 561e57df13)
2018-03-28 23:45:39 +02:00
bruvzg
d8a0b6ba63 Hack to force macOS window activation for non-bundled app.
(cherry picked from commit 506e17ee70)
2018-03-28 23:39:16 +02:00
Poommetee Ketson
bf4d8ee69c EditorAudioBus: expand effects list
(cherry picked from commit 555a8c0b8d)
2018-03-28 23:36:58 +02:00
Blazej Floch
2c93def09d Add "Show Origin" and "Show Viewport" options to 2D Editor Viewport
(cherry picked from commit 934498d37a)
2018-03-28 23:33:03 +02:00
Andreas Haas
9cbcff4e91 ScriptEditor: Use EditorSettings instead of hardcoded values in constructor.
(cherry picked from commit 1cfc43421e)
2018-03-28 23:13:46 +02:00
Marcelo Fernandez
985b84689f Support for uneven amount of channels on PulseAudio
(cherry picked from commit 00693f4ad0)
2018-03-28 23:05:23 +02:00
Nicolas Silva
89e4125241 Use GL_LINE_STRIP instead of GL_LINES when drawing polylines.
(cherry picked from commit 20cab06f9a)
2018-03-28 23:01:09 +02:00
Hugo Locurcio
209acbaac7 Add documentation for the DynamicFont hinting property
(cherry picked from commit a0ddd6122c)
2018-03-28 22:56:29 +02:00
Hugo Locurcio
8a0966a8cb Add an hinting mode setting to DynamicFonts
- Editor font hinting can now be tweaked in the Editor Settings.
- DynamicFonts used in projects now have tweakable hinting settings
  in their DynamicFontData child. Changes will be visible upon
  reloading the scene in the editor.

(cherry picked from commit c1544c12ef)
2018-03-28 22:56:04 +02:00
MrCdK
99331ca395 Added pitch scale property to AudioStreamPlayer, AudioStreamPlayer2D and AudioStreamPlayer3D
(cherry picked from commit 5bc010e8ee)
2018-03-28 22:43:44 +02:00
Unknown
ec362d54a9 Fix Automatic switch to viewport when playing a scene #16357
(cherry picked from commit d002b7d24a)
2018-03-28 22:41:06 +02:00
MrCdK
5e8e2a8730 AudioServer emit bus_layout_changed signal when adding, moving or deleting a bus
(cherry picked from commit 56dcf4b983)
2018-03-28 22:34:43 +02:00
bruvzg
df7d60a9d3 Abort compilation on missing return values (CGG/clang)
(cherry picked from commit 5ec09455ed)
2018-03-28 22:21:33 +02:00
J Andrew Long
fe20a1e35b add restore purchases for iOS
(cherry picked from commit da652c1539)
2018-03-28 22:16:07 +02:00
Poommetee Ketson
55a66efa38 Fix get_drive (bookmarks) in linux not working
(cherry picked from commit 7e5b10b7d3)
2018-03-28 22:13:39 +02:00
geequlim
5eebe51014 Fix builtin script cannot open from debug stacks
(cherry picked from commit 095e2bcc26)
2018-03-28 22:12:31 +02:00
geequlim
9febb6f747 Don't print error message when select debugger stacks if the debugger is stopped.
Clear debugger stack inspector if the debugger is stopped when selected stack changed.

(cherry picked from commit cfde737478)
2018-03-28 22:09:16 +02:00
volzhs
626525d23a Draw relationship line on scene tree dock if option is on
(cherry picked from commit 36aa62802a)
2018-03-28 22:06:01 +02:00
JFonS
a026e2626c Fix weird editor crash when switching from editing one gradient to another keeps 'grabbing' variable to true
(cherry picked from commit f68594a525)
2018-03-28 22:01:19 +02:00
Marc Gilleron
cf2e30b30c Fix Line2D tile mode for non-square textures
(cherry picked from commit d2fae5c9a6)
2018-03-28 21:33:49 +02:00
poke1024
f7efa9d43a Fix line thickness for CollisionPolygon2D.
(cherry picked from commit a36f6e5386)
2018-03-28 21:23:42 +02:00
poke1024
dfb739aff0 Fix grid mesh tile panning bug (issue 16524)
Fix basic function and interference of touch pad pan with mesh tile delete (shift + right click on touch pad) in grid map editor (fix 16524)

(cherry picked from commit b90810ce8e)
2018-03-28 21:11:38 +02:00
Fabio Alessandrelli
89bff17cd2 More threading in AssetLib
AssetLib now uses thread as requested to download previews and items

(cherry picked from commit 3a25415a1c)
2018-03-28 21:03:56 +02:00
Poommetee Ketson
3e1716b2c3 GridMapEditorPlgn: fix a leak
(cherry picked from commit 5cf331588a)
2018-03-28 21:02:51 +02:00
Hein-Pieter van Braam
e6200de73a Bump version to 3.0.3-devel
And onwards!
2018-03-18 02:38:31 +01:00
Rémi Verschelde
593e616a48 Dist: Fix Linux desktop file launch argument
(cherry picked from commit a55e2f2dac)
2018-03-14 12:06:18 +01:00
Rémi Verschelde
eeb7385f02 SCons: Fix linking system pcre2 on server platform
Fixes #17245.

(cherry picked from commit e619727e99)
2018-03-04 13:47:35 +01:00
Hein-Pieter van Braam
2ff3b08583 Bump to 3.0.2-stable
Thanks to all of our contributors!
2018-03-03 15:22:04 +01:00
Hein-Pieter van Braam
6ab8fb04af Fix documentation indentation for apply_torqe_impulse 2018-03-03 15:19:40 +01:00
Hein-Pieter van Braam
498d177cfe Update changelog for 3.0.2 2018-03-03 15:12:41 +01:00
Chaosus
06a60bb6ef Fix floatBitsToUint function
(cherry picked from commit c6b6af7bb5)
2018-03-03 14:54:52 +01:00
Rémi Verschelde
c0132f30c4 Viewport: Fix missing tooltips w/ disabled physics object picking
Previously this option seemed to be the sole responsible for enabling
physics processing in Viewport, while several other features like
tooltips and debugging collision hints rely on it.

All this logic is moved to internal processing (it's incorrect to let
it be affected by users disabling physics/idle processing), and disabling
physics object picking no longer affects the internal physics processing.

Fixes #17001.

(cherry picked from commit ce7da2c7d6)
2018-03-03 14:19:57 +01:00
Max Hilbrunner
649cb70ddb [DOCS] Small fix to Area: Fix copy/paste errors
(cherry picked from commit fdd0f18959)
2018-03-03 11:00:41 +01:00
Rémi Verschelde
65d214d3da i18n: Sync translation templates with current source 2018-03-03 10:58:19 +01:00
Rémi Verschelde
9ee98e999b i18n: Sync translations with Weblate
(cherry picked from commit 7c7d3efb5b)
2018-03-03 10:56:41 +01:00
Max Hilbrunner
5bcc7f88b6 [DOCS] Small fix to PinJoint2D
(cherry picked from commit 0b65bac1a1)
2018-03-03 01:55:33 +01:00
Max Hilbrunner
93e99846b0 [DOCS] NetworkedMultiplayerENet
(cherry picked from commit 5aae17a6fb)
2018-03-03 01:55:27 +01:00
Rhody Lugo
5c2e554853 prune cache only at the start and end of build
(cherry picked from commit 29e6ec6594)
2018-03-03 01:53:22 +01:00
Poommetee Ketson
c4468aef5d s/Camear/Camera in docs
(cherry picked from commit b099a500eb)
2018-03-03 01:52:12 +01:00
Bernhard Liebl
f967334f53 Fix more regressions in RichTextLabel from PR 15711
(cherry picked from commit 0e1e95c41f)
2018-03-03 01:47:52 +01:00
Rémi Verschelde
4132f2ea7e Update AUTHORS and DONORS list
New contributors added as AUTHORS:
@mrcdk, @binbitten, @paulloz, @PJB3005

New Gold sponsor: Skirmish <https://skirmish.io>

Thanks and welcome! :)

[ci skip]

(cherry picked from commit 741af0652d)
2018-03-02 19:48:12 +01:00
Rémi Verschelde
262c97098d Fix serialization of identifiers with non printable ASCII characters
Fixes #6888.

(cherry picked from commit ab001d830b)
2018-03-02 14:54:45 +01:00
Hein-Pieter van Braam
cee20e24bd Don't crash when trying to add an invalid navmesh
It is possible to try to add an invalid object as a navmesh through
GDScript which results in an engine crash. This creates a debug message
that should help the user figure out what's wrong.

(cherry picked from commit 555eebf3f4)
2018-03-02 12:06:46 +01:00
Rémi Verschelde
87476c057a NativeScript: Fix initialization in wrong scope
Regression from d702d7b335 which broke javascript build.

(cherry picked from commit 08cadc3d87)
2018-03-02 02:08:50 +01:00
Hein-Pieter van Braam
53693e393d Revert "Make KEY_ESCAPE close all output/debugger docks on bottom"
This reverts commit c04d868476.

This caused a regression when trying to close the typing suggestion.
Reverting this for now until a better implementation for this behavior
gets made.
2018-03-01 23:06:26 +01:00
Anish
3f7e036c4f Godot now allows built-in irrespective of the filepath.
Since the file in the filepath is irrelevant when setting the file
as built-in, changes have been made to allow setting to built-in
even if the file in the path exists.

Fixes #16425

(cherry picked from commit 1fdb8251d2)
2018-03-01 21:38:15 +01:00
Poommetee Ketson
0aab429453 AnimationEditor: fix time indicator offset
(cherry picked from commit acf54f8bdc)
2018-03-01 21:18:58 +01:00
Marcelo Fernandez
61fd30c00e Fixed Windows ignoring minimized/maximized status set by user
(cherry picked from commit f8da9550f4)
2018-03-01 21:15:35 +01:00
Fabio Alessandrelli
44b206a3fa Fix server build on FreeBSD
(cherry picked from commit 8f9914bd94)
2018-03-01 21:12:28 +01:00
Hein-Pieter van Braam
675899a521 Fix various valgrind reported uninitialized variable uses
(cherry picked from commit d702d7b335)
2018-03-01 21:06:31 +01:00
Ruslan Mustakov
61a9ef5d81 Fix intermittent audio driver crash during startup on Android
set_pause can be called before the driver is initialized, and there
already is a check for that. The problem is that the 'active' field
was not initialied in the constructor, which lead to it having an
undefined value.

(cherry picked from commit c10749d51f)
2018-03-01 21:05:15 +01:00
Nicolas Silva
9c27e4d885 Allow degenerate triangles in polygon triangulation when necessary.
(cherry picked from commit e73266a51c)
2018-03-01 20:18:08 +01:00
poke1024
c800653c6f Fix regression through fa98637aca
(cherry picked from commit 89f607604e)
2018-03-01 19:19:29 +01:00
Hein-Pieter van Braam
3e931e258c More reliably find mscorlib.dll on Linux
(cherry picked from commit c094e90b25)
2018-02-27 22:12:01 +01:00
Hein-Pieter van Braam
7e5a374825 Deprecate a typo for a new method introduced in 3.0.1 2018-02-27 17:53:46 +01:00
Hein-Pieter van Braam
a850ebf352 Revert "fix spurious error messages during autocomplete and validate"
This reverts commit b7faa76485.

This causes a regression in 3.0.1. We haven't found a proper fix yet so
we're removing this from 3.0.2
2018-02-27 17:52:18 +01:00
Hein-Pieter van Braam
4e1d19b20c Revert "[Mono] Basis values now marshalled in the correct order."
This reverts commit 9173819b71.

The fixes for these issues aren't quite baked yet. Taking them out of
3.0.2
2018-02-27 17:52:18 +01:00
Hein-Pieter van Braam
d7430ef077 Revert "The marshalling in was also incorrect."
This reverts commit b6f958965b.

The fixes for these issues aren't quite baked yet. Taking them out of
3.0.2
2018-02-27 17:52:18 +01:00
Poommetee Ketson
17408bea9c (Magnify|Pan)Gesture: implement as_text
(cherry picked from commit 67e20dc2b6)
2018-02-27 17:52:18 +01:00
Rémi Verschelde
2c55064708 doc: Sync with current source 2018-02-27 13:57:29 +01:00
Rémi Verschelde
42e82b9377 doc: Update version string for 3.0.2 2018-02-27 13:57:10 +01:00
Rémi Verschelde
a4b077a0ba Android: Mark GLES3 as required in the manifest
Fixes #17076.

(cherry picked from commit 7d09e6540a)
2018-02-27 13:33:59 +01:00
Ignacio Etcheverry
f6c65d9d15 Mono: Buildsystem improvements
- Bundle with mscorlib.dll to avoid compatibilities issues
- Add build option 'mono_assemblies_output_dir' to specify the output directory where the assemblies will be copied to. '#bin' by default.

(cherry picked from commit a45697d8df)
2018-02-27 11:35:19 +01:00
Michele Valente
990bddcf36 fix release builds with mono
"_signals" and "signals_invalidated" were moved out of the
"TOOLS_ENABLED" directive. Updated also the two "update_signals" and
"_update_signals" methods so it makes sense.

(cherry picked from commit 3c7d9001bc)
2018-02-27 11:34:52 +01:00
Poommetee Ketson
c730a6ce44 Fix error spam when using PanoramaSky without texture
(cherry picked from commit 7a1b7ddf6c)
2018-02-27 11:34:03 +01:00
indicainkwell
115c0a7415 added docs on Control's drag and drop api
(cherry picked from commit 7154a96d3f)
2018-02-27 11:32:35 +01:00
Paul Joannon
87242c7b92 fix build error when compiling with mono, tools=no, target=release
change TTR to RTR in `print_unhandled_exception`

(cherry picked from commit 90a705d671)
2018-02-27 11:25:10 +01:00
Andrea Catania
4eb9ee9355 Fixed physics server typo
(cherry picked from commit 134cca0cf2)
2018-02-27 11:22:56 +01:00
bruvzg
48ed52184d Add missing return statements (iOS and server).
(cherry picked from commit e3c2778d7e)
2018-02-27 00:06:01 +01:00
JFonS
69274ef368 Fix visibility of gizmos on scene load
(cherry picked from commit 99d740c46e)
2018-02-27 00:02:01 +01:00
Paul Joannon
039fc750d5 only show information we have in stacktrace
do not show line number and/or file if not defined

(cherry picked from commit 3ee4ce51a9)
2018-02-26 23:55:27 +01:00
Paul Joannon
58a7d78c22 [mono] get stacktraces for all inner exceptions
(cherry picked from commit 89af6c2cd7)
2018-02-26 23:55:13 +01:00
Ignacio Etcheverry
c0386f0124 Mono: Fix bindings for parameters in vararg methods
(cherry picked from commit 0c82858121)
2018-02-26 23:54:32 +01:00
Nathan Warden
b6f958965b The marshalling in was also incorrect.
(cherry picked from commit 60daa9d718)
2018-02-26 22:45:53 +01:00
Ignacio Etcheverry
dde14e15c6 Mono: Better versioning and gracefully unloading of Godot API assemblies
(cherry picked from commit f37090ccf4)
2018-02-26 22:36:03 +01:00
Hein-Pieter van Braam
1ea805a4aa Add missing #endif for the main.cpp fix.
I forgot to amend my previous commit.
2018-02-26 21:02:03 +01:00
Hein-Pieter van Braam
3b96b3fd12 Allow running with a custom resource without a main scene
After 3f8a4cc719 trying to run an
individual scene on a project without a main scene fails. We move the
check until after we've determined whether or not we're trying to run an
individual scene.

We also stop trying to show the project manager if any game pack is
found at all, unless the user explicitly asks for the project manager to
be shown.

(cherry picked from commit b4215c991a)
2018-02-26 20:39:48 +01:00
Hein-Pieter van Braam
e499b9b4b6 Bump to version 3.0.2-devel 2018-02-26 20:36:43 +01:00
Hein-Pieter van Braam
8ea709a7a9 Update the changelog for 3.0.1 2018-02-26 20:35:13 +01:00
Hugo Locurcio
f2e19a26f5 Add a project changelog
(cherry picked from commit f00b2dfc55)
2018-02-25 15:32:08 +01:00
Rémi Verschelde
be771e7165 Fix version.txt validation logic for export templates .tpz
It assumed that the version would always be `x.y-status`,
with no dot possible in `status`, so:
- It would not work for 3.0.1-stable (nor 3.0.1.stable with new version logic)
- It would not support Mono templates when we provide them

The validation it did was not really useful anyway, so we just use the raw
string.

(cherry picked from commit eec9261a75)
2018-02-25 15:29:28 +01:00
Rémi Verschelde
cb65617897 Revert "Bump to version 3.0.2-devel"
This reverts commit bcbe7a8a6f.

Need to push a fix and retag 3.0.1-stable, sorry.
2018-02-25 14:09:38 +01:00
Hein-Pieter van Braam
bcbe7a8a6f Bump to version 3.0.2-devel
The start of the next patch release. Wooooooooooo
2018-02-24 20:08:32 +01:00
Hein-Pieter van Braam
ae540c2efe Bump version to 3.0.1-stable
Thanks everyone for all your amazing work getting our first stable patch
release out for the 3.0 series. I'd particularly like to thank @fales
and @fire for their work on the server platform.

Onwards to 3.0.2!
2018-02-24 19:21:52 +01:00
Hein-Pieter van Braam
5f15642fde Update doc version strings to 3.0.1 2018-02-24 18:59:38 +01:00
Hein-Pieter van Braam
17d7084780 Correct version number for 3.0.1 in the manpage 2018-02-24 18:37:01 +01:00
Poommetee Ketson
fe38b648b0 [DOCS] clarify that OS.get_user_data_dir needs project name
[ci skip]

(cherry picked from commit 2c22c9dcfb)
2018-02-24 18:33:43 +01:00
Rémi Verschelde
ad325be5a0 Add --quit option to help output and update manpage
(cherry picked from commit 95b8984d5f)
2018-02-24 18:32:22 +01:00
Hein-Pieter van Braam
d69d58deea Fix Windows file case changing
Windows APIs don't really provide a way to change a filename case. This
implements a little juggling to make this work. We first create a
guaranteed unique temporary file, we then replace the original file with
the temporary file and we finally rename it to the desired filename
case.
2018-02-24 17:37:07 +01:00
Gilles Roudiere
34591f9451 Fixes collisions shape selection
(cherry picked from commit c250a9a9f9)
2018-02-24 10:53:10 +01:00
Rémi Verschelde
d79a7a2773 Refactor version macros and fix related bugs
The previous logic with VERSION_MKSTRING was a bit unwieldy, so there were
several places hardcoding their own variant of the version string, potentially
with bugs (e.g. forgetting the patch number when defined).

The new logic defines:

- VERSION_BRANCH, the main 'major.minor' version (e.g. 3.1)
- VERSION_NUMBER, which can be 'major.minor' or 'major.minor.patch',
  depending on whether the latter is defined (e.g. 3.1.4)
- VERSION_FULL_CONFIG, which contains the version status (e.g. stable)
  and the module-specific suffix (e.g. mono)
- VERSION_FULL_BUILD, same as above but with build/reference name
  (e.g. official, custom_build, mageia, etc.)
  Note: Slight change here, as the previous format had the build name
  *before* the module-specific suffix; now it's after
- VERSION_FULL_NAME, same as before, so VERSION_FULL_BUILD prefixed
  with "Godot v" for readability

Bugs fixed thanks to that:

- Export templates version matching now properly takes VERSION_PATCH
  into account by relying on VERSION_FULL_CONFIG.
- ClassDB hash no longer takes the build name into account, but limits
  itself to VERSION_FULL_CONFIG (build name is cosmetic, not relevant
  for the API hash).
- Docs XML no longer hardcode the VERSION_STATUS, this was annoying.
- Small cleanup in Windows .rc file thanks to new macros.

(cherry picked from commit 23ebae01dc)
2018-02-24 01:34:34 +01:00
Rémi Verschelde
05fec82f31 Merge pull request #16934 from anakimluke/fix_space_around_args
Removed whitespaces around arguments of functions.
2018-02-24 01:32:59 +01:00
anakimluke
370f84f41c Removed whitespaces around arguments of functions.
Functions automatically generated by conneting
signals via GUI put whitespaces around the
arguments of the generated function. This is
inconsistent with the style guide.

This commit fixes that.
2018-02-22 19:41:37 -03:00
Rémi Verschelde
689dfcd9ec server: Add support for statically linking libgcc and libstdc++
(cherry picked from commit be7bfdfac3)
2018-02-22 19:06:36 +01:00
Rémi Verschelde
46b594054c doc: Sync classref with current source 2018-02-22 19:02:37 +01:00
Rémi Verschelde
07e2461995 i18n: Sync translation templates with current source 2018-02-22 18:47:07 +01:00
Rémi Verschelde
ca5f3b9f8d i18n: Sync translations with Weblate
(cherry picked from commit 661ab3c88e)
2018-02-22 18:42:25 +01:00
Rado'sPC\aRaGaR
3d804778fd Fix quotation in string
fix for #16404

(cherry picked from commit f38e819fc1)
2018-02-22 13:23:44 +01:00
Yan Pas
3e8c214a19 Delete all selected lines using the delete line shortcut in script editor
(cherry picked from commit 7368978a48)
2018-02-22 13:09:02 +01:00
Pieter-Jan Briers
e9d8dfbf0e Ignore tools CLI flags in non-tools builds.
Some flags were still parsed but either did nothing or broke everything.

No reason to parse them.

(cherry picked from commit dd19826277)
2018-02-22 13:08:03 +01:00
Pieter-Jan Briers
3687faa78f Enforce insert_final_newline in the editorconfig.
(cherry picked from commit 6861886f70)
2018-02-22 13:06:25 +01:00
Artem Varaksa
eacd66e784 Clean up some bad words from code comments
(cherry picked from commit d35e486228)
2018-02-22 12:22:41 +01:00
Poommetee Ketson
b5f8c1a53b Fix timer second not zero padded when < 10
Also RTR "Time Left:"

(cherry picked from commit d2e3607fa0)
2018-02-22 12:20:23 +01:00
Rémi Verschelde
f04cd405ac Fix loading project.binary from PCK file
Regression introduced in #16825.
My logic was correct, but not the error code I was expecting.
The error reporting in FileAccess likely needs a review too.

(cherry picked from commit 57d562b394)
2018-02-22 12:19:43 +01:00
Rémi Verschelde
f55b376d78 Improve error reporting of ProjectSettings::setup()
And use it to better report errors in the console and project manager
when a project.godot file is corrupted.

Fixes #14963.

(cherry picked from commit 7839076f95)
2018-02-22 12:19:28 +01:00
Michael Alexsander Silva Dias
fdac09a0aa Made the Debugger's Stack Frames items reselectable.
(cherry picked from commit 32e3f257ac)
2018-02-22 12:18:45 +01:00
luz.paz
751806b5c7 Fix typos with codespell
Found via `codespell -q 3 --skip="./thirdparty,./editor/translations" -I ../godot-word-whitelist.txt`
Whitelist consists of:
```
ang
doubleclick
lod
nd
que
te
unselect
```

(cherry picked from commit 612ab4bbc6)
2018-02-22 12:17:06 +01:00
Poommetee Ketson
40018e995c Color:fix setting V switch S to old V value
(cherry picked from commit f4f92b55e1)
2018-02-22 12:07:07 +01:00
BastiaanOlij
be6323d848 Added documentation for VehicleBody
(cherry picked from commit 234b86e6b2)
2018-02-22 12:03:10 +01:00
Artem Varaksa
29089b715d Insert proper copy icon to debugger
(cherry picked from commit db2a1544c0)
2018-02-22 12:02:41 +01:00
Daniel J. Ramirez
7e89cc46dd Icons update
includes new enum, MeshInstance2D, Skeleton2D, Cut, Copy and Paste icons.

(cherry picked from commit cecf274364)
2018-02-22 12:02:02 +01:00
Chaosus
a86829211a Added missing shader functions
(cherry picked from commit 8f04a13c98)
2018-02-22 00:02:52 +01:00
isaacremnant
f01821b60a Force controls to save rect_clip_content since they do not all default to false.
(cherry picked from commit cc902cf9ab)
2018-02-22 00:01:33 +01:00
hungrymonkey
245c11be08 Change function signature from float to double to match type get_doubleCloses #16160
(cherry picked from commit d2f1c87063)
2018-02-21 23:59:15 +01:00
Bernhard Liebl
fa98637aca Fixes wrong vertical font layout in RichTextLabel
(cherry picked from commit 77b1320fb4)
2018-02-21 23:52:49 +01:00
Ian
723613dbc3 TextEdit folding over unindented comments
(cherry picked from commit d327f75392)
2018-02-21 23:51:45 +01:00
Hein-Pieter van Braam
99efa7ce62 Revert "Fix wrong return type of xform functions"
As this will change bindings API this will have to wait for 3.1

This reverts commit 187c40d64d.
2018-02-21 23:47:04 +01:00
AndreaCatania
c7040f3218 Fixed sky reflection rendering when transparent BG
(cherry picked from commit c34f18acce)
2018-02-21 23:40:59 +01:00
Neil Moore
5975b44ded Fixes gravity calculation for kinematic bodies in Bullet
(cherry picked from commit 5fb8a6a6c2)
2018-02-21 23:38:30 +01:00
Hein-Pieter van Braam
8efb9c8cdd Actually fix the db/dc renaming mess
Local builds save lives :)
2018-02-21 23:21:21 +01:00
Hein-Pieter van Braam
75289b4017 revert the renaming _tree_db_selected function 2018-02-21 22:57:50 +01:00
Rémi Verschelde
ccf27376a6 Update warning about C# support
(cherry picked from commit 24cf4fe062)
2018-02-21 22:55:46 +01:00
Michael Alexsander Silva Dias
23b9f09c58 Fixed "Open" button being enabled when nothing is selected in a FileDialog while in "Open folder" mode.
(cherry picked from commit db80d56388)
2018-02-21 22:23:24 +01:00
Florian Zwoch
e1fc7776f6 gltf: improve embedded data discovery
Some editors seems to use the image resource's mime type (e.g. "image/png") for data embedded uris instead of "application/octet-stream".

(cherry picked from commit 1abf464b59)
2018-02-21 22:17:09 +01:00
Chaosus
c6a96fc360 Enable snapping when control key pressed
(cherry picked from commit 24c170555d)
2018-02-21 22:16:20 +01:00
Max
4383fae5a4 Fixed disappearing text on filedialog buttons
(cherry picked from commit 6a48f952ca)
2018-02-21 22:15:05 +01:00
Nathan Warden
9cfcf102a0 [Mono] Fixed "expression did not evaluate to a constant" compiler error for visual studio.
(cherry picked from commit 72fe70272d)
2018-02-21 22:12:57 +01:00
Bojidar Marinov
8dc946c89c Fix a rendering bug with screen_texture
(cherry picked from commit ea57a19b34)
2018-02-21 22:11:47 +01:00
karroffel
327fea741a using TIME in light shader enables uses_fragment_time
The GLES3 shader compiler performs certain checks to enable or disable
the usage of certain uniform variables (and with that the set-up of UBOs).

If the `TIME` variable gets used inside the `vertex` function then the
renderer knows that it has to insert that value into the UBO.
The same applies to the `fragment` function.

The `light` function gets executed inside the fragment shader for every
light source that is relevant to the current pixel. If the `TIME` variable
gets used in that function then it needs to be present in the fragment-UBO.
The check for this was missing, so if a shader uses `TIME` inside `light`
but not inside `fragment` then the uniform will not actually be set up.

(cherry picked from commit bb655856e2)
2018-02-21 22:10:28 +01:00
volzhs
317cb336eb Keep to show current script when closing all docs
also fix error when removing multiple tabs from TabContainer at same frame.
like closing multiple docs at once.

Fix #16403

(cherry picked from commit df84290a7e)
2018-02-21 22:09:23 +01:00
Nathan Warden
83b76a8171 Added an auto quit and auto build flag to the command line options.
(cherry picked from commit 4bfb504c2f)
2018-02-21 21:56:37 +01:00
K. S. Ernest (iFire) Lee
70b082c0d9 Create and return LightmapCapture.
(cherry picked from commit 2e66730061)
2018-02-21 21:49:16 +01:00
K. S. Ernest (iFire) Lee
bbfec2a7cc Add dummy audio driver, fix dummy rasterizer
(cherry picked from commit 4e1923a931)
2018-02-21 21:49:10 +01:00
Fabio Alessandrelli
8849377f6d Fixes to OS_Server and DummyRasterizer to match new signatures
(cherry picked from commit 2de10aa467)
2018-02-21 21:48:58 +01:00
Fabio Alessandrelli
149ffcb1a4 server platform now compiles and run on linux.
Seems to also be able to do exports of some demos I tried.

(cherry picked from commit 6784d743f7)
2018-02-21 21:48:46 +01:00
Fabio Alessandrelli
fb4a784319 Add dummy Texture handling
(cherry picked from commit 72ef766dfa)
2018-02-21 21:48:33 +01:00
Fabio Alessandrelli
8f231d82bb Disable GLES builders and source from server compilation
(cherry picked from commit 8699f643c9)
2018-02-21 21:48:21 +01:00
Fabio Alessandrelli
cc280545dc Add dummy resterizer driver
(cherry picked from commit c0dce6e480)
2018-02-21 21:47:38 +01:00
George Marques
fa02b58b46 Remove unused variable from plugin settings update
Fix #16199

(cherry picked from commit 9f0cce840d)
2018-02-19 23:15:56 +01:00
Stephen Traskal
000caef623 Fixing folder/file case sensitive renaming issue
Example:
Could not rename "Objects" to "objects" or vice versa

(cherry picked from commit e790ca084d)
2018-02-19 22:47:39 +01:00
x1212
b7faa76485 fix spurious error messages during autocomplete and validate
_parse() caused resets on members like validating and
for_completion by calling clear().

(cherry picked from commit 48c9ed4545)
2018-02-19 22:46:49 +01:00
Konrad Nowakowski
a76dfe9c72 Fix 2d collision body update on shape remove
(cherry picked from commit 3659df6624)
2018-02-19 22:43:33 +01:00
Leon Krause
a423adbee6 Flush HTTPClient response data only on request/close in HTML5 platform
(cherry picked from commit 98039909f2)
2018-02-19 22:42:38 +01:00
Leon Krause
c5b5fd61d4 Warn when polling HTTPClient synchronously in HTML5 platform
(cherry picked from commit ca9fa9cca8)
2018-02-19 22:42:31 +01:00
Leon Krause
5bb269d01d Disable insecure HTTP methods CONNECT and TRACE in HTML5 platform
(cherry picked from commit 2cd7bc04ea)
2018-02-19 22:42:22 +01:00
Leon Krause
d5535d9357 Fix HTML5 HTTPClient response header retrieval
(cherry picked from commit 8a21f27f54)
2018-02-19 22:42:08 +01:00
Leon Krause
2714b851bf Fix HTML5 HTTPClient failure detection
(cherry picked from commit 9ea4452d21)
2018-02-19 22:42:01 +01:00
Ignacio Etcheverry
2abbdcaa20 Mono: Fix build status icons
(cherry picked from commit 8bd05f0c71)
2018-02-19 22:40:21 +01:00
Paul Joannon
9cba5ef772 implement signal related methods in csharp_script so signals can be used with emit
(cherry picked from commit cfbd7fd21e)
2018-02-19 22:39:51 +01:00
Paul Joannon
416cd9c8b8 add a [Signal] attribute to CSharpScripts
(cherry picked from commit efd52cd172)
2018-02-19 22:39:44 +01:00
Benjamin Stammen
7a20495a80 Direct to InputEventJoypadButton for using buttons
(cherry picked from commit 6af7dafd6c)
2018-02-19 22:37:09 +01:00
Pedro J. Estébanez
bafbd73b51 Remove window decorations for fullscreen on X11
(cherry picked from commit 935a99e758)
2018-02-19 22:36:20 +01:00
Anish
ac6811c4fa Gridmap editor now lists plane instead of floor when not horizontal.
Instead of gridmap editor calling grid as floor irrespective of the
orientation, it now calls the grid plane if it's vertical and floor
if horizontal.

Resolves: #14611
(cherry picked from commit 7c356a9c05)
2018-02-19 22:34:16 +01:00
Rémi Verschelde
8372a404bb X11: Link libgcc statically with use_static_cpp option
We were already linking libstdc++ statically for official binaries,
protecting us against most portability issues. But apparently since
we started using GCC 7 for official builds, we also need to link
libgcc statically for at least 32-bit builds to be portable.

Fixes #16409.

(cherry picked from commit b526088ae2)
2018-02-19 22:33:29 +01:00
Rémi Verschelde
5b04dcfabd Update CA certificates to latest Mozilla bundle
Copied from an up-to-date Fedora 27 install (ca-certificates-2018.2.22-1.0.fc27).

(cherry picked from commit 294af5617a)
2018-02-19 22:32:53 +01:00
Pieter-Jan Briers
4b581104e7 Makes project manager never initialize mono debug.
The heuristic whether we're in the project manager inside GDMono
didn't work if the project manager was launched by not having any path
to run.

This is fixed now by making a Main::is_project_manager().

(cherry picked from commit 1099838079)
2018-02-19 22:32:17 +01:00
Pieter-Jan Briers
f49601a934 Give C# NodePath a ToString().
It already had an implicit cast operator to string,
but this doesn't get used in say string formatting.

So now something like $"path: {GetPath()}" works.

(cherry picked from commit 3c1f8efd9e)
2018-02-19 22:31:33 +01:00
Pieter-Jan Briers
3e6ab9f3d5 Makes NodePath and RID follow PascalCase in C#.
Fixes #15685

(cherry picked from commit b1a81374d4)
2018-02-19 22:30:45 +01:00
damarindra
9f9731da3a fix crash autotile edit mode
(cherry picked from commit cceb176be3)
2018-02-19 22:30:13 +01:00
Alexander Alekseev
18735ff6f2 Fixes OptionButton selection index being reset to zero at instanciation
Bug: engine tries to set selected item before items were added during save scene/run project, because of wrong properties order.
Fixes #10213.

(cherry picked from commit 66c39b1426)
2018-02-19 22:29:36 +01:00
Michael Alexsander Silva Dias
237cf72f89 Made modifications to the RigidBody(2D) descriptions.
(cherry picked from commit 50e6b3c005)
2018-02-19 22:28:47 +01:00
Anish
5c2b2ca95b Documentation tool does not add escapes to code and codeblocks
Instead of adding the escapes to all * and _ the tool now excludes
the characters inside [code] and [codeblock].

Resolves: #15156
(cherry picked from commit 84e8c49f5d)
2018-02-19 22:28:03 +01:00
Rémi Verschelde
57f707f951 Add locale renames for Hebrew and Indonesian on Windows
Windows does not fully respect ISO 639-1 like other systems,
so we have to override its locale values for those languages.

Also added comments to document the locale provenance.

(cherry picked from commit 0c7bed45c4)
2018-02-19 22:27:19 +01:00
ianb96
2f87e7ffe9 option to disable sort in script list
(cherry picked from commit e1778fb921)
2018-02-19 22:26:29 +01:00
BTaskaya
12da8dcdeb PEP3101 applied with changing old type string formatting as new ones
(cherry picked from commit 78dba05fc0)
2018-02-19 22:25:41 +01:00
Marcelo Fernandez
c5388fb0cf Fix for a possible compile error under OS X
(cherry picked from commit 621d28adef)
2018-02-19 22:24:57 +01:00
Michael Alexsander Silva Dias
02e910275c Fixed small typos in the SConstruct file.
(cherry picked from commit b92c5669de)
2018-02-19 22:23:38 +01:00
Andrea Catania
285f47f037 Added return true o collide when no rusult is NULL
(cherry picked from commit f48845428d)
2018-02-19 22:21:58 +01:00
Michael Alexsander Silva Dias
9fb843db06 Added "allow_reselect" property to ItemList and enabled it for the method/help lists.
(cherry picked from commit 4dbf6ac1b8)
2018-02-19 22:21:14 +01:00
Iskustvo
4bdcee2b9d [X11] Improving error detection in move_to_trash
(cherry picked from commit 268d7c7c5b)
2018-02-19 22:20:06 +01:00
Rémi Verschelde
fd033473c7 Fix broken APK expansion due to missed option renames
Command line options were refactored for 3.0 to follow the common usage
of double-dashed long options, but `--main-pack` went through the cracks.

Fixes #16533.

(cherry picked from commit e3658a6464)
2018-02-19 22:19:08 +01:00
George Marques
a39930c5b9 Add a function to remove controls from containers
Closes #5968

(cherry picked from commit da69a06253)
2018-02-19 22:18:22 +01:00
Artem Varaksa
c94d8e6577 Fix #16543 (add button to copy error from debugger)
(cherry picked from commit b169b16f98)
2018-02-19 22:17:26 +01:00
George Marques
eb5e5200cc Fix infinite recursion with editor import plugins
(cherry picked from commit 95f7879923)
2018-02-19 22:16:33 +01:00
George Marques
d54ac732ae Expose priority and order for custom import plugins
(cherry picked from commit c68948fdfa)
2018-02-19 22:16:13 +01:00
Brandon DeRosier
62fcd772be Add Xbox One Elite and Xbox 360 Afterglow pads
(cherry picked from commit ae579a256e)
2018-02-19 22:15:05 +01:00
Marcelo Fernandez
150423203b Added OS::center_window to center the window precisely on desktop platforms
(cherry picked from commit ea1d726a46)
2018-02-19 22:14:05 +01:00
ShyRed
ef60123938 Add import option "scale_mesh" to obj file importer
The new import option "scale_mesh" allows setting a scale that is applied to the mesh's vertices during import.

(cherry picked from commit 291c1d0f45)
2018-02-19 22:13:46 +01:00
Jonathan Tinkham
0d03b5f162 Add and use mono build variables with cloned environment.
(cherry picked from commit 70d281b946)
2018-02-19 22:13:46 +01:00
Paulb23
148e059940 Fixed members overview not scrolling to correct line
(cherry picked from commit 4d92c5e1c3)
2018-02-19 22:13:46 +01:00
Artem Varaksa
7af43c4ca3 Fix #16479 (deselect text when jumping to function)
(cherry picked from commit 3094e89782)
2018-02-19 22:13:46 +01:00
ronroniv
5b32be4701 Update an outdated method name in error message
set_enable_monitoring -> set_monitoring

(cherry picked from commit 5e8f7c9782)
2018-02-19 22:13:46 +01:00
Andrew Silver
47b49200b0 Fixed KinematicBody move_and_slide documentation naming
(cherry picked from commit da81d9f843)
2018-02-19 22:13:46 +01:00
Hugo Locurcio
a7d7f763d0 Remove debugging prints related to the asset library
(cherry picked from commit 5513e4e1f9)
2018-02-19 22:13:46 +01:00
Ovnuniarchos
eda94419df SpinBoxes calculate correctly their width before first redraw.
(cherry picked from commit fe1ca3c6e6)
2018-02-19 22:13:46 +01:00
Marcin Zawiejski
e6252bda5e download templates to a file using separate thread
(cherry picked from commit b4f1a035e3)
2018-02-19 22:13:46 +01:00
Federico Frenguelli
069658f1be Fixed #15082: line edit emits two "text_changed" signals when pasting while text is selected
(cherry picked from commit 9cd3ed4ace)
2018-02-19 22:13:46 +01:00
Nicolas Silva
a0e59a7259 Fix polygon triangulation failure.
The ear clipping algorithm used to triangulate polygons has a slightly too conservative point-in-triangle test which can, in some configurations prevent it from finding a possible tessellation. Relaxing the test by considering that points exactly on edges don't belong the triangle fixes the issue. Changing the semantic of the test is safe because no other code makes use of it. A more detailed explanation can be found in issue #16395.

Fixes #16395.

(cherry picked from commit 91215e1919)
2018-02-19 22:13:46 +01:00
Paolo Perkovic
82b9a13e0c Fix timeline track name overlapping keyframe area
(cherry picked from commit 398f5b74e3)
2018-02-19 22:13:46 +01:00
Hugo Locurcio
79ef5f92a9 Remove a few debugging prints
(cherry picked from commit 84267915f5)
2018-02-19 22:13:46 +01:00
Hugo Locurcio
5d7867082d Always detect and use hiDPI in the project manager if needed
This makes its hiDPI behavior consistent with the editor.

(cherry picked from commit 55a2bffac9)
2018-02-19 22:13:45 +01:00
Hugo Locurcio
fda35b3f42 Draw the Camera gizmo more accurately
The Camera gizmo no longer looks twice as wide as it actually is.
This fixes #16399.

(cherry picked from commit 0d7d293889)
2018-02-19 22:13:45 +01:00
Michael Alexsander Silva Dias
a0e9d751a3 Fixed wrong example in JSONParseResult.
(cherry picked from commit 24e87f97c6)
2018-02-19 22:13:45 +01:00
Marcin Zawiejski
d4a70c6c08 fix buffer write performance on Windows and Unix
(cherry picked from commit 8315aa40cc)
2018-02-19 22:13:45 +01:00
binbitten
65aa9063c4 Fix spaces and quotes in external editor flags
(cherry picked from commit fb8d2420b5)
2018-02-19 22:13:45 +01:00
ianb96
9eb546e7ff drop path text at mouse pos
(cherry picked from commit 06965f2770)
2018-02-19 22:13:45 +01:00
ianb96
f031e2f665 disable scene tree shortcuts when in a textfield
(cherry picked from commit 4e96e04389)
2018-02-19 22:13:45 +01:00
Poommetee Ketson
4bed14f69b Gradient: fix wrong property type
(cherry picked from commit 4f9ef96b54)
2018-02-19 22:13:45 +01:00
Chaosus
91692ce72a Fix gradient texture preview
(cherry picked from commit 3ba43ac975)
2018-02-19 22:13:45 +01:00
binbitten
05e97db6f2 Fix wrong property type for fixed icon size in ItemList
(cherry picked from commit 331cfc1d18)
2018-02-19 22:13:45 +01:00
Michael Alexsander Silva Dias
617bcd1b91 Capitalized "View" menu options.
(cherry picked from commit b507eeddcc)
2018-02-19 22:13:45 +01:00
Benjamin Dobell
34d8625d82 Fix pkgconfig detection of mono
(cherry picked from commit 5920bc6f72)
2018-02-19 22:13:45 +01:00
Paolo Perkovic
79b931d093 Fix UX with project settings search functionality
(cherry picked from commit e7b98119df)
2018-02-19 22:13:45 +01:00
Nathan Warden
9173819b71 [Mono] Basis values now marshalled in the correct order.
(cherry picked from commit 0cc4de1f24)
2018-02-19 22:13:45 +01:00
JFonS
8787850286 Fix gizmo solid box mesh being added twice
(cherry picked from commit d0a2931cd7)
2018-02-19 22:13:45 +01:00
Max Hilbrunner
2515d42a14 [DOCS] parse_json: Objects do not keep key order
Document JSON not guaranteeing key order.

(cherry picked from commit 82b8f1729d)
2018-02-19 22:13:44 +01:00
Guilherme Felipe
1a9a40fe31 Make parent folder selectable. Fix #16253
(cherry picked from commit 6e1c02b828)
2018-02-19 22:13:44 +01:00
Guilherme Felipe
eda3169cd1 Fixes open button not appearing with multiple selection
Fix #16231

(cherry picked from commit 09c277693e)
2018-02-19 22:13:44 +01:00
George Marques
d7f73031fb Show default values in docs for GDScript built-in functions
(cherry picked from commit dca2ae78dd)
2018-02-19 22:13:44 +01:00
Poommetee Ketson
ba36ef5465 3DEditor: fix selecting node in viewport not update inspector
(cherry picked from commit cfac160f9f)
2018-02-19 22:13:44 +01:00
Poommetee Ketson
41f9904e71 3DEditor: fix multiple node selection crash the editor
I'm not sure about this fix. This seems to also fixes the weird
selection bug where when selecting node 1 to 3 it focuses on
2nd node.

(cherry picked from commit 25dd1f0681)
2018-02-19 22:13:44 +01:00
Gilles Roudiere
a206d3d2fc Fixes a Gridcontainer wrong children fitting with expanded+non-zero minisize
(cherry picked from commit d1f32708b7)
2018-02-19 22:13:44 +01:00
Gilles Roudiere
a6ca62ac79 Fixes a bas resizing with SplitContainer
(cherry picked from commit 30e1e42175)
2018-02-19 22:13:44 +01:00
Rémi Verschelde
85dedc09a8 Readd VS.sync and VS.draw to keep compatibility
Those are deprecated as VS.force_sync and VS.force_draw do the same and more explicitly,
but we cannot remove them without marking them as deprecated before that.

Fixes issue introduced in #15892.

(cherry picked from commit fd92e571ac)
2018-02-19 22:13:44 +01:00
Marc Gilleron
9e7c3016d1 Added all missing VisualServer bindings
- Added bindings for multimesh, immediate, skeleton, light, reflection probe, gi probe, lightmap, particles, camera, environment, scenario, instance
- Removed draw and sync, were duplicates of force_* equivalents
- Bumped binders max arguments from 11 to 13
- Wrote some wrappers as not all methods were variant-friendly

(cherry picked from commit e415fd05bb)
2018-02-19 22:13:44 +01:00
Marcelo Fernandez
906cf28dae Improved WASAPI driver so that it always uses the default audio device
(cherry picked from commit d5afcf7ab1)
2018-02-19 22:13:44 +01:00
Rémi Verschelde
801b544ee1 Windows: Fix case of imm32 for case-sensitive MinGW build
Fixes #16713.

(cherry picked from commit 4fa8987494)
2018-02-19 22:13:44 +01:00
geequlim
097f95993f Windows: implement OS.get_unique_id and OS.set_ime_position
(cherry picked from commit 3be04f73f5)
2018-02-19 22:13:39 +01:00
Bernhard Liebl
c04d868476 Make KEY_ESCAPE close all output/debugger docks on bottom
(cherry picked from commit 2ae2735a7a)
2018-02-19 21:01:41 +01:00
Saracen
50674dbe15 Expose 'lightmap_unwrap' method to the scripting engine.
(cherry picked from commit e3fdacdf90)
2018-02-19 20:57:40 +01:00
Paul Joannon
71607d9198 Fix bug when launching a game with no main scene
Check for a main scene after loading project settings and exit if there's none (except if launching in editor mode).

(cherry picked from commit 3f8a4cc719)
2018-02-19 20:56:54 +01:00
Julian Murgia
3548f71cc4 Display path to preloaded res + button to open it
(cherry picked from commit b766a849ad)
2018-02-19 20:56:16 +01:00
Paul Joannon
a1455f6a03 Change 'Build Project' button style in Mono panel
Address #15208

(cherry picked from commit 484f664331)
2018-02-19 20:50:39 +01:00
Jerome67000
f64b68d870 Change primitive meshes acccuracy value
(cherry picked from commit b72c9b85d0)
2018-02-19 20:49:41 +01:00
Michael Alexsander Silva Dias
f1d26c1c72 Re-enabled type icons.
(cherry picked from commit f7547a7f28)
2018-02-19 20:48:36 +01:00
Vincenzo Greco
7f5fde6459 Select root node if search_box is empty in create_dialog
(cherry picked from commit 586e735125)
2018-02-19 20:47:44 +01:00
Colin Kinloch
611caa06a5 Fixed android arm64v8
(cherry picked from commit 853b1daa49)
2018-02-19 20:46:49 +01:00
Nathan Warden
3f6e8d70cf Added async and await as C# keywords.
(cherry picked from commit 3dcf0567a1)
2018-02-05 09:33:01 +01:00
Ignacio Etcheverry
40c779fb70 Mono: Remove automatic script multilevel calls
(cherry picked from commit 84437b4864)
2018-02-05 09:32:29 +01:00
Phil Jones
532abf228c Fix texture import spelling
(cherry picked from commit d1a471f909)
2018-02-04 20:11:13 +01:00
Michael Alexsander Silva Dias
248fea2a79 Small fixes for the Control description in the docs.
(cherry picked from commit 5e0821e867)
2018-02-04 20:10:45 +01:00
Paolo Perkovic
7de47fbabb Fix inconsistencies and typos in argument names
(cherry picked from commit 08d4bfacaf)
2018-02-04 20:10:13 +01:00
volzhs
62dc7ba82f Expand project root directory on editor start
close #16232
Option for expanding all directories on start up is a bit tricky and buggy.

(cherry picked from commit 127d1241bd)
2018-02-04 20:09:26 +01:00
Nathan Warden
4a3a597377 Fix an infinite recursion in the Mathf.Decimals method when using floats.
(cherry picked from commit 2109bd3f97)
2018-02-04 20:08:26 +01:00
Guilherme Felipe
501880e9ba Hide button tree when file system dock isn't in split mode
(cherry picked from commit bb936b5503)
2018-02-04 20:07:56 +01:00
Profesor Tartelett
bd02969263 Errata fix on Image get_format() description
The description of this function seems to be duplicated from the preceding description.

(cherry picked from commit 9d735ffacb)
2018-02-04 20:07:19 +01:00
binbitten
0fa4325153 Fix TextEdit current line highlight horizontal offset
(cherry picked from commit ba8c5bff69)
2018-02-04 20:06:46 +01:00
George Marques
acf01c955f Expose a few GraphEdit methods to script languages
(cherry picked from commit b80bc73a17)
2018-02-04 20:05:47 +01:00
George Marques
0a75a38db4 Add interface for plugins to enable/disable other plugins
(cherry picked from commit 87be0bc110)
2018-02-04 20:05:12 +01:00
Andreas Haas
845f44b976 ProjectSettings: Disallow adding properties without name.
(cherry picked from commit d664d6e634)
2018-02-04 20:04:31 +01:00
Poommetee Ketson
77ee4ced30 AudioEffectReverb: max predelay_feedback to 0.98
(cherry picked from commit 5a26e0786c)
2018-02-04 20:03:16 +01:00
Chaosus
780a7a281b Viewport doc improvements
(cherry picked from commit ffcbb0c358)
2018-02-04 20:02:38 +01:00
Marlon Henry Schweigert
5481ece976 Display set_nodelay to GDScript
Pass enabled arg

Rename set_nodelay to set_no_delay

Add description to the method

Change description

(cherry picked from commit 87adf9cfba)
2018-02-04 20:02:04 +01:00
Hein-Pieter van Braam
ef49c166f6 Allow focus on disabled buttons
This behavior better matches other gui toolkits. A selected disabled
button still can't be interacted with but it can now be selected. This
seems to be what QT and GTK do also.

This fixes #16131

(cherry picked from commit 713f190a30)
2018-02-04 20:00:23 +01:00
Mariano Suligoy
77cc0a023b attemp to fix #15870
(cherry picked from commit 517ff5c8d7)
2018-02-04 19:59:34 +01:00
robfram
1036a76bc5 Fix issue 15895, audio streams don't signalling finished after the first one
if the audio player is set to play again due to the order of calls in
_notification. First it emits the signal, and later it disable the internal
processing regardless what the callback did.

Changed to emit the signal at the end to ensure the changes done at callback
remains.

(cherry picked from commit d588fe2740)
2018-02-04 19:56:37 +01:00
Rémi Verschelde
e44bef4404 Update DONORS list
[ci skip]

(cherry picked from commit f13d034485)
2018-02-02 10:07:40 +01:00
Juan Linietsky
c77047d6a3 Ability to import .escn files, which is just a .tscn but with forced import.
This works together with the new Blender to Godot exporter.

(cherry picked from commit 1322ca6fb2)
2018-01-31 01:15:00 +01:00
Hein-Pieter van Braam
a34afa3820 Implement OS::get_processor_count() for Windows
Current this is hardcoded as '1' for any platform except Unix. The
little is_wow64() dance is required to get correct output on a 32bit
compiled godot running on 64bit Windows according to MSDN.

This code should be UWP safe but I have no way to test that so it's not
implemented for UWP yet.

(cherry picked from commit b4d369c887)
2018-01-30 20:56:53 +01:00
bruvzg
77d27053c3 [macOS] Strip executable when separate_debug_symbols is set to yes
(cherry picked from commit 9ef0315b06)
2018-01-30 20:56:16 +01:00
Poommetee Ketson
187c40d64d Fix wrong return type of xform functions
(cherry picked from commit ebe2337515)
2018-01-30 20:55:41 +01:00
Hein-Pieter van Braam
e69b30b276 Fix Copy/Paste problems on X11
The target of the TARGETS type should be XA_ATOM and not XA_TARGETS when
requested. Since we are sending a number of ATOMS the size should be set
to the integer size and not the char size.

The size field of the atoms is also the number of atoms and not the size
of the array. This caused some clients to wrongly interpret the data and
read garbage in the X11 packet.

I also add the more modern representation for UTF-8 and clarify the
error message if a client attempts to request a type we don't know
about.

This fixes #10431

(cherry picked from commit fb60f2dbe6)
2018-01-30 20:55:11 +01:00
Geequlim
99e72894a2 Remote debugger send the real instance of WeakRef referenced to
(cherry picked from commit 10f0451cc2)
2018-01-30 20:54:25 +01:00
MrCdK
258119a9cf Expose audio streams get_length()
(cherry picked from commit 8a9f1c2a5d)
2018-01-30 20:53:37 +01:00
Hein-Pieter van Braam
3f6694b894 Bump version to 3.0.1-devel
Onwards, but slowly, towards stability. And the stars.
2018-01-30 20:51:06 +01:00
17164 changed files with 2053723 additions and 5711778 deletions

32
.appveyor.yml Normal file
View File

@@ -0,0 +1,32 @@
os: Visual Studio 2015
environment:
HOME: "%HOMEDRIVE%%HOMEPATH%"
PYTHON: C:\Python27
SCONS_CACHE_ROOT: "%HOME%\\scons_cache"
SCONS_CACHE_LIMIT: 512
matrix:
- VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
GD_PLATFORM: windows
TOOLS: yes
TARGET: release_debug
ARCH: amd64
cache:
- "%SCONS_CACHE_ROOT%"
install:
- SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- pip install -U wheel # needed for pip install scons to work, otherwise a flag is missing
- pip install scons
- if defined VS call "%VS%" %ARCH% # if defined - so we can also use mingw
before_build:
- echo %GD_PLATFORM%
- python --version
- scons --version
- cl.exe
- SET "SCONS_CACHE=%SCONS_CACHE_ROOT%\master"
build_script:
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% verbose=yes progress=no gdnative_wrapper=yes

View File

@@ -1,238 +1,119 @@
# Commented out parameters are those with the same value as base LLVM style.
# Commented out parameters are those with the same value as base LLVM style
# We can uncomment them if we want to change their value, or enforce the
# chosen value in case the base style changes (last sync: Clang 17.0.6).
BasedOnStyle: LLVM
# chosen value in case the base style changes (last sync: Clang 5.0.0).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
# AlignArrayOfStructures: None
# AlignConsecutiveAssignments:
# Enabled: false
# AcrossEmptyLines: false
# AcrossComments: false
# AlignCompound: false
# PadOperators: true
# AlignConsecutiveBitFields:
# Enabled: false
# AcrossEmptyLines: false
# AcrossComments: false
# AlignCompound: false
# PadOperators: false
# AlignConsecutiveDeclarations:
# Enabled: false
# AcrossEmptyLines: false
# AcrossComments: false
# AlignCompound: false
# PadOperators: false
# AlignConsecutiveMacros:
# Enabled: false
# AcrossEmptyLines: false
# AcrossComments: false
# AlignCompound: false
# PadOperators: false
# AlignConsecutiveShortCaseStatements:
# Enabled: false
# AcrossEmptyLines: false
# AcrossComments: false
# AlignCaseColons: false
# AlignConsecutiveAssignments: false
# AlignConsecutiveDeclarations: false
# AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments:
Kind: Never
OverEmptyLines: 0
# AllowAllArgumentsOnNextLine: true
# AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
# AllowShortBlocksOnASingleLine: Never
# AllowShortCaseLabelsOnASingleLine: false
# AllowShortEnumsOnASingleLine: true
# AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
# AllowShortIfStatementsOnASingleLine: Never
# AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
# AllowShortLoopsOnASingleLine: false
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
# AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: MultiLine
# AttributeMacros:
# - __capability
# AlwaysBreakTemplateDeclarations: false
# BinPackArguments: true
# BinPackParameters: true
# BitFieldColonSpacing: Both
# BraceWrapping:
# AfterCaseLabel: false
# AfterClass: false
# AfterControlStatement: Never
# AfterEnum: false
# AfterFunction: false
# AfterNamespace: false
# AfterClass: false
# AfterControlStatement: false
# AfterEnum: false
# AfterFunction: false
# AfterNamespace: false
# AfterObjCDeclaration: false
# AfterStruct: false
# AfterUnion: false
# AfterExternBlock: false
# BeforeCatch: false
# BeforeElse: false
# BeforeLambdaBody: false
# BeforeWhile: false
# IndentBraces: false
# AfterStruct: false
# AfterUnion: false
# BeforeCatch: false
# BeforeElse: false
# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
# BreakAfterAttributes: Never
# BreakAfterJavaFieldAnnotations: false
# BreakArrays: true
# BreakBeforeBinaryOperators: None
# BreakBeforeBraces: Attach
# BreakBeforeConceptDeclarations: Always
# BreakBeforeInlineASMColon: OnlyMultiline
# BreakBeforeTernaryOperators: true
# BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: false
# BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: AfterColon
# BreakInheritanceList: BeforeColon
# BreakStringLiterals: true
ColumnLimit: 0
# CommentPragmas: "^ IWYU pragma:"
ColumnLimit: 0
# CommentPragmas: '^ IWYU pragma:'
# CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
# DerivePointerAlignment: false
# DisableFormat: false
# EmptyLineAfterAccessModifier: Never
# EmptyLineBeforeAccessModifier: LogicalBlock
# DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IfMacros:
# - KJ_IF_MAYBE
# IncludeBlocks: Preserve
IncludeCategories:
- Regex: ^".*"$
Priority: 1
- Regex: ^<.*\.h>$
Priority: 2
- Regex: ^<.*>$
Priority: 3
# IncludeIsMainRegex: (Test)?$
# IncludeIsMainSourceRegex: ""
# IndentAccessModifiers: false
# IndentCaseBlocks: false
- Regex: '".*"'
Priority: 1
- Regex: '^<.*\.h>'
Priority: 2
- Regex: '^<.*'
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
# IndentExternBlock: AfterExternBlock
# IndentGotoLabels: true
# IndentPPDirectives: None
# IndentRequiresClause: true
IndentWidth: 4
IndentWidth: 4
# IndentWrappedFunctionNames: false
InsertBraces: true
# InsertNewlineAtEOF: false
# InsertTrailingCommas: None
# IntegerLiteralSeparator:
# Binary: 0
# BinaryMinDigits: 0
# Decimal: 0
# DecimalMinDigits: 0
# Hex: 0
# HexMinDigits: 0
JavaImportGroups:
- org.godotengine
- android
- androidx
- com.android
- com.google
- java
- javax
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtEOF: false
KeepEmptyLinesAtTheStartOfBlocks: false
# LambdaBodyIndentation: Signature
# Language: Cpp
# LineEnding: DeriveLF
# MacroBlockBegin: ""
# MacroBlockEnd: ""
# KeepEmptyLinesAtTheStartOfBlocks: true
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
# ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
# ObjCBreakBeforeNestedBlockParam: true
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
# PPIndentWidth: -1
PackConstructorInitializers: NextLine
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 19
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakOpenParenthesis: 0
# PenaltyBreakString: 1000
# PenaltyBreakTemplateDeclaration: 10
# PenaltyExcessCharacter: 1000000
# PenaltyIndentedWhitespace: 0
# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
# QualifierAlignment: Leave
# ReferenceAlignment: Pointer
# ReflowComments: true
# RemoveBracesLLVM: false
# RemoveParentheses: Leave
RemoveSemicolon: true
# RequiresClausePosition: OwnLine
# RequiresExpressionIndentation: OuterScope
# SeparateDefinitionBlocks: Leave
# ShortNamespaceLines: 1
# SortIncludes: CaseSensitive
# SortJavaStaticImport: Before
# SortUsingDeclarations: LexicographicNumeric
# ReflowComments: true
# SortIncludes: true
# SortUsingDeclarations: true
# SpaceAfterCStyleCast: false
# SpaceAfterLogicalNot: false
# SpaceAfterTemplateKeyword: true
# SpaceAroundPointerQualifiers: Default
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeCaseColon: false
# SpaceBeforeCpp11BracedList: false
# SpaceBeforeCtorInitializerColon: true
# SpaceBeforeInheritanceColon: true
# SpaceBeforeJsonColon: false
# SpaceBeforeParens: ControlStatements
# SpaceBeforeParensOptions:
# AfterControlStatements: true
# AfterForeachMacros: true
# AfterFunctionDeclarationName: false
# AfterFunctionDefinitionName: false
# AfterIfMacros: true
# AfterOverloadedOperator: false
# AfterRequiresInClause: false
# AfterRequiresInExpression: false
# BeforeNonEmptyParentheses: false
# SpaceBeforeRangeBasedForLoopColon: true
# SpaceBeforeSquareBrackets: false
# SpaceInEmptyBlock: false
# SpaceInEmptyParentheses: false
# SpacesBeforeTrailingComments: 1
# SpacesInAngles: Never
# SpacesInAngles: false
# SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 0 # We want a minimum of 1 for comments, but allow 0 for disabled code.
Maximum: -1
# SpacesInParens: Never
# SpacesInParensOptions:
# InConditionalStatements: false
# InCStyleCasts: false
# InEmptyParentheses: false
# Other: false
# SpacesInCStyleCastParentheses: false
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
Standard: c++20
# StatementAttributeLikeMacros:
# - Q_EMIT
# StatementMacros:
# - Q_UNUSED
# - QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Always
# VerilogBreakBetweenInstancePorts: true
# WhitespaceSensitiveMacros:
# - BOOST_PP_STRINGIZE
# - CF_SWIFT_NAME
# - NS_SWIFT_NAME
# - PP_STRINGIZE
# - STRINGIZE
TabWidth: 4
UseTab: Always
---
### C++ specific config ###
Language: Cpp
Standard: Cpp03
---
### ObjC specific config ###
Language: ObjC
ObjCBlockIndentWidth: 4
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
---
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
...

View File

@@ -1,19 +0,0 @@
Checks:
- -*
- cppcoreguidelines-pro-type-member-init
- modernize-redundant-void-arg
- modernize-use-bool-literals
- modernize-use-default-member-init
- modernize-use-nullptr
- readability-braces-around-statements
- readability-redundant-member-init
HeaderFileExtensions: ["", h, hh, hpp, hxx, inc, glsl]
ImplementationFileExtensions: [c, cc, cpp, cxx, m, mm, java]
HeaderFilterRegex: (core|doc|drivers|editor|main|modules|platform|scene|servers|tests)/
FormatStyle: file
CheckOptions:
cppcoreguidelines-pro-type-member-init.IgnoreArrays: true
cppcoreguidelines-pro-type-member-init.UseAssignment: true
modernize-use-bool-literals.IgnoreMacros: false
modernize-use-default-member-init.IgnoreMacros: false
modernize-use-default-member-init.UseAssignment: true

31
.clangd
View File

@@ -1,31 +0,0 @@
# https://clangd.llvm.org/config
---
# Default conditions, apply everywhere.
Diagnostics:
Includes:
IgnoreHeader:
- core/typedefs\.h # Our "main" header, featuring transitive includes; allow everywhere.
- \.compat\.inc
---
# Header-specific conditions.
If:
PathMatch: .*\.(h|hh|hpp|hxx|inc)
# Exclude certain, noisy warnings that lack full context. Replace with lowered severity if/when
# clangd gets diagnostic severity support. (See: https://github.com/clangd/clangd/issues/1937)
CompileFlags:
Add:
- -Wno-unneeded-internal-declaration
- -Wno-unused-const-variable
- -Wno-unused-function
- -Wno-unused-variable
---
# Suppress all third-party warnings.
If:
PathMatch: thirdparty/.*
Diagnostics:
Suppress: "*"

View File

@@ -3,18 +3,16 @@ root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
insert_final_newline = true
max_line_length = 120
[*.{cpp,hpp,c,h,mm}]
trim_trailing_whitespace = true
[{*.py,SConstruct,SCsub}]
[*.py]
indent_style = space
indent_size = 4
[{*.{yml,yaml},.clang{-format,-tidy,d}}]
[.travis.yml]
indent_style = space
indent_size = 2
indent_style = space
[*.svg]
insert_final_newline = false

View File

@@ -1,68 +0,0 @@
# This file contains a list of Git commit hashes that should be hidden from the
# regular Git history. Typically, this includes commits involving mass auto-formatting
# or other normalizations. Commit hashes *must* use the full 40-character notation.
# To apply the ignore list in your local Git client, you must run:
#
# git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# This file is automatically used by GitHub.com's blame view.
# A Whole New World (clang-format edition)
5dbf1809c6e3e905b94b8764e99491e608122261
# Style: clang-format: Disable KeepEmptyLinesAtTheStartOfBlocks
0be6d925dc3c6413bce7a3ccb49631b8e4a6e67a
# Style: clang-format: Disable AllowShortIfStatementsOnASingleLine
e956e80c1fa1cc8aefcb1533e5acf5cf3c8ffdd9
# One Copyright Update to rule them all
d95794ec8a7c362b06a9cf080e2554ef77adb667
# Update copyright statements to 2022
fe52458154c64fb1b741df4f7bd10106395f7cbd
# Update copyright statements to 2021
b5334d14f7a471f94bcbd64d5bae2ad853d0b7f1
# Update copyright statements to 2020
a7f49ac9a107820a62677ee3fb49d38982a25165
# Update copyright statements to 2019
b16c309f82c77d606472c3c721a1857e323a09e7
# Update copyright statements to 2018
b50a9114b105dafafdda8248a38653bca314a6f3
# Welcome in 2017, dear changelog reader!
c7bc44d5ad9aae4902280012f7654e2318cd910e
# Update copyright to 2016 in headers
5be9ff7b6715a661e85f99b108f96340de7ef435
# Updated copyright year in all headers
fdaa2920eb21fff3320a17e9239e04dfadecdb00
# Add missing copyright headers and fix formatting
e4213e66b2dd8f5a87d8cf5015ac83ba3143279d
# Use HTTPS URL for Godot's website in the headers
bd282ff43f23fe845f29a3e25c8efc01bd65ffb0
# Add "Godot Engine contributors" copyright line
df61dc4b2bd54a5a40c515493c76f5a458e5b541
# Enforce template syntax `typename` over `class`
9903e6779b70fc03aae70a37b9cf053f4f355b91
# Style: Apply new `clang-format` fixes
b37fc1014abf7adda70dc30b0822d775b3a4433f
# Set clang-format `RemoveSemicolon` rule to `true`
0d350e71086fffce0553811739aae9f6ad66136c
# Style: Apply clang-tidy fixes (superficial)
bb5f390fb9b466be35a5df7651323d7e66afca31
# Style: Enforce `AllowShortFunctionsOnASingleLine`
e06d83860d798b6766b23d6eae48557387a7db85

30
.gitattributes vendored
View File

@@ -1,23 +1,11 @@
# Properly detect languages on Github
*.h linguist-language=C++
*.inc linguist-language=C++
thirdparty/* linguist-vendored
*.h linguist-language=cpp
*.inc linguist-language=cpp
drivers/* linguist-vendored
# Normalize EOL for all files that Git considers text files
* text=auto eol=lf
# Except for Windows-only / Visual Studio files
*.bat eol=crlf
*.sln eol=crlf
*.csproj eol=crlf
misc/msvs/*.template eol=crlf
# And some test files where the EOL matters
*.test.txt -text
# The above only works properly for Git 2.10+, so for older versions
# we need to manually list the binary files we don't want modified.
*.icns binary
*.ico binary
*.jar binary
*.png binary
*.ttf binary
*.tza binary
*.cpp eol=lf
*.mm eol=lf
*.h eol=lf
*.py eol=lf
*.hpp eol=lf
*.xml eol=lf

251
.github/CODEOWNERS vendored
View File

@@ -1,251 +0,0 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# Owners can be @users, @org/teams or emails.
# Core
/core/ @godotengine/core
/core/crypto/ @godotengine/network
/core/debugger/ @godotengine/debugger
/core/extension/ @godotengine/gdextension
/core/input/ @godotengine/input
# Doc
/doc/ @godotengine/documentation
# Drivers
## Audio
/drivers/alsa/ @godotengine/audio
/drivers/alsamidi/ @godotengine/audio
/drivers/coreaudio/ @godotengine/audio
/drivers/coremidi/ @godotengine/audio
/drivers/pulseaudio/ @godotengine/audio
/drivers/wasapi/ @godotengine/audio
/drivers/winmidi/ @godotengine/audio
/drivers/xaudio2/ @godotengine/audio
## Rendering
/drivers/d3d12/ @godotengine/rendering
/drivers/dummy/ @godotengine/rendering
/drivers/egl/ @godotengine/rendering
/drivers/gles3/ @godotengine/rendering
/drivers/metal/ @godotengine/rendering
/drivers/spirv-reflect/ @godotengine/rendering
/drivers/vulkan/ @godotengine/rendering
## OS
/drivers/unix/ @godotengine/linux-bsd
/drivers/windows/ @godotengine/windows
## Misc
/drivers/png/ @godotengine/import
# Editor
/editor/**/*2d* @godotengine/2d-editor
/editor/**/*3d* @godotengine/3d-editor
/editor/**/*audio* @godotengine/audio
/editor/**/*code* @godotengine/script-editor
/editor/**/*debugger* @godotengine/debugger
/editor/**/*dock* @godotengine/docks
/editor/**/*script* @godotengine/script-editor
/editor/**/*shader* @godotengine/shaders
/editor/debugger/ @godotengine/debugger
/editor/gui/ @godotengine/usability @godotengine/gui-nodes
/editor/icons/ @godotengine/usability
/editor/import/ @godotengine/import
/editor/themes/ @godotengine/usability @godotengine/gui-nodes
# Main
/main/ @godotengine/core
# Misc
/misc/ @godotengine/buildsystem
/misc/extension_api_validation/ @godotengine/gdextension @godotengine/dotnet
# Modules
## Audio (+ video)
/modules/interactive_music/ @godotengine/audio
/modules/interactive_music/doc_classes/ @godotengine/audio @godotengine/documentation
/modules/minimp3/ @godotengine/audio
/modules/minimp3/doc_classes/ @godotengine/audio @godotengine/documentation
/modules/ogg/ @godotengine/audio
/modules/ogg/doc_classes/ @godotengine/audio @godotengine/documentation
/modules/theora/ @godotengine/audio
/modules/theora/doc_classes/ @godotengine/audio @godotengine/documentation
/modules/vorbis/ @godotengine/audio
/modules/vorbis/doc_classes/ @godotengine/audio @godotengine/documentation
## Import
/modules/astcenc/ @godotengine/import
/modules/basis_universal/ @godotengine/import
/modules/bcdec/ @godotengine/import
/modules/betsy/ @godotengine/import
/modules/bmp/ @godotengine/import
/modules/cvtt/ @godotengine/import
/modules/dds/ @godotengine/import
/modules/etcpak/ @godotengine/import
/modules/fbx/ @godotengine/import
/modules/fbx/doc_classes/ @godotengine/import @godotengine/documentation
/modules/gltf/ @godotengine/import
/modules/gltf/doc_classes/ @godotengine/import @godotengine/documentation
/modules/gltf/tests/ @godotengine/import @godotengine/tests
/modules/hdr/ @godotengine/import
/modules/jpg/ @godotengine/import
/modules/ktx/ @godotengine/import
/modules/squish/ @godotengine/import
/modules/svg/ @godotengine/import
/modules/tga/ @godotengine/import
/modules/tinyexr/ @godotengine/import
/modules/webp/ @godotengine/import
## Network
/modules/enet/ @godotengine/network
/modules/enet/doc_classes/ @godotengine/network @godotengine/documentation
/modules/mbedtls/ @godotengine/network
/modules/mbedtls/tests/ @godotengine/network @godotengine/tests
/modules/multiplayer/ @godotengine/network
/modules/multiplayer/doc_classes/ @godotengine/network @godotengine/documentation
/modules/multiplayer/tests/ @godotengine/network @godotengine/tests
/modules/upnp/ @godotengine/network
/modules/upnp/doc_classes/ @godotengine/network @godotengine/documentation
/modules/webrtc/ @godotengine/network
/modules/webrtc/doc_classes/ @godotengine/network @godotengine/documentation
/modules/websocket/ @godotengine/network
/modules/websocket/doc_classes/ @godotengine/network @godotengine/documentation
## Physics
/modules/godot_physics_2d/ @godotengine/physics
/modules/godot_physics_3d/ @godotengine/physics
/modules/jolt_physics/ @godotengine/physics
## Rendering
/modules/glslang/ @godotengine/rendering
/modules/lightmapper_rd/ @godotengine/rendering
/modules/meshoptimizer/ @godotengine/rendering
/modules/raycast/ @godotengine/rendering
/modules/vhacd/ @godotengine/rendering
/modules/xatlas_unwrap/ @godotengine/rendering
## Scripting
/modules/gdscript/ @godotengine/gdscript
/modules/gdscript/doc_classes/ @godotengine/gdscript @godotengine/documentation
/modules/gdscript/icons/ @godotengine/gdscript @godotengine/usability
/modules/gdscript/tests/ @godotengine/gdscript @godotengine/tests
/modules/jsonrpc/ @godotengine/gdscript @godotengine/network
/modules/jsonrpc/tests/ @godotengine/gdscript @godotengine/network @godotengine/tests
/modules/mono/ @godotengine/dotnet
/modules/mono/doc_classes/ @godotengine/dotnet @godotengine/documentation
/modules/mono/icons/ @godotengine/dotnet @godotengine/usability
## Text
/modules/freetype/ @godotengine/buildsystem
/modules/msdfgen/ @godotengine/buildsystem
/modules/text_server_adv/ @godotengine/gui-nodes
/modules/text_server_adv/doc_classes/ @godotengine/gui-nodes @godotengine/documentation
/modules/text_server_fb/ @godotengine/gui-nodes
/modules/text_server_fb/doc_classes/ @godotengine/gui-nodes @godotengine/documentation
## XR
/modules/camera/ @godotengine/xr
/modules/mobile_vr/ @godotengine/xr
/modules/mobile_vr/doc_classes/ @godotengine/xr @godotengine/documentation
/modules/openxr/ @godotengine/xr
/modules/openxr/doc_classes/ @godotengine/xr @godotengine/documentation
/modules/webxr/ @godotengine/xr
/modules/webxr/doc_classes/ @godotengine/xr @godotengine/documentation
## Misc
/modules/csg/ @godotengine/3d-nodes
/modules/csg/doc_classes/ @godotengine/3d-nodes @godotengine/documentation
/modules/csg/icons/ @godotengine/3d-nodes @godotengine/usability
/modules/gridmap/ @godotengine/3d-nodes
/modules/gridmap/doc_classes/ @godotengine/3d-nodes @godotengine/documentation
/modules/gridmap/icons/ @godotengine/3d-nodes @godotengine/usability
/modules/navigation/ @godotengine/navigation
/modules/noise/ @godotengine/core
/modules/noise/doc_classes/ @godotengine/core @godotengine/documentation
/modules/noise/icons/ @godotengine/core @godotengine/usability
/modules/noise/tests/ @godotengine/core @godotengine/tests
/modules/regex/ @godotengine/core
/modules/regex/doc_classes/ @godotengine/core @godotengine/documentation
/modules/regex/icons/ @godotengine/core @godotengine/usability
/modules/regex/tests/ @godotengine/core @godotengine/tests
/modules/zip/ @godotengine/core
/modules/zip/doc_classes/ @godotengine/core @godotengine/documentation
# Platform
/platform/android/ @godotengine/android
/platform/android/doc_classes/ @godotengine/android @godotengine/documentation
/platform/ios/ @godotengine/ios
/platform/ios/doc_classes/ @godotengine/ios @godotengine/documentation
/platform/linuxbsd/ @godotengine/linux-bsd
/platform/linuxbsd/doc_classes/ @godotengine/linux-bsd @godotengine/documentation
/platform/macos/ @godotengine/macos
/platform/macos/doc_classes/ @godotengine/macos @godotengine/documentation
/platform/web/ @godotengine/web
/platform/web/doc_classes/ @godotengine/web @godotengine/documentation
/platform/windows/ @godotengine/windows
/platform/windows/doc_classes/ @godotengine/windows @godotengine/documentation
# Scene
/scene/2d/ @godotengine/2d-nodes
/scene/2d/physics/ @godotengine/2d-nodes @godotengine/physics
/scene/3d/ @godotengine/3d-nodes
/scene/3d/physics/ @godotengine/3d-nodes @godotengine/physics
/scene/animation/ @godotengine/animation
/scene/audio/ @godotengine/audio
/scene/debugger/ @godotengine/debugger
/scene/gui/ @godotengine/gui-nodes
/scene/main/ @godotengine/core
/scene/resources/2d/ @godotengine/2d-nodes
/scene/resources/3d/ @godotengine/3d-nodes
/scene/resources/animated* @godotengine/animation
/scene/resources/animation* @godotengine/animation
/scene/resources/audio* @godotengine/audio
/scene/resources/font* @godotengine/gui-nodes
/scene/resources/shader* @godotengine/shaders
/scene/resources/text_* @godotengine/gui-nodes
/scene/resources/visual_shader* @godotengine/shaders
/scene/theme/ @godotengine/gui-nodes
/scene/theme/icons/ @godotengine/gui-nodes @godotengine/usability
# Servers
/servers/**/audio_* @godotengine/audio
/servers/**/camera_* @godotengine/xr
/servers/**/debugger_* @godotengine/debugger
/servers/**/navigation_* @godotengine/navigation
/servers/**/physics_* @godotengine/physics
/servers/**/rendering_* @godotengine/rendering
/servers/**/text_* @godotengine/gui-nodes
/servers/**/xr_* @godotengine/xr
/servers/audio/ @godotengine/audio
/servers/camera/ @godotengine/xr
/servers/debugger/ @godotengine/debugger
/servers/navigation/ @godotengine/navigation
/servers/rendering/ @godotengine/rendering
/servers/text/ @godotengine/gui-nodes
/servers/xr/ @godotengine/xr
# Tests
/tests/ @godotengine/tests
# Thirdparty
/thirdparty/ @godotengine/buildsystem
# Buildsystem (After everything to catch all)
/*.* @godotengine/buildsystem
*.py @godotengine/buildsystem
SConstruct @godotengine/buildsystem
SCsub @godotengine/buildsystem

View File

@@ -1,72 +0,0 @@
name: Bug report
description: Report a bug in Godot
body:
- type: markdown
attributes:
value: |
When reporting bugs, please follow the guidelines in this template. This helps identify the problem precisely and thus enables contributors to fix it faster.
- Write a descriptive issue title above.
- The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
- Search [open](https://github.com/godotengine/godot/issues) and [closed](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
- Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/latest/about/release_policy.html). Please always check if your issue is reproducible in the latest version it may already have been fixed!
- If you use a custom build, please test if your issue is reproducible in official builds too. Likewise if you use any C++ modules, GDExtensions, or editor plugins, you should check if the bug is reproducible in a project without these.
- type: textarea
attributes:
label: Tested versions
description: |
To properly fix a bug, we need to identify if the bug was recently introduced in the engine, or if it was always present.
- Please specify the Godot version you found the issue in, including the **Git commit hash** if using a development or non-official build. The exact Godot version (including the commit hash) can be copied by clicking the version shown in the editor (bottom bar) or in the project manager (top bar).
- If you can, **please test earlier Godot versions** (previous stable branch, and development snapshots of the current feature release) and, if applicable, newer versions (development snapshots for the next feature release). Mention whether the bug is reproducible or not in the versions you tested. You can find all Godot releases in our [download archive](https://godotengine.org/download/archive/).
- The aim is for us to identify whether a bug is a **regression**, i.e. an issue that didn't exist in a previous version, but was introduced later on, breaking existing functionality. For example, if a bug is reproducible in 4.2.stable but not in 4.1.stable, we would like you to test intermediate 4.2 dev and beta snapshots to find which snapshot is the first one where the issue can be reproduced.
placeholder: |
- Reproducible in: 4.3.dev [d76c1d0e5], 4.2.stable, 4.2.dev5 and later 4.2 snapshots.
- Not reproducible in: 4.1.3.stable, 4.2.dev4 and earlier 4.2 snapshots.
validations:
required: true
- type: input
attributes:
label: System information
description: |
- Specify the OS version, and when relevant hardware information.
- For issues that are likely OS-specific and/or graphics-related, please specify the CPU model and architecture.
- For graphics-related issues, specify the GPU model, driver version, and the rendering backend (GLES2, GLES3, Vulkan).
- **Bug reports not including the required information may be closed at the maintainers' discretion.** If in doubt, always include all the requested information; it's better to include too much information than not enough information.
- **Starting from Godot 4.1, you can copy this information to your clipboard by using *Help > Copy System Info* at the top of the editor window.**
placeholder: Windows 10 - Godot v4.0.3.stable - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 970 (nvidia, 510.85.02) - Intel Core i7-10700KF CPU @ 3.80GHz (16 Threads)
validations:
required: true
- type: textarea
attributes:
label: Issue description
description: |
Describe your issue briefly. What doesn't work, and how do you expect it to work instead?
You can include images or videos with drag and drop, and format code blocks or logs with <code>\`\`\`</code> tags, on separate lines before and after the text. (Use <code>\`\`\`gdscript</code> to add GDScript syntax highlighting.)
Please do not add code examples or error messages as screenshots, but as text, this helps searching for issues and testing the code. If you are reporting a bug in the editor interface, like the script editor, please provide both a screenshot *and* the text of the code to help with testing.
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: |
List of steps or sample code that reproduces the issue. Having reproducible issues is a prerequisite for contributors to be able to solve them.
If you include a minimal reproduction project below, you can detail how to use it here.
validations:
required: true
- type: textarea
attributes:
label: Minimal reproduction project (MRP)
description: |
- A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the `.godot` folder in the archive (but keep `project.godot`).
- Having an MRP is very important for contributors to be able to reproduce the bug in the same way that you are experiencing it. When testing a potential fix for the issue, contributors will use the MRP to validate that the fix is working as intended.
- If the reproduction steps are not project dependent (e.g. the bug is visible in a brand new project), you can write "N/A" in the field.
- Drag and drop a ZIP archive to upload it (max 10 MB). **Do not select another field until the project is done uploading.**
- **Note for C# users:** If your issue is *not* C#-specific, please upload a minimal reproduction project written in GDScript. This will make it easier for contributors to reproduce the issue locally as not everyone has a .NET setup available.
validations:
required: true

View File

@@ -1,14 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Godot proposals
url: https://github.com/godotengine/godot-proposals
about: Please submit feature proposals on the Godot proposals repository, not here.
- name: Godot documentation repository
url: https://github.com/godotengine/godot-docs
about: Please report issues with documentation on the Godot documentation repository, not here.
- name: Godot community channels
url: https://godotengine.org/community
about: Please ask for technical support on one of the other community channels, not here.

View File

@@ -1,8 +0,0 @@
<!--
Please target the `master` branch in priority.
Relevant fixes are cherry-picked for stable branches as needed by maintainers.
To speed up the contribution process and avoid CI errors, please set up pre-commit hooks locally:
https://docs.godotengine.org/en/latest/contributing/development/code_style_guidelines.html
-->

View File

@@ -1,20 +0,0 @@
name: Download Godot artifact
description: Download the Godot artifact.
inputs:
name:
description: The artifact name.
default: ${{ github.job }}
path:
description: The path to download and extract to.
required: true
default: ./
runs:
using: composite
steps:
- name: Download Godot Artifact
uses: actions/download-artifact@v4
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}

View File

@@ -1,25 +0,0 @@
name: Dump Godot API
description: Dump Godot API for GDExtension
inputs:
bin:
description: The path to the Godot executable
required: true
runs:
using: composite
steps:
# Dump GDExtension interface and API
- name: Dump GDExtension interface and API for godot-cpp build
shell: sh
run: |
${{ inputs.bin }} --headless --dump-gdextension-interface --dump-extension-api
mkdir godot-api
cp -f gdextension_interface.h godot-api/
cp -f extension_api.json godot-api/
- name: Upload API dump
uses: ./.github/actions/upload-artifact
with:
name: godot-api-dump
path: ./godot-api/*

View File

@@ -1,51 +0,0 @@
name: Build Godot
description: Build Godot with the provided options.
inputs:
target:
description: Build target (editor, template_release, template_debug).
default: editor
tests:
description: Unit tests.
default: false
required: false
platform:
description: Target platform.
required: false
sconsflags:
description: Additional SCons flags.
default: ""
required: false
scons-cache:
description: The SCons cache path.
default: ${{ github.workspace }}/.scons_cache/
scons-cache-limit:
description: The SCons cache size limit.
# actions/cache has 10 GiB limit, and GitHub runners have a 14 GiB disk.
# Limit to 7 GiB to avoid having the extracted cache fill the disk.
default: 7
runs:
using: composite
steps:
- name: SCons Build
shell: sh
env:
SCONSFLAGS: ${{ inputs.sconsflags }}
run: |
echo "Building with flags:" platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}" cache_limit=${{ inputs.scons-cache-limit }}
if [ "${{ inputs.target }}" != "editor" ]; then
# Ensure we don't include editor code in export template builds.
rm -rf editor
fi
if [ "${{ github.event.number }}" != "" ]; then
# Set build identifier with pull request number if available. This is displayed throughout the editor.
export BUILD_NAME="gh-${{ github.event.number }}"
else
export BUILD_NAME="gh"
fi
scons platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} "cache_path=${{ inputs.scons-cache }}" cache_limit=${{ inputs.scons-cache-limit }}
ls -l bin/

View File

@@ -1,34 +0,0 @@
name: Restore Godot build cache
description: Restore Godot build cache.
inputs:
cache-name:
description: The cache base name (job name by default).
default: ${{ github.job }}
scons-cache:
description: The SCons cache path.
default: ${{ github.workspace }}/.scons_cache/
runs:
using: composite
steps:
- name: Restore SCons cache directory
uses: actions/cache/restore@v4
with:
path: ${{ inputs.scons-cache }}
key: ${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}
# We try to match an existing cache to restore from it. Each potential key is checked against
# all existing caches as a prefix. E.g. 'linux-template-minimal' would match any cache that
# starts with "linux-template-minimal", such as "linux-template-minimal-master-refs/heads/master-6588a4a29af1621086feac0117d5d4d37af957fd".
#
# We check these prefixes in this order:
#
# 1. The exact match, including the base branch, the commit reference, and the SHA hash of the commit.
# 2. A partial match for the same base branch and the same commit reference.
# 3. A partial match for the same base branch and the base branch commit reference.
# 4. A partial match for the same base branch only (not ideal, matches any PR with the same base branch).
restore-keys: |
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-refs/heads/${{ env.GODOT_BASE_BRANCH }}
${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}

View File

@@ -1,18 +0,0 @@
name: Save Godot build cache
description: Save Godot build cache.
inputs:
cache-name:
description: The cache base name (job name by default).
default: ${{ github.job }}
scons-cache:
description: The SCons cache path.
default: ${{ github.workspace }}/.scons_cache/
runs:
using: composite
steps:
- name: Save SCons cache directory
uses: actions/cache/save@v4
with:
path: ${{ inputs.scons-cache }}
key: ${{ inputs.cache-name }}-${{ env.GODOT_BASE_BRANCH }}-${{ github.ref }}-${{ github.sha }}

View File

@@ -1,20 +0,0 @@
name: Test Godot project converter
description: Test the Godot project converter.
inputs:
bin:
description: The path to the Godot executable
required: true
runs:
using: composite
steps:
- name: Test 3-to-4 conversion
shell: sh
run: |
mkdir converter_test
cd converter_test
touch project.godot
../${{ inputs.bin }} --headless --validate-conversion-3to4
cd ..
rm converter_test -rf

View File

@@ -1,40 +0,0 @@
name: Build godot-cpp
description: Build godot-cpp with the provided options.
inputs:
bin:
description: Path to the Godot binary.
required: true
type: string
scons-flags:
description: Additional SCons flags.
type: string
scons-cache:
description: The SCons cache path.
default: ${{ github.workspace }}/.scons_cache/
type: string
godot-cpp-branch:
description: The godot-cpp branch.
default: master
type: string
runs:
using: composite
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
repository: godotengine/godot-cpp
ref: ${{ inputs.godot-cpp-branch }}
path: godot-cpp
- name: Extract API
shell: sh
run: ${{ inputs.bin }} --headless --dump-gdextension-interface --dump-extension-api
- name: SCons Build
shell: sh
env:
SCONS_CACHE: ${{ inputs.scons-cache }}
run: scons --directory=./godot-cpp/test "gdextension_dir=${{ github.workspace }}" ${{ inputs.scons-flags }}

View File

@@ -1,35 +0,0 @@
name: Setup Python and SCons
description: Setup Python, install the pip version of SCons.
inputs:
python-version:
description: The Python version to use.
default: 3.x
python-arch:
description: The Python architecture.
default: x64
scons-version:
description: The SCons version to use.
default: 4.8.1
runs:
using: composite
steps:
- name: Set up Python 3.x
uses: actions/setup-python@v5
with:
# Semantic version range syntax or exact version of a Python version.
python-version: ${{ inputs.python-version }}
# Optional - x64 or x86 architecture, defaults to x64.
architecture: ${{ inputs.python-arch }}
- name: Setup SCons
shell: bash
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons==${{ inputs.scons-version }}
scons --version
- name: Setup problem matchers
shell: bash
run: echo ::add-matcher::misc/utility/problem-matchers.json

View File

@@ -1,39 +0,0 @@
name: Test Godot project
description: Run the test Godot project.
inputs:
bin:
description: The path to the Godot executable
required: true
runs:
using: composite
steps:
# Download and extract zip archive with project, folder is renamed to be able to easy change used project
- name: Download test project
shell: sh
run: |
wget https://github.com/godotengine/regression-test-project/archive/4.0.zip
unzip 4.0.zip
mv "regression-test-project-4.0" "test_project"
# Editor is quite complicated piece of software, so it is easy to introduce bug here.
- name: Open and close editor (Vulkan)
shell: sh
run: |
xvfb-run ${{ inputs.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt
- name: Open and close editor (GLES3)
shell: sh
run: |
DRI_PRIME=0 xvfb-run ${{ inputs.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt
# Run test project
- name: Run project
shell: sh
run: |
xvfb-run ${{ inputs.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt

View File

@@ -1,22 +0,0 @@
name: Upload Godot artifact
description: Upload the Godot artifact.
inputs:
name:
description: The artifact name.
default: ${{ github.job }}
path:
description: The path to upload.
required: true
default: bin/*
runs:
using: composite
steps:
- name: Upload Godot Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}
# Default is 90 days.
retention-days: 60

View File

@@ -1,129 +0,0 @@
name: 🤖 Android Builds
on:
workflow_call:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes strict_checks=yes
jobs:
build-android:
runs-on: ubuntu-24.04
name: ${{ matrix.name }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- name: Editor (target=editor)
cache-name: android-editor
target: editor
tests: false
sconsflags: arch=arm64 production=yes swappy=yes
cache-limit: 1
- name: Template arm32 (target=template_release, arch=arm32)
cache-name: android-template-arm32
target: template_release
tests: false
sconsflags: arch=arm32 swappy=yes
cache-limit: 1
- name: Template arm64 (target=template_release, arch=arm64)
cache-name: android-template-arm64
target: template_release
tests: false
sconsflags: arch=arm64 swappy=yes
cache-limit: 1
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Java 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Setup Python and SCons
uses: ./.github/actions/godot-deps
- name: Download pre-built Android Swappy Frame Pacing Library
uses: dsaltares/fetch-gh-release-asset@1.1.2
with:
repo: godotengine/godot-swappy
version: tags/from-source-2025-01-31
file: godot-swappy.7z
target: swappy/godot-swappy.7z
- name: Extract pre-built Android Swappy Frame Pacing Library
run: 7za x -y swappy/godot-swappy.7z -o${{github.workspace}}/thirdparty/swappy-frame-pacing
- name: Compilation
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
platform: android
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: ${{ matrix.cache-limit }}
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Generate Godot templates
if: matrix.target == 'template_release'
run: |
cd platform/android/java
./gradlew generateGodotTemplates
cd ../../..
ls -l bin/
- name: Generate Godot editor
if: matrix.target == 'editor'
run: |
cd platform/android/java
./gradlew generateGodotEditor
./gradlew generateGodotHorizonOSEditor
./gradlew generateGodotPicoOSEditor
cd ../../..
ls -l bin/android_editor_builds/
# Separate different editors for multiple artifacts
mkdir horizonos
mv bin/android_editor_builds/*-horizonos-* horizonos
mkdir picoos
mv bin/android_editor_builds/*-picoos-* picoos
- name: Upload artifact
uses: ./.github/actions/upload-artifact
with:
name: ${{ matrix.cache-name }}
- name: Upload artifact (Horizon OS)
if: matrix.target == 'editor'
uses: ./.github/actions/upload-artifact
with:
name: ${{ matrix.cache-name }}-horizonos
path: horizonos
- name: Upload artifact (PICO OS)
if: matrix.target == 'editor'
uses: ./.github/actions/upload-artifact
with:
name: ${{ matrix.cache-name }}-picoos
path: picoos

View File

@@ -1,44 +0,0 @@
name: 🍏 iOS Builds
on:
workflow_call:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes strict_checks=yes
jobs:
ios-template:
runs-on: macos-latest
name: Template (target=template_release)
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
continue-on-error: true
- name: Setup Python and SCons
uses: ./.github/actions/godot-deps
- name: Compilation (arm64)
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }}
platform: ios
target: template_release
tests: false
scons-cache-limit: 1
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
continue-on-error: true
- name: Upload artifact
uses: ./.github/actions/upload-artifact

View File

@@ -1,248 +0,0 @@
name: 🐧 Linux Builds
on:
workflow_call:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
GODOT_CPP_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes strict_checks=yes
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
TSAN_OPTIONS: suppressions=misc/error_suppressions/tsan.txt
UBSAN_OPTIONS: suppressions=misc/error_suppressions/ubsan.txt
jobs:
build-linux:
# Stay one LTS before latest to increase portability of Linux artifacts.
runs-on: ubuntu-22.04
name: ${{ matrix.name }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- name: Editor w/ Mono (target=editor)
cache-name: linux-editor-mono
target: editor
sconsflags: module_mono_enabled=yes
bin: ./bin/godot.linuxbsd.editor.x86_64.mono
build-mono: true
tests: false # Disabled due freeze caused by mix Mono build and CI
doc-test: true
proj-conv: true
api-compat: true
artifact: true
# Validate godot-cpp compatibility on one arbitrary editor build.
godot-cpp: true
cache-limit: 2
- name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)
cache-name: linux-editor-double-sanitizers
target: editor
# Debug symbols disabled as they're huge on this build and we hit the 14 GB limit for runners.
sconsflags: dev_build=yes scu_build=yes debug_symbols=no precision=double use_asan=yes use_ubsan=yes linker=gold
bin: ./bin/godot.linuxbsd.editor.dev.double.x86_64.san
build-mono: false
tests: true
proj-test: true
# Skip 2GiB artifact speeding up action.
artifact: false
cache-limit: 7
- name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
cache-name: linux-editor-llvm-sanitizers
target: editor
sconsflags: dev_build=yes use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
bin: ./bin/godot.linuxbsd.editor.dev.x86_64.llvm.san
build-mono: false
tests: true
# Skip 2GiB artifact speeding up action.
artifact: false
# Test our oldest supported SCons/Python versions on one arbitrary editor build.
legacy-scons: true
cache-limit: 7
- name: Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)
cache-name: linux-editor-thread-sanitizer
target: editor
tests: true
sconsflags: dev_build=yes use_tsan=yes use_llvm=yes linker=lld
bin: ./bin/godot.linuxbsd.editor.dev.x86_64.llvm.san
build-mono: false
# Skip 2GiB artifact speeding up action.
artifact: false
cache-limit: 5
- name: Template w/ Mono, release (target=template_release, tests=yes)
cache-name: linux-template-mono
target: template_release
sconsflags: module_mono_enabled=yes
bin: ./bin/godot.linuxbsd.template_release.x86_64.mono
build-mono: false
tests: true
artifact: true
cache-limit: 1
- name: Template w/ Mono, debug (target=template_debug, tests=yes)
cache-name: linux-template-mono-debug
target: template_debug
sconsflags: module_mono_enabled=yes
bin: ./bin/godot.linuxbsd.template_debug.x86_64.mono
build-mono: false
tests: true
artifact: true
cache-limit: 1
- name: Minimal template (target=template_release, tests=yes, everything disabled)
cache-name: linux-template-minimal
target: template_release
sconsflags: modules_enabled_by_default=no disable_3d=yes disable_advanced_gui=yes deprecated=no minizip=no
bin: ./bin/godot.linuxbsd.template_release.x86_64
tests: true
artifact: true
cache-limit: 1
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
# Need newer mesa for lavapipe to work properly.
- name: Linux dependencies for tests
if: matrix.proj-test
run: |
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EB8B81E14DA65431D7504EA8F63F0F2B90935439
sudo add-apt-repository "deb https://ppa.launchpadcontent.net/kisak/turtle/ubuntu jammy main"
sudo apt-get install -qq mesa-vulkan-drivers
# TODO: Figure out somehow how to embed this one.
- name: wayland-scanner dependency
run: |
sudo apt-get install libwayland-bin
- name: Free disk space on runner
run: |
echo "Disk usage before:" && df -h
sudo rm -rf /usr/local/lib/android
echo "Disk usage after:" && df -h
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Setup Python and SCons
if: "!matrix.legacy-scons"
uses: ./.github/actions/godot-deps
- name: Setup Python and SCons (legacy versions)
if: matrix.legacy-scons
uses: ./.github/actions/godot-deps
with:
# Sync with Ensure*Version in SConstruct.
python-version: 3.8
scons-version: 4.0
- name: Force remove preinstalled .NET SDKs
if: matrix.build-mono
run: |
sudo rm -rf /usr/share/dotnet/sdk/*
- name: Setup older .NET SDK as baseline
if: matrix.build-mono
uses: actions/setup-dotnet@v4
with:
# Targeting the oldest version we want to support to ensure it still builds.
dotnet-version: 8.0.100
- name: Compilation
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
platform: linuxbsd
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: ${{ matrix.cache-limit }}
- name: Compilation (godot-cpp)
uses: ./.github/actions/godot-cpp-build
if: matrix.godot-cpp
with:
bin: ${{ matrix.bin }}
scons-flags: target=template_debug dev_build=yes verbose=yes
godot-cpp-branch: ${{ env.GODOT_CPP_BRANCH }}
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Generate C# glue
if: matrix.build-mono
run: |
${{ matrix.bin }} --headless --generate-mono-glue ./modules/mono/glue
- name: Build .NET solutions
if: matrix.build-mono
run: |
dotnet --info
./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd --werror
- name: Prepare artifact
if: matrix.artifact
run: |
strip bin/godot.*
chmod +x bin/godot.*
- name: Upload artifact
uses: ./.github/actions/upload-artifact
if: matrix.artifact
with:
name: ${{ matrix.cache-name }}
- name: Unit tests
if: matrix.tests
run: |
${{ matrix.bin }} --version
${{ matrix.bin }} --help
${{ matrix.bin }} --headless --test --force-colors
- name: .NET source generators tests
if: matrix.build-mono
run: |
dotnet test modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests
# Check class reference
- name: Check for class reference updates
if: matrix.doc-test
run: |
echo "Running --doctool to see if this changes the public API without updating the documentation."
echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true
git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$'
# Check API backwards compatibility
- name: Check for GDExtension compatibility
if: matrix.api-compat
run: |
./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}"
# Download and run the test project
- name: Test Godot project
uses: ./.github/actions/godot-project-test
if: matrix.proj-test
with:
bin: ${{ matrix.bin }}
# Test the project converter
- name: Test project converter
uses: ./.github/actions/godot-converter-test
if: matrix.proj-conv
with:
bin: ${{ matrix.bin }}

View File

@@ -1,95 +0,0 @@
name: 🍎 macOS Builds
on:
workflow_call:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes strict_checks=yes
jobs:
build-macos:
runs-on: macos-latest
name: ${{ matrix.name }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- name: Editor (target=editor, tests=yes)
cache-name: macos-editor
target: editor
tests: true
bin: ./bin/godot.macos.editor.universal
cache-limit: 1
- name: Template (target=template_release, tests=yes)
cache-name: macos-template
target: template_release
tests: true
sconsflags: debug_symbols=no
bin: ./bin/godot.macos.template_release.universal
cache-limit: 1
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Setup Python and SCons
uses: ./.github/actions/godot-deps
- name: Setup Vulkan SDK
run: |
sh misc/scripts/install_vulkan_sdk_macos.sh
- name: Compilation (x86_64)
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} arch=x86_64
platform: macos
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: 0 # Only cap on second run to avoid purging unnecessarily
- name: Compilation (arm64)
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} arch=arm64
platform: macos
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: ${{ matrix.cache-limit }}
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Prepare artifact
run: |
lipo -create ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64 -output ./bin/godot.macos.${{ matrix.target }}.universal
rm ./bin/godot.macos.${{ matrix.target }}.x86_64 ./bin/godot.macos.${{ matrix.target }}.arm64
strip bin/godot.*
chmod +x bin/godot.*
- name: Upload artifact
uses: ./.github/actions/upload-artifact
with:
name: ${{ matrix.cache-name }}
- name: Unit tests
if: matrix.tests
run: |
${{ matrix.bin }} --version
${{ matrix.bin }} --help
${{ matrix.bin }} --test --force-colors

View File

@@ -1,46 +0,0 @@
name: 🔗 GHA
on: [push, pull_request, merge_group]
concurrency:
group: ${{ github.workflow }}|${{ github.ref_name }}
cancel-in-progress: true
jobs:
# First stage: Only static checks, fast and prevent expensive builds from running.
static-checks:
if: "!vars.DISABLE_GODOT_CI"
name: 📊 Static checks
uses: ./.github/workflows/static_checks.yml
# Second stage: Run all the builds and some of the tests.
android-build:
name: 🤖 Android
needs: static-checks
uses: ./.github/workflows/android_builds.yml
ios-build:
name: 🍏 iOS
needs: static-checks
uses: ./.github/workflows/ios_builds.yml
linux-build:
name: 🐧 Linux
needs: static-checks
uses: ./.github/workflows/linux_builds.yml
macos-build:
name: 🍎 macOS
needs: static-checks
uses: ./.github/workflows/macos_builds.yml
windows-build:
name: 🏁 Windows
needs: static-checks
uses: ./.github/workflows/windows_builds.yml
web-build:
name: 🌐 Web
needs: static-checks
uses: ./.github/workflows/web_builds.yml

View File

@@ -1,60 +0,0 @@
name: 📊 Static Checks
on:
workflow_call:
jobs:
static-checks:
name: Code style, file formatting, and docs
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Install APT dependencies
run: |
sudo apt update
sudo apt install -y libxml2-utils
- name: Install Python dependencies and general setup
run: |
pip3 install pytest==7.1.2
git config diff.wsErrorHighlight all
- name: Get changed files
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
files=$(git diff-tree --no-commit-id --name-only -r HEAD^1..HEAD 2> /dev/null || true)
elif [ "${{ github.event_name }}" == "push" -a "${{ github.event.forced }}" == "false" -a "${{ github.event.created }}" == "false" ]; then
files=$(git diff-tree --no-commit-id --name-only -r ${{ github.event.before }}..${{ github.event.after }} 2> /dev/null || true)
fi
echo "$files" >> changed.txt
cat changed.txt
files=$(echo "$files" | grep -v 'thirdparty' | xargs -I {} sh -c 'echo "\"./{}\""' | tr '\n' ' ')
echo "CHANGED_FILES=$files" >> $GITHUB_ENV
# This needs to happen before Python and npm execution; it must happen before any extra files are written.
- name: .gitignore checks (gitignore_check.sh)
run: |
bash ./misc/scripts/gitignore_check.sh
- name: Style checks via pre-commit
uses: pre-commit/action@v3.0.1
with:
extra_args: --files ${{ env.CHANGED_FILES }}
- name: Python builders checks via pytest
run: |
pytest ./tests/python_build
- name: Class reference schema checks
run: |
xmllint --quiet --noout --schema doc/class.xsd doc/classes/*.xml modules/*/doc_classes/*.xml platform/*/doc_classes/*.xml
- name: Run C compiler on `gdextension_interface.h`
run: |
gcc -c core/extension/gdextension_interface.h

View File

@@ -1,79 +0,0 @@
name: 🌐 Web Builds
on:
workflow_call:
# Global Settings
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no use_closure_compiler=yes strict_checks=yes
EM_VERSION: 3.1.64
jobs:
web-template:
runs-on: ubuntu-24.04
name: ${{ matrix.name }}
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
- name: Template w/ threads (target=template_release, threads=yes)
cache-name: web-template
target: template_release
sconsflags: threads=yes
tests: false
artifact: true
- name: Template w/o threads (target=template_release, threads=no)
cache-name: web-nothreads-template
target: template_release
sconsflags: threads=no
tests: false
artifact: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v14
with:
version: ${{ env.EM_VERSION }}
no-cache: true
- name: Verify Emscripten setup
run: |
emcc -v
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Setup Python and SCons
uses: ./.github/actions/godot-deps
- name: Compilation
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
platform: web
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: 0.5
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Upload artifact
uses: ./.github/actions/upload-artifact
if: matrix.artifact
with:
name: ${{ matrix.cache-name }}

View File

@@ -1,121 +0,0 @@
name: 🏁 Windows Builds
on:
workflow_call:
# Global Settings
# SCONS_CACHE for windows must be set in the build environment
env:
# Used for the cache key. Add version suffix to force clean build.
GODOT_BASE_BRANCH: 4.4
SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes d3d12=yes strict_checks=yes "angle_libs=${{ github.workspace }}/"
SCONS_CACHE_MSVC_CONFIG: true
jobs:
build-windows:
# Windows 10 with latest image
runs-on: windows-latest
name: ${{ matrix.name }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
include:
- name: Editor (target=editor, tests=yes)
cache-name: windows-editor
target: editor
tests: true
# Skip debug symbols, they're way too big with MSVC.
sconsflags: debug_symbols=no vsproj=yes vsproj_gen_only=no windows_subsystem=console
bin: ./bin/godot.windows.editor.x86_64.exe
compiler: msvc
cache-limit: 2
- name: Editor w/ clang-cl (target=editor, tests=yes, use_llvm=yes)
cache-name: windows-editor-clang
target: editor
tests: true
sconsflags: debug_symbols=no windows_subsystem=console use_llvm=yes
bin: ./bin/godot.windows.editor.x86_64.llvm.exe
compiler: clang
cache-limit: 1
- name: Template (target=template_release, tests=yes)
cache-name: windows-template
target: template_release
tests: true
sconsflags: debug_symbols=no
bin: ./bin/godot.windows.template_release.x86_64.console.exe
compiler: msvc
cache-limit: 2
- name: Template w/ GCC (target=template_release, tests=yes, use_mingw=yes)
cache-name: windows-template-gcc
# MinGW takes MUCH longer to compile; save time by only targeting Template.
target: template_release
tests: true
sconsflags: debug_symbols=no use_mingw=yes
bin: ./bin/godot.windows.template_release.x86_64.console.exe
compiler: gcc
cache-limit: 1
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
- name: Restore Godot build cache
uses: ./.github/actions/godot-cache-restore
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Setup Python and SCons
uses: ./.github/actions/godot-deps
- name: Download Direct3D 12 SDK components
run: python ./misc/scripts/install_d3d12_sdk_windows.py
- name: Download pre-built ANGLE static libraries
uses: dsaltares/fetch-gh-release-asset@1.1.2
with:
repo: godotengine/godot-angle-static
version: tags/chromium/6601.2
file: godot-angle-static-x86_64-${{ matrix.compiler == 'gcc' && 'gcc' || 'msvc' }}-release.zip
target: angle/angle.zip
- name: Extract pre-built ANGLE static libraries
run: Expand-Archive -Force angle/angle.zip ${{ github.workspace }}/
- name: Compilation
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
platform: windows
target: ${{ matrix.target }}
tests: ${{ matrix.tests }}
scons-cache-limit: ${{ matrix.cache-limit }}
- name: Save Godot build cache
uses: ./.github/actions/godot-cache-save
with:
cache-name: ${{ matrix.cache-name }}
continue-on-error: true
- name: Prepare artifact
if: matrix.compiler == 'msvc'
run: |
Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
- name: Upload artifact
if: matrix.compiler == 'msvc'
uses: ./.github/actions/upload-artifact
with:
name: ${{ matrix.cache-name }}
- name: Unit tests
if: matrix.tests
run: |
${{ matrix.bin }} --version
${{ matrix.bin }} --help
${{ matrix.bin }} --test --force-colors

481
.gitignore vendored
View File

@@ -1,290 +1,120 @@
# Godot .gitignore config
#
# Aims to encompass the most commonly found files that we don't want committed
# to Git, such as compilation output, IDE specific files, etc.
#
# It doesn't cover *all* thirdparty IDE extensions under the sun so if you have
# specific needs covered here, you can add them to:
# .git/info/exclude
#
# Or contribute them to this file if they're common enough that a good number of
# users would benefit from the shared rules.
#
# This file is organized by sections, with subsections ordered alphabetically.
# - Build configuration
# - Godot generated files
# - General build output
# - IDE and tool specific
# - Visual Studio specific
# - OS specific
###########################
### Build configuration ###
###########################
/custom.py
misc/hooks/pre-commit-custom-*
#############################
### Godot generated files ###
#############################
# Buildsystem
bin
# Godot auto generated files
*.gen.*
compile_commands.json
platform/windows/godot_res.res
# Ninja build files
*.ninja
.ninja/
run_ninja_env.bat
# Documentation generated by doxygen or from classes.xml
doc/_build/
# Generated by Godot binary
.import/
/gdextension_interface.h
extension_api.json
logs/
# Javascript specific
*.bc
# Generated by unit tests
tests/data/*.translation
tests/data/crypto/out*
# Android specific
platform/android/java/build.gradle
platform/android/java/.gradle
platform/android/java/.gradletasknamecache
platform/android/java/local.properties
platform/android/java/project.properties
platform/android/java/build.gradle
platform/android/java/AndroidManifest.xml
platform/android/java/libs/*
platform/android/java/assets
platform/android/java/.idea/*
platform/android/java/*.iml
############################
### General build output ###
############################
# C/C++ generated
# General c++ generated files
*.lib
*.o
*.ox
*.a
*.ax
*.d
*.dll
*.lib
*.lo
*.o
*.os
*.ox
*.Plo
*.so
# Binutils tmp linker output of the form "stXXXXXX" where "X" is alphanumeric
st[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]
*.os
*.Plo
*.lo
# Python development
.venv
venv
# Python generated
__pycache__/
*.pyc
# Python modules
.*_cache/
# Documentation
doc/_build/
# Android
.gradle/
local.properties
*.iml
.gradletasknamecache
project.properties
platform/android/java/*/.cxx/
platform/android/java/*/build/
platform/android/java/*/libs/
# iOS
*.dSYM
# Web platform
*.bc
platform/web/node_modules/
# Misc
*.debug
#############################
### IDE and tool specific ###
#############################
# Automake
# Libs generated files
.deps/*
.dirstamp
# ccls
.ccls-cache/
# clangd
.clangd/
.cache/
# CLion
cmake-build-debug
# Code::Blocks
*.cbp
*.layout
*.depend
# CodeLite
*.project
*.workspace
.codelite/
# Cppcheck
*.cppcheck
cppcheck-cppcheck-build-dir/
# Eclipse CDT
.cproject
.settings/
*.pydevproject
*.launch
# Emacs
\#*\#
.\#*
# GCOV code coverage
*.gcda
*.gcno
# Geany
*.geany
.geanyprj
# Gprof
# Gprof output
gmon.out
# Jetbrains IDEs
.idea/
.fleet/
# Vim temp files
*.swo
*.swp
# Kate
*.kate-swp
.kateproject.build
# Kdevelop
*.kdev4
# Qt Creator
# QT project files
*.config
*.creator
*.creator.*
*.files
*.includes
*.cflags
*.cxxflags
# SCons
# Eclipse CDT files
.cproject
.settings/
# Geany/geany-plugins files
*.geany
.geanyprj
# Misc
.DS_Store
logs/
# for projects that use SCons for building: http://http://www.scons.org/
.sconf_temp
.sconsign*.dblite
.scons_env.json
.scons_node_count
.sconsign.dblite
*.pyc
# Sourcetrail
*.srctrl*
# Tags
# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
TAGS
!TAGS/
tags
*.tags
!tags/
gtags.files
GTAGS
GRTAGS
GPATH
cscope.files
cscope.out
cscope.in.out
cscope.po.out
# Vim
*.swo
*.swp
# Visual Studio Code
.vscode/
*.code-workspace
.history/
# Xcode
xcuserdata/
*.xcscmblueprint
*.xccheckout
*.xcodeproj/*
!misc/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
##############################
### Visual Studio specific ###
##############################
# https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# Ignore Visual Studio temporary files, build results, and
# files generated by popular Visual Studio add-ons.
# Actual VS project files we don't use
*.sln
*.vcxproj*
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
*.sln
*.vcxproj*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
build/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
*.debug
*.dSYM
# Do not ignore arch-specific folders anywhere under thirdparty libraries
!thirdparty/**/x64/
!thirdparty/**/x86/
!thirdparty/**/arm/
!thirdparty/**/arm64/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
thirdparty/swappy-frame-pacing/arm64-v8a/abi.json
thirdparty/swappy-frame-pacing/armeabi-v7a/abi.json
thirdparty/swappy-frame-pacing/x86/abi.json
thirdparty/swappy-frame-pacing/x86_64/abi.json
# Hints for improving IntelliSense, created together with VS project
cpp.hint
# Visual Studio 2015/2017 cache/options directory
.vs/
# Visualizers for the VS debugger
*.natvis
# Visual Studio 2017 auto generated files
Generated\ Files/
#NUNIT
*.VisualState.xml
TestResult.xml
# Files built by Visual Studio
*.o
*.a
*_i.c
*_p.c
*_h.h
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
@@ -294,9 +124,7 @@ Generated\ Files/
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
@@ -304,85 +132,182 @@ Generated\ Files/
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.opendb
*.VC.VC.opendb
enc_temp_folder/
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# CodeLite project files
*.project
*.workspace
.codelite/
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/*
## TODO: If the tool you use requires repositories.config, also uncomment the next line
#!packages/repositories.config
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
enc_temp_folder/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
node_modules/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
# KDE
.directory
#Kdevelop project files
*.kdev4
# xCode
xcuserdata
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# Hint file for IntelliSense
cpp.hint
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
###################
### OS specific ###
###################
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Linux
*~
.directory
# Microsoft Fakes
FakesAssemblies/
# macOS
.DS_Store
__MACOSX
Godot.app
# =========================
# Windows detritus
# =========================
# Windows
# https://github.com/github/gitignore/blob/main/Global/Windows.gitignore
[Tt]humbs.db
[Tt]humbs.db:encryptable
# Windows image file caches
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
*.stackdump
[Dd]esktop.ini
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
*.cab
*.msi
*.msix
*.msm
*.msp
*.lnk
*.generated.props
logo.h
*.autosave
# https://github.com/github/gitignore/blob/master/Global/Tags.gitignore
# Ignore tags created by etags, ctags, gtags (GNU global) and cscope
TAGS
!TAGS/
tags
!tags/
gtags.files
GTAGS
GRTAGS
GPATH
cscope.files
cscope.out
cscope.in.out
cscope.po.out
godot.creator.*
projects/
platform/windows/godot_res.res
# Visual Studio 2017 and Visual Studio Code workspace folder
/.vs
/.vscode
# Scons progress indicator
.scons_node_count

190
.mailmap
View File

@@ -1,195 +1,29 @@
Aaron Record <aaronjrecord@gmail.com>
ajreckof <66184050+ajreckof@users.noreply.github.com> <tbonhoure@ymail.com>
Alexander Hartmann <alex.hart.278@gmail.com>
Alexander Holland <alexander.holland@live.de>
Alexander Holland <alexander.holland@live.de> <alexander.holland@haw-hamburg.de>
Alexander Holland <alexander.holland@live.de> <AlexHolly>
Alfred Reinold Baudisch <alfred@alfredbaudisch.com>
Andrea Catania <info@andreacatania.com>
Anish Bhobe <anishbhobe@hotmail.com>
Anutrix <numaanzaheerahmed@yahoo.com>
Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com>
Andreas Haas <liu.gam3@gmail.com>
Andreas Haas <Hinsbart@users.noreply.github.com>
Andreas Haas <entenflugstuhl@gmail.com>
Ariel Manzur <ariel@godotengine.org>
Ariel Manzur <ariel@godotengine.org> <puntob@gmail.com>
Ariel Manzur <ariel@godotengine.org> <punto@godotengine.org>
Ariel Manzur <ariel@godotengine.org> <ariel@okamstudio.com>
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini.local>
Ariel Manzur <ariel@godotengine.org> <punto@Ariels-Mac-mini-2.local>
Arman Elgudzhyan <48544263+puchik@users.noreply.github.com>
A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> <over999ships@gmail.com>
Ariel Manzur <ariel@okamstudio.com>
Bastiaan Olij <mux213@gmail.com>
Benjamin <mafortion.benjamin@gmail.com>
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.de>
Bernhard Liebl <Bernhard.Liebl@gmx.org> <poke1024@gmx.org>
Bruno Lourenço <madequa@users.noreply.github.com> <bmlourenco@gmail.com>
Chaosus <chaosus89@gmail.com>
ChibiDenDen <pdaniq@gmail.com>
Chris Bradfield <chris@kidscancode.org> <cb@scribe.net>
Clay John <claynjohn@gmail.com>
Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca>
CookieBadger <emil.dobetsberger@gmail.com>
Dana Olson <dana@shineuponthee.com> <adolson@gmail.com>
dankan1890 <mewuidev2@gmail.com>
Daniel J. Ramirez <djrmuv@gmail.com>
Dario <dariosamo@gmail.com>
David Cambré <david.cambre@gmail.com> <David.Cambre@gmail.com>
DmitriySalnikov <salnikov.mine@yandex.ru>
DmitriySalnikov <salnikov.mine@yandex.ru> <dimokgamer@gmail.com>
Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
DeeJayLSP <djlsplays@gmail.com> <60024671+DeeJayLSP@users.noreply.github.com>
Emmanuel Barroga <emmanuelbarroga@gmail.com>
Eric M <itsjusteza@gmail.com>
Eric Rybicki <info@ericrybicki.com> <stratos695@googlemail.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com>
Erik Selecký <35656626+rxlecky@users.noreply.github.com> <35656626+SeleckyErik@users.noreply.github.com>
Eveline Jarosz <marqin.pl@gmail.com>
Eveline Jarosz <marqin.pl@gmail.com> <marqin.pl+git@gmail.com>
Fabian <supagu@gmail.com>
Ferenc Arn <tagcup@yahoo.com>
Ferenc Arn <tagcup@yahoo.com> <tagcup@users.noreply.github.com>
FireForge <67974470+fire-forge@users.noreply.github.com> <isaacr.7.2005@gmail.com>
Florian Kothmeier <floriankothmeier@web.de>
foxydevloper <12120644+foxydevloper@users.noreply.github.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@fb.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@meta.com>
Bernhard Liebl <poke1024@gmx.de>
Bernhard Liebl <poke1024@gmx.org>
Geequlim <geequlim@gmail.com>
Gilles Roudiere <gilles.roudiere@gmail.com>
Gilles Roudiere <gilles.roudiere@gmail.com> <gilles.roudiere@laas.fr>
Gordon MacPherson <gordon@gordonite.tech>
Guilherme Felipe <guilhermefelipecgs@gmail.com>
Hakim <hakim.rouatbi@gmail.com>
Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
HaSa1002 <johawitt@outlook.de>
Hein-Pieter van Braam-Stewart <hp@tmm.cx>
Hugo Locurcio <hugo.locurcio@hugo.pro>
Hugo Locurcio <hugo.locurcio@hugo.pro> <hugo.l@openmailbox.org>
Hugo Locurcio <hugo.locurcio@hugo.pro> <Calinou@users.noreply.github.com>
Hugo Locurcio <hugo.locurcio@hugo.pro> Calinou <calinou@opmbx.org>
Ian Bishop <ianb96@gmail.com>
Ignacio Etcheverry <ignalfonsore@gmail.com>
Ignacio Etcheverry <ignalfonsore@gmail.com> <neikeq@users.noreply.github.com>
Ilaria Cislaghi <cislaghi.ilaria@gmail.com>
Ilaria Cislaghi <cislaghi.ilaria@gmail.com> <ilaria.cislaghi@simedis.com>
Indah Sylvia <ISylvox@yahoo.com>
Ivan Shakhov <ivan.shakhov@jetbrains.com> <Ivan.Shakhov@jetbrains.com>
Ivan Shakhov <ivan.shakhov@jetbrains.com> <van800@gmail.com>
iwek <miwanczuk7@gmail.com>
J08nY <johny@neuromancer.sk> <jancar.jj@gmail.com>
J08nY <johny@neuromancer.sk> <J08nY@users.noreply.github.com>
Jake Young <young9003@gmail.com>
Jakub Grzesik <kubecz3k@gmail.com>
Jakub Marcowski <chubercikbattle@gmail.com> <01158831@pw.edu.pl>
Jakub Marcowski <chubercikbattle@gmail.com> <37378746+Chubercik@users.noreply.github.com>
janglee <merupatel123@gmail.com>
Jason Knight <00jknight@gmail.com> <jason@winterpixel.com>
Jean-Michel Bernard <jmb462@gmail.com>
Jérôme Gully <jerome.gully0@gmail.com>
JFonS <joan.fonssanchez@gmail.com>
jitspoe <jitspoe@yahoo.com> <jitspoeAyahoooDcom>
Johan Aires Rastén <johan@oljud.se>
Juan Linietsky <reduzio@gmail.com>
Juan Linietsky <reduzio@gmail.com> <juan@godotengine.org>
Juan Linietsky <reduzio@gmail.com> <juan@okamstudio.com>
Juan Linietsky <reduzio@gmail.com> <reduz@Juans-MBP.fibertel.com.ar>
Juan Linietsky <reduzio@gmail.com> <red@kyoko>
Juan Linietsky <juan@okamstudio.com>
Juan Linietsky <reduz@Juans-MBP.fibertel.com.ar>
Julian Murgia <the.straton@gmail.com>
Kanabenki <lucien.menassol@gmail.com> <18357657+Kanabenki@users.noreply.github.com>
karroffel <therzog@mail.de>
karroffel <therzog@mail.de> <thomas.herzog@mail.com>
karroffel <therzog@mail.de> <thomas.herzog@simedis.com>
Kasper Arnklit Frandsen <kasper.arnklit@gmail.com>
Kelly Thomas <kelly.thomas@hotmail.com.au>
Kongfa Waroros <gongpha@hotmail.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com> <fire@users.noreply.github.com>
kleonc <9283098+kleonc@users.noreply.github.com> <kleonc@users.noreply.github.com>
Leon Krause <lk@leonkrause.com> <eska@eska.me>
Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
Liz Haas <27thLiz@gmail.com>
Liz Haas <27thLiz@gmail.com> <liu.gam3@gmail.com>
Liz Haas <27thLiz@gmail.com> <hinsbart@gmail.com>
Liz Haas <27thLiz@gmail.com> <hinsbart@users.noreply.github.com>
Liz Haas <27thLiz@gmail.com> <entenflugstuhl@gmail.com>
Logan Lang <devloglogan@gmail.com>
Manuele Finocchiaro <m4nu3lf@gmail.com>
Manuel Strey <manuel.strey@gmx.de>
Marcel Admiraal <madmiraal@users.noreply.github.com>
Leon Krause <eska@eska.me>
Leon Krause <eska@eska.me> <eska014@users.noreply.github.com>
Marcelo Fernandez <marcelofg55@gmail.com>
Marcin Zawiejski <dragmz@gmail.com>
Marcus Elg <marcusaccounts@yahoo.se>
Mariano Javier Suligoy <marianognu.easyrpg@gmail.com>
Mario Schlack <m4r10.5ch14ck@gmail.com>
Mark DiBarry <markdibarry@protonmail.com>
marxin <mliska@suse.cz>
marynate <mary.w.nate@gmail.com> <marynate@github.com>
Mateo Kuruk Miccino <mateomiccino@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com>
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
MewPurPur <mew.pur.pur@abv.bg>
Michael Alexsander <michaelalexsander@protonmail.com>
Micky <micheledevita2@gmail.com> <66727710+Mickeon@users.noreply.github.com>
Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com>
Nathan Lovato <nathan@gdquest.com>
Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com>
Nazarii <nazarii.yablonskyi.pp.2022@lpnu.ua>
Nicholas Huelin <62965063+SirQuartz@users.noreply.github.com>
Nils ANDRÉ-CHANG <nils@nilsand.re>
Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com>
Nông Văn Tình <vannongtinh@gmail.com>
Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt>
ocean (they/them) <anvilfolk@gmail.com>
Pawel Kowal <pkowal1982@gmail.com>
Pedro J. Estébanez <pedrojrulez@gmail.com> <RandomShaper@users.noreply.github.com>
Patrick Exner <patrick.exner1@web.de>
Patrick <firefly2442@gmail.com>
Paul Batty <p_batty@hotmail.co.uk>
Paul Batty <p_batty@hotmail.co.uk> <Paulb23@users.noreply.github.com>
Pāvels Nadtočajevs <7645683+bruvzg@users.noreply.github.com>
Pawel Kowal <pkowal1982@gmail.com> <pawel.kowal@javart.eu>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Pieter-Jan Briers <pieterjan.briers+git@gmail.com> <pieterjan.briers@gmail.com>
Poommetee Ketson <poommetee@protonmail.com>
Przemysław Gołąb (n-pigeon) <golab.przemyslaw@gmail.com>
Radiant <69520693+RadiantUwU@users.noreply.github.com> <i.like.using.discord@gmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com>
Rafał Mikrut <mikrutrafal@protonmail.com> <mikrutrafal54@gmail.com>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@posteo.de>
Ralf Hölzemer <r.hoelzemer@posteo.de> <rollenrolm@users.noreply.github.com>
Ramesh Ravone <ramesh.maran443@gmail.com>
RaphaelHunter <raphael10241024@gmail.com>
RaphaelHunter <raphael10241024@gmail.com> <Raphael10241024@gmail.com>
RaphaelHunter <raphael10241024@gmail.com> <raphael20141024@gmail.com>
Rémi Verschelde <rverschelde@gmail.com> <remi@verschelde.fr>
Rhody Lugo <rhodylugo@gmail.com> <rhodylugo@me.com>
Ricardo Subtil <ricasubtil@gmail.com>
Rindbee <idleman@yeah.net>
Riteo Siuga <riteo@posteo.net>
Robin Hübner <profan@prfn.se> <robinhubner@gmail.com>
romulox_x <romulox_x@yahoo.com>
Rudolph Bester <Rudolph.f.Bester@gmail.com> <Rudolph.f.bester@gmail.com>
rune-scape <allie.smith.epic@gmail.com>
rune-scape <allie.smith.epic@gmail.com> <spartacrafter@gmail.com>
Ruslan Mustakov <r.mustakov@gmail.com> <ruslan.mustakov@xored.com>
Saracen <SaracenOne@gmail.com>
sheepandshepherd <sheepandshepherd@hotmail.com> <sheepandshepherd@users.noreply.github.com>
Silc 'Tokage' Renew <tokage.it.lab@gmail.com>
Silc 'Tokage' Renew <tokage.it.lab@gmail.com> <61938263+TokageItLab@users.noreply.github.com>
Swarnim Arun <swarnimarun11@gmail.com>
TechnoPorg <jonah.janzen@gmail.com> <69441745+TechnoPorg@users.noreply.github.com>
tetrapod00 <145553014+tetrapod00@users.noreply.github.com>
Theo Hallenius <redsymbzone@hotmail.com>
Tomasz Chabora <kobewi4e@gmail.com>
Twarit <wtwarit@gmail.com>
Vitika9 <vitika.program@gmail.com>
V.VamsiKrishna <vk@bsb.in> <vamsikrishna.v@gmail.com>
Wilhem Barbier <nounoursheureux@openmailbox.org> <wilhem.b@free.fr>
Wilhem Barbier <nounoursheureux@openmailbox.org> <schtroumps31@gmail.com>
Will Nations <willnationsdev@gmail.com>
yg2f <yoann@terminajones.com>
Yuri Sizov <yuris@humnom.net> <pycbouh@users.noreply.github.com>
Yuri Sizov <yuris@humnom.net> <yaschik4ilicha@gmail.com>
Zae <zaevi@live.com>
Zak Stam <zakscomputers@hotmail.com>
Thomas Herzog <therzog@mail.de>
Zher Huei Lee <lee.zh.92@gmail.com>

View File

@@ -1,192 +0,0 @@
default_language_version:
python: python3
exclude: |
(?x)^(
.*thirdparty/.*|
.*-so_wrap\.(h|c)|
platform/android/java/editor/src/main/java/com/android/.*|
platform/android/java/lib/src/com/google/.*
)$
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v19.1.3
hooks:
- id: clang-format
files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java)$
types_or: [text]
exclude: ^tests/python_build/.*
- id: clang-format
name: clang-format-glsl
files: \.glsl$
types_or: [text]
exclude: ^tests/python_build/.*
args: [-style=file:misc/utility/clang_format_glsl.yml]
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.3.5
hooks:
- id: clang-tidy
files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java|glsl)$
args: [--fix, --quiet, --use-color]
types_or: [text]
exclude: ^tests/python_build/.*
additional_dependencies: [clang-tidy==19.1.0]
require_serial: true
stages: [manual] # Not automatically triggered, invoked via `pre-commit run --hook-stage manual clang-tidy`
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.4
hooks:
- id: ruff
args: [--fix]
files: (\.py|SConstruct|SCsub)$
types_or: [text]
- id: ruff-format
files: (\.py|SConstruct|SCsub)$
types_or: [text]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.14.1
hooks:
- id: mypy
files: \.py$
types_or: [text]
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies: [tomli]
### Requires Docker; look into alternative implementation.
# - repo: https://github.com/comkieffer/pre-commit-xmllint.git
# rev: 1.0.0
# hooks:
# - id: xmllint
# language: docker
# types_or: [text]
# files: ^(doc/classes|.*/doc_classes)/.*\.xml$
# args: [--schema, doc/class.xsd]
- repo: local
hooks:
- id: make-rst
name: make-rst
language: python
entry: python doc/tools/make_rst.py
args: [doc/classes, modules, platform, --dry-run, --color]
pass_filenames: false
files: ^(doc/classes|.*/doc_classes)/.*\.xml$
- id: doc-status
name: doc-status
language: python
entry: python doc/tools/doc_status.py
args: [doc/classes, modules/*/doc_classes, platform/*/doc_classes, -c]
pass_filenames: false
files: ^(doc/classes|.*/doc_classes)/.*\.xml$
- id: eslint
name: eslint
language: node
entry: eslint
files: ^(platform/web/js/|modules/|misc/dist/html/).*\.(js|html)$
args:
- --fix
- --no-warn-ignored
- --no-config-lookup
- --config
- platform/web/eslint.config.cjs
additional_dependencies:
- "@eslint/js@^9.3.0"
- "@html-eslint/eslint-plugin@^0.24.1"
- "@html-eslint/parser@^0.24.1"
- "@stylistic/eslint-plugin@^2.1.0"
- eslint@^9.3.0
- eslint-plugin-html@^8.1.1
- globals@^15.3.0
- espree@^10.0.1
- id: jsdoc
name: jsdoc
language: node
entry: jsdoc
files: ^platform/web/js/engine/(engine|config|features)\.js$
args:
- --template
- platform/web/js/jsdoc2rst/
- platform/web/js/engine/engine.js
- platform/web/js/engine/config.js
- platform/web/js/engine/features.js
- --destination
- ""
- -d
- dry-run
pass_filenames: false
additional_dependencies: [jsdoc@^4.0.3]
- id: svgo
name: svgo
language: node
entry: svgo
files: \.svg$
args: [--quiet, --config, misc/utility/svgo.config.mjs]
additional_dependencies: [svgo@3.3.2]
- id: copyright-headers
name: copyright-headers
language: python
entry: python misc/scripts/copyright_headers.py
files: \.(c|h|cpp|hpp|cc|hh|cxx|hxx|m|mm|inc|java)$
exclude: |
(?x)^(
core/math/bvh_.*\.inc|
platform/(?!android|ios|linuxbsd|macos|web|windows)\w+/.*|
platform/android/java/lib/src/org/godotengine/godot/gl/GLSurfaceView\.java|
platform/android/java/lib/src/org/godotengine/godot/gl/EGLLogWrapper\.java|
platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix\.java
)$
- id: header-guards
name: header-guards
language: python
entry: python misc/scripts/header_guards.py
files: \.(h|hpp|hh|hxx)$
exclude: ^.*/(dummy|thread|platform_config|platform_gl)\.h$
- id: file-format
name: file-format
language: python
entry: python misc/scripts/file_format.py
types_or: [text]
exclude: |
(?x)^(
.*\.test\.txt|
.*\.svg|
.*\.patch|
.*\.out|
modules/gdscript/tests/scripts/parser/features/mixed_indentation_on_blank_lines\.gd|
modules/gdscript/tests/scripts/parser/warnings/empty_file_newline_comment\.norun\.gd|
modules/gdscript/tests/scripts/parser/warnings/empty_file_newline\.norun\.gd|
tests/data/.*\.bin
)$
- id: dotnet-format
name: dotnet-format
language: python
entry: python misc/scripts/dotnet_format.py
types_or: [c#]
#
# End of upstream Godot pre-commit hooks.
#
# Keep this separation to let downstream forks add their own hooks to this file,
# without running into merge conflicts when rebasing on latest upstream.
#
# Start of downstream pre-commit hooks.
#
# This is still the "repo: local" scope, so new local hooks can be defined directly at this indentation:
# - id: new-local-hook
# To add external repo hooks, bring the indentation back to:
# - repo: my-remote-hook

97
.travis.yml Normal file
View File

@@ -0,0 +1,97 @@
language: cpp
dist: trusty
sudo: false
env:
global:
- SCONS_CACHE=$HOME/.scons_cache
- SCONS_CACHE_LIMIT=1024
cache:
directories:
- $SCONS_CACHE
matrix:
include:
- env: STATIC_CHECKS=yes
os: linux
compiler: clang
- env: GODOT_TARGET=x11 TOOLS=yes CACHE_NAME=${GODOT_TARGET}-gcc-tools
os: linux
compiler: gcc
- env: GODOT_TARGET=x11 TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
os: linux
compiler: clang
#- env: GODOT_TARGET=windows TOOLS=yes CACHE_NAME=${GODOT_TARGET}-gcc-tools
# os: linux
# compiler: gcc
- env: GODOT_TARGET=android TOOLS=no CACHE_NAME=${GODOT_TARGET}-gcc
os: linux
compiler: gcc
#- env: GODOT_TARGET=osx TOOLS=yes CACHE_NAME=${GODOT_TARGET}-clang-tools
# os: osx
# compiler: clang
#- env: GODOT_TARGET=iphone TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
# os: osx
# compiler: clang
- env: GODOT_TARGET=server TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang"
os: linux
compiler: clang
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
packages:
- build-essential
- scons
- pkg-config
- libx11-dev
- libxcursor-dev
- libxi-dev
- libxinerama-dev
- libxrandr-dev
- libgl1-mesa-dev
- libglu1-mesa-dev
- libasound2-dev
- libfreetype6-dev
- libssl-dev
# For cross-compiling to Windows.
#- binutils-mingw-w64-i686
#- binutils-mingw-w64-x86-64
#- gcc-mingw-w64-i686
#- gcc-mingw-w64-x86-64
#- g++-mingw-w64-i686
#- g++-mingw-w64-x86-64
#- mingw-w64
# For style checks.
- clang-format-5.0
install:
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "android" ]; then
misc/travis/android-tools-linux.sh;
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
misc/travis/scons-local-osx.sh;
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then
misc/travis/android-tools-osx.sh;
fi
before_script:
- if [ "$GODOT_TARGET" = "android" ]; then
export ANDROID_HOME=$TRAVIS_BUILD_DIR/godot-dev/build-tools/android-sdk;
export ANDROID_NDK_ROOT=$TRAVIS_BUILD_DIR/godot-dev/build-tools/android-ndk;
fi
script:
- if [ "$STATIC_CHECKS" = "yes" ]; then
sh ./misc/travis/clang-format.sh;
else
scons -j2 CC=$CC CXX=$CXX platform=$GODOT_TARGET TOOLS=$TOOLS verbose=yes progress=no openmp=no gdnative_wrapper=yes;
fi

View File

@@ -1,17 +1,11 @@
# Godot Engine authors
Godot Engine is developed by a community of voluntary contributors who
contribute code, bug reports, documentation, translations, support, etc.,
across multiple repositories.
contribute code, bug reports, documentation, artwork, support, etc.
It is impossible to list them all; nevertheless, this file aims at listing
the developers who contributed significant improvements to the engine code.
To keep the list curated, we use a threshold of a minimum of 11 commits.
This file does not strictly reflect copyright ownership for the engine
source code. For this, refer to the Git history to know which contributor
wrote which part of the codebase.
the developers who contributed significant patches to this MIT licensed
source code. "Significant" is arbitrarily decided, but should be fair :)
GitHub usernames are indicated in parentheses, or as sole entry when no other
name is available.
@@ -31,329 +25,105 @@ name is available.
## Developers
Aaron Franke (aaronfranke)
Aaron Pagano (aaronp64)
Aaron Record (LightningAA)
Adam Scott (adamscott)
Alexander Hartmann (Alex2782)
(in alphabetical order, with 10 commits or more excluding merges)
Alexander Holland (AlexHolly)
Alex Drozd (brno32)
Alexey Khoroshavin (allkhor)
Allen Pestaluky (allenwp)
Alfred Reinold Baudisch (alfredbaudisch)
Alistair Leslie-Hughes (alesliehughes)
Alexey Velikiy (jonyrock)
Alket Rexhepi (alketii)
Alvin Wong (alvinhochun)
Andrea Catania (AndreaCatania)
Andreia Gaita (shana)
Andrés Botero (0xafbf)
Andrii Doroshenko (Xrayez)
Andy Maloney (asmaloney)
Andreas Haas (Hinsbart)
Andy Moss (MillionOstrich)
Angad Kambli (angad-k)
Anilforextra (AnilBK)
Anish Bhobe (KidRigger)
Anish Mishra (syntaxerror247)
Anni Ryynänen (anniryynanen)
Anton Yabchinskiy (a12n)
Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
arkology
Arman Elgudzhyan (puchik)
Arseny Kapoulkine (zeux)
AThousandShips
aXu-AP
Bartłomiej T. Listwon (Listwon)
Bastiaan Olij (BastiaanOlij)
Ben Brookshire (sheepandshepherd)
Benjamin Larsson (Nallebeorn)
Bernhard Liebl (poke1024)
Bhuvan Vemula (Bhu1-V)
bitsawer
Błażej Szczygieł (zaps166)
BlueCube3310
Benjamin (Nallebeorn)
Bernard Liebl (poke1024)
Bojidar Marinov (bojidar-bg)
Brian Semrau (briansemrau)
Bruno Lourenço (MadEqua)
Cameron Reikes (creikey)
Camille Mohr-Daurat (pouleyKetchoupp)
Caner Demirer (cdemirer)
Błażej Szczygieł (zaps166)
Carl Olsson (not-surt)
Carter Anderson (cart)
ChibiDenDen
Chris Bradfield (cbscribe)
Chris Cranford (Naros)
Christian Kaiser (ckaiser)
Clay John (clayjohn)
ConteZero
CookieBadger
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Daniel Rakos (aqnuep)
Daniel Zilberleyb (dzil123)
Danil Alexeev (dalexeev)
dankan1890
Darío Banini (DarioSamo)
David Cambré (Gallilus)
David Sichma (DavidSichma)
David Snopek (dsnopek)
derammo
Dharkael (lupoDharkael)
Dirk Steinmetz (rsjtdrjgfuzkfg)
Dmitry Koteroff (Krakean)
Dmitry Maganov (vonagam)
Dominik Jasiński (dreamsComeTrue)
Douglas Leão (DeeJayLSP)
DualMatrix
Ellen Poe (ellenhp)
Emilio Coppola (coppolaemilio)
Emmanuel Barroga (codecustard)
Дмитрий Сальников (DmitriySalnikov)
Emmanuel Leblond (touilleMan)
Eoin O'Neill (Eoin-ONeill-Yokai)
Eric Lasota (elasota)
Eric M (EricEzaM)
Eric Rybicki (ericrybick)
Erik Selecký (rxlecky)
est31
Eveline Jarosz (Marqin)
Fabian Mathews (supagu)
Fabio Alessandrelli (Faless)
Fabrice Cipolla (fabriceci)
Ferenc Arn (tagcup)
FireForge (fire-forge)
Florent Guiocheau (Flarkk)
Florian Kothmeier (Dragoncraft89)
follower
foxydevloper
François Belair (Razoric480)
Franklin Sobrinho (TheHX)
Fredia Huya-Kouadio (m4gr3d)
Geequlim
Gen (dbsGen)
George Marques (vnen)
Gerrit Großkopf (Grosskopf)
Giganzo
Gilles Roudiere (groud)
Gordon MacPherson (RevoluPowered)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
Guillaume Mouton (kiroxas)
Hakim Rouatbi (hakro)
Hanif Bin Ariffin (hbina)
Haoyu Qiu (timothyqiu)
Hein-Pieter van Braam-Stewart (hpvb)
Hendrik Brucker (Geometror)
Hilderin
Hein-Pieter van Braam (hpvb)
Hiroshi Ogawa (hi-ogawa)
HolonProduction
homer666
hoontee
Hubert Jarosz (Marqin)
Hugo Locurcio (Calinou)
Ian Bishop (ianb96)
Ibrahn Sahir (ibrahn)
Ignacio Roldán Etcheverry (neikeq)
Igor Kordiukiewicz (IgorKordiukiewicz)
Ilaria Cislaghi (QbieShay)
Ignacio Etcheverry (neikeq)
Indah Sylvia (ISylvox)
Ivan Šachov (van800)
J08nY
Jake Young (Duroxxigar)
Jakub Grzesik (kubecz3k)
Jakub Marcowski (Chubercik)
James Buck (jbuck3)
Jan Haller (Bromeon)
Jason Knight (jasonwinterpixel)
Jean-Michel Bernard (jmb462)
Jérôme Gully (Nutriz)
Jia Jun Chai (SkyLucilfer)
jitspoe
Joan Fons Sanchez (JFonS)
Johan Aires Rastén (JohanAR)
Jérôme GULLY (Nutriz)
Johan Manuel (29jm)
Johannes Witt (HaSa1002)
Jonathan Nicholl (jtnicholl)
Jordan Schidlowsky (winterpixelgames)
Josh Jones (DarkKilauea)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
Julian Murgia (StraToN)
Julien Nguyen (Blackiris)
Jummit
Justo Delgado (mrcdk)
karroffel
Kassandra Pucher (PucklaJ)
Kelly Thomas (KellyThomas)
kleonc
Kongfa Waroros (gongpha)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
Kyle Eichlin (likeich)
Lars Pettersson (larspet)
lawnjelly
Leon Krause (leonkrause)
Liz Haas (27thLiz)
Logan Lang (devloglogan)
Lucien Menassol (Kanabenki)
Lukas Tenbrink (Ivorforce)
Lyuma
Maganty Rushyendra (mrushyendra)
Magian (magian1127)
Mai Lavelle (maiself)
Malcolm Anderson (Meorge)
Malcolm Nixon (Malcolmnixon)
Manuele Finocchiaro (m4nu3lf)
Marcel Admiraal (madmiraal)
Marcelo Fernandez (marcelofg55)
Leon Krause (eska014)
Marc Gilleron (Zylann)
Marcin Zawiejski (dragmz)
Marcus Brummer (mbrlabs)
Marcus Elg (MCrafterzz)
Marcelo Fernandez (marcelofg55)
Mariano Javier Suligoy (MarianoGnu)
Mario Liebisch (MarioLiebisch)
Mario Schlack (hurikhan)
Marios Staikopoulos (marstaik)
Marius Hanl (Maran23)
Mark DiBarry (markdibarry)
Mark Riedesel (klowner)
Markus Sauermann (Sauermann)
Martin Capitanio (capnm)
Martin Liška (marxin)
Martin Sjursen (binbitten)
marynate
Masoud BH (masoudbh3)
Mateo Kuruk Miccino (kuruk-mm)
Matias N. Goldberg (darksylinc)
Matthew Murphy (mashumafi)
Matthew (skyace65)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
merumelu
Meru Patel (Janglee123)
MewPurPur
Michael Alexsander (YeldhamDev)
Michał Iwańczuk (iwek7)
MichiRecRoom (LikeLakers2)
Micky (Mickeon)
Mikael Hermansson (mihe)
Mika Viskari (miv391)
MinusKube
MJacred
Mounir Tohami (WhalesState)
mrezai
Muhammad Huri (CakHuri)
muiroc
myaaaaaaaaa
Nathalie Galla (MurderVeggie)
Nathan Franke (nathanfranke)
Nathan Lovato (NathanLovato)
Michael Alexsander Silva Dias (YeldhamDev)
Nathan Warden (NathanWarden)
Nazarii Yablonskyi (Nazarwadim)
Nicholas Huelin (SirQuartz)
Nikita Lita (nikitalita)
Nils André-Chang (NilsIrl)
Noah Beard (TwistedTwigleg)
Nông Văn Tình (nongvantinh)
Nuno Donato (nunodonato)
ocean (they/them) (anvilfolk)
Omar El Sheikh (The-O-King)
Ovnuniarchos
Pablo Andres Fuente (pafuent)
Pascal Richter (ShyRed)
passivestar
Patrick Dawson (pkdawson)
Patrick Exner (FlameLizard)
Patrick (firefly2442)
patwork
Paul Batty (Paulb23)
Paul Joannon (paulloz)
Paul Trojahn (ptrojahn)
Pāvels Nadtočajevs (bruvzg)
Paweł Fertyk (pfertyk)
Pawel Kowal (pkowal1982)
Pawel Lampe (Scony)
Pedro J. Estébanez (RandomShaper)
Pieter-Jan Briers (PJB3005)
Poommetee Ketson (Noshyaar)
Przemysław Gołąb (n-pigeon)
Radiant (radiantgurl)
Rafael M. G. (rafallus)
Rafał Mikrut (qarmin)
Raffaele Picca (RPicster)
Ralf Hölzemer (rollenrolm)
Ramesh Ravone (RameshRavone)
Raphael2048
Raul Santos (raulsntos)
Ray Koopa (RayKoopa)
RedMser
RedworkDE
Rémi Verschelde (akien-mga)
Rhody Lugo (rraallvv)
Ricardo Buring (rburing)
Ricardo Subtil (Ev1lbl0w)
Riteo Siuga (Riteo)
Roberto F. Arroyo (robfram)
Robert Yevdokimov (ryevdokimov)
Robin Hübner (profan)
romulox-x
Rudolph Bester (Rudolph-B)
Rune Smith (rune-scape)
Ruslan Mustakov (endragor)
Ryan Roden-Corrent (rrcore)
Saniko (sanikoyes)
santouits
SaracenOne
Septian Ganendra S. K. (sepTN)
Sergey Minakov (naithar)
sersoong
Shiqing (kawa-yoiko)
Silc 'Tokage' Renew (TokageItLab)
Simon Wenner (swenner)
smix8
snailrhymer
Sofox (TheSofox)
Stanislav Labzyuk (DarkMessiah)
Stijn Hinlopen (hinlopen)
stmSi
Stuart Carnie (stuartcarnie)
Swarnim Arun (minraws)
TC (floppyhammer)
TechnoPorg
tetrapod00
Thaddeus Crews (Repiteo)
Thakee Nathees (ThakeeNathees)
thebestnom
Theo Hallenius (TheoXD)
Thomas ten Cate (ttencate)
Timo Schwarzer (timoschwarzer)
Timothé Bonhoure (ajreckof)
Thomas Herzog (karroffel)
Timo (toger5)
Tomasz Chabora (KoBeWi)
Travis Lange (TCROC)
trollodel
Twarit Waikar (IronicallySerious)
Umang Kalra (theoway)
Victor Hampel (havi05)
Vinzenz Feenstra (vinzenz)
Vitika Soni (Vitika9)
박한얼 (volzhs)
V. Vamsi Krishna (vkbsb)
Vinzenz Feenstra (vinzenz)
Wilhem Barbier (nounoursheureux)
William Deurwaarder (williamd67)
Will Nations (willnationsdev)
Wilson E. Alvarez (Rubonnek)
Xavier Cho (mysticfall)
Yaohua Xiong (xiongyaohua)
Yevhen Babiichuk (dustdfg)
yg2f (SuperUserNameMan)
Yordan Dolchinkov (Jordyfel)
Yufeng Ying (YYF233333)
Yuri Rubinsky (Chaosus)
Yuri Sizov (YuriSizov)
Zae Chao (zaevi)
Zak Stam (zaksnet)
Yuri Roubinski (Chaosus)
Zher Huei Lee (leezh)
Zi Ye (MajorMcDoom)
ZuBsPaCe
Дмитрий Сальников (DmitriySalnikov)
忘忧の (Daylily-Zeleen)
谢天 (jsjtxietian)
风青山 (Rindbee)
박한얼 (volzhs)
bruvzg
est31
m4nu3lf
marynate
mrezai
romulox-x
rraallvv
sersoong
yg2f (SuperUserNameMan)

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +1,80 @@
# Contributors guidelines
# How to contribute efficiently
This document summarizes the most important points for people interested in
contributing to Godot, especially via bug reports or pull requests.
Sections covered in this file:
The Godot documentation has a dedicated [Contributing section](https://docs.godotengine.org/en/latest/contributing/how_to_contribute.html)
which details these points and more, and is a recommended read.
* [Reporting bugs or proposing features](#reporting-bugs-or-proposing-features)
* [Contributing pull requests](#contributing-pull-requests)
* [Contributing to Godot's translation](#contributing-to-godots-translation)
* [Communicating with developers](#communicating-with-developers)
## Table of contents
**Please read the first section before reporting a bug!**
- [Reporting bugs](#reporting-bugs)
- [Proposing features or improvements](#proposing-features-or-improvements)
- [Contributing pull requests](#contributing-pull-requests)
- [Contributing to Godot translations](#contributing-to-godot-translations)
- [Communicating with developers](#communicating-with-developers)
## Reporting bugs or proposing features
## Reporting bugs
The golden rule is to **always open *one* issue for *one* bug**. If you notice
several bugs and want to report them, make sure to create one new issue for
each of them.
Report bugs [here](https://github.com/godotengine/godot/issues/new?assignees=&labels=&template=bug_report.yml).
Please follow the instructions in the template when you do.
Everything referred to hereafter as "bug" also applies for feature requests.
Notably, please include a Minimal Reproduction Project (MRP), which is a small
Godot project which reproduces the issue, with no unnecessary files included.
Be sure to not include the `.godot` folder in the archive to save space.
If you are reporting a new issue, you will make our life much simpler (and the
fix come much sooner) by following those guidelines:
Make sure that the bug you are experiencing is reproducible in the latest Godot
releases. You can find an overview of all Godot releases [on the website](https://godotengine.org/download/archive/)
to confirm whether your current version is the latest one. It's worth testing
against both the latest stable release and the latest dev snapshot for the next
Godot release.
#### Search first in the existing database
If you run into a bug which wasn't present in an earlier Godot version (what we
call a _regression_), please mention it and clarify which versions you tested
(both the one(s) working and the one(s) exhibiting the bug).
Issues are often reported several times by various users. It's a good practice
to **search first** in the issues database before reporting your issue. If you
don't find a relevant match or if you are unsure, don't hesitate to **open a
new issue**. The bugsquad will handle it from there if it's a duplicate.
## Proposing features or improvements
#### Specify the platform
**The main issue tracker is for bug reports and does not accept feature proposals.**
Godot runs on a large variety of platforms and operating systems and devices.
If you believe your issue is device/platform dependent (for example if it is
related to the rendering, crashes or compilation errors), please specify:
* Operating system
* Device (including architecture, e.g. x86, x86_64, arm, etc.)
* GPU model (and driver in use if you know it)
Instead, head to the [Godot Proposals repository](https://github.com/godotengine/godot-proposals)
and follow the instructions in the README file and issue template.
#### Specify steps to reproduce
Many bugs can't be reproduced unless specific steps are taken. Please **specify
the exact steps** that must be taken to reproduce the condition, and try to
keep them as minimal as possible.
#### Provide a simple, example project
Sometimes an unexpected behavior happens in your project. In such case,
understand that:
* What happens to you may not happen to other users.
* We can't take the time to look at your project, understand how it is set up
and then figure out why it's failing.
To speed up our work, please prepare for us **a simple project** that isolates
and reproduces the issue. This is always the **the best way for us to fix it**.
You can attach a zip file with the minimal project directly to the bug report,
by drag and dropping the file in the GitHub edition field.
## Contributing pull requests
If you want to add new engine features, please make sure that:
If you want to add new engine functionalities, please make sure that:
- This functionality is desired, which means that it solves a common use case
that several users will need in their real-life projects.
- You talked to other developers on how to implement it best. See also
[Proposing features or improvements](#proposing-features-or-improvements).
- Even if it doesn't get merged, your PR is useful for future work by another
* This functionality is desired.
* You talked to other developers on how to implement it best (on either
communication channel, and maybe in a GitHub issue first before making your
PR).
* Even if it does not get merged, your PR is useful for future work by another
developer.
Similar rules can be applied when contributing bug fixes - it's always best to
discuss the implementation in the bug report first if you are not 100% about
what would be the best fix.
You can refer to the [Pull request review process](https://docs.godotengine.org/en/latest/contributing/workflow/pr_review_guidelines.html)
for insights into the intended lifecycle of pull requests. This should help you
ensure that your pull request fulfills the requirements.
#### Be nice to the git history
In addition to the following tips, also take a look at the
[Engine development guide](https://docs.godotengine.org/en/latest/contributing/development/index.html)
for an introduction to developing on Godot.
The [Contributing docs](https://docs.godotengine.org/en/latest/contributing/how_to_contribute.html)
also have important information on the [PR workflow](https://docs.godotengine.org/en/latest/contributing/workflow/pr_workflow.html)
(with a helpful guide for Git usage), and our [Code style guidelines](https://docs.godotengine.org/en/latest/contributing/development/code_style_guidelines.html)
which all contributions need to follow.
### Be mindful of your commits
Try to make simple PRs that handle one specific topic. Just like for reporting
issues, it's better to open 3 different PRs that each address a different issue
than one big PR with three commits. This makes it easier to review, approve, and
merge the changes independently.
Try to make simple PRs with that handle one specific topic. Just like for
reporting issues, it's better to open 3 different PRs that each address a
different issue than one big PR with three commits.
When updating your fork with upstream changes, please use ``git pull --rebase``
to avoid creating "merge commits". Those commits unnecessarily pollute the git
@@ -81,48 +82,34 @@ history when coming from PRs.
Also try to make commits that bring the engine from one stable state to another
stable state, i.e. if your first commit has a bug that you fixed in the second
commit, try to merge them together before making your pull request. This
includes fixing build issues or typos, adding documentation, etc.
commit, try to merge them together before making your pull request (see ``git
rebase -i`` and relevant help about rebasing or amending commits on the
Internet).
See our [PR workflow](https://docs.godotengine.org/en/latest/contributing/workflow/pr_workflow.html)
documentation for tips on using Git, amending commits and rebasing branches.
This git style guide has some good practices to have in mind:
[Git Style Guide](https://github.com/agis-/git-style-guide)
This [Git style guide](https://github.com/agis-/git-style-guide) also has some
good practices to have in mind.
#### Format your commit logs with readability in mind
### Format your commit messages with readability in mind
The way you format your commit messages is quite important to ensure that the
commit history and changelog will be easy to read and understand. A Git commit
message is formatted as a short title (first line) and an extended description
The way you format your commit logs is quite important to ensure that the
commit history and changelog will be easy to read and understand. A git commit
log is formatted as a short title (first line) and an extended description
(everything after the first line and an empty separation line).
The short title is the most important part, as it is what will appear in the
changelog or in the GitHub interface unless you click the "expand" button.
Try to keep that first line under 72 characters, but you can go slightly above
if necessary to keep the sentence clear.
`shortlog` changelog (one line per commit, so no description shown) or in the
GitHub interface unless you click the "expand" button. As the name tells it,
try to keep that first line relatively short (ideally <= 50 chars, though it's
rare to be able to tell enough in so few characters, so you can go a bit
higher) - it should describe what the commit does globally, while details would
go in the description. Typically, if you can't keep the title short because you
have too much stuff to mention, it means that you should probably split your
changes in several commits :)
It should be written in English, starting with a capital letter, and usually
with a verb in imperative form. A typical bugfix would start with "Fix", while
the addition of a new feature would start with "Add". A prefix can be added to
specify the engine area affected by the commit. Some examples:
- Add C# iOS support
- Show doc tooltips when hovering properties in the theme editor
- Fix GLES3 instanced rendering color and custom data defaults
- Core: Fix `Object::has_method()` for script static methods
If your commit fixes a reported issue, please include it in the _description_
of the PR (not in the title, or the commit message) using one of the
[GitHub closing keywords](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)
such as "Fixes #1234". This will cause the issue to be closed automatically if
the PR is merged. Adding it to the commit message is easier, but adds a lot of
unnecessary updates in the issue distracting from the thread.
Here's an example of a well-formatted commit message (note how the extended
Here's an example of a well-formatted commit log (note how the extended
description is also manually wrapped at 80 chars for readability):
```text
```
Prevent French fries carbonization by fixing heat regulation
When using the French fries frying module, Godot would not regulate the heat
@@ -132,58 +119,20 @@ unwanted side effects in the physics engine.
By fixing the regulation system via an added binding to the internal feature,
this commit now ensures that Godot will not go past the ebullition temperature
of cooking oil under normal atmospheric conditions.
Fixes #1789, long live the Realm!
```
**Note:** When using the GitHub online editor or its drag-and-drop
feature, *please* edit the commit title to something meaningful. Commits named
"Update my_file.cpp" won't be accepted.
*Note:* When using the GitHub online editor (or worse, the drag and drop
feature), *please* edit the commit title to something meaningful. Commits named
"Update my_file.cpp" will not be accepted.
### Document your changes
## Contributing to Godot's translation
If your pull request adds methods, properties or signals that are exposed to
scripting APIs, you **must** update the class reference to document those.
This is to ensure the documentation coverage doesn't decrease as contributions
are merged.
[Update documentation XML files](https://docs.godotengine.org/en/latest/contributing/documentation/updating_the_class_reference.html)
using your compiled binary, then fill in the descriptions.
Follow the style guide described in the
[Documentation writing guidelines](https://docs.godotengine.org/en/latest/contributing/documentation/docs_writing_guidelines.html).
If your pull request modifies parts of the code in a non-obvious way, make sure
to add comments in the code as well. This helps other people understand the
change without having to dive into the Git history.
### Write unit tests
When fixing a bug or contributing a new feature, we recommend including unit
tests in the same commit as the rest of the pull request. Unit tests are pieces
of code that compare the output to a predetermined *expected result* to detect
regressions. Tests are compiled and run on GitHub Actions for every commit and
pull request.
Pull requests that include tests are more likely to be merged, since we can have
greater confidence in them not being the target of regressions in the future.
For bugs, the unit tests should cover the functionality that was previously
broken. If done well, this ensures regressions won't appear in the future
again. For new features, the unit tests should cover the newly added
functionality, testing both the "success" and "expected failure" cases if
applicable.
Feel free to contribute standalone pull requests to add new tests or improve
existing tests as well.
See [Unit testing](https://docs.godotengine.org/en/latest/contributing/development/core_and_modules/unit_testing.html)
for information on writing tests in Godot's C++ codebase.
## Contributing to Godot translations
You can contribute to Godot translations on [Hosted Weblate](https://hosted.weblate.org/projects/godot-engine/),
an open source and web-based translation platform.
Please refer to our [editor and documentation localization guidelines](https://docs.godotengine.org/en/latest/contributing/documentation/editor_and_docs_localization.html)
for an overview of the translation resources and what they correspond to.
You can contribute to Godot's translation from the [Hosted
Weblate](https://hosted.weblate.org/projects/godot-engine/godot), an open
source and web-based translation platform. Please refer to the [translation
readme](editor/translations/README.md) for more information.
## Communicating with developers
@@ -193,21 +142,26 @@ discussions and support, others more for development discussions.
To communicate with developers (e.g. to discuss a feature you want to implement
or a bug you want to fix), the following channels can be used:
- [GitHub issues](https://github.com/godotengine/godot/issues): If there is an
existing issue about a topic you want to discuss, just add a comment to it -
all developers watch the repository and will get an email notification. You
can also create a new issue - please keep in mind to create issues only to
discuss quite specific points about the development, and not general user
feedback or support requests.
- [#godotengine-devel IRC channel on
Freenode](https://webchat.freenode.net/?channels=godotengine-devel): You will
find most core developers there, so it's the go-to channel for direct chat
about Godot Engine development. Feel free to start discussing something there
to get some early feedback before writing up a detailed proposal in a GitHub
issue.
- [devel@godotengine.org mailing
list](https://listengine.tuxfamily.org/godotengine.org/devel/): Mailing list
for Godot developers, used primarily to announce developer meetings on IRC
and other important discussions that need to reach people directly in their
mailbox. See the [index
page](https://listengine.tuxfamily.org/godotengine.org/devel/) for
subscription instructions.
- [Godot Contributors Chat](https://chat.godotengine.org): You will
find most core developers there, so it's the go-to platform for direct chat
about Godot Engine development. Browse the [Directory](https://chat.godotengine.org/directory/channels)
for an overview of public channels focusing on various engine areas which you
might be interested in.
- [Bug tracker](https://github.com/godotengine/godot/issues): If there is an
existing issue about a topic you want to discuss, you can participate directly.
If not, you can open a new issue. Please mind the guidelines outlined above
for bug reporting.
- [Feature proposals](https://github.com/godotengine/godot-proposals/issues):
To propose a new feature, we have a dedicated issue tracker for that. Don't
hesitate to start by talking about your idea on the Godot Contributors Chat
to make sure that it makes sense in Godot's context.
Thanks!
Thanks for your interest in contributing!
—The Godot development team
The Godot development team

File diff suppressed because it is too large Load Diff

527
DONORS.md
View File

@@ -7,287 +7,286 @@ support of generous donors.
The ways to donate to the project, as well as details on how the funds are
used, are described on [Godot's website](https://godotengine.org/donate).
The following is a list of the current monthly donors, who will have their
The following is a list of the current monthly donors, to be have their
generous deed immortalized in the next stable release of Godot Engine.
## Patrons
Khronos® Group <https://www.khronos.org/>
OSS Capital <https://oss.capital/>
## Platinum sponsors
Scorewarrior <https://scwr.gg/godot>
V-Sekai <https://github.com/V-Sekai>
W4 Games <https://w4games.com/>
Enjin Coin <https://enjincoin.io>
## Gold sponsors
Mega Crit <https://www.megacrit.com/>
Prehensile Tales <https://prehensile-tales.com>
Robot Gentleman <http://robotgentleman.com/>
Gamblify <https://www.gamblify.com>
GameDev.TV <https://www.gamedev.tv>
Skirmish <https://skirmish.io>
## Silver sponsors
## Mini sponsors
Bippinbits <https://bippinbits.com/>
Broken Rules <https://brokenrul.es>
Chasing Carrots <https://www.chasing-carrots.com>
Copia Wealth Studios <https://copiawealthstudios.com/>
LoadComplete <https://loadcomplete.com/>
Null <https://null.com/>
Orbital Knight <https://www.orbitalknight.com/>
Playful Studios <https://playfulstudios.com/>
Re-Logic <https://re-logic.com/>
## Diamond members
ASIFA-Hollywood <https://www.asifa-hollywood.org/>
Christina Coffin <https://bsky.app/profile/christinacoffin.bsky.social>
Dominic Harris <https://wayfarer-games.com/>
Kiri "ExpiredPopsicle" Artemis <https://expiredpopsicle.com/>
Petr Kharitonov <https://petrkharitonov.com/>
Seats.aero <https://seats.aero/>
Sylv <https://rankith.itch.io/unnamed-space-idle-prototype>
And 5 anonymous donors
## Titanium members
Adriaan de Jongh <https://adriaan.games>
Basically Games
Draknek & Friends <https://www.draknek.org/>
Garry Newman
Gigabrain AI Reddit Search Engine <https://thegigabrain.com/?utm_source=godot>
Jettelly <https://jettelly.com/>
Justo Delgado Baudí <https://portfolio.mrcdk.com/>
Kenney <https://kenney.nl/>
Lucid Silence Games
Matthew Hall <https://crossyroad.com/>
PolyMars <https://polymars.dev/>
Purple Moss Collectors <https://purplemosscollectors.com/>
RPG in a Box <https://www.rpginabox.com>
Starkandco <https://github.com/Starkandco>
Studio Sunshower <https://www.studiosunshower.com/>
TrampolineTales <https://TrampolineTales.com/>
粟二华 (Su Erhua)
And 4 anonymous donors
## Platinum members
Andy Touch
BlockImperiumGames (BIG)
Bytten Studio
Christopher Shifflett
Cody Bentley
Darrin Massena
Fabio Alessandrelli
HP van Braam
iCommitGames
Jason Hamilton
Jonah Stich
Josh Anthony
Ludvig Temperli Risan
Matthew Ekenstedt
Memories in 8Bit
Michael Martin
Brandon Lamb
Christian Uldall Pedersen
Christopher Igoe
Christoph Woinke
Claudiu Dumitru
E Hewert
Hein-Pieter van Braam
Igors Vaitkus
Jamal Alyafei
Jay Sistar
Matthieu Huvé
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
Nico Ulriksen
Nikita Blizniuk
Raptor85
Rémi Verschelde
Ronnie Cheng
Ryan Heath
ShikadiGum
Silver Creek Entertainment
Stephan Kessler
Stephen Rice
And 14 anonymous donors
Pascal Julien
Ruslan Mustakov
Sébastien Manin
Slobodan Milnovic
Stephan Lanfermann
Stoney Meyerhoeffer
Thomas Mathews
VilliHaukka
## Gold members
## Gold donors
2 Nerdy Nerds
73unny
80px
Abigail F.
Admiral Potato
afreytes
AinaVT
Ajat BlackSun
Alex177Alex
alMoo Games
Alva Majo
Andrew Eiche
Antti Vesanen
Arediss
Asher Glick
Axthelm
BangTheWall
Benito
Benjamin Bridges
Ben Rog-Wilhelm
BetaTester704
Brut
Bryce Dixon
Carlo Cabanilla
Carlo del Mundo
Carl van der Geest
Chocolate Software
Chris Backas
Chris Lambson
Christine Elisabeth Koppel
Cindy Trieu
ClarkThyLord
Codex404
cora
Daniel Eichler
Daniel Krafft
Datzju
David Chen Zhen
David Coles
David Hubber
David Snopek
Deakcor
Delton Ding
dgehrig
Disco Cat
Distorted Realities
DitherDream
Dominik Frizel
Don't You Know Who I Am? Inc.
Dustuu
Dylan Dromard
Edelweiss
eelSkillz
Emily Flion
Ends
Eren Ogrul
Eric Brand
Eric Phy
Faisal Al-Kubaisi (QatariGameDev)
Fanny Pack Studios
Felix Adam
FeralBytes
Francisco Aliaga
Francis Jasmin
Frozen Fractal
Gaudipern
GetIntoGameDev
GlassBrick
Grau
Grzegorz Wereszko
Guangzhou Lingchan
Guilherme Cattani
Hayden Oliver
hiulit
https://domi.zip
Huedeane
Ikuti
Illyan
I.M.I.Self
Immaculate Lift Studio
Intrepid Marmot LLC
Isaac Marovitz
Ivan Tabashki
jakemiki
Jam
Jason Cawood
Jeff Hungerford
Jesús Chicharro
3Dexplorer
Alexander Otto
Asdf
cheese65536
K9Kraken
Kris Michael
Manuele Finocchiaro
Nathanael Beisiegel
Officine Pixel S.n.c.
Zaven Muradyan
Allen Schade
Andreas Schüle
Austen McRae
Bernhard Liebl
Catalin Moldovan
DeepSquid
Fidget Sinner
Florian Breisch
Gary Oberbrunner
Johannes Wuensch
John Gabriel
Jonas Yamazaki
Jonathan
José Canepa
Julian Todd
Justin Laster
Justin Sasso
Kalydi Balázs
KAR Games
Kiryonn
kodebold
KOGA Mitsuhiro (@shiena)
korinVR
Kristian Kriehl
KyletheDab
Lars Thießen
Lisandro Lorea (Red Mage Games)
Logan Apple
Luca Junge
LyaaaaaGames
m1n1ster
Madison Nicole Videogames
Mara Huldra
Marek Belski
Martin Šenkeřík
Matthias B.
Michael Alexsander
Michael Gooch
Michael Harrington
Modus Ponens
Moshe Harris
Moth Soup
Mr. Byte
Muscarian Softworks
Nassor Paulino da Silva
Neuroticfly Games
nezticle
nikkehtine
Niklas Wahrman
Nitzan Bueno
NotNet
Oathbringer
Officine Pixel
ohanaya3
Okatima AB
Oscar Robin
ovym
Patrick Traynor
Péter Horváth-Lázár
Petr Maláč
pirey
protogames
Rafa Laguna
Reid Hannaford
@reilaos
Request
re:thinc
Richard Ivánek
Robin Ward
Ronny Mühle
Rubén Rüger
Samuel Judd
Santi_FC
Seref Karahan
shazzner
Shiny Shinken
Silverclad Studios
Skie Radscale
Snow Diamond
Josep G. Camarasa
Joshua Lesperance
Libre-Dépanne
Matthew Bennett
Olafur Gislason
Paul LaMotte
Ranoller
Svenne Krap
Timothy Hagberg
BanjoNode2D
Beliar
Chris Serino
Conrad Curry
Craig Smith
Daniel Egger
David Churchill
Dean Harmon
Dexter Miguel
Guilherme Felipe de C. G. da Silva
John
Justo Delgado Baudí
KTL
Laurence Bannister
Rami
Robert Willes
Robin Arys
Ronnie Ashlock
Rufus Xavier Sarsaparilla
ScottMakesGames
Thomas Bjarnelöf
William Connell
Wojciech Chojnacki
Xavier Tan
Zaq Poi
Alessandra Pereyra
Alexey Dyadchenko
Amanda Haldy
Chris Brown
Chris Petrich
Chris Wilson
Cody Parker
Corey Auger
D
Daniel Eliasinski
E.G.
Eric Monson
flesk
G Barnes
GGGames.org
Giovanni Solimeno
Hasen Judy
Heath Hayes
Jay Horton
Jeppe Zapp
joe513
Jordan M Lucas
Juraj Móza
Justin Arnold
Leandro Voltolino
Lisandro Lorea
Markus Wiesner
Marvin
Mohammad Taleb
Nick Nikitin
Pablo Cholaky
Patrick Schnorbus
Pete Goodwin
Phyronnaz
Ruben Soares Luis
Sofox
Space Kraken Studios
Spoony Panda
tenuki
ThatGamer
Thomas Lobig
Tobias Bocanegra
Tom Langwaldt
Trevor Slocum
tukon
twitch.tv/RobitussinMD
Tyler C
Urban Protagonist
Vincent Foulon
Vojtech Lacina
Voxel Floof
Watchinofoye
Yannick
zikes
Zoey Smith
嗯大爷
Stoned Xander
Ted
Tim Dalporto
Trent McPheron
Vladimir
And 143 anonymous donors
## Silver donors
## Silver and bronze donors
1D_Inc
Adam Carr
Adam Smeltzer
Alder Stefano
Alessandro Senese
Álvaro Domínguez López
Anders Jensen-Urstad
Anthony Bongiovanni
Arda Erol
Arthur S. Muszynski
Aubrey Falconer
Avencherus
Bailey
Bastian Böhm
Benedikt
Benjamin Beshara
Ben Vercammen
Blair Allen
Brandon
Bryan Stevenson
Carwyn Edwards
Casey Foote
Chris Chapin
Christian Baune
Christian Winter
Christopher Schmitt
Collin Shooltz
Daniel Delgado Corona
Daniel Johnson
Daniel Kaplan
DanielMaximiano
Daniel Mircea
David
David Cravens
David May
Dominik Wetzel
Duy Kevin Nguyen
Edward Herbert
Eric Martini
Fabian Becker
fengjiongmax
Francesco Lisi
G3Dev sàrl
Gerrit Großkopf
Gerrit Procee
Gilberto K. Otubo
Guldoman
Gumichan01
Heribert Hirth
hubert jenkins
Hunter Jones
ialex32x
Ivan Vodopiviz
Jahn Johansen
Jaime Ruiz-Borau Vizárraga
Jed
Jeff Hungerford
Joel Fivat
Johan Lindberg
Jonas Rudlang
Jonas Yamazaki
Jonathan Martin
Jonathan Nieto
Jonathon
Josh 'Cheeseness' Bush
Juan Negrier
Judd
Julian Murgia
Justin Luk
KC Chan
Kevin Boyer
Kevin Kamper Meejach Petersen
Klavdij Voncina
Krzysztof Jankowski
Lars pfeffer
Linus Lind Lundgren
Luis Moraes
Macil
magodev
Martin Eigel
Martins Odabi
Matthew Fitzpatrick
Max R.R. Collada
Maxwell
mhilbrunner
Michael Dürwald
Michael Gringauz
Michael Labbe
Mikael Olsson
MoM
Moritz Laass
Natrim
nee
Neil Blakey-Milner
Nick Pavlica
Niclas Eriksen
Nicolas SAN AGUSTIN
Niko Leopold
nivardus
Noi Sek
Oleg Tyshchenko
Oleksandr Yemets
Pablo Seibelt
Pan Ip
Pat LaBine
Patrick Nafarrete
Patric Vormstein
Paul Mason
Paweł Kowal
Pierre-Igor Berthet
Pietro Vertechi
Piotr Kaczmarski
Rea
Rémi Verschelde
Richman Stewart
Roger Burgess
Roger Smith
Roman Tinkov
Ryan Whited
Samuel El-Borai
Sasori Olkof
Sootstone
Stefan Butucea
Theo Cranmore
Thibault Barbaroux
Thomas Bell
Thomas Kurz
Tomasz Wacławek
Tom Larrow
Tyler Stafos
UltyX
Victor
Victor Gonzalez Fernandez
Viktor Ferenczi
werner mendizabal
Wout Standaert
Yu He
## Bronze donors
There are even more donors that support the project with a small monthly donation.
Every bit counts and we thank every one of them for their amazing support!

21
ISSUE_TEMPLATE.md Normal file
View File

@@ -0,0 +1,21 @@
<!-- Please search existing issues for potential duplicates before filing yours:
https://github.com/godotengine/godot/issues?q=is%3Aissue
-->
**Godot version:**
<!-- Specify commit hash if non-official. -->
**OS/device including version:**
<!-- Specify GPU model and drivers if graphics-related. -->
**Issue description:**
<!-- What happened, and what was expected. -->
**Steps to reproduce:**
**Minimal reproduction project:**
<!-- Recommended as it greatly speeds up debugging. Drag and drop a zip archive to upload it. -->

View File

@@ -1,5 +1,5 @@
Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md).
Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur.
Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

3
LOGO_LICENSE.md Normal file
View File

@@ -0,0 +1,3 @@
Godot Logo (C) Andrea Calabró
Distributed under the terms of the Creative Commons Attribution License
version 3.0 (CC-BY 3.0) <https://creativecommons.org/licenses/by/3.0/legalcode>.

View File

@@ -1,5 +0,0 @@
Godot Engine Logo
Copyright (c) 2017 Andrea Calabró
This work is licensed under the Creative Commons Attribution 4.0 International
license (CC BY 4.0 International): https://creativecommons.org/licenses/by/4.0/

View File

@@ -1,78 +1,69 @@
# Godot Engine
[![Godot Engine logo](/logo.png)](https://godotengine.org)
<p align="center">
<a href="https://godotengine.org">
<img src="logo_outlined.svg" width="400" alt="Godot Engine logo">
</a>
</p>
## Godot Engine
## 2D and 3D cross-platform game engine
Homepage: https://godotengine.org
**[Godot Engine](https://godotengine.org) is a feature-packed, cross-platform
game engine to create 2D and 3D games from a unified interface.** It provides a
comprehensive set of [common tools](https://godotengine.org/features), so that
users can focus on making games without having to reinvent the wheel. Games can
be exported with one click to a number of platforms, including the major desktop
platforms (Linux, macOS, Windows), mobile platforms (Android, iOS), as well as
Web-based platforms and [consoles](https://docs.godotengine.org/en/latest/tutorials/platform/consoles.html).
#### 2D and 3D cross-platform game engine
## Free, open source and community-driven
Godot Engine is a feature-packed, cross-platform game engine to create 2D and
3D games from a unified interface. It provides a comprehensive set of common
tools, so that users can focus on making games without having to reinvent the
wheel. Games can be exported in one click to a number of platforms, including
the major desktop platforms (Linux, Mac OSX, Windows) as well as mobile
(Android, iOS) and web-based (HTML5) platforms.
Godot is completely free and open source under the very permissive [MIT license](https://godotengine.org/license).
#### Free, open source and community-driven
Godot is completely free and open source under the very permissive MIT license.
No strings attached, no royalties, nothing. The users' games are theirs, down
to the last line of engine code. Godot's development is fully independent and
community-driven, empowering users to help shape their engine to match their
expectations. It is supported by the [Godot Foundation](https://godot.foundation/)
expectations. It is supported by the Software Freedom Conservancy
not-for-profit.
Before being open sourced in [February 2014](https://github.com/godotengine/godot/commit/0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac),
Godot had been developed by [Juan Linietsky](https://github.com/reduz) and
[Ariel Manzur](https://github.com/punto-) (both still maintaining the project)
for several years as an in-house engine, used to publish several work-for-hire
titles.
Before being open sourced in February 2014, Godot had been developed by Juan
Linietsky and Ariel Manzur (both still maintaining the project) for several
years as an in-house engine, used to publish several work-for-hire titles.
![Screenshot of a 3D scene in the Godot Engine editor](https://raw.githubusercontent.com/godotengine/godot-design/master/screenshots/editor_tps_demo_1920x1080.jpg)
![Screenshot of a 3D scene in Godot Engine](http://download.tuxfamily.org/godotengine/media/screenshots/editor_3d_fracteed.jpg)
## Getting the engine
### Getting the engine
### Binary downloads
#### Binary downloads
Official binaries for the Godot editor and the export templates can be found
[on the Godot website](https://godotengine.org/download).
[on the homepage](https://godotengine.org/download).
### Compiling from source
#### Compiling from source
[See the official docs](https://docs.godotengine.org/en/latest/contributing/development/compiling)
[See the official docs](http://docs.godotengine.org/en/latest/development/compiling/)
for compilation instructions for every supported platform.
## Community and contributing
### Community
Godot is not only an engine but an ever-growing community of users and engine
developers. The main community channels are listed [on the homepage](https://godotengine.org/community).
The best way to get in touch with the core engine developers is to join the
[Godot Contributors Chat](https://chat.godotengine.org).
To get in touch with the developers, the best way is to join the
[#godotengine IRC channel](https://webchat.freenode.net/?channels=godotengine)
on Freenode.
To get started contributing to the project, see the [contributing guide](CONTRIBUTING.md).
This document also includes guidelines for reporting bugs.
### Documentation and demos
## Documentation and demos
The official documentation is hosted on [Read the Docs](https://docs.godotengine.org).
The official documentation is hosted on [ReadTheDocs](http://docs.godotengine.org).
It is maintained by the Godot community in its own [GitHub repository](https://github.com/godotengine/godot-docs).
The [class reference](https://docs.godotengine.org/en/latest/classes/)
is also accessible from the Godot editor.
The [class reference](http://docs.godotengine.org/en/latest/classes/)
is also accessible from within the engine.
We also maintain official demos in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
as well as a list of [awesome Godot community resources](https://github.com/godotengine/awesome-godot).
The official demos are maintained in their own [GitHub repository](https://github.com/godotengine/godot-demo-projects)
as well.
There are also a number of other
[learning resources](https://docs.godotengine.org/en/latest/community/tutorials.html)
provided by the community, such as text and video tutorials, demos, etc.
Consult the [community channels](https://godotengine.org/community)
for more information.
There are also a number of other learning resources provided by the community,
such as text and video tutorials, demos, etc. Consult the [community channels](https://godotengine.org/community)
for more info.
[![Travis Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/bfiihqq6byxsjxxh/branch/master?svg=true)](https://ci.appveyor.com/project/akien-mga/godot)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/godotengine/godot)](https://www.tickgit.com/browse?repo=github.com/godotengine/godot)

1535
SConstruct

File diff suppressed because it is too large Load Diff

64
compat.py Normal file
View File

@@ -0,0 +1,64 @@
import sys
if sys.version_info < (3,):
def isbasestring(s):
return isinstance(s, basestring)
def open_utf8(filename, mode):
return open(filename, mode)
def byte_to_str(x):
return str(ord(x))
import cStringIO
def StringIO():
return cStringIO.StringIO()
def encode_utf8(x):
return x
def decode_utf8(x):
return x
def iteritems(d):
return d.iteritems()
def escape_string(s):
if isinstance(s, unicode):
s = s.encode('ascii')
result = ''
for c in s:
if not (32 <= ord(c) < 127) or c in ('\\', '"'):
result += '\\%03o' % ord(c)
else:
result += c
return result
else:
def isbasestring(s):
return isinstance(s, (str, bytes))
def open_utf8(filename, mode):
return open(filename, mode, encoding="utf-8")
def byte_to_str(x):
return str(x)
import io
def StringIO():
return io.StringIO()
import codecs
def encode_utf8(x):
return codecs.utf_8_encode(x)[0]
def decode_utf8(x):
return codecs.utf_8_decode(x)[0]
def iteritems(d):
return iter(d.items())
def charcode_to_c_escapes(c):
rev_result = []
while c >= 256:
c, low = (c // 256, c % 256)
rev_result.append('\\%03o' % low)
rev_result.append('\\%03o' % c)
return ''.join(reversed(rev_result))
def escape_string(s):
result = ''
if isinstance(s, str):
s = s.encode('utf-8')
for c in s:
if not(32 <= c < 127) or c in (ord('\\'), ord('"')):
result += charcode_to_c_escapes(c)
else:
result += chr(c)
return result

View File

@@ -1,301 +1,110 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
import os
import core_builders
import methods
Import('env')
env.core_sources = []
# Add required thirdparty code.
thirdparty_obj = []
# Generate global defaults
gd_call = ""
gd_inc = ""
env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()
for x in env.global_defaults:
env.core_sources.append("#platform/" + x + "/globals/global_defaults.cpp")
gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n'
gd_call += "\tregister_" + x + "_global_defaults();\n"
# Misc thirdparty code: header paths are hardcoded, we don't need to append
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
thirdparty_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"fastlz.c",
"r128.c",
"smaz.c",
# C++ sources
"pcg.cpp",
"polypartition.cpp",
"smolv.cpp",
]
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources)
gd_cpp = '#include "project_settings.h"\n'
gd_cpp += gd_inc
gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
# Brotli
if env["brotli"] and env["builtin_brotli"]:
thirdparty_brotli_dir = "#thirdparty/brotli/"
thirdparty_brotli_sources = [
"common/constants.c",
"common/context.c",
"common/dictionary.c",
"common/platform.c",
"common/shared_dictionary.c",
"common/transform.c",
"dec/bit_reader.c",
"dec/decode.c",
"dec/huffman.c",
"dec/state.c",
]
thirdparty_brotli_sources = [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
env.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
if env.get("use_ubsan") or env.get("use_asan") or env.get("use_tsan") or env.get("use_lsan") or env.get("use_msan"):
env_thirdparty.Append(CPPDEFINES=["BROTLI_BUILD_PORTABLE"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_brotli_sources)
# Clipper2 Thirdparty source files used for polygon and polyline boolean operations.
if env["builtin_clipper2"]:
thirdparty_clipper_dir = "#thirdparty/clipper2/"
thirdparty_clipper_sources = [
"src/clipper.engine.cpp",
"src/clipper.offset.cpp",
"src/clipper.rectclip.cpp",
]
thirdparty_clipper_sources = [thirdparty_clipper_dir + file for file in thirdparty_clipper_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"])
env.Prepend(CPPPATH=[thirdparty_clipper_dir + "include"])
env_thirdparty.Append(CPPDEFINES=["CLIPPER2_ENABLED"])
env.Append(CPPDEFINES=["CLIPPER2_ENABLED"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_clipper_sources)
# Zlib library, can be unbundled
if env["builtin_zlib"]:
thirdparty_zlib_dir = "#thirdparty/zlib/"
thirdparty_zlib_sources = [
"adler32.c",
"compress.c",
"crc32.c",
"deflate.c",
"inffast.c",
"inflate.c",
"inftrees.c",
"trees.c",
"uncompr.c",
"zutil.c",
]
thirdparty_zlib_sources = [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_zlib_dir])
# Needs to be available in main env too
env.Prepend(CPPPATH=[thirdparty_zlib_dir])
if env.dev_build:
env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"])
# Affects headers so it should also be defined for Godot code
env.Append(CPPDEFINES=["ZLIB_DEBUG"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zlib_sources)
# Minizip library, could be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = ["ioapi.c", "unzip.c", "zip.c"]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_minizip_sources)
# Zstd library, can be unbundled in theory
# though we currently use some private symbols
# https://github.com/godotengine/godot/issues/17374
if env["builtin_zstd"]:
thirdparty_zstd_dir = "#thirdparty/zstd/"
thirdparty_zstd_sources = [
"common/debug.c",
"common/entropy_common.c",
"common/error_private.c",
"common/fse_decompress.c",
"common/pool.c",
"common/threading.c",
"common/xxhash.c",
"common/zstd_common.c",
"compress/fse_compress.c",
"compress/hist.c",
"compress/huf_compress.c",
"compress/zstd_compress.c",
"compress/zstd_double_fast.c",
"compress/zstd_fast.c",
"compress/zstd_lazy.c",
"compress/zstd_ldm.c",
"compress/zstd_opt.c",
"compress/zstdmt_compress.c",
"compress/zstd_compress_literals.c",
"compress/zstd_compress_sequences.c",
"compress/zstd_compress_superblock.c",
"decompress/huf_decompress.c",
"decompress/zstd_ddict.c",
"decompress/zstd_decompress_block.c",
"decompress/zstd_decompress.c",
]
if env["platform"] in ["android", "ios", "linuxbsd", "macos"] and env["arch"] == "x86_64":
# Match platforms with ZSTD_ASM_SUPPORTED in common/portability_macros.h
thirdparty_zstd_sources.append("decompress/huf_decompress_amd64.S")
thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
env.Prepend(CPPPATH=thirdparty_zstd_dir)
# Also needed in main env includes will trigger warnings
env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"])
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_zstd_sources)
env.core_sources += thirdparty_obj
# Godot source files
env.add_source_files(env.core_sources, "*.cpp")
# Generate disabled classes
def disabled_class_builder(target, source, env):
with methods.generated_wrapper(target) as file:
for c in source[0].read():
cs = c.strip()
if cs != "":
file.write(f"#define ClassDB_Disable_{cs} 1\n")
env.CommandNoCache("disabled_classes.gen.h", env.Value(env.disabled_classes), env.Run(disabled_class_builder))
# Generate version info
def version_info_builder(target, source, env):
with methods.generated_wrapper(target) as file:
file.write(
"""\
#define VERSION_SHORT_NAME "{short_name}"
#define VERSION_NAME "{name}"
#define VERSION_MAJOR {major}
#define VERSION_MINOR {minor}
#define VERSION_PATCH {patch}
#define VERSION_STATUS "{status}"
#define VERSION_BUILD "{build}"
#define VERSION_MODULE_CONFIG "{module_config}"
#define VERSION_WEBSITE "{website}"
#define VERSION_DOCS_BRANCH "{docs_branch}"
#define VERSION_DOCS_URL "https://docs.godotengine.org/en/" VERSION_DOCS_BRANCH
""".format(**env.version_info)
)
env.CommandNoCache("version_generated.gen.h", env.Value(env.version_info), env.Run(version_info_builder))
# Generate version hash
def version_hash_builder(target, source, env):
with methods.generated_wrapper(target) as file:
file.write(
"""\
#include "core/version.h"
const char *const VERSION_HASH = "{git_hash}";
const uint64_t VERSION_TIMESTAMP = {git_timestamp};
""".format(**env.version_info)
)
gen_hash = env.CommandNoCache(
"version_hash.gen.cpp", env.Value(env.version_info["git_hash"]), env.Run(version_hash_builder)
)
env.add_source_files(env.core_sources, gen_hash)
f = open("global_defaults.gen.cpp", "w")
f.write(gd_cpp)
f.close()
# Generate AES256 script encryption key
def encryption_key_builder(target, source, env):
with methods.generated_wrapper(target) as file:
file.write(
f"""\
#include "core/config/project_settings.h"
uint8_t script_encryption_key[32] = {{
{source[0]}
}};"""
)
gdkey = os.environ.get("SCRIPT_AES256_ENCRYPTION_KEY", "0" * 64)
ec_valid = len(gdkey) == 64
if ec_valid:
try:
gdkey = ", ".join([str(int(f"{a}{b}", 16)) for a, b in zip(gdkey[0::2], gdkey[1::2])])
except Exception:
import os
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
txt = ""
ec_valid = True
if (len(e) != 64):
ec_valid = False
if not ec_valid:
methods.print_error(
f'Invalid AES256 encryption key, not 64 hexadecimal characters: "{gdkey}".\n'
"Unset `SCRIPT_AES256_ENCRYPTION_KEY` in your environment "
"or make sure that it contains exactly 64 hexadecimal characters."
)
Exit(255)
gen_encrypt = env.CommandNoCache("script_encryption_key.gen.cpp", env.Value(gdkey), env.Run(encryption_key_builder))
env.add_source_files(env.core_sources, gen_encrypt)
else:
for i in range(len(e) >> 1):
if (i > 0):
txt += ","
txts = "0x" + e[i * 2:i * 2 + 2]
try:
int(txts, 16)
except:
ec_valid = False
txt += txts
if (not ec_valid):
txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0"
print("Invalid AES256 encryption key, not 64 bits hex: " + e)
f = open("script_encryption_key.gen.cpp", "w")
f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
# Certificates
env.Depends(
"#core/io/certs_compressed.gen.h",
["#thirdparty/certs/ca-certificates.crt", env.Value(env["builtin_certs"]), env.Value(env["system_certs_path"])],
)
env.CommandNoCache(
"#core/io/certs_compressed.gen.h",
"#thirdparty/certs/ca-certificates.crt",
env.Run(core_builders.make_certs_header),
)
# Add required thirdparty code. Header paths are hardcoded, we don't need to append
# to the include path (saves a few chars on the compiler invocation for touchy MSVC...)
thirdparty_dir = "#thirdparty/misc/"
thirdparty_sources = [
# C sources
"base64.c",
"fastlz.c",
"sha256.c",
"smaz.c",
# Authors
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header))
# C++ sources
"aes256.cpp",
"hq2x.cpp",
"md5.cpp",
"pcg.cpp",
"triangulator.cpp",
]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env.add_source_files(env.core_sources, thirdparty_sources)
# Donors
env.Depends("#core/donors.gen.h", "../DONORS.md")
env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header))
# Minizip library, can be unbundled in theory
# However, our version has some custom modifications, so it won't compile with the system one
thirdparty_minizip_dir = "#thirdparty/minizip/"
thirdparty_minizip_sources = [
"ioapi.c",
"unzip.c",
"zip.c",
]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env.add_source_files(env.core_sources, thirdparty_minizip_sources)
if 'builtin_zstd' in env and env['builtin_zstd']:
SConscript("#thirdparty/zstd/SCsub")
# Godot's own sources
env.add_source_files(env.core_sources, "*.cpp")
# Make binders
import make_binders
env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run)
# License
env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.CommandNoCache(
"#core/license.gen.h",
["../COPYRIGHT.txt", "../LICENSE.txt"],
env.Run(core_builders.make_license_header),
)
# Chain load SCsubs
SConscript("os/SCsub")
SConscript("math/SCsub")
SConscript("crypto/SCsub")
SConscript("io/SCsub")
SConscript("debugger/SCsub")
SConscript("input/SCsub")
SConscript("variant/SCsub")
SConscript("extension/SCsub")
SConscript("object/SCsub")
SConscript("templates/SCsub")
SConscript("string/SCsub")
SConscript("config/SCsub")
SConscript("error/SCsub")
SConscript('os/SCsub')
SConscript('math/SCsub')
SConscript('io/SCsub')
SConscript('bind/SCsub')
SConscript('helper/SCsub')
# Build it all as a library
lib = env.add_library("core", env.core_sources)
env.Prepend(LIBS=[lib])
# Needed to force rebuilding the core files when the thirdparty code is updated.
env.Depends(lib, thirdparty_obj)
Export('env')

194
core/allocators.h Normal file
View File

@@ -0,0 +1,194 @@
/*************************************************************************/
/* allocators.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef ALLOCATORS_H
#define ALLOCATORS_H
#include "os/memory.h"
template <int PREALLOC_COUNT = 64, int MAX_HANDS = 8>
class BalloonAllocator {
enum {
USED_FLAG = (1 << 30),
USED_MASK = USED_FLAG - 1
};
struct Balloon {
Balloon *next;
Balloon *prev;
uint32_t hand;
};
struct Hand {
int used;
int allocated;
Balloon *first;
Balloon *last;
};
Hand hands[MAX_HANDS];
public:
void *alloc(size_t p_size) {
size_t max = (1 << MAX_HANDS);
ERR_FAIL_COND_V(p_size > max, NULL);
unsigned int hand = 0;
while (p_size > (size_t)(1 << hand))
++hand;
Hand &h = hands[hand];
if (h.used == h.allocated) {
for (int i = 0; i < PREALLOC_COUNT; i++) {
Balloon *b = (Balloon *)memalloc(sizeof(Balloon) + (1 << hand));
b->hand = hand;
if (h.last) {
b->prev = h.last;
h.last->next = b;
h.last = b;
} else {
b->prev = NULL;
h.last = b;
h.first = b;
}
}
h.last->next = NULL;
h.allocated += PREALLOC_COUNT;
}
Balloon *pick = h.last;
ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL);
// remove last
h.last = h.last->prev;
h.last->next = NULL;
pick->next = h.first;
h.first->prev = pick;
pick->prev = NULL;
h.first = pick;
h.used++;
pick->hand |= USED_FLAG;
return (void *)(pick + 1);
}
void free(void *p_ptr) {
Balloon *b = (Balloon *)p_ptr;
b -= 1;
ERR_FAIL_COND(!(b->hand & USED_FLAG));
b->hand = b->hand & USED_MASK; // not used
int hand = b->hand;
Hand &h = hands[hand];
if (b == h.first)
h.first = b->next;
if (b->prev)
b->prev->next = b->next;
if (b->next)
b->next->prev = b->prev;
if (h.last != b) {
h.last->next = b;
b->prev = h.last;
b->next = NULL;
h.last = b;
}
h.used--;
if (h.used <= (h.allocated - (PREALLOC_COUNT * 2))) { // this is done to ensure no alloc/free is done constantly
for (int i = 0; i < PREALLOC_COUNT; i++) {
ERR_CONTINUE(h.last->hand & USED_FLAG);
Balloon *new_last = h.last->prev;
if (new_last)
new_last->next = NULL;
memfree(h.last);
h.last = new_last;
}
h.allocated -= PREALLOC_COUNT;
}
}
BalloonAllocator() {
for (int i = 0; i < MAX_HANDS; i++) {
hands[i].allocated = 0;
hands[i].used = 0;
hands[i].first = NULL;
hands[i].last = NULL;
}
}
void clear() {
for (int i = 0; i < MAX_HANDS; i++) {
while (hands[i].first) {
Balloon *b = hands[i].first;
hands[i].first = b->next;
memfree(b);
}
hands[i].allocated = 0;
hands[i].used = 0;
hands[i].first = NULL;
hands[i].last = NULL;
}
}
~BalloonAllocator() {
clear();
}
};
#endif // ALLOCATORS_H

357
core/array.cpp Normal file
View File

@@ -0,0 +1,357 @@
/*************************************************************************/
/* array.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "array.h"
#include "hashfuncs.h"
#include "object.h"
#include "variant.h"
#include "vector.h"
struct ArrayPrivate {
SafeRefCount refcount;
Vector<Variant> array;
};
void Array::_ref(const Array &p_from) const {
ArrayPrivate *_fp = p_from._p;
ERR_FAIL_COND(!_fp); // should NOT happen.
if (_fp == _p)
return; // whatever it is, nothing to do here move along
bool success = _fp->refcount.ref();
ERR_FAIL_COND(!success); // should really not happen either
_unref();
_p = p_from._p;
}
void Array::_unref() const {
if (!_p)
return;
if (_p->refcount.unref()) {
memdelete(_p);
}
_p = NULL;
}
Variant &Array::operator[](int p_idx) {
return _p->array[p_idx];
}
const Variant &Array::operator[](int p_idx) const {
return _p->array[p_idx];
}
int Array::size() const {
return _p->array.size();
}
bool Array::empty() const {
return _p->array.empty();
}
void Array::clear() {
_p->array.clear();
}
bool Array::operator==(const Array &p_array) const {
return _p == p_array._p;
}
uint32_t Array::hash() const {
uint32_t h = hash_djb2_one_32(0);
for (int i = 0; i < _p->array.size(); i++) {
h = hash_djb2_one_32(_p->array[i].hash(), h);
}
return h;
}
void Array::operator=(const Array &p_array) {
_ref(p_array);
}
void Array::push_back(const Variant &p_value) {
_p->array.push_back(p_value);
}
Error Array::resize(int p_new_size) {
return _p->array.resize(p_new_size);
}
void Array::insert(int p_pos, const Variant &p_value) {
_p->array.insert(p_pos, p_value);
}
void Array::erase(const Variant &p_value) {
_p->array.erase(p_value);
}
Variant Array::front() const {
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
return operator[](0);
}
Variant Array::back() const {
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
return operator[](_p->array.size() - 1);
}
int Array::find(const Variant &p_value, int p_from) const {
return _p->array.find(p_value, p_from);
}
int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array.size() == 0)
return -1;
if (p_from < 0) {
// Relative offset from the end
p_from = _p->array.size() + p_from;
}
if (p_from < 0 || p_from >= _p->array.size()) {
// Limit to array boundaries
p_from = _p->array.size() - 1;
}
for (int i = p_from; i >= 0; i--) {
if (_p->array[i] == p_value) {
return i;
};
};
return -1;
}
int Array::find_last(const Variant &p_value) const {
return rfind(p_value);
}
int Array::count(const Variant &p_value) const {
if (_p->array.size() == 0)
return 0;
int amount = 0;
for (int i = 0; i < _p->array.size(); i++) {
if (_p->array[i] == p_value) {
amount++;
};
};
return amount;
}
bool Array::has(const Variant &p_value) const {
return _p->array.find(p_value, 0) != -1;
}
void Array::remove(int p_pos) {
_p->array.remove(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
operator[](p_idx) = p_value;
}
const Variant &Array::get(int p_idx) const {
return operator[](p_idx);
}
Array Array::duplicate() const {
Array new_arr;
int element_count = size();
new_arr.resize(element_count);
for (int i = 0; i < element_count; i++) {
new_arr[i] = get(i);
}
return new_arr;
}
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
Variant res;
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
if (!valid)
res = false;
return res;
}
};
Array &Array::sort() {
_p->array.sort_custom<_ArrayVariantSort>();
return *this;
}
struct _ArrayVariantSortCustom {
Object *obj;
StringName func;
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
const Variant *args[2] = { &p_l, &p_r };
Variant::CallError err;
bool res = obj->call(func, args, 2, err);
if (err.error != Variant::CallError::CALL_OK)
res = false;
return res;
}
};
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
ERR_FAIL_NULL_V(p_obj, *this);
SortArray<Variant, _ArrayVariantSortCustom> avs;
avs.compare.obj = p_obj;
avs.compare.func = p_function;
avs.sort(_p->array.ptrw(), _p->array.size());
return *this;
}
template <typename Less>
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
int lo = 0;
int hi = p_array.size();
if (p_before) {
while (lo < hi) {
const int mid = (lo + hi) / 2;
if (p_less(p_array.get(mid), p_value)) {
lo = mid + 1;
} else {
hi = mid;
}
}
} else {
while (lo < hi) {
const int mid = (lo + hi) / 2;
if (p_less(p_value, p_array.get(mid))) {
hi = mid;
} else {
lo = mid + 1;
}
}
}
return lo;
}
int Array::bsearch(const Variant &p_value, bool p_before) {
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
}
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
ERR_FAIL_NULL_V(p_obj, 0);
_ArrayVariantSortCustom less;
less.obj = p_obj;
less.func = p_function;
return bisect(_p->array, p_value, p_before, less);
}
Array &Array::invert() {
_p->array.invert();
return *this;
}
void Array::push_front(const Variant &p_value) {
_p->array.insert(0, p_value);
}
Variant Array::pop_back() {
if (!_p->array.empty()) {
int n = _p->array.size() - 1;
Variant ret = _p->array.get(n);
_p->array.resize(n);
return ret;
}
return Variant();
}
Variant Array::pop_front() {
if (!_p->array.empty()) {
Variant ret = _p->array.get(0);
_p->array.remove(0);
return ret;
}
return Variant();
}
Array::Array(const Array &p_from) {
_p = NULL;
_ref(p_from);
}
Array::Array() {
_p = memnew(ArrayPrivate);
_p->refcount.init();
}
Array::~Array() {
_unref();
}

97
core/array.h Normal file
View File

@@ -0,0 +1,97 @@
/*************************************************************************/
/* array.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef ARRAY_H
#define ARRAY_H
#include "typedefs.h"
class Variant;
class ArrayPrivate;
class Object;
class StringName;
class Array {
mutable ArrayPrivate *_p;
void _ref(const Array &p_from) const;
void _unref() const;
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
void set(int p_idx, const Variant &p_value);
const Variant &get(int p_idx) const;
int size() const;
bool empty() const;
void clear();
bool operator==(const Array &p_array) const;
uint32_t hash() const;
void operator=(const Array &p_array);
void push_back(const Variant &p_value);
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
Error resize(int p_new_size);
void insert(int p_pos, const Variant &p_value);
void remove(int p_pos);
Variant front() const;
Variant back() const;
Array &sort();
Array &sort_custom(Object *p_obj, const StringName &p_function);
int bsearch(const Variant &p_value, bool p_before = true);
int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true);
Array &invert();
int find(const Variant &p_value, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
int find_last(const Variant &p_value) const;
int count(const Variant &p_value) const;
bool has(const Variant &p_value) const;
void erase(const Variant &p_value);
void push_front(const Variant &p_value);
Variant pop_back();
Variant pop_front();
Array duplicate() const;
Array(const Array &p_from);
Array();
~Array();
};
#endif // ARRAY_H

7
core/bind/SCsub Normal file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/env python
Import('env')
env.add_source_files(env.core_sources, "*.cpp")
Export('env')

2793
core/bind/core_bind.cpp Normal file

File diff suppressed because it is too large Load Diff

737
core/bind/core_bind.h Normal file
View File

@@ -0,0 +1,737 @@
/*************************************************************************/
/* core_bind.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef CORE_BIND_H
#define CORE_BIND_H
#include "image.h"
#include "io/compression.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/dir_access.h"
#include "os/file_access.h"
#include "os/os.h"
#include "os/semaphore.h"
#include "os/thread.h"
class _ResourceLoader : public Object {
GDCLASS(_ResourceLoader, Object);
protected:
static void _bind_methods();
static _ResourceLoader *singleton;
public:
static _ResourceLoader *get_singleton() { return singleton; }
Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "");
RES load(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false);
PoolVector<String> get_recognized_extensions_for_type(const String &p_type);
void set_abort_on_missing_resources(bool p_abort);
PoolStringArray get_dependencies(const String &p_path);
bool has(const String &p_path);
_ResourceLoader();
};
class _ResourceSaver : public Object {
GDCLASS(_ResourceSaver, Object);
protected:
static void _bind_methods();
static _ResourceSaver *singleton;
public:
enum SaverFlags {
FLAG_RELATIVE_PATHS = 1,
FLAG_BUNDLE_RESOURCES = 2,
FLAG_CHANGE_PATH = 4,
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
};
static _ResourceSaver *get_singleton() { return singleton; }
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags);
PoolVector<String> get_recognized_extensions(const RES &p_resource);
_ResourceSaver();
};
VARIANT_ENUM_CAST(_ResourceSaver::SaverFlags);
class MainLoop;
class _OS : public Object {
GDCLASS(_OS, Object);
protected:
static void _bind_methods();
static _OS *singleton;
public:
enum PowerState {
POWERSTATE_UNKNOWN, /**< cannot determine power status */
POWERSTATE_ON_BATTERY, /**< Not plugged in, running on the battery */
POWERSTATE_NO_BATTERY, /**< Plugged in, no battery available */
POWERSTATE_CHARGING, /**< Plugged in, charging battery */
POWERSTATE_CHARGED /**< Plugged in, battery charged */
};
enum Weekday {
DAY_SUNDAY,
DAY_MONDAY,
DAY_TUESDAY,
DAY_WEDNESDAY,
DAY_THURSDAY,
DAY_FRIDAY,
DAY_SATURDAY
};
enum Month {
/// Start at 1 to follow Windows SYSTEMTIME structure
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
MONTH_JANUARY = 1,
MONTH_FEBRUARY,
MONTH_MARCH,
MONTH_APRIL,
MONTH_MAY,
MONTH_JUNE,
MONTH_JULY,
MONTH_AUGUST,
MONTH_SEPTEMBER,
MONTH_OCTOBER,
MONTH_NOVEMBER,
MONTH_DECEMBER
};
Point2 get_mouse_position() const;
void set_window_title(const String &p_title);
int get_mouse_button_state() const;
void set_clipboard(const String &p_text);
String get_clipboard() const;
void set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen = 0);
Size2 get_video_mode(int p_screen = 0) const;
bool is_video_mode_fullscreen(int p_screen = 0) const;
bool is_video_mode_resizable(int p_screen = 0) const;
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_screen_count() const;
virtual int get_current_screen() const;
virtual void set_current_screen(int p_screen);
virtual Point2 get_screen_position(int p_screen = -1) const;
virtual Size2 get_screen_size(int p_screen = -1) const;
virtual int get_screen_dpi(int p_screen = -1) const;
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2 &p_position);
virtual Size2 get_window_size() const;
virtual Size2 get_real_window_size() const;
virtual Rect2 get_window_safe_area() const;
virtual void set_window_size(const Size2 &p_size);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
virtual void set_window_resizable(bool p_enabled);
virtual bool is_window_resizable() const;
virtual void set_window_minimized(bool p_enabled);
virtual bool is_window_minimized() const;
virtual void set_window_maximized(bool p_enabled);
virtual bool is_window_maximized() const;
virtual void set_window_always_on_top(bool p_enabled);
virtual bool is_window_always_on_top() const;
virtual void request_attention();
virtual void center_window();
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const;
virtual void set_ime_position(const Point2 &p_pos);
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
void native_video_pause();
void native_video_unpause();
void native_video_stop();
void set_low_processor_usage_mode(bool p_enabled);
bool is_in_low_processor_usage_mode() const;
String get_executable_path() const;
int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output = Array());
Error kill(int p_pid);
Error shell_open(String p_uri);
int get_process_id() const;
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
String get_name() const;
Vector<String> get_cmdline_args();
String get_locale() const;
String get_latin_keyboard_variant() const;
String get_model_name() const;
void dump_memory_to_file(const String &p_file);
void dump_resources_to_file(const String &p_file);
bool has_virtual_keyboard() const;
void show_virtual_keyboard(const String &p_existing_text = "");
void hide_virtual_keyboard();
int get_virtual_keyboard_height();
void print_resources_in_use(bool p_short = false);
void print_all_resources(const String &p_to_file);
void print_all_textures_by_size();
void print_resources_by_type(const Vector<String> &p_types);
bool has_touchscreen_ui_hint() const;
bool is_debug_build() const;
String get_unique_id() const;
String get_scancode_string(uint32_t p_code) const;
bool is_scancode_unicode(uint32_t p_unicode) const;
int find_scancode_from_string(const String &p_code) const;
/*
struct Date {
int year;
Month month;
int day;
Weekday weekday;
bool dst;
};
struct Time {
int hour;
int min;
int sec;
};
*/
void set_use_file_access_save_and_swap(bool p_enable);
void set_icon(const Ref<Image> &p_icon);
int get_exit_code() const;
void set_exit_code(int p_code);
Dictionary get_date(bool utc) const;
Dictionary get_time(bool utc) const;
Dictionary get_datetime(bool utc) const;
Dictionary get_datetime_from_unix_time(uint64_t unix_time_val) const;
uint64_t get_unix_time_from_datetime(Dictionary datetime) const;
Dictionary get_time_zone_info() const;
uint64_t get_unix_time() const;
uint64_t get_system_time_secs() const;
int get_static_memory_usage() const;
int get_static_memory_peak_usage() const;
int get_dynamic_memory_usage() const;
void delay_usec(uint32_t p_usec) const;
void delay_msec(uint32_t p_msec) const;
uint32_t get_ticks_msec() const;
uint32_t get_splash_tick_msec() const;
bool can_use_threads() const;
bool can_draw() const;
bool is_userfs_persistent() const;
bool is_stdout_verbose() const;
int get_processor_count() const;
enum SystemDir {
SYSTEM_DIR_DESKTOP,
SYSTEM_DIR_DCIM,
SYSTEM_DIR_DOCUMENTS,
SYSTEM_DIR_DOWNLOADS,
SYSTEM_DIR_MOVIES,
SYSTEM_DIR_MUSIC,
SYSTEM_DIR_PICTURES,
SYSTEM_DIR_RINGTONES,
};
enum ScreenOrientation {
SCREEN_ORIENTATION_LANDSCAPE,
SCREEN_ORIENTATION_PORTRAIT,
SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
SCREEN_ORIENTATION_REVERSE_PORTRAIT,
SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
SCREEN_ORIENTATION_SENSOR_PORTRAIT,
SCREEN_ORIENTATION_SENSOR,
};
String get_system_dir(SystemDir p_dir) const;
String get_user_data_dir() const;
void alert(const String &p_alert, const String &p_title = "ALERT!");
void set_screen_orientation(ScreenOrientation p_orientation);
ScreenOrientation get_screen_orientation() const;
void set_keep_screen_on(bool p_enabled);
bool is_keep_screen_on() const;
bool is_ok_left_and_cancel_right() const;
Error set_thread_name(const String &p_name);
void set_use_vsync(bool p_enable);
bool is_vsync_enabled() const;
PowerState get_power_state();
int get_power_seconds_left();
int get_power_percent_left();
bool has_feature(const String &p_feature) const;
static _OS *get_singleton() { return singleton; }
_OS();
};
VARIANT_ENUM_CAST(_OS::PowerState);
VARIANT_ENUM_CAST(_OS::Weekday);
VARIANT_ENUM_CAST(_OS::Month);
VARIANT_ENUM_CAST(_OS::SystemDir);
VARIANT_ENUM_CAST(_OS::ScreenOrientation);
class _Geometry : public Object {
GDCLASS(_Geometry, Object);
static _Geometry *singleton;
protected:
static void _bind_methods();
public:
static _Geometry *get_singleton();
PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
PoolVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
PoolVector<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
Variant segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
PoolVector<Vector2> get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
PoolVector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Variant ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
PoolVector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
PoolVector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
PoolVector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
int get_uv84_normal_bit(const Vector3 &p_vector);
Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon);
Vector<Point2> convex_hull_2d(const Vector<Point2> &p_points);
Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane);
Dictionary make_atlas(const Vector<Size2> &p_rects);
_Geometry();
};
class _File : public Reference {
GDCLASS(_File, Reference);
FileAccess *f;
bool eswap;
protected:
static void _bind_methods();
public:
enum ModeFlags {
READ = 1,
WRITE = 2,
READ_WRITE = 3,
WRITE_READ = 7,
};
enum CompressionMode {
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
COMPRESSION_ZSTD = Compression::MODE_ZSTD,
COMPRESSION_GZIP = Compression::MODE_GZIP
};
Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key);
Error open_encrypted_pass(const String &p_path, int p_mode_flags, const String &p_pass);
Error open_compressed(const String &p_path, int p_mode_flags, int p_compress_mode = 0);
Error open(const String &p_path, int p_mode_flags); ///< open a file
void close(); ///< close a file
bool is_open() const; ///< true when file is open
String get_path() const; /// returns the path for the current open file
String get_path_absolute() const; /// returns the absolute path for the current open file
void seek(int64_t p_position); ///< seek to a given position
void seek_end(int64_t p_position = 0); ///< seek from the end of file
int64_t get_position() const; ///< get position in the file
int64_t get_len() const; ///< get size of the file
bool eof_reached() const; ///< reading passed EOF
uint8_t get_8() const; ///< get a byte
uint16_t get_16() const; ///< get 16 bits uint
uint32_t get_32() const; ///< get 32 bits uint
uint64_t get_64() const; ///< get 64 bits uint
float get_float() const;
double get_double() const;
real_t get_real() const;
Variant get_var() const;
PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
String get_as_text() const;
String get_md5(const String &p_path) const;
String get_sha256(const String &p_path) const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
* this flags get reset to false (little endian) on each open
*/
void set_endian_swap(bool p_swap);
bool get_endian_swap();
Error get_error() const; ///< get last error
void store_8(uint8_t p_dest); ///< store a byte
void store_16(uint16_t p_dest); ///< store 16 bits uint
void store_32(uint32_t p_dest); ///< store 32 bits uint
void store_64(uint64_t p_dest); ///< store 64 bits uint
void store_float(float p_dest);
void store_double(double p_dest);
void store_real(real_t p_real);
void store_string(const String &p_string);
void store_line(const String &p_string);
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
Vector<String> get_csv_line(String delim = ",") const;
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
void store_var(const Variant &p_var);
bool file_exists(const String &p_name) const; ///< return true if a file exists
uint64_t get_modified_time(const String &p_file) const;
_File();
virtual ~_File();
};
VARIANT_ENUM_CAST(_File::ModeFlags);
VARIANT_ENUM_CAST(_File::CompressionMode);
class _Directory : public Reference {
GDCLASS(_Directory, Reference);
DirAccess *d;
protected:
static void _bind_methods();
public:
Error open(const String &p_path);
Error list_dir_begin(bool p_skip_navigational = false, bool p_skip_hidden = false); ///< This starts dir listing
String get_next();
bool current_is_dir() const;
void list_dir_end(); ///<
int get_drive_count();
String get_drive(int p_drive);
int get_current_drive();
Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
String get_current_dir(); ///< return current dir location
Error make_dir(String p_dir);
Error make_dir_recursive(String p_dir);
bool file_exists(String p_file);
bool dir_exists(String p_dir);
int get_space_left();
Error copy(String p_from, String p_to);
Error rename(String p_from, String p_to);
Error remove(String p_name);
_Directory();
virtual ~_Directory();
private:
bool _list_skip_navigational;
bool _list_skip_hidden;
};
class _Marshalls : public Reference {
GDCLASS(_Marshalls, Reference);
static _Marshalls *singleton;
protected:
static void _bind_methods();
public:
static _Marshalls *get_singleton();
String variant_to_base64(const Variant &p_var);
Variant base64_to_variant(const String &p_str);
String raw_to_base64(const PoolVector<uint8_t> &p_arr);
PoolVector<uint8_t> base64_to_raw(const String &p_str);
String utf8_to_base64(const String &p_str);
String base64_to_utf8(const String &p_str);
_Marshalls() { singleton = this; }
~_Marshalls() { singleton = NULL; }
};
class _Mutex : public Reference {
GDCLASS(_Mutex, Reference);
Mutex *mutex;
static void _bind_methods();
public:
void lock();
Error try_lock();
void unlock();
_Mutex();
~_Mutex();
};
class _Semaphore : public Reference {
GDCLASS(_Semaphore, Reference);
Semaphore *semaphore;
static void _bind_methods();
public:
Error wait();
Error post();
_Semaphore();
~_Semaphore();
};
class _Thread : public Reference {
GDCLASS(_Thread, Reference);
protected:
Variant ret;
Variant userdata;
volatile bool active;
Object *target_instance;
StringName target_method;
Thread *thread;
static void _bind_methods();
static void _start_func(void *ud);
public:
enum Priority {
PRIORITY_LOW,
PRIORITY_NORMAL,
PRIORITY_HIGH
};
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), int p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_active() const;
Variant wait_to_finish();
_Thread();
~_Thread();
};
VARIANT_ENUM_CAST(_Thread::Priority);
class _ClassDB : public Object {
GDCLASS(_ClassDB, Object)
protected:
static void _bind_methods();
public:
PoolStringArray get_class_list() const;
PoolStringArray get_inheriters_from_class(const StringName &p_class) const;
StringName get_parent_class(const StringName &p_class) const;
bool class_exists(const StringName &p_class) const;
bool is_parent_class(const StringName &p_class, const StringName &p_inherits) const;
bool can_instance(const StringName &p_class) const;
Variant instance(const StringName &p_class) const;
bool has_signal(StringName p_class, StringName p_signal) const;
Dictionary get_signal(StringName p_class, StringName p_signal) const;
Array get_signal_list(StringName p_class, bool p_no_inheritance = false) const;
Array get_property_list(StringName p_class, bool p_no_inheritance = false) const;
Variant get_property(Object *p_object, const StringName &p_property) const;
Error set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const;
bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const;
Array get_method_list(StringName p_class, bool p_no_inheritance = false) const;
PoolStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
bool has_integer_constant(const StringName &p_class, const StringName &p_name) const;
int get_integer_constant(const StringName &p_class, const StringName &p_name) const;
StringName get_category(const StringName &p_node) const;
bool is_class_enabled(StringName p_class) const;
_ClassDB();
~_ClassDB();
};
class _Engine : public Object {
GDCLASS(_Engine, Object);
protected:
static void _bind_methods();
static _Engine *singleton;
public:
static _Engine *get_singleton() { return singleton; }
void set_iterations_per_second(int p_ips);
int get_iterations_per_second() const;
void set_target_fps(int p_fps);
int get_target_fps() const;
float get_frames_per_second() const;
int get_frames_drawn();
void set_time_scale(float p_scale);
float get_time_scale();
MainLoop *get_main_loop() const;
Dictionary get_version_info() const;
bool is_in_physics_frame() const;
bool has_singleton(const String &p_name) const;
Object *get_singleton_object(const String &p_name) const;
void set_editor_hint(bool p_enabled);
bool is_editor_hint() const;
_Engine();
};
class _JSON;
class JSONParseResult : public Reference {
GDCLASS(JSONParseResult, Reference)
friend class _JSON;
Error error;
String error_string;
int error_line;
Variant result;
protected:
static void _bind_methods();
public:
void set_error(Error p_error);
Error get_error() const;
void set_error_string(const String &p_error_string);
String get_error_string() const;
void set_error_line(int p_error_line);
int get_error_line() const;
void set_result(const Variant &p_result);
Variant get_result() const;
};
class _JSON : public Object {
GDCLASS(_JSON, Object)
protected:
static void _bind_methods();
static _JSON *singleton;
public:
static _JSON *get_singleton() { return singleton; }
String print(const Variant &p_value, const String &p_indent = "", bool p_sort_keys = false);
Ref<JSONParseResult> parse(const String &p_json);
_JSON();
};
#endif // CORE_BIND_H

1415
core/class_db.cpp Normal file

File diff suppressed because it is too large Load Diff

400
core/class_db.h Normal file
View File

@@ -0,0 +1,400 @@
/*************************************************************************/
/* class_db.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef CLASS_DB_H
#define CLASS_DB_H
#include "method_bind.h"
#include "object.h"
#include "print_string.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#define DEFVAL(m_defval) (m_defval)
//#define SIMPLE_METHODDEF
#ifdef DEBUG_METHODS_ENABLED
struct MethodDefinition {
StringName name;
Vector<StringName> args;
MethodDefinition() {}
MethodDefinition(const char *p_name) :
name(p_name) {}
MethodDefinition(const StringName &p_name) :
name(p_name) {}
};
MethodDefinition D_METHOD(const char *p_name);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13);
#else
//#define NO_VARIADIC_MACROS
#ifdef NO_VARIADIC_MACROS
static _FORCE_INLINE_ const char *D_METHOD(const char *m_name, ...) {
return m_name;
}
#else
// When DEBUG_METHODS_ENABLED is set this will let the engine know
// the argument names for easier debugging.
#define D_METHOD(m_c, ...) m_c
#endif
#endif
class ClassDB {
public:
enum APIType {
API_CORE,
API_EDITOR,
API_NONE
};
public:
struct PropertySetGet {
int index;
StringName setter;
StringName getter;
MethodBind *_setptr;
MethodBind *_getptr;
Variant::Type type;
};
struct ClassInfo {
APIType api;
ClassInfo *inherits_ptr;
HashMap<StringName, MethodBind *, StringNameHasher> method_map;
HashMap<StringName, int, StringNameHasher> constant_map;
HashMap<StringName, MethodInfo, StringNameHasher> signal_map;
List<PropertyInfo> property_list;
#ifdef DEBUG_METHODS_ENABLED
HashMap<StringName, List<StringName> > enum_map;
List<StringName> constant_order;
List<StringName> method_order;
Set<StringName> methods_in_properties;
List<MethodInfo> virtual_methods;
StringName category;
#endif
HashMap<StringName, PropertySetGet, StringNameHasher> property_setget;
StringName inherits;
StringName name;
bool disabled;
bool exposed;
Object *(*creation_func)();
ClassInfo();
~ClassInfo();
};
template <class T>
static Object *creator() {
return memnew(T);
}
static RWLock *lock;
static HashMap<StringName, ClassInfo, StringNameHasher> classes;
static HashMap<StringName, StringName, StringNameHasher> resource_base_extensions;
static HashMap<StringName, StringName, StringNameHasher> compat_classes;
#ifdef DEBUG_METHODS_ENABLED
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const Variant **p_defs, int p_defcount);
#else
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const char *method_name, const Variant **p_defs, int p_defcount);
#endif
static APIType current_api;
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template <class T>
static void _add_class() {
_add_class2(T::get_class_static(), T::get_parent_class_static());
}
template <class T>
static void register_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->creation_func = &creator<T>;
t->exposed = true;
T::register_custom_data_to_otdb();
}
template <class T>
static void register_virtual_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->exposed = true;
//nothing
}
template <class T>
static Object *_create_ptr_func() {
return T::create();
}
template <class T>
static void register_custom_instance_class() {
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->creation_func = &_create_ptr_func<T>;
t->exposed = true;
T::register_custom_data_to_otdb();
}
static void get_class_list(List<StringName> *p_classes);
static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static StringName get_parent_class_nocheck(const StringName &p_class);
static StringName get_parent_class(const StringName &p_class);
static bool class_exists(const StringName &p_class);
static bool is_parent_class(const StringName &p_class, const StringName &p_inherits);
static bool can_instance(const StringName &p_class);
static Object *instance(const StringName &p_class);
static APIType get_api_type(const StringName &p_class);
static uint64_t get_api_hash(APIType p_api);
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method) {
MethodBind *bind = create_method_bind(p_method);
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, NULL, 0); //use static function, much smaller binary usage
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[1] = { &p_def1 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 1);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[2] = { &p_def1, &p_def2 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 2);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 3);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 4);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 5);
}
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6);
}
template <class M>
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>()) {
GLOBAL_LOCK_FUNCTION;
MethodBind *bind = create_vararg_method_bind(p_method, p_info);
ERR_FAIL_COND_V(!bind, NULL);
bind->set_name(p_name);
bind->set_default_arguments(p_default_args);
String instance_type = bind->get_instance_class();
ClassInfo *type = classes.getptr(instance_type);
if (!type) {
memdelete(bind);
ERR_FAIL_COND_V(!type, NULL);
}
if (type->method_map.has(p_name)) {
memdelete(bind);
// overloading not supported
ERR_EXPLAIN("Method already bound: " + instance_type + "::" + p_name);
ERR_FAIL_V(NULL);
}
type->method_map[p_name] = bind;
#ifdef DEBUG_METHODS_ENABLED
// FIXME: <reduz> set_return_type is no longer in MethodBind, so I guess it should be moved to vararg method bind
//bind->set_return_type("Variant");
type->method_order.push_back(p_name);
#endif
return bind;
}
static void add_signal(StringName p_class, const MethodInfo &p_signal);
static bool has_signal(StringName p_class, StringName p_signal);
static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal);
static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
static void add_property_group(StringName p_class, const String &p_name, const String &p_prefix = "");
static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = NULL);
static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = NULL);
static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL);
static StringName get_property_setter(StringName p_class, const StringName p_property);
static StringName get_property_getter(StringName p_class, const StringName p_property);
static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false);
static void set_method_flags(StringName p_class, StringName p_method, int p_flags);
static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static MethodBind *get_method(StringName p_class, StringName p_name);
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
static int get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = NULL);
#ifdef DEBUG_METHODS_ENABLED
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
#endif
static StringName get_category(const StringName &p_node);
static void set_class_enabled(StringName p_class, bool p_enable);
static bool is_class_enabled(StringName p_class);
static bool is_class_exposed(StringName p_class);
static void add_resource_base_extension(const StringName &p_extension, const StringName &p_class);
static void get_resource_base_extensions(List<String> *p_extensions);
static void get_extensions_for_type(const StringName &p_class, List<String> *p_extensions);
static void add_compatibility_class(const StringName &p_class, const StringName &p_fallback);
static void init();
static void set_current_api(APIType p_api);
static void cleanup();
};
#ifdef DEBUG_METHODS_ENABLED
#define BIND_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#define BIND_ENUM_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
#else
#define BIND_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#define BIND_ENUM_CONSTANT(m_constant) \
ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
#endif
#ifdef TOOLS_ENABLED
#define BIND_VMETHOD(m_method) \
ClassDB::add_virtual_method(get_class_static(), m_method);
#else
#define BIND_VMETHOD(m_method)
#endif
#endif // CLASS_DB_H

529
core/color.cpp Normal file
View File

@@ -0,0 +1,529 @@
/*************************************************************************/
/* color.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "color.h"
#include "color_names.inc"
#include "map.h"
#include "math_funcs.h"
#include "print_string.h"
uint32_t Color::to_argb32() const {
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
return c;
}
uint32_t Color::to_abgr32() const {
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(r * 255);
return c;
}
uint32_t Color::to_rgba32() const {
uint32_t c = (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)(b * 255);
c <<= 8;
c |= (uint8_t)(a * 255);
return c;
}
float Color::get_h() const {
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float delta = max - min;
if (delta == 0)
return 0;
float h;
if (r == max)
h = (g - b) / delta; // between yellow & magenta
else if (g == max)
h = 2 + (b - r) / delta; // between cyan & yellow
else
h = 4 + (r - g) / delta; // between magenta & cyan
h /= 6.0;
if (h < 0)
h += 1.0;
return h;
}
float Color::get_s() const {
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
max = MAX(max, b);
float delta = max - min;
return (max != 0) ? (delta / max) : 0;
}
float Color::get_v() const {
float max = MAX(r, g);
max = MAX(max, b);
return max;
}
void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
int i;
float f, p, q, t;
a = p_alpha;
if (p_s == 0) {
// acp_hromatic (grey)
r = g = b = p_v;
return;
}
p_h *= 6.0;
p_h = Math::fmod(p_h, 6);
i = Math::floor(p_h);
f = p_h - i;
p = p_v * (1 - p_s);
q = p_v * (1 - p_s * f);
t = p_v * (1 - p_s * (1 - f));
switch (i) {
case 0: // Red is the dominant color
r = p_v;
g = t;
b = p;
break;
case 1: // Green is the dominant color
r = q;
g = p_v;
b = p;
break;
case 2:
r = p;
g = p_v;
b = t;
break;
case 3: // Blue is the dominant color
r = p;
g = q;
b = p_v;
break;
case 4:
r = t;
g = p;
b = p_v;
break;
default: // (5) Red is the dominant color
r = p_v;
g = p;
b = q;
break;
}
}
void Color::invert() {
r = 1.0 - r;
g = 1.0 - g;
b = 1.0 - b;
}
void Color::contrast() {
r = Math::fmod(r + 0.5, 1.0);
g = Math::fmod(g + 0.5, 1.0);
b = Math::fmod(b + 0.5, 1.0);
}
Color Color::hex(uint32_t p_hex) {
float a = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float b = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float g = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float r = (p_hex & 0xFF) / 255.0;
return Color(r, g, b, a);
}
static float _parse_col(const String &p_str, int p_ofs) {
int ig = 0;
for (int i = 0; i < 2; i++) {
int c = p_str[i + p_ofs];
int v = 0;
if (c >= '0' && c <= '9') {
v = c - '0';
} else if (c >= 'a' && c <= 'f') {
v = c - 'a';
v += 10;
} else if (c >= 'A' && c <= 'F') {
v = c - 'A';
v += 10;
} else {
return -1;
}
if (i == 0)
ig += v * 16;
else
ig += v;
}
return ig;
}
Color Color::inverted() const {
Color c = *this;
c.invert();
return c;
}
Color Color::contrasted() const {
Color c = *this;
c.contrast();
return c;
}
Color Color::html(const String &p_color) {
String color = p_color;
if (color.length() == 0)
return Color();
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
if (color.length() == 3 || color.length() == 4) {
String exp_color;
for (int i = 0; i < color.length(); i++) {
exp_color += color[i];
exp_color += color[i];
}
color = exp_color;
}
bool alpha = false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
} else {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int a = 255;
if (alpha) {
a = _parse_col(color, 0);
if (a < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
}
int from = alpha ? 2 : 0;
int r = _parse_col(color, from + 0);
if (r < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int g = _parse_col(color, from + 2);
if (g < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int b = _parse_col(color, from + 4);
if (b < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
}
bool Color::html_is_valid(const String &p_color) {
String color = p_color;
if (color.length() == 0)
return false;
if (color[0] == '#')
color = color.substr(1, color.length() - 1);
bool alpha = false;
if (color.length() == 8) {
alpha = true;
} else if (color.length() == 6) {
alpha = false;
} else {
return false;
}
int a = 255;
if (alpha) {
a = _parse_col(color, 0);
if (a < 0) {
return false;
}
}
int from = alpha ? 2 : 0;
int r = _parse_col(color, from + 0);
if (r < 0) {
return false;
}
int g = _parse_col(color, from + 2);
if (g < 0) {
return false;
}
int b = _parse_col(color, from + 4);
if (b < 0) {
return false;
}
return true;
}
Color Color::named(const String &p_name) {
if (_named_colors.empty()) _populate_named_colors(); // from color_names.inc
String name = p_name;
// Normalize name
name = name.replace(" ", "");
name = name.replace("-", "");
name = name.replace("_", "");
name = name.replace("'", "");
name = name.replace(".", "");
name = name.to_lower();
const Map<String, Color>::Element *color = _named_colors.find(name);
if (color) {
return color->value();
} else {
ERR_EXPLAIN("Invalid Color Name: " + p_name);
ERR_FAIL_V(Color());
}
}
String _to_hex(float p_val) {
int v = p_val * 255;
v = CLAMP(v, 0, 255);
String ret;
for (int i = 0; i < 2; i++) {
CharType c[2] = { 0, 0 };
int lv = v & 0xF;
if (lv < 10)
c[0] = '0' + lv;
else
c[0] = 'a' + lv - 10;
v >>= 4;
String cs = (const CharType *)c;
ret = cs + ret;
}
return ret;
}
String Color::to_html(bool p_alpha) const {
String txt;
txt += _to_hex(r);
txt += _to_hex(g);
txt += _to_hex(b);
if (p_alpha)
txt = _to_hex(a) + txt;
return txt;
}
float Color::gray() const {
return (r + g + b) / 3.0;
}
Color::operator String() const {
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
}
Color Color::operator+(const Color &p_color) const {
return Color(
r + p_color.r,
g + p_color.g,
b + p_color.b,
a + p_color.a);
}
void Color::operator+=(const Color &p_color) {
r = r + p_color.r;
g = g + p_color.g;
b = b + p_color.b;
a = a + p_color.a;
}
Color Color::operator-(const Color &p_color) const {
return Color(
r - p_color.r,
g - p_color.g,
b - p_color.b,
a - p_color.a);
}
void Color::operator-=(const Color &p_color) {
r = r - p_color.r;
g = g - p_color.g;
b = b - p_color.b;
a = a - p_color.a;
}
Color Color::operator*(const Color &p_color) const {
return Color(
r * p_color.r,
g * p_color.g,
b * p_color.b,
a * p_color.a);
}
Color Color::operator*(const real_t &rvalue) const {
return Color(
r * rvalue,
g * rvalue,
b * rvalue,
a * rvalue);
}
void Color::operator*=(const Color &p_color) {
r = r * p_color.r;
g = g * p_color.g;
b = b * p_color.b;
a = a * p_color.a;
}
void Color::operator*=(const real_t &rvalue) {
r = r * rvalue;
g = g * rvalue;
b = b * rvalue;
a = a * rvalue;
}
Color Color::operator/(const Color &p_color) const {
return Color(
r / p_color.r,
g / p_color.g,
b / p_color.b,
a / p_color.a);
}
Color Color::operator/(const real_t &rvalue) const {
return Color(
r / rvalue,
g / rvalue,
b / rvalue,
a / rvalue);
}
void Color::operator/=(const Color &p_color) {
r = r / p_color.r;
g = g / p_color.g;
b = b / p_color.b;
a = a / p_color.a;
}
void Color::operator/=(const real_t &rvalue) {
if (rvalue == 0) {
r = 1.0;
g = 1.0;
b = 1.0;
a = 1.0;
} else {
r = r / rvalue;
g = g / rvalue;
b = b / rvalue;
a = a / rvalue;
}
};
Color Color::operator-() const {
return Color(
1.0 - r,
1.0 - g,
1.0 - b,
1.0 - a);
}

232
core/color.h Normal file
View File

@@ -0,0 +1,232 @@
/*************************************************************************/
/* color.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef COLOR_H
#define COLOR_H
#include "math_funcs.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
struct Color {
union {
struct {
float r;
float g;
float b;
float a;
};
float components[4];
};
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); }
uint32_t to_rgba32() const;
uint32_t to_argb32() const;
uint32_t to_abgr32() const;
float gray() const;
float get_h() const;
float get_s() const;
float get_v() const;
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
_FORCE_INLINE_ float &operator[](int idx) {
return components[idx];
}
_FORCE_INLINE_ const float &operator[](int idx) const {
return components[idx];
}
Color operator+(const Color &p_color) const;
void operator+=(const Color &p_color);
Color operator-() const;
Color operator-(const Color &p_color) const;
void operator-=(const Color &p_color);
Color operator*(const Color &p_color) const;
Color operator*(const real_t &rvalue) const;
void operator*=(const Color &p_color);
void operator*=(const real_t &rvalue);
Color operator/(const Color &p_color) const;
Color operator/(const real_t &rvalue) const;
void operator/=(const Color &p_color);
void operator/=(const real_t &rvalue);
void invert();
void contrast();
Color inverted() const;
Color contrasted() const;
_FORCE_INLINE_ Color linear_interpolate(const Color &p_b, float p_t) const {
Color res = *this;
res.r += (p_t * (p_b.r - r));
res.g += (p_t * (p_b.g - g));
res.b += (p_t * (p_b.b - b));
res.a += (p_t * (p_b.a - a));
return res;
}
_FORCE_INLINE_ Color darkened(float p_amount) const {
Color res = *this;
res.r = res.r * (1.0f - p_amount);
res.g = res.g * (1.0f - p_amount);
res.b = res.b * (1.0f - p_amount);
return res;
}
_FORCE_INLINE_ Color lightened(float p_amount) const {
Color res = *this;
res.r = res.r + (1.0f - res.r) * p_amount;
res.g = res.g + (1.0f - res.g) * p_amount;
res.b = res.b + (1.0f - res.b) * p_amount;
return res;
}
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
const float pow2to9 = 512.0f;
const float B = 15.0f;
//const float Emax = 31.0f;
const float N = 9.0f;
float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
float cRed = MAX(0.0f, MIN(sharedexp, r));
float cGreen = MAX(0.0f, MIN(sharedexp, g));
float cBlue = MAX(0.0f, MIN(sharedexp, b));
float cMax = MAX(cRed, MAX(cGreen, cBlue));
// expp = MAX(-B - 1, log2(maxc)) + 1 + B
float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
float exps = expp + 1.0f;
if (0.0 <= sMax && sMax < pow2to9) {
exps = expp;
}
float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
}
_FORCE_INLINE_ Color blend(const Color &p_over) const {
Color res;
float sa = 1.0 - p_over.a;
res.a = a * sa + p_over.a;
if (res.a == 0) {
return Color(0, 0, 0, 0);
} else {
res.r = (r * a * sa + p_over.r * p_over.a) / res.a;
res.g = (g * a * sa + p_over.g * p_over.a) / res.a;
res.b = (b * a * sa + p_over.b * p_over.a) / res.a;
}
return res;
}
_FORCE_INLINE_ Color to_linear() const {
return Color(
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
b < 0.04045 ? b * (1.0 / 12.92) : Math::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4),
a);
}
_FORCE_INLINE_ Color to_srgb() const {
return Color(
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
b < 0.0031308 ? 12.92 * b : (1.0 + 0.055) * Math::pow(b, 1.0f / 2.4f) - 0.055, a);
}
static Color hex(uint32_t p_hex);
static Color html(const String &p_color);
static bool html_is_valid(const String &p_color);
static Color named(const String &p_name);
String to_html(bool p_alpha = true) const;
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const;
/**
* No construct parameters, r=0, g=0, b=0. a=255
*/
_FORCE_INLINE_ Color() {
r = 0;
g = 0;
b = 0;
a = 1.0;
}
/**
* RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0
*/
_FORCE_INLINE_ Color(float p_r, float p_g, float p_b, float p_a = 1.0) {
r = p_r;
g = p_g;
b = p_b;
a = p_a;
}
};
bool Color::operator<(const Color &p_color) const {
if (r == p_color.r) {
if (g == p_color.g) {
if (b == p_color.b) {
return (a < p_color.a);
} else
return (b < p_color.b);
} else
return g < p_color.g;
} else
return r < p_color.r;
}
#endif

152
core/color_names.inc Normal file
View File

@@ -0,0 +1,152 @@
// Names from https://en.wikipedia.org/wiki/List_of_colors (through https://raw.githubusercontent.com/SuperUserNameMan/color_to_name/616a7cddafefda91478b7bc26167de97fb5badb1/godot_version.gd), slightly edited and normalized
#include "map.h"
static Map<String, Color> _named_colors;
static void _populate_named_colors() {
if(!_named_colors.empty()) return;
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
_named_colors.insert("aquamarine", Color(0.50, 1.00, 0.83));
_named_colors.insert("azure", Color(0.94, 1.00, 1.00));
_named_colors.insert("beige", Color(0.96, 0.96, 0.86));
_named_colors.insert("bisque", Color(1.00, 0.89, 0.77));
_named_colors.insert("black", Color(0.00, 0.00, 0.00));
_named_colors.insert("blanchedalmond", Color(1.00, 0.92, 0.80));
_named_colors.insert("blue", Color(0.00, 0.00, 1.00));
_named_colors.insert("blueviolet", Color(0.54, 0.17, 0.89));
_named_colors.insert("brown", Color(0.65, 0.16, 0.16));
_named_colors.insert("burlywood", Color(0.87, 0.72, 0.53));
_named_colors.insert("cadetblue", Color(0.37, 0.62, 0.63));
_named_colors.insert("chartreuse", Color(0.50, 1.00, 0.00));
_named_colors.insert("chocolate", Color(0.82, 0.41, 0.12));
_named_colors.insert("coral", Color(1.00, 0.50, 0.31));
_named_colors.insert("cornflower", Color(0.39, 0.58, 0.93));
_named_colors.insert("cornsilk", Color(1.00, 0.97, 0.86));
_named_colors.insert("crimson", Color(0.86, 0.08, 0.24));
_named_colors.insert("cyan", Color(0.00, 1.00, 1.00));
_named_colors.insert("darkblue", Color(0.00, 0.00, 0.55));
_named_colors.insert("darkcyan", Color(0.00, 0.55, 0.55));
_named_colors.insert("darkgoldenrod", Color(0.72, 0.53, 0.04));
_named_colors.insert("darkgray", Color(0.66, 0.66, 0.66));
_named_colors.insert("darkgreen", Color(0.00, 0.39, 0.00));
_named_colors.insert("darkkhaki", Color(0.74, 0.72, 0.42));
_named_colors.insert("darkmagenta", Color(0.55, 0.00, 0.55));
_named_colors.insert("darkolivegreen", Color(0.33, 0.42, 0.18));
_named_colors.insert("darkorange", Color(1.00, 0.55, 0.00));
_named_colors.insert("darkorchid", Color(0.60, 0.20, 0.80));
_named_colors.insert("darkred", Color(0.55, 0.00, 0.00));
_named_colors.insert("darksalmon", Color(0.91, 0.59, 0.48));
_named_colors.insert("darkseagreen", Color(0.56, 0.74, 0.56));
_named_colors.insert("darkslateblue", Color(0.28, 0.24, 0.55));
_named_colors.insert("darkslategray", Color(0.18, 0.31, 0.31));
_named_colors.insert("darkturquoise", Color(0.00, 0.81, 0.82));
_named_colors.insert("darkviolet", Color(0.58, 0.00, 0.83));
_named_colors.insert("deeppink", Color(1.00, 0.08, 0.58));
_named_colors.insert("deepskyblue", Color(0.00, 0.75, 1.00));
_named_colors.insert("dimgray", Color(0.41, 0.41, 0.41));
_named_colors.insert("dodgerblue", Color(0.12, 0.56, 1.00));
_named_colors.insert("firebrick", Color(0.70, 0.13, 0.13));
_named_colors.insert("floralwhite", Color(1.00, 0.98, 0.94));
_named_colors.insert("forestgreen", Color(0.13, 0.55, 0.13));
_named_colors.insert("fuchsia", Color(1.00, 0.00, 1.00));
_named_colors.insert("gainsboro", Color(0.86, 0.86, 0.86));
_named_colors.insert("ghostwhite", Color(0.97, 0.97, 1.00));
_named_colors.insert("gold", Color(1.00, 0.84, 0.00));
_named_colors.insert("goldenrod", Color(0.85, 0.65, 0.13));
_named_colors.insert("gray", Color(0.75, 0.75, 0.75));
_named_colors.insert("webgray", Color(0.50, 0.50, 0.50));
_named_colors.insert("green", Color(0.00, 1.00, 0.00));
_named_colors.insert("webgreen", Color(0.00, 0.50, 0.00));
_named_colors.insert("greenyellow", Color(0.68, 1.00, 0.18));
_named_colors.insert("honeydew", Color(0.94, 1.00, 0.94));
_named_colors.insert("hotpink", Color(1.00, 0.41, 0.71));
_named_colors.insert("indianred", Color(0.80, 0.36, 0.36));
_named_colors.insert("indigo", Color(0.29, 0.00, 0.51));
_named_colors.insert("ivory", Color(1.00, 1.00, 0.94));
_named_colors.insert("khaki", Color(0.94, 0.90, 0.55));
_named_colors.insert("lavender", Color(0.90, 0.90, 0.98));
_named_colors.insert("lavenderblush", Color(1.00, 0.94, 0.96));
_named_colors.insert("lawngreen", Color(0.49, 0.99, 0.00));
_named_colors.insert("lemonchiffon", Color(1.00, 0.98, 0.80));
_named_colors.insert("lightblue", Color(0.68, 0.85, 0.90));
_named_colors.insert("lightcoral", Color(0.94, 0.50, 0.50));
_named_colors.insert("lightcyan", Color(0.88, 1.00, 1.00));
_named_colors.insert("lightgoldenrod", Color(0.98, 0.98, 0.82));
_named_colors.insert("lightgray", Color(0.83, 0.83, 0.83));
_named_colors.insert("lightgreen", Color(0.56, 0.93, 0.56));
_named_colors.insert("lightpink", Color(1.00, 0.71, 0.76));
_named_colors.insert("lightsalmon", Color(1.00, 0.63, 0.48));
_named_colors.insert("lightseagreen", Color(0.13, 0.70, 0.67));
_named_colors.insert("lightskyblue", Color(0.53, 0.81, 0.98));
_named_colors.insert("lightslategray", Color(0.47, 0.53, 0.60));
_named_colors.insert("lightsteelblue", Color(0.69, 0.77, 0.87));
_named_colors.insert("lightyellow", Color(1.00, 1.00, 0.88));
_named_colors.insert("lime", Color(0.00, 1.00, 0.00));
_named_colors.insert("limegreen", Color(0.20, 0.80, 0.20));
_named_colors.insert("linen", Color(0.98, 0.94, 0.90));
_named_colors.insert("magenta", Color(1.00, 0.00, 1.00));
_named_colors.insert("maroon", Color(0.69, 0.19, 0.38));
_named_colors.insert("webmaroon", Color(0.50, 0.00, 0.00));
_named_colors.insert("mediumaquamarine", Color(0.40, 0.80, 0.67));
_named_colors.insert("mediumblue", Color(0.00, 0.00, 0.80));
_named_colors.insert("mediumorchid", Color(0.73, 0.33, 0.83));
_named_colors.insert("mediumpurple", Color(0.58, 0.44, 0.86));
_named_colors.insert("mediumseagreen", Color(0.24, 0.70, 0.44));
_named_colors.insert("mediumslateblue", Color(0.48, 0.41, 0.93));
_named_colors.insert("mediumspringgreen", Color(0.00, 0.98, 0.60));
_named_colors.insert("mediumturquoise", Color(0.28, 0.82, 0.80));
_named_colors.insert("mediumvioletred", Color(0.78, 0.08, 0.52));
_named_colors.insert("midnightblue", Color(0.10, 0.10, 0.44));
_named_colors.insert("mintcream", Color(0.96, 1.00, 0.98));
_named_colors.insert("mistyrose", Color(1.00, 0.89, 0.88));
_named_colors.insert("moccasin", Color(1.00, 0.89, 0.71));
_named_colors.insert("navajowhite", Color(1.00, 0.87, 0.68));
_named_colors.insert("navyblue", Color(0.00, 0.00, 0.50));
_named_colors.insert("oldlace", Color(0.99, 0.96, 0.90));
_named_colors.insert("olive", Color(0.50, 0.50, 0.00));
_named_colors.insert("olivedrab", Color(0.42, 0.56, 0.14));
_named_colors.insert("orange", Color(1.00, 0.65, 0.00));
_named_colors.insert("orangered", Color(1.00, 0.27, 0.00));
_named_colors.insert("orchid", Color(0.85, 0.44, 0.84));
_named_colors.insert("palegoldenrod", Color(0.93, 0.91, 0.67));
_named_colors.insert("palegreen", Color(0.60, 0.98, 0.60));
_named_colors.insert("paleturquoise", Color(0.69, 0.93, 0.93));
_named_colors.insert("palevioletred", Color(0.86, 0.44, 0.58));
_named_colors.insert("papayawhip", Color(1.00, 0.94, 0.84));
_named_colors.insert("peachpuff", Color(1.00, 0.85, 0.73));
_named_colors.insert("peru", Color(0.80, 0.52, 0.25));
_named_colors.insert("pink", Color(1.00, 0.75, 0.80));
_named_colors.insert("plum", Color(0.87, 0.63, 0.87));
_named_colors.insert("powderblue", Color(0.69, 0.88, 0.90));
_named_colors.insert("purple", Color(0.63, 0.13, 0.94));
_named_colors.insert("webpurple", Color(0.50, 0.00, 0.50));
_named_colors.insert("rebeccapurple", Color(0.40, 0.20, 0.60));
_named_colors.insert("red", Color(1.00, 0.00, 0.00));
_named_colors.insert("rosybrown", Color(0.74, 0.56, 0.56));
_named_colors.insert("royalblue", Color(0.25, 0.41, 0.88));
_named_colors.insert("saddlebrown", Color(0.55, 0.27, 0.07));
_named_colors.insert("salmon", Color(0.98, 0.50, 0.45));
_named_colors.insert("sandybrown", Color(0.96, 0.64, 0.38));
_named_colors.insert("seagreen", Color(0.18, 0.55, 0.34));
_named_colors.insert("seashell", Color(1.00, 0.96, 0.93));
_named_colors.insert("sienna", Color(0.63, 0.32, 0.18));
_named_colors.insert("silver", Color(0.75, 0.75, 0.75));
_named_colors.insert("skyblue", Color(0.53, 0.81, 0.92));
_named_colors.insert("slateblue", Color(0.42, 0.35, 0.80));
_named_colors.insert("slategray", Color(0.44, 0.50, 0.56));
_named_colors.insert("snow", Color(1.00, 0.98, 0.98));
_named_colors.insert("springgreen", Color(0.00, 1.00, 0.50));
_named_colors.insert("steelblue", Color(0.27, 0.51, 0.71));
_named_colors.insert("tan", Color(0.82, 0.71, 0.55));
_named_colors.insert("teal", Color(0.00, 0.50, 0.50));
_named_colors.insert("thistle", Color(0.85, 0.75, 0.85));
_named_colors.insert("tomato", Color(1.00, 0.39, 0.28));
_named_colors.insert("turquoise", Color(0.25, 0.88, 0.82));
_named_colors.insert("violet", Color(0.93, 0.51, 0.93));
_named_colors.insert("wheat", Color(0.96, 0.87, 0.70));
_named_colors.insert("white", Color(1.00, 1.00, 1.00));
_named_colors.insert("whitesmoke", Color(0.96, 0.96, 0.96));
_named_colors.insert("yellow", Color(1.00, 1.00, 0.00));
_named_colors.insert("yellowgreen", Color(0.60, 0.80, 0.20));
}

130
core/command_queue_mt.cpp Normal file
View File

@@ -0,0 +1,130 @@
/*************************************************************************/
/* command_queue_mt.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "command_queue_mt.h"
#include "os/os.h"
void CommandQueueMT::lock() {
if (mutex)
mutex->lock();
}
void CommandQueueMT::unlock() {
if (mutex)
mutex->unlock();
}
void CommandQueueMT::wait_for_flush() {
// wait one millisecond for a flush to happen
OS::get_singleton()->delay_usec(1000);
}
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
int idx = -1;
while (true) {
lock();
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
if (!sync_sems[i].in_use) {
sync_sems[i].in_use = true;
idx = i;
break;
}
}
unlock();
if (idx == -1) {
wait_for_flush();
} else {
break;
}
}
return &sync_sems[idx];
}
bool CommandQueueMT::dealloc_one() {
tryagain:
if (dealloc_ptr == write_ptr) {
// The queue is empty
return false;
}
uint32_t size = *(uint32_t *)&command_mem[dealloc_ptr];
if (size == 0) {
// End of command buffer wrap down
dealloc_ptr = 0;
goto tryagain;
}
if (size & 1) {
// Still used, nothing can be deallocated
return false;
}
dealloc_ptr += (size >> 1) + sizeof(uint32_t);
return true;
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
read_ptr = 0;
write_ptr = 0;
mutex = Mutex::create();
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
sync_sems[i].sem = Semaphore::create();
sync_sems[i].in_use = false;
}
if (p_sync)
sync = Semaphore::create();
else
sync = NULL;
}
CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
memdelete(mutex);
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
memdelete(sync_sems[i].sem);
}
}

480
core/command_queue_mt.h Normal file
View File

@@ -0,0 +1,480 @@
/*************************************************************************/
/* command_queue_mt.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef COMMAND_QUEUE_MT_H
#define COMMAND_QUEUE_MT_H
#include "os/memory.h"
#include "os/mutex.h"
#include "os/semaphore.h"
#include "simple_type.h"
#include "typedefs.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#define COMMA(N) _COMMA_##N
#define _COMMA_0
#define _COMMA_1 ,
#define _COMMA_2 ,
#define _COMMA_3 ,
#define _COMMA_4 ,
#define _COMMA_5 ,
#define _COMMA_6 ,
#define _COMMA_7 ,
#define _COMMA_8 ,
#define _COMMA_9 ,
#define _COMMA_10 ,
#define _COMMA_11 ,
#define _COMMA_12 ,
// 1-based comma separated list of ITEMs
#define COMMA_SEP_LIST(ITEM, LENGTH) _COMMA_SEP_LIST_##LENGTH(ITEM)
#define _COMMA_SEP_LIST_12(ITEM) \
_COMMA_SEP_LIST_11(ITEM) \
, ITEM(12)
#define _COMMA_SEP_LIST_11(ITEM) \
_COMMA_SEP_LIST_10(ITEM) \
, ITEM(11)
#define _COMMA_SEP_LIST_10(ITEM) \
_COMMA_SEP_LIST_9(ITEM) \
, ITEM(10)
#define _COMMA_SEP_LIST_9(ITEM) \
_COMMA_SEP_LIST_8(ITEM) \
, ITEM(9)
#define _COMMA_SEP_LIST_8(ITEM) \
_COMMA_SEP_LIST_7(ITEM) \
, ITEM(8)
#define _COMMA_SEP_LIST_7(ITEM) \
_COMMA_SEP_LIST_6(ITEM) \
, ITEM(7)
#define _COMMA_SEP_LIST_6(ITEM) \
_COMMA_SEP_LIST_5(ITEM) \
, ITEM(6)
#define _COMMA_SEP_LIST_5(ITEM) \
_COMMA_SEP_LIST_4(ITEM) \
, ITEM(5)
#define _COMMA_SEP_LIST_4(ITEM) \
_COMMA_SEP_LIST_3(ITEM) \
, ITEM(4)
#define _COMMA_SEP_LIST_3(ITEM) \
_COMMA_SEP_LIST_2(ITEM) \
, ITEM(3)
#define _COMMA_SEP_LIST_2(ITEM) \
_COMMA_SEP_LIST_1(ITEM) \
, ITEM(2)
#define _COMMA_SEP_LIST_1(ITEM) \
_COMMA_SEP_LIST_0(ITEM) \
ITEM(1)
#define _COMMA_SEP_LIST_0(ITEM)
// 1-based semicolon separated list of ITEMs
#define SEMIC_SEP_LIST(ITEM, LENGTH) _SEMIC_SEP_LIST_##LENGTH(ITEM)
#define _SEMIC_SEP_LIST_12(ITEM) \
_SEMIC_SEP_LIST_11(ITEM); \
ITEM(12)
#define _SEMIC_SEP_LIST_11(ITEM) \
_SEMIC_SEP_LIST_10(ITEM); \
ITEM(11)
#define _SEMIC_SEP_LIST_10(ITEM) \
_SEMIC_SEP_LIST_9(ITEM); \
ITEM(10)
#define _SEMIC_SEP_LIST_9(ITEM) \
_SEMIC_SEP_LIST_8(ITEM); \
ITEM(9)
#define _SEMIC_SEP_LIST_8(ITEM) \
_SEMIC_SEP_LIST_7(ITEM); \
ITEM(8)
#define _SEMIC_SEP_LIST_7(ITEM) \
_SEMIC_SEP_LIST_6(ITEM); \
ITEM(7)
#define _SEMIC_SEP_LIST_6(ITEM) \
_SEMIC_SEP_LIST_5(ITEM); \
ITEM(6)
#define _SEMIC_SEP_LIST_5(ITEM) \
_SEMIC_SEP_LIST_4(ITEM); \
ITEM(5)
#define _SEMIC_SEP_LIST_4(ITEM) \
_SEMIC_SEP_LIST_3(ITEM); \
ITEM(4)
#define _SEMIC_SEP_LIST_3(ITEM) \
_SEMIC_SEP_LIST_2(ITEM); \
ITEM(3)
#define _SEMIC_SEP_LIST_2(ITEM) \
_SEMIC_SEP_LIST_1(ITEM); \
ITEM(2)
#define _SEMIC_SEP_LIST_1(ITEM) \
_SEMIC_SEP_LIST_0(ITEM) \
ITEM(1)
#define _SEMIC_SEP_LIST_0(ITEM)
// 1-based space separated list of ITEMs
#define SPACE_SEP_LIST(ITEM, LENGTH) _SPACE_SEP_LIST_##LENGTH(ITEM)
#define _SPACE_SEP_LIST_12(ITEM) \
_SPACE_SEP_LIST_11(ITEM) \
ITEM(12)
#define _SPACE_SEP_LIST_11(ITEM) \
_SPACE_SEP_LIST_10(ITEM) \
ITEM(11)
#define _SPACE_SEP_LIST_10(ITEM) \
_SPACE_SEP_LIST_9(ITEM) \
ITEM(10)
#define _SPACE_SEP_LIST_9(ITEM) \
_SPACE_SEP_LIST_8(ITEM) \
ITEM(9)
#define _SPACE_SEP_LIST_8(ITEM) \
_SPACE_SEP_LIST_7(ITEM) \
ITEM(8)
#define _SPACE_SEP_LIST_7(ITEM) \
_SPACE_SEP_LIST_6(ITEM) \
ITEM(7)
#define _SPACE_SEP_LIST_6(ITEM) \
_SPACE_SEP_LIST_5(ITEM) \
ITEM(6)
#define _SPACE_SEP_LIST_5(ITEM) \
_SPACE_SEP_LIST_4(ITEM) \
ITEM(5)
#define _SPACE_SEP_LIST_4(ITEM) \
_SPACE_SEP_LIST_3(ITEM) \
ITEM(4)
#define _SPACE_SEP_LIST_3(ITEM) \
_SPACE_SEP_LIST_2(ITEM) \
ITEM(3)
#define _SPACE_SEP_LIST_2(ITEM) \
_SPACE_SEP_LIST_1(ITEM) \
ITEM(2)
#define _SPACE_SEP_LIST_1(ITEM) \
_SPACE_SEP_LIST_0(ITEM) \
ITEM(1)
#define _SPACE_SEP_LIST_0(ITEM)
#define ARG(N) p##N
#define PARAM(N) P##N p##N
#define TYPE_PARAM(N) class P##N
#define PARAM_DECL(N) typename GetSimpleTypeT<P##N>::type_t p##N
#define DECL_CMD(N) \
template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
struct Command##N : public CommandBase { \
T *instance; \
M method; \
SEMIC_SEP_LIST(PARAM_DECL, N); \
virtual void call() { \
(instance->*method)(COMMA_SEP_LIST(ARG, N)); \
} \
};
#define DECL_CMD_RET(N) \
template <class T, class M, COMMA_SEP_LIST(TYPE_PARAM, N) COMMA(N) class R> \
struct CommandRet##N : public SyncCommand { \
R *ret; \
T *instance; \
M method; \
SEMIC_SEP_LIST(PARAM_DECL, N); \
virtual void call() { \
*ret = (instance->*method)(COMMA_SEP_LIST(ARG, N)); \
} \
};
#define DECL_CMD_SYNC(N) \
template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
struct CommandSync##N : public SyncCommand { \
T *instance; \
M method; \
SEMIC_SEP_LIST(PARAM_DECL, N); \
virtual void call() { \
(instance->*method)(COMMA_SEP_LIST(ARG, N)); \
} \
};
#define TYPE_ARG(N) P##N
#define CMD_TYPE(N) Command##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
#define CMD_ASSIGN_PARAM(N) cmd->p##N = p##N
#define DECL_PUSH(N) \
template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
void push(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \
CMD_TYPE(N) *cmd = allocate_and_lock<CMD_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
unlock(); \
if (sync) sync->post(); \
}
#define CMD_RET_TYPE(N) CommandRet##N<T, M, COMMA_SEP_LIST(TYPE_ARG, N) COMMA(N) R>
#define DECL_PUSH_AND_RET(N) \
template <class T, class M, COMMA_SEP_LIST(TYPE_PARAM, N) COMMA(N) class R> \
void push_and_ret(T *p_instance, M p_method, COMMA_SEP_LIST(PARAM, N) COMMA(N) R *r_ret) { \
SyncSemaphore *ss = _alloc_sync_sem(); \
CMD_RET_TYPE(N) *cmd = allocate_and_lock<CMD_RET_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
cmd->ret = r_ret; \
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
}
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
#define DECL_PUSH_AND_SYNC(N) \
template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
void push_and_sync(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \
SyncSemaphore *ss = _alloc_sync_sem(); \
CMD_SYNC_TYPE(N) *cmd = allocate_and_lock<CMD_SYNC_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
ss->sem->wait(); \
}
#define MAX_CMD_PARAMS 12
class CommandQueueMT {
struct SyncSemaphore {
Semaphore *sem;
bool in_use;
};
struct CommandBase {
virtual void call() = 0;
virtual void post(){};
virtual ~CommandBase(){};
};
struct SyncCommand : public CommandBase {
SyncSemaphore *sync_sem;
virtual void post() {
sync_sem->sem->post();
sync_sem->in_use = false;
}
};
DECL_CMD(0)
SPACE_SEP_LIST(DECL_CMD, 12)
/* comands that return */
DECL_CMD_RET(0)
SPACE_SEP_LIST(DECL_CMD_RET, 12)
/* commands that don't return but sync */
DECL_CMD_SYNC(0)
SPACE_SEP_LIST(DECL_CMD_SYNC, 12)
/***** BASE *******/
enum {
COMMAND_MEM_SIZE_KB = 256,
COMMAND_MEM_SIZE = COMMAND_MEM_SIZE_KB * 1024,
SYNC_SEMAPHORES = 8
};
uint8_t command_mem[COMMAND_MEM_SIZE];
uint32_t read_ptr = 0;
uint32_t write_ptr = 0;
uint32_t dealloc_ptr = 0;
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
Mutex *mutex;
Semaphore *sync;
template <class T>
T *allocate() {
// alloc size is size+T+safeguard
uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
tryagain:
if (write_ptr < dealloc_ptr) {
// behind dealloc_ptr, check that there is room
if ((dealloc_ptr - write_ptr) <= alloc_size) {
// There is no more room, try to deallocate something
if (dealloc_one()) {
goto tryagain;
}
return NULL;
}
} else if (write_ptr >= dealloc_ptr) {
// ahead of dealloc_ptr, check that there is room
if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + sizeof(uint32_t)) {
// no room at the end, wrap down;
if (dealloc_ptr == 0) { // don't want write_ptr to become dealloc_ptr
// There is no more room, try to deallocate something
if (dealloc_one()) {
goto tryagain;
}
return NULL;
}
// if this happens, it's a bug
ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL);
// zero means, wrap to beginning
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
*p = 0;
write_ptr = 0;
goto tryagain;
}
}
// Allocate the size and the 'in use' bit.
// First bit used to mark if command is still in use (1)
// or if it has been destroyed and can be deallocated (0).
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
*p = (sizeof(T) << 1) | 1;
write_ptr += sizeof(uint32_t);
// allocate the command
T *cmd = memnew_placement(&command_mem[write_ptr], T);
write_ptr += sizeof(T);
return cmd;
}
template <class T>
T *allocate_and_lock() {
lock();
T *ret;
while ((ret = allocate<T>()) == NULL) {
unlock();
// sleep a little until fetch happened and some room is made
wait_for_flush();
lock();
}
return ret;
}
bool flush_one(bool p_lock = true) {
if (p_lock) lock();
tryagain:
// tried to read an empty queue
if (read_ptr == write_ptr)
return false;
uint32_t size_ptr = read_ptr;
uint32_t size = *(uint32_t *)&command_mem[read_ptr] >> 1;
if (size == 0) {
//end of ringbuffer, wrap
read_ptr = 0;
goto tryagain;
}
read_ptr += sizeof(uint32_t);
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
read_ptr += size;
if (p_lock) unlock();
cmd->call();
if (p_lock) lock();
cmd->post();
cmd->~CommandBase();
*(uint32_t *)&command_mem[size_ptr] &= ~1;
if (p_lock) unlock();
return true;
}
void lock();
void unlock();
void wait_for_flush();
SyncSemaphore *_alloc_sync_sem();
bool dealloc_one();
public:
/* NORMAL PUSH COMMANDS */
DECL_PUSH(0)
SPACE_SEP_LIST(DECL_PUSH, 12)
/* PUSH AND RET COMMANDS */
DECL_PUSH_AND_RET(0)
SPACE_SEP_LIST(DECL_PUSH_AND_RET, 12)
/* PUSH AND RET SYNC COMMANDS*/
DECL_PUSH_AND_SYNC(0)
SPACE_SEP_LIST(DECL_PUSH_AND_SYNC, 12)
void wait_and_flush_one() {
ERR_FAIL_COND(!sync);
sync->wait();
flush_one();
}
void flush_all() {
//ERR_FAIL_COND(sync);
lock();
while (flush_one(false))
;
unlock();
}
CommandQueueMT(bool p_sync);
~CommandQueueMT();
};
#undef ARG
#undef PARAM
#undef TYPE_PARAM
#undef PARAM_DECL
#undef DECL_CMD
#undef DECL_CMD_RET
#undef DECL_CMD_SYNC
#undef TYPE_ARG
#undef CMD_TYPE
#undef CMD_ASSIGN_PARAM
#undef DECL_PUSH
#undef CMD_RET_TYPE
#undef DECL_PUSH_AND_RET
#undef CMD_SYNC_TYPE
#undef DECL_CMD_SYNC
#endif

View File

@@ -0,0 +1,314 @@
/*************************************************************************/
/* compressed_translation.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "compressed_translation.h"
#include "pair.h"
extern "C" {
#include "thirdparty/misc/smaz.h"
}
struct _PHashTranslationCmp {
int orig_len;
CharString compressed;
int offset;
};
void PHashTranslation::generate(const Ref<Translation> &p_from) {
#ifdef TOOLS_ENABLED
List<StringName> keys;
p_from->get_message_list(&keys);
int size = Math::larger_prime(keys.size());
print_line("compressing keys: " + itos(keys.size()));
Vector<Vector<Pair<int, CharString> > > buckets;
Vector<Map<uint32_t, int> > table;
Vector<uint32_t> hfunc_table;
Vector<_PHashTranslationCmp> compressed;
table.resize(size);
hfunc_table.resize(size);
buckets.resize(size);
compressed.resize(keys.size());
int idx = 0;
int total_compression_size = 0;
int total_string_size = 0;
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
//hash string
CharString cs = E->get().operator String().utf8();
uint32_t h = hash(0, cs.get_data());
Pair<int, CharString> p;
p.first = idx;
p.second = cs;
buckets[h % size].push_back(p);
//compress string
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
_PHashTranslationCmp ps;
ps.orig_len = src_s.size();
ps.offset = total_compression_size;
if (ps.orig_len != 0) {
CharString dst_s;
dst_s.resize(src_s.size());
int ret = smaz_compress(src_s.get_data(), src_s.size(), &dst_s[0], src_s.size());
if (ret >= src_s.size()) {
//if compressed is larger than original, just use original
ps.orig_len = src_s.size();
ps.compressed = src_s;
} else {
dst_s.resize(ret);
//ps.orig_len=;
ps.compressed = dst_s;
}
} else {
ps.orig_len = 1;
ps.compressed.resize(1);
ps.compressed[0] = 0;
}
compressed[idx] = ps;
total_compression_size += ps.compressed.size();
total_string_size += src_s.size();
idx++;
}
int bucket_table_size = 0;
print_line("total compressed string size: " + itos(total_compression_size) + " (" + itos(total_string_size) + " uncompressed).");
for (int i = 0; i < size; i++) {
Vector<Pair<int, CharString> > &b = buckets[i];
Map<uint32_t, int> &t = table[i];
if (b.size() == 0)
continue;
//print_line("bucket: "+itos(i)+" - elements: "+itos(b.size()));
int d = 1;
int item = 0;
while (item < b.size()) {
uint32_t slot = hash(d, b[item].second.get_data());
if (t.has(slot)) {
item = 0;
d++;
t.clear();
} else {
t[slot] = b[item].first;
item++;
}
}
hfunc_table[i] = d;
bucket_table_size += 2 + b.size() * 4;
}
print_line("bucket table size: " + itos(bucket_table_size * 4));
print_line("hash table size: " + itos(size * 4));
hash_table.resize(size);
bucket_table.resize(bucket_table_size);
PoolVector<int>::Write htwb = hash_table.write();
PoolVector<int>::Write btwb = bucket_table.write();
uint32_t *htw = (uint32_t *)&htwb[0];
uint32_t *btw = (uint32_t *)&btwb[0];
int btindex = 0;
int collisions = 0;
for (int i = 0; i < size; i++) {
Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
continue;
} else if (t.size() > 1) {
collisions += t.size() - 1;
}
htw[i] = btindex;
btw[btindex++] = t.size();
btw[btindex++] = hfunc_table[i];
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
btw[btindex++] = E->key();
btw[btindex++] = compressed[E->get()].offset;
btw[btindex++] = compressed[E->get()].compressed.size();
btw[btindex++] = compressed[E->get()].orig_len;
}
}
print_line("total collisions: " + itos(collisions));
strings.resize(total_compression_size);
PoolVector<uint8_t>::Write cw = strings.write();
for (int i = 0; i < compressed.size(); i++) {
memcpy(&cw[compressed[i].offset], compressed[i].compressed.get_data(), compressed[i].compressed.size());
}
ERR_FAIL_COND(btindex != bucket_table_size);
set_locale(p_from->get_locale());
#endif
}
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name.operator String();
if (name == "hash_table") {
hash_table = p_value;
//print_line("translation: loaded hash table of size: "+itos(hash_table.size()));
} else if (name == "bucket_table") {
bucket_table = p_value;
//print_line("translation: loaded bucket table of size: "+itos(bucket_table.size()));
} else if (name == "strings") {
strings = p_value;
//print_line("translation: loaded string table of size: "+itos(strings.size()));
} else if (name == "load_from") {
//print_line("generating");
generate(p_value);
} else
return false;
return true;
}
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
String name = p_name.operator String();
if (name == "hash_table")
r_ret = hash_table;
else if (name == "bucket_table")
r_ret = bucket_table;
else if (name == "strings")
r_ret = strings;
else
return false;
return true;
}
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
int htsize = hash_table.size();
if (htsize == 0)
return StringName();
CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0, str.get_data());
PoolVector<int>::Read htr = hash_table.read();
const uint32_t *htptr = (const uint32_t *)&htr[0];
PoolVector<int>::Read btr = bucket_table.read();
const uint32_t *btptr = (const uint32_t *)&btr[0];
PoolVector<uint8_t>::Read sr = strings.read();
const char *sptr = (const char *)&sr[0];
uint32_t p = htptr[h % htsize];
//print_line("String: "+p_src_text.operator String());
//print_line("Hash: "+itos(p));
if (p == 0xFFFFFFFF) {
//print_line("GETMSG: Nothing!");
return StringName(); //nothing
}
const Bucket &bucket = *(const Bucket *)&btptr[p];
h = hash(bucket.func, str.get_data());
int idx = -1;
for (int i = 0; i < bucket.size; i++) {
if (bucket.elem[i].key == h) {
idx = i;
break;
}
}
//print_line("bucket pos: "+itos(idx));
if (idx == -1) {
//print_line("GETMSG: Not in Bucket!");
return StringName();
}
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
String rstr;
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
//print_line("Uncompressed, size: "+itos(bucket.elem[idx].comp_size));
//print_line("Return: "+rstr);
return rstr;
} else {
CharString uncomp;
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
String rstr;
rstr.parse_utf8(uncomp.get_data());
//print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size));
//print_line("Return: "+rstr);
return rstr;
}
}
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "hash_table"));
p_list->push_back(PropertyInfo(Variant::POOL_INT_ARRAY, "bucket_table"));
p_list->push_back(PropertyInfo(Variant::POOL_BYTE_ARRAY, "strings"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
}
void PHashTranslation::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate", "from"), &PHashTranslation::generate);
}
PHashTranslation::PHashTranslation() {
}

View File

@@ -0,0 +1,92 @@
/*************************************************************************/
/* compressed_translation.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef COMPRESSED_TRANSLATION_H
#define COMPRESSED_TRANSLATION_H
#include "translation.h"
class PHashTranslation : public Translation {
GDCLASS(PHashTranslation, Translation);
//this translation uses a sort of modified perfect hash algorithm
//it requires hashing strings twice and then does a binary search,
//so it's slower, but at the same time it has an extreemly high chance
//of catching untranslated strings
//load/store friendly types
PoolVector<int> hash_table;
PoolVector<int> bucket_table;
PoolVector<uint8_t> strings;
struct Bucket {
int size;
uint32_t func;
struct Elem {
uint32_t key;
uint32_t str_offset;
uint32_t comp_size;
uint32_t uncomp_size;
};
Elem elem[1];
};
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
if (d == 0)
d = 0x1000193;
while (*p_str) {
d = (d * 0x1000193) ^ uint32_t(*p_str);
p_str++;
}
return d;
}
protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
virtual StringName get_message(const StringName &p_src_text) const; //overridable for other implementations
void generate(const Ref<Translation> &p_from);
PHashTranslation();
};
#endif // COMPRESSED_TRANSLATION_H

View File

@@ -1,8 +0,0 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
env_config = env.Clone()
env_config.add_source_files(env.core_sources, "*.cpp")

View File

@@ -1,446 +0,0 @@
/**************************************************************************/
/* engine.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "engine.h"
#include "core/authors.gen.h"
#include "core/config/project_settings.h"
#include "core/donors.gen.h"
#include "core/license.gen.h"
#include "core/variant/typed_array.h"
#include "core/version.h"
#include "servers/rendering/rendering_device.h"
void Engine::set_physics_ticks_per_second(int p_ips) {
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
ips = p_ips;
}
int Engine::get_physics_ticks_per_second() const {
return ips;
}
void Engine::set_max_physics_steps_per_frame(int p_max_physics_steps) {
ERR_FAIL_COND_MSG(p_max_physics_steps <= 0, "Maximum number of physics steps per frame must be greater than 0.");
max_physics_steps_per_frame = p_max_physics_steps;
}
int Engine::get_max_physics_steps_per_frame() const {
return max_physics_steps_per_frame;
}
void Engine::set_physics_jitter_fix(double p_threshold) {
if (p_threshold < 0) {
p_threshold = 0;
}
physics_jitter_fix = p_threshold;
}
double Engine::get_physics_jitter_fix() const {
return physics_jitter_fix;
}
void Engine::set_max_fps(int p_fps) {
_max_fps = p_fps > 0 ? p_fps : 0;
RenderingDevice *rd = RenderingDevice::get_singleton();
if (rd) {
rd->_set_max_fps(_max_fps);
}
}
int Engine::get_max_fps() const {
return _max_fps;
}
void Engine::set_audio_output_latency(int p_msec) {
_audio_output_latency = p_msec > 1 ? p_msec : 1;
}
int Engine::get_audio_output_latency() const {
return _audio_output_latency;
}
void Engine::increment_frames_drawn() {
if (frame_server_synced) {
server_syncs++;
} else {
server_syncs = 0;
}
frame_server_synced = false;
frames_drawn++;
}
uint64_t Engine::get_frames_drawn() {
return frames_drawn;
}
void Engine::set_frame_delay(uint32_t p_msec) {
_frame_delay = p_msec;
}
uint32_t Engine::get_frame_delay() const {
return _frame_delay;
}
void Engine::set_time_scale(double p_scale) {
_time_scale = p_scale;
}
double Engine::get_time_scale() const {
return freeze_time_scale ? 0 : _time_scale;
}
double Engine::get_unfrozen_time_scale() const {
return _time_scale;
}
Dictionary Engine::get_version_info() const {
Dictionary dict;
dict["major"] = VERSION_MAJOR;
dict["minor"] = VERSION_MINOR;
dict["patch"] = VERSION_PATCH;
dict["hex"] = VERSION_HEX;
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
String hash = String(VERSION_HASH);
dict["hash"] = hash.is_empty() ? String("unknown") : hash;
dict["timestamp"] = VERSION_TIMESTAMP;
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
if ((int)dict["patch"] != 0) {
stringver += "." + String(dict["patch"]);
}
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
dict["string"] = stringver;
return dict;
}
static Array array_from_info(const char *const *info_list) {
Array arr;
for (int i = 0; info_list[i] != nullptr; i++) {
arr.push_back(String::utf8(info_list[i]));
}
return arr;
}
static Array array_from_info_count(const char *const *info_list, int info_count) {
Array arr;
for (int i = 0; i < info_count; i++) {
arr.push_back(String::utf8(info_list[i]));
}
return arr;
}
Dictionary Engine::get_author_info() const {
Dictionary dict;
dict["lead_developers"] = array_from_info(AUTHORS_LEAD_DEVELOPERS);
dict["project_managers"] = array_from_info(AUTHORS_PROJECT_MANAGERS);
dict["founders"] = array_from_info(AUTHORS_FOUNDERS);
dict["developers"] = array_from_info(AUTHORS_DEVELOPERS);
return dict;
}
TypedArray<Dictionary> Engine::get_copyright_info() const {
TypedArray<Dictionary> components;
for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) {
const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index];
Dictionary component_dict;
component_dict["name"] = String::utf8(cp_info.name);
Array parts;
for (int i = 0; i < cp_info.part_count; i++) {
const ComponentCopyrightPart &cp_part = cp_info.parts[i];
Dictionary part_dict;
part_dict["files"] = array_from_info_count(cp_part.files, cp_part.file_count);
part_dict["copyright"] = array_from_info_count(cp_part.copyright_statements, cp_part.copyright_count);
part_dict["license"] = String::utf8(cp_part.license);
parts.push_back(part_dict);
}
component_dict["parts"] = parts;
components.push_back(component_dict);
}
return components;
}
Dictionary Engine::get_donor_info() const {
Dictionary donors;
donors["patrons"] = array_from_info(DONORS_PATRONS);
donors["platinum_sponsors"] = array_from_info(DONORS_SPONSORS_PLATINUM);
donors["gold_sponsors"] = array_from_info(DONORS_SPONSORS_GOLD);
donors["silver_sponsors"] = array_from_info(DONORS_SPONSORS_SILVER);
donors["diamond_members"] = array_from_info(DONORS_MEMBERS_DIAMOND);
donors["titanium_members"] = array_from_info(DONORS_MEMBERS_TITANIUM);
donors["platinum_members"] = array_from_info(DONORS_MEMBERS_PLATINUM);
donors["gold_members"] = array_from_info(DONORS_MEMBERS_GOLD);
return donors;
}
Dictionary Engine::get_license_info() const {
Dictionary licenses;
for (int i = 0; i < LICENSE_COUNT; i++) {
licenses[LICENSE_NAMES[i]] = LICENSE_BODIES[i];
}
return licenses;
}
String Engine::get_license_text() const {
return String(GODOT_LICENSE_TEXT);
}
String Engine::get_architecture_name() const {
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64)
return "x86_64";
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
return "x86_32";
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
return "arm64";
#elif defined(__arm__) || defined(_M_ARM)
return "arm32";
#elif defined(__riscv)
#if __riscv_xlen == 8
return "rv64";
#else
return "riscv";
#endif
#elif defined(__powerpc__)
#if defined(__powerpc64__)
return "ppc64";
#else
return "ppc";
#endif
#elif defined(__loongarch64)
return "loongarch64";
#elif defined(__wasm__)
#if defined(__wasm64__)
return "wasm64";
#elif defined(__wasm32__)
return "wasm32";
#endif
#endif
}
bool Engine::is_abort_on_gpu_errors_enabled() const {
return abort_on_gpu_errors;
}
int32_t Engine::get_gpu_index() const {
return gpu_idx;
}
bool Engine::is_validation_layers_enabled() const {
return use_validation_layers;
}
bool Engine::is_generate_spirv_debug_info_enabled() const {
return generate_spirv_debug_info;
}
bool Engine::is_extra_gpu_memory_tracking_enabled() const {
return extra_gpu_memory_tracking;
}
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
bool Engine::is_accurate_breadcrumbs_enabled() const {
return accurate_breadcrumbs;
}
#endif
void Engine::set_print_to_stdout(bool p_enabled) {
CoreGlobals::print_line_enabled = p_enabled;
}
bool Engine::is_printing_to_stdout() const {
return CoreGlobals::print_line_enabled;
}
void Engine::set_print_error_messages(bool p_enabled) {
CoreGlobals::print_error_enabled = p_enabled;
}
bool Engine::is_printing_error_messages() const {
return CoreGlobals::print_error_enabled;
}
void Engine::print_header(const String &p_string) const {
if (_print_header) {
print_line(p_string);
}
}
void Engine::print_header_rich(const String &p_string) const {
if (_print_header) {
print_line_rich(p_string);
}
}
void Engine::add_singleton(const Singleton &p_singleton) {
ERR_FAIL_COND_MSG(singleton_ptrs.has(p_singleton.name), vformat("Can't register singleton '%s' because it already exists.", p_singleton.name));
singletons.push_back(p_singleton);
singleton_ptrs[p_singleton.name] = p_singleton.ptr;
}
Object *Engine::get_singleton_object(const StringName &p_name) const {
HashMap<StringName, Object *>::ConstIterator E = singleton_ptrs.find(p_name);
ERR_FAIL_COND_V_MSG(!E, nullptr, vformat("Failed to retrieve non-existent singleton '%s'.", p_name));
#ifdef TOOLS_ENABLED
if (!is_editor_hint() && is_singleton_editor_only(p_name)) {
ERR_FAIL_V_MSG(nullptr, vformat("Can't retrieve singleton '%s' outside of editor.", p_name));
}
#endif
return E->value;
}
bool Engine::is_singleton_user_created(const StringName &p_name) const {
ERR_FAIL_COND_V(!singleton_ptrs.has(p_name), false);
for (const Singleton &E : singletons) {
if (E.name == p_name && E.user_created) {
return true;
}
}
return false;
}
bool Engine::is_singleton_editor_only(const StringName &p_name) const {
ERR_FAIL_COND_V(!singleton_ptrs.has(p_name), false);
for (const Singleton &E : singletons) {
if (E.name == p_name && E.editor_only) {
return true;
}
}
return false;
}
void Engine::remove_singleton(const StringName &p_name) {
ERR_FAIL_COND(!singleton_ptrs.has(p_name));
for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) {
if (E->get().name == p_name) {
singletons.erase(E);
singleton_ptrs.erase(p_name);
return;
}
}
}
bool Engine::has_singleton(const StringName &p_name) const {
return singleton_ptrs.has(p_name);
}
void Engine::get_singletons(List<Singleton> *p_singletons) {
for (const Singleton &E : singletons) {
#ifdef TOOLS_ENABLED
if (!is_editor_hint() && E.editor_only) {
continue;
}
#endif
p_singletons->push_back(E);
}
}
String Engine::get_write_movie_path() const {
return write_movie_path;
}
void Engine::set_write_movie_path(const String &p_path) {
write_movie_path = p_path;
}
void Engine::set_shader_cache_path(const String &p_path) {
shader_cache_path = p_path;
}
String Engine::get_shader_cache_path() const {
return shader_cache_path;
}
Engine *Engine::singleton = nullptr;
Engine *Engine::get_singleton() {
return singleton;
}
bool Engine::notify_frame_server_synced() {
frame_server_synced = true;
return server_syncs > SERVER_SYNC_FRAME_COUNT_WARNING;
}
void Engine::set_freeze_time_scale(bool p_frozen) {
freeze_time_scale = p_frozen;
}
void Engine::set_embedded_in_editor(bool p_enabled) {
embedded_in_editor = p_enabled;
}
bool Engine::is_embedded_in_editor() const {
return embedded_in_editor;
}
Engine::Engine() {
singleton = this;
}
Engine::~Engine() {
if (singleton == this) {
singleton = nullptr;
}
}
Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr, const StringName &p_class_name) :
name(p_name),
ptr(p_ptr),
class_name(p_class_name) {
#ifdef DEBUG_ENABLED
RefCounted *rc = Object::cast_to<RefCounted>(p_ptr);
if (rc && !rc->is_referenced()) {
WARN_PRINT("You must use Ref<> to ensure the lifetime of a RefCounted object intended to be used as a singleton.");
}
#endif
}

View File

@@ -1,218 +0,0 @@
/**************************************************************************/
/* engine.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef ENGINE_H
#define ENGINE_H
#include "core/os/main_loop.h"
#include "core/string/ustring.h"
#include "core/templates/list.h"
template <typename T>
class TypedArray;
class Engine {
public:
struct Singleton {
StringName name;
Object *ptr = nullptr;
StringName class_name; // Used for binding generation hinting.
// Singleton scope flags.
bool user_created = false;
bool editor_only = false;
Singleton(const StringName &p_name = StringName(), Object *p_ptr = nullptr, const StringName &p_class_name = StringName());
};
private:
friend class Main;
uint64_t frames_drawn = 0;
uint32_t _frame_delay = 0;
uint64_t _frame_ticks = 0;
double _process_step = 0;
int ips = 60;
double physics_jitter_fix = 0.5;
double _fps = 1;
int _max_fps = 0;
int _audio_output_latency = 0;
double _time_scale = 1.0;
uint64_t _physics_frames = 0;
int max_physics_steps_per_frame = 8;
double _physics_interpolation_fraction = 0.0f;
bool abort_on_gpu_errors = false;
bool use_validation_layers = false;
bool generate_spirv_debug_info = false;
bool extra_gpu_memory_tracking = false;
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
bool accurate_breadcrumbs = false;
#endif
int32_t gpu_idx = -1;
uint64_t _process_frames = 0;
bool _in_physics = false;
List<Singleton> singletons;
HashMap<StringName, Object *> singleton_ptrs;
bool editor_hint = false;
bool project_manager_hint = false;
bool extension_reloading = false;
bool embedded_in_editor = false;
bool recovery_mode_hint = false;
bool _print_header = true;
static Engine *singleton;
String write_movie_path;
String shader_cache_path;
static constexpr int SERVER_SYNC_FRAME_COUNT_WARNING = 5;
int server_syncs = 0;
bool frame_server_synced = false;
bool freeze_time_scale = false;
public:
static Engine *get_singleton();
virtual void set_physics_ticks_per_second(int p_ips);
virtual int get_physics_ticks_per_second() const;
virtual void set_max_physics_steps_per_frame(int p_max_physics_steps);
virtual int get_max_physics_steps_per_frame() const;
void set_physics_jitter_fix(double p_threshold);
double get_physics_jitter_fix() const;
virtual void set_max_fps(int p_fps);
virtual int get_max_fps() const;
virtual void set_audio_output_latency(int p_msec);
virtual int get_audio_output_latency() const;
virtual double get_frames_per_second() const { return _fps; }
uint64_t get_frames_drawn();
uint64_t get_physics_frames() const { return _physics_frames; }
uint64_t get_process_frames() const { return _process_frames; }
bool is_in_physics_frame() const { return _in_physics; }
uint64_t get_frame_ticks() const { return _frame_ticks; }
double get_process_step() const { return _process_step; }
double get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
void set_time_scale(double p_scale);
double get_time_scale() const;
double get_unfrozen_time_scale() const;
void set_print_to_stdout(bool p_enabled);
bool is_printing_to_stdout() const;
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;
void print_header(const String &p_string) const;
void print_header_rich(const String &p_string) const;
void set_frame_delay(uint32_t p_msec);
uint32_t get_frame_delay() const;
void add_singleton(const Singleton &p_singleton);
void get_singletons(List<Singleton> *p_singletons);
bool has_singleton(const StringName &p_name) const;
Object *get_singleton_object(const StringName &p_name) const;
void remove_singleton(const StringName &p_name);
bool is_singleton_user_created(const StringName &p_name) const;
bool is_singleton_editor_only(const StringName &p_name) const;
#ifdef TOOLS_ENABLED
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; }
_FORCE_INLINE_ bool is_editor_hint() const { return editor_hint; }
_FORCE_INLINE_ void set_project_manager_hint(bool p_enabled) { project_manager_hint = p_enabled; }
_FORCE_INLINE_ bool is_project_manager_hint() const { return project_manager_hint; }
_FORCE_INLINE_ void set_extension_reloading_enabled(bool p_enabled) { extension_reloading = p_enabled; }
_FORCE_INLINE_ bool is_extension_reloading_enabled() const { return extension_reloading; }
_FORCE_INLINE_ void set_recovery_mode_hint(bool p_enabled) { recovery_mode_hint = p_enabled; }
_FORCE_INLINE_ bool is_recovery_mode_hint() const { return recovery_mode_hint; }
#else
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) {}
_FORCE_INLINE_ bool is_editor_hint() const { return false; }
_FORCE_INLINE_ void set_project_manager_hint(bool p_enabled) {}
_FORCE_INLINE_ bool is_project_manager_hint() const { return false; }
_FORCE_INLINE_ void set_extension_reloading_enabled(bool p_enabled) {}
_FORCE_INLINE_ bool is_extension_reloading_enabled() const { return false; }
_FORCE_INLINE_ void set_recovery_mode_hint(bool p_enabled) {}
_FORCE_INLINE_ bool is_recovery_mode_hint() const { return false; }
#endif
Dictionary get_version_info() const;
Dictionary get_author_info() const;
TypedArray<Dictionary> get_copyright_info() const;
Dictionary get_donor_info() const;
Dictionary get_license_info() const;
String get_license_text() const;
void set_write_movie_path(const String &p_path);
String get_write_movie_path() const;
String get_architecture_name() const;
void set_shader_cache_path(const String &p_path);
String get_shader_cache_path() const;
bool is_abort_on_gpu_errors_enabled() const;
bool is_validation_layers_enabled() const;
bool is_generate_spirv_debug_info_enabled() const;
bool is_extra_gpu_memory_tracking_enabled() const;
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
bool is_accurate_breadcrumbs_enabled() const;
#endif
int32_t get_gpu_index() const;
void increment_frames_drawn();
bool notify_frame_server_synced();
void set_freeze_time_scale(bool p_frozen);
void set_embedded_in_editor(bool p_enabled);
bool is_embedded_in_editor() const;
Engine();
virtual ~Engine();
};
#endif // ENGINE_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,247 +0,0 @@
/**************************************************************************/
/* project_settings.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef PROJECT_SETTINGS_H
#define PROJECT_SETTINGS_H
#include "core/object/class_db.h"
template <typename T>
class TypedArray;
class ProjectSettings : public Object {
GDCLASS(ProjectSettings, Object);
_THREAD_SAFE_CLASS_
friend class TestProjectSettingsInternalsAccessor;
bool is_changed = false;
public:
typedef HashMap<String, Variant> CustomMap;
static const String PROJECT_DATA_DIR_NAME_SUFFIX;
// Properties that are not for built in values begin from this value, so builtin ones are displayed first.
constexpr static const int32_t NO_BUILTIN_ORDER_BASE = 1 << 16;
#ifdef TOOLS_ENABLED
const static PackedStringArray get_required_features();
const static PackedStringArray get_unsupported_features(const PackedStringArray &p_project_features);
#endif // TOOLS_ENABLED
struct AutoloadInfo {
StringName name;
String path;
bool is_singleton = false;
};
protected:
struct VariantContainer {
int order = 0;
bool persist = false;
bool basic = false;
bool internal = false;
Variant variant;
Variant initial;
bool hide_from_editor = false;
bool restart_if_changed = false;
#ifdef DEBUG_METHODS_ENABLED
bool ignore_value_in_docs = false;
#endif
VariantContainer() {}
VariantContainer(const Variant &p_variant, int p_order, bool p_persist = false) :
order(p_order),
persist(p_persist),
variant(p_variant) {
}
};
int last_order = NO_BUILTIN_ORDER_BASE;
int last_builtin_order = 0;
uint64_t last_save_time = 0;
RBMap<StringName, VariantContainer> props; // NOTE: Key order is used e.g. in the save_custom method.
String resource_path;
HashMap<StringName, PropertyInfo> custom_prop_info;
bool using_datapack = false;
bool project_loaded = false;
List<String> input_presets;
HashSet<String> custom_features;
HashMap<StringName, LocalVector<Pair<StringName, StringName>>> feature_overrides;
LocalVector<String> hidden_prefixes;
HashMap<StringName, AutoloadInfo> autoloads;
HashMap<StringName, String> global_groups;
HashMap<StringName, HashSet<StringName>> scene_groups_cache;
Array global_class_list;
bool is_global_class_list_loaded = false;
String project_data_dir_name;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
bool _property_can_revert(const StringName &p_name) const;
bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
void _queue_changed();
void _emit_changed();
static ProjectSettings *singleton;
Error _load_settings_text(const String &p_path);
Error _load_settings_binary(const String &p_path);
Error _load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path);
Error _save_settings_text(const String &p_file, const RBMap<String, List<String>> &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
Error _save_settings_binary(const String &p_file, const RBMap<String, List<String>> &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String());
Error _save_custom_bnd(const String &p_file);
#ifdef TOOLS_ENABLED
const static PackedStringArray _get_supported_features();
const static PackedStringArray _trim_to_supported_features(const PackedStringArray &p_project_features);
#endif // TOOLS_ENABLED
void _convert_to_last_version(int p_from_version);
bool load_resource_pack(const String &p_pack, bool p_replace_files, int p_offset);
bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, int p_offset = 0, bool p_main_pack = false);
void _add_property_info_bind(const Dictionary &p_info);
Error _setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false);
void _add_builtin_input_map();
protected:
static void _bind_methods();
public:
static const int CONFIG_VERSION = 5;
void set_setting(const String &p_setting, const Variant &p_value);
Variant get_setting(const String &p_setting, const Variant &p_default_value = Variant()) const;
TypedArray<Dictionary> get_global_class_list();
void refresh_global_class_list();
void store_global_class_list(const Array &p_classes);
String get_global_class_list_path() const;
bool has_setting(const String &p_var) const;
String localize_path(const String &p_path) const;
String globalize_path(const String &p_path) const;
void set_initial_value(const String &p_name, const Variant &p_value);
void set_as_basic(const String &p_name, bool p_basic);
void set_as_internal(const String &p_name, bool p_internal);
void set_restart_if_changed(const String &p_name, bool p_restart);
void set_ignore_value_in_docs(const String &p_name, bool p_ignore);
bool get_ignore_value_in_docs(const String &p_name) const;
void add_hidden_prefix(const String &p_prefix);
String get_project_data_dir_name() const;
String get_project_data_path() const;
String get_resource_path() const;
String get_imported_files_path() const;
static ProjectSettings *get_singleton();
void clear(const String &p_name);
int get_order(const String &p_name) const;
void set_order(const String &p_name, int p_order);
void set_builtin_order(const String &p_name);
bool is_builtin_setting(const String &p_name) const;
Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false, bool p_ignore_override = false);
Error load_custom(const String &p_path);
Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Vector<String> &p_custom_features = Vector<String>(), bool p_merge_with_current = true);
Error save();
void set_custom_property_info(const PropertyInfo &p_info);
const HashMap<StringName, PropertyInfo> &get_custom_property_info() const;
uint64_t get_last_saved_time() { return last_save_time; }
List<String> get_input_presets() const { return input_presets; }
Variant get_setting_with_override(const StringName &p_name) const;
bool is_using_datapack() const;
bool is_project_loaded() const;
bool has_custom_feature(const String &p_feature) const;
const HashMap<StringName, AutoloadInfo> &get_autoload_list() const;
void add_autoload(const AutoloadInfo &p_autoload);
void remove_autoload(const StringName &p_autoload);
bool has_autoload(const StringName &p_autoload) const;
AutoloadInfo get_autoload(const StringName &p_name) const;
const HashMap<StringName, String> &get_global_groups_list() const;
void add_global_group(const StringName &p_name, const String &p_description);
void remove_global_group(const StringName &p_name);
bool has_global_group(const StringName &p_name) const;
const HashMap<StringName, HashSet<StringName>> &get_scene_groups_cache() const;
void add_scene_groups_cache(const StringName &p_path, const HashSet<StringName> &p_cache);
void remove_scene_groups_cache(const StringName &p_path);
void save_scene_groups_cache();
String get_scene_groups_cache_path() const;
void load_scene_groups_cache();
#ifdef TOOLS_ENABLED
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#endif
ProjectSettings();
ProjectSettings(const String &p_path);
~ProjectSettings();
};
// Not a macro any longer.
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false, bool p_internal = false);
Variant _GLOBAL_DEF(const PropertyInfo &p_info, const Variant &p_default, bool p_restart_if_changed = false, bool p_ignore_value_in_docs = false, bool p_basic = false, bool p_internal = false);
#define GLOBAL_DEF(m_var, m_value) _GLOBAL_DEF(m_var, m_value)
#define GLOBAL_DEF_RST(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true)
#define GLOBAL_DEF_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true)
#define GLOBAL_DEF_RST_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true)
#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var)
#define GLOBAL_DEF_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, true)
#define GLOBAL_DEF_RST_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, false, true)
#define GLOBAL_DEF_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true, true)
#define GLOBAL_DEF_RST_NOVAL_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true, true)
#define GLOBAL_DEF_INTERNAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, false, true)
#endif // PROJECT_SETTINGS_H

View File

@@ -1,62 +0,0 @@
/**************************************************************************/
/* core_bind.compat.inc */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DISABLE_DEPRECATED
namespace core_bind {
// Semaphore
void Semaphore::_post_bind_compat_93605() {
post(1);
}
void Semaphore::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("post"), &Semaphore::_post_bind_compat_93605);
}
// OS
String OS::_read_string_from_stdin_bind_compat_91201() {
return read_string_from_stdin(1024);
}
Dictionary OS::_execute_with_pipe_bind_compat_94434(const String &p_path, const Vector<String> &p_arguments) {
return execute_with_pipe(p_path, p_arguments, true);
}
void OS::_bind_compatibility_methods() {
ClassDB::bind_compatibility_method(D_METHOD("read_string_from_stdin"), &OS::_read_string_from_stdin_bind_compat_91201);
ClassDB::bind_compatibility_method(D_METHOD("execute_with_pipe", "path", "arguments"), &OS::_execute_with_pipe_bind_compat_94434);
}
} // namespace core_bind
#endif // DISABLE_DEPRECATED

File diff suppressed because it is too large Load Diff

View File

@@ -1,674 +0,0 @@
/**************************************************************************/
/* core_bind.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CORE_BIND_H
#define CORE_BIND_H
#include "core/debugger/engine_profiler.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "core/templates/safe_refcount.h"
class MainLoop;
template <typename T>
class TypedArray;
namespace core_bind {
class ResourceLoader : public Object {
GDCLASS(ResourceLoader, Object);
protected:
static void _bind_methods();
static ResourceLoader *singleton;
public:
enum ThreadLoadStatus {
THREAD_LOAD_INVALID_RESOURCE,
THREAD_LOAD_IN_PROGRESS,
THREAD_LOAD_FAILED,
THREAD_LOAD_LOADED
};
enum CacheMode {
CACHE_MODE_IGNORE,
CACHE_MODE_REUSE,
CACHE_MODE_REPLACE,
CACHE_MODE_IGNORE_DEEP,
CACHE_MODE_REPLACE_DEEP,
};
static ResourceLoader *get_singleton() { return singleton; }
Error load_threaded_request(const String &p_path, const String &p_type_hint = "", bool p_use_sub_threads = false, CacheMode p_cache_mode = CACHE_MODE_REUSE);
ThreadLoadStatus load_threaded_get_status(const String &p_path, Array r_progress = ClassDB::default_array_arg);
Ref<Resource> load_threaded_get(const String &p_path);
Ref<Resource> load(const String &p_path, const String &p_type_hint = "", CacheMode p_cache_mode = CACHE_MODE_REUSE);
Vector<String> get_recognized_extensions_for_type(const String &p_type);
void add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front);
void remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader);
void set_abort_on_missing_resources(bool p_abort);
PackedStringArray get_dependencies(const String &p_path);
bool has_cached(const String &p_path);
Ref<Resource> get_cached_ref(const String &p_path);
bool exists(const String &p_path, const String &p_type_hint = "");
ResourceUID::ID get_resource_uid(const String &p_path);
Vector<String> list_directory(const String &p_directory);
ResourceLoader() { singleton = this; }
};
class ResourceSaver : public Object {
GDCLASS(ResourceSaver, Object);
protected:
static void _bind_methods();
static ResourceSaver *singleton;
public:
enum SaverFlags {
FLAG_NONE = 0,
FLAG_RELATIVE_PATHS = 1,
FLAG_BUNDLE_RESOURCES = 2,
FLAG_CHANGE_PATH = 4,
FLAG_OMIT_EDITOR_PROPERTIES = 8,
FLAG_SAVE_BIG_ENDIAN = 16,
FLAG_COMPRESS = 32,
FLAG_REPLACE_SUBRESOURCE_PATHS = 64,
};
static ResourceSaver *get_singleton() { return singleton; }
Error save(const Ref<Resource> &p_resource, const String &p_path, BitField<SaverFlags> p_flags);
Vector<String> get_recognized_extensions(const Ref<Resource> &p_resource);
void add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front);
void remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver);
ResourceUID::ID get_resource_id_for_path(const String &p_path, bool p_generate = false);
ResourceSaver() { singleton = this; }
};
class OS : public Object {
GDCLASS(OS, Object);
mutable HashMap<String, bool> feature_cache;
protected:
static void _bind_methods();
static OS *singleton;
#ifndef DISABLE_DEPRECATED
Dictionary _execute_with_pipe_bind_compat_94434(const String &p_path, const Vector<String> &p_arguments);
String _read_string_from_stdin_bind_compat_91201();
static void _bind_compatibility_methods();
#endif
public:
enum RenderingDriver {
RENDERING_DRIVER_VULKAN,
RENDERING_DRIVER_OPENGL3,
RENDERING_DRIVER_D3D12,
RENDERING_DRIVER_METAL,
};
PackedByteArray get_entropy(int p_bytes);
String get_system_ca_certificates();
enum StdHandleType {
STD_HANDLE_INVALID,
STD_HANDLE_CONSOLE,
STD_HANDLE_FILE,
STD_HANDLE_PIPE,
STD_HANDLE_UNKNOWN,
};
virtual PackedStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
void set_low_processor_usage_mode(bool p_enabled);
bool is_in_low_processor_usage_mode() const;
void set_low_processor_usage_mode_sleep_usec(int p_usec);
int get_low_processor_usage_mode_sleep_usec() const;
void set_delta_smoothing(bool p_enabled);
bool is_delta_smoothing_enabled() const;
void alert(const String &p_alert, const String &p_title = "ALERT!");
void crash(const String &p_message);
Vector<String> get_system_fonts() const;
String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const;
Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const;
String get_executable_path() const;
String read_string_from_stdin(int64_t p_buffer_size = 1024);
PackedByteArray read_buffer_from_stdin(int64_t p_buffer_size = 1024);
StdHandleType get_stdin_type() const;
StdHandleType get_stdout_type() const;
StdHandleType get_stderr_type() const;
int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = ClassDB::default_array_arg, bool p_read_stderr = false, bool p_open_console = false);
Dictionary execute_with_pipe(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true);
int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false);
int create_instance(const Vector<String> &p_arguments);
Error kill(int p_pid);
Error shell_open(const String &p_uri);
Error shell_show_in_file_manager(const String &p_path, bool p_open_folder = true);
bool is_process_running(int p_pid) const;
int get_process_exit_code(int p_pid) const;
int get_process_id() const;
void set_restart_on_exit(bool p_restart, const Vector<String> &p_restart_arguments = Vector<String>());
bool is_restart_on_exit_set() const;
Vector<String> get_restart_on_exit_arguments() const;
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
void set_environment(const String &p_var, const String &p_value) const;
void unset_environment(const String &p_var) const;
String get_name() const;
String get_distribution_name() const;
String get_version() const;
String get_version_alias() const;
Vector<String> get_cmdline_args();
Vector<String> get_cmdline_user_args();
Vector<String> get_video_adapter_driver_info() const;
String get_locale() const;
String get_locale_language() const;
String get_model_name() const;
bool is_debug_build() const;
String get_unique_id() const;
String get_keycode_string(Key p_code) const;
bool is_keycode_unicode(char32_t p_unicode) const;
Key find_keycode_from_string(const String &p_code) const;
void set_use_file_access_save_and_swap(bool p_enable);
uint64_t get_static_memory_usage() const;
uint64_t get_static_memory_peak_usage() const;
Dictionary get_memory_info() const;
void delay_usec(int p_usec) const;
void delay_msec(int p_msec) const;
uint64_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
bool is_userfs_persistent() const;
bool is_stdout_verbose() const;
int get_processor_count() const;
String get_processor_name() const;
enum SystemDir {
SYSTEM_DIR_DESKTOP,
SYSTEM_DIR_DCIM,
SYSTEM_DIR_DOCUMENTS,
SYSTEM_DIR_DOWNLOADS,
SYSTEM_DIR_MOVIES,
SYSTEM_DIR_MUSIC,
SYSTEM_DIR_PICTURES,
SYSTEM_DIR_RINGTONES,
};
String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
Error move_to_trash(const String &p_path) const;
String get_user_data_dir() const;
String get_config_dir() const;
String get_data_dir() const;
String get_cache_dir() const;
String get_temp_dir() const;
Error set_thread_name(const String &p_name);
::Thread::ID get_thread_caller_id() const;
::Thread::ID get_main_thread_id() const;
bool has_feature(const String &p_feature) const;
bool is_sandboxed() const;
bool request_permission(const String &p_name);
bool request_permissions();
Vector<String> get_granted_permissions() const;
void revoke_granted_permissions();
static OS *get_singleton() { return singleton; }
OS() { singleton = this; }
};
class Geometry2D : public Object {
GDCLASS(Geometry2D, Object);
static Geometry2D *singleton;
protected:
static void _bind_methods();
public:
static Geometry2D *get_singleton();
Variant segment_intersects_segment(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b);
Variant line_intersects_line(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b);
Vector<Vector2> get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2);
Vector2 get_closest_point_to_segment(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
Vector2 get_closest_point_to_segment_uncapped(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b);
bool point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const;
bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius);
real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius);
bool is_polygon_clockwise(const Vector<Vector2> &p_polygon);
bool is_point_in_polygon(const Point2 &p_point, const Vector<Vector2> &p_polygon);
Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon);
Vector<int> triangulate_delaunay(const Vector<Vector2> &p_points);
Vector<Point2> convex_hull(const Vector<Point2> &p_points);
TypedArray<PackedVector2Array> decompose_polygon_in_convex(const Vector<Vector2> &p_polygon);
enum PolyBooleanOperation {
OPERATION_UNION,
OPERATION_DIFFERENCE,
OPERATION_INTERSECTION,
OPERATION_XOR
};
// 2D polygon boolean operations.
TypedArray<PackedVector2Array> merge_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Union (add).
TypedArray<PackedVector2Array> clip_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Difference (subtract).
TypedArray<PackedVector2Array> intersect_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Common area (multiply).
TypedArray<PackedVector2Array> exclude_polygons(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // All but common area (xor).
// 2D polyline vs polygon operations.
TypedArray<PackedVector2Array> clip_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Cut.
TypedArray<PackedVector2Array> intersect_polyline_with_polygon(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Chop.
// 2D offset polygons/polylines.
enum PolyJoinType {
JOIN_SQUARE,
JOIN_ROUND,
JOIN_MITER
};
enum PolyEndType {
END_POLYGON,
END_JOINED,
END_BUTT,
END_SQUARE,
END_ROUND
};
TypedArray<PackedVector2Array> offset_polygon(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE);
TypedArray<PackedVector2Array> offset_polyline(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE, PolyEndType p_end_type = END_SQUARE);
Dictionary make_atlas(const Vector<Size2> &p_rects);
TypedArray<Point2i> bresenham_line(const Point2i &p_from, const Point2i &p_to);
Geometry2D() { singleton = this; }
};
class Geometry3D : public Object {
GDCLASS(Geometry3D, Object);
static Geometry3D *singleton;
protected:
static void _bind_methods();
public:
static Geometry3D *get_singleton();
Vector<Vector3> compute_convex_mesh_points(const TypedArray<Plane> &p_planes);
TypedArray<Plane> build_box_planes(const Vector3 &p_extents);
TypedArray<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
TypedArray<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z);
Vector<Vector3> get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2);
Vector3 get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector3 get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b);
Vector3 get_triangle_barycentric_coords(const Vector3 &p_point, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Variant ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Variant segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2);
Vector<Vector3> segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius);
Vector<Vector3> segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius);
Vector<Vector3> segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray<Plane> &p_planes);
Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane);
Vector<int32_t> tetrahedralize_delaunay(const Vector<Vector3> &p_points);
Geometry3D() { singleton = this; }
};
class Marshalls : public Object {
GDCLASS(Marshalls, Object);
static Marshalls *singleton;
protected:
static void _bind_methods();
public:
static Marshalls *get_singleton();
String variant_to_base64(const Variant &p_var, bool p_full_objects = false);
Variant base64_to_variant(const String &p_str, bool p_allow_objects = false);
String raw_to_base64(const Vector<uint8_t> &p_arr);
Vector<uint8_t> base64_to_raw(const String &p_str);
String utf8_to_base64(const String &p_str);
String base64_to_utf8(const String &p_str);
Marshalls() { singleton = this; }
~Marshalls() { singleton = nullptr; }
};
class Mutex : public RefCounted {
GDCLASS(Mutex, RefCounted);
::Mutex mutex;
static void _bind_methods();
public:
void lock();
bool try_lock();
void unlock();
};
class Semaphore : public RefCounted {
GDCLASS(Semaphore, RefCounted);
::Semaphore semaphore;
protected:
static void _bind_methods();
#ifndef DISABLE_DEPRECATED
void _post_bind_compat_93605();
static void _bind_compatibility_methods();
#endif // DISABLE_DEPRECATED
public:
void wait();
bool try_wait();
void post(int p_count = 1);
};
class Thread : public RefCounted {
GDCLASS(Thread, RefCounted);
protected:
Variant ret;
SafeFlag running;
Callable target_callable;
::Thread thread;
static void _bind_methods();
static void _start_func(void *ud);
public:
enum Priority {
PRIORITY_LOW,
PRIORITY_NORMAL,
PRIORITY_HIGH,
PRIORITY_MAX
};
Error start(const Callable &p_callable, Priority p_priority = PRIORITY_NORMAL);
String get_id() const;
bool is_started() const;
bool is_alive() const;
Variant wait_to_finish();
static void set_thread_safety_checks_enabled(bool p_enabled);
};
namespace special {
class ClassDB : public Object {
GDCLASS(ClassDB, Object);
protected:
static void _bind_methods();
public:
enum APIType {
API_CORE,
API_EDITOR,
API_EXTENSION,
API_EDITOR_EXTENSION,
API_NONE,
};
PackedStringArray get_class_list() const;
PackedStringArray get_inheriters_from_class(const StringName &p_class) const;
StringName get_parent_class(const StringName &p_class) const;
bool class_exists(const StringName &p_class) const;
bool is_parent_class(const StringName &p_class, const StringName &p_inherits) const;
bool can_instantiate(const StringName &p_class) const;
Variant instantiate(const StringName &p_class) const;
APIType class_get_api_type(const StringName &p_class) const;
bool class_has_signal(const StringName &p_class, const StringName &p_signal) const;
Dictionary class_get_signal(const StringName &p_class, const StringName &p_signal) const;
TypedArray<Dictionary> class_get_signal_list(const StringName &p_class, bool p_no_inheritance = false) const;
TypedArray<Dictionary> class_get_property_list(const StringName &p_class, bool p_no_inheritance = false) const;
StringName class_get_property_getter(const StringName &p_class, const StringName &p_property);
StringName class_get_property_setter(const StringName &p_class, const StringName &p_property);
Variant class_get_property(Object *p_object, const StringName &p_property) const;
Error class_set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const;
Variant class_get_property_default_value(const StringName &p_class, const StringName &p_property) const;
bool class_has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false) const;
int class_get_method_argument_count(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false) const;
TypedArray<Dictionary> class_get_method_list(const StringName &p_class, bool p_no_inheritance = false) const;
Variant class_call_static(const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error);
PackedStringArray class_get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
bool class_has_integer_constant(const StringName &p_class, const StringName &p_name) const;
int64_t class_get_integer_constant(const StringName &p_class, const StringName &p_name) const;
bool class_has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
PackedStringArray class_get_enum_list(const StringName &p_class, bool p_no_inheritance = false) const;
PackedStringArray class_get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance = false) const;
StringName class_get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
bool is_class_enum_bitfield(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance = false) const;
bool is_class_enabled(const StringName &p_class) const;
#ifdef TOOLS_ENABLED
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#endif
ClassDB() {}
~ClassDB() {}
};
} // namespace special
class Engine : public Object {
GDCLASS(Engine, Object);
protected:
static void _bind_methods();
static Engine *singleton;
public:
static Engine *get_singleton() { return singleton; }
void set_physics_ticks_per_second(int p_ips);
int get_physics_ticks_per_second() const;
void set_max_physics_steps_per_frame(int p_max_physics_steps);
int get_max_physics_steps_per_frame() const;
void set_physics_jitter_fix(double p_threshold);
double get_physics_jitter_fix() const;
double get_physics_interpolation_fraction() const;
void set_max_fps(int p_fps);
int get_max_fps() const;
double get_frames_per_second() const;
uint64_t get_physics_frames() const;
uint64_t get_process_frames() const;
int get_frames_drawn();
void set_time_scale(double p_scale);
double get_time_scale();
MainLoop *get_main_loop() const;
Dictionary get_version_info() const;
Dictionary get_author_info() const;
TypedArray<Dictionary> get_copyright_info() const;
Dictionary get_donor_info() const;
Dictionary get_license_info() const;
String get_license_text() const;
String get_architecture_name() const;
bool is_in_physics_frame() const;
bool has_singleton(const StringName &p_name) const;
Object *get_singleton_object(const StringName &p_name) const;
void register_singleton(const StringName &p_name, Object *p_object);
void unregister_singleton(const StringName &p_name);
Vector<String> get_singleton_list() const;
Error register_script_language(ScriptLanguage *p_language);
Error unregister_script_language(const ScriptLanguage *p_language);
int get_script_language_count();
ScriptLanguage *get_script_language(int p_index) const;
void set_editor_hint(bool p_enabled);
bool is_editor_hint() const;
bool is_embedded_in_editor() const;
// `set_write_movie_path()` is not exposed to the scripting API as changing it at run-time has no effect.
String get_write_movie_path() const;
void set_print_to_stdout(bool p_enabled);
bool is_printing_to_stdout() const;
void set_print_error_messages(bool p_enabled);
bool is_printing_error_messages() const;
#ifdef TOOLS_ENABLED
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
#endif
Engine() { singleton = this; }
};
class EngineDebugger : public Object {
GDCLASS(EngineDebugger, Object);
HashMap<StringName, Callable> captures;
HashMap<StringName, Ref<EngineProfiler>> profilers;
protected:
static void _bind_methods();
static EngineDebugger *singleton;
public:
static EngineDebugger *get_singleton() { return singleton; }
bool is_active();
void register_profiler(const StringName &p_name, Ref<EngineProfiler> p_profiler);
void unregister_profiler(const StringName &p_name);
bool is_profiling(const StringName &p_name);
bool has_profiler(const StringName &p_name);
void profiler_add_frame_data(const StringName &p_name, const Array &p_data);
void profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts = Array());
void register_message_capture(const StringName &p_name, const Callable &p_callable);
void unregister_message_capture(const StringName &p_name);
bool has_capture(const StringName &p_name);
void send_message(const String &p_msg, const Array &p_data);
void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false);
void script_debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false);
static Error call_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured);
void line_poll();
void set_lines_left(int p_lines);
int get_lines_left() const;
void set_depth(int p_depth);
int get_depth() const;
bool is_breakpoint(int p_line, const StringName &p_source) const;
bool is_skipping_breakpoints() const;
void insert_breakpoint(int p_line, const StringName &p_source);
void remove_breakpoint(int p_line, const StringName &p_source);
void clear_breakpoints();
EngineDebugger() { singleton = this; }
~EngineDebugger();
};
} // namespace core_bind
VARIANT_ENUM_CAST(core_bind::ResourceLoader::ThreadLoadStatus);
VARIANT_ENUM_CAST(core_bind::ResourceLoader::CacheMode);
VARIANT_BITFIELD_CAST(core_bind::ResourceSaver::SaverFlags);
VARIANT_ENUM_CAST(core_bind::OS::RenderingDriver);
VARIANT_ENUM_CAST(core_bind::OS::SystemDir);
VARIANT_ENUM_CAST(core_bind::OS::StdHandleType);
VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyBooleanOperation);
VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyJoinType);
VARIANT_ENUM_CAST(core_bind::Geometry2D::PolyEndType);
VARIANT_ENUM_CAST(core_bind::Thread::Priority);
VARIANT_ENUM_CAST(core_bind::special::ClassDB::APIType);
#endif // CORE_BIND_H

View File

@@ -1,315 +0,0 @@
"""Functions used to generate source files during build time"""
import zlib
def escape_string(s):
def charcode_to_c_escapes(c):
rev_result = []
while c >= 256:
c, low = (c // 256, c % 256)
rev_result.append("\\%03o" % low)
rev_result.append("\\%03o" % c)
return "".join(reversed(rev_result))
result = ""
if isinstance(s, str):
s = s.encode("utf-8")
for c in s:
if not (32 <= c < 127) or c in (ord("\\"), ord('"')):
result += charcode_to_c_escapes(c)
else:
result += chr(c)
return result
def make_certs_header(target, source, env):
src = str(source[0])
dst = str(target[0])
with open(src, "rb") as f, open(dst, "w", encoding="utf-8", newline="\n") as g:
buf = f.read()
decomp_size = len(buf)
# Use maximum zlib compression level to further reduce file size
# (at the cost of initial build times).
buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION)
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef CERTS_COMPRESSED_GEN_H\n")
g.write("#define CERTS_COMPRESSED_GEN_H\n")
# System certs path. Editor will use them if defined. (for package maintainers)
path = env["system_certs_path"]
g.write('#define _SYSTEM_CERTS_PATH "%s"\n' % str(path))
if env["builtin_certs"]:
# Defined here and not in env so changing it does not trigger a full rebuild.
g.write("#define BUILTIN_CERTS_ENABLED\n")
g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n")
g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n")
g.write("static const unsigned char _certs_compressed[] = {\n")
for i in range(len(buf)):
g.write("\t" + str(buf[i]) + ",\n")
g.write("};\n")
g.write("#endif // CERTS_COMPRESSED_GEN_H")
def make_authors_header(target, source, env):
sections = [
"Project Founders",
"Lead Developer",
"Project Manager",
"Developers",
]
sections_id = [
"AUTHORS_FOUNDERS",
"AUTHORS_LEAD_DEVELOPERS",
"AUTHORS_PROJECT_MANAGERS",
"AUTHORS_DEVELOPERS",
]
src = str(source[0])
dst = str(target[0])
with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g:
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef AUTHORS_GEN_H\n")
g.write("#define AUTHORS_GEN_H\n")
reading = False
def close_section():
g.write("\t0\n")
g.write("};\n")
for line in f:
if reading:
if line.startswith(" "):
g.write('\t"' + escape_string(line.strip()) + '",\n')
continue
if line.startswith("## "):
if reading:
close_section()
reading = False
for section, section_id in zip(sections, sections_id):
if line.strip().endswith(section):
current_section = escape_string(section_id)
reading = True
g.write("const char *const " + current_section + "[] = {\n")
break
if reading:
close_section()
g.write("#endif // AUTHORS_GEN_H\n")
def make_donors_header(target, source, env):
sections = [
"Patrons",
"Platinum sponsors",
"Gold sponsors",
"Silver sponsors",
"Diamond members",
"Titanium members",
"Platinum members",
"Gold members",
]
sections_id = [
"DONORS_PATRONS",
"DONORS_SPONSORS_PLATINUM",
"DONORS_SPONSORS_GOLD",
"DONORS_SPONSORS_SILVER",
"DONORS_MEMBERS_DIAMOND",
"DONORS_MEMBERS_TITANIUM",
"DONORS_MEMBERS_PLATINUM",
"DONORS_MEMBERS_GOLD",
]
src = str(source[0])
dst = str(target[0])
with open(src, "r", encoding="utf-8") as f, open(dst, "w", encoding="utf-8", newline="\n") as g:
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef DONORS_GEN_H\n")
g.write("#define DONORS_GEN_H\n")
reading = False
def close_section():
g.write("\t0\n")
g.write("};\n")
for line in f:
if reading >= 0:
if line.startswith(" "):
g.write('\t"' + escape_string(line.strip()) + '",\n')
continue
if line.startswith("## "):
if reading:
close_section()
reading = False
for section, section_id in zip(sections, sections_id):
if line.strip().endswith(section):
current_section = escape_string(section_id)
reading = True
g.write("const char *const " + current_section + "[] = {\n")
break
if reading:
close_section()
g.write("#endif // DONORS_GEN_H\n")
def make_license_header(target, source, env):
src_copyright = str(source[0])
src_license = str(source[1])
dst = str(target[0])
class LicenseReader:
def __init__(self, license_file):
self._license_file = license_file
self.line_num = 0
self.current = self.next_line()
def next_line(self):
line = self._license_file.readline()
self.line_num += 1
while line.startswith("#"):
line = self._license_file.readline()
self.line_num += 1
self.current = line
return line
def next_tag(self):
if ":" not in self.current:
return ("", [])
tag, line = self.current.split(":", 1)
lines = [line.strip()]
while self.next_line() and self.current.startswith(" "):
lines.append(self.current.strip())
return (tag, lines)
from collections import OrderedDict
projects: dict = OrderedDict()
license_list = []
with open(src_copyright, "r", encoding="utf-8") as copyright_file:
reader = LicenseReader(copyright_file)
part = {}
while reader.current:
tag, content = reader.next_tag()
if tag in ("Files", "Copyright", "License"):
part[tag] = content[:]
elif tag == "Comment" and part:
# attach non-empty part to named project
projects[content[0]] = projects.get(content[0], []) + [part]
if not tag or not reader.current:
# end of a paragraph start a new part
if "License" in part and "Files" not in part:
# no Files tag in this one, so assume standalone license
license_list.append(part["License"])
part = {}
reader.next_line()
data_list: list = []
for project in iter(projects.values()):
for part in project:
part["file_index"] = len(data_list)
data_list += part["Files"]
part["copyright_index"] = len(data_list)
data_list += part["Copyright"]
with open(dst, "w", encoding="utf-8", newline="\n") as f:
f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
f.write("#ifndef LICENSE_GEN_H\n")
f.write("#define LICENSE_GEN_H\n")
f.write("const char *const GODOT_LICENSE_TEXT =")
with open(src_license, "r", encoding="utf-8") as license_file:
for line in license_file:
escaped_string = escape_string(line.strip())
f.write('\n\t\t"' + escaped_string + '\\n"')
f.write(";\n\n")
f.write(
"struct ComponentCopyrightPart {\n"
"\tconst char *license;\n"
"\tconst char *const *files;\n"
"\tconst char *const *copyright_statements;\n"
"\tint file_count;\n"
"\tint copyright_count;\n"
"};\n\n"
)
f.write(
"struct ComponentCopyright {\n"
"\tconst char *name;\n"
"\tconst ComponentCopyrightPart *parts;\n"
"\tint part_count;\n"
"};\n\n"
)
f.write("const char *const COPYRIGHT_INFO_DATA[] = {\n")
for line in data_list:
f.write('\t"' + escape_string(line) + '",\n')
f.write("};\n\n")
f.write("const ComponentCopyrightPart COPYRIGHT_PROJECT_PARTS[] = {\n")
part_index = 0
part_indexes = {}
for project_name, project in iter(projects.items()):
part_indexes[project_name] = part_index
for part in project:
f.write(
'\t{ "'
+ escape_string(part["License"][0])
+ '", '
+ "&COPYRIGHT_INFO_DATA["
+ str(part["file_index"])
+ "], "
+ "&COPYRIGHT_INFO_DATA["
+ str(part["copyright_index"])
+ "], "
+ str(len(part["Files"]))
+ ", "
+ str(len(part["Copyright"]))
+ " },\n"
)
part_index += 1
f.write("};\n\n")
f.write("const int COPYRIGHT_INFO_COUNT = " + str(len(projects)) + ";\n")
f.write("const ComponentCopyright COPYRIGHT_INFO[] = {\n")
for project_name, project in iter(projects.items()):
f.write(
'\t{ "'
+ escape_string(project_name)
+ '", '
+ "&COPYRIGHT_PROJECT_PARTS["
+ str(part_indexes[project_name])
+ "], "
+ str(len(project))
+ " },\n"
)
f.write("};\n\n")
f.write("const int LICENSE_COUNT = " + str(len(license_list)) + ";\n")
f.write("const char *const LICENSE_NAMES[] = {\n")
for license in license_list:
f.write('\t"' + escape_string(license[0]) + '",\n')
f.write("};\n\n")
f.write("const char *const LICENSE_BODIES[] = {\n\n")
for license in license_list:
for line in license[1:]:
if line == ".":
f.write('\t"\\n"\n')
else:
f.write('\t"' + escape_string(line) + '\\n"\n')
f.write('\t"",\n\n')
f.write("};\n\n")
f.write("#endif // LICENSE_GEN_H\n")

View File

@@ -1,862 +0,0 @@
/**************************************************************************/
/* core_constants.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "core_constants.h"
#include "core/input/input_event.h"
#include "core/object/class_db.h"
#include "core/os/keyboard.h"
#include "core/variant/variant.h"
struct _CoreConstant {
#ifdef DEBUG_METHODS_ENABLED
bool ignore_value_in_docs = false;
bool is_bitfield = false;
#endif
StringName enum_name;
const char *name = nullptr;
int64_t value = 0;
_CoreConstant() {}
#ifdef DEBUG_METHODS_ENABLED
_CoreConstant(const StringName &p_enum_name, const char *p_name, int64_t p_value, bool p_ignore_value_in_docs = false, bool p_is_bitfield = false) :
ignore_value_in_docs(p_ignore_value_in_docs),
is_bitfield(p_is_bitfield),
enum_name(p_enum_name),
name(p_name),
value(p_value) {
}
#else
_CoreConstant(const StringName &p_enum_name, const char *p_name, int64_t p_value) :
enum_name(p_enum_name),
name(p_name),
value(p_value) {
}
#endif
};
static Vector<_CoreConstant> _global_constants;
static HashMap<StringName, int> _global_constants_map;
static HashMap<StringName, Vector<_CoreConstant>> _global_enums;
#ifdef DEBUG_METHODS_ENABLED
#define BIND_CORE_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_FLAG(m_constant) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant, false, true)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
// This just binds enum classes as if they were regular enum constants.
#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_CLASS_FLAG(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member, false, true)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_name); \
_global_constants.push_back(_CoreConstant(enum_name, #m_name, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(m_enum, m_name, m_member) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_enum::m_member, #m_name); \
_global_constants.push_back(_CoreConstant(enum_name, #m_name, (int64_t)m_enum::m_member, false, true)); \
_global_constants_map[#m_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member, true)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, m_custom_name, m_constant)); \
_global_constants_map[m_custom_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_CONSTANT_NO_VAL(m_constant) \
_global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant, true)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1;
#define BIND_CORE_ENUM_CONSTANT_NO_VAL(m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant, true)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, m_custom_name, m_constant, true)); \
_global_constants_map[m_custom_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#else
#define BIND_CORE_CONSTANT(m_constant) \
_global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1;
#define BIND_CORE_ENUM_CONSTANT(m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_FLAG(m_constant) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
// This just binds enum classes as if they were regular enum constants.
#define BIND_CORE_ENUM_CLASS_CONSTANT(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_CLASS_FLAG(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(m_enum, m_name, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_name); \
_global_constants.push_back(_CoreConstant(enum_name, #m_name, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(m_enum, m_name, m_member) \
{ \
StringName enum_name = __constant_get_bitfield_name(m_enum::m_member, #m_name); \
_global_constants.push_back(_CoreConstant(enum_name, #m_name, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CLASS_CONSTANT_NO_VAL(m_enum, m_prefix, m_member) \
{ \
StringName enum_name = __constant_get_enum_name(m_enum::m_member, #m_prefix "_" #m_member); \
_global_constants.push_back(_CoreConstant(enum_name, #m_prefix "_" #m_member, (int64_t)m_enum::m_member)); \
_global_constants_map[#m_prefix "_" #m_member] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CONSTANT_CUSTOM(m_custom_name, m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, m_custom_name, m_constant)); \
_global_constants_map[m_custom_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_CONSTANT_NO_VAL(m_constant) \
_global_constants.push_back(_CoreConstant(StringName(), #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1;
#define BIND_CORE_ENUM_CONSTANT_NO_VAL(m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, #m_constant, m_constant)); \
_global_constants_map[#m_constant] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#define BIND_CORE_ENUM_CONSTANT_CUSTOM_NO_VAL(m_custom_name, m_constant) \
{ \
StringName enum_name = __constant_get_enum_name(m_constant, #m_constant); \
_global_constants.push_back(_CoreConstant(enum_name, m_custom_name, m_constant)); \
_global_constants_map[m_custom_name] = _global_constants.size() - 1; \
_global_enums[enum_name].push_back((_global_constants.ptr())[_global_constants.size() - 1]); \
}
#endif
void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(SIDE_LEFT);
BIND_CORE_ENUM_CONSTANT(SIDE_TOP);
BIND_CORE_ENUM_CONSTANT(SIDE_RIGHT);
BIND_CORE_ENUM_CONSTANT(SIDE_BOTTOM);
BIND_CORE_ENUM_CONSTANT(CORNER_TOP_LEFT);
BIND_CORE_ENUM_CONSTANT(CORNER_TOP_RIGHT);
BIND_CORE_ENUM_CONSTANT(CORNER_BOTTOM_RIGHT);
BIND_CORE_ENUM_CONSTANT(CORNER_BOTTOM_LEFT);
BIND_CORE_ENUM_CONSTANT(VERTICAL);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL);
BIND_CORE_ENUM_CONSTANT(CLOCKWISE);
BIND_CORE_ENUM_CONSTANT(COUNTERCLOCKWISE);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_LEFT);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_CENTER);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_RIGHT);
BIND_CORE_ENUM_CONSTANT(HORIZONTAL_ALIGNMENT_FILL);
BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_TOP);
BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_CENTER);
BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_BOTTOM);
BIND_CORE_ENUM_CONSTANT(VERTICAL_ALIGNMENT_FILL);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP_TO);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER_TO);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BASELINE_TO);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM_TO);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_TOP);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_CENTER);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BASELINE);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TO_BOTTOM);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TOP);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_CENTER);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_BOTTOM);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_IMAGE_MASK);
BIND_CORE_ENUM_CONSTANT(INLINE_ALIGNMENT_TEXT_MASK);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, XYZ);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, XZY);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, YXZ);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, YZX);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, ZXY);
BIND_CORE_ENUM_CLASS_CONSTANT(EulerOrder, EULER_ORDER, ZYX);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NONE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPECIAL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ESCAPE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, TAB);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKTAB);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKSPACE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ENTER);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_ENTER);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, INSERT);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_DELETE, KEY_DELETE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAUSE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PRINT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SYSREQ);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CLEAR);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HOME);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, END);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAGEUP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PAGEDOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SHIFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CTRL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, META);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ALT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, CAPSLOCK);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NUMLOCK);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SCROLLLOCK);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F1);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F2);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F3);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F4);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F5);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F6);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F7);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F8);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F9);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F10);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F11);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F12);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F13);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F14);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F15);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F16);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F17);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F18);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F19);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F20);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F21);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F22);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F23);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F24);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F25);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F26);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F27);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F28);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F29);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F30);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F31);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F32);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F33);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F34);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F35);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_MULTIPLY);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_DIVIDE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_SUBTRACT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_PERIOD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_ADD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_0);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_1);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_2);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_3);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_4);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_5);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_6);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_7);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_8);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KP_9);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MENU);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HYPER);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HELP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACK);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, FORWARD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, STOP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, REFRESH);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEDOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEMUTE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, VOLUMEUP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIAPLAY);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIASTOP);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIAPREVIOUS);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIANEXT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MEDIARECORD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, HOMEPAGE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, FAVORITES);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SEARCH);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, STANDBY);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, OPENURL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHMAIL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHMEDIA);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH0);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH1);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH2);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH3);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH4);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH5);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH6);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH7);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH8);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCH9);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHA);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHB);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHC);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LAUNCHF);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GLOBE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, KEYBOARD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_EISU);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, JIS_KANA);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNKNOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SPACE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EXCLAM);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUOTEDBL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, NUMBERSIGN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, DOLLAR);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PERCENT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AMPERSAND);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, APOSTROPHE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PARENLEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PARENRIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASTERISK);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PLUS);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, COMMA);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, MINUS);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, PERIOD);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SLASH);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_0, KEY_0);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_1, KEY_1);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_2, KEY_2);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_3, KEY_3);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_4, KEY_4);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_5, KEY_5);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_6, KEY_6);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_7, KEY_7);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_8, KEY_8);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(Key, KEY_9, KEY_9);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, COLON);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SEMICOLON);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, LESS);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, EQUAL);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, GREATER);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUESTION);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, AT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, A);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, B);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, C);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, D);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, E);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, F);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, G);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, H);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, I);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, J);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, K);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, L);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, M);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, N);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, O);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, P);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Q);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, R);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, S);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, T);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, U);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, V);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, W);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, X);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Y);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, Z);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACKETLEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BACKSLASH);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACKETRIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIICIRCUM);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, UNDERSCORE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, QUOTELEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACELEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BAR);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, BRACERIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, ASCIITILDE);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, YEN);
BIND_CORE_ENUM_CLASS_CONSTANT(Key, KEY, SECTION);
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_CODE_MASK, CODE_MASK);
BIND_CORE_BITFIELD_CLASS_FLAG_CUSTOM(KeyModifierMask, KEY_MODIFIER_MASK, MODIFIER_MASK);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CMD_OR_CTRL);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, SHIFT);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, ALT);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, META);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, CTRL);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, KPAD);
BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, GROUP_SWITCH);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, UNSPECIFIED);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, NONE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, MIDDLE);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_UP);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_DOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, WHEEL_RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON1, MB_XBUTTON1);
BIND_CORE_ENUM_CLASS_CONSTANT_CUSTOM(MouseButton, MOUSE_BUTTON_XBUTTON2, MB_XBUTTON2);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, LEFT);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, RIGHT);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MIDDLE);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON1);
BIND_CORE_BITFIELD_CLASS_FLAG(MouseButtonMask, MOUSE_BUTTON_MASK, MB_XBUTTON2);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, INVALID);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, A);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, B);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, X);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, Y);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, BACK);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, GUIDE);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, START);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, LEFT_STICK);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, RIGHT_STICK);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, LEFT_SHOULDER);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, RIGHT_SHOULDER);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_UP);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_DOWN);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, DPAD_RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, MISC1);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE1);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE2);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE3);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, PADDLE4);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, TOUCHPAD);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, SDL_MAX);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyButton, JOY_BUTTON, MAX);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, INVALID);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_X);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, LEFT_Y);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_X);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, RIGHT_Y);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_LEFT);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, TRIGGER_RIGHT);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, SDL_MAX);
BIND_CORE_ENUM_CLASS_CONSTANT(JoyAxis, JOY_AXIS, MAX);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NONE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_OFF);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, NOTE_ON);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, AFTERTOUCH);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CONTROL_CHANGE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PROGRAM_CHANGE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CHANNEL_PRESSURE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, PITCH_BEND);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SYSTEM_EXCLUSIVE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, QUARTER_FRAME);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SONG_POSITION_POINTER);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SONG_SELECT);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, TUNE_REQUEST);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, TIMING_CLOCK);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, START);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, CONTINUE);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, STOP);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, ACTIVE_SENSING);
BIND_CORE_ENUM_CLASS_CONSTANT(MIDIMessage, MIDI_MESSAGE, SYSTEM_RESET);
// error list
BIND_CORE_ENUM_CONSTANT(OK); // (0)
BIND_CORE_ENUM_CONSTANT(FAILED);
BIND_CORE_ENUM_CONSTANT(ERR_UNAVAILABLE);
BIND_CORE_ENUM_CONSTANT(ERR_UNCONFIGURED);
BIND_CORE_ENUM_CONSTANT(ERR_UNAUTHORIZED);
BIND_CORE_ENUM_CONSTANT(ERR_PARAMETER_RANGE_ERROR); // (5)
BIND_CORE_ENUM_CONSTANT(ERR_OUT_OF_MEMORY);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_NOT_FOUND);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_BAD_DRIVE);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_BAD_PATH);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_NO_PERMISSION); // (10)
BIND_CORE_ENUM_CONSTANT(ERR_FILE_ALREADY_IN_USE);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_OPEN);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_WRITE);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_CANT_READ);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_UNRECOGNIZED); // (15)
BIND_CORE_ENUM_CONSTANT(ERR_FILE_CORRUPT);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_MISSING_DEPENDENCIES);
BIND_CORE_ENUM_CONSTANT(ERR_FILE_EOF);
BIND_CORE_ENUM_CONSTANT(ERR_CANT_OPEN);
BIND_CORE_ENUM_CONSTANT(ERR_CANT_CREATE); // (20)
BIND_CORE_ENUM_CONSTANT(ERR_QUERY_FAILED);
BIND_CORE_ENUM_CONSTANT(ERR_ALREADY_IN_USE);
BIND_CORE_ENUM_CONSTANT(ERR_LOCKED);
BIND_CORE_ENUM_CONSTANT(ERR_TIMEOUT);
BIND_CORE_ENUM_CONSTANT(ERR_CANT_CONNECT); // (25)
BIND_CORE_ENUM_CONSTANT(ERR_CANT_RESOLVE);
BIND_CORE_ENUM_CONSTANT(ERR_CONNECTION_ERROR);
BIND_CORE_ENUM_CONSTANT(ERR_CANT_ACQUIRE_RESOURCE);
BIND_CORE_ENUM_CONSTANT(ERR_CANT_FORK);
BIND_CORE_ENUM_CONSTANT(ERR_INVALID_DATA); // (30)
BIND_CORE_ENUM_CONSTANT(ERR_INVALID_PARAMETER);
BIND_CORE_ENUM_CONSTANT(ERR_ALREADY_EXISTS);
BIND_CORE_ENUM_CONSTANT(ERR_DOES_NOT_EXIST);
BIND_CORE_ENUM_CONSTANT(ERR_DATABASE_CANT_READ);
BIND_CORE_ENUM_CONSTANT(ERR_DATABASE_CANT_WRITE); // (35)
BIND_CORE_ENUM_CONSTANT(ERR_COMPILATION_FAILED);
BIND_CORE_ENUM_CONSTANT(ERR_METHOD_NOT_FOUND);
BIND_CORE_ENUM_CONSTANT(ERR_LINK_FAILED);
BIND_CORE_ENUM_CONSTANT(ERR_SCRIPT_FAILED);
BIND_CORE_ENUM_CONSTANT(ERR_CYCLIC_LINK); // (40)
BIND_CORE_ENUM_CONSTANT(ERR_INVALID_DECLARATION);
BIND_CORE_ENUM_CONSTANT(ERR_DUPLICATE_SYMBOL);
BIND_CORE_ENUM_CONSTANT(ERR_PARSE_ERROR);
BIND_CORE_ENUM_CONSTANT(ERR_BUSY);
BIND_CORE_ENUM_CONSTANT(ERR_SKIP); // (45)
BIND_CORE_ENUM_CONSTANT(ERR_HELP);
BIND_CORE_ENUM_CONSTANT(ERR_BUG);
BIND_CORE_ENUM_CONSTANT(ERR_PRINTER_ON_FIRE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NONE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM_SUGGESTION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LINK);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FLAGS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_RENDER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_PHYSICS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_2D_NAVIGATION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_RENDER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_PHYSICS);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_3D_NAVIGATION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LAYERS_AVOIDANCE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_DIR);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_DIR);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXPRESSION);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PLACEHOLDER_TEXT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_OBJECT_ID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TYPE_STRING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_OBJECT_TOO_BIG);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_DICTIONARY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALE_ID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALIZABLE_STRING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_HIDE_QUATERNION_EDIT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_PASSWORD);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_TOOL_BUTTON);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ONESHOT);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NONE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORAGE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_INTERNAL);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKABLE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CHECKED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_GROUP);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CATEGORY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SUBGROUP);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_BITFIELD);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_VARIABLE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_STORE_IF_NULL);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_CLASS_IS_ENUM);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NIL_IS_VARIANT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_ARRAY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_ALWAYS_DUPLICATE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NEVER_DUPLICATE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_HIGH_END_GFX);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_KEYING_INCREMENTS);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFERRED_SET_RESOURCE);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_EDITOR_BASIC_SETTING);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_READ_ONLY);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_SECRET);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_DEFAULT);
BIND_CORE_BITFIELD_FLAG(PROPERTY_USAGE_NO_EDITOR);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_NORMAL);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_EDITOR);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_CONST);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VIRTUAL);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VARARG);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_STATIC);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAG_VIRTUAL_REQUIRED);
BIND_CORE_BITFIELD_FLAG(METHOD_FLAGS_DEFAULT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BOOL", Variant::BOOL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_INT", Variant::INT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_FLOAT", Variant::FLOAT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING", Variant::STRING);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2", Variant::VECTOR2);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR2I", Variant::VECTOR2I);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RECT2", Variant::RECT2);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RECT2I", Variant::RECT2I);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4", Variant::VECTOR4);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4I", Variant::VECTOR4I);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUATERNION", Variant::QUATERNION);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM3D", Variant::TRANSFORM3D);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PROJECTION", Variant::PROJECTION);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_RID", Variant::RID);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_OBJECT", Variant::OBJECT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_CALLABLE", Variant::CALLABLE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_SIGNAL", Variant::SIGNAL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_DICTIONARY", Variant::DICTIONARY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_ARRAY", Variant::ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_BYTE_ARRAY", Variant::PACKED_BYTE_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT32_ARRAY", Variant::PACKED_INT32_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_INT64_ARRAY", Variant::PACKED_INT64_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT32_ARRAY", Variant::PACKED_FLOAT32_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_FLOAT64_ARRAY", Variant::PACKED_FLOAT64_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_STRING_ARRAY", Variant::PACKED_STRING_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR2_ARRAY", Variant::PACKED_VECTOR2_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR3_ARRAY", Variant::PACKED_VECTOR3_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_COLOR_ARRAY", Variant::PACKED_COLOR_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PACKED_VECTOR4_ARRAY", Variant::PACKED_VECTOR4_ARRAY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_MAX", Variant::VARIANT_MAX);
//comparison
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_EQUAL", Variant::OP_EQUAL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NOT_EQUAL", Variant::OP_NOT_EQUAL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_LESS", Variant::OP_LESS);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_LESS_EQUAL", Variant::OP_LESS_EQUAL);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_GREATER", Variant::OP_GREATER);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_GREATER_EQUAL", Variant::OP_GREATER_EQUAL);
//mathematic
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_ADD", Variant::OP_ADD);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SUBTRACT", Variant::OP_SUBTRACT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MULTIPLY", Variant::OP_MULTIPLY);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_DIVIDE", Variant::OP_DIVIDE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NEGATE", Variant::OP_NEGATE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_POSITIVE", Variant::OP_POSITIVE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MODULE", Variant::OP_MODULE);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_POWER", Variant::OP_POWER);
//bitwise
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_LEFT", Variant::OP_SHIFT_LEFT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_SHIFT_RIGHT", Variant::OP_SHIFT_RIGHT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_AND", Variant::OP_BIT_AND);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_OR", Variant::OP_BIT_OR);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_XOR", Variant::OP_BIT_XOR);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_BIT_NEGATE", Variant::OP_BIT_NEGATE);
//logic
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_AND", Variant::OP_AND);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_OR", Variant::OP_OR);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_XOR", Variant::OP_XOR);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_NOT", Variant::OP_NOT);
//containment
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_IN", Variant::OP_IN);
BIND_CORE_ENUM_CONSTANT_CUSTOM("OP_MAX", Variant::OP_MAX);
}
void unregister_global_constants() {
_global_constants.clear();
_global_constants_map.clear();
_global_enums.clear();
}
int CoreConstants::get_global_constant_count() {
return _global_constants.size();
}
StringName CoreConstants::get_global_constant_enum(int p_idx) {
return _global_constants[p_idx].enum_name;
}
#ifdef DEBUG_METHODS_ENABLED
bool CoreConstants::is_global_constant_bitfield(int p_idx) {
return _global_constants[p_idx].is_bitfield;
}
bool CoreConstants::get_ignore_value_in_docs(int p_idx) {
return _global_constants[p_idx].ignore_value_in_docs;
}
#else
bool CoreConstants::is_global_constant_bitfield(int p_idx) {
return false;
}
bool CoreConstants::get_ignore_value_in_docs(int p_idx) {
return false;
}
#endif
const char *CoreConstants::get_global_constant_name(int p_idx) {
return _global_constants[p_idx].name;
}
int64_t CoreConstants::get_global_constant_value(int p_idx) {
return _global_constants[p_idx].value;
}
bool CoreConstants::is_global_constant(const StringName &p_name) {
return _global_constants_map.has(p_name);
}
int CoreConstants::get_global_constant_index(const StringName &p_name) {
ERR_FAIL_COND_V_MSG(!_global_constants_map.has(p_name), -1, "Trying to get index of non-existing constant.");
return _global_constants_map[p_name];
}
bool CoreConstants::is_global_enum(const StringName &p_enum) {
return _global_enums.has(p_enum);
}
void CoreConstants::get_enum_values(const StringName &p_enum, HashMap<StringName, int64_t> *p_values) {
ERR_FAIL_NULL_MSG(p_values, "Trying to get enum values with null map.");
ERR_FAIL_COND_MSG(!_global_enums.has(p_enum), "Trying to get values of non-existing enum.");
for (const _CoreConstant &constant : _global_enums[p_enum]) {
(*p_values)[constant.name] = constant.value;
}
}

View File

@@ -1,51 +0,0 @@
/**************************************************************************/
/* core_constants.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CORE_CONSTANTS_H
#define CORE_CONSTANTS_H
#include "core/string/string_name.h"
#include "core/templates/hash_map.h"
class CoreConstants {
public:
static int get_global_constant_count();
static StringName get_global_constant_enum(int p_idx);
static bool is_global_constant_bitfield(int p_idx);
static bool get_ignore_value_in_docs(int p_idx);
static const char *get_global_constant_name(int p_idx);
static int64_t get_global_constant_value(int p_idx);
static bool is_global_constant(const StringName &p_name);
static int get_global_constant_index(const StringName &p_name);
static bool is_global_enum(const StringName &p_enum);
static void get_enum_values(const StringName &p_enum, HashMap<StringName, int64_t> *p_values);
};
#endif // CORE_CONSTANTS_H

View File

@@ -1,35 +0,0 @@
/**************************************************************************/
/* core_globals.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "core_globals.h"
bool CoreGlobals::leak_reporting_enabled = true;
bool CoreGlobals::print_line_enabled = true;
bool CoreGlobals::print_error_enabled = true;

View File

@@ -1,44 +0,0 @@
/**************************************************************************/
/* core_globals.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CORE_GLOBALS_H
#define CORE_GLOBALS_H
// Home for state needed from global functions
// that cannot be stored in Engine or OS due to e.g. circular includes
class CoreGlobals {
public:
static bool leak_reporting_enabled;
static bool print_line_enabled;
static bool print_error_enabled;
};
#endif // CORE_GLOBALS_H

View File

@@ -0,0 +1,74 @@
/*************************************************************************/
/* core_string_names.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "core_string_names.h"
CoreStringNames *CoreStringNames::singleton = NULL;
CoreStringNames::CoreStringNames() :
_free(StaticCString::create("free")),
changed(StaticCString::create("changed")),
_meta(StaticCString::create("__meta__")),
_script(StaticCString::create("script")),
script_changed(StaticCString::create("script_changed")),
___pdcdata(StaticCString::create("___pdcdata")),
__getvar(StaticCString::create("__getvar")),
_iter_init(StaticCString::create("_iter_init")),
_iter_next(StaticCString::create("_iter_next")),
_iter_get(StaticCString::create("_iter_get")),
get_rid(StaticCString::create("get_rid")),
#ifdef TOOLS_ENABLED
_sections_unfolded(StaticCString::create("_sections_unfolded")),
#endif
_custom_features(StaticCString::create("_custom_features")) {
x = StaticCString::create("x");
y = StaticCString::create("y");
z = StaticCString::create("z");
w = StaticCString::create("w");
r = StaticCString::create("r");
g = StaticCString::create("g");
b = StaticCString::create("b");
a = StaticCString::create("a");
position = StaticCString::create("position");
size = StaticCString::create("size");
end = StaticCString::create("end");
basis = StaticCString::create("basis");
origin = StaticCString::create("origin");
normal = StaticCString::create("normal");
d = StaticCString::create("d");
h = StaticCString::create("h");
s = StaticCString::create("s");
v = StaticCString::create("v");
r8 = StaticCString::create("r8");
g8 = StaticCString::create("g8");
b8 = StaticCString::create("b8");
a8 = StaticCString::create("a8");
}

View File

@@ -1,91 +1,94 @@
/**************************************************************************/
/* core_string_names.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
/*************************************************************************/
/* core_string_names.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef CORE_STRING_NAMES_H
#define CORE_STRING_NAMES_H
#include "core/string/string_name.h"
#include "string_db.h"
class CoreStringNames {
inline static CoreStringNames *singleton = nullptr;
public:
friend void register_core_types();
friend void unregister_core_types();
static void create() { singleton = memnew(CoreStringNames); }
static void free() {
memdelete(singleton);
singleton = nullptr;
singleton = NULL;
}
CoreStringNames();
public:
_FORCE_INLINE_ static CoreStringNames *get_singleton() { return singleton; }
const StringName free_ = StaticCString::create("free"); // free would conflict with C++ keyword.
const StringName changed = StaticCString::create("changed");
const StringName script = StaticCString::create("script");
const StringName script_changed = StaticCString::create("script_changed");
const StringName _iter_init = StaticCString::create("_iter_init");
const StringName _iter_next = StaticCString::create("_iter_next");
const StringName _iter_get = StaticCString::create("_iter_get");
const StringName get_rid = StaticCString::create("get_rid");
const StringName _to_string = StaticCString::create("_to_string");
const StringName _custom_features = StaticCString::create("_custom_features");
static CoreStringNames *singleton;
const StringName x = StaticCString::create("x");
const StringName y = StaticCString::create("y");
const StringName z = StaticCString::create("z");
const StringName w = StaticCString::create("w");
const StringName r = StaticCString::create("r");
const StringName g = StaticCString::create("g");
const StringName b = StaticCString::create("b");
const StringName a = StaticCString::create("a");
const StringName position = StaticCString::create("position");
const StringName size = StaticCString::create("size");
const StringName end = StaticCString::create("end");
const StringName basis = StaticCString::create("basis");
const StringName origin = StaticCString::create("origin");
const StringName normal = StaticCString::create("normal");
const StringName d = StaticCString::create("d");
const StringName h = StaticCString::create("h");
const StringName s = StaticCString::create("s");
const StringName v = StaticCString::create("v");
const StringName r8 = StaticCString::create("r8");
const StringName g8 = StaticCString::create("g8");
const StringName b8 = StaticCString::create("b8");
const StringName a8 = StaticCString::create("a8");
StringName _free;
StringName changed;
StringName _meta;
StringName _script;
StringName script_changed;
StringName ___pdcdata;
StringName __getvar;
StringName _iter_init;
StringName _iter_next;
StringName _iter_get;
StringName get_rid;
#ifdef TOOLS_ENABLED
StringName _sections_unfolded;
#endif
StringName _custom_features;
const StringName call = StaticCString::create("call");
const StringName call_deferred = StaticCString::create("call_deferred");
const StringName bind = StaticCString::create("bind");
const StringName notification = StaticCString::create("notification");
const StringName property_list_changed = StaticCString::create("property_list_changed");
StringName x;
StringName y;
StringName z;
StringName w;
StringName r;
StringName g;
StringName b;
StringName a;
StringName position;
StringName size;
StringName end;
StringName basis;
StringName origin;
StringName normal;
StringName d;
StringName h;
StringName s;
StringName v;
StringName r8;
StringName g8;
StringName b8;
StringName a8;
};
#define CoreStringName(m_name) CoreStringNames::get_singleton()->m_name
#endif // CORE_STRING_NAMES_H
#endif // SCENE_STRING_NAMES_H

View File

@@ -1,65 +0,0 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
env_crypto = env.Clone()
is_builtin = env["builtin_mbedtls"]
has_module = env["module_mbedtls_enabled"]
thirdparty_obj = []
if is_builtin or not has_module:
# Use our headers for builtin or if the module is not going to be compiled.
# We decided not to depend on system mbedtls just for these few files that can
# be easily extracted.
env_crypto.Prepend(CPPPATH=["#thirdparty/mbedtls/include"])
# MbedTLS core functions (for CryptoCore).
# If the mbedtls module is compiled we don't need to add the .c files with our
# custom config since they will be built by the module itself.
# Only if the module is not enabled, we must compile here the required sources
# to make a "light" build with only the necessary mbedtls files.
if not has_module:
# Minimal mbedTLS config file
config_path = "thirdparty/mbedtls/include/godot_core_mbedtls_config.h"
config_path = f"<{config_path}>" if env_crypto["ninja"] and env_crypto.msvc else f'\\"{config_path}\\"'
env_crypto.Append(CPPDEFINES=[("MBEDTLS_CONFIG_FILE", config_path)])
# Build minimal mbedTLS library (MD5/SHA/Base64/AES).
env_thirdparty = env_crypto.Clone()
env_thirdparty.disable_warnings()
thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
thirdparty_mbedtls_sources = [
"aes.c",
"base64.c",
"constant_time.c",
"ctr_drbg.c",
"entropy.c",
"md.c",
"md5.c",
"sha1.c",
"sha256.c",
"godot_core_mbedtls_platform.c",
]
thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources]
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_mbedtls_sources)
# Needed to force rebuilding the library when the configuration file is updated.
env_thirdparty.Depends(thirdparty_obj, "#thirdparty/mbedtls/include/godot_core_mbedtls_config.h")
env.core_sources += thirdparty_obj
elif is_builtin:
# Module mbedTLS config file
config_path = "thirdparty/mbedtls/include/godot_module_mbedtls_config.h"
config_path = f"<{config_path}>" if env_crypto["ninja"] and env_crypto.msvc else f'\\"{config_path}\\"'
env_crypto.Append(CPPDEFINES=[("MBEDTLS_CONFIG_FILE", config_path)])
# Needed to force rebuilding the core files when the configuration file is updated.
thirdparty_obj = ["#thirdparty/mbedtls/include/godot_module_mbedtls_config.h"]
# Godot source files
core_obj = []
env_crypto.add_source_files(core_obj, "*.cpp")
env.core_sources += core_obj
# Needed to force rebuilding the core files when the thirdparty library is updated.
env.Depends(core_obj, thirdparty_obj)

View File

@@ -1,115 +0,0 @@
/**************************************************************************/
/* aes_context.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "core/crypto/aes_context.h"
Error AESContext::start(Mode p_mode, const PackedByteArray &p_key, const PackedByteArray &p_iv) {
ERR_FAIL_COND_V_MSG(mode != MODE_MAX, ERR_ALREADY_IN_USE, "AESContext already started. Call 'finish' before starting a new one.");
ERR_FAIL_COND_V_MSG(p_mode < 0 || p_mode >= MODE_MAX, ERR_INVALID_PARAMETER, "Invalid mode requested.");
// Key check.
int key_bits = p_key.size() << 3;
ERR_FAIL_COND_V_MSG(key_bits != 128 && key_bits != 256, ERR_INVALID_PARAMETER, "AES key must be either 16 or 32 bytes");
// Initialization vector.
if (p_mode == MODE_CBC_ENCRYPT || p_mode == MODE_CBC_DECRYPT) {
ERR_FAIL_COND_V_MSG(p_iv.size() != 16, ERR_INVALID_PARAMETER, "The initialization vector (IV) must be exactly 16 bytes.");
iv.resize(0);
iv.append_array(p_iv);
}
// Encryption/decryption key.
if (p_mode == MODE_CBC_ENCRYPT || p_mode == MODE_ECB_ENCRYPT) {
ctx.set_encode_key(p_key.ptr(), key_bits);
} else {
ctx.set_decode_key(p_key.ptr(), key_bits);
}
mode = p_mode;
return OK;
}
PackedByteArray AESContext::update(const PackedByteArray &p_src) {
ERR_FAIL_COND_V_MSG(mode < 0 || mode >= MODE_MAX, PackedByteArray(), "AESContext not started. Call 'start' before calling 'update'.");
int len = p_src.size();
ERR_FAIL_COND_V_MSG(len % 16, PackedByteArray(), "The number of bytes to be encrypted must be multiple of 16. Add padding if needed");
PackedByteArray out;
out.resize(len);
const uint8_t *src_ptr = p_src.ptr();
uint8_t *out_ptr = out.ptrw();
switch (mode) {
case MODE_ECB_ENCRYPT: {
for (int i = 0; i < len; i += 16) {
Error err = ctx.encrypt_ecb(src_ptr + i, out_ptr + i);
ERR_FAIL_COND_V(err != OK, PackedByteArray());
}
} break;
case MODE_ECB_DECRYPT: {
for (int i = 0; i < len; i += 16) {
Error err = ctx.decrypt_ecb(src_ptr + i, out_ptr + i);
ERR_FAIL_COND_V(err != OK, PackedByteArray());
}
} break;
case MODE_CBC_ENCRYPT: {
Error err = ctx.encrypt_cbc(len, iv.ptrw(), p_src.ptr(), out.ptrw());
ERR_FAIL_COND_V(err != OK, PackedByteArray());
} break;
case MODE_CBC_DECRYPT: {
Error err = ctx.decrypt_cbc(len, iv.ptrw(), p_src.ptr(), out.ptrw());
ERR_FAIL_COND_V(err != OK, PackedByteArray());
} break;
default:
ERR_FAIL_V_MSG(PackedByteArray(), "Bug!");
}
return out;
}
PackedByteArray AESContext::get_iv_state() {
ERR_FAIL_COND_V_MSG(mode != MODE_CBC_ENCRYPT && mode != MODE_CBC_DECRYPT, PackedByteArray(), "Calling 'get_iv_state' only makes sense when the context is started in CBC mode.");
PackedByteArray out;
out.append_array(iv);
return out;
}
void AESContext::finish() {
mode = MODE_MAX;
iv.resize(0);
}
void AESContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "mode", "key", "iv"), &AESContext::start, DEFVAL(PackedByteArray()));
ClassDB::bind_method(D_METHOD("update", "src"), &AESContext::update);
ClassDB::bind_method(D_METHOD("get_iv_state"), &AESContext::get_iv_state);
ClassDB::bind_method(D_METHOD("finish"), &AESContext::finish);
BIND_ENUM_CONSTANT(MODE_ECB_ENCRYPT);
BIND_ENUM_CONSTANT(MODE_ECB_DECRYPT);
BIND_ENUM_CONSTANT(MODE_CBC_ENCRYPT);
BIND_ENUM_CONSTANT(MODE_CBC_DECRYPT);
BIND_ENUM_CONSTANT(MODE_MAX);
}
AESContext::AESContext() {
}

View File

@@ -1,68 +0,0 @@
/**************************************************************************/
/* aes_context.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef AES_CONTEXT_H
#define AES_CONTEXT_H
#include "core/crypto/crypto_core.h"
#include "core/object/ref_counted.h"
class AESContext : public RefCounted {
GDCLASS(AESContext, RefCounted);
public:
enum Mode : int32_t {
MODE_ECB_ENCRYPT,
MODE_ECB_DECRYPT,
MODE_CBC_ENCRYPT,
MODE_CBC_DECRYPT,
MODE_MAX
};
private:
Mode mode = MODE_MAX;
CryptoCore::AESContext ctx;
PackedByteArray iv;
protected:
static void _bind_methods();
public:
Error start(Mode p_mode, const PackedByteArray &p_key, const PackedByteArray &p_iv = PackedByteArray());
PackedByteArray update(const PackedByteArray &p_src);
PackedByteArray get_iv_state();
void finish();
AESContext();
};
VARIANT_ENUM_CAST(AESContext::Mode);
#endif // AES_CONTEXT_H

View File

@@ -1,259 +0,0 @@
/**************************************************************************/
/* crypto.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "crypto.h"
/// Resources
CryptoKey *(*CryptoKey::_create)(bool p_notify_postinitialize) = nullptr;
CryptoKey *CryptoKey::create(bool p_notify_postinitialize) {
if (_create) {
return _create(p_notify_postinitialize);
}
return nullptr;
}
void CryptoKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path", "public_only"), &CryptoKey::save, DEFVAL(false));
ClassDB::bind_method(D_METHOD("load", "path", "public_only"), &CryptoKey::load, DEFVAL(false));
ClassDB::bind_method(D_METHOD("is_public_only"), &CryptoKey::is_public_only);
ClassDB::bind_method(D_METHOD("save_to_string", "public_only"), &CryptoKey::save_to_string, DEFVAL(false));
ClassDB::bind_method(D_METHOD("load_from_string", "string_key", "public_only"), &CryptoKey::load_from_string, DEFVAL(false));
}
X509Certificate *(*X509Certificate::_create)(bool p_notify_postinitialize) = nullptr;
X509Certificate *X509Certificate::create(bool p_notify_postinitialize) {
if (_create) {
return _create(p_notify_postinitialize);
}
return nullptr;
}
void X509Certificate::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
ClassDB::bind_method(D_METHOD("save_to_string"), &X509Certificate::save_to_string);
ClassDB::bind_method(D_METHOD("load_from_string", "string"), &X509Certificate::load_from_string);
}
/// TLSOptions
Ref<TLSOptions> TLSOptions::client(Ref<X509Certificate> p_trusted_chain, const String &p_common_name_override) {
Ref<TLSOptions> opts;
opts.instantiate();
opts->mode = MODE_CLIENT;
opts->trusted_ca_chain = p_trusted_chain;
opts->common_name = p_common_name_override;
return opts;
}
Ref<TLSOptions> TLSOptions::client_unsafe(Ref<X509Certificate> p_trusted_chain) {
Ref<TLSOptions> opts;
opts.instantiate();
opts->mode = MODE_CLIENT_UNSAFE;
opts->trusted_ca_chain = p_trusted_chain;
return opts;
}
Ref<TLSOptions> TLSOptions::server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate) {
Ref<TLSOptions> opts;
opts.instantiate();
opts->mode = MODE_SERVER;
opts->own_certificate = p_own_certificate;
opts->private_key = p_own_key;
return opts;
}
void TLSOptions::_bind_methods() {
ClassDB::bind_static_method("TLSOptions", D_METHOD("client", "trusted_chain", "common_name_override"), &TLSOptions::client, DEFVAL(Ref<X509Certificate>()), DEFVAL(String()));
ClassDB::bind_static_method("TLSOptions", D_METHOD("client_unsafe", "trusted_chain"), &TLSOptions::client_unsafe, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_static_method("TLSOptions", D_METHOD("server", "key", "certificate"), &TLSOptions::server);
ClassDB::bind_method(D_METHOD("is_server"), &TLSOptions::is_server);
ClassDB::bind_method(D_METHOD("is_unsafe_client"), &TLSOptions::is_unsafe_client);
ClassDB::bind_method(D_METHOD("get_common_name_override"), &TLSOptions::get_common_name_override);
ClassDB::bind_method(D_METHOD("get_trusted_ca_chain"), &TLSOptions::get_trusted_ca_chain);
ClassDB::bind_method(D_METHOD("get_private_key"), &TLSOptions::get_private_key);
ClassDB::bind_method(D_METHOD("get_own_certificate"), &TLSOptions::get_own_certificate);
}
/// HMACContext
void HMACContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "hash_type", "key"), &HMACContext::start);
ClassDB::bind_method(D_METHOD("update", "data"), &HMACContext::update);
ClassDB::bind_method(D_METHOD("finish"), &HMACContext::finish);
}
HMACContext *(*HMACContext::_create)(bool p_notify_postinitialize) = nullptr;
HMACContext *HMACContext::create(bool p_notify_postinitialize) {
if (_create) {
return _create(p_notify_postinitialize);
}
ERR_FAIL_V_MSG(nullptr, "HMACContext is not available when the mbedtls module is disabled.");
}
/// Crypto
void (*Crypto::_load_default_certificates)(const String &p_path) = nullptr;
Crypto *(*Crypto::_create)(bool p_notify_postinitialize) = nullptr;
Crypto *Crypto::create(bool p_notify_postinitialize) {
if (_create) {
return _create(p_notify_postinitialize);
}
ERR_FAIL_V_MSG(nullptr, "Crypto is not available when the mbedtls module is disabled.");
}
void Crypto::load_default_certificates(const String &p_path) {
if (_load_default_certificates) {
_load_default_certificates(p_path);
}
}
PackedByteArray Crypto::hmac_digest(HashingContext::HashType p_hash_type, const PackedByteArray &p_key, const PackedByteArray &p_msg) {
Ref<HMACContext> ctx = Ref<HMACContext>(HMACContext::create());
ERR_FAIL_COND_V_MSG(ctx.is_null(), PackedByteArray(), "HMAC is not available without mbedtls module.");
Error err = ctx->start(p_hash_type, p_key);
ERR_FAIL_COND_V(err != OK, PackedByteArray());
err = ctx->update(p_msg);
ERR_FAIL_COND_V(err != OK, PackedByteArray());
return ctx->finish();
}
// Compares two HMACS for equality without leaking timing information in order to prevent timing attacks.
// @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy
bool Crypto::constant_time_compare(const PackedByteArray &p_trusted, const PackedByteArray &p_received) {
const uint8_t *t = p_trusted.ptr();
const uint8_t *r = p_received.ptr();
int tlen = p_trusted.size();
int rlen = p_received.size();
// If the lengths are different then nothing else matters.
if (tlen != rlen) {
return false;
}
uint8_t v = 0;
for (int i = 0; i < tlen; i++) {
v |= t[i] ^ r[i];
}
return v == 0;
}
void Crypto::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate_random_bytes", "size"), &Crypto::generate_random_bytes);
ClassDB::bind_method(D_METHOD("generate_rsa", "size"), &Crypto::generate_rsa);
ClassDB::bind_method(D_METHOD("generate_self_signed_certificate", "key", "issuer_name", "not_before", "not_after"), &Crypto::generate_self_signed_certificate, DEFVAL("CN=myserver,O=myorganisation,C=IT"), DEFVAL("20140101000000"), DEFVAL("20340101000000"));
ClassDB::bind_method(D_METHOD("sign", "hash_type", "hash", "key"), &Crypto::sign);
ClassDB::bind_method(D_METHOD("verify", "hash_type", "hash", "signature", "key"), &Crypto::verify);
ClassDB::bind_method(D_METHOD("encrypt", "key", "plaintext"), &Crypto::encrypt);
ClassDB::bind_method(D_METHOD("decrypt", "key", "ciphertext"), &Crypto::decrypt);
ClassDB::bind_method(D_METHOD("hmac_digest", "hash_type", "key", "msg"), &Crypto::hmac_digest);
ClassDB::bind_method(D_METHOD("constant_time_compare", "trusted", "received"), &Crypto::constant_time_compare);
}
/// Resource loader/saver
Ref<Resource> ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
X509Certificate *cert = X509Certificate::create();
if (cert) {
cert->load(p_path);
}
return cert;
} else if (el == "key") {
CryptoKey *key = CryptoKey::create();
if (key) {
key->load(p_path, false);
}
return key;
} else if (el == "pub") {
CryptoKey *key = CryptoKey::create();
if (key) {
key->load(p_path, true);
}
return key;
}
return nullptr;
}
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("crt");
p_extensions->push_back("key");
p_extensions->push_back("pub");
}
bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
return p_type == "X509Certificate" || p_type == "CryptoKey";
}
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
return "X509Certificate";
} else if (el == "key" || el == "pub") {
return "CryptoKey";
}
return "";
}
Error ResourceFormatSaverCrypto::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) {
Error err;
Ref<X509Certificate> cert = p_resource;
Ref<CryptoKey> key = p_resource;
if (cert.is_valid()) {
err = cert->save(p_path);
} else if (key.is_valid()) {
String el = p_path.get_extension().to_lower();
err = key->save(p_path, el == "pub");
} else {
ERR_FAIL_V(ERR_INVALID_PARAMETER);
}
ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot save Crypto resource to file '%s'.", p_path));
return OK;
}
void ResourceFormatSaverCrypto::get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const {
const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
if (cert) {
p_extensions->push_back("crt");
}
if (key) {
if (!key->is_public_only()) {
p_extensions->push_back("key");
}
p_extensions->push_back("pub");
}
}
bool ResourceFormatSaverCrypto::recognize(const Ref<Resource> &p_resource) const {
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
}

View File

@@ -1,171 +0,0 @@
/**************************************************************************/
/* crypto.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CRYPTO_H
#define CRYPTO_H
#include "core/crypto/hashing_context.h"
#include "core/io/resource.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/object/ref_counted.h"
class CryptoKey : public Resource {
GDCLASS(CryptoKey, Resource);
protected:
static void _bind_methods();
static CryptoKey *(*_create)(bool p_notify_postinitialize);
public:
static CryptoKey *create(bool p_notify_postinitialize = true);
virtual Error load(const String &p_path, bool p_public_only = false) = 0;
virtual Error save(const String &p_path, bool p_public_only = false) = 0;
virtual String save_to_string(bool p_public_only = false) = 0;
virtual Error load_from_string(const String &p_string_key, bool p_public_only = false) = 0;
virtual bool is_public_only() const = 0;
};
class X509Certificate : public Resource {
GDCLASS(X509Certificate, Resource);
protected:
static void _bind_methods();
static X509Certificate *(*_create)(bool p_notify_postinitialize);
public:
static X509Certificate *create(bool p_notify_postinitialize = true);
virtual Error load(const String &p_path) = 0;
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
virtual Error save(const String &p_path) = 0;
virtual String save_to_string() = 0;
virtual Error load_from_string(const String &string) = 0;
};
class TLSOptions : public RefCounted {
GDCLASS(TLSOptions, RefCounted);
private:
enum Mode {
MODE_CLIENT = 0,
MODE_CLIENT_UNSAFE = 1,
MODE_SERVER = 2,
};
Mode mode = MODE_CLIENT;
String common_name;
Ref<X509Certificate> trusted_ca_chain;
Ref<X509Certificate> own_certificate;
Ref<CryptoKey> private_key;
protected:
static void _bind_methods();
public:
static Ref<TLSOptions> client(Ref<X509Certificate> p_trusted_chain = Ref<X509Certificate>(), const String &p_common_name_override = String());
static Ref<TLSOptions> client_unsafe(Ref<X509Certificate> p_trusted_chain);
static Ref<TLSOptions> server(Ref<CryptoKey> p_own_key, Ref<X509Certificate> p_own_certificate);
String get_common_name_override() const { return common_name; }
Ref<X509Certificate> get_trusted_ca_chain() const { return trusted_ca_chain; }
Ref<X509Certificate> get_own_certificate() const { return own_certificate; }
Ref<CryptoKey> get_private_key() const { return private_key; }
bool is_server() const { return mode == MODE_SERVER; }
bool is_unsafe_client() const { return mode == MODE_CLIENT_UNSAFE; }
};
class HMACContext : public RefCounted {
GDCLASS(HMACContext, RefCounted);
protected:
static void _bind_methods();
static HMACContext *(*_create)(bool p_notify_postinitialize);
public:
static HMACContext *create(bool p_notify_postinitialize = true);
virtual Error start(HashingContext::HashType p_hash_type, const PackedByteArray &p_key) = 0;
virtual Error update(const PackedByteArray &p_data) = 0;
virtual PackedByteArray finish() = 0;
HMACContext() {}
virtual ~HMACContext() {}
};
class Crypto : public RefCounted {
GDCLASS(Crypto, RefCounted);
protected:
static void _bind_methods();
static Crypto *(*_create)(bool p_notify_postinitialize);
static void (*_load_default_certificates)(const String &p_path);
public:
static Crypto *create(bool p_notify_postinitialize = true);
static void load_default_certificates(const String &p_path);
virtual PackedByteArray generate_random_bytes(int p_bytes) = 0;
virtual Ref<CryptoKey> generate_rsa(int p_bytes) = 0;
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, const String &p_issuer_name, const String &p_not_before, const String &p_not_after) = 0;
virtual Vector<uint8_t> sign(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, Ref<CryptoKey> p_key) = 0;
virtual bool verify(HashingContext::HashType p_hash_type, const Vector<uint8_t> &p_hash, const Vector<uint8_t> &p_signature, Ref<CryptoKey> p_key) = 0;
virtual Vector<uint8_t> encrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_plaintext) = 0;
virtual Vector<uint8_t> decrypt(Ref<CryptoKey> p_key, const Vector<uint8_t> &p_ciphertext) = 0;
PackedByteArray hmac_digest(HashingContext::HashType p_hash_type, const PackedByteArray &p_key, const PackedByteArray &p_msg);
// Compares two PackedByteArrays for equality without leaking timing information in order to prevent timing attacks.
// @see: https://paragonie.com/blog/2015/11/preventing-timing-attacks-on-string-comparison-with-double-hmac-strategy
bool constant_time_compare(const PackedByteArray &p_trusted, const PackedByteArray &p_received);
Crypto() {}
};
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
public:
virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE) override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
virtual bool handles_type(const String &p_type) const override;
virtual String get_resource_type(const String &p_path) const override;
// Treat certificates as text files, do not generate a `*.{crt,key,pub}.uid` file.
virtual ResourceUID::ID get_resource_uid(const String &p_path) const override { return ResourceUID::INVALID_ID; }
virtual bool has_custom_uid_support() const override { return true; }
};
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
public:
virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0) override;
virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const override;
virtual bool recognize(const Ref<Resource> &p_resource) const override;
};
#endif // CRYPTO_H

View File

@@ -1,251 +0,0 @@
/**************************************************************************/
/* crypto_core.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "crypto_core.h"
#include "core/os/os.h"
#include <mbedtls/aes.h>
#include <mbedtls/base64.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#if MBEDTLS_VERSION_MAJOR >= 3
#include <mbedtls/compat-2.x.h>
#endif
// RandomGenerator
CryptoCore::RandomGenerator::RandomGenerator() {
entropy = memalloc(sizeof(mbedtls_entropy_context));
mbedtls_entropy_init((mbedtls_entropy_context *)entropy);
mbedtls_entropy_add_source((mbedtls_entropy_context *)entropy, &CryptoCore::RandomGenerator::_entropy_poll, nullptr, 256, MBEDTLS_ENTROPY_SOURCE_STRONG);
ctx = memalloc(sizeof(mbedtls_ctr_drbg_context));
mbedtls_ctr_drbg_init((mbedtls_ctr_drbg_context *)ctx);
}
CryptoCore::RandomGenerator::~RandomGenerator() {
mbedtls_ctr_drbg_free((mbedtls_ctr_drbg_context *)ctx);
memfree(ctx);
mbedtls_entropy_free((mbedtls_entropy_context *)entropy);
memfree(entropy);
}
int CryptoCore::RandomGenerator::_entropy_poll(void *p_data, unsigned char *r_buffer, size_t p_len, size_t *r_len) {
*r_len = 0;
Error err = OS::get_singleton()->get_entropy(r_buffer, p_len);
ERR_FAIL_COND_V(err, MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
*r_len = p_len;
return 0;
}
Error CryptoCore::RandomGenerator::init() {
int ret = mbedtls_ctr_drbg_seed((mbedtls_ctr_drbg_context *)ctx, mbedtls_entropy_func, (mbedtls_entropy_context *)entropy, nullptr, 0);
if (ret) {
ERR_FAIL_COND_V_MSG(ret, FAILED, vformat(" failed\n ! mbedtls_ctr_drbg_seed returned an error %d.", ret));
}
return OK;
}
Error CryptoCore::RandomGenerator::get_random_bytes(uint8_t *r_buffer, size_t p_bytes) {
ERR_FAIL_NULL_V(ctx, ERR_UNCONFIGURED);
int ret = mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context *)ctx, r_buffer, p_bytes);
ERR_FAIL_COND_V_MSG(ret, FAILED, vformat(" failed\n ! mbedtls_ctr_drbg_seed returned an error %d.", ret));
return OK;
}
// MD5
CryptoCore::MD5Context::MD5Context() {
ctx = memalloc(sizeof(mbedtls_md5_context));
mbedtls_md5_init((mbedtls_md5_context *)ctx);
}
CryptoCore::MD5Context::~MD5Context() {
mbedtls_md5_free((mbedtls_md5_context *)ctx);
memfree((mbedtls_md5_context *)ctx);
}
Error CryptoCore::MD5Context::start() {
int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) {
int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// SHA1
CryptoCore::SHA1Context::SHA1Context() {
ctx = memalloc(sizeof(mbedtls_sha1_context));
mbedtls_sha1_init((mbedtls_sha1_context *)ctx);
}
CryptoCore::SHA1Context::~SHA1Context() {
mbedtls_sha1_free((mbedtls_sha1_context *)ctx);
memfree((mbedtls_sha1_context *)ctx);
}
Error CryptoCore::SHA1Context::start() {
int ret = mbedtls_sha1_starts_ret((mbedtls_sha1_context *)ctx);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA1Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha1_update_ret((mbedtls_sha1_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA1Context::finish(unsigned char r_hash[20]) {
int ret = mbedtls_sha1_finish_ret((mbedtls_sha1_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// SHA256
CryptoCore::SHA256Context::SHA256Context() {
ctx = memalloc(sizeof(mbedtls_sha256_context));
mbedtls_sha256_init((mbedtls_sha256_context *)ctx);
}
CryptoCore::SHA256Context::~SHA256Context() {
mbedtls_sha256_free((mbedtls_sha256_context *)ctx);
memfree((mbedtls_sha256_context *)ctx);
}
Error CryptoCore::SHA256Context::start() {
int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::update(const uint8_t *p_src, size_t p_len) {
int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len);
return ret ? FAILED : OK;
}
Error CryptoCore::SHA256Context::finish(unsigned char r_hash[32]) {
int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash);
return ret ? FAILED : OK;
}
// AES256
CryptoCore::AESContext::AESContext() {
ctx = memalloc(sizeof(mbedtls_aes_context));
mbedtls_aes_init((mbedtls_aes_context *)ctx);
}
CryptoCore::AESContext::~AESContext() {
mbedtls_aes_free((mbedtls_aes_context *)ctx);
memfree((mbedtls_aes_context *)ctx);
}
Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) {
int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, r_iv, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
size_t iv_off = 0; // Ignore and assume 16-byte alignment.
int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_length, &iv_off, p_iv, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) {
int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
int ret = mbedtls_aes_crypt_cbc((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_length, r_iv, p_src, r_dst);
return ret ? FAILED : OK;
}
Error CryptoCore::AESContext::decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst) {
size_t iv_off = 0; // Ignore and assume 16-byte alignment.
int ret = mbedtls_aes_crypt_cfb128((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_length, &iv_off, p_iv, p_src, r_dst);
return ret ? FAILED : OK;
}
// CryptoCore
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
int b64len = p_src_len / 3 * 4 + 4 + 1;
Vector<uint8_t> b64buff;
b64buff.resize(b64len);
uint8_t *w64 = b64buff.ptrw();
size_t strlen = 0;
int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len);
w64[strlen] = 0;
return ret ? String() : (const char *)&w64[0];
}
Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) {
int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len);
return ret ? FAILED : OK;
}
Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) {
int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) {
int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash);
return ret ? FAILED : OK;
}
Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) {
int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0);
return ret ? FAILED : OK;
}

View File

@@ -1,119 +0,0 @@
/**************************************************************************/
/* crypto_core.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef CRYPTO_CORE_H
#define CRYPTO_CORE_H
#include "core/object/ref_counted.h"
class CryptoCore {
public:
class RandomGenerator {
private:
void *entropy = nullptr;
void *ctx = nullptr;
static int _entropy_poll(void *p_data, unsigned char *r_buffer, size_t p_len, size_t *r_len);
public:
RandomGenerator();
~RandomGenerator();
Error init();
Error get_random_bytes(uint8_t *r_buffer, size_t p_bytes);
};
class MD5Context {
private:
void *ctx = nullptr;
public:
MD5Context();
~MD5Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[16]);
};
class SHA1Context {
private:
void *ctx = nullptr;
public:
SHA1Context();
~SHA1Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[20]);
};
class SHA256Context {
private:
void *ctx = nullptr;
public:
SHA256Context();
~SHA256Context();
Error start();
Error update(const uint8_t *p_src, size_t p_len);
Error finish(unsigned char r_hash[32]);
};
class AESContext {
private:
void *ctx = nullptr;
public:
AESContext();
~AESContext();
Error set_encode_key(const uint8_t *p_key, size_t p_bits);
Error set_decode_key(const uint8_t *p_key, size_t p_bits);
Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]);
Error encrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst);
Error decrypt_cbc(size_t p_length, uint8_t r_iv[16], const uint8_t *p_src, uint8_t *r_dst);
Error encrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst);
Error decrypt_cfb(size_t p_length, uint8_t p_iv[16], const uint8_t *p_src, uint8_t *r_dst);
};
static String b64_encode_str(const uint8_t *p_src, int p_src_len);
static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len);
static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]);
static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]);
static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]);
};
#endif // CRYPTO_CORE_H

View File

@@ -1,134 +0,0 @@
/**************************************************************************/
/* hashing_context.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "hashing_context.h"
#include "core/crypto/crypto_core.h"
Error HashingContext::start(HashType p_type) {
ERR_FAIL_COND_V(ctx != nullptr, ERR_ALREADY_IN_USE);
_create_ctx(p_type);
ERR_FAIL_NULL_V(ctx, ERR_UNAVAILABLE);
switch (type) {
case HASH_MD5:
return ((CryptoCore::MD5Context *)ctx)->start();
case HASH_SHA1:
return ((CryptoCore::SHA1Context *)ctx)->start();
case HASH_SHA256:
return ((CryptoCore::SHA256Context *)ctx)->start();
}
return ERR_UNAVAILABLE;
}
Error HashingContext::update(const PackedByteArray &p_chunk) {
ERR_FAIL_NULL_V(ctx, ERR_UNCONFIGURED);
size_t len = p_chunk.size();
ERR_FAIL_COND_V(len == 0, FAILED);
const uint8_t *r = p_chunk.ptr();
switch (type) {
case HASH_MD5:
return ((CryptoCore::MD5Context *)ctx)->update(&r[0], len);
case HASH_SHA1:
return ((CryptoCore::SHA1Context *)ctx)->update(&r[0], len);
case HASH_SHA256:
return ((CryptoCore::SHA256Context *)ctx)->update(&r[0], len);
}
return ERR_UNAVAILABLE;
}
PackedByteArray HashingContext::finish() {
ERR_FAIL_NULL_V(ctx, PackedByteArray());
PackedByteArray out;
Error err = FAILED;
switch (type) {
case HASH_MD5:
out.resize(16);
err = ((CryptoCore::MD5Context *)ctx)->finish(out.ptrw());
break;
case HASH_SHA1:
out.resize(20);
err = ((CryptoCore::SHA1Context *)ctx)->finish(out.ptrw());
break;
case HASH_SHA256:
out.resize(32);
err = ((CryptoCore::SHA256Context *)ctx)->finish(out.ptrw());
break;
}
_delete_ctx();
ERR_FAIL_COND_V(err != OK, PackedByteArray());
return out;
}
void HashingContext::_create_ctx(HashType p_type) {
type = p_type;
switch (type) {
case HASH_MD5:
ctx = memnew(CryptoCore::MD5Context);
break;
case HASH_SHA1:
ctx = memnew(CryptoCore::SHA1Context);
break;
case HASH_SHA256:
ctx = memnew(CryptoCore::SHA256Context);
break;
default:
ctx = nullptr;
}
}
void HashingContext::_delete_ctx() {
switch (type) {
case HASH_MD5:
memdelete((CryptoCore::MD5Context *)ctx);
break;
case HASH_SHA1:
memdelete((CryptoCore::SHA1Context *)ctx);
break;
case HASH_SHA256:
memdelete((CryptoCore::SHA256Context *)ctx);
break;
}
ctx = nullptr;
}
void HashingContext::_bind_methods() {
ClassDB::bind_method(D_METHOD("start", "type"), &HashingContext::start);
ClassDB::bind_method(D_METHOD("update", "chunk"), &HashingContext::update);
ClassDB::bind_method(D_METHOD("finish"), &HashingContext::finish);
BIND_ENUM_CONSTANT(HASH_MD5);
BIND_ENUM_CONSTANT(HASH_SHA1);
BIND_ENUM_CONSTANT(HASH_SHA256);
}
HashingContext::~HashingContext() {
if (ctx != nullptr) {
_delete_ctx();
}
}

View File

@@ -1,66 +0,0 @@
/**************************************************************************/
/* hashing_context.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef HASHING_CONTEXT_H
#define HASHING_CONTEXT_H
#include "core/object/ref_counted.h"
class HashingContext : public RefCounted {
GDCLASS(HashingContext, RefCounted);
public:
enum HashType : int32_t {
HASH_MD5,
HASH_SHA1,
HASH_SHA256
};
private:
void *ctx = nullptr;
HashType type = HASH_MD5;
protected:
static void _bind_methods();
void _create_ctx(HashType p_type);
void _delete_ctx();
public:
Error start(HashType p_type);
Error update(const PackedByteArray &p_chunk);
PackedByteArray finish();
HashingContext() {}
~HashingContext();
};
VARIANT_ENUM_CAST(HashingContext::HashType);
#endif // HASHING_CONTEXT_H

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
env.add_source_files(env.core_sources, "*.cpp")

View File

@@ -1,183 +0,0 @@
/**************************************************************************/
/* debugger_marshalls.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "debugger_marshalls.h"
#include "core/io/marshalls.h"
#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
Array DebuggerMarshalls::ScriptStackDump::serialize() {
Array arr;
arr.push_back(frames.size() * 3);
for (const ScriptLanguage::StackInfo &frame : frames) {
arr.push_back(frame.file);
arr.push_back(frame.line);
arr.push_back(frame.func);
}
return arr;
}
bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) {
CHECK_SIZE(p_arr, 1, "ScriptStackDump");
uint32_t size = p_arr[0];
CHECK_SIZE(p_arr, size, "ScriptStackDump");
int idx = 1;
for (uint32_t i = 0; i < size / 3; i++) {
ScriptLanguage::StackInfo sf;
sf.file = p_arr[idx];
sf.line = p_arr[idx + 1];
sf.func = p_arr[idx + 2];
frames.push_back(sf);
idx += 3;
}
CHECK_END(p_arr, idx, "ScriptStackDump");
return true;
}
Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
Array arr;
arr.push_back(name);
arr.push_back(type);
arr.push_back(value.get_type());
Variant var = value;
if (value.get_type() == Variant::OBJECT && value.get_validated_object() == nullptr) {
var = Variant();
}
int len = 0;
Error err = encode_variant(var, nullptr, len, false);
if (err != OK) {
ERR_PRINT("Failed to encode variant.");
}
if (len > max_size) {
arr.push_back(Variant());
} else {
arr.push_back(var);
}
return arr;
}
bool DebuggerMarshalls::ScriptStackVariable::deserialize(const Array &p_arr) {
CHECK_SIZE(p_arr, 4, "ScriptStackVariable");
name = p_arr[0];
type = p_arr[1];
var_type = p_arr[2];
value = p_arr[3];
CHECK_END(p_arr, 4, "ScriptStackVariable");
return true;
}
Array DebuggerMarshalls::OutputError::serialize() {
Array arr;
arr.push_back(hr);
arr.push_back(min);
arr.push_back(sec);
arr.push_back(msec);
arr.push_back(source_file);
arr.push_back(source_func);
arr.push_back(source_line);
arr.push_back(error);
arr.push_back(error_descr);
arr.push_back(warning);
unsigned int size = callstack.size();
const ScriptLanguage::StackInfo *r = callstack.ptr();
arr.push_back(size * 3);
for (int i = 0; i < callstack.size(); i++) {
arr.push_back(r[i].file);
arr.push_back(r[i].func);
arr.push_back(r[i].line);
}
return arr;
}
bool DebuggerMarshalls::OutputError::deserialize(const Array &p_arr) {
CHECK_SIZE(p_arr, 11, "OutputError");
hr = p_arr[0];
min = p_arr[1];
sec = p_arr[2];
msec = p_arr[3];
source_file = p_arr[4];
source_func = p_arr[5];
source_line = p_arr[6];
error = p_arr[7];
error_descr = p_arr[8];
warning = p_arr[9];
unsigned int stack_size = p_arr[10];
CHECK_SIZE(p_arr, stack_size, "OutputError");
int idx = 11;
callstack.resize(stack_size / 3);
ScriptLanguage::StackInfo *w = callstack.ptrw();
for (unsigned int i = 0; i < stack_size / 3; i++) {
w[i].file = p_arr[idx];
w[i].func = p_arr[idx + 1];
w[i].line = p_arr[idx + 2];
idx += 3;
}
CHECK_END(p_arr, idx, "OutputError");
return true;
}
Array DebuggerMarshalls::serialize_key_shortcut(const Ref<Shortcut> &p_shortcut) {
ERR_FAIL_COND_V(p_shortcut.is_null(), Array());
Array keys;
for (const Ref<InputEvent> ev : p_shortcut->get_events()) {
const Ref<InputEventKey> kev = ev;
ERR_CONTINUE(kev.is_null());
if (kev->get_physical_keycode() != Key::NONE) {
keys.push_back(true);
keys.push_back(kev->get_physical_keycode_with_modifiers());
} else {
keys.push_back(false);
keys.push_back(kev->get_keycode_with_modifiers());
}
}
return keys;
}
Ref<Shortcut> DebuggerMarshalls::deserialize_key_shortcut(const Array &p_keys) {
Array key_events;
ERR_FAIL_COND_V(p_keys.size() % 2 != 0, Ref<Shortcut>());
for (int i = 0; i < p_keys.size(); i += 2) {
ERR_CONTINUE(p_keys[i].get_type() != Variant::BOOL);
ERR_CONTINUE(p_keys[i + 1].get_type() != Variant::INT);
key_events.push_back(InputEventKey::create_reference((Key)p_keys[i + 1].operator int(), p_keys[i].operator bool()));
}
if (key_events.is_empty()) {
return Ref<Shortcut>();
}
Ref<Shortcut> shortcut;
shortcut.instantiate();
shortcut->set_events(key_events);
return shortcut;
}

View File

@@ -1,77 +0,0 @@
/**************************************************************************/
/* debugger_marshalls.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef DEBUGGER_MARSHALLS_H
#define DEBUGGER_MARSHALLS_H
#include "core/input/shortcut.h"
#include "core/object/script_language.h"
struct DebuggerMarshalls {
struct ScriptStackVariable {
String name;
Variant value;
int type = -1;
int var_type = -1;
Array serialize(int max_size = 1 << 20); // 1 MiB default.
bool deserialize(const Array &p_arr);
};
struct ScriptStackDump {
List<ScriptLanguage::StackInfo> frames;
ScriptStackDump() {}
Array serialize();
bool deserialize(const Array &p_arr);
};
struct OutputError {
int hr = -1;
int min = -1;
int sec = -1;
int msec = -1;
String source_file;
String source_func;
int source_line = -1;
String error;
String error_descr;
bool warning = false;
Vector<ScriptLanguage::StackInfo> callstack;
Array serialize();
bool deserialize(const Array &p_arr);
};
static Array serialize_key_shortcut(const Ref<Shortcut> &p_shortcut);
static Ref<Shortcut> deserialize_key_shortcut(const Array &p_keys);
};
#endif // DEBUGGER_MARSHALLS_H

View File

@@ -1,203 +0,0 @@
/**************************************************************************/
/* engine_debugger.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "engine_debugger.h"
#include "core/debugger/local_debugger.h"
#include "core/debugger/remote_debugger.h"
#include "core/debugger/remote_debugger_peer.h"
#include "core/debugger/script_debugger.h"
#include "core/os/os.h"
EngineDebugger *EngineDebugger::singleton = nullptr;
ScriptDebugger *EngineDebugger::script_debugger = nullptr;
HashMap<StringName, EngineDebugger::Profiler> EngineDebugger::profilers;
HashMap<StringName, EngineDebugger::Capture> EngineDebugger::captures;
HashMap<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols;
void (*EngineDebugger::allow_focus_steal_fn)();
void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) {
ERR_FAIL_COND_MSG(profilers.has(p_name), vformat("Profiler already registered: '%s'.", p_name));
profilers.insert(p_name, p_func);
}
void EngineDebugger::unregister_profiler(const StringName &p_name) {
ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Profiler not registered: '%s'.", p_name));
Profiler &p = profilers[p_name];
if (p.active && p.toggle) {
p.toggle(p.data, false, Array());
p.active = false;
}
profilers.erase(p_name);
}
void EngineDebugger::register_message_capture(const StringName &p_name, Capture p_func) {
ERR_FAIL_COND_MSG(captures.has(p_name), vformat("Capture already registered: '%s'.", p_name));
captures.insert(p_name, p_func);
}
void EngineDebugger::unregister_message_capture(const StringName &p_name) {
ERR_FAIL_COND_MSG(!captures.has(p_name), vformat("Capture not registered: '%s'.", p_name));
captures.erase(p_name);
}
void EngineDebugger::register_uri_handler(const String &p_protocol, CreatePeerFunc p_func) {
ERR_FAIL_COND_MSG(protocols.has(p_protocol), vformat("Protocol handler already registered: '%s'.", p_protocol));
protocols.insert(p_protocol, p_func);
}
void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) {
ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Can't change profiler state, no profiler: '%s'.", p_name));
Profiler &p = profilers[p_name];
if (p.toggle) {
p.toggle(p.data, p_enabled, p_opts);
}
p.active = p_enabled;
}
void EngineDebugger::profiler_add_frame_data(const StringName &p_name, const Array &p_data) {
ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Can't add frame data, no profiler: '%s'.", p_name));
Profiler &p = profilers[p_name];
if (p.add) {
p.add(p.data, p_data);
}
}
bool EngineDebugger::is_profiling(const StringName &p_name) {
return profilers.has(p_name) && profilers[p_name].active;
}
bool EngineDebugger::has_profiler(const StringName &p_name) {
return profilers.has(p_name);
}
bool EngineDebugger::has_capture(const StringName &p_name) {
return captures.has(p_name);
}
Error EngineDebugger::capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured) {
r_captured = false;
ERR_FAIL_COND_V_MSG(!captures.has(p_name), ERR_UNCONFIGURED, vformat("Capture not registered: '%s'.", p_name));
const Capture &cap = captures[p_name];
return cap.capture(cap.data, p_msg, p_args, r_captured);
}
void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, uint64_t p_physics_ticks, double p_physics_frame_time) {
frame_time = USEC_TO_SEC(p_frame_ticks);
process_time = USEC_TO_SEC(p_process_ticks);
physics_time = USEC_TO_SEC(p_physics_ticks);
physics_frame_time = p_physics_frame_time;
// Notify tick to running profilers
for (KeyValue<StringName, Profiler> &E : profilers) {
Profiler &p = E.value;
if (!p.active || !p.tick) {
continue;
}
p.tick(p.data, frame_time, process_time, physics_time, physics_frame_time);
}
singleton->poll_events(true);
}
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)()) {
register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
if (p_uri.is_empty()) {
return;
}
if (p_uri == "local://") {
singleton = memnew(LocalDebugger);
script_debugger = memnew(ScriptDebugger);
// Tell the OS that we want to handle termination signals.
OS::get_singleton()->initialize_debugging();
} else if (p_uri.contains("://")) {
const String proto = p_uri.substr(0, p_uri.find("://") + 3);
if (!protocols.has(proto)) {
return;
}
RemoteDebuggerPeer *peer = protocols[proto](p_uri);
if (!peer) {
return;
}
singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(peer)));
script_debugger = memnew(ScriptDebugger);
// Notify editor of our pid (to allow focus stealing).
Array msg;
msg.push_back(OS::get_singleton()->get_process_id());
singleton->send_message("set_pid", msg);
}
if (!singleton) {
return;
}
// There is a debugger, parse breakpoints.
ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints);
for (int i = 0; i < p_breakpoints.size(); i++) {
const String &bp = p_breakpoints[i];
int sp = bp.rfind_char(':');
ERR_CONTINUE_MSG(sp == -1, vformat("Invalid breakpoint: '%s', expected file:line format.", bp));
singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp));
}
allow_focus_steal_fn = p_allow_focus_steal_fn;
}
void EngineDebugger::deinitialize() {
if (singleton) {
// Stop all profilers
for (const KeyValue<StringName, Profiler> &E : profilers) {
if (E.value.active) {
singleton->profiler_enable(E.key, false);
}
}
// Flush any remaining message
singleton->poll_events(false);
memdelete(singleton);
singleton = nullptr;
}
// Clear profilers/captures/protocol handlers.
profilers.clear();
captures.clear();
protocols.clear();
}
EngineDebugger::~EngineDebugger() {
if (script_debugger) {
memdelete(script_debugger);
}
script_debugger = nullptr;
singleton = nullptr;
}

View File

@@ -1,144 +0,0 @@
/**************************************************************************/
/* engine_debugger.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef ENGINE_DEBUGGER_H
#define ENGINE_DEBUGGER_H
#include "core/string/string_name.h"
#include "core/string/ustring.h"
#include "core/templates/hash_map.h"
#include "core/templates/vector.h"
#include "core/variant/array.h"
class RemoteDebuggerPeer;
class ScriptDebugger;
class EngineDebugger {
public:
typedef void (*ProfilingToggle)(void *p_user, bool p_enable, const Array &p_opts);
typedef void (*ProfilingTick)(void *p_user, double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time);
typedef void (*ProfilingAdd)(void *p_user, const Array &p_arr);
typedef Error (*CaptureFunc)(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
typedef RemoteDebuggerPeer *(*CreatePeerFunc)(const String &p_uri);
class Profiler {
friend class EngineDebugger;
ProfilingToggle toggle = nullptr;
ProfilingAdd add = nullptr;
ProfilingTick tick = nullptr;
void *data = nullptr;
bool active = false;
public:
Profiler() {}
Profiler(void *p_data, ProfilingToggle p_toggle, ProfilingAdd p_add, ProfilingTick p_tick) {
data = p_data;
toggle = p_toggle;
add = p_add;
tick = p_tick;
}
};
class Capture {
friend class EngineDebugger;
CaptureFunc capture = nullptr;
void *data = nullptr;
public:
Capture() {}
Capture(void *p_data, CaptureFunc p_capture) {
data = p_data;
capture = p_capture;
}
};
private:
double frame_time = 0.0;
double process_time = 0.0;
double physics_time = 0.0;
double physics_frame_time = 0.0;
uint32_t poll_every = 0;
protected:
static EngineDebugger *singleton;
static ScriptDebugger *script_debugger;
static HashMap<StringName, Profiler> profilers;
static HashMap<StringName, Capture> captures;
static HashMap<String, CreatePeerFunc> protocols;
static void (*allow_focus_steal_fn)();
public:
_FORCE_INLINE_ static EngineDebugger *get_singleton() { return singleton; }
_FORCE_INLINE_ static bool is_active() { return singleton != nullptr && script_debugger != nullptr; }
_FORCE_INLINE_ static ScriptDebugger *get_script_debugger() { return script_debugger; }
static void initialize(const String &p_uri, bool p_skip_breakpoints, const Vector<String> &p_breakpoints, void (*p_allow_focus_steal_fn)());
static void deinitialize();
static void register_profiler(const StringName &p_name, const Profiler &p_profiler);
static void unregister_profiler(const StringName &p_name);
static bool is_profiling(const StringName &p_name);
static bool has_profiler(const StringName &p_name);
static void profiler_add_frame_data(const StringName &p_name, const Array &p_data);
static void register_message_capture(const StringName &p_name, Capture p_func);
static void unregister_message_capture(const StringName &p_name);
static bool has_capture(const StringName &p_name);
static void register_uri_handler(const String &p_protocol, CreatePeerFunc p_func);
void iteration(uint64_t p_frame_ticks, uint64_t p_process_ticks, uint64_t p_physics_ticks, double p_physics_frame_time);
void profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts = Array());
Error capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured);
void line_poll() {
// The purpose of this is just processing events every now and then when the script might get too busy otherwise bugs like infinite loops can't be caught.
if (unlikely(poll_every % 2048) == 0) {
poll_events(false);
}
poll_every++;
}
virtual void poll_events(bool p_is_idle) {}
virtual void send_message(const String &p_msg, const Array &p_data) = 0;
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) = 0;
virtual void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false) = 0;
virtual ~EngineDebugger();
};
#endif // ENGINE_DEBUGGER_H

View File

@@ -1,82 +0,0 @@
/**************************************************************************/
/* engine_profiler.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "engine_profiler.h"
#include "core/debugger/engine_debugger.h"
void EngineProfiler::_bind_methods() {
GDVIRTUAL_BIND(_toggle, "enable", "options");
GDVIRTUAL_BIND(_add_frame, "data");
GDVIRTUAL_BIND(_tick, "frame_time", "process_time", "physics_time", "physics_frame_time");
}
void EngineProfiler::toggle(bool p_enable, const Array &p_array) {
GDVIRTUAL_CALL(_toggle, p_enable, p_array);
}
void EngineProfiler::add(const Array &p_data) {
GDVIRTUAL_CALL(_add_frame, p_data);
}
void EngineProfiler::tick(double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) {
GDVIRTUAL_CALL(_tick, p_frame_time, p_process_time, p_physics_time, p_physics_frame_time);
}
Error EngineProfiler::bind(const String &p_name) {
ERR_FAIL_COND_V(is_bound(), ERR_ALREADY_IN_USE);
EngineDebugger::Profiler prof(
this,
[](void *p_user, bool p_enable, const Array &p_opts) {
static_cast<EngineProfiler *>(p_user)->toggle(p_enable, p_opts);
},
[](void *p_user, const Array &p_data) {
static_cast<EngineProfiler *>(p_user)->add(p_data);
},
[](void *p_user, double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) {
static_cast<EngineProfiler *>(p_user)->tick(p_frame_time, p_process_time, p_physics_time, p_physics_frame_time);
});
registration = p_name;
EngineDebugger::register_profiler(p_name, prof);
return OK;
}
Error EngineProfiler::unbind() {
ERR_FAIL_COND_V(!is_bound(), ERR_UNCONFIGURED);
EngineDebugger::unregister_profiler(registration);
registration.clear();
return OK;
}
EngineProfiler::~EngineProfiler() {
if (is_bound()) {
unbind();
}
}

View File

@@ -1,63 +0,0 @@
/**************************************************************************/
/* engine_profiler.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef ENGINE_PROFILER_H
#define ENGINE_PROFILER_H
#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
class EngineProfiler : public RefCounted {
GDCLASS(EngineProfiler, RefCounted);
private:
String registration;
protected:
static void _bind_methods();
public:
virtual void toggle(bool p_enable, const Array &p_opts);
virtual void add(const Array &p_data);
virtual void tick(double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time);
Error bind(const String &p_name);
Error unbind();
bool is_bound() const { return registration.length() > 0; }
GDVIRTUAL2(_toggle, bool, Array);
GDVIRTUAL1(_add_frame, Array);
GDVIRTUAL4(_tick, double, double, double, double);
EngineProfiler() {}
virtual ~EngineProfiler();
};
#endif // ENGINE_PROFILER_H

View File

@@ -1,390 +0,0 @@
/**************************************************************************/
/* local_debugger.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "local_debugger.h"
#include "core/debugger/script_debugger.h"
#include "core/os/os.h"
struct LocalDebugger::ScriptsProfiler {
struct ProfileInfoSort {
bool operator()(const ScriptLanguage::ProfilingInfo &A, const ScriptLanguage::ProfilingInfo &B) const {
return A.total_time > B.total_time;
}
};
double frame_time = 0;
uint64_t idle_accum = 0;
Vector<ScriptLanguage::ProfilingInfo> pinfo;
void toggle(bool p_enable, const Array &p_opts) {
if (p_enable) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->profiling_start();
}
print_line("BEGIN PROFILING");
pinfo.resize(32768);
} else {
_print_frame_data(true);
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->profiling_stop();
}
}
}
void tick(double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) {
frame_time = p_frame_time;
_print_frame_data(false);
}
void _print_frame_data(bool p_accumulated) {
uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum;
if (!p_accumulated && diff < 1000000) { //show every one second
return;
}
idle_accum = OS::get_singleton()->get_ticks_usec();
int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (p_accumulated) {
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
} else {
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
}
}
SortArray<ScriptLanguage::ProfilingInfo, ProfileInfoSort> sort;
sort.sort(pinfo.ptrw(), ofs);
// compute total script frame time
uint64_t script_time_us = 0;
for (int i = 0; i < ofs; i++) {
script_time_us += pinfo[i].self_time;
}
double script_time = USEC_TO_SEC(script_time_us);
double total_time = p_accumulated ? script_time : frame_time;
if (!p_accumulated) {
print_line("FRAME: total: " + rtos(total_time) + " script: " + rtos(script_time) + "/" + itos(script_time * 100 / total_time) + " %");
} else {
print_line("ACCUMULATED: total: " + rtos(total_time));
}
for (int i = 0; i < ofs; i++) {
print_line(itos(i) + ":" + pinfo[i].signature);
double tt = USEC_TO_SEC(pinfo[i].total_time);
double st = USEC_TO_SEC(pinfo[i].self_time);
print_line("\ttotal: " + rtos(tt) + "/" + itos(tt * 100 / total_time) + " % \tself: " + rtos(st) + "/" + itos(st * 100 / total_time) + " % tcalls: " + itos(pinfo[i].call_count));
}
}
ScriptsProfiler() {
idle_accum = OS::get_singleton()->get_ticks_usec();
}
};
void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
ScriptLanguage *script_lang = script_debugger->get_break_language();
if (!target_function.is_empty()) {
String current_function = script_lang->debug_get_stack_level_function(0);
if (current_function != target_function) {
script_debugger->set_depth(0);
script_debugger->set_lines_left(1);
return;
}
target_function = "";
}
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(0) + " - " + script_lang->debug_get_stack_level_source(0) + ":" + itos(script_lang->debug_get_stack_level_line(0)) + " in function '" + script_lang->debug_get_stack_level_function(0) + "'");
print_line("Enter \"help\" for assistance.");
int current_frame = 0;
int total_frames = script_lang->debug_get_stack_level_count();
while (true) {
OS::get_singleton()->print("debug> ");
String line = OS::get_singleton()->get_stdin_string().strip_edges();
// Cache options
String variable_prefix = options["variable_prefix"];
if (line.is_empty() && !feof(stdin)) {
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
print_line("Enter \"help\" for assistance.");
} else if (line == "c" || line == "continue") {
break;
} else if (line == "bt" || line == "breakpoint") {
for (int i = 0; i < total_frames; i++) {
String cfi = (current_frame == i) ? "*" : " "; //current frame indicator
print_line(cfi + "Frame " + itos(i) + " - " + script_lang->debug_get_stack_level_source(i) + ":" + itos(script_lang->debug_get_stack_level_line(i)) + " in function '" + script_lang->debug_get_stack_level_function(i) + "'");
}
} else if (line.begins_with("fr") || line.begins_with("frame")) {
if (line.get_slice_count(" ") == 1) {
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
} else {
int frame = line.get_slicec(' ', 1).to_int();
if (frame < 0 || frame >= total_frames) {
print_line("Error: Invalid frame.");
} else {
current_frame = frame;
print_line("*Frame " + itos(frame) + " - " + script_lang->debug_get_stack_level_source(frame) + ":" + itos(script_lang->debug_get_stack_level_line(frame)) + " in function '" + script_lang->debug_get_stack_level_function(frame) + "'");
}
}
} else if (line.begins_with("set")) {
if (line.get_slice_count(" ") == 1) {
for (const KeyValue<String, String> &E : options) {
print_line("\t" + E.key + "=" + E.value);
}
} else {
String key_value = line.get_slicec(' ', 1);
int value_pos = key_value.find_char('=');
if (value_pos < 0) {
print_line("Error: Invalid set format. Use: set key=value");
} else {
String key = key_value.left(value_pos);
if (!options.has(key)) {
print_line("Error: Unknown option " + key);
} else {
// Allow explicit tab character
String value = key_value.substr(value_pos + 1).replace("\\t", "\t");
options[key] = value;
}
}
}
} else if (line == "lv" || line == "locals") {
List<String> locals;
List<Variant> values;
script_lang->debug_get_stack_level_locals(current_frame, &locals, &values);
print_variables(locals, values, variable_prefix);
} else if (line == "gv" || line == "globals") {
List<String> globals;
List<Variant> values;
script_lang->debug_get_globals(&globals, &values);
print_variables(globals, values, variable_prefix);
} else if (line == "mv" || line == "members") {
List<String> members;
List<Variant> values;
script_lang->debug_get_stack_level_members(current_frame, &members, &values);
print_variables(members, values, variable_prefix);
} else if (line.begins_with("p") || line.begins_with("print")) {
if (line.find_char(' ') < 0) {
print_line("Usage: print <expression>");
} else {
String expr = line.split(" ", true, 1)[1];
String res = script_lang->debug_parse_stack_level_expression(current_frame, expr);
print_line(res);
}
} else if (line == "s" || line == "step") {
script_debugger->set_depth(-1);
script_debugger->set_lines_left(1);
break;
} else if (line == "n" || line == "next") {
script_debugger->set_depth(0);
script_debugger->set_lines_left(1);
break;
} else if (line == "fin" || line == "finish") {
String current_function = script_lang->debug_get_stack_level_function(0);
for (int i = 0; i < total_frames; i++) {
target_function = script_lang->debug_get_stack_level_function(i);
if (target_function != current_function) {
script_debugger->set_depth(0);
script_debugger->set_lines_left(1);
return;
}
}
print_line("Error: Reached last frame.");
target_function = "";
} else if (line.begins_with("br") || line.begins_with("break")) {
if (line.get_slice_count(" ") <= 1) {
const HashMap<int, HashSet<StringName>> &breakpoints = script_debugger->get_breakpoints();
if (breakpoints.size() == 0) {
print_line("No Breakpoints.");
continue;
}
print_line("Breakpoint(s): " + itos(breakpoints.size()));
for (const KeyValue<int, HashSet<StringName>> &E : breakpoints) {
print_line("\t" + String(*E.value.begin()) + ":" + itos(E.key));
}
} else {
Pair<String, int> breakpoint = to_breakpoint(line);
String source = breakpoint.first;
int linenr = breakpoint.second;
if (source.is_empty()) {
continue;
}
script_debugger->insert_breakpoint(linenr, source);
print_line("Added breakpoint at " + source + ":" + itos(linenr));
}
} else if (line == "q" || line == "quit" ||
(line.is_empty() && feof(stdin))) {
// Do not stop again on quit
script_debugger->clear_breakpoints();
script_debugger->set_depth(-1);
script_debugger->set_lines_left(-1);
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
if (main_loop->get_class() == "SceneTree") {
main_loop->call("quit");
}
break;
} else if (line.begins_with("delete")) {
if (line.get_slice_count(" ") <= 1) {
script_debugger->clear_breakpoints();
} else {
Pair<String, int> breakpoint = to_breakpoint(line);
String source = breakpoint.first;
int linenr = breakpoint.second;
if (source.is_empty()) {
continue;
}
script_debugger->remove_breakpoint(linenr, source);
print_line("Removed breakpoint at " + source + ":" + itos(linenr));
}
} else if (line == "h" || line == "help") {
print_line("Built-In Debugger command list:\n");
print_line("\tc,continue\t\t Continue execution.");
print_line("\tbt,backtrace\t\t Show stack trace (frames).");
print_line("\tfr,frame <frame>:\t Change current frame.");
print_line("\tlv,locals\t\t Show local variables for current frame.");
print_line("\tmv,members\t\t Show member variables for \"this\" in frame.");
print_line("\tgv,globals\t\t Show global variables.");
print_line("\tp,print <expr>\t\t Execute and print variable in expression.");
print_line("\ts,step\t\t\t Step to next line.");
print_line("\tn,next\t\t\t Next line.");
print_line("\tfin,finish\t\t Step out of current frame.");
print_line("\tbr,break [source:line]\t List all breakpoints or place a breakpoint.");
print_line("\tdelete [source:line]:\t Delete one/all breakpoints.");
print_line("\tset [key=value]:\t List all options, or set one.");
print_line("\tq,quit\t\t\t Quit application.");
} else {
print_line("Error: Invalid command, enter \"help\" for assistance.");
}
}
}
void LocalDebugger::print_variables(const List<String> &names, const List<Variant> &values, const String &variable_prefix) {
String value;
Vector<String> value_lines;
const List<Variant>::Element *V = values.front();
for (const String &E : names) {
value = String(V->get());
if (variable_prefix.is_empty()) {
print_line(E + ": " + String(V->get()));
} else {
print_line(E + ":");
value_lines = value.split("\n");
for (int i = 0; i < value_lines.size(); ++i) {
print_line(variable_prefix + value_lines[i]);
}
}
V = V->next();
}
}
Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
String breakpoint_part = p_line.get_slicec(' ', 1);
Pair<String, int> breakpoint;
int last_colon = breakpoint_part.rfind_char(':');
if (last_colon < 0) {
print_line("Error: Invalid breakpoint format. Expected [source:line]");
return breakpoint;
}
breakpoint.first = script_debugger->breakpoint_find_source(breakpoint_part.left(last_colon).strip_edges());
breakpoint.second = breakpoint_part.substr(last_colon).strip_edges().to_int();
return breakpoint;
}
void LocalDebugger::send_message(const String &p_message, const Array &p_args) {
// This needs to be cleaned up entirely.
// print_line("MESSAGE: '" + p_message + "' - " + String(Variant(p_args)));
}
void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
print_line("ERROR: '" + (p_descr.is_empty() ? p_err : p_descr) + "'");
}
LocalDebugger::LocalDebugger() {
options["variable_prefix"] = "";
// Bind scripts profiler.
scripts_profiler = memnew(ScriptsProfiler);
Profiler scr_prof(
scripts_profiler,
[](void *p_user, bool p_enable, const Array &p_opts) {
static_cast<ScriptsProfiler *>(p_user)->toggle(p_enable, p_opts);
},
nullptr,
[](void *p_user, double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) {
static_cast<ScriptsProfiler *>(p_user)->tick(p_frame_time, p_process_time, p_physics_time, p_physics_frame_time);
});
register_profiler("scripts", scr_prof);
}
LocalDebugger::~LocalDebugger() {
unregister_profiler("scripts");
if (scripts_profiler) {
memdelete(scripts_profiler);
}
}

View File

@@ -1,59 +0,0 @@
/**************************************************************************/
/* local_debugger.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef LOCAL_DEBUGGER_H
#define LOCAL_DEBUGGER_H
#include "core/debugger/engine_debugger.h"
#include "core/object/script_language.h"
#include "core/templates/list.h"
class LocalDebugger : public EngineDebugger {
private:
struct ScriptsProfiler;
ScriptsProfiler *scripts_profiler = nullptr;
String target_function;
HashMap<String, String> options;
Pair<String, int> to_breakpoint(const String &p_line);
void print_variables(const List<String> &names, const List<Variant> &values, const String &variable_prefix);
public:
void debug(bool p_can_continue, bool p_is_error_breakpoint);
void send_message(const String &p_message, const Array &p_args);
void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type);
LocalDebugger();
~LocalDebugger();
};
#endif // LOCAL_DEBUGGER_H

View File

@@ -1,736 +0,0 @@
/**************************************************************************/
/* remote_debugger.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "remote_debugger.h"
#include "core/config/project_settings.h"
#include "core/debugger/debugger_marshalls.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/engine_profiler.h"
#include "core/debugger/script_debugger.h"
#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/math/expression.h"
#include "core/object/script_language.h"
#include "core/os/os.h"
#include "servers/display_server.h"
class RemoteDebugger::PerformanceProfiler : public EngineProfiler {
Object *performance = nullptr;
int last_perf_time = 0;
uint64_t last_monitor_modification_time = 0;
public:
void toggle(bool p_enable, const Array &p_opts) {}
void add(const Array &p_data) {}
void tick(double p_frame_time, double p_process_time, double p_physics_time, double p_physics_frame_time) {
if (!performance) {
return;
}
uint64_t pt = OS::get_singleton()->get_ticks_msec();
if (pt - last_perf_time < 1000) {
return;
}
last_perf_time = pt;
Array custom_monitor_names = performance->call("get_custom_monitor_names");
uint64_t monitor_modification_time = performance->call("get_monitor_modification_time");
if (monitor_modification_time > last_monitor_modification_time) {
last_monitor_modification_time = monitor_modification_time;
EngineDebugger::get_singleton()->send_message("performance:profile_names", custom_monitor_names);
}
int max = performance->get("MONITOR_MAX");
Array arr;
arr.resize(max + custom_monitor_names.size());
for (int i = 0; i < max; i++) {
arr[i] = performance->call("get_monitor", i);
}
for (int i = 0; i < custom_monitor_names.size(); i++) {
Variant monitor_value = performance->call("get_custom_monitor", custom_monitor_names[i]);
if (!monitor_value.is_num()) {
ERR_PRINT(vformat("Value of custom monitor '%s' is not a number.", String(custom_monitor_names[i])));
arr[i + max] = Variant();
} else {
arr[i + max] = monitor_value;
}
}
EngineDebugger::get_singleton()->send_message("performance:profile_frame", arr);
}
explicit PerformanceProfiler(Object *p_performance) {
performance = p_performance;
}
};
Error RemoteDebugger::_put_msg(const String &p_message, const Array &p_data) {
Array msg;
msg.push_back(p_message);
msg.push_back(Thread::get_caller_id());
msg.push_back(p_data);
Error err = peer->put_message(msg);
if (err != OK) {
n_messages_dropped++;
}
return err;
}
void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
if (p_type == ERR_HANDLER_SCRIPT) {
return; //ignore script errors, those go through debugger
}
RemoteDebugger *rd = static_cast<RemoteDebugger *>(p_this);
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive errors during flush.
return;
}
Vector<ScriptLanguage::StackInfo> si;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
si = ScriptServer::get_language(i)->debug_get_current_stack_info();
if (si.size()) {
break;
}
}
// send_error will lock internally.
rd->script_debugger->send_error(String::utf8(p_func), String::utf8(p_file), p_line, String::utf8(p_err), String::utf8(p_descr), p_editor_notify, p_type, si);
}
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich) {
RemoteDebugger *rd = static_cast<RemoteDebugger *>(p_this);
if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
return;
}
String s = p_string;
int allowed_chars = MIN(MAX(rd->max_chars_per_second - rd->char_count, 0), s.length());
if (allowed_chars == 0 && s.length() > 0) {
return;
}
if (allowed_chars < s.length()) {
s = s.substr(0, allowed_chars);
}
MutexLock lock(rd->mutex);
rd->char_count += allowed_chars;
bool overflowed = rd->char_count >= rd->max_chars_per_second;
if (rd->is_peer_connected()) {
if (overflowed) {
s += "[...]";
}
OutputString output_string;
output_string.message = s;
if (p_error) {
output_string.type = MESSAGE_TYPE_ERROR;
} else if (p_rich) {
output_string.type = MESSAGE_TYPE_LOG_RICH;
} else {
output_string.type = MESSAGE_TYPE_LOG;
}
rd->output_strings.push_back(output_string);
if (overflowed) {
output_string.message = "[output overflow, print less text!]";
output_string.type = MESSAGE_TYPE_ERROR;
rd->output_strings.push_back(output_string);
}
}
}
RemoteDebugger::ErrorMessage RemoteDebugger::_create_overflow_error(const String &p_what, const String &p_descr) {
ErrorMessage oe;
oe.error = p_what;
oe.error_descr = p_descr;
oe.warning = false;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr = time / 3600000;
oe.min = (time / 60000) % 60;
oe.sec = (time / 1000) % 60;
oe.msec = time % 1000;
return oe;
}
void RemoteDebugger::flush_output() {
MutexLock lock(mutex);
flush_thread = Thread::get_caller_id();
flushing = true;
if (!is_peer_connected()) {
return;
}
if (n_messages_dropped > 0) {
ErrorMessage err_msg = _create_overflow_error("TOO_MANY_MESSAGES", "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped. Profiling might misbheave, try raising 'network/limits/debugger/max_queued_messages' in project setting.");
if (_put_msg("error", err_msg.serialize()) == OK) {
n_messages_dropped = 0;
}
}
if (output_strings.size()) {
// Join output strings so we generate less messages.
Vector<String> joined_log_strings;
Vector<String> strings;
Vector<int> types;
for (const OutputString &output_string : output_strings) {
if (output_string.type == MESSAGE_TYPE_ERROR) {
if (!joined_log_strings.is_empty()) {
strings.push_back(String("\n").join(joined_log_strings));
types.push_back(MESSAGE_TYPE_LOG);
joined_log_strings.clear();
}
strings.push_back(output_string.message);
types.push_back(MESSAGE_TYPE_ERROR);
} else if (output_string.type == MESSAGE_TYPE_LOG_RICH) {
if (!joined_log_strings.is_empty()) {
strings.push_back(String("\n").join(joined_log_strings));
types.push_back(MESSAGE_TYPE_LOG_RICH);
joined_log_strings.clear();
}
strings.push_back(output_string.message);
types.push_back(MESSAGE_TYPE_LOG_RICH);
} else {
joined_log_strings.push_back(output_string.message);
}
}
if (!joined_log_strings.is_empty()) {
strings.push_back(String("\n").join(joined_log_strings));
types.push_back(MESSAGE_TYPE_LOG);
}
Array arr;
arr.push_back(strings);
arr.push_back(types);
_put_msg("output", arr);
output_strings.clear();
}
while (errors.size()) {
ErrorMessage oe = errors.front()->get();
_put_msg("error", oe.serialize());
errors.pop_front();
}
// Update limits
uint64_t ticks = OS::get_singleton()->get_ticks_usec() / 1000;
if (ticks - last_reset > 1000) {
last_reset = ticks;
char_count = 0;
err_count = 0;
n_errors_dropped = 0;
warn_count = 0;
n_warnings_dropped = 0;
}
flushing = false;
}
void RemoteDebugger::send_message(const String &p_message, const Array &p_args) {
MutexLock lock(mutex);
if (is_peer_connected()) {
_put_msg(p_message, p_args);
}
}
void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) {
ErrorMessage oe;
oe.error = p_err;
oe.error_descr = p_descr;
oe.source_file = p_file;
oe.source_line = p_line;
oe.source_func = p_func;
oe.warning = p_type == ERR_HANDLER_WARNING;
uint64_t time = OS::get_singleton()->get_ticks_msec();
oe.hr = time / 3600000;
oe.min = (time / 60000) % 60;
oe.sec = (time / 1000) % 60;
oe.msec = time % 1000;
oe.callstack.append_array(script_debugger->get_error_stack_info());
if (flushing && Thread::get_caller_id() == flush_thread) { // Can't handle recursive errors during flush.
return;
}
MutexLock lock(mutex);
if (oe.warning) {
warn_count++;
} else {
err_count++;
}
if (is_peer_connected()) {
if (oe.warning) {
if (warn_count > max_warnings_per_second) {
n_warnings_dropped++;
if (n_warnings_dropped == 1) {
// Only print one message about dropping per second
ErrorMessage overflow = _create_overflow_error("TOO_MANY_WARNINGS", "Too many warnings! Ignoring warnings for up to 1 second.");
errors.push_back(overflow);
}
} else {
errors.push_back(oe);
}
} else {
if (err_count > max_errors_per_second) {
n_errors_dropped++;
if (n_errors_dropped == 1) {
// Only print one message about dropping per second
ErrorMessage overflow = _create_overflow_error("TOO_MANY_ERRORS", "Too many errors! Ignoring errors for up to 1 second.");
errors.push_back(overflow);
}
} else {
errors.push_back(oe);
}
}
}
}
void RemoteDebugger::_send_stack_vars(List<String> &p_names, List<Variant> &p_vals, int p_type) {
DebuggerMarshalls::ScriptStackVariable stvar;
List<String>::Element *E = p_names.front();
List<Variant>::Element *F = p_vals.front();
while (E) {
stvar.name = E->get();
stvar.value = F->get();
stvar.type = p_type;
send_message("stack_frame_var", stvar.serialize());
E = E->next();
F = F->next();
}
}
Error RemoteDebugger::_try_capture(const String &p_msg, const Array &p_data, bool &r_captured) {
const int idx = p_msg.find_char(':');
r_captured = false;
if (idx < 0) { // No prefix, unknown message.
return OK;
}
const String cap = p_msg.substr(0, idx);
if (!has_capture(cap)) {
return ERR_UNAVAILABLE; // Unknown message...
}
const String msg = p_msg.substr(idx + 1);
return capture_parse(cap, msg, p_data, r_captured);
}
void RemoteDebugger::_poll_messages() {
MutexLock mutex_lock(mutex);
peer->poll();
while (peer->has_message()) {
Array cmd = peer->get_message();
ERR_CONTINUE(cmd.size() != 3);
ERR_CONTINUE(cmd[0].get_type() != Variant::STRING);
ERR_CONTINUE(cmd[1].get_type() != Variant::INT);
ERR_CONTINUE(cmd[2].get_type() != Variant::ARRAY);
Thread::ID thread = cmd[1];
if (!messages.has(thread)) {
continue; // This thread is not around to receive the messages
}
Message msg;
msg.message = cmd[0];
msg.data = cmd[2];
messages[thread].push_back(msg);
}
}
bool RemoteDebugger::_has_messages() {
MutexLock mutex_lock(mutex);
return messages.has(Thread::get_caller_id()) && !messages[Thread::get_caller_id()].is_empty();
}
Array RemoteDebugger::_get_message() {
MutexLock mutex_lock(mutex);
ERR_FAIL_COND_V(!messages.has(Thread::get_caller_id()), Array());
List<Message> &message_list = messages[Thread::get_caller_id()];
ERR_FAIL_COND_V(message_list.is_empty(), Array());
Array msg;
msg.resize(2);
msg[0] = message_list.front()->get().message;
msg[1] = message_list.front()->get().data;
message_list.pop_front();
return msg;
}
void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
//this function is called when there is a debugger break (bug on script)
//or when execution is paused from editor
{
MutexLock lock(mutex);
// Tests that require mutex.
if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint) {
return;
}
ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
if (!peer->can_block()) {
return; // Peer does not support blocking IO. We could at least send the error though.
}
}
ScriptLanguage *script_lang = script_debugger->get_break_language();
const String error_str = script_lang ? script_lang->debug_get_error() : "";
Array msg;
msg.push_back(p_can_continue);
msg.push_back(error_str);
ERR_FAIL_NULL(script_lang);
msg.push_back(script_lang->debug_get_stack_level_count() > 0);
msg.push_back(Thread::get_caller_id() == Thread::get_main_id() ? String(RTR("Main Thread")) : itos(Thread::get_caller_id()));
if (allow_focus_steal_fn) {
allow_focus_steal_fn();
}
send_message("debug_enter", msg);
Input::MouseMode mouse_mode = Input::MOUSE_MODE_VISIBLE;
if (Thread::get_caller_id() == Thread::get_main_id()) {
mouse_mode = Input::get_singleton()->get_mouse_mode();
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
}
} else {
MutexLock mutex_lock(mutex);
messages.insert(Thread::get_caller_id(), List<Message>());
}
while (is_peer_connected()) {
flush_output();
_poll_messages();
if (_has_messages()) {
Array cmd = _get_message();
ERR_CONTINUE(cmd.size() != 2);
ERR_CONTINUE(cmd[0].get_type() != Variant::STRING);
ERR_CONTINUE(cmd[1].get_type() != Variant::ARRAY);
String command = cmd[0];
Array data = cmd[1];
if (command == "step") {
script_debugger->set_depth(-1);
script_debugger->set_lines_left(1);
break;
} else if (command == "next") {
script_debugger->set_depth(0);
script_debugger->set_lines_left(1);
break;
} else if (command == "continue") {
script_debugger->set_depth(-1);
script_debugger->set_lines_left(-1);
break;
} else if (command == "break") {
ERR_PRINT("Got break when already broke!");
break;
} else if (command == "get_stack_dump") {
DebuggerMarshalls::ScriptStackDump dump;
int slc = script_lang->debug_get_stack_level_count();
for (int i = 0; i < slc; i++) {
ScriptLanguage::StackInfo frame;
frame.file = script_lang->debug_get_stack_level_source(i);
frame.line = script_lang->debug_get_stack_level_line(i);
frame.func = script_lang->debug_get_stack_level_function(i);
dump.frames.push_back(frame);
}
send_message("stack_dump", dump.serialize());
} else if (command == "get_stack_frame_vars") {
ERR_FAIL_COND(data.size() != 1);
ERR_FAIL_NULL(script_lang);
int lv = data[0];
List<String> members;
List<Variant> member_vals;
if (ScriptInstance *inst = script_lang->debug_get_stack_level_instance(lv)) {
members.push_back("self");
member_vals.push_back(inst->get_owner());
}
script_lang->debug_get_stack_level_members(lv, &members, &member_vals);
ERR_FAIL_COND(members.size() != member_vals.size());
List<String> locals;
List<Variant> local_vals;
script_lang->debug_get_stack_level_locals(lv, &locals, &local_vals);
ERR_FAIL_COND(locals.size() != local_vals.size());
List<String> globals;
List<Variant> globals_vals;
script_lang->debug_get_globals(&globals, &globals_vals);
ERR_FAIL_COND(globals.size() != globals_vals.size());
Array var_size;
var_size.push_back(local_vals.size() + member_vals.size() + globals_vals.size());
send_message("stack_frame_vars", var_size);
_send_stack_vars(locals, local_vals, 0);
_send_stack_vars(members, member_vals, 1);
_send_stack_vars(globals, globals_vals, 2);
} else if (command == "reload_scripts") {
script_paths_to_reload = data;
} else if (command == "reload_all_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
ERR_FAIL_COND(data.size() < 3);
bool set = data[2];
if (set) {
script_debugger->insert_breakpoint(data[1], data[0]);
} else {
script_debugger->remove_breakpoint(data[1], data[0]);
}
} else if (command == "set_skip_breakpoints") {
ERR_FAIL_COND(data.is_empty());
script_debugger->set_skip_breakpoints(data[0]);
} else if (command == "evaluate") {
String expression_str = data[0];
int frame = data[1];
ScriptInstance *breaked_instance = script_debugger->get_break_language()->debug_get_stack_level_instance(frame);
if (!breaked_instance) {
break;
}
List<String> locals;
List<Variant> local_vals;
script_debugger->get_break_language()->debug_get_stack_level_locals(frame, &locals, &local_vals);
ERR_FAIL_COND(locals.size() != local_vals.size());
PackedStringArray locals_vector;
for (const String &S : locals) {
locals_vector.append(S);
}
Array local_vals_array;
for (const Variant &V : local_vals) {
local_vals_array.append(V);
}
Expression expression;
expression.parse(expression_str, locals_vector);
const Variant return_val = expression.execute(local_vals_array, breaked_instance->get_owner());
DebuggerMarshalls::ScriptStackVariable stvar;
stvar.name = expression_str;
stvar.value = return_val;
stvar.type = 3;
send_message("evaluation_return", stvar.serialize());
} else {
bool captured = false;
ERR_CONTINUE(_try_capture(command, data, captured) != OK);
if (!captured) {
WARN_PRINT(vformat("Unknown message received from debugger: %s.", command));
}
}
} else {
OS::get_singleton()->delay_usec(10000);
if (Thread::get_caller_id() == Thread::get_main_id()) {
// If this is a busy loop on the main thread, events still need to be processed.
DisplayServer::get_singleton()->force_process_and_drop_events();
}
}
}
send_message("debug_exit", Array());
if (Thread::get_caller_id() == Thread::get_main_id()) {
if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
Input::get_singleton()->set_mouse_mode(mouse_mode);
}
} else {
MutexLock mutex_lock(mutex);
messages.erase(Thread::get_caller_id());
}
}
void RemoteDebugger::poll_events(bool p_is_idle) {
if (peer.is_null()) {
return;
}
flush_output();
_poll_messages();
while (_has_messages()) {
Array arr = _get_message();
ERR_CONTINUE(arr.size() != 2);
ERR_CONTINUE(arr[0].get_type() != Variant::STRING);
ERR_CONTINUE(arr[1].get_type() != Variant::ARRAY);
const String cmd = arr[0];
const int idx = cmd.find_char(':');
bool parsed = false;
if (idx < 0) { // Not prefix, use scripts capture.
capture_parse("core", cmd, arr[1], parsed);
continue;
}
const String cap = cmd.substr(0, idx);
if (!has_capture(cap)) {
continue; // Unknown message...
}
const String msg = cmd.substr(idx + 1);
capture_parse(cap, msg, arr[1], parsed);
}
// Reload scripts during idle poll only.
if (p_is_idle) {
if (reload_all_scripts) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->reload_all_scripts();
}
reload_all_scripts = false;
} else if (!script_paths_to_reload.is_empty()) {
Array scripts_to_reload;
for (int i = 0; i < script_paths_to_reload.size(); ++i) {
String path = script_paths_to_reload[i];
Error err = OK;
Ref<Script> script = ResourceLoader::load(path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &err);
ERR_CONTINUE_MSG(err != OK, vformat("Could not reload script '%s': %s", path, error_names[err]));
ERR_CONTINUE_MSG(script.is_null(), vformat("Could not reload script '%s': Not a script!", path, error_names[err]));
scripts_to_reload.push_back(script);
}
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->reload_scripts(scripts_to_reload, true);
}
}
script_paths_to_reload.clear();
}
}
Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bool &r_captured) {
r_captured = true;
if (p_cmd == "reload_scripts") {
script_paths_to_reload = p_data;
} else if (p_cmd == "reload_all_scripts") {
reload_all_scripts = true;
} else if (p_cmd == "breakpoint") {
ERR_FAIL_COND_V(p_data.size() < 3, ERR_INVALID_DATA);
bool set = p_data[2];
if (set) {
script_debugger->insert_breakpoint(p_data[1], p_data[0]);
} else {
script_debugger->remove_breakpoint(p_data[1], p_data[0]);
}
} else if (p_cmd == "set_skip_breakpoints") {
ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA);
script_debugger->set_skip_breakpoints(p_data[0]);
} else if (p_cmd == "break") {
script_debugger->debug(script_debugger->get_break_language());
} else {
r_captured = false;
}
return OK;
}
Error RemoteDebugger::_profiler_capture(const String &p_cmd, const Array &p_data, bool &r_captured) {
r_captured = false;
ERR_FAIL_COND_V(p_data.is_empty(), ERR_INVALID_DATA);
ERR_FAIL_COND_V(p_data[0].get_type() != Variant::BOOL, ERR_INVALID_DATA);
ERR_FAIL_COND_V(!has_profiler(p_cmd), ERR_UNAVAILABLE);
Array opts;
if (p_data.size() > 1) { // Optional profiler parameters.
ERR_FAIL_COND_V(p_data[1].get_type() != Variant::ARRAY, ERR_INVALID_DATA);
opts = p_data[1];
}
r_captured = true;
profiler_enable(p_cmd, p_data[0], opts);
return OK;
}
RemoteDebugger::RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer) {
peer = p_peer;
max_chars_per_second = GLOBAL_GET("network/limits/debugger/max_chars_per_second");
max_errors_per_second = GLOBAL_GET("network/limits/debugger/max_errors_per_second");
max_warnings_per_second = GLOBAL_GET("network/limits/debugger/max_warnings_per_second");
// Performance Profiler
Object *perf = Engine::get_singleton()->get_singleton_object("Performance");
if (perf) {
performance_profiler.instantiate(perf);
performance_profiler->bind("performance");
profiler_enable("performance", true);
}
// Core and profiler captures.
Capture core_cap(this,
[](void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) {
return static_cast<RemoteDebugger *>(p_user)->_core_capture(p_cmd, p_data, r_captured);
});
register_message_capture("core", core_cap);
Capture profiler_cap(this,
[](void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) {
return static_cast<RemoteDebugger *>(p_user)->_profiler_capture(p_cmd, p_data, r_captured);
});
register_message_capture("profiler", profiler_cap);
// Error handlers
phl.printfunc = _print_handler;
phl.userdata = this;
add_print_handler(&phl);
eh.errfunc = _err_handler;
eh.userdata = this;
add_error_handler(&eh);
messages.insert(Thread::get_main_id(), List<Message>());
}
RemoteDebugger::~RemoteDebugger() {
remove_print_handler(&phl);
remove_error_handler(&eh);
}

View File

@@ -1,126 +0,0 @@
/**************************************************************************/
/* remote_debugger.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef REMOTE_DEBUGGER_H
#define REMOTE_DEBUGGER_H
#include "core/debugger/debugger_marshalls.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/remote_debugger_peer.h"
#include "core/object/class_db.h"
#include "core/string/string_name.h"
#include "core/string/ustring.h"
#include "core/variant/array.h"
class RemoteDebugger : public EngineDebugger {
public:
enum MessageType {
MESSAGE_TYPE_LOG,
MESSAGE_TYPE_ERROR,
MESSAGE_TYPE_LOG_RICH,
};
private:
typedef DebuggerMarshalls::OutputError ErrorMessage;
class PerformanceProfiler;
Ref<PerformanceProfiler> performance_profiler;
Ref<RemoteDebuggerPeer> peer;
struct OutputString {
String message;
MessageType type;
};
List<OutputString> output_strings;
List<ErrorMessage> errors;
int n_messages_dropped = 0;
int max_errors_per_second = 0;
int max_chars_per_second = 0;
int max_warnings_per_second = 0;
int n_errors_dropped = 0;
int n_warnings_dropped = 0;
int char_count = 0;
int err_count = 0;
int warn_count = 0;
int last_reset = 0;
bool reload_all_scripts = false;
Array script_paths_to_reload;
// Make handlers and send_message thread safe.
Mutex mutex;
bool flushing = false;
Thread::ID flush_thread = 0;
struct Message {
String message;
Array data;
};
HashMap<Thread::ID, List<Message>> messages;
void _poll_messages();
bool _has_messages();
Array _get_message();
PrintHandlerList phl;
static void _print_handler(void *p_this, const String &p_string, bool p_error, bool p_rich);
ErrorHandlerList eh;
static void _err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, bool p_editor_notify, ErrorHandlerType p_type);
ErrorMessage _create_overflow_error(const String &p_what, const String &p_descr);
Error _put_msg(const String &p_message, const Array &p_data);
bool is_peer_connected() { return peer->is_peer_connected(); }
void flush_output();
void _send_stack_vars(List<String> &p_names, List<Variant> &p_vals, int p_type);
Error _profiler_capture(const String &p_cmd, const Array &p_data, bool &r_captured);
Error _core_capture(const String &p_cmd, const Array &p_data, bool &r_captured);
template <typename T>
void _bind_profiler(const String &p_name, T *p_prof);
Error _try_capture(const String &p_name, const Array &p_data, bool &r_captured);
public:
// Overrides
void poll_events(bool p_is_idle);
void send_message(const String &p_message, const Array &p_args);
void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type);
void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false);
explicit RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer);
~RemoteDebugger();
};
#endif // REMOTE_DEBUGGER_H

View File

@@ -1,243 +0,0 @@
/**************************************************************************/
/* remote_debugger_peer.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "remote_debugger_peer.h"
#include "core/config/project_settings.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
bool RemoteDebuggerPeerTCP::is_peer_connected() {
return connected;
}
bool RemoteDebuggerPeerTCP::has_message() {
return in_queue.size() > 0;
}
Array RemoteDebuggerPeerTCP::get_message() {
MutexLock lock(mutex);
ERR_FAIL_COND_V(!has_message(), Array());
Array out = in_queue.front()->get();
in_queue.pop_front();
return out;
}
Error RemoteDebuggerPeerTCP::put_message(const Array &p_arr) {
MutexLock lock(mutex);
if (out_queue.size() >= max_queued_messages) {
return ERR_OUT_OF_MEMORY;
}
out_queue.push_back(p_arr);
return OK;
}
int RemoteDebuggerPeerTCP::get_max_message_size() const {
return 8 << 20; // 8 MiB
}
void RemoteDebuggerPeerTCP::close() {
running = false;
if (thread.is_started()) {
thread.wait_to_finish();
}
tcp_client->disconnect_from_host();
out_buf.clear();
in_buf.clear();
}
RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) {
// This means remote debugger takes 16 MiB just because it exists...
in_buf.resize((8 << 20) + 4); // 8 MiB should be way more than enough (need 4 extra bytes for encoding packet size).
out_buf.resize(8 << 20); // 8 MiB should be way more than enough
tcp_client = p_tcp;
if (tcp_client.is_valid()) { // Attaching to an already connected stream.
connected = true;
running = true;
thread.start(_thread_func, this);
} else {
tcp_client.instantiate();
}
}
RemoteDebuggerPeerTCP::~RemoteDebuggerPeerTCP() {
close();
}
void RemoteDebuggerPeerTCP::_write_out() {
while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_OUT) == OK) {
uint8_t *buf = out_buf.ptrw();
if (out_left <= 0) {
if (out_queue.size() == 0) {
break; // Nothing left to send
}
mutex.lock();
Variant var = out_queue.front()->get();
out_queue.pop_front();
mutex.unlock();
int size = 0;
Error err = encode_variant(var, nullptr, size);
ERR_CONTINUE(err != OK || size > out_buf.size() - 4); // 4 bytes separator.
encode_uint32(size, buf);
encode_variant(var, buf + 4, size);
out_left = size + 4;
out_pos = 0;
}
int sent = 0;
tcp_client->put_partial_data(buf + out_pos, out_left, sent);
out_left -= sent;
out_pos += sent;
}
}
void RemoteDebuggerPeerTCP::_read_in() {
while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED && tcp_client->wait(NetSocket::POLL_TYPE_IN) == OK) {
uint8_t *buf = in_buf.ptrw();
if (in_left <= 0) {
if (in_queue.size() > max_queued_messages) {
break; // Too many messages already in queue.
}
if (tcp_client->get_available_bytes() < 4) {
break; // Need 4 more bytes.
}
uint32_t size = 0;
int read = 0;
Error err = tcp_client->get_partial_data((uint8_t *)&size, 4, read);
ERR_CONTINUE(read != 4 || err != OK || size > (uint32_t)in_buf.size());
in_left = size;
in_pos = 0;
}
int read = 0;
tcp_client->get_partial_data(buf + in_pos, in_left, read);
in_left -= read;
in_pos += read;
if (in_left == 0) {
Variant var;
Error err = decode_variant(var, buf, in_pos, &read);
ERR_CONTINUE(read != in_pos || err != OK);
ERR_CONTINUE_MSG(var.get_type() != Variant::ARRAY, "Malformed packet received, not an Array.");
MutexLock lock(mutex);
in_queue.push_back(var);
}
}
}
Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_port) {
IPAddress ip;
if (p_host.is_valid_ip_address()) {
ip = p_host;
} else {
ip = IP::get_singleton()->resolve_hostname(p_host);
}
int port = p_port;
const int tries = 6;
const int waits[tries] = { 1, 10, 100, 1000, 1000, 1000 };
tcp_client->connect_to_host(ip, port);
for (int i = 0; i < tries; i++) {
tcp_client->poll();
if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
print_verbose("Remote Debugger: Connected!");
break;
} else {
const int ms = waits[i];
OS::get_singleton()->delay_usec(ms * 1000);
print_verbose("Remote Debugger: Connection failed with status: '" + String::num_int64(tcp_client->get_status()) + "', retrying in " + String::num_int64(ms) + " msec.");
}
}
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
ERR_PRINT(vformat("Remote Debugger: Unable to connect. Status: %s.", String::num_int64(tcp_client->get_status())));
return FAILED;
}
connected = true;
running = true;
thread.start(_thread_func, this);
return OK;
}
void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
// Update in time for 144hz monitors
const uint64_t min_tick = 6900;
RemoteDebuggerPeerTCP *peer = static_cast<RemoteDebuggerPeerTCP *>(p_ud);
while (peer->running && peer->is_peer_connected()) {
uint64_t ticks_usec = OS::get_singleton()->get_ticks_usec();
peer->_poll();
if (!peer->is_peer_connected()) {
break;
}
ticks_usec = OS::get_singleton()->get_ticks_usec() - ticks_usec;
if (ticks_usec < min_tick) {
OS::get_singleton()->delay_usec(min_tick - ticks_usec);
}
}
}
void RemoteDebuggerPeerTCP::poll() {
// Nothing to do, polling is done in thread.
}
void RemoteDebuggerPeerTCP::_poll() {
tcp_client->poll();
if (connected) {
_write_out();
_read_in();
connected = tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED;
}
}
RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
ERR_FAIL_COND_V(!p_uri.begins_with("tcp://"), nullptr);
String debug_host = p_uri.replace("tcp://", "");
uint16_t debug_port = 6007;
if (debug_host.contains_char(':')) {
int sep_pos = debug_host.rfind_char(':');
debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos);
}
RemoteDebuggerPeerTCP *peer = memnew(RemoteDebuggerPeerTCP);
Error err = peer->connect_to_host(debug_host, debug_port);
if (err != OK) {
memdelete(peer);
return nullptr;
}
return peer;
}
RemoteDebuggerPeer::RemoteDebuggerPeer() {
max_queued_messages = (int)GLOBAL_GET("network/limits/debugger/max_queued_messages");
}

View File

@@ -1,96 +0,0 @@
/**************************************************************************/
/* remote_debugger_peer.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef REMOTE_DEBUGGER_PEER_H
#define REMOTE_DEBUGGER_PEER_H
#include "core/io/stream_peer_tcp.h"
#include "core/object/ref_counted.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
#include "core/string/ustring.h"
class RemoteDebuggerPeer : public RefCounted {
protected:
int max_queued_messages = 4096;
public:
virtual bool is_peer_connected() = 0;
virtual int get_max_message_size() const = 0;
virtual bool has_message() = 0;
virtual Error put_message(const Array &p_arr) = 0;
virtual Array get_message() = 0;
virtual void close() = 0;
virtual void poll() = 0;
virtual bool can_block() const { return true; } // If blocking io is allowed on main thread (debug).
RemoteDebuggerPeer();
};
class RemoteDebuggerPeerTCP : public RemoteDebuggerPeer {
private:
Ref<StreamPeerTCP> tcp_client;
Mutex mutex;
Thread thread;
List<Array> in_queue;
List<Array> out_queue;
int out_left = 0;
int out_pos = 0;
Vector<uint8_t> out_buf;
int in_left = 0;
int in_pos = 0;
Vector<uint8_t> in_buf;
bool connected = false;
bool running = false;
static void _thread_func(void *p_ud);
void _poll();
void _write_out();
void _read_in();
public:
static RemoteDebuggerPeer *create(const String &p_uri);
Error connect_to_host(const String &p_host, uint16_t p_port);
bool is_peer_connected() override;
int get_max_message_size() const override;
bool has_message() override;
Error put_message(const Array &p_arr) override;
Array get_message() override;
void poll() override;
void close() override;
RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_stream = Ref<StreamPeerTCP>());
~RemoteDebuggerPeerTCP();
};
#endif // REMOTE_DEBUGGER_PEER_H

View File

@@ -1,102 +0,0 @@
/**************************************************************************/
/* script_debugger.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "script_debugger.h"
#include "core/debugger/engine_debugger.h"
thread_local int ScriptDebugger::lines_left = -1;
thread_local int ScriptDebugger::depth = -1;
thread_local ScriptLanguage *ScriptDebugger::break_lang = nullptr;
thread_local Vector<ScriptDebugger::StackInfo> ScriptDebugger::error_stack_info;
void ScriptDebugger::set_lines_left(int p_left) {
lines_left = p_left;
}
void ScriptDebugger::set_depth(int p_depth) {
depth = p_depth;
}
void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) {
if (!breakpoints.has(p_line)) {
breakpoints[p_line] = HashSet<StringName>();
}
breakpoints[p_line].insert(p_source);
}
void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) {
if (!breakpoints.has(p_line)) {
return;
}
breakpoints[p_line].erase(p_source);
if (breakpoints[p_line].size() == 0) {
breakpoints.erase(p_line);
}
}
String ScriptDebugger::breakpoint_find_source(const String &p_source) const {
return p_source;
}
void ScriptDebugger::clear_breakpoints() {
breakpoints.clear();
}
void ScriptDebugger::set_skip_breakpoints(bool p_skip_breakpoints) {
skip_breakpoints = p_skip_breakpoints;
}
bool ScriptDebugger::is_skipping_breakpoints() {
return skip_breakpoints;
}
void ScriptDebugger::debug(ScriptLanguage *p_lang, bool p_can_continue, bool p_is_error_breakpoint) {
ScriptLanguage *prev = break_lang;
break_lang = p_lang;
EngineDebugger::get_singleton()->debug(p_can_continue, p_is_error_breakpoint);
break_lang = prev;
}
void ScriptDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info) {
// Store stack info, this is ugly, but allows us to separate EngineDebugger and ScriptDebugger. There might be a better way.
error_stack_info.append_array(p_stack_info);
EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_editor_notify, p_type);
error_stack_info.clear(); // Clear because this is thread local
}
Vector<ScriptLanguage::StackInfo> ScriptDebugger::get_error_stack_info() const {
return error_stack_info;
}
ScriptLanguage *ScriptDebugger::get_break_language() const {
return break_lang;
}

View File

@@ -1,86 +0,0 @@
/**************************************************************************/
/* script_debugger.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef SCRIPT_DEBUGGER_H
#define SCRIPT_DEBUGGER_H
#include "core/object/script_language.h"
#include "core/string/string_name.h"
#include "core/templates/hash_set.h"
#include "core/templates/vector.h"
class ScriptDebugger {
typedef ScriptLanguage::StackInfo StackInfo;
bool skip_breakpoints = false;
HashMap<int, HashSet<StringName>> breakpoints;
static thread_local int lines_left;
static thread_local int depth;
static thread_local ScriptLanguage *break_lang;
static thread_local Vector<StackInfo> error_stack_info;
public:
void set_lines_left(int p_left);
_ALWAYS_INLINE_ int get_lines_left() const {
return lines_left;
}
void set_depth(int p_depth);
_ALWAYS_INLINE_ int get_depth() const {
return depth;
}
String breakpoint_find_source(const String &p_source) const;
void set_break_language(ScriptLanguage *p_lang) { break_lang = p_lang; }
ScriptLanguage *get_break_language() { return break_lang; }
void set_skip_breakpoints(bool p_skip_breakpoints);
bool is_skipping_breakpoints();
void insert_breakpoint(int p_line, const StringName &p_source);
void remove_breakpoint(int p_line, const StringName &p_source);
_ALWAYS_INLINE_ bool is_breakpoint(int p_line, const StringName &p_source) const {
if (likely(!breakpoints.has(p_line))) {
return false;
}
return breakpoints[p_line].has(p_source);
}
void clear_breakpoints();
const HashMap<int, HashSet<StringName>> &get_breakpoints() const { return breakpoints; }
void debug(ScriptLanguage *p_lang, bool p_can_continue = true, bool p_is_error_breakpoint = false);
ScriptLanguage *get_break_language() const;
void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type, const Vector<StackInfo> &p_stack_info);
Vector<StackInfo> get_error_stack_info() const;
ScriptDebugger() {}
};
#endif // SCRIPT_DEBUGGER_H

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