Compare commits

..

228 Commits

Author SHA1 Message Date
2ff3b08583 Bump to 3.0.2-stable
Thanks to all of our contributors!
2018-03-03 15:22:04 +01:00
6ab8fb04af Fix documentation indentation for apply_torqe_impulse 2018-03-03 15:19:40 +01:00
498d177cfe Update changelog for 3.0.2 2018-03-03 15:12:41 +01:00
06a60bb6ef Fix floatBitsToUint function
(cherry picked from commit c6b6af7bb5)
2018-03-03 14:54:52 +01:00
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
649cb70ddb [DOCS] Small fix to Area: Fix copy/paste errors
(cherry picked from commit fdd0f18959)
2018-03-03 11:00:41 +01:00
65d214d3da i18n: Sync translation templates with current source 2018-03-03 10:58:19 +01:00
9ee98e999b i18n: Sync translations with Weblate
(cherry picked from commit 7c7d3efb5b)
2018-03-03 10:56:41 +01:00
5bcc7f88b6 [DOCS] Small fix to PinJoint2D
(cherry picked from commit 0b65bac1a1)
2018-03-03 01:55:33 +01:00
93e99846b0 [DOCS] NetworkedMultiplayerENet
(cherry picked from commit 5aae17a6fb)
2018-03-03 01:55:27 +01:00
5c2e554853 prune cache only at the start and end of build
(cherry picked from commit 29e6ec6594)
2018-03-03 01:53:22 +01:00
c4468aef5d s/Camear/Camera in docs
(cherry picked from commit b099a500eb)
2018-03-03 01:52:12 +01:00
f967334f53 Fix more regressions in RichTextLabel from PR 15711
(cherry picked from commit 0e1e95c41f)
2018-03-03 01:47:52 +01:00
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
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
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
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
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
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
0aab429453 AnimationEditor: fix time indicator offset
(cherry picked from commit acf54f8bdc)
2018-03-01 21:18:58 +01:00
61fd30c00e Fixed Windows ignoring minimized/maximized status set by user
(cherry picked from commit f8da9550f4)
2018-03-01 21:15:35 +01:00
44b206a3fa Fix server build on FreeBSD
(cherry picked from commit 8f9914bd94)
2018-03-01 21:12:28 +01:00
675899a521 Fix various valgrind reported uninitialized variable uses
(cherry picked from commit d702d7b335)
2018-03-01 21:06:31 +01:00
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
9c27e4d885 Allow degenerate triangles in polygon triangulation when necessary.
(cherry picked from commit e73266a51c)
2018-03-01 20:18:08 +01:00
c800653c6f Fix regression through fa98637aca
(cherry picked from commit 89f607604e)
2018-03-01 19:19:29 +01:00
3e931e258c More reliably find mscorlib.dll on Linux
(cherry picked from commit c094e90b25)
2018-02-27 22:12:01 +01:00
7e5a374825 Deprecate a typo for a new method introduced in 3.0.1 2018-02-27 17:53:46 +01:00
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
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
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
17408bea9c (Magnify|Pan)Gesture: implement as_text
(cherry picked from commit 67e20dc2b6)
2018-02-27 17:52:18 +01:00
2c55064708 doc: Sync with current source 2018-02-27 13:57:29 +01:00
42e82b9377 doc: Update version string for 3.0.2 2018-02-27 13:57:10 +01:00
a4b077a0ba Android: Mark GLES3 as required in the manifest
Fixes #17076.

(cherry picked from commit 7d09e6540a)
2018-02-27 13:33:59 +01:00
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
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
c730a6ce44 Fix error spam when using PanoramaSky without texture
(cherry picked from commit 7a1b7ddf6c)
2018-02-27 11:34:03 +01:00
115c0a7415 added docs on Control's drag and drop api
(cherry picked from commit 7154a96d3f)
2018-02-27 11:32:35 +01:00
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
4eb9ee9355 Fixed physics server typo
(cherry picked from commit 134cca0cf2)
2018-02-27 11:22:56 +01:00
48ed52184d Add missing return statements (iOS and server).
(cherry picked from commit e3c2778d7e)
2018-02-27 00:06:01 +01:00
69274ef368 Fix visibility of gizmos on scene load
(cherry picked from commit 99d740c46e)
2018-02-27 00:02:01 +01:00
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
58a7d78c22 [mono] get stacktraces for all inner exceptions
(cherry picked from commit 89af6c2cd7)
2018-02-26 23:55:13 +01:00
c0386f0124 Mono: Fix bindings for parameters in vararg methods
(cherry picked from commit 0c82858121)
2018-02-26 23:54:32 +01:00
b6f958965b The marshalling in was also incorrect.
(cherry picked from commit 60daa9d718)
2018-02-26 22:45:53 +01:00
dde14e15c6 Mono: Better versioning and gracefully unloading of Godot API assemblies
(cherry picked from commit f37090ccf4)
2018-02-26 22:36:03 +01:00
1ea805a4aa Add missing #endif for the main.cpp fix.
I forgot to amend my previous commit.
2018-02-26 21:02:03 +01:00
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
e499b9b4b6 Bump to version 3.0.2-devel 2018-02-26 20:36:43 +01:00
8ea709a7a9 Update the changelog for 3.0.1 2018-02-26 20:35:13 +01:00
f2e19a26f5 Add a project changelog
(cherry picked from commit f00b2dfc55)
2018-02-25 15:32:08 +01:00
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
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
bcbe7a8a6f Bump to version 3.0.2-devel
The start of the next patch release. Wooooooooooo
2018-02-24 20:08:32 +01:00
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
5f15642fde Update doc version strings to 3.0.1 2018-02-24 18:59:38 +01:00
17d7084780 Correct version number for 3.0.1 in the manpage 2018-02-24 18:37:01 +01:00
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
ad325be5a0 Add --quit option to help output and update manpage
(cherry picked from commit 95b8984d5f)
2018-02-24 18:32:22 +01:00
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
34591f9451 Fixes collisions shape selection
(cherry picked from commit c250a9a9f9)
2018-02-24 10:53:10 +01:00
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
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
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
689dfcd9ec server: Add support for statically linking libgcc and libstdc++
(cherry picked from commit be7bfdfac3)
2018-02-22 19:06:36 +01:00
46b594054c doc: Sync classref with current source 2018-02-22 19:02:37 +01:00
07e2461995 i18n: Sync translation templates with current source 2018-02-22 18:47:07 +01:00
ca5f3b9f8d i18n: Sync translations with Weblate
(cherry picked from commit 661ab3c88e)
2018-02-22 18:42:25 +01:00
3d804778fd Fix quotation in string
fix for #16404

(cherry picked from commit f38e819fc1)
2018-02-22 13:23:44 +01:00
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
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
3687faa78f Enforce insert_final_newline in the editorconfig.
(cherry picked from commit 6861886f70)
2018-02-22 13:06:25 +01:00
eacd66e784 Clean up some bad words from code comments
(cherry picked from commit d35e486228)
2018-02-22 12:22:41 +01:00
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
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
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
fdac09a0aa Made the Debugger's Stack Frames items reselectable.
(cherry picked from commit 32e3f257ac)
2018-02-22 12:18:45 +01:00
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
40018e995c Color:fix setting V switch S to old V value
(cherry picked from commit f4f92b55e1)
2018-02-22 12:07:07 +01:00
be6323d848 Added documentation for VehicleBody
(cherry picked from commit 234b86e6b2)
2018-02-22 12:03:10 +01:00
29089b715d Insert proper copy icon to debugger
(cherry picked from commit db2a1544c0)
2018-02-22 12:02:41 +01:00
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
a86829211a Added missing shader functions
(cherry picked from commit 8f04a13c98)
2018-02-22 00:02:52 +01:00
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
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
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
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
c7040f3218 Fixed sky reflection rendering when transparent BG
(cherry picked from commit c34f18acce)
2018-02-21 23:40:59 +01:00
5975b44ded Fixes gravity calculation for kinematic bodies in Bullet
(cherry picked from commit 5fb8a6a6c2)
2018-02-21 23:38:30 +01:00
8efb9c8cdd Actually fix the db/dc renaming mess
Local builds save lives :)
2018-02-21 23:21:21 +01:00
75289b4017 revert the renaming _tree_db_selected function 2018-02-21 22:57:50 +01:00
ccf27376a6 Update warning about C# support
(cherry picked from commit 24cf4fe062)
2018-02-21 22:55:46 +01:00
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
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
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
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
8dc946c89c Fix a rendering bug with screen_texture
(cherry picked from commit ea57a19b34)
2018-02-21 22:11:47 +01:00
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
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
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
70b082c0d9 Create and return LightmapCapture.
(cherry picked from commit 2e66730061)
2018-02-21 21:49:16 +01:00
bbfec2a7cc Add dummy audio driver, fix dummy rasterizer
(cherry picked from commit 4e1923a931)
2018-02-21 21:49:10 +01:00
8849377f6d Fixes to OS_Server and DummyRasterizer to match new signatures
(cherry picked from commit 2de10aa467)
2018-02-21 21:48:58 +01:00
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
fb4a784319 Add dummy Texture handling
(cherry picked from commit 72ef766dfa)
2018-02-21 21:48:33 +01:00
8f231d82bb Disable GLES builders and source from server compilation
(cherry picked from commit 8699f643c9)
2018-02-21 21:48:21 +01:00
cc280545dc Add dummy resterizer driver
(cherry picked from commit c0dce6e480)
2018-02-21 21:47:38 +01:00
fa02b58b46 Remove unused variable from plugin settings update
Fix #16199

(cherry picked from commit 9f0cce840d)
2018-02-19 23:15:56 +01:00
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
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
a76dfe9c72 Fix 2d collision body update on shape remove
(cherry picked from commit 3659df6624)
2018-02-19 22:43:33 +01:00
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
c5b5fd61d4 Warn when polling HTTPClient synchronously in HTML5 platform
(cherry picked from commit ca9fa9cca8)
2018-02-19 22:42:31 +01:00
5bb269d01d Disable insecure HTTP methods CONNECT and TRACE in HTML5 platform
(cherry picked from commit 2cd7bc04ea)
2018-02-19 22:42:22 +01:00
d5535d9357 Fix HTML5 HTTPClient response header retrieval
(cherry picked from commit 8a21f27f54)
2018-02-19 22:42:08 +01:00
2714b851bf Fix HTML5 HTTPClient failure detection
(cherry picked from commit 9ea4452d21)
2018-02-19 22:42:01 +01:00
2abbdcaa20 Mono: Fix build status icons
(cherry picked from commit 8bd05f0c71)
2018-02-19 22:40:21 +01:00
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
416cd9c8b8 add a [Signal] attribute to CSharpScripts
(cherry picked from commit efd52cd172)
2018-02-19 22:39:44 +01:00
7a20495a80 Direct to InputEventJoypadButton for using buttons
(cherry picked from commit 6af7dafd6c)
2018-02-19 22:37:09 +01:00
bafbd73b51 Remove window decorations for fullscreen on X11
(cherry picked from commit 935a99e758)
2018-02-19 22:36:20 +01:00
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
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
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
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
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
3e6ab9f3d5 Makes NodePath and RID follow PascalCase in C#.
Fixes #15685

(cherry picked from commit b1a81374d4)
2018-02-19 22:30:45 +01:00
9f9731da3a fix crash autotile edit mode
(cherry picked from commit cceb176be3)
2018-02-19 22:30:13 +01:00
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
237cf72f89 Made modifications to the RigidBody(2D) descriptions.
(cherry picked from commit 50e6b3c005)
2018-02-19 22:28:47 +01:00
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
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
2f87e7ffe9 option to disable sort in script list
(cherry picked from commit e1778fb921)
2018-02-19 22:26:29 +01:00
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
c5388fb0cf Fix for a possible compile error under OS X
(cherry picked from commit 621d28adef)
2018-02-19 22:24:57 +01:00
02e910275c Fixed small typos in the SConstruct file.
(cherry picked from commit b92c5669de)
2018-02-19 22:23:38 +01:00
285f47f037 Added return true o collide when no rusult is NULL
(cherry picked from commit f48845428d)
2018-02-19 22:21:58 +01:00
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
4bdcee2b9d [X11] Improving error detection in move_to_trash
(cherry picked from commit 268d7c7c5b)
2018-02-19 22:20:06 +01:00
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
a39930c5b9 Add a function to remove controls from containers
Closes #5968

(cherry picked from commit da69a06253)
2018-02-19 22:18:22 +01:00
c94d8e6577 Fix #16543 (add button to copy error from debugger)
(cherry picked from commit b169b16f98)
2018-02-19 22:17:26 +01:00
eb5e5200cc Fix infinite recursion with editor import plugins
(cherry picked from commit 95f7879923)
2018-02-19 22:16:33 +01:00
d54ac732ae Expose priority and order for custom import plugins
(cherry picked from commit c68948fdfa)
2018-02-19 22:16:13 +01:00
62fcd772be Add Xbox One Elite and Xbox 360 Afterglow pads
(cherry picked from commit ae579a256e)
2018-02-19 22:15:05 +01:00
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
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
0d03b5f162 Add and use mono build variables with cloned environment.
(cherry picked from commit 70d281b946)
2018-02-19 22:13:46 +01:00
148e059940 Fixed members overview not scrolling to correct line
(cherry picked from commit 4d92c5e1c3)
2018-02-19 22:13:46 +01:00
7af43c4ca3 Fix #16479 (deselect text when jumping to function)
(cherry picked from commit 3094e89782)
2018-02-19 22:13:46 +01:00
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
47b49200b0 Fixed KinematicBody move_and_slide documentation naming
(cherry picked from commit da81d9f843)
2018-02-19 22:13:46 +01:00
a7d7f763d0 Remove debugging prints related to the asset library
(cherry picked from commit 5513e4e1f9)
2018-02-19 22:13:46 +01:00
eda94419df SpinBoxes calculate correctly their width before first redraw.
(cherry picked from commit fe1ca3c6e6)
2018-02-19 22:13:46 +01:00
e6252bda5e download templates to a file using separate thread
(cherry picked from commit b4f1a035e3)
2018-02-19 22:13:46 +01:00
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
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
82b9a13e0c Fix timeline track name overlapping keyframe area
(cherry picked from commit 398f5b74e3)
2018-02-19 22:13:46 +01:00
79ef5f92a9 Remove a few debugging prints
(cherry picked from commit 84267915f5)
2018-02-19 22:13:46 +01:00
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
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
a0e9d751a3 Fixed wrong example in JSONParseResult.
(cherry picked from commit 24e87f97c6)
2018-02-19 22:13:45 +01:00
d4a70c6c08 fix buffer write performance on Windows and Unix
(cherry picked from commit 8315aa40cc)
2018-02-19 22:13:45 +01:00
65aa9063c4 Fix spaces and quotes in external editor flags
(cherry picked from commit fb8d2420b5)
2018-02-19 22:13:45 +01:00
9eb546e7ff drop path text at mouse pos
(cherry picked from commit 06965f2770)
2018-02-19 22:13:45 +01:00
f031e2f665 disable scene tree shortcuts when in a textfield
(cherry picked from commit 4e96e04389)
2018-02-19 22:13:45 +01:00
4bed14f69b Gradient: fix wrong property type
(cherry picked from commit 4f9ef96b54)
2018-02-19 22:13:45 +01:00
91692ce72a Fix gradient texture preview
(cherry picked from commit 3ba43ac975)
2018-02-19 22:13:45 +01:00
05e97db6f2 Fix wrong property type for fixed icon size in ItemList
(cherry picked from commit 331cfc1d18)
2018-02-19 22:13:45 +01:00
617bcd1b91 Capitalized "View" menu options.
(cherry picked from commit b507eeddcc)
2018-02-19 22:13:45 +01:00
34d8625d82 Fix pkgconfig detection of mono
(cherry picked from commit 5920bc6f72)
2018-02-19 22:13:45 +01:00
79b931d093 Fix UX with project settings search functionality
(cherry picked from commit e7b98119df)
2018-02-19 22:13:45 +01:00
9173819b71 [Mono] Basis values now marshalled in the correct order.
(cherry picked from commit 0cc4de1f24)
2018-02-19 22:13:45 +01:00
8787850286 Fix gizmo solid box mesh being added twice
(cherry picked from commit d0a2931cd7)
2018-02-19 22:13:45 +01:00
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
1a9a40fe31 Make parent folder selectable. Fix #16253
(cherry picked from commit 6e1c02b828)
2018-02-19 22:13:44 +01:00
eda3169cd1 Fixes open button not appearing with multiple selection
Fix #16231

(cherry picked from commit 09c277693e)
2018-02-19 22:13:44 +01:00
d7f73031fb Show default values in docs for GDScript built-in functions
(cherry picked from commit dca2ae78dd)
2018-02-19 22:13:44 +01:00
ba36ef5465 3DEditor: fix selecting node in viewport not update inspector
(cherry picked from commit cfac160f9f)
2018-02-19 22:13:44 +01:00
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
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
a6ca62ac79 Fixes a bas resizing with SplitContainer
(cherry picked from commit 30e1e42175)
2018-02-19 22:13:44 +01:00
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
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
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
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
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
c04d868476 Make KEY_ESCAPE close all output/debugger docks on bottom
(cherry picked from commit 2ae2735a7a)
2018-02-19 21:01:41 +01:00
50674dbe15 Expose 'lightmap_unwrap' method to the scripting engine.
(cherry picked from commit e3fdacdf90)
2018-02-19 20:57:40 +01:00
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
3548f71cc4 Display path to preloaded res + button to open it
(cherry picked from commit b766a849ad)
2018-02-19 20:56:16 +01:00
a1455f6a03 Change 'Build Project' button style in Mono panel
Address #15208

(cherry picked from commit 484f664331)
2018-02-19 20:50:39 +01:00
f64b68d870 Change primitive meshes acccuracy value
(cherry picked from commit b72c9b85d0)
2018-02-19 20:49:41 +01:00
f1d26c1c72 Re-enabled type icons.
(cherry picked from commit f7547a7f28)
2018-02-19 20:48:36 +01:00
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
611caa06a5 Fixed android arm64v8
(cherry picked from commit 853b1daa49)
2018-02-19 20:46:49 +01:00
3f6e8d70cf Added async and await as C# keywords.
(cherry picked from commit 3dcf0567a1)
2018-02-05 09:33:01 +01:00
40c779fb70 Mono: Remove automatic script multilevel calls
(cherry picked from commit 84437b4864)
2018-02-05 09:32:29 +01:00
532abf228c Fix texture import spelling
(cherry picked from commit d1a471f909)
2018-02-04 20:11:13 +01:00
248fea2a79 Small fixes for the Control description in the docs.
(cherry picked from commit 5e0821e867)
2018-02-04 20:10:45 +01:00
7de47fbabb Fix inconsistencies and typos in argument names
(cherry picked from commit 08d4bfacaf)
2018-02-04 20:10:13 +01:00
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
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
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
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
0fa4325153 Fix TextEdit current line highlight horizontal offset
(cherry picked from commit ba8c5bff69)
2018-02-04 20:06:46 +01:00
acf01c955f Expose a few GraphEdit methods to script languages
(cherry picked from commit b80bc73a17)
2018-02-04 20:05:47 +01:00
0a75a38db4 Add interface for plugins to enable/disable other plugins
(cherry picked from commit 87be0bc110)
2018-02-04 20:05:12 +01:00
845f44b976 ProjectSettings: Disallow adding properties without name.
(cherry picked from commit d664d6e634)
2018-02-04 20:04:31 +01:00
77ee4ced30 AudioEffectReverb: max predelay_feedback to 0.98
(cherry picked from commit 5a26e0786c)
2018-02-04 20:03:16 +01:00
780a7a281b Viewport doc improvements
(cherry picked from commit ffcbb0c358)
2018-02-04 20:02:38 +01:00
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
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
77cc0a023b attemp to fix #15870
(cherry picked from commit 517ff5c8d7)
2018-02-04 19:59:34 +01:00
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
e44bef4404 Update DONORS list
[ci skip]

(cherry picked from commit f13d034485)
2018-02-02 10:07:40 +01:00
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
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
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
187c40d64d Fix wrong return type of xform functions
(cherry picked from commit ebe2337515)
2018-01-30 20:55:41 +01:00
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
99e72894a2 Remote debugger send the real instance of WeakRef referenced to
(cherry picked from commit 10f0451cc2)
2018-01-30 20:54:25 +01:00
258119a9cf Expose audio streams get_length()
(cherry picked from commit 8a9f1c2a5d)
2018-01-30 20:53:37 +01:00
3f6694b894 Bump version to 3.0.1-devel
Onwards, but slowly, towards stability. And the stars.
2018-01-30 20:51:06 +01:00
8146 changed files with 920348 additions and 1772882 deletions

31
.appveyor.yml Normal file
View File

@ -0,0 +1,31 @@
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 --egg scons # it will fail on AppVeyor without --egg flag
- 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,6 +1,6 @@
# 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 6.0.1).
# chosen value in case the base style changes (last sync: Clang 5.0.0).
---
### General config, applies to all languages ###
BasedOnStyle: LLVM
@ -32,7 +32,6 @@ AllowShortIfStatementsOnASingleLine: true
# AfterObjCDeclaration: false
# AfterStruct: false
# AfterUnion: false
# AfterExternBlock: false
# BeforeCatch: false
# BeforeElse: false
# IndentBraces: false
@ -61,7 +60,6 @@ Cpp11BracedListStyle: false
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IncludeBlocks: Preserve
IncludeCategories:
- Regex: '".*"'
Priority: 1
@ -71,7 +69,6 @@ IncludeCategories:
Priority: 3
# IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
# IndentPPDirectives: None
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
@ -89,10 +86,6 @@ IndentWidth: 4
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 60
# PointerAlignment: Right
# RawStringFormats:
# - Delimiter: pb
# Language: TextProto
# BasedOnStyle: google
# ReflowComments: true
# SortIncludes: true
# SortUsingDeclarations: true
@ -116,7 +109,6 @@ Standard: Cpp03
---
### ObjC specific config ###
Language: ObjC
Standard: Cpp03
ObjCBlockIndentWidth: 4
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
@ -124,5 +116,4 @@ ObjCBlockIndentWidth: 4
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...

View File

@ -9,19 +9,10 @@ insert_final_newline = true
[*.{cpp,hpp,c,h,mm}]
trim_trailing_whitespace = true
[{*.gradle,AndroidManifest.xml}]
[*.py]
indent_style = space
indent_size = 4
[{*.{py,cs},SConstruct,SCsub}]
indent_style = space
indent_size = 4
# YAML requires indentation with spaces instead of tabs.
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.{csproj,props,targets,nuspec}]
[.travis.yml]
indent_style = space
indent_size = 2

18
.gitattributes vendored
View File

@ -1,15 +1,11 @@
# Properly detect languages on Github
*.h linguist-language=cpp
*.inc linguist-language=cpp
thirdparty/* linguist-vendored
drivers/* linguist-vendored
# Normalize EOL for all files that Git considers text files
* text=auto eol=lf
# 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
*.cpp eol=lf
*.mm eol=lf
*.h eol=lf
*.py eol=lf
*.hpp eol=lf
*.xml eol=lf

174
.github/CODEOWNERS vendored
View File

@ -1,174 +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
# Buildsystem
.* @godotengine/buildsystem
.github/ @godotengine/buildsystem
*.py @godotengine/buildsystem
SConstruct @godotengine/buildsystem
SCsub @godotengine/buildsystem
# Core
/core/ @godotengine/core
/core/crypto/ @godotengine/network
/core/input*.* @godotengine/input
# Doc
/doc/ @godotengine/documentation
doc_classes/* @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/dummy/ @godotengine/rendering
/drivers/gl_context/ @godotengine/rendering
/drivers/gles2/ @godotengine/rendering
/drivers/gles3/ @godotengine/rendering
/drivers/gles_common/ @godotengine/rendering
## OS
/drivers/unix/ @godotengine/_platforms
/drivers/windows/ @godotengine/windows
## Misc
/drivers/png/ @godotengine/import
# Editor
/editor/*debugger* @godotengine/debugger
/editor/icons/ @godotengine/usability
/editor/import/ @godotengine/import
/editor/plugins/*2d_*.* @godotengine/2d-editor
/editor/plugins/script_*.* @godotengine/script-editor
/editor/plugins/*shader*.* @godotengine/shaders
/editor/code_editor.* @godotengine/script-editor
/editor/*dock*.* @godotengine/docks
# Main
/main/ @godotengine/core
/main/tests/ @godotengine/tests
# Misc
/misc/ @godotengine/buildsystem
# Modules
## Audio (+ video)
/modules/minimp3/ @godotengine/audio
/modules/ogg/ @godotengine/audio
/modules/opus/ @godotengine/audio
/modules/stb_vorbis/ @godotengine/audio
/modules/theora/ @godotengine/audio
/modules/vorbis/ @godotengine/audio
/modules/webm/ @godotengine/audio
## Import
/modules/basis_universal/ @godotengine/import
/modules/bmp/ @godotengine/import
/modules/cvtt/ @godotengine/import
/modules/dds/ @godotengine/import
/modules/etc/ @godotengine/import
/modules/fbx/ @godotengine/import
/modules/gltf/ @godotengine/import
/modules/hdr/ @godotengine/import
/modules/jpg/ @godotengine/import
/modules/pvr/ @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/mbedtls/ @godotengine/network
/modules/upnp/ @godotengine/network
/modules/webrtc/ @godotengine/network
/modules/websocket/ @godotengine/network
## Rendering
/modules/denoise/ @godotengine/rendering
/modules/glslang/ @godotengine/rendering
/modules/lightmapper_cpu/ @godotengine/rendering
/modules/meshoptimizer/ @godotengine/rendering
/modules/raycast/ @godotengine/rendering
/modules/vhacd/ @godotengine/rendering
/modules/xatlas_unwrap/ @godotengine/rendering
## Scripting
/modules/gdnative/ @godotengine/gdnative
/modules/gdscript/ @godotengine/gdscript
/modules/jsonrpc/ @godotengine/gdscript
/modules/mono/ @godotengine/mono
/modules/visual_script/ @godotengine/visualscript
## Text
/modules/freetype/ @godotengine/buildsystem
/modules/gdnative/text/ @godotengine/gui-nodes
/modules/text_server_adv/ @godotengine/gui-nodes
/modules/text_server_fb/ @godotengine/gui-nodes
## XR
/modules/camera/ @godotengine/xr
/modules/gdnative/arvr/ @godotengine/xr
/modules/mobile_vr/ @godotengine/xr
/modules/webxr/ @godotengine/xr
## Misc
/modules/bullet/ @godotengine/physics
/modules/csg/ @godotengine/3d-nodes
/modules/gridmap/ @godotengine/3d-nodes
/modules/opensimplex/ @godotengine/3d-nodes
/modules/recast/ @godotengine/navigation
/modules/regex/ @godotengine/core
# Platform
/platform/android/ @godotengine/android
/platform/iphone/ @godotengine/ios
/platform/javascript/ @godotengine/html5
/platform/x11/ @godotengine/linux-bsd
/platform/osx/ @godotengine/macos
/platform/uwp/ @godotengine/uwp
/platform/windows/ @godotengine/windows
# Scene
/scene/2d/ @godotengine/2d-nodes
/scene/3d/ @godotengine/3d-nodes
/scene/animation/ @godotengine/animation
/scene/audio/ @godotengine/audio
/scene/debugger/ @godotengine/debugger
/scene/gui/ @godotengine/gui-nodes
/scene/main/ @godotengine/core
/scene/resources/default_theme/ @godotengine/gui-nodes
/scene/resources/font.* @godotengine/gui-nodes
/scene/resources/visual_shader*.* @godotengine/shaders
# Servers
/servers/arvr* @godotengine/xr
/servers/audio* @godotengine/audio
/servers/camera* @godotengine/xr
/servers/physics* @godotengine/physics
/servers/visual* @godotengine/rendering
# Thirdparty
/thirdparty/ @godotengine/buildsystem

View File

@ -1,18 +0,0 @@
---
name: Bug report
about: Report a bug in Godot
title: ''
labels: ''
assignees: ''
---
**Godot version:**
**OS/device including version:**
**Issue description:**
**Steps to reproduce:**
**Minimal reproduction project:**

View File

@ -1,19 +0,0 @@
---
name: Feature / Enhancement Request
about: Adding new features or improving existing ones.
title: 'IMPORTANT: This repository no longer accepts feature / enhancement requests.'
labels: ''
assignees: ''
---
**IMPORTANT, PLEASE READ**
Feature / Enhancement requests are no longer accepted in the main Godot repository.
Please open an item by filling the relevant fields in the *Proposals* repository:
https://github.com/godotengine/godot-proposals/issues/new/choose
Do not submit to this repository or your issue will be closed.
**IMPORTANT, PLEASE READ**

View File

@ -1,80 +0,0 @@
name: 🤖 Android Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=android verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
ANDROID_NDK_VERSION: 21.1.6352462
jobs:
android-template:
runs-on: "ubuntu-20.04"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
- name: Set up Java 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Install Android NDK r21
run: |
sudo ${ANDROID_HOME}/tools/bin/sdkmanager --install 'ndk;${{env.ANDROID_NDK_VERSION}}'
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: android-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
ANDROID_NDK_ROOT: /usr/local/lib/android/sdk/ndk/${{env.ANDROID_NDK_VERSION}}/
run: |
scons target=release tools=no android_arch=armv7
scons target=release tools=no android_arch=arm64v8
cd platform/android/java
./gradlew generateGodotTemplates
cd ../../..
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,58 +0,0 @@
name: 🍏 iOS Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=iphone verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
ios-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: ios-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,85 +0,0 @@
name: 🌐 JavaScript Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=javascript verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
EM_VERSION: 1.39.20
EM_CACHE_FOLDER: 'emsdk-cache'
jobs:
javascript-template:
runs-on: "ubuntu-20.04"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: javascript-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Additional cache for Emscripten generated system libraries
- name: Load Emscripten cache
id: javascript-template-emscripten-cache
uses: actions/cache@v2
with:
path: ${{env.EM_CACHE_FOLDER}}
key: ${{env.EM_VERSION}}-${{github.job}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v7
with:
version: ${{env.EM_VERSION}}
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
- name: Verify Emscripten setup
run: |
emcc -v
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no use_closure_compiler=yes
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,210 +0,0 @@
name: 🐧 Linux Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=linuxbsd verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
linux-editor-mono:
runs-on: "ubuntu-20.04"
name: Editor w/ Mono (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev xvfb \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-editor-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
xvfb-run ./bin/godot.x11.opt.tools.64.mono --generate-mono-glue modules/mono/glue || true
scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=yes
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
linux-template-mono:
runs-on: "ubuntu-20.04"
name: Template w/ Mono (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no module_mono_enabled=yes mono_glue=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
linux-editor-sanitizers:
runs-on: "ubuntu-20.04"
name: Editor and exported project with sanitizers (target=debug/release, tools=yes/no, use_ubsan=yes, use_asan=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm \
xvfb wget2 unzip
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-sanitizer-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=debug use_asan=yes use_ubsan=yes
ls -l bin/
# Download and test project to check leaks and invalid memory usage.
# CI has no audio device, so use the Dummy audio driver to avoid spurious error messages.
- name: Importing and running project project
run: |
wget2 https://github.com/qarmin/RegressionTestProject/archive/3.x.zip
unzip 3.x.zip
mv "RegressionTestProject-3.x" "test_project"
echo "----- Open editor to check for memory leaks -----"
DRI_PRIME=0 xvfb-run bin/godot.x11.tools.64s --audio-driver Dummy -e -q --path test_project 2>&1 | tee sanitizers_log.txt || true
misc/scripts/check_ci_log.py sanitizers_log.txt
echo "----- Run and test project -----"
DRI_PRIME=0 xvfb-run bin/godot.x11.tools.64s 30 --video-driver GLES3 --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,109 +0,0 @@
name: 🍎 macOS Builds
on: [push, pull_request]
# Global Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=osx verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
macos-editor:
runs-on: "macos-latest"
name: Editor (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: macos-editor-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons tools=yes target=release_debug
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
macos-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: macos-template-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

View File

@ -1,118 +0,0 @@
name: ☁ Server Builds
on: [push, pull_request]
# Global Cache Settings
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=server verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_LIMIT: 4096
jobs:
linux-editor:
runs-on: "ubuntu-20.04"
name: Linux Headless w/ Mono (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-headless-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons -j2 verbose=yes warnings=all werror=yes platform=server tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
linux-server:
runs-on: "ubuntu-20.04"
name: Linux Server w/ Mono (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
# Install all packages (except scons)
- name: Configure dependencies
run: |
sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
# Upload cache on completion and check it out now
- name: Load .scons_cache directory
id: linux-server-cache
uses: actions/cache@v2
with:
path: ${{github.workspace}}/.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
run: |
scons -j2 target=release tools=no module_mono_enabled=yes mono_glue=no

View File

@ -1,47 +0,0 @@
name: 📊 Static Checks
on: [push, pull_request]
jobs:
static-checks:
name: Static Checks (clang-format, black format, file format, documentation checks)
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f misc/ci/sources.list /etc/apt/sources.list
sudo apt-get update
- name: Install dependencies
run: |
sudo apt-get install -qq dos2unix recode clang-format-11
sudo update-alternatives --remove-all clang-format
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-11 100
sudo pip3 install black==20.8b1 pygments
- name: File formatting checks (file_format.sh)
run: |
bash ./misc/scripts/file_format.sh
- name: Style checks via clang-format (clang_format.sh)
run: |
bash ./misc/scripts/clang_format.sh
- name: Python style checks via black (black_format.sh)
run: |
bash ./misc/scripts/black_format.sh
- name: JavaScript style and documentation checks via ESLint and JSDoc
run: |
cd platform/javascript
npm ci
npm run lint
npm run docs -- -d dry-run
- name: Documentation checks
run: |
doc/tools/makerst.py --dry-run doc/classes modules

View File

@ -1,115 +0,0 @@
name: 🏁 Windows Builds
on: [push, pull_request]
# Global Settings
# SCONS_CACHE for windows must be set in the build environment
env:
GODOT_BASE_BRANCH: 3.x
SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
SCONS_CACHE_MSVC_CONFIG: true
SCONS_CACHE_LIMIT: 4096
jobs:
windows-editor:
# Windows 10 with latest image
runs-on: "windows-latest"
# Windows Editor - checkout with the plugin
name: Editor (target=release_debug, tools=yes)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
# Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache.
- name: Load .scons_cache directory
id: windows-editor-cache
uses: actions/cache@v2
with:
path: /.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform; best to keep self contained in it's own step)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons pywin32
python --version
scons --version
# We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
- name: Compilation
env:
SCONS_CACHE: /.scons_cache/
run: |
scons tools=yes target=release_debug
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14
windows-template:
runs-on: "windows-latest"
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v2
# Upload cache on completion and check it out now
# Editing this is pretty dangerous for Windows since it can break and needs to be properly tested with a fresh cache.
- name: Load .scons_cache directory
id: windows-template-cache
uses: RevoluPowered/cache@v2.1
with:
path: /.scons_cache/
key: ${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
restore-keys: |
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}
${{github.job}}-${{env.GODOT_BASE_BRANCH}}
# Use python 3.x release (works cross platform)
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
# Semantic version range syntax or exact version of a Python version
python-version: '3.x'
# Optional - x64 or x86 architecture, defaults to x64
architecture: 'x64'
# You can test your matrix by printing the current Python version
- name: Configuring Python packages
run: |
python -c "import sys; print(sys.version)"
python -m pip install scons pywin32
python --version
scons --version
- name: Compilation
env:
SCONS_CACHE: /.scons_cache/
run: |
scons target=release tools=no
ls -l bin/
- uses: actions/upload-artifact@v2
with:
name: ${{ github.job }}
path: bin/*
retention-days: 14

98
.gitignore vendored
View File

@ -1,6 +1,5 @@
# Godot auto generated files
*.gen.*
.import/
# Documentation generated by doxygen or from classes.xml
doc/_build/
@ -8,20 +7,16 @@ doc/_build/
# Javascript specific
*.bc
# CLion
cmake-build-debug
# Android specific
.gradle
local.properties
*.iml
.idea
.gradletasknamecache
project.properties
platform/android/java/app/libs/*
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/lib/.cxx/
platform/android/java/nativeSrcsConfigs/.cxx/
platform/android/java/assets
# General c++ generated files
*.lib
@ -34,8 +29,6 @@ platform/android/java/nativeSrcsConfigs/.cxx/
*.os
*.Plo
*.lo
# 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]
# Libs generated files
.deps/*
@ -48,43 +41,30 @@ gmon.out
*.swo
*.swp
# Qt project files
# QT project files
*.config
*.creator
*.creator.*
*.files
*.includes
*.cflags
*.cxxflags
# Code::Blocks files
*.cbp
*.layout
*.depend
# Eclipse CDT files
.cproject
.settings/
*.pydevproject
*.launch
# Geany/geany-plugins files
*.geany
.geanyprj
# Jetbrains IDEs
.idea/
# Misc
.DS_Store
__MACOSX
logs/
# for projects that use SCons for building: http://http://www.scons.org/
.sconf_temp
.sconsign*.dblite
.sconsign.dblite
*.pyc
# 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.
@ -96,9 +76,6 @@ logs/
*.sln
*.vcxproj*
# Custom SCons configuration override
/custom.py
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@ -111,9 +88,6 @@ bld/
*.debug
*.dSYM
# Visual Studio cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
@ -121,6 +95,9 @@ bld/
# Hints for improving IntelliSense, created together with VS project
cpp.hint
# Visualizers for the VS debugger
*.natvis
#NUNIT
*.VisualState.xml
TestResult.xml
@ -144,7 +121,6 @@ TestResult.xml
*.tlh
*.tmp
*.tmp_proj
*.bak
*.log
*.vspscc
*.vssscc
@ -152,7 +128,6 @@ TestResult.xml
*.pidb
*.svclog
*.scc
*.nib
# Chutzpah Test files
_Chutzpah*
@ -260,22 +235,15 @@ ClientBin/
*.pfx
*.publishsettings
node_modules/
__pycache__/
# KDE
.directory
# Kdevelop project files
#Kdevelop project files
*.kdev4
# Kate swap files
*.kate-swp
# Xcode
xcuserdata/
*.xcscmblueprint
*.xccheckout
*.xcodeproj/*
# xCode
xcuserdata
# RIA/Silverlight projects
Generated_Code/
@ -304,19 +272,11 @@ FakesAssemblies/
# =========================
# Windows image file caches
[Tt]humbs.db
[Tt]humbs.db:encryptable
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Windows stackdumps
*.stackdump
# Windows shortcuts
*.lnk
# Folder config file
[Dd]esktop.ini
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
@ -328,7 +288,6 @@ logo.h
TAGS
!TAGS/
tags
*.tags
!tags/
gtags.files
GTAGS
@ -347,24 +306,5 @@ platform/windows/godot_res.res
/.vs
/.vscode
# Visual Studio Code workspace file
*.code-workspace
# Scons construction environment dump
.scons_env.json
# Scons progress indicator
.scons_node_count
# ccls cache (https://github.com/MaskRay/ccls)
.ccls-cache/
# compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
compile_commands.json
# Cppcheck
*.cppcheck
# https://clangd.llvm.org/ cache folder
.clangd/
.cache/

126
.mailmap
View File

@ -1,133 +1,29 @@
Alexander Holland <alexander.holland@live.de>
Alexander Holland <alexander.holland@live.de> <alexander.holland@haw-hamburg.de>
Alexander Holland <alexander.holland@live.de> <AlexHolly>
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>
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>
Chris Bradfield <chris@kidscancode.org> <cb@scribe.net>
Clay John <claynjohn@gmail.com>
Clay John <claynjohn@gmail.com> <clayjohn@shaw.ca>
Dana Olson <dana@shineuponthee.com> <adolson@gmail.com>
dankan1890 <mewuidev2@gmail.com>
Daniel J. Ramirez <djrmuv@gmail.com>
Dominik 'dreamsComeTrue' Jasiński <dominikjasinski@o2.pl>
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>
Fabian <supagu@gmail.com>
Ferenc Arn <tagcup@yahoo.com>
Ferenc Arn <tagcup@yahoo.com> <tagcup@users.noreply.github.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com>
Fredia Huya-Kouadio <fhuyakou@gmail.com> <fhuya@google.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>
Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
HaSa1002 <johawitt@outlook.de>
Hein-Pieter van Braam-Stewart <hp@tmm.cx>
Hubert Jarosz <marqin.pl@gmail.com>
Hubert Jarosz <marqin.pl@gmail.com> <marqin.pl+git@gmail.com>
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>
J08nY <johny@neuromancer.sk> <jancar.jj@gmail.com>
J08nY <johny@neuromancer.sk> <J08nY@users.noreply.github.com>
Jakub Grzesik <kubecz3k@gmail.com>
Jérôme Gully <jerome.gully0@gmail.com>
JFonS <joan.fonssanchez@gmail.com>
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>
Kelly Thomas <kelly.thomas@hotmail.com.au>
Kongfa Waroros <gongpha@hotmail.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.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>
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>
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>
Michael Alexsander <michaelalexsander@protonmail.com>
Nathan Franke <natfra@pm.me> <nathanwfranke@gmail.com>
Nathan Lovato <nathan@gdquest.com>
Nathan Warden <nathan@nathanwarden.com> <nathanwardenlee@icloud.com>
Nils ANDRÉ-CHANG <nils@nilsand.re>
Nils ANDRÉ-CHANG <nils@nilsand.re> <nils.andre.chang@gmail.com>
Nuno Donato <nunodonato@gmail.com> <n.donato@estrelasustentavel.pt>
Pedro J. Estébanez <pedrojrulez@gmail.com> <RandomShaper@users.noreply.github.com>
Paul Batty <p_batty@hotmail.co.uk>
Paul Batty <p_batty@hotmail.co.uk> <Paulb23@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>
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>
Robin Hübner <profan@prfn.se> <robinhubner@gmail.com>
romulox_x <romulox_x@yahoo.com>
Ruslan Mustakov <r.mustakov@gmail.com> <ruslan.mustakov@xored.com>
Saracen <SaracenOne@gmail.com>
sheepandshepherd <sheepandshepherd@hotmail.com> <sheepandshepherd@users.noreply.github.com>
Swarnim Arun <swarnimarun11@gmail.com>
Theo Hallenius <redsymbzone@hotmail.com>
Thomas Herzog <therzog@mail.de>
Thomas Herzog <therzog@mail.de> <thomas.herzog@mail.com>
Thomas Herzog <therzog@mail.de> <thomas.herzog@simedis.com>
Tomasz Chabora <kobewi4e@gmail.com>
Twarit <wtwarit@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>
Zak Stam <zakscomputers@hotmail.com>
Zher Huei Lee <lee.zh.92@gmail.com>

94
.travis.yml Normal file
View File

@ -0,0 +1,94 @@
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
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

@ -25,178 +25,99 @@ name is available.
## Developers
(in alphabetical order, with over 10 commits excluding merges)
(in alphabetical order, with 10 commits or more excluding merges)
Aaron Franke (aaronfranke)
Alexander Holland (AlexHolly)
Alexey Khoroshavin (allkhor)
Alexey Velikiy (jonyrock)
Alket Rexhepi (alketii)
Andrea Catania (AndreaCatania)
Andrii Doroshenko (Xrayez)
Andreas Haas (Hinsbart)
Andy Moss (MillionOstrich)
Anish Bhobe (KidRigger)
Anton Yabchinskiy (a12n)
Anutrix
Aren Villanueva (kurikaesu)
Ariel Manzur (punto-)
Bastiaan Olij (BastiaanOlij)
Ben Brookshire (sheepandshepherd)
Benjamin Larsson (Nallebeorn)
Bernard Liebl (poke1024)
Błażej Szczygieł (zaps166)
Bojidar Marinov (bojidar-bg)
Bruno Lourenço (MadEqua)
bruvzg
Cameron Reikes (creikey)
Camille Mohr-Daurat (pouleyKetchoupp)
Błażej Szczygieł (zaps166)
Carl Olsson (not-surt)
Carter Anderson (cart)
Chris Bradfield (cbscribe)
Clay John (clayjohn)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
Daniel Rakos (aqnuep)
dankan1890
Danil Alexeev (dalexeev)
David Sichma (DavidSichma)
David Snopek (dsnopek)
Dharkael (lupoDharkael)
Dmitry Koteroff (Krakean)
Dominik Jasiński (dreamsComeTrue)
DualMatrix
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
Fabian Mathews (supagu)
Fabio Alessandrelli (Faless)
Ferenc Arn (tagcup)
Franklin Sobrinho (TheHX)
Fredia Huya-Kouadio (m4gr3d)
Geequlim
Gen (dbsGen)
George Marques (vnen)
Gerrit Großkopf (Grosskopf)
Gilles Roudiere (groud)
Gordon MacPherson (RevoluPowered)
Guilherme Felipe de C. G. da Silva (guilhermefelipecgs)
Hanif Bin Ariffin (hbina)
Haoyu Qiu (timothyqiu)
Hein-Pieter van Braam-Stewart (hpvb)
Hein-Pieter van Braam (hpvb)
Hiroshi Ogawa (hi-ogawa)
homer666
Hubert Jarosz (Marqin)
Hugo Locurcio (Calinou)
Ian Bishop (ianb96)
Ibrahn Sahir (ibrahn)
Ignacio Etcheverry (neikeq)
Ilaria Cislaghi (QbieShay)
Indah Sylvia (ISylvox)
J08nY
Jakub Grzesik (kubecz3k)
James Buck (jbuck3)
Jérôme Gully (Nutriz)
Jia Jun Chai (SkyLucilfer)
jmb462
Joan Fons Sanchez (JFonS)
Johannes Witt (HaSa1002)
Jérôme GULLY (Nutriz)
Johan Manuel (29jm)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
Julian Murgia (StraToN)
Justo Delgado (mrcdk)
Kelly Thomas (KellyThomas)
Kongfa Waroros (gongpha)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
lawnjelly
Leon Krause (leonkrause)
Liz Haas (27thLiz)
Lucien Menassol (Kanabenki)
Lyuma
m4nu3lf
Maganty Rushyendra (mrushyendra)
Marcel Admiraal (madmiraal)
Marcelo Fernandez (marcelofg55)
Leon Krause (eska014)
Marc Gilleron (Zylann)
Marcin Zawiejski (dragmz)
Marcus Brummer (mbrlabs)
Marcus (MCrafterzz)
Marcelo Fernandez (marcelofg55)
Mariano Javier Suligoy (MarianoGnu)
Mario Schlack (hurikhan)
Martin Capitanio (capnm)
Martin Liška (marxin)
Martin Sjursen (binbitten)
marynate
Masoud BH (masoudbh3)
Mateo Kuruk Miccino (kuruk-mm)
Matthew (skyace65)
Matthias Hölzl (hoelzl)
Max Hilbrunner (mhilbrunner)
merumelu
Michael Alexsander (YeldhamDev)
MichiRecRoom (LikeLakers2)
mrezai
muiroc
Nathan Franke (nathanfranke)
Nathan Lovato (NathanLovato)
Michael Alexsander Silva Dias (YeldhamDev)
Nathan Warden (NathanWarden)
Nils André-Chang (NilsIrl)
Noah Beard (TwistedTwigleg)
Nuno Donato (nunodonato)
Ovnuniarchos
Pascal Richter (ShyRed)
Patrick (firefly2442)
Paul Batty (Paulb23)
Paul Joannon (paulloz)
Paul Trojahn (ptrojahn)
Pawel Kowal (pkowal1982)
Pedro J. Estébanez (RandomShaper)
Pieter-Jan Briers (PJB3005)
Poommetee Ketson (Noshyaar)
Przemysław Gołąb (n-pigeon)
Rafał Mikrut (qarmin)
Ralf Hölzemer (rollenrolm)
Ramesh Ravone (RameshRavone)
raphael10241024
Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
Rhody Lugo (rraallvv)
Ricardo Subtil (Ev1lbl0w)
Roberto F. Arroyo (robfram)
Robin Hübner (profan)
romulox-x
Ruslan Mustakov (endragor)
Ryan Roden-Corrent (rrcore)
Saniko (sanikoyes)
santouits
SaracenOne
Sergey Minakov (naithar)
sersoong
Shiqing (kawa-yoiko)
Simon Wenner (swenner)
Stijn Hinlopen (hinlopen)
Swarnim Arun (minraws)
Thakee Nathees (ThakeeNathees)
Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
Timo Schwarzer (timoschwarzer)
Timo (toger5)
Tomasz Chabora (KoBeWi)
Twarit Waikar (IronicallySerious)
Vinzenz Feenstra (vinzenz)
박한얼 (volzhs)
V. Vamsi Krishna (vkbsb)
Vinzenz Feenstra (vinzenz)
Wilhem Barbier (nounoursheureux)
Will Nations (willnationsdev)
Wilson E. Alvarez (Rubonnek)
Xavier Cho (mysticfall)
yg2f (SuperUserNameMan)
Yuri Roubinsky (Chaosus)
Yuri Sizov (pycbouh)
Zak Stam (zaksnet)
Yuri Roubinski (Chaosus)
Zher Huei Lee (leezh)
ZuBsPaCe
박한얼 (volzhs)
bruvzg
est31
m4nu3lf
marynate
mrezai
rraallvv
romulox-x
sersoong
yg2f (SuperUserNameMan)

File diff suppressed because it is too large Load Diff

View File

@ -1,145 +1,80 @@
# How to contribute efficiently
## Table of contents
Sections covered in this file:
- [Reporting bugs](#reporting-bugs)
- [Proposing features or improvements](#proposing-features-or-improvements)
- [Contributing pull requests](#contributing-pull-requests)
- [Contributing to Godot's translation](#contributing-to-godots-translation)
- [Communicating with developers](#communicating-with-developers)
* [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)
**Please read the first section before reporting a bug!**
## Reporting bugs
## Reporting bugs or proposing features
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.
If you're reporting a new bug, you'll make our life simpler (and the
fix will come sooner) by following these guidelines:
Everything referred to hereafter as "bug" also applies for feature requests.
### Search first in the existing database
If you are reporting a new issue, you will make our life much simpler (and the
fix come much sooner) by following those guidelines:
Issues are often reported several times by various users. It's good practice to
**search first in the [issue tracker](https://github.com/godotengine/godot/issues)
before reporting your issue**. 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.
#### Search first in the existing database
### Specify the platform
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.
#### Specify the platform
Godot runs on a large variety of platforms and operating systems and devices.
**In your bug reports, please always specify:**
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)
- Operating system and version (e.g. Windows 10, macOS 10.15, Ubuntu 19.10)
- Godot version (e.g. 3.2, 3.1.2, or the Git commit hash if you're using a development branch)
For bugs that are likely OS-specific and/or graphics-related, please also specify:
- Device (CPU model including architecture, e.g. x86, x86_64, ARM, etc.)
- GPU model (and the driver version in use if you know it)
**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.
### Specify steps to reproduce
#### 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. If you're describing a procedure to follow
in the editor, don't hesitate to include screenshots.
keep them as minimal as possible.
Making your bug report easy to reproduce will make it easier for contributors
to fix the bug.
#### Provide a simple, example project
### Provide a simple, example project
Sometimes, unexpected behavior can happen in your project. In such case,
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
* 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 upload a minimal project** that isolates
and reproduces the issue. This is always the **best way for us to fix it**.
You can attach a ZIP file with the minimal project directly to the bug report,
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.
We recommend always attaching a minimal reproduction project, even if the issue
may seem simple to reproduce manually.
**If you've been asked by a maintainer to upload a minimal reproduction project,
you *must* do so within 7 days.** Otherwise, your bug report will be closed as
it'll be considered too difficult to diagnose.
Now that you've read the guidelines, click the link below to create a
bug report:
- **[Report a bug](https://github.com/godotengine/godot/issues/new?assignees=&labels=&template=bug_report.md&title=)**
## Proposing features or improvements
**Since August 2019, the main issue tracker no longer accepts feature proposals.**
Instead, head to the [Godot Proposals repository](https://github.com/godotengine/godot-proposals)
and follow the instructions in the README file. High-quality feature proposals
are more likely to be well-received by the maintainers and community, so do
your best :)
See [this article](https://godotengine.org/article/introducing-godot-proposals-repository)
for detailed rationale on this change.
## 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.
[This blog post](https://godotengine.org/article/will-your-contribution-be-merged-heres-how-tell)
outlines the process used by core developers when assessing PRs. We strongly
recommend that you have a look at it to know what's important to take into
account for a PR to be considered for merging.
#### 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/development/cpp/)
for an introduction to developing on Godot.
The [Contributing docs](https://docs.godotengine.org/en/latest/community/contributing/index.html)
also have important information on the PR workflow and the code style we use.
### Document your changes
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 the documentation template](https://docs.godotengine.org/en/latest/community/contributing/updating_the_class_reference.html#updating-the-documentation-template)
using your compiled binary, then fill in the descriptions.
Follow the style guide described in the
[Docs writing guidelines](https://docs.godotengine.org/en/latest/community/contributing/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 look at `git blame`.
### Be nice to the Git history
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.
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
@ -151,31 +86,30 @@ 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).
This [Git style guide](https://github.com/agis-/git-style-guide) has some
good practices to have in mind.
This git style guide has some good practices to have in mind:
[Git Style Guide](https://github.com/agis-/git-style-guide)
See our [PR workflow](https://docs.godotengine.org/en/latest/community/contributing/pr_workflow.html)
documentation for tips on using Git, amending commits and rebasing branches.
#### 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
`shortlog` changelog (one line per commit, so no description shown) or in the
GitHub interface unless you click the "expand" button. As the name says, try to
keep that first line under 72 characters. 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
you should probably split your changes in several commits :)
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 :)
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
@ -189,9 +123,9 @@ 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.
## Contributing to Godot's translation
@ -200,10 +134,6 @@ 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.
You can also help translate [Godot's
documentation](https://hosted.weblate.org/projects/godot-engine/godot-docs/)
on Weblate.
## Communicating with developers
The Godot Engine community has [many communication
@ -212,23 +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:
- [Godot Contributors Chat](https://chat.godotengine.org): You will
find most core developers there, so it's the go-to platform for direct chat
- [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.
- [Bug tracker](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 -
many developers watch the repository and will get a 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.
- [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.
- [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.
Thanks for your interest in contributing!
Thanks!
The Godot development team
The Godot development team

File diff suppressed because it is too large Load Diff

840
DONORS.md
View File

@ -12,727 +12,245 @@ generous deed immortalized in the next stable release of Godot Engine.
## Platinum sponsors
Gamblify <https://www.gamblify.com>
Heroic Labs <https://heroiclabs.com>
Spiffcode <http://www.spiffcode.com>
Enjin Coin <https://enjincoin.io>
## Gold sponsors
None currently, become one! <https://godotengine.org/donate>
## Silver sponsors
ASIFA-Hollywood <https://www.asifa-hollywood.org>
Moonwards <https://www.moonwards.com>
Zenva Academy <https://academy.zenva.com>
## Bronze sponsors
Brandon Lamb
Garry Newman
Gordon MacPherson
Hunter Dickson
Kyle Szklenski
Gamblify <https://www.gamblify.com>
GameDev.TV <https://www.gamedev.tv>
Skirmish <https://skirmish.io>
## Mini sponsors
AD Ford
Alejandro Saucedo
alex brown
Andrew Dunai
anti666
Ben Nolan
blurp
CD
Christian Baune
Christoffer Sundbom
Christopher Montesano
Darrin Massena
David Mydlarz
Digital Grows
Dov Zimring
Edward Flick
Florian Neumann
Gamechuck
GameDev.net
Andreas
Brandon Lamb
Christian Uldall Pedersen
Christopher Igoe
Christoph Woinke
codetrotter
E Hewert
Hein-Pieter van Braam
Jacob McKenney
Jasper Brooks
Javary Co.
Jeffery Chiu
John G Gentzel
Jonah Stich
Justin Arnold
Kamil Brzezinski
Marcel Kräml
Jamal Alyafei
Jay Sistar
Matthieu Huvé
Maxim Karsten
Mike King
Nathan Warden
Neal Gompa (Conan Kudo)
Patrick Horn
Patrick Schmidt
Péter Magyar
Rami
Ronnie Cheng
Pascal Julien
Ruslan Mustakov
Sébastien Manin
Slobodan Milnovic
Stephan Lanfermann
Steve
Thomas Krampl
Tristan Pemble
Violin Iliev
Xwdit
Stoney Meyerhoeffer
Thomas Mathews
## Gold donors
Acheron
albinaask
Alvaro A Baena R
Asher Glick
Barugon
Carlo Cabanilla
Chris Goddard
Christopher Case
Daniel James
David Gehrig
David Snopek
Don B
Ed Morley
Ellen Poe
Florian Rämisch
Forge
Gamejunkey
Hoojib
Jakub Grzesik
Javier Roman
Joan Fons
Johnny IV Young
Jon Woodward
Karl Werf
Klavdij Voncina
kuku
Lex Steers
Luke
Maciej Pendolski
3Dexplorer
Alexander Otto
Asdf
cheese65536
Jake Bo
Manuele Finocchiaro
Markus Wiesner
Mason Bially
Matthew Hillier
Michael
m kaersten
Monster Vial
Officine Pixel S.n.c.
Rene
Retro Village
Rob Messick
Roland Fredenhagen
Ronan Zeegers
Sandro Jenny
Sarksus
Scott B
Sean
Sergey
Sofox
Taylor Ritenour
Tom Langwaldt
Tricky Fat Cat
tukon
Vitaliy Sapronenko
William Wold
xagonist
Xeno Coliseum
Rémi Verschelde
Zaven Muradyan
Adam Nakonieczny
Adrian Adamiak
Alexander J Maynard
Alex de la Mare
Alexey Dyadchenko
Alex Khayrullin
alice gambrell
Andreas Funke
Andrew Cunningham
Antanas Paskauskas
Antoni Batchelli
Arisaka Mayuki
Arthur S. Muszynski
Ben Botwin
Brandon Hawkinson
Caleb Sizemore
Can Eris
Charlie Whitfield
Chase Taranto
Chelsea Hash
Chris Petrich
Allen Schade
Andreas Schüle
Austen McRae
Benjamin Botwin
Bernhard Liebl
Johannes Wuensch
Josep G. Camarasa
Kris Michael
Libre-Dépanne
Mike King
Ranoller
Rob Messick
Svenne Krap
Timothy Hagberg
BanjoNode2D
Brandon
Chris Serino
Christian Leth Jeppesen
Craig Ostrin
Conrad Curry
Craig Smith
Cristopher
D
dan didenko
Darrian Little
Dennis Belfrage
Dev To be curious
Digital Denizen
Dimitri Nüscheler
Donn Eddy
Easypete
Edgar Sun
Eric Brand
Eugenio Hugo Salgüero Jáñez
EXUREI
flesk
F S
Gabrielius Vaiškūnas
Gary Hulst
gavlig
General Chicken
GGGames.org
David Churchill
Dean Harmon
Dexter Miguel
Garrett Dockins
Guilherme Felipe de C. G. da Silva
Harvey Fong
Heath Hayes
Horváth Péter
Hu Hund
Jake Burga
James Couzens
Jared
Jared White
Jesús Chicharro
Joel Fivat
Joel Höglund
Johnathan Kupferer
Jose Malheiro
Jose Manuel Muñoz Perez
Joseph Crane
Joshie Sparks
Joshua Flores
Joshua Lesperance
Juan T Chen
Juan Velandia
Judd
Julian Todd
Juraj Móza
JUSTIN CARROLL
Justo Delgado Baudí
Kelteseth
kickmaniac
kinfox
Kos
Lachie
Lain Ballard
Laszlo Kiss
leetNightshade
Leo Fidel R Liban
Liam Smyth
Luc-Frédéric Langis
Łukasz Nowak
MadScientistCarl
Marcelo Dornbusch Lopes
Marcus Dobler
Marcus Richter
Marek Belski
Mark Barrett
Martin Eigel
Martin Kotz
Martin Soucek
Matt Eunson
Matt Greene
Matthias Toepp
medecau
Michael
Michael Dürwald
Michael Policastro
MightyPossum
MikadoSC
MuffinManKen
nate etan
Nick Abousselam
Nicole Barovic
Oliver Dick
Oscar Campos
Patrick Ting
Paul Hocker
Paul Von Zimmerman
Pavel Kotlyar
Pedro Silva
Pete Goodwin
Petr Malac
PhaineOfCatz
pl
Raymond Harris
Raz A
Rene Tailleur
Rhodochrone
Ricardo Alcantara
Robert Larnach
Harman Bains
Henrique Alves
Karsten Bock
Laurence Bannister
Rami
Robert Willes
Rob McInroy
Rocknight Studios
Rodrigo Favarete
Ronnie Ashlock
Ronny Mühle
Ryan Scott
Ryszard Sommefeldt
Samuel Judd
Sean Morgan
Sebastian Hutter
Sébastien
Serban Serafimescu
Sergey Fonaryov
Sergey Minakov
Shishir Tandale
SKison
Song Junwoo
spacechase0
Stephan Hennion
Steven Landow
Stoned Xander
Sven F.
Robin Arys
ScottMakesGames
Testus Maximus
Thomas Bjarnelöf
Thomas Kurz
Tim Howard
Tobias Bocanegra
Todd Smith
Turntsnaco
tweaklab
Valryia
Vincent Cloutier
Vlad Ceru Opran
VoidPointer
voxelv
Wojciech Chojnacki
xzibiting
Yuancheng Zhang
Zhou Tuizhi
Zie Weaver
Zoran Kukulj
Xavier Tan
Zaq Poi
Alexey Dyadchenko
Amanda Haldy
Arnaud Verstuyf
Chris Brown
Chris Wilson
Cody Parker
D
Daniel Eliasinski
Eric Monson
flesk
François Cantin
G Barnes
GGGames.org
Heath Hayes
Jeppe Zapp
Jeremi Biernacki
joe513
Jordan M Lucas
Juraj Móza
Justin Arnold
Justo Delgado Baudí
Leandro Voltolino
Lisandro Lorea
Markus Wiesner
Marty Plumbo
Marvin
Nick Nikitin
Pablo Cholaky
Patrick Schnorbus
Pete Goodwin
Phyronnaz
Ted
Travis Womack
Trent McPheron
## Silver donors
1D_Inc
Abraham Haskins
Adam
Adam Brown
Adam Brunnmeier
Adam Carr
Adam Long
Adam McCurdy
Adam N Webber
Adam Carr
Adam Smeltzer
Adam Szymański
Adisibio
Agar3s - Giovanny Beltrán
Agustinus Arya
Ahmet Kalyoncu
Aidan O'Flannagain
Aki Mimoto
Alan Beauchamp
Alberto Vilches
Albin Jonasson Svärdsby
Alder Stefano
AleMax
Alessandro Senese
Alexander Erlemann
Alexander Ryndin
Alexander Walter (SilvanuZ)
Alexandre Beaudoin
alex clavelle
Alex (Well Done Games)
Allan Davis
Allen Schade
Anders Marstein Kruke
Andreas Krampitz
Andre Stackhouse
andrew james morris
Andrew Mansuetti
Álvaro Domínguez López
Andrea Badii
Andrew Thomas
Ano Nim
Anthony Avina
Anton Bouwer
aomimezura11
AP Condomines
Arch Toasty
Anthony Bongiovanni
Arda Erol
Armin Preiml
Arseniy M
Ashley Claymore
Astier Mickael
Aubrey Falconer
AzulCrescent
Balázs Batári
Bartosz Bielecki
Arthur S. Muszynski
Avencherus
Bastian Böhm
Benedikt
Benjamin Beshara
Ben Vercammen
Bernd Jänichen
Bernhard Werner
Bjarne Voigtländer
Black Block
blackjacksike
Blair Allen
Bobby CC Wong
Borkzilla
Boyd Trolinger
Bram
brian
Brian Klein
Brodie Fairhall
Bronson Zgeb
Bùi Việt Thành
Burney Waring
bwhirt
Caleb Gartner
Cameron Meyer
Carlos Cejudo
Carl van der Geest
Bryan Crow
Bryanna M
Bryan Stevenson
Carwyn Edwards
Cas Brugman
Cassidy James
Cédric Givord
Chad Steadman
Charles Alston
Casey Foote
Chris Chapin
Chris Langford
Christian Clavet
Christian Mauduit
Christian Baune
Christian Winter
Christoffer Dahlblom
Christophe Gagnier
Christopher Chin
Christopher Schmitt
Chris Truebe
Clay Heaton
Cody Parker
Conall O
Craig Post
CzechBlueBear
Daniel Cheney
Daniel Johnson
DanielMaximiano
Daren Scot Wilson
Dave Walker
David Bôle
Collin Shooltz
Daniel Egger
Daniel Kaplan
Daniel Langegger
Daniel Mircea
David Cravens
David May
David Maziarka
David Woodard
deadwithbread
Devin Carraway
Diego Pereira
Dmitry Fisher
Dmytro Korchynskyi
Dominik Wetzel
Douglas Plumley
Dragontrapper
Dr Ewan Murray
Dr.Raccoon
Duobix
Duodecimal
DurrDiss
Eduardo Teixeira
Edward Herbert
Edward Swartz
Egon Elbre
Elgenzay
Elias Nykrem
Ephemeral
Eric Stokes
Eric Walkingshaw
Eric Williams
Erkki Seppälä
Evan Rose
Faisal Alkubaisi
Fancy Ants Studios
fby
Fekinox
Felix Bohmann
Flaredown
Forty Doubleu
Francois Holland
Frank
Game Endeavor
Gareth Knowles
Gary Thomas
George Marques
georgios katsanakis
GFizz
Greg Lincoln
Greg Olson
Greyson Richey
Grid
Guillaume Audirac
Guillaume Pham Ngoc
Eric Martini
Fabian Becker
fengjiongmax
Francesco Lisi
G3Dev sàrl
Geequlim
Gerrit Großkopf
Gerrit Procee
Gilberto K. Otubo
Guldoman
Gustavo Loureiro dos Reis
Hal A
helija
HeartBeast
Heribert Hirth
Hunter Jones
Ian Williams
Iiari
IndustrialRobot
Ivan Nikolaev
iveks
Jackson Harmer
Jacob
Jaguar
ialex32x
Jaime Ruiz-Borau Vizárraga
Jake D
Jake Huxell
Jako Danar
James
James A F Manley
James Quincy
James Thomas
Jamie Massey
Jan Vetulani
JARKKO PARVIAINEN
Jason Bolton
Jason Uechi
Jed Rose
Jeff Hungerford
Jennifer Graves
Jesse Dubay
Jhon Adams
Joe Klemmer
John Gabriel
Jonah Branch
Jonas
Jonas Bernemann
Jonas Rudlang
Joel Fivat
Johannes du Randt
Jonas Yamazaki
Jonatan R
Jonathan G
Jon Bonazza
Jon Oakes
Jon Sully
Jordy Goodridge
Jorge Antunes
Jorge Araya Navarro
Jose C. Rubio
Joseph Catrambone
Josep Sanchez
Josh Taylor
Joshua Heidrich
jromkjrom
Juanfran
Juan Uys
Jueast
Jonathan Martin
Jonathan Nieto
Jonathon
Josh 'Cheeseness' Bush
Juan Negrier
Judd
JuDelCo
Julian Murgia
June Little
Justin Hamilton
Justin Oaksford
Justin Spedding
Justin W. Flory
KaDokta
Kalin
Keedong Park
Keinan Powers
Keith Bradner
Kenji Kawabata
Ken Minardo
Kenneth Lee
Kent Jofur
Ketafuki
Kiri Jolly
Kjetil Haugland
Konstantin Goncharov
Kridsada Thanabulpong
Kristian Nygaard Jensen
KsyTek Games
kycho
Kyle Jacobs
Kyuppin
Lasse le Dous
Laurent CHEA
Laurent Tréguier
Laxman Pradhan
LEMMiNO
Leonardo Dimano
Lin Chear
Justin Luk
KC Chan
Kevin Boyer
Kevin Kamper Meejach Petersen
Klavdij Voncina
Lars pfeffer
Linus Lind Lundgren
Luigi Renna
Luis Gaemperle
Luis M
LunaticInAHat
Major Haul
makoto asano
Malcolm
Marco Lardelli
Mark Jad
Mark Malone
Markus Martin
Markus Michael Egger
Martin FIbik
Martin Holas
Martin Trbola
Marvin
Mathieu
Matt Edwards
Matthew Booe
Matt Sylvia
Max Fiedler
Maxime Blade
Maxwell
Megasploot
Melissa Mears
Merlyn Morgan-Graham
mewin
Michael
Michael Bruce-Lockhart
Michael Haney
Michał Skwarek
MidoriBunn 'tis BS
Mikayla
Mike
Mike Birkhead
Mike Copley
Mike Cunningham
Mitchell J. Wagner
MJacred
Molinghu
Molly Jameson
MrAZIE
Nathan Fish
Nathaniel
magodev
Martin Eigel
Martin Novák
Matthew Fitzpatrick
Matthias Hölzl
Max R.R. Collada
memoryruins
mhilbrunner
Michael Dürwald
Michael Gringauz
Michael Labbe
Mikael Olsson
MoM
monokrome
Moritz Laass
nee
neighty
Neil Blakey-Milner
Neil Wang
Nerdforge
Nerdyninja
Nicholas
Nick Macholl
Niclas Eriksen
Nicolas Goll-Perrier
Nicolas Rosset
Nicolas SAN AGUSTIN
Nima Farid
NZ
oceoh
Okatima
OKV
Oleg Reva
Oleksandr Kryvonos
Omar Delarosa
Oriol Muñoz Princep
Oscar Domingo
Patrick Brock
Nik Lee
Niko Leopold
nivardus
Noi Sek
Oleg Tyshchenko
Pablo Seibelt
Pan Ip
Pat LaBine
Patrick Nafarrete
Paul Gieske
Patric Vormstein
Paul Mason
Paweł Kowal
Paweł Łyczkowski
Peter Höglund
Peter Richmond
Petrus Prinsloo
Philip Cohoe
Philip Ludington (MrPhil)
Pierre Caye
Piotr Góral
Point08
Preethi Vaidyanathan
pwab
Rad Cat
Rafa Laguna
Raffaele Aramo
Rami Hanano
RAMupgrade
Remi Rampin
Rémi Verschelde
Reneator
Riccardo Marini
Richard Ivánek
Riley
Robert Farr (Larington)
Rob Ruana
Pedro Luz
Pierre-Igor Berthet
Pietro Vertechi
Piotr Kaczmarski
Richman Stewart
Rodolfo Baeza
Roger Burgess
Roger Smith
Roland Rząsa
Roman Tinkov
Ronald Ho Hip (CrimsonZA)
Ronan
Ross Squires
Ryan Groom
Sam Caulfield
Sam Edson
Samuele Zolfanelli
scapegoat57
Sasori Olkof
Scott D. Yelich
Scott Longley
Sean Lynch
Sebastian Michailidis
SeongWan Kim
Sergey
Sergiy Onenko
Shane
Shane Sicienski
Shane Spoor
Siim Raidma
simdee
Simon Jonas Larsen
Simon Schoenenberger
Simon Wenner
Skalli
smbe19
smo1704
soft circles
Squirrel
Stéphane Roussel
Steve Cloete
summerblind
Sung soo Choi
Svenne Krap
tadashi endo
tannhauser_gate
Tarch
Terry
Theodore Lindsey
TheVoiceInMyHead
thomas
Thomas Bechtold
Thomas Detoy
Thomas Horwath
Tim Drumheller
Tim Erskine
Tim Gleason
Timothy B. MacDonald
TMoney
Tobias Bradtke
Tom Coxon
Toni Duran
Tony Zhao
Torgeir Lilleskog
Torsten Crass
toupeira
Travis O'Brien
Trent Skinner
tril zerobyte
Triumph263 .
Troy Bonneau
Tryggve Sollid
Turgut Temucin
Tyler Compton
Sootstone
Theo Cranmore
Thibault Barbaroux
Thomas Bell
Thomas Herzog & Xananax
Tom Larrow
Tyler Stafos
UltyX
Uther
Vaughan Ling
Victor
Viktor Ismagilov
Vi Watch
Vladimir Savin
Vladislav Smirnov
Vytenis Narušis
waka nya
Wayne Haak
werner mendizabal
Wiley Thompson
William Edwards
William F Siqueira
William Hogben
Wyatt Goodin
x1212
xenomat
Yegor Smirnov
Zak Stephens
Эльдар Будагов
蕭惟允
Victor Holt
Wout Standaert
Yu He
## Bronze donors

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) 2007-2021 Juan Linietsky, Ariel Manzur.
Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).
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

View File

@ -1,5 +1,3 @@
Godot Engine Logo
Copyright (c) 2017 Andrea Calabró
This work is licensed under a Creative Commons Attribution 4.0 International
License (CC-BY-4.0 International) <https://creativecommons.org/licenses/by/4.0/>.
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,78 +1,69 @@
# Godot Engine
[![Godot Engine logo](/logo.png)](https://godotengine.org)
<p align="center">
<a href="https://godotengine.org">
<img src="logo.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, 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, macOS,
Windows), mobile platforms (Android, iOS), as well as Web-based platforms
(HTML5) 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.
#### 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 [Software Freedom Conservancy](https://sfconservancy.org/)
expectations. It is supported by the Software Freedom Conservancy
not-for-profit.
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 Godot Engine](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 homepage](https://godotengine.org/download).
### Compiling from source
#### Compiling from source
[See the official docs](https://docs.godotengine.org/en/latest/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).
To get in touch with the engine developers, the best way 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).
### Documentation and demos
## Documentation and demos
The official documentation is hosted on [ReadTheDocs](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.
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.
[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
[![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)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/godotengine/godot)](https://www.tickgit.com/browse?repo=github.com/godotengine/godot)

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +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 itervalues(d):
return d.itervalues()
def escape_string(s):
if isinstance(s, unicode):
s = s.encode("ascii")
result = ""
s = s.encode('ascii')
result = ''
for c in s:
if not (32 <= ord(c) < 127) or c in ("\\", '"'):
result += "\\%03o" % ord(c)
if not (32 <= ord(c) < 127) or c in ('\\', '"'):
result += '\\%03o' % ord(c)
else:
result += c
return result
def qualname(obj):
# Not properly equivalent to __qualname__ in py3, but it doesn't matter.
return obj.__name__
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 itervalues(d):
return iter(d.values())
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))
rev_result.append('\\%03o' % low)
rev_result.append('\\%03o' % c)
return ''.join(reversed(rev_result))
def escape_string(s):
result = ""
result = ''
if isinstance(s, str):
s = s.encode("utf-8")
s = s.encode('utf-8')
for c in s:
if not (32 <= c < 127) or c in (ord("\\"), ord('"')):
if not(32 <= c < 127) or c in (ord('\\'), ord('"')):
result += charcode_to_c_escapes(c)
else:
result += chr(c)
return result
def qualname(obj):
return obj.__qualname__

View File

@ -1,187 +1,110 @@
#!/usr/bin/env python
Import("env")
import core_builders
import make_binders
from platform_methods import run_in_subprocess
Import('env')
env.core_sources = []
# Generate global defaults
gd_call = ""
gd_inc = ""
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"
gd_cpp = '#include "project_settings.h"\n'
gd_cpp += gd_inc
gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
f = open("global_defaults.gen.cpp", "w")
f.write(gd_cpp)
f.close()
# Generate AES256 script encryption key
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:
if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
e = os.environ["SCRIPT_AES256_ENCRYPTION_KEY"]
txt = ""
ec_valid = True
if len(e) != 64:
if (len(e) != 64):
ec_valid = False
else:
for i in range(len(e) >> 1):
if i > 0:
if (i > 0):
txt += ","
txts = "0x" + e[i * 2 : i * 2 + 2]
txts = "0x" + e[i * 2:i * 2 + 2]
try:
int(txts, 16)
except Exception:
except:
ec_valid = False
txt += txts
if not ec_valid:
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)
# NOTE: It is safe to generate this file here, since this is still executed serially
with open("script_encryption_key.gen.cpp", "w") as f:
f.write('#include "core/project_settings.h"\nuint8_t script_encryption_key[32]={' + txt + "};\n")
f = open("script_encryption_key.gen.cpp", "w")
f.write("#include \"project_settings.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n")
f.close()
# Add required thirdparty code.
env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()
# Misc thirdparty code: header paths are hardcoded, we don't need to append
# 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_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"fastlz.c",
"smaz.c",
# C++ sources
"hq2x.cpp",
"pcg.cpp",
"triangulator.cpp",
"clipper.cpp",
thirdparty_dir = "#thirdparty/misc/"
thirdparty_sources = [
# C sources
"base64.c",
"fastlz.c",
"sha256.c",
"smaz.c",
# C++ sources
"aes256.cpp",
"hq2x.cpp",
"md5.cpp",
"pcg.cpp",
"triangulator.cpp",
]
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_misc_sources)
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env.add_source_files(env.core_sources, thirdparty_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",
"infback.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["target"] == "debug":
env_thirdparty.Append(CPPDEFINES=["ZLIB_DEBUG"])
env_thirdparty.add_source_files(env.core_sources, thirdparty_zlib_sources)
# Minizip library, could be unbundled in theory
# 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",
"ioapi.c",
"unzip.c",
"zip.c",
]
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env_thirdparty.add_source_files(env.core_sources, thirdparty_minizip_sources)
env.add_source_files(env.core_sources, 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",
]
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(env.core_sources, thirdparty_zstd_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")
# 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",
run_in_subprocess(core_builders.make_certs_header),
)
# Make binders
env.CommandNoCache(
["method_bind.gen.inc", "method_bind_ext.gen.inc", "method_bind_free_func.gen.inc"],
"make_binders.py",
run_in_subprocess(make_binders.run),
)
import make_binders
env.Command(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run)
# Authors
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", run_in_subprocess(core_builders.make_authors_header))
# Donors
env.Depends("#core/donors.gen.h", "../DONORS.md")
env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", run_in_subprocess(core_builders.make_donors_header))
# License
env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.CommandNoCache(
"#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(core_builders.make_license_header)
)
# Chain load SCsubs
SConscript("os/SCsub")
SConscript("math/SCsub")
SConscript("crypto/SCsub")
SConscript("io/SCsub")
SConscript("bind/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])
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

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,13 +30,13 @@
#include "array.h"
#include "core/hashfuncs.h"
#include "core/object.h"
#include "core/variant.h"
#include "core/vector.h"
#include "hashfuncs.h"
#include "object.h"
#include "variant.h"
#include "vector.h"
struct ArrayPrivate {
class ArrayPrivate {
public:
SafeRefCount refcount;
Vector<Variant> array;
};
@ -72,7 +72,7 @@ void Array::_unref() const {
Variant &Array::operator[](int p_idx) {
return _p->array.write[p_idx];
return _p->array[p_idx];
}
const Variant &Array::operator[](int p_idx) const {
@ -117,11 +117,6 @@ void Array::push_back(const Variant &p_value) {
_p->array.push_back(p_value);
}
void Array::append_array(const Array &p_array) {
_p->array.append_array(p_array._p->array);
}
Error Array::resize(int p_new_size) {
return _p->array.resize(p_new_size);
@ -138,12 +133,12 @@ void Array::erase(const Variant &p_value) {
}
Variant Array::front() const {
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
return operator[](0);
}
Variant Array::back() const {
ERR_FAIL_COND_V_MSG(_p->array.size() == 0, Variant(), "Can't take value from empty array.");
ERR_FAIL_COND_V(_p->array.size() == 0, Variant());
return operator[](_p->array.size() - 1);
}
@ -170,8 +165,8 @@ int Array::rfind(const Variant &p_value, int p_from) const {
if (_p->array[i] == p_value) {
return i;
}
}
};
};
return -1;
}
@ -191,8 +186,8 @@ int Array::count(const Variant &p_value) const {
if (_p->array[i] == p_value) {
amount++;
}
}
};
};
return amount;
}
@ -216,67 +211,17 @@ const Variant &Array::get(int p_idx) const {
return operator[](p_idx);
}
Array Array::duplicate(bool p_deep) const {
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] = p_deep ? get(i).duplicate(p_deep) : get(i);
new_arr[i] = get(i);
}
return new_arr;
}
int Array::_clamp_slice_index(int p_index) const {
int arr_size = size();
int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
if (fixed_index < 0) {
fixed_index = arr_size + fixed_index;
}
return fixed_index;
}
Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
Array new_arr;
ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
if (empty()) // Don't try to slice empty arrays.
return new_arr;
if (p_step > 0) {
if (p_begin >= size() || p_end < -size())
return new_arr;
} else { // p_step < 0
if (p_begin < -size() || p_end >= size())
return new_arr;
}
int begin = _clamp_slice_index(p_begin);
int end = _clamp_slice_index(p_end);
int new_arr_size = MAX(((end - begin + p_step) / p_step), 0);
new_arr.resize(new_arr_size);
if (p_step > 0) {
int dest_idx = 0;
for (int idx = begin; idx <= end; idx += p_step) {
ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
} else { // p_step < 0
int dest_idx = 0;
for (int idx = begin; idx >= end; idx += p_step) {
ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
}
return new_arr;
}
struct _ArrayVariantSort {
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
@ -314,27 +259,13 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
ERR_FAIL_NULL_V(p_obj, *this);
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
SortArray<Variant, _ArrayVariantSortCustom> avs;
avs.compare.obj = p_obj;
avs.compare.func = p_function;
avs.sort(_p->array.ptrw(), _p->array.size());
return *this;
}
void Array::shuffle() {
const int n = _p->array.size();
if (n < 2)
return;
Variant *data = _p->array.ptrw();
for (int i = n - 1; i >= 1; i--) {
const int j = Math::rand() % (i + 1);
const Variant tmp = data[j];
data[j] = data[i];
data[i] = tmp;
}
}
template <typename Less>
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
@ -410,62 +341,11 @@ Variant Array::pop_front() {
return Variant();
}
Variant Array::min() const {
Variant minval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
minval = get(i);
} else {
bool valid;
Variant ret;
Variant test = get(i);
Variant::evaluate(Variant::OP_LESS, test, minval, ret, valid);
if (!valid) {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
//is less
minval = test;
}
}
}
return minval;
}
Variant Array::max() const {
Variant maxval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
maxval = get(i);
} else {
bool valid;
Variant ret;
Variant test = get(i);
Variant::evaluate(Variant::OP_GREATER, test, maxval, ret, valid);
if (!valid) {
return Variant(); //not a valid comparison
}
if (bool(ret)) {
//is less
maxval = test;
}
}
}
return maxval;
}
const void *Array::id() const {
return _p->array.ptr();
}
Array::Array(const Array &p_from) {
_p = NULL;
_ref(p_from);
}
Array::Array() {
_p = memnew(ArrayPrivate);

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,8 +31,7 @@
#ifndef ARRAY_H
#define ARRAY_H
#include "core/typedefs.h"
#include "typedefs.h"
class Variant;
class ArrayPrivate;
class Object;
@ -44,8 +43,6 @@ class Array {
void _ref(const Array &p_from) const;
void _unref() const;
inline int _clamp_slice_index(int p_index) const;
public:
Variant &operator[](int p_idx);
const Variant &operator[](int p_idx) const;
@ -64,7 +61,6 @@ public:
void push_back(const Variant &p_value);
_FORCE_INLINE_ void append(const Variant &p_value) { push_back(p_value); } //for python compatibility
void append_array(const Array &p_array);
Error resize(int p_new_size);
void insert(int p_pos, const Variant &p_value);
@ -75,7 +71,6 @@ public:
Array &sort();
Array &sort_custom(Object *p_obj, const StringName &p_function);
void shuffle();
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();
@ -92,14 +87,7 @@ public:
Variant pop_back();
Variant pop_front();
Array duplicate(bool p_deep = false) const;
Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const;
Variant min() const;
Variant max() const;
const void *id() const;
Array duplicate() const;
Array(const Array &p_from);
Array();

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,16 +31,15 @@
#ifndef CORE_BIND_H
#define CORE_BIND_H
#include "core/image.h"
#include "core/io/compression.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "core/safe_refcount.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);
@ -56,11 +55,7 @@ public:
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);
#ifndef DISABLE_DEPRECATED
bool has(const String &p_path);
#endif // DISABLE_DEPRECATED
bool has_cached(const String &p_path);
bool exists(const String &p_path, const String &p_type_hint = "");
_ResourceLoader();
};
@ -81,12 +76,11 @@ public:
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 String &p_path, const RES &p_resource, SaverFlags p_flags);
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags);
PoolVector<String> get_recognized_extensions(const RES &p_resource);
_ResourceSaver();
@ -104,17 +98,12 @@ protected:
static _OS *singleton;
public:
enum VideoDriver {
VIDEO_DRIVER_GLES3,
VIDEO_DRIVER_GLES2,
};
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.
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 {
@ -128,8 +117,8 @@ public:
};
enum Month {
// Start at 1 to follow Windows SYSTEMTIME structure
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
/// 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,
@ -144,22 +133,8 @@ public:
MONTH_DECEMBER
};
enum HandleType {
APPLICATION_HANDLE, // HINSTANCE, NSApplication*, UIApplication*, JNIEnv* ...
DISPLAY_HANDLE, // X11::Display* ...
WINDOW_HANDLE, // HWND, X11::Window*, NSWindow*, UIWindow*, Android activity ...
WINDOW_VIEW, // HDC, NSView*, UIView*, Android surface ...
OPENGL_CONTEXT, // HGLRC, X11::GLXContext, NSOpenGLContext*, EGLContext* ...
};
void global_menu_add_item(const String &p_menu, const String &p_label, const Variant &p_signal, const Variant &p_meta);
void global_menu_add_separator(const String &p_menu);
void global_menu_remove_item(const String &p_menu, int p_idx);
void global_menu_clear(const String &p_menu);
Point2 get_mouse_position() const;
void set_window_title(const String &p_title);
void set_window_mouse_passthrough(const PoolVector2Array &p_region);
int get_mouse_button_state() const;
void set_clipboard(const String &p_text);
@ -171,34 +146,16 @@ public:
bool is_video_mode_resizable(int p_screen = 0) const;
Array get_fullscreen_mode_list(int p_screen = 0) const;
virtual int get_video_driver_count() const;
virtual String get_video_driver_name(VideoDriver p_driver) const;
virtual VideoDriver get_current_video_driver() const;
virtual int get_audio_driver_count() const;
virtual String get_audio_driver_name(int p_driver) const;
virtual PoolStringArray get_connected_midi_inputs();
virtual void open_midi_inputs();
virtual void close_midi_inputs();
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 float get_screen_scale(int p_screen = -1) const;
virtual float get_screen_max_scale() const;
virtual Point2 get_window_position() const;
virtual void set_window_position(const Point2 &p_position);
virtual Size2 get_max_window_size() const;
virtual Size2 get_min_window_size() const;
virtual Size2 get_window_size() const;
virtual Size2 get_real_window_size() const;
virtual Rect2 get_window_safe_area() const;
virtual void set_max_window_size(const Size2 &p_size);
virtual void set_min_window_size(const Size2 &p_size);
virtual void set_window_size(const Size2 &p_size);
virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
@ -208,25 +165,13 @@ public:
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 bool is_window_focused() const;
virtual void request_attention();
virtual void center_window();
virtual void move_window_to_foreground();
virtual int64_t get_native_handle(HandleType p_handle_type);
virtual void set_borderless_window(bool p_borderless);
virtual bool get_borderless_window() const;
virtual bool get_window_per_pixel_transparency_enabled() const;
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
virtual void set_ime_active(const bool p_active);
virtual void set_ime_position(const Point2 &p_pos);
virtual Point2 get_ime_selection() const;
virtual String get_ime_text() const;
Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
bool native_video_is_playing();
@ -237,11 +182,8 @@ public:
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;
String get_executable_path() const;
int execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking = true, Array p_output = Array(), bool p_read_stderr = false);
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);
@ -250,18 +192,12 @@ public:
bool has_environment(const String &p_var) const;
String get_environment(const String &p_var) const;
bool set_environment(const String &p_var, const String &p_value) const;
String get_name() const;
Vector<String> get_cmdline_args();
String get_locale() const;
String get_latin_keyboard_variant() const;
int keyboard_get_layout_count() const;
int keyboard_get_current_layout() const;
void keyboard_set_current_layout(int p_index);
String keyboard_get_layout_language(int p_index) const;
String keyboard_get_layout_name(int p_index) const;
String get_model_name() const;
@ -269,7 +205,7 @@ public:
void dump_resources_to_file(const String &p_file);
bool has_virtual_keyboard() const;
void show_virtual_keyboard(const String &p_existing_text = "", bool p_multiline = false);
void show_virtual_keyboard(const String &p_existing_text = "");
void hide_virtual_keyboard();
int get_virtual_keyboard_height();
@ -288,9 +224,26 @@ public:
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_native_icon(const String &p_filename);
void set_icon(const Ref<Image> &p_icon);
int get_exit_code() const;
@ -298,21 +251,19 @@ public:
Dictionary get_date(bool utc) const;
Dictionary get_time(bool utc) const;
Dictionary get_datetime(bool utc) const;
Dictionary get_datetime_from_unix_time(int64_t unix_time_val) const;
int64_t get_unix_time_from_datetime(Dictionary datetime) 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;
uint64_t get_system_time_msecs() const;
uint64_t get_static_memory_usage() const;
uint64_t get_static_memory_peak_usage() const;
uint64_t get_dynamic_memory_usage() const;
int get_static_memory_usage() const;
int get_static_memory_peak_usage() const;
int get_dynamic_memory_usage() const;
void delay_usec(int p_usec) const;
void delay_msec(int p_msec) const;
void delay_usec(uint32_t p_usec) const;
void delay_msec(uint32_t p_msec) const;
uint32_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
uint32_t get_splash_tick_msec() const;
bool can_use_threads() const;
@ -362,41 +313,26 @@ public:
bool is_ok_left_and_cancel_right() const;
Error set_thread_name(const String &p_name);
Thread::ID get_thread_caller_id() const;
void set_use_vsync(bool p_enable);
bool is_vsync_enabled() const;
void set_vsync_via_compositor(bool p_enable);
bool is_vsync_via_compositor_enabled() const;
PowerState get_power_state();
int get_power_seconds_left();
int get_power_percent_left();
bool has_feature(const String &p_feature) const;
bool request_permission(const String &p_name);
bool request_permissions();
Vector<String> get_granted_permissions() const;
int get_tablet_driver_count() const;
String get_tablet_driver_name(int p_driver) const;
String get_current_tablet_driver() const;
void set_current_tablet_driver(const String &p_driver);
static _OS *get_singleton() { return singleton; }
_OS();
};
VARIANT_ENUM_CAST(_OS::VideoDriver);
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);
VARIANT_ENUM_CAST(_OS::HandleType);
class _Geometry : public Object {
@ -413,7 +349,6 @@ public:
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);
Variant line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_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);
@ -427,58 +362,18 @@ public:
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);
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);
int get_uv84_normal_bit(const Vector3 &p_vector);
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_2d(const Vector<Vector2> &p_points);
Vector<Point2> convex_hull_2d(const Vector<Point2> &p_points);
Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane);
enum PolyBooleanOperation {
OPERATION_UNION,
OPERATION_DIFFERENCE,
OPERATION_INTERSECTION,
OPERATION_XOR
};
// 2D polygon boolean operations.
Array merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Union (add).
Array clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Difference (subtract).
Array intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // Common area (multiply).
Array exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b); // All but common area (xor).
// 2D polyline vs polygon operations.
Array clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon); // Cut.
Array intersect_polyline_with_polygon_2d(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
};
Array offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type = JOIN_SQUARE);
Array offset_polyline_2d(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);
_Geometry();
};
VARIANT_ENUM_CAST(_Geometry::PolyBooleanOperation);
VARIANT_ENUM_CAST(_Geometry::PolyJoinType);
VARIANT_ENUM_CAST(_Geometry::PolyEndType);
class _File : public Reference {
GDCLASS(_File, Reference);
@ -504,57 +399,52 @@ public:
COMPRESSION_GZIP = Compression::MODE_GZIP
};
Error open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key);
Error open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass);
Error open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode = COMPRESSION_FASTLZ);
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, ModeFlags p_mode_flags); // open a file.
void flush(); // Flush a file (write its buffer to disk).
void close(); // Close a file.
bool is_open() const; // True when file is open.
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
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
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.
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(bool p_allow_objects = false) const;
Variant get_var() const;
PoolVector<uint8_t> get_buffer(int p_length) const; // Get an array of bytes.
PoolVector<uint8_t> get_buffer(int p_length) const; ///< get an array of bytes
String get_line() const;
Vector<String> get_csv_line(const String &p_delim = ",") 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).
/**< 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.
* 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.
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_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);
@ -562,16 +452,17 @@ public:
void store_string(const String &p_string);
void store_line(const String &p_string);
void store_csv_line(const Vector<String> &p_values, const String &p_delim = ",");
virtual void store_pascal_string(const String &p_string);
virtual String get_pascal_string();
void store_buffer(const PoolVector<uint8_t> &p_buffer); // Store an array of bytes.
Vector<String> get_csv_line(String delim = ",") const;
void store_var(const Variant &p_var, bool p_full_objects = false);
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
bool file_exists(const String &p_name) const; // Return true if a file exists.
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;
@ -593,18 +484,18 @@ protected:
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.
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();
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 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);
@ -626,9 +517,9 @@ private:
bool _list_skip_hidden;
};
class _Marshalls : public Object {
class _Marshalls : public Reference {
GDCLASS(_Marshalls, Object);
GDCLASS(_Marshalls, Reference);
static _Marshalls *singleton;
@ -638,8 +529,8 @@ protected:
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 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);
@ -654,7 +545,7 @@ public:
class _Mutex : public Reference {
GDCLASS(_Mutex, Reference);
Mutex mutex;
Mutex *mutex;
static void _bind_methods();
@ -662,18 +553,24 @@ public:
void lock();
Error try_lock();
void unlock();
_Mutex();
~_Mutex();
};
class _Semaphore : public Reference {
GDCLASS(_Semaphore, Reference);
Semaphore semaphore;
Semaphore *semaphore;
static void _bind_methods();
public:
Error wait();
Error post();
_Semaphore();
~_Semaphore();
};
class _Thread : public Reference {
@ -683,10 +580,10 @@ class _Thread : public Reference {
protected:
Variant ret;
Variant userdata;
SafeFlag active;
volatile bool active;
Object *target_instance;
StringName target_method;
Thread thread;
Thread *thread;
static void _bind_methods();
static void _start_func(void *ud);
@ -695,11 +592,10 @@ public:
PRIORITY_LOW,
PRIORITY_NORMAL,
PRIORITY_HIGH,
PRIORITY_MAX
PRIORITY_HIGH
};
Error start(Object *p_instance, const StringName &p_method, const Variant &p_userdata = Variant(), Priority p_priority = PRIORITY_NORMAL);
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();
@ -712,7 +608,7 @@ VARIANT_ENUM_CAST(_Thread::Priority);
class _ClassDB : public Object {
GDCLASS(_ClassDB, Object);
GDCLASS(_ClassDB, Object)
protected:
static void _bind_methods();
@ -761,16 +657,10 @@ public:
void set_iterations_per_second(int p_ips);
int get_iterations_per_second() const;
void set_physics_jitter_fix(float p_threshold);
float get_physics_jitter_fix() const;
float get_physics_interpolation_fraction() const;
void set_target_fps(int p_fps);
int get_target_fps() const;
float get_frames_per_second() const;
uint64_t get_physics_frames() const;
uint64_t get_idle_frames() const;
int get_frames_drawn();
@ -780,11 +670,6 @@ public:
MainLoop *get_main_loop() const;
Dictionary get_version_info() const;
Dictionary get_author_info() const;
Array get_copyright_info() const;
Dictionary get_donor_info() const;
Dictionary get_license_info() const;
String get_license_text() const;
bool is_in_physics_frame() const;
@ -800,7 +685,7 @@ public:
class _JSON;
class JSONParseResult : public Reference {
GDCLASS(JSONParseResult, Reference);
GDCLASS(JSONParseResult, Reference)
friend class _JSON;
@ -825,13 +710,10 @@ public:
void set_result(const Variant &p_result);
Variant get_result() const;
JSONParseResult() :
error_line(-1) {}
};
class _JSON : public Object {
GDCLASS(_JSON, Object);
GDCLASS(_JSON, Object)
protected:
static void _bind_methods();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,13 +30,21 @@
#include "class_db.h"
#include "core/engine.h"
#include "core/os/mutex.h"
#include "core/version.h"
#include "os/mutex.h"
#include "version.h"
#ifdef NO_THREADS
#define OBJTYPE_RLOCK
#define OBJTYPE_WLOCK
#else
#define OBJTYPE_RLOCK RWLockRead _rw_lockr_(lock);
#define OBJTYPE_WLOCK RWLockWrite _rw_lockw_(lock);
#endif
#ifdef DEBUG_METHODS_ENABLED
MethodDefinition D_METHOD(const char *p_name) {
@ -59,8 +67,8 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(2);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
return md;
}
@ -69,9 +77,9 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(3);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
return md;
}
@ -80,10 +88,10 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(4);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
return md;
}
@ -92,11 +100,11 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(5);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
return md;
}
@ -105,12 +113,12 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(6);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
return md;
}
@ -119,13 +127,13 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(7);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
return md;
}
@ -134,14 +142,14 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(8);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
return md;
}
@ -150,15 +158,15 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(9);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args.write[8] = StaticCString::create(p_arg9);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
md.args[8] = StaticCString::create(p_arg9);
return md;
}
@ -167,16 +175,16 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(10);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args.write[8] = StaticCString::create(p_arg9);
md.args.write[9] = StaticCString::create(p_arg10);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
md.args[8] = StaticCString::create(p_arg9);
md.args[9] = StaticCString::create(p_arg10);
return md;
}
@ -185,17 +193,17 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(11);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args.write[8] = StaticCString::create(p_arg9);
md.args.write[9] = StaticCString::create(p_arg10);
md.args.write[10] = StaticCString::create(p_arg11);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
md.args[8] = StaticCString::create(p_arg9);
md.args[9] = StaticCString::create(p_arg10);
md.args[10] = StaticCString::create(p_arg11);
return md;
}
@ -204,18 +212,18 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(12);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args.write[8] = StaticCString::create(p_arg9);
md.args.write[9] = StaticCString::create(p_arg10);
md.args.write[10] = StaticCString::create(p_arg11);
md.args.write[11] = StaticCString::create(p_arg12);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
md.args[8] = StaticCString::create(p_arg9);
md.args[9] = StaticCString::create(p_arg10);
md.args[10] = StaticCString::create(p_arg11);
md.args[11] = StaticCString::create(p_arg12);
return md;
}
@ -224,19 +232,19 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(13);
md.args.write[0] = StaticCString::create(p_arg1);
md.args.write[1] = StaticCString::create(p_arg2);
md.args.write[2] = StaticCString::create(p_arg3);
md.args.write[3] = StaticCString::create(p_arg4);
md.args.write[4] = StaticCString::create(p_arg5);
md.args.write[5] = StaticCString::create(p_arg6);
md.args.write[6] = StaticCString::create(p_arg7);
md.args.write[7] = StaticCString::create(p_arg8);
md.args.write[8] = StaticCString::create(p_arg9);
md.args.write[9] = StaticCString::create(p_arg10);
md.args.write[10] = StaticCString::create(p_arg11);
md.args.write[11] = StaticCString::create(p_arg12);
md.args.write[12] = StaticCString::create(p_arg13);
md.args[0] = StaticCString::create(p_arg1);
md.args[1] = StaticCString::create(p_arg2);
md.args[2] = StaticCString::create(p_arg3);
md.args[3] = StaticCString::create(p_arg4);
md.args[4] = StaticCString::create(p_arg5);
md.args[5] = StaticCString::create(p_arg6);
md.args[6] = StaticCString::create(p_arg7);
md.args[7] = StaticCString::create(p_arg8);
md.args[8] = StaticCString::create(p_arg9);
md.args[9] = StaticCString::create(p_arg10);
md.args[10] = StaticCString::create(p_arg11);
md.args[11] = StaticCString::create(p_arg12);
md.args[12] = StaticCString::create(p_arg13);
return md;
}
@ -249,28 +257,23 @@ void ClassDB::set_current_api(APIType p_api) {
current_api = p_api;
}
ClassDB::APIType ClassDB::get_current_api() {
return current_api;
}
HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
HashMap<StringName, StringName> ClassDB::resource_base_extensions;
HashMap<StringName, StringName> ClassDB::compat_classes;
HashMap<StringName, ClassDB::ClassInfo, StringNameHasher> ClassDB::classes;
HashMap<StringName, StringName, StringNameHasher> ClassDB::resource_base_extensions;
HashMap<StringName, StringName, StringNameHasher> ClassDB::compat_classes;
ClassDB::ClassInfo::ClassInfo() {
api = API_NONE;
creation_func = NULL;
inherits_ptr = NULL;
disabled = false;
exposed = false;
}
ClassDB::ClassInfo::~ClassInfo() {
}
bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_inherits) {
bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) {
OBJTYPE_RLOCK;
StringName inherits = p_class;
@ -278,19 +281,11 @@ bool ClassDB::_is_parent_class(const StringName &p_class, const StringName &p_in
if (inherits == p_inherits)
return true;
inherits = _get_parent_class(inherits);
inherits = get_parent_class(inherits);
}
return false;
}
bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) {
OBJTYPE_RLOCK;
return _is_parent_class(p_class, p_inherits);
}
void ClassDB::get_class_list(List<StringName> *p_classes) {
OBJTYPE_RLOCK;
@ -313,20 +308,7 @@ void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringNa
while ((k = classes.next(k))) {
if (*k != p_class && _is_parent_class(*k, p_class))
p_classes->push_back(*k);
}
}
void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) {
OBJTYPE_RLOCK;
const StringName *k = NULL;
while ((k = classes.next(k))) {
if (*k != p_class && _get_parent_class(*k) == p_class)
if (*k != p_class && is_parent_class(*k, p_class))
p_classes->push_back(*k);
}
}
@ -341,18 +323,13 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) {
return ti->inherits;
}
StringName ClassDB::_get_parent_class(const StringName &p_class) {
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V_MSG(!ti, StringName(), "Cannot get class '" + String(p_class) + "'.");
return ti->inherits;
}
StringName ClassDB::get_parent_class(const StringName &p_class) {
OBJTYPE_RLOCK;
return _get_parent_class(p_class);
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V(!ti, StringName());
return ti->inherits;
}
ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
@ -361,7 +338,7 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V_MSG(!ti, API_NONE, "Cannot get class '" + String(p_class) + "'.");
ERR_FAIL_COND_V(!ti, API_NONE);
return ti->api;
}
@ -386,8 +363,8 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
ClassInfo *t = classes.getptr(E->get());
ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'.");
if (t->api != p_api || !t->exposed)
ERR_FAIL_COND_V(!t, 0);
if (t->api != p_api)
continue;
hash = hash_djb2_one_64(t->name.hash(), hash);
hash = hash_djb2_one_64(t->inherits.hash(), hash);
@ -400,13 +377,6 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
while ((k = t->method_map.next(k))) {
String name = k->operator String();
ERR_CONTINUE(name.empty());
if (name[0] == '_')
continue; // Ignore non-virtual methods that start with an underscore
snames.push_back(*k);
}
@ -498,7 +468,6 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
PropertySetGet *psg = t->property_setget.getptr(F->get());
ERR_FAIL_COND_V(!psg, 0);
hash = hash_djb2_one_64(F->get().hash(), hash);
hash = hash_djb2_one_64(psg->setter.hash(), hash);
@ -546,16 +515,11 @@ Object *ClassDB::instance(const StringName &p_class) {
ti = classes.getptr(compat_classes[p_class]);
}
}
ERR_FAIL_COND_V_MSG(!ti, NULL, "Cannot get class '" + String(p_class) + "'.");
ERR_FAIL_COND_V_MSG(ti->disabled, NULL, "Class '" + String(p_class) + "' is disabled.");
ERR_FAIL_COND_V(!ti, NULL);
ERR_FAIL_COND_V(ti->disabled, NULL);
ERR_FAIL_COND_V(!ti->creation_func, NULL);
}
#ifdef TOOLS_ENABLED
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
ERR_PRINTS("Class '" + String(p_class) + "' can only be instantiated by editor.");
return NULL;
}
#endif
return ti->creation_func();
}
bool ClassDB::can_instance(const StringName &p_class) {
@ -563,12 +527,7 @@ bool ClassDB::can_instance(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
#ifdef TOOLS_ENABLED
if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) {
return false;
}
#endif
ERR_FAIL_COND_V(!ti, false);
return (!ti->disabled && ti->creation_func != NULL);
}
@ -576,9 +535,9 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
OBJTYPE_WLOCK;
const StringName &name = p_class;
StringName name = p_class;
ERR_FAIL_COND_MSG(classes.has(name), "Class '" + String(p_class) + "' already exists.");
ERR_FAIL_COND(classes.has(name));
classes[name] = ClassInfo();
ClassInfo &ti = classes[name];
@ -690,8 +649,10 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
if (!type) {
ERR_FAIL_COND(!type);
ERR_FAIL_COND(!type);
}
if (type->constant_map.has(p_name)) {
@ -699,6 +660,7 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
}
type->constant_map[p_name] = p_constant;
#ifdef DEBUG_METHODS_ENABLED
String enum_name = p_enum;
if (enum_name != String()) {
@ -717,7 +679,6 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
}
}
#ifdef DEBUG_METHODS_ENABLED
type->constant_order.push_back(p_name);
#endif
}
@ -773,6 +734,7 @@ int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p
return 0;
}
#ifdef DEBUG_METHODS_ENABLED
StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
OBJTYPE_RLOCK;
@ -841,6 +803,7 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
type = type->inherits_ptr;
}
}
#endif
void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
@ -849,12 +812,15 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
StringName sname = p_signal.name;
#ifdef DEBUG_METHODS_ENABLED
ClassInfo *check = type;
StringName sname = p_signal.name;
#ifdef DEBUG_METHODS_ENABLED
while (check) {
ERR_FAIL_COND_MSG(check->signal_map.has(sname), "Class '" + String(p_class) + "' already has signal '" + String(sname) + "'.");
if (check->signal_map.has(sname)) {
ERR_EXPLAIN("Type " + String(p_class) + " already has signal: " + String(sname));
ERR_FAIL();
}
check = check->inherits_ptr;
}
#endif
@ -929,9 +895,15 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
lock.read_lock();
#ifndef NO_THREADS
lock->read_lock();
#endif
ClassInfo *type = classes.getptr(p_class);
lock.read_unlock();
#ifndef NO_THREADS
lock->read_unlock();
#endif
ERR_FAIL_COND(!type);
@ -939,11 +911,16 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
if (p_setter) {
mb_set = get_method(p_class, p_setter);
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_MSG(!mb_set, "Invalid setter '" + p_class + "::" + p_setter + "' for property '" + p_pinfo.name + "'.");
int exp_args = 1 + (p_index >= 0 ? 1 : 0);
ERR_FAIL_COND_MSG(mb_set->get_argument_count() != exp_args, "Invalid function for setter '" + p_class + "::" + p_setter + " for property '" + p_pinfo.name + "'.");
if (!mb_set) {
ERR_EXPLAIN("Invalid Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name);
ERR_FAIL_COND(!mb_set);
} else {
int exp_args = 1 + (p_index >= 0 ? 1 : 0);
if (mb_set->get_argument_count() != exp_args) {
ERR_EXPLAIN("Invalid Function for Setter: " + p_class + "::" + p_setter + " for property: " + p_pinfo.name);
ERR_FAIL();
}
}
#endif
}
@ -953,15 +930,26 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
mb_get = get_method(p_class, p_getter);
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_MSG(!mb_get, "Invalid getter '" + p_class + "::" + p_getter + "' for property '" + p_pinfo.name + "'.");
if (!mb_get) {
ERR_EXPLAIN("Invalid Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name);
ERR_FAIL_COND(!mb_get);
} else {
int exp_args = 0 + (p_index >= 0 ? 1 : 0);
ERR_FAIL_COND_MSG(mb_get->get_argument_count() != exp_args, "Invalid function for getter '" + p_class + "::" + p_getter + "' for property: '" + p_pinfo.name + "'.");
int exp_args = 0 + (p_index >= 0 ? 1 : 0);
if (mb_get->get_argument_count() != exp_args) {
ERR_EXPLAIN("Invalid Function for Getter: " + p_class + "::" + p_getter + " for property: " + p_pinfo.name);
ERR_FAIL();
}
}
#endif
}
#ifdef DEBUG_METHODS_ENABLED
ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), "Object '" + p_class + "' already has property '" + p_pinfo.name + "'.");
if (type->property_setget.has(p_pinfo.name)) {
ERR_EXPLAIN("Object already has property: " + p_class);
ERR_FAIL();
}
#endif
OBJTYPE_WLOCK
@ -986,13 +974,6 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
type->property_setget[p_pinfo.name] = psg;
}
void ClassDB::set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default) {
if (!default_values.has(p_class)) {
default_values[p_class] = HashMap<StringName, Variant>();
}
default_values[p_class][p_name] = p_default;
}
void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
OBJTYPE_RLOCK;
@ -1018,7 +999,6 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list,
}
}
bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) {
ERR_FAIL_NULL_V(p_object, false);
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
@ -1065,7 +1045,6 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
return false;
}
bool ClassDB::get_property(Object *p_object, const StringName &p_property, Variant &r_value) {
ERR_FAIL_NULL_V(p_object, false);
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
@ -1151,7 +1130,7 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String
return Variant::NIL;
}
StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) {
StringName ClassDB::get_property_setter(StringName p_class, const StringName p_property) {
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@ -1168,7 +1147,7 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_
return StringName();
}
StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) {
StringName ClassDB::get_property_getter(StringName p_class, const StringName p_property) {
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@ -1242,26 +1221,32 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(has_method(instance_type, mdname), NULL, "Class " + String(instance_type) + " already has a method " + String(mdname) + ".");
if (has_method(instance_type, mdname)) {
ERR_EXPLAIN("Class " + String(instance_type) + " already has a method " + String(mdname));
ERR_FAIL_V(NULL);
}
#endif
ClassInfo *type = classes.getptr(instance_type);
if (!type) {
ERR_PRINTS("Couldn't bind method '" + mdname + "' for instance: " + instance_type);
memdelete(p_bind);
ERR_FAIL_V_MSG(NULL, "Couldn't bind method '" + mdname + "' for instance '" + instance_type + "'.");
ERR_FAIL_V(NULL);
}
if (type->method_map.has(mdname)) {
memdelete(p_bind);
// overloading not supported
ERR_FAIL_V_MSG(NULL, "Method already bound '" + instance_type + "::" + mdname + "'.");
ERR_EXPLAIN("Method already bound: " + instance_type + "::" + mdname);
ERR_FAIL_V(NULL);
}
#ifdef DEBUG_METHODS_ENABLED
if (method_name.args.size() > p_bind->get_argument_count()) {
memdelete(p_bind);
ERR_FAIL_V_MSG(NULL, "Method definition provides more arguments than the method actually has '" + instance_type + "::" + mdname + "'.");
ERR_EXPLAIN("Method definition provides more arguments than the method actually has: " + instance_type + "::" + mdname);
ERR_FAIL_V(NULL);
}
p_bind->set_argument_names(method_name.args);
@ -1276,7 +1261,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
defvals.resize(p_defcount);
for (int i = 0; i < p_defcount; i++) {
defvals.write[i] = *p_defs[p_defcount - i - 1];
defvals[i] = *p_defs[p_defcount - i - 1];
}
p_bind->set_default_arguments(defvals);
@ -1285,7 +1270,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
}
void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual) {
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
ERR_FAIL_COND(!classes.has(p_class));
OBJTYPE_WLOCK;
@ -1300,7 +1285,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) {
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
ERR_FAIL_COND(!classes.has(p_class));
#ifdef DEBUG_METHODS_ENABLED
@ -1324,7 +1309,7 @@ void ClassDB::set_class_enabled(StringName p_class, bool p_enable) {
OBJTYPE_WLOCK;
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
ERR_FAIL_COND(!classes.has(p_class));
classes[p_class].disabled = !p_enable;
}
@ -1339,7 +1324,7 @@ bool ClassDB::is_class_enabled(StringName p_class) {
}
}
ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
ERR_FAIL_COND_V(!ti, false);
return !ti->disabled;
}
@ -1348,7 +1333,7 @@ bool ClassDB::is_class_exposed(StringName p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
ERR_FAIL_COND_V_MSG(!ti, false, "Cannot get class '" + String(p_class) + "'.");
ERR_FAIL_COND_V(!ti, false);
return ti->exposed;
}
@ -1391,70 +1376,14 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p
}
}
HashMap<StringName, HashMap<StringName, Variant> > ClassDB::default_values;
Set<StringName> ClassDB::default_values_cached;
RWLock *ClassDB::lock = NULL;
Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) {
void ClassDB::init() {
if (!default_values_cached.has(p_class)) {
#ifndef NO_THREADS
if (!default_values.has(p_class)) {
default_values[p_class] = HashMap<StringName, Variant>();
}
Object *c = NULL;
bool cleanup_c = false;
if (Engine::get_singleton()->has_singleton(p_class)) {
c = Engine::get_singleton()->get_singleton_object(p_class);
cleanup_c = false;
} else if (ClassDB::can_instance(p_class)) {
c = ClassDB::instance(p_class);
cleanup_c = true;
}
if (c) {
List<PropertyInfo> plist;
c->get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) {
if (!default_values[p_class].has(E->get().name)) {
Variant v = c->get(E->get().name);
default_values[p_class][E->get().name] = v;
}
}
}
if (cleanup_c) {
memdelete(c);
}
}
default_values_cached.insert(p_class);
}
if (!default_values.has(p_class)) {
if (r_valid != NULL) *r_valid = false;
return Variant();
}
if (!default_values[p_class].has(p_property)) {
if (r_valid != NULL) *r_valid = false;
return Variant();
}
if (r_valid != NULL) *r_valid = true;
return default_values[p_class][p_property];
}
RWLock ClassDB::lock;
void ClassDB::cleanup_defaults() {
default_values.clear();
default_values_cached.clear();
lock = RWLock::create();
#endif
}
void ClassDB::cleanup() {
@ -1476,6 +1405,11 @@ void ClassDB::cleanup() {
classes.clear();
resource_base_extensions.clear();
compat_classes.clear();
#ifndef NO_THREADS
memdelete(lock);
#endif
}
//

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,13 +31,13 @@
#ifndef CLASS_DB_H
#define CLASS_DB_H
#include "core/method_bind.h"
#include "core/object.h"
#include "core/print_string.h"
#include "method_bind.h"
#include "object.h"
#include "print_string.h"
/** To bind more then 6 parameters include this:
* #include "core/method_bind_ext.gen.inc"
*/
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
#define DEFVAL(m_defval) (m_defval)
@ -114,20 +114,19 @@ public:
APIType api;
ClassInfo *inherits_ptr;
void *class_ptr;
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, int> constant_map;
HashMap<StringName, List<StringName> > enum_map;
HashMap<StringName, MethodInfo> signal_map;
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> property_setget;
HashMap<StringName, PropertySetGet, StringNameHasher> property_setget;
StringName inherits;
StringName name;
@ -143,10 +142,10 @@ public:
return memnew(T);
}
static RWLock lock;
static HashMap<StringName, ClassInfo> classes;
static HashMap<StringName, StringName> resource_base_extensions;
static HashMap<StringName, StringName> compat_classes;
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);
@ -158,14 +157,6 @@ public:
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
static Set<StringName> default_values_cached;
private:
// Non-locking variants of get_parent_class and is_parent_class.
static StringName _get_parent_class(const StringName &p_class);
static bool _is_parent_class(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>
@ -183,7 +174,6 @@ public:
ERR_FAIL_COND(!t);
t->creation_func = &creator<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
T::register_custom_data_to_otdb();
}
@ -195,7 +185,6 @@ public:
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
//nothing
}
@ -214,13 +203,11 @@ public:
ERR_FAIL_COND(!t);
t->creation_func = &_create_ptr_func<T>;
t->exposed = true;
t->class_ptr = T::get_class_ptr_static();
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 void get_direct_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);
@ -293,30 +280,12 @@ public:
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6);
}
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, const Variant &p_def7) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7);
}
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, const Variant &p_def7, const Variant &p_def8) {
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8);
}
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>(), bool p_return_nil_is_variant = true) {
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, p_return_nil_is_variant);
MethodBind *bind = create_vararg_method_bind(p_method, p_info);
ERR_FAIL_COND_V(!bind, NULL);
bind->set_name(p_name);
@ -333,7 +302,8 @@ public:
if (type->method_map.has(p_name)) {
memdelete(bind);
// overloading not supported
ERR_FAIL_V_MSG(NULL, "Method already bound: " + instance_type + "::" + p_name + ".");
ERR_EXPLAIN("Method already bound: " + instance_type + "::" + p_name);
ERR_FAIL_V(NULL);
}
type->method_map[p_name] = bind;
#ifdef DEBUG_METHODS_ENABLED
@ -352,15 +322,14 @@ public:
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 set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
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 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);
@ -375,11 +344,11 @@ public:
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);
static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = NULL);
#endif
static StringName get_category(const StringName &p_node);
@ -393,10 +362,9 @@ public:
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 APIType get_current_api();
static void cleanup_defaults();
static void cleanup();
};

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,85 +30,45 @@
#include "color.h"
#include "core/color_names.inc"
#include "core/map.h"
#include "core/math/math_funcs.h"
#include "core/print_string.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)Math::round(a * 255);
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(r * 255);
c |= (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
c |= (uint8_t)(b * 255);
return c;
}
uint32_t Color::to_abgr32() const {
uint32_t c = (uint8_t)Math::round(a * 255);
uint32_t c = (uint8_t)(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
c |= (uint8_t)(b * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(r * 255);
c |= (uint8_t)(r * 255);
return c;
}
uint32_t Color::to_rgba32() const {
uint32_t c = (uint8_t)Math::round(r * 255);
uint32_t c = (uint8_t)(r * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
c |= (uint8_t)(g * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
c |= (uint8_t)(b * 255);
c <<= 8;
c |= (uint8_t)Math::round(a * 255);
return c;
}
uint64_t Color::to_abgr64() const {
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(r * 65535);
return c;
}
uint64_t Color::to_argb64() const {
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(r * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
return c;
}
uint64_t Color::to_rgba64() const {
uint64_t c = (uint16_t)Math::round(r * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
c <<= 16;
c |= (uint16_t)Math::round(a * 65535);
c |= (uint8_t)(a * 255);
return c;
}
@ -214,11 +174,6 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
}
bool Color::is_equal_approx(const Color &p_color) const {
return Math::is_equal_approx(r, p_color.r) && Math::is_equal_approx(g, p_color.g) && Math::is_equal_approx(b, p_color.b) && Math::is_equal_approx(a, p_color.a);
}
void Color::invert() {
r = 1.0 - r;
@ -245,34 +200,6 @@ Color Color::hex(uint32_t p_hex) {
return Color(r, g, b, a);
}
Color Color::hex64(uint64_t p_hex) {
float a = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float b = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float g = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float r = (p_hex & 0xFFFF) / 65535.0;
return Color(r, g, b, a);
}
Color Color::from_rgbe9995(uint32_t p_rgbe) {
float r = p_rgbe & 0x1ff;
float g = (p_rgbe >> 9) & 0x1ff;
float b = (p_rgbe >> 18) & 0x1ff;
float e = (p_rgbe >> 27);
float m = Math::pow(2, e - 15.0 - 9.0);
float rd = r * m;
float gd = g * m;
float bd = b * m;
return Color(rd, gd, bd, 1.0f);
}
static float _parse_col(const String &p_str, int p_ofs) {
int ig = 0;
@ -340,23 +267,36 @@ Color Color::html(const String &p_color) {
} else if (color.length() == 6) {
alpha = false;
} else {
ERR_FAIL_V_MSG(Color(), "Invalid color code: " + p_color + ".");
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int a = 255;
if (alpha) {
a = _parse_col(color, 0);
ERR_FAIL_COND_V_MSG(a < 0, Color(), "Invalid color code: " + p_color + ".");
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);
ERR_FAIL_COND_V_MSG(r < 0, Color(), "Invalid color code: " + p_color + ".");
if (r < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int g = _parse_col(color, from + 2);
ERR_FAIL_COND_V_MSG(g < 0, Color(), "Invalid color code: " + p_color + ".");
if (g < 0) {
ERR_EXPLAIN("Invalid Color Code: " + p_color);
ERR_FAIL_V(Color());
}
int b = _parse_col(color, from + 4);
ERR_FAIL_COND_V_MSG(b < 0, Color(), "Invalid color code: " + p_color + ".");
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);
}
@ -380,8 +320,9 @@ bool Color::html_is_valid(const String &p_color) {
return false;
}
int a = 255;
if (alpha) {
int a = _parse_col(color, 0);
a = _parse_col(color, 0);
if (a < 0) {
return false;
}
@ -417,13 +358,17 @@ Color Color::named(const String &p_name) {
name = name.to_lower();
const Map<String, Color>::Element *color = _named_colors.find(name);
ERR_FAIL_NULL_V_MSG(color, Color(), "Invalid color name: " + p_name + ".");
return color->value();
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 = Math::round(p_val * 255);
int v = p_val * 255;
v = CLAMP(v, 0, 255);
String ret;
@ -455,16 +400,8 @@ String Color::to_html(bool p_alpha) const {
return txt;
}
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
Color c;
c.set_hsv(p_h, p_s, p_v, p_a);
return c;
}
// FIXME: Remove once Godot 3.1 has been released
float Color::gray() const {
WARN_DEPRECATED_MSG("'Color.gray()' is deprecated and will be removed in a future version. Use 'Color.v' for a better grayscale approximation.");
return (r + g + b) / 3.0;
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,9 +31,11 @@
#ifndef COLOR_H
#define COLOR_H
#include "core/math/math_funcs.h"
#include "core/ustring.h"
#include "math_funcs.h"
#include "ustring.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
struct Color {
union {
@ -53,9 +55,6 @@ struct Color {
uint32_t to_rgba32() const;
uint32_t to_argb32() const;
uint32_t to_abgr32() const;
uint64_t to_rgba64() const;
uint64_t to_argb64() const;
uint64_t to_abgr64() const;
float gray() const;
float get_h() const;
float get_s() const;
@ -86,8 +85,6 @@ struct Color {
void operator/=(const Color &p_color);
void operator/=(const real_t &rvalue);
bool is_equal_approx(const Color &p_color) const;
void invert();
void contrast();
Color inverted() const;
@ -189,13 +186,10 @@ struct Color {
}
static Color hex(uint32_t p_hex);
static Color hex64(uint64_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;
Color from_hsv(float p_h, float p_s, float p_v, float p_a) const;
static Color from_rgbe9995(uint32_t p_rgbe);
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const;

View File

@ -1,9 +1,9 @@
// Names from https://en.wikipedia.org/wiki/X11_color_names
#include "core/map.h"
// 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;
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));
@ -143,7 +143,6 @@ static void _populate_named_colors() {
_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("transparent", Color(1.00, 1.00, 1.00, 0.00));
_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));

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,17 +30,18 @@
#include "command_queue_mt.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "os/os.h"
void CommandQueueMT::lock() {
mutex.lock();
if (mutex)
mutex->lock();
}
void CommandQueueMT::unlock() {
mutex.unlock();
if (mutex)
mutex->unlock();
}
void CommandQueueMT::wait_for_flush() {
@ -78,7 +79,7 @@ CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
bool CommandQueueMT::dealloc_one() {
tryagain:
if (dealloc_ptr == (write_ptr_and_epoch >> 1)) {
if (dealloc_ptr == write_ptr) {
// The queue is empty
return false;
}
@ -96,35 +97,34 @@ tryagain:
return false;
}
dealloc_ptr += (size >> 1) + 8;
dealloc_ptr += (size >> 1) + sizeof(uint32_t);
return true;
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
read_ptr_and_epoch = 0;
write_ptr_and_epoch = 0;
dealloc_ptr = 0;
command_mem_size = GLOBAL_DEF_RST("memory/limits/command_queue/multithreading_queue_size_kb", DEFAULT_COMMAND_MEM_SIZE_KB);
ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/command_queue/multithreading_queue_size_kb", PropertyInfo(Variant::INT, "memory/limits/command_queue/multithreading_queue_size_kb", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"));
command_mem_size *= 1024;
command_mem = (uint8_t *)memalloc(command_mem_size);
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 = memnew(Semaphore);
} else {
if (p_sync)
sync = Semaphore::create();
else
sync = NULL;
}
}
CommandQueueMT::~CommandQueueMT() {
if (sync)
memdelete(sync);
memfree(command_mem);
memdelete(mutex);
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
memdelete(sync_sems[i].sem);
}
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,11 +31,14 @@
#ifndef COMMAND_QUEUE_MT_H
#define COMMAND_QUEUE_MT_H
#include "core/os/memory.h"
#include "core/os/mutex.h"
#include "core/os/semaphore.h"
#include "core/simple_type.h"
#include "core/typedefs.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
@ -51,13 +54,9 @@
#define _COMMA_10 ,
#define _COMMA_11 ,
#define _COMMA_12 ,
#define _COMMA_13 ,
// 1-based comma separated list of ITEMs
#define COMMA_SEP_LIST(ITEM, LENGTH) _COMMA_SEP_LIST_##LENGTH(ITEM)
#define _COMMA_SEP_LIST_13(ITEM) \
_COMMA_SEP_LIST_12(ITEM) \
, ITEM(13)
#define _COMMA_SEP_LIST_12(ITEM) \
_COMMA_SEP_LIST_11(ITEM) \
, ITEM(12)
@ -98,9 +97,6 @@
// 1-based semicolon separated list of ITEMs
#define SEMIC_SEP_LIST(ITEM, LENGTH) _SEMIC_SEP_LIST_##LENGTH(ITEM)
#define _SEMIC_SEP_LIST_13(ITEM) \
_SEMIC_SEP_LIST_12(ITEM); \
ITEM(13)
#define _SEMIC_SEP_LIST_12(ITEM) \
_SEMIC_SEP_LIST_11(ITEM); \
ITEM(12)
@ -141,9 +137,6 @@
// 1-based space separated list of ITEMs
#define SPACE_SEP_LIST(ITEM, LENGTH) _SPACE_SEP_LIST_##LENGTH(ITEM)
#define _SPACE_SEP_LIST_13(ITEM) \
_SPACE_SEP_LIST_12(ITEM) \
ITEM(13)
#define _SPACE_SEP_LIST_12(ITEM) \
_SPACE_SEP_LIST_11(ITEM) \
ITEM(12)
@ -250,8 +243,7 @@
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
ss->sem->wait(); \
}
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
@ -267,17 +259,16 @@
cmd->sync_sem = ss; \
unlock(); \
if (sync) sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
ss->sem->wait(); \
}
#define MAX_CMD_PARAMS 13
#define MAX_CMD_PARAMS 12
class CommandQueueMT {
struct SyncSemaphore {
Semaphore sem;
Semaphore *sem;
bool in_use;
};
@ -293,48 +284,45 @@ class CommandQueueMT {
SyncSemaphore *sync_sem;
virtual void post() {
sync_sem->sem.post();
sync_sem->sem->post();
sync_sem->in_use = false;
}
};
DECL_CMD(0)
SPACE_SEP_LIST(DECL_CMD, 13)
SPACE_SEP_LIST(DECL_CMD, 12)
/* comands that return */
DECL_CMD_RET(0)
SPACE_SEP_LIST(DECL_CMD_RET, 13)
SPACE_SEP_LIST(DECL_CMD_RET, 12)
/* commands that don't return but sync */
DECL_CMD_SYNC(0)
SPACE_SEP_LIST(DECL_CMD_SYNC, 13)
SPACE_SEP_LIST(DECL_CMD_SYNC, 12)
/***** BASE *******/
enum {
DEFAULT_COMMAND_MEM_SIZE_KB = 256,
COMMAND_MEM_SIZE_KB = 256,
COMMAND_MEM_SIZE = COMMAND_MEM_SIZE_KB * 1024,
SYNC_SEMAPHORES = 8
};
uint8_t *command_mem;
uint32_t read_ptr_and_epoch;
uint32_t write_ptr_and_epoch;
uint32_t dealloc_ptr;
uint32_t command_mem_size;
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;
Mutex *mutex;
Semaphore *sync;
template <class T>
T *allocate() {
// alloc size is size+T+safeguard
uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
// Assert that the buffer is big enough to hold at least two messages.
ERR_FAIL_COND_V(alloc_size * 2 + sizeof(uint32_t) > command_mem_size, NULL);
uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
tryagain:
uint32_t write_ptr = write_ptr_and_epoch >> 1;
if (write_ptr < dealloc_ptr) {
// behind dealloc_ptr, check that there is room
@ -346,10 +334,10 @@ class CommandQueueMT {
}
return NULL;
}
} else {
} 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)) {
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
@ -362,31 +350,24 @@ class CommandQueueMT {
}
// if this happens, it's a bug
ERR_FAIL_COND_V((command_mem_size - write_ptr) < 8, NULL);
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 = 1;
write_ptr_and_epoch = 0 | (1 & ~write_ptr_and_epoch); // Invert epoch.
// See if we can get the thread to run and clear up some more space while we wait.
// This is required if alloc_size * 2 + 4 > COMMAND_MEM_SIZE
if (sync) {
sync->post();
}
*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 size = (sizeof(T) + 8 - 1) & ~(8 - 1);
uint32_t *p = (uint32_t *)&command_mem[write_ptr];
*p = (size << 1) | 1;
write_ptr += 8;
*p = (sizeof(T) << 1) | 1;
write_ptr += sizeof(uint32_t);
// allocate the command
T *cmd = memnew_placement(&command_mem[write_ptr], T);
write_ptr += size;
write_ptr_and_epoch = (write_ptr << 1) | (write_ptr_and_epoch & 1);
write_ptr += sizeof(T);
return cmd;
}
@ -412,30 +393,24 @@ class CommandQueueMT {
tryagain:
// tried to read an empty queue
if (read_ptr_and_epoch == write_ptr_and_epoch) {
if (p_lock) unlock();
if (read_ptr == write_ptr)
return false;
}
uint32_t read_ptr = read_ptr_and_epoch >> 1;
uint32_t size_ptr = read_ptr;
uint32_t size = *(uint32_t *)&command_mem[read_ptr] >> 1;
if (size == 0) {
*(uint32_t *)&command_mem[read_ptr] = 0; // clear in-use bit.
//end of ringbuffer, wrap
read_ptr_and_epoch = 0 | (1 & ~read_ptr_and_epoch); // Invert epoch.
read_ptr = 0;
goto tryagain;
}
read_ptr += 8;
read_ptr += sizeof(uint32_t);
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
read_ptr += size;
read_ptr_and_epoch = (read_ptr << 1) | (read_ptr_and_epoch & 1);
if (p_lock) unlock();
cmd->call();
if (p_lock) lock();
@ -457,15 +432,15 @@ class CommandQueueMT {
public:
/* NORMAL PUSH COMMANDS */
DECL_PUSH(0)
SPACE_SEP_LIST(DECL_PUSH, 13)
SPACE_SEP_LIST(DECL_PUSH, 12)
/* PUSH AND RET COMMANDS */
DECL_PUSH_AND_RET(0)
SPACE_SEP_LIST(DECL_PUSH_AND_RET, 13)
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, 13)
SPACE_SEP_LIST(DECL_PUSH_AND_SYNC, 12)
void wait_and_flush_one() {
ERR_FAIL_COND(!sync);

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,7 +30,7 @@
#include "compressed_translation.h"
#include "core/pair.h"
#include "pair.h"
extern "C" {
#include "thirdparty/misc/smaz.h"
@ -50,6 +50,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
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;
@ -72,7 +73,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
Pair<int, CharString> p;
p.first = idx;
p.second = cs;
buckets.write[h % size].push_back(p);
buckets[h % size].push_back(p);
//compress string
CharString src_s = p_from->get_message(E->get()).operator String().utf8();
@ -83,7 +84,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
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.ptrw(), 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();
@ -99,22 +100,25 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
ps.compressed[0] = 0;
}
compressed.write[idx] = ps;
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++) {
const Vector<Pair<int, CharString> > &b = buckets[i];
Map<uint32_t, int> &t = table.write[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;
@ -132,11 +136,12 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
}
}
hfunc_table.write[i] = d;
hfunc_table[i] = d;
bucket_table_size += 2 + b.size() * 4;
}
ERR_FAIL_COND(bucket_table_size == 0);
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);
@ -152,7 +157,7 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
for (int i = 0; i < size; i++) {
const Map<uint32_t, int> &t = table[i];
Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
continue;
@ -173,6 +178,8 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
}
}
print_line("total collisions: " + itos(collisions));
strings.resize(total_compression_size);
PoolVector<uint8_t>::Write cw = strings.write();
@ -191,11 +198,15 @@ 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;
@ -237,7 +248,11 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
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
}
@ -256,7 +271,9 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
}
}
//print_line("bucket pos: "+itos(idx));
if (idx == -1) {
//print_line("GETMSG: Not in Bucket!");
return StringName();
}
@ -264,6 +281,8 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
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 {
@ -273,6 +292,8 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
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;
}
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef COMPRESSED_TRANSLATION_H
#define COMPRESSED_TRANSLATION_H
#include "core/translation.h"
#include "translation.h"
class PHashTranslation : public Translation {

View File

@ -1,308 +0,0 @@
"""Functions used to generate source files during build time
All such functions are invoked in a subprocess on Windows to prevent build flakiness.
"""
from platform_methods import subprocess_main
from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
def make_certs_header(target, source, env):
src = source[0]
dst = target[0]
f = open(src, "rb")
g = open_utf8(dst, "w")
buf = f.read()
decomp_size = len(buf)
import zlib
buf = zlib.compress(buf)
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _CERTS_RAW_H\n")
g.write("#define _CERTS_RAW_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" + byte_to_str(buf[i]) + ",\n")
g.write("};\n")
g.write("#endif")
g.close()
f.close()
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 = source[0]
dst = target[0]
f = open_utf8(src, "r")
g = open_utf8(dst, "w")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _EDITOR_AUTHORS_H\n")
g.write("#define _EDITOR_AUTHORS_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\n")
g.close()
f.close()
def make_donors_header(target, source, env):
sections = [
"Platinum sponsors",
"Gold sponsors",
"Silver sponsors",
"Bronze sponsors",
"Mini sponsors",
"Gold donors",
"Silver donors",
"Bronze donors",
]
sections_id = [
"DONORS_SPONSOR_PLATINUM",
"DONORS_SPONSOR_GOLD",
"DONORS_SPONSOR_SILVER",
"DONORS_SPONSOR_BRONZE",
"DONORS_SPONSOR_MINI",
"DONORS_GOLD",
"DONORS_SILVER",
"DONORS_BRONZE",
]
src = source[0]
dst = target[0]
f = open_utf8(src, "r")
g = open_utf8(dst, "w")
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef _EDITOR_DONORS_H\n")
g.write("#define _EDITOR_DONORS_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\n")
g.close()
f.close()
def make_license_header(target, source, env):
src_copyright = source[0]
src_license = source[1]
dst = 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 = OrderedDict()
license_list = []
with open_utf8(src_copyright, "r") 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":
# attach 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 not "Files" in part:
# no Files tag in this one, so assume standalone license
license_list.append(part["License"])
part = {}
reader.next_line()
data_list = []
for project in itervalues(projects):
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_utf8(dst, "w") as f:
f.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
f.write("#ifndef _EDITOR_LICENSE_H\n")
f.write("#define _EDITOR_LICENSE_H\n")
f.write("const char *const GODOT_LICENSE_TEXT =")
with open_utf8(src_license, "r") 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 iteritems(projects):
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 iteritems(projects):
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 l in license_list:
f.write('\t"' + escape_string(l[0]) + '",\n')
f.write("};\n\n")
f.write("const char *const LICENSE_BODIES[] = {\n\n")
for l in license_list:
for line in l[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\n")
if __name__ == "__main__":
subprocess_main(globals())

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -44,31 +44,31 @@ CoreStringNames::CoreStringNames() :
_iter_next(StaticCString::create("_iter_next")),
_iter_get(StaticCString::create("_iter_get")),
get_rid(StaticCString::create("get_rid")),
_to_string(StaticCString::create("_to_string")),
#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")) {
_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

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef CORE_STRING_NAMES_H
#define CORE_STRING_NAMES_H
#include "core/string_name.h"
#include "string_db.h"
class CoreStringNames {
@ -62,7 +62,6 @@ public:
StringName _iter_next;
StringName _iter_get;
StringName get_rid;
StringName _to_string;
#ifdef TOOLS_ENABLED
StringName _sections_unfolded;
#endif

View File

@ -1,391 +0,0 @@
/*************************************************************************/
/* cowdata.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 COWDATA_H_
#define COWDATA_H_
#include <string.h>
#include "core/error_macros.h"
#include "core/os/memory.h"
#include "core/safe_refcount.h"
template <class T>
class Vector;
class String;
class CharString;
template <class T, class V>
class VMap;
#if !defined(NO_THREADS)
SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t)
#endif
template <class T>
class CowData {
template <class TV>
friend class Vector;
friend class String;
friend class CharString;
template <class TV, class VV>
friend class VMap;
private:
mutable T *_ptr;
// internal helpers
_FORCE_INLINE_ SafeNumeric<uint32_t> *_get_refcount() const {
if (!_ptr)
return NULL;
return reinterpret_cast<SafeNumeric<uint32_t> *>(_ptr) - 2;
}
_FORCE_INLINE_ uint32_t *_get_size() const {
if (!_ptr)
return NULL;
return reinterpret_cast<uint32_t *>(_ptr) - 1;
}
_FORCE_INLINE_ T *_get_data() const {
if (!_ptr)
return NULL;
return reinterpret_cast<T *>(_ptr);
}
_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
return next_power_of_2(p_elements * sizeof(T));
}
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
#if defined(_add_overflow) && defined(_mul_overflow)
size_t o;
size_t p;
if (_mul_overflow(p_elements, sizeof(T), &o)) {
*out = 0;
return false;
}
*out = next_power_of_2(o);
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
return true;
#else
// Speed is more important than correctness here, do the operations unchecked
// and hope the best
*out = _get_alloc_size(p_elements);
return true;
#endif
}
void _unref(void *p_data);
void _ref(const CowData *p_from);
void _ref(const CowData &p_from);
uint32_t _copy_on_write();
public:
void operator=(const CowData<T> &p_from) { _ref(p_from); }
_FORCE_INLINE_ T *ptrw() {
_copy_on_write();
return (T *)_get_data();
}
_FORCE_INLINE_ const T *ptr() const {
return _get_data();
}
_FORCE_INLINE_ int size() const {
uint32_t *size = (uint32_t *)_get_size();
if (size)
return *size;
else
return 0;
}
_FORCE_INLINE_ void clear() { resize(0); }
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
_get_data()[p_index] = p_elem;
}
_FORCE_INLINE_ T &get_m(int p_index) {
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
return _get_data()[p_index];
}
_FORCE_INLINE_ const T &get(int p_index) const {
CRASH_BAD_INDEX(p_index, size());
return _get_data()[p_index];
}
Error resize(int p_size);
_FORCE_INLINE_ void remove(int p_index) {
ERR_FAIL_INDEX(p_index, size());
T *p = ptrw();
int len = size();
for (int i = p_index; i < len - 1; i++) {
p[i] = p[i + 1];
};
resize(len - 1);
};
Error insert(int p_pos, const T &p_val) {
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
resize(size() + 1);
for (int i = (size() - 1); i > p_pos; i--)
set(i, get(i - 1));
set(p_pos, p_val);
return OK;
};
int find(const T &p_val, int p_from = 0) const;
_FORCE_INLINE_ CowData();
_FORCE_INLINE_ ~CowData();
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
};
template <class T>
void CowData<T>::_unref(void *p_data) {
if (!p_data)
return;
SafeNumeric<uint32_t> *refc = _get_refcount();
if (refc->decrement() > 0)
return; // still in use
// clean up
if (!__has_trivial_destructor(T)) {
uint32_t *count = _get_size();
T *data = (T *)(count + 1);
for (uint32_t i = 0; i < *count; ++i) {
// call destructors
data[i].~T();
}
}
// free mem
Memory::free_static((uint8_t *)p_data, true);
}
template <class T>
uint32_t CowData<T>::_copy_on_write() {
if (!_ptr)
return 0;
SafeNumeric<uint32_t> *refc = _get_refcount();
uint32_t rc = refc->get();
if (likely(rc > 1)) {
/* in use by more than me */
uint32_t current_size = *_get_size();
uint32_t *mem_new = (uint32_t *)Memory::alloc_static(_get_alloc_size(current_size), true);
new (mem_new - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
*(mem_new - 1) = current_size; //size
T *_data = (T *)(mem_new);
// initialize new elements
if (__has_trivial_copy(T)) {
memcpy(mem_new, _ptr, current_size * sizeof(T));
} else {
for (uint32_t i = 0; i < current_size; i++) {
memnew_placement(&_data[i], T(_get_data()[i]));
}
}
_unref(_ptr);
_ptr = _data;
rc = 1;
}
return rc;
}
template <class T>
Error CowData<T>::resize(int p_size) {
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
int current_size = size();
if (p_size == current_size)
return OK;
if (p_size == 0) {
// wants to clean up
_unref(_ptr);
_ptr = NULL;
return OK;
}
// possibly changing size, copy on write
uint32_t rc = _copy_on_write();
size_t current_alloc_size = _get_alloc_size(current_size);
size_t alloc_size;
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
if (p_size > current_size) {
if (alloc_size != current_alloc_size) {
if (current_size == 0) {
// alloc from scratch
uint32_t *ptr = (uint32_t *)Memory::alloc_static(alloc_size, true);
ERR_FAIL_COND_V(!ptr, ERR_OUT_OF_MEMORY);
*(ptr - 1) = 0; //size, currently none
new (ptr - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(1); //refcount
_ptr = (T *)ptr;
} else {
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
_ptr = (T *)(_ptrnew);
}
}
// construct the newly created elements
if (!__has_trivial_constructor(T)) {
T *elems = _get_data();
for (int i = *_get_size(); i < p_size; i++) {
memnew_placement(&elems[i], T);
}
}
*_get_size() = p_size;
} else if (p_size < current_size) {
if (!__has_trivial_destructor(T)) {
// deinitialize no longer needed elements
for (uint32_t i = p_size; i < *_get_size(); i++) {
T *t = &_get_data()[i];
t->~T();
}
}
if (alloc_size != current_alloc_size) {
uint32_t *_ptrnew = (uint32_t *)Memory::realloc_static(_ptr, alloc_size, true);
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
new (_ptrnew - 2, sizeof(uint32_t), "") SafeNumeric<uint32_t>(rc); //refcount
_ptr = (T *)(_ptrnew);
}
*_get_size() = p_size;
}
return OK;
}
template <class T>
int CowData<T>::find(const T &p_val, int p_from) const {
int ret = -1;
if (p_from < 0 || size() == 0) {
return ret;
}
for (int i = p_from; i < size(); i++) {
if (get(i) == p_val) {
ret = i;
break;
}
}
return ret;
}
template <class T>
void CowData<T>::_ref(const CowData *p_from) {
_ref(*p_from);
}
template <class T>
void CowData<T>::_ref(const CowData &p_from) {
if (_ptr == p_from._ptr)
return; // self assign, do nothing.
_unref(_ptr);
_ptr = NULL;
if (!p_from._ptr)
return; //nothing to do
if (p_from._get_refcount()->conditional_increment() > 0) { // could reference
_ptr = p_from._ptr;
}
}
template <class T>
CowData<T>::CowData() {
_ptr = NULL;
}
template <class T>
CowData<T>::~CowData() {
_unref(_ptr);
}
#endif /* COW_H_ */

View File

@ -1,40 +0,0 @@
#!/usr/bin/env python
Import("env")
env_crypto = env.Clone()
is_builtin = env["builtin_mbedtls"]
has_module = env["module_mbedtls_enabled"]
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:
env_thirdparty = env_crypto.Clone()
env_thirdparty.disable_warnings()
# Custom config file
env_thirdparty.Append(
CPPDEFINES=[("MBEDTLS_CONFIG_FILE", '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')]
)
thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/"
thirdparty_mbedtls_sources = [
"aes.c",
"base64.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(env.core_sources, thirdparty_mbedtls_sources)
env_crypto.add_source_files(env.core_sources, "*.cpp")

View File

@ -1,158 +0,0 @@
/*************************************************************************/
/* crypto.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "crypto.h"
#include "core/engine.h"
#include "core/io/certs_compressed.gen.h"
#include "core/io/compression.h"
/// Resources
CryptoKey *(*CryptoKey::_create)() = NULL;
CryptoKey *CryptoKey::create() {
if (_create)
return _create();
return NULL;
}
void CryptoKey::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &CryptoKey::save);
ClassDB::bind_method(D_METHOD("load", "path"), &CryptoKey::load);
}
X509Certificate *(*X509Certificate::_create)() = NULL;
X509Certificate *X509Certificate::create() {
if (_create)
return _create();
return NULL;
}
void X509Certificate::_bind_methods() {
ClassDB::bind_method(D_METHOD("save", "path"), &X509Certificate::save);
ClassDB::bind_method(D_METHOD("load", "path"), &X509Certificate::load);
}
/// Crypto
void (*Crypto::_load_default_certificates)(String p_path) = NULL;
Crypto *(*Crypto::_create)() = NULL;
Crypto *Crypto::create() {
if (_create)
return _create();
ERR_FAIL_V_MSG(NULL, "Crypto is not available when the mbedtls module is disabled.");
}
void Crypto::load_default_certificates(String p_path) {
if (_load_default_certificates)
_load_default_certificates(p_path);
}
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"));
}
Crypto::Crypto() {
}
/// Resource loader/saver
RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error) {
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);
return key;
}
return NULL;
}
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("crt");
p_extensions->push_back("key");
}
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")
return "CryptoKey";
return "";
}
Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, 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()) {
err = key->save(p_path);
} else {
ERR_FAIL_V(ERR_INVALID_PARAMETER);
}
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Crypto resource to file '" + p_path + "'.");
return OK;
}
void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &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) {
p_extensions->push_back("key");
}
}
bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
}

View File

@ -1,101 +0,0 @@
/*************************************************************************/
/* crypto.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 CRYPTO_H
#define CRYPTO_H
#include "core/reference.h"
#include "core/resource.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
class CryptoKey : public Resource {
GDCLASS(CryptoKey, Resource);
protected:
static void _bind_methods();
static CryptoKey *(*_create)();
public:
static CryptoKey *create();
virtual Error load(String p_path) = 0;
virtual Error save(String p_path) = 0;
};
class X509Certificate : public Resource {
GDCLASS(X509Certificate, Resource);
protected:
static void _bind_methods();
static X509Certificate *(*_create)();
public:
static X509Certificate *create();
virtual Error load(String p_path) = 0;
virtual Error load_from_memory(const uint8_t *p_buffer, int p_len) = 0;
virtual Error save(String p_path) = 0;
};
class Crypto : public Reference {
GDCLASS(Crypto, Reference);
protected:
static void _bind_methods();
static Crypto *(*_create)();
static void (*_load_default_certificates)(String p_path);
public:
static Crypto *create();
static void load_default_certificates(String p_path);
virtual PoolByteArray 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, String p_issuer_name, String p_not_before, String p_not_after) = 0;
Crypto();
};
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
virtual bool recognize(const RES &p_resource) const;
};
#endif // CRYPTO_H

View File

@ -1,183 +0,0 @@
/*************************************************************************/
/* crypto_core.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "crypto_core.h"
#include <mbedtls/aes.h>
#include <mbedtls/base64.h>
#include <mbedtls/md5.h>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
// 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::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;
}
// CryptoCore
String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) {
int b64len = p_src_len / 3 * 4 + 4 + 1;
PoolVector<uint8_t> b64buff;
b64buff.resize(b64len);
PoolVector<uint8_t>::Write w64 = b64buff.write();
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,104 +0,0 @@
/*************************************************************************/
/* crypto_core.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 CRYPTO_CORE_H
#define CRYPTO_CORE_H
#include "core/reference.h"
class CryptoCore {
public:
class MD5Context {
private:
void *ctx; // To include, or not to include...
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; // To include, or not to include...
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; // To include, or not to include...
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; // To include, or not to include...
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]);
};
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,138 +0,0 @@
/*************************************************************************/
/* hashing_context.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "hashing_context.h"
#include "core/crypto/crypto_core.h"
Error HashingContext::start(HashType p_type) {
ERR_FAIL_COND_V(ctx != NULL, ERR_ALREADY_IN_USE);
_create_ctx(p_type);
ERR_FAIL_COND_V(ctx == NULL, 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(PoolByteArray p_chunk) {
ERR_FAIL_COND_V(ctx == NULL, ERR_UNCONFIGURED);
size_t len = p_chunk.size();
ERR_FAIL_COND_V(len == 0, FAILED);
PoolByteArray::Read r = p_chunk.read();
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;
}
PoolByteArray HashingContext::finish() {
ERR_FAIL_COND_V(ctx == NULL, PoolByteArray());
PoolByteArray out;
Error err = FAILED;
switch (type) {
case HASH_MD5:
out.resize(16);
err = ((CryptoCore::MD5Context *)ctx)->finish(out.write().ptr());
break;
case HASH_SHA1:
out.resize(20);
err = ((CryptoCore::SHA1Context *)ctx)->finish(out.write().ptr());
break;
case HASH_SHA256:
out.resize(32);
err = ((CryptoCore::SHA256Context *)ctx)->finish(out.write().ptr());
break;
}
_delete_ctx();
ERR_FAIL_COND_V(err != OK, PoolByteArray());
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 = NULL;
}
}
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 = NULL;
}
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() {
ctx = NULL;
}
HashingContext::~HashingContext() {
if (ctx != NULL)
_delete_ctx();
}

View File

@ -1,66 +0,0 @@
/*************************************************************************/
/* hashing_context.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 HASHING_CONTEXT_H
#define HASHING_CONTEXT_H
#include "core/reference.h"
class HashingContext : public Reference {
GDCLASS(HashingContext, Reference);
public:
enum HashType {
HASH_MD5,
HASH_SHA1,
HASH_SHA256
};
private:
void *ctx;
HashType type;
protected:
static void _bind_methods();
void _create_ctx(HashType p_type);
void _delete_ctx();
public:
Error start(HashType p_type);
Error update(PoolByteArray p_chunk);
PoolByteArray finish();
HashingContext();
~HashingContext();
};
VARIANT_ENUM_CAST(HashingContext::HashType);
#endif // HASHING_CONTEXT_H

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,9 +30,9 @@
#include "dictionary.h"
#include "core/ordered_hash_map.h"
#include "core/safe_refcount.h"
#include "core/variant.h"
#include "ordered_hash_map.h"
#include "safe_refcount.h"
#include "variant.h"
struct DictionaryPrivate {
@ -50,32 +50,6 @@ void Dictionary::get_key_list(List<Variant> *p_keys) const {
}
}
Variant Dictionary::get_key_at_index(int p_index) const {
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
return E.key();
}
index++;
}
return Variant();
}
Variant Dictionary::get_value_at_index(int p_index) const {
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
return E.value();
}
index++;
}
return Variant();
}
Variant &Dictionary::operator[](const Variant &p_key) {
return _p->variant_map[p_key];
@ -112,15 +86,6 @@ Variant Dictionary::get_valid(const Variant &p_key) const {
return E.get();
}
Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
const Variant *result = getptr(p_key);
if (!result) {
return p_default;
}
return *result;
}
int Dictionary::size() const {
return _p->variant_map.size();
@ -144,9 +109,9 @@ bool Dictionary::has_all(const Array &p_keys) const {
return true;
}
bool Dictionary::erase(const Variant &p_key) {
void Dictionary::erase(const Variant &p_key) {
return _p->variant_map.erase(p_key);
_p->variant_map.erase(p_key);
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
@ -154,11 +119,6 @@ bool Dictionary::operator==(const Dictionary &p_dictionary) const {
return _p == p_dictionary._p;
}
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
return _p != p_dictionary._p;
}
void Dictionary::_ref(const Dictionary &p_from) const {
//make a copy first (thread safe)
@ -192,9 +152,13 @@ uint32_t Dictionary::hash() const {
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
h = hash_djb2_one_32(E.key().hash(), h);
h = hash_djb2_one_32(E.value().hash(), h);
List<Variant> keys;
get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
h = hash_djb2_one_32(E->get().hash(), h);
h = hash_djb2_one_32(operator[](E->get()).hash(), h);
}
return h;
@ -203,11 +167,10 @@ uint32_t Dictionary::hash() const {
Array Dictionary::keys() const {
Array varr;
varr.resize(size());
if (_p->variant_map.empty())
return varr;
varr.resize(size());
int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
varr[i] = E.key();
@ -220,11 +183,10 @@ Array Dictionary::keys() const {
Array Dictionary::values() const {
Array varr;
varr.resize(size());
if (_p->variant_map.empty())
return varr;
varr.resize(size());
int i = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
varr[i] = E.get();
@ -249,12 +211,15 @@ const Variant *Dictionary::next(const Variant *p_key) const {
return NULL;
}
Dictionary Dictionary::duplicate(bool p_deep) const {
Dictionary Dictionary::duplicate() const {
Dictionary n;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
n[E.key()] = p_deep ? E.value().duplicate(true) : E.value();
List<Variant> keys;
get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
n[E->get()] = operator[](E->get());
}
return n;
@ -265,10 +230,6 @@ void Dictionary::operator=(const Dictionary &p_dictionary) {
_ref(p_dictionary);
}
const void *Dictionary::id() const {
return _p->variant_map.id();
}
Dictionary::Dictionary(const Dictionary &p_from) {
_p = NULL;
_ref(p_from);

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,10 +31,9 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
#include "core/array.h"
#include "core/list.h"
#include "core/ustring.h"
#include "array.h"
#include "list.h"
#include "ustring.h"
class Variant;
struct DictionaryPrivate;
@ -48,8 +47,6 @@ class Dictionary {
public:
void get_key_list(List<Variant> *p_keys) const;
Variant get_key_at_index(int p_index) const;
Variant get_value_at_index(int p_index) const;
Variant &operator[](const Variant &p_key);
const Variant &operator[](const Variant &p_key) const;
@ -58,7 +55,6 @@ public:
Variant *getptr(const Variant &p_key);
Variant get_valid(const Variant &p_key) const;
Variant get(const Variant &p_key, const Variant &p_default) const;
int size() const;
bool empty() const;
@ -67,10 +63,9 @@ public:
bool has(const Variant &p_key) const;
bool has_all(const Array &p_keys) const;
bool erase(const Variant &p_key);
void erase(const Variant &p_key);
bool operator==(const Dictionary &p_dictionary) const;
bool operator!=(const Dictionary &p_dictionary) const;
uint32_t hash() const;
void operator=(const Dictionary &p_dictionary);
@ -80,9 +75,7 @@ public:
Array keys() const;
Array values() const;
Dictionary duplicate(bool p_deep = false) const;
const void *id() const;
Dictionary duplicate() const;
Dictionary(const Dictionary &p_from);
Dictionary();

71
core/dvector.cpp Normal file
View File

@ -0,0 +1,71 @@
/*************************************************************************/
/* dvector.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 "dvector.h"
Mutex *dvector_lock = NULL;
PoolAllocator *MemoryPool::memory_pool = NULL;
uint8_t *MemoryPool::pool_memory = NULL;
size_t *MemoryPool::pool_size = NULL;
MemoryPool::Alloc *MemoryPool::allocs = NULL;
MemoryPool::Alloc *MemoryPool::free_list = NULL;
uint32_t MemoryPool::alloc_count = 0;
uint32_t MemoryPool::allocs_used = 0;
Mutex *MemoryPool::alloc_mutex = NULL;
size_t MemoryPool::total_memory = 0;
size_t MemoryPool::max_memory = 0;
void MemoryPool::setup(uint32_t p_max_allocs) {
allocs = memnew_arr(Alloc, p_max_allocs);
alloc_count = p_max_allocs;
allocs_used = 0;
for (uint32_t i = 0; i < alloc_count - 1; i++) {
allocs[i].free_list = &allocs[i + 1];
}
free_list = &allocs[0];
alloc_mutex = Mutex::create();
}
void MemoryPool::cleanup() {
memdelete_arr(allocs);
memdelete(alloc_mutex);
ERR_EXPLAINC("There are still MemoryPool allocs in use at exit!");
ERR_FAIL_COND(allocs_used > 0);
}

643
core/dvector.h Normal file
View File

@ -0,0 +1,643 @@
/*************************************************************************/
/* dvector.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 DVECTOR_H
#define DVECTOR_H
#include "os/copymem.h"
#include "os/memory.h"
#include "os/rw_lock.h"
#include "pool_allocator.h"
#include "safe_refcount.h"
#include "ustring.h"
struct MemoryPool {
//avoid accessing these directly, must be public for template access
static PoolAllocator *memory_pool;
static uint8_t *pool_memory;
static size_t *pool_size;
struct Alloc {
SafeRefCount refcount;
uint32_t lock;
void *mem;
PoolAllocator::ID pool_id;
size_t size;
Alloc *free_list;
Alloc() {
mem = NULL;
lock = 0;
pool_id = POOL_ALLOCATOR_INVALID_ID;
size = 0;
free_list = NULL;
}
};
static Alloc *allocs;
static Alloc *free_list;
static uint32_t alloc_count;
static uint32_t allocs_used;
static Mutex *alloc_mutex;
static size_t total_memory;
static size_t max_memory;
static void setup(uint32_t p_max_allocs = (1 << 16));
static void cleanup();
};
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
template <class T>
class PoolVector {
MemoryPool::Alloc *alloc;
void _copy_on_write() {
if (!alloc)
return;
// ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all
// Refcount should not be zero, otherwise it's a misuse of COW
if (alloc->refcount.get() == 1)
return; //nothing to do
//must allocate something
MemoryPool::alloc_mutex->lock();
if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
MemoryPool::alloc_mutex->unlock();
ERR_EXPLAINC("All memory pool allocations are in use, can't COW.");
ERR_FAIL();
}
MemoryPool::Alloc *old_alloc = alloc;
//take one from the free list
alloc = MemoryPool::free_list;
MemoryPool::free_list = alloc->free_list;
//increment the used counter
MemoryPool::allocs_used++;
//copy the alloc data
alloc->size = old_alloc->size;
alloc->refcount.init();
alloc->pool_id = POOL_ALLOCATOR_INVALID_ID;
alloc->lock = 0;
#ifdef DEBUG_ENABLED
MemoryPool::total_memory += alloc->size;
if (MemoryPool::total_memory > MemoryPool::max_memory) {
MemoryPool::max_memory = MemoryPool::total_memory;
}
#endif
MemoryPool::alloc_mutex->unlock();
if (MemoryPool::memory_pool) {
} else {
alloc->mem = memalloc(alloc->size);
}
{
Write w;
w._ref(alloc);
Read r;
r._ref(old_alloc);
int cur_elements = alloc->size / sizeof(T);
T *dst = (T *)w.ptr();
const T *src = (const T *)r.ptr();
for (int i = 0; i < cur_elements; i++) {
memnew_placement(&dst[i], T(src[i]));
}
}
if (old_alloc->refcount.unref() == true) {
//this should never happen but..
#ifdef DEBUG_ENABLED
MemoryPool::alloc_mutex->lock();
MemoryPool::total_memory -= old_alloc->size;
MemoryPool::alloc_mutex->unlock();
#endif
{
Write w;
w._ref(old_alloc);
int cur_elements = old_alloc->size / sizeof(T);
T *elems = (T *)w.ptr();
for (int i = 0; i < cur_elements; i++) {
elems[i].~T();
}
}
if (MemoryPool::memory_pool) {
//resize memory pool
//if none, create
//if some resize
} else {
memfree(old_alloc->mem);
old_alloc->mem = NULL;
old_alloc->size = 0;
MemoryPool::alloc_mutex->lock();
old_alloc->free_list = MemoryPool::free_list;
MemoryPool::free_list = old_alloc;
MemoryPool::allocs_used--;
MemoryPool::alloc_mutex->unlock();
}
}
}
void _reference(const PoolVector &p_dvector) {
if (alloc == p_dvector.alloc)
return;
_unreference();
if (!p_dvector.alloc) {
return;
}
if (p_dvector.alloc->refcount.ref()) {
alloc = p_dvector.alloc;
}
}
void _unreference() {
if (!alloc)
return;
if (alloc->refcount.unref() == false) {
alloc = NULL;
return;
}
//must be disposed!
{
int cur_elements = alloc->size / sizeof(T);
// Don't use write() here because it could otherwise provoke COW,
// which is not desirable here because we are destroying the last reference anyways
Write w;
// Reference to still prevent other threads from touching the alloc
w._ref(alloc);
for (int i = 0; i < cur_elements; i++) {
w[i].~T();
}
}
#ifdef DEBUG_ENABLED
MemoryPool::alloc_mutex->lock();
MemoryPool::total_memory -= alloc->size;
MemoryPool::alloc_mutex->unlock();
#endif
if (MemoryPool::memory_pool) {
//resize memory pool
//if none, create
//if some resize
} else {
memfree(alloc->mem);
alloc->mem = NULL;
alloc->size = 0;
MemoryPool::alloc_mutex->lock();
alloc->free_list = MemoryPool::free_list;
MemoryPool::free_list = alloc;
MemoryPool::allocs_used--;
MemoryPool::alloc_mutex->unlock();
}
alloc = NULL;
}
public:
class Access {
friend class PoolVector;
protected:
MemoryPool::Alloc *alloc;
T *mem;
_FORCE_INLINE_ void _ref(MemoryPool::Alloc *p_alloc) {
alloc = p_alloc;
if (alloc) {
if (atomic_increment(&alloc->lock) == 1) {
if (MemoryPool::memory_pool) {
//lock it and get mem
}
}
mem = (T *)alloc->mem;
}
}
_FORCE_INLINE_ void _unref() {
if (alloc) {
if (atomic_decrement(&alloc->lock) == 0) {
if (MemoryPool::memory_pool) {
//put mem back
}
}
mem = NULL;
alloc = NULL;
}
}
Access() {
alloc = NULL;
mem = NULL;
}
public:
virtual ~Access() {
_unref();
}
};
class Read : public Access {
public:
_FORCE_INLINE_ const T &operator[](int p_index) const { return this->mem[p_index]; }
_FORCE_INLINE_ const T *ptr() const { return this->mem; }
void operator=(const Read &p_read) {
if (this->alloc == p_read.alloc)
return;
this->_unref();
this->_ref(p_read.alloc);
}
Read(const Read &p_read) {
this->_ref(p_read.alloc);
}
Read() {}
};
class Write : public Access {
public:
_FORCE_INLINE_ T &operator[](int p_index) const { return this->mem[p_index]; }
_FORCE_INLINE_ T *ptr() const { return this->mem; }
void operator=(const Write &p_read) {
if (this->alloc == p_read.alloc)
return;
this->_unref();
this->_ref(p_read.alloc);
}
Write(const Write &p_read) {
this->_ref(p_read.alloc);
}
Write() {}
};
Read read() const {
Read r;
if (alloc) {
r._ref(alloc);
}
return r;
}
Write write() {
Write w;
if (alloc) {
_copy_on_write(); //make sure there is only one being acessed
w._ref(alloc);
}
return w;
}
template <class MC>
void fill_with(const MC &p_mc) {
int c = p_mc.size();
resize(c);
Write w = write();
int idx = 0;
for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) {
w[idx++] = E->get();
}
}
void remove(int p_index) {
int s = size();
ERR_FAIL_INDEX(p_index, s);
Write w = write();
for (int i = p_index; i < s - 1; i++) {
w[i] = w[i + 1];
};
w = Write();
resize(s - 1);
}
inline int size() const;
T get(int p_index) const;
void set(int p_index, const T &p_val);
void push_back(const T &p_val);
void append(const T &p_val) { push_back(p_val); }
void append_array(const PoolVector<T> &p_arr) {
int ds = p_arr.size();
if (ds == 0)
return;
int bs = size();
resize(bs + ds);
Write w = write();
Read r = p_arr.read();
for (int i = 0; i < ds; i++)
w[bs + i] = r[i];
}
PoolVector<T> subarray(int p_from, int p_to) {
if (p_from < 0) {
p_from = size() + p_from;
}
if (p_to < 0) {
p_to = size() + p_to;
}
CRASH_BAD_INDEX(p_from, size());
CRASH_BAD_INDEX(p_to, size());
PoolVector<T> slice;
int span = 1 + p_to - p_from;
slice.resize(span);
Read r = read();
Write w = slice.write();
for (int i = 0; i < span; ++i) {
w[i] = r[p_from + i];
}
return slice;
}
Error insert(int p_pos, const T &p_val) {
int s = size();
ERR_FAIL_INDEX_V(p_pos, s + 1, ERR_INVALID_PARAMETER);
resize(s + 1);
{
Write w = write();
for (int i = s; i > p_pos; i--)
w[i] = w[i - 1];
w[p_pos] = p_val;
}
return OK;
}
String join(String delimiter) {
String rs = "";
int s = size();
Read r = read();
for (int i = 0; i < s; i++) {
rs += r[i] + delimiter;
}
rs.erase(rs.length() - delimiter.length(), delimiter.length());
return rs;
}
bool is_locked() const { return alloc && alloc->lock > 0; }
inline const T operator[](int p_index) const;
Error resize(int p_size);
void invert();
void operator=(const PoolVector &p_dvector) { _reference(p_dvector); }
PoolVector() { alloc = NULL; }
PoolVector(const PoolVector &p_dvector) {
alloc = NULL;
_reference(p_dvector);
}
~PoolVector() { _unreference(); }
};
template <class T>
int PoolVector<T>::size() const {
return alloc ? alloc->size / sizeof(T) : 0;
}
template <class T>
T PoolVector<T>::get(int p_index) const {
return operator[](p_index);
}
template <class T>
void PoolVector<T>::set(int p_index, const T &p_val) {
if (p_index < 0 || p_index >= size()) {
ERR_FAIL_COND(p_index < 0 || p_index >= size());
}
Write w = write();
w[p_index] = p_val;
}
template <class T>
void PoolVector<T>::push_back(const T &p_val) {
resize(size() + 1);
set(size() - 1, p_val);
}
template <class T>
const T PoolVector<T>::operator[](int p_index) const {
CRASH_BAD_INDEX(p_index, size());
Read r = read();
return r[p_index];
}
template <class T>
Error PoolVector<T>::resize(int p_size) {
if (alloc == NULL) {
if (p_size == 0)
return OK; //nothing to do here
//must allocate something
MemoryPool::alloc_mutex->lock();
if (MemoryPool::allocs_used == MemoryPool::alloc_count) {
MemoryPool::alloc_mutex->unlock();
ERR_EXPLAINC("All memory pool allocations are in use.");
ERR_FAIL_V(ERR_OUT_OF_MEMORY);
}
//take one from the free list
alloc = MemoryPool::free_list;
MemoryPool::free_list = alloc->free_list;
//increment the used counter
MemoryPool::allocs_used++;
//cleanup the alloc
alloc->size = 0;
alloc->refcount.init();
alloc->pool_id = POOL_ALLOCATOR_INVALID_ID;
MemoryPool::alloc_mutex->unlock();
} else {
ERR_FAIL_COND_V(alloc->lock > 0, ERR_LOCKED); //can't resize if locked!
}
size_t new_size = sizeof(T) * p_size;
if (alloc->size == new_size)
return OK; //nothing to do
if (p_size == 0) {
_unreference();
return OK;
}
_copy_on_write(); // make it unique
#ifdef DEBUG_ENABLED
MemoryPool::alloc_mutex->lock();
MemoryPool::total_memory -= alloc->size;
MemoryPool::total_memory += new_size;
if (MemoryPool::total_memory > MemoryPool::max_memory) {
MemoryPool::max_memory = MemoryPool::total_memory;
}
MemoryPool::alloc_mutex->unlock();
#endif
int cur_elements = alloc->size / sizeof(T);
if (p_size > cur_elements) {
if (MemoryPool::memory_pool) {
//resize memory pool
//if none, create
//if some resize
} else {
if (alloc->size == 0) {
alloc->mem = memalloc(new_size);
} else {
alloc->mem = memrealloc(alloc->mem, new_size);
}
}
alloc->size = new_size;
Write w = write();
for (int i = cur_elements; i < p_size; i++) {
memnew_placement(&w[i], T);
}
} else {
{
Write w = write();
for (int i = p_size; i < cur_elements; i++) {
w[i].~T();
}
}
if (MemoryPool::memory_pool) {
//resize memory pool
//if none, create
//if some resize
} else {
if (new_size == 0) {
memfree(alloc->mem);
alloc->mem = NULL;
alloc->size = 0;
MemoryPool::alloc_mutex->lock();
alloc->free_list = MemoryPool::free_list;
MemoryPool::free_list = alloc;
MemoryPool::allocs_used--;
MemoryPool::alloc_mutex->unlock();
} else {
alloc->mem = memrealloc(alloc->mem, new_size);
alloc->size = new_size;
}
}
}
return OK;
}
template <class T>
void PoolVector<T>::invert() {
T temp;
Write w = write();
int s = size();
int half_s = s / 2;
for (int i = 0; i < half_s; i++) {
temp = w[i];
w[i] = w[s - i - 1];
w[s - i - 1] = temp;
}
}
#endif

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,15 +30,11 @@
#include "engine.h"
#include "core/authors.gen.h"
#include "core/donors.gen.h"
#include "core/license.gen.h"
#include "core/version.h"
#include "core/version_hash.gen.h"
#include "version.h"
#include "version_hash.gen.h"
void Engine::set_iterations_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_iterations_per_second() const {
@ -46,21 +42,11 @@ int Engine::get_iterations_per_second() const {
return ips;
}
void Engine::set_physics_jitter_fix(float p_threshold) {
if (p_threshold < 0)
p_threshold = 0;
physics_jitter_fix = p_threshold;
}
float Engine::get_physics_jitter_fix() const {
return physics_jitter_fix;
}
void Engine::set_target_fps(int p_fps) {
_target_fps = p_fps > 0 ? p_fps : 0;
}
int Engine::get_target_fps() const {
float Engine::get_target_fps() const {
return _target_fps;
}
@ -94,8 +80,11 @@ Dictionary Engine::get_version_info() const {
Dictionary dict;
dict["major"] = VERSION_MAJOR;
dict["minor"] = VERSION_MINOR;
#ifdef VERSION_PATCH
dict["patch"] = VERSION_PATCH;
dict["hex"] = VERSION_HEX;
#else
dict["patch"] = 0;
#endif
dict["status"] = VERSION_STATUS;
dict["build"] = VERSION_BUILD;
dict["year"] = VERSION_YEAR;
@ -112,80 +101,6 @@ Dictionary Engine::get_version_info() const {
return dict;
}
static Array array_from_info(const char *const *info_list) {
Array arr;
for (int i = 0; info_list[i] != NULL; i++) {
arr.push_back(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(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;
}
Array Engine::get_copyright_info() const {
Array 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"] = 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"] = 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["platinum_sponsors"] = array_from_info(DONORS_SPONSOR_PLATINUM);
donors["gold_sponsors"] = array_from_info(DONORS_SPONSOR_GOLD);
donors["silver_sponsors"] = array_from_info(DONORS_SPONSOR_SILVER);
donors["bronze_sponsors"] = array_from_info(DONORS_SPONSOR_BRONZE);
donors["mini_sponsors"] = array_from_info(DONORS_SPONSOR_MINI);
donors["gold_donors"] = array_from_info(DONORS_GOLD);
donors["silver_donors"] = array_from_info(DONORS_SILVER);
donors["bronze_donors"] = array_from_info(DONORS_BRONZE);
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);
}
void Engine::add_singleton(const Singleton &p_singleton) {
singletons.push_back(p_singleton);
@ -195,7 +110,8 @@ void Engine::add_singleton(const Singleton &p_singleton) {
Object *Engine::get_singleton_object(const String &p_name) const {
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
ERR_FAIL_COND_V_MSG(!E, NULL, "Failed to retrieve non-existent singleton '" + p_name + "'.");
ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'");
ERR_FAIL_COND_V(!E, NULL);
return E->get();
};
@ -221,13 +137,11 @@ Engine::Engine() {
singleton = this;
frames_drawn = 0;
ips = 60;
physics_jitter_fix = 0.5;
_physics_interpolation_fraction = 0.0f;
_frame_delay = 0;
_fps = 1;
_target_fps = 0;
_time_scale = 1.0;
_gpu_pixel_snap = false;
_pixel_snap = false;
_physics_frames = 0;
_idle_frames = 0;
_in_physics = false;
@ -235,14 +149,3 @@ Engine::Engine() {
_frame_step = 0;
editor_hint = false;
}
Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr) :
name(p_name),
ptr(p_ptr) {
#ifdef DEBUG_ENABLED
Reference *ref = Object::cast_to<Reference>(p_ptr);
if (ref && !ref->is_referenced()) {
WARN_PRINT("You must use Ref<> to ensure the lifetime of a Reference object intended to be used as a singleton.");
}
#endif
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,10 +31,10 @@
#ifndef ENGINE_H
#define ENGINE_H
#include "core/list.h"
#include "core/os/main_loop.h"
#include "core/ustring.h"
#include "core/vector.h"
#include "list.h"
#include "os/main_loop.h"
#include "ustring.h"
#include "vector.h"
class Engine {
@ -42,7 +42,10 @@ public:
struct Singleton {
StringName name;
Object *ptr;
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL);
Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) :
name(p_name),
ptr(p_ptr) {
}
};
private:
@ -54,13 +57,11 @@ private:
float _frame_step;
int ips;
float physics_jitter_fix;
float _fps;
int _target_fps;
float _time_scale;
bool _gpu_pixel_snap;
bool _pixel_snap;
uint64_t _physics_frames;
float _physics_interpolation_fraction;
uint64_t _idle_frames;
bool _in_physics;
@ -78,11 +79,8 @@ public:
virtual void set_iterations_per_second(int p_ips);
virtual int get_iterations_per_second() const;
void set_physics_jitter_fix(float p_threshold);
float get_physics_jitter_fix() const;
virtual void set_target_fps(int p_fps);
virtual int get_target_fps() const;
virtual float get_target_fps() const;
virtual float get_frames_per_second() const { return _fps; }
@ -93,7 +91,6 @@ public:
bool is_in_physics_frame() const { return _in_physics; }
uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
float get_idle_frame_step() const { return _frame_step; }
float get_physics_interpolation_fraction() const { return _physics_interpolation_fraction; }
void set_time_scale(float p_scale);
float get_time_scale() const;
@ -106,7 +103,7 @@ public:
bool has_singleton(const String &p_name) const;
Object *get_singleton_object(const String &p_name) const;
_FORCE_INLINE_ bool get_use_gpu_pixel_snap() const { return _gpu_pixel_snap; }
_FORCE_INLINE_ bool get_use_pixel_snap() const { return _pixel_snap; }
#ifdef TOOLS_ENABLED
_FORCE_INLINE_ void set_editor_hint(bool p_enabled) { editor_hint = p_enabled; }
@ -117,14 +114,8 @@ public:
#endif
Dictionary get_version_info() const;
Dictionary get_author_info() const;
Array get_copyright_info() const;
Dictionary get_donor_info() const;
Dictionary get_license_info() const;
String get_license_text() const;
Engine();
virtual ~Engine() {}
};
#endif // ENGINE_H

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -39,7 +39,7 @@
*/
enum Error {
OK, // (0)
OK,
FAILED, ///< Generic fail error
ERR_UNAVAILABLE, ///< What is requested is unsupported/unavailable
ERR_UNCONFIGURED, ///< The object being used hasn't been properly set up yet
@ -69,12 +69,12 @@ enum Error {
ERR_CONNECTION_ERROR,
ERR_CANT_ACQUIRE_RESOURCE,
ERR_CANT_FORK,
ERR_INVALID_DATA, ///< Data passed is invalid (30)
ERR_INVALID_DATA, ///< Data passed is invalid (30)
ERR_INVALID_PARAMETER, ///< Parameter passed is invalid
ERR_ALREADY_EXISTS, ///< When adding, item already exists
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, if item does not exist
ERR_DOES_NOT_EXIST, ///< When retrieving/erasing, it item does not exist
ERR_DATABASE_CANT_READ, ///< database is full
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
ERR_DATABASE_CANT_WRITE, ///< database is full (35)
ERR_COMPILATION_FAILED,
ERR_METHOD_NOT_FOUND,
ERR_LINK_FAILED,

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,12 +30,23 @@
#include "error_macros.h"
#include "core/io/logger.h"
#include "core/ustring.h"
#include "io/logger.h"
#include "os/os.h"
bool _err_error_exists = false;
static ErrorHandlerList *error_handler_list = NULL;
void _err_set_last_error(const char *p_err) {
OS::get_singleton()->set_last_error(p_err);
}
void _err_clear_last_error() {
OS::get_singleton()->clear_last_error();
}
void add_error_handler(ErrorHandlerList *p_handler) {
_global_lock();
@ -69,47 +80,28 @@ void remove_error_handler(ErrorHandlerList *p_handler) {
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error, "", p_type);
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), "", p_type);
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) {
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (Logger::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
while (l) {
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type);
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", p_type);
l = l->next;
}
_global_unlock();
if (_err_error_exists) {
OS::get_singleton()->clear_last_error();
_err_error_exists = false;
}
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message, p_type);
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error, p_message.utf8().get_data(), p_type);
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type) {
_err_print_error(p_function, p_file, p_line, p_error.utf8().get_data(), p_message.utf8().get_data(), p_type);
}
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) {
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal) {
String fstr(fatal ? "FATAL: " : "");
String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
}
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal) {
_err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), fatal);
String err(fstr + "Index " + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")");
_err_print_error(p_function, p_file, p_line, err.utf8().get_data());
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,19 +31,17 @@
#ifndef ERROR_MACROS_H
#define ERROR_MACROS_H
#include "core/safe_refcount.h"
#include "core/typedefs.h"
#include "typedefs.h"
/**
* Error macros. Unlike exceptions and asserts, these macros try to maintain consistency and stability
* inside the code. It is recommended to always return processable data, so in case of an error,
* the engine can keep working well.
* inside the code. It is recommended to always return processable data, so in case of an error, the
* engine can stay working well.
* In most cases, bugs and/or invalid data are not fatal and should never allow a perfectly running application
* to fail or crash.
*/
/**
* Pointer to the error macro printing function. Reassign to any function to have errors printed
* Pointer to the error macro priting function. Reassign to any function to have errors printed
*/
/** Function used by the error macros */
@ -57,8 +55,9 @@ enum ErrorHandlerType {
ERR_HANDLER_SHADER,
};
class String;
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _err_set_last_error(const char *p_err);
void _err_clear_last_error();
struct ErrorHandlerList {
@ -78,13 +77,7 @@ void add_error_handler(ErrorHandlerList *p_handler);
void remove_error_handler(ErrorHandlerList *p_handler);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const char *p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal = false);
#ifndef _STR
#define _STR(m_x) #m_x
@ -93,7 +86,30 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define _FNL __FILE__ ":"
/** An index has failed if m_index<0 or m_index >=m_size, the function exits */
/** An index has failed if m_index<0 or m_index >=m_size, the function exists */
extern bool _err_error_exists;
#ifdef DEBUG_ENABLED
/** Print a warning string.
*/
#define ERR_EXPLAINC(m_reason) \
{ \
_err_set_last_error(m_reason); \
_err_error_exists = true; \
}
#define ERR_EXPLAIN(m_string) \
{ \
_err_set_last_error(String(m_string).utf8().get_data()); \
_err_error_exists = true; \
}
#else
#define ERR_EXPLAIN(m_text)
#define ERR_EXPLAINC(m_text)
#endif
#ifdef __GNUC__
//#define FUNCTION_STR __PRETTY_FUNCTION__ - too annoying
@ -113,445 +129,186 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define GENERATE_TRAP __builtin_trap();
#endif
// Used to strip debug messages in release mode
#ifdef DEBUG_ENABLED
#define DEBUG_STR(m_msg) m_msg
#else
#define DEBUG_STR(m_msg) ""
#endif
// (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`, prints a generic
* error message and returns from the function. This macro should be preferred to
* `ERR_FAIL_COND` for bounds checking.
*/
#define ERR_FAIL_INDEX(m_index, m_size) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
return; \
} \
} else \
_err_error_exists = false; \
} while (0); // (*)
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`, prints a custom
* error message and returns from the function. This macro should be preferred to
* `ERR_FAIL_COND_MSG` for bounds checking.
*/
#define ERR_FAIL_INDEX_MSG(m_index, m_size, m_msg) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
return; \
} \
} while (0); // (*)
/** An index has failed if m_index<0 or m_index >=m_size, the function exists.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`,
* prints a generic error message and returns the value specified in `m_retval`.
* This macro should be preferred to `ERR_FAIL_COND_V` for bounds checking.
*/
#define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
return m_retval; \
} \
} else \
_err_error_exists = false; \
} while (0); // (*)
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`,
* prints a custom error message and returns the value specified in `m_retval`.
* This macro should be preferred to `ERR_FAIL_COND_V_MSG` for bounds checking.
*/
#define ERR_FAIL_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
return m_retval; \
} \
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
* We'll return a null reference and try to keep running.
*/
#define CRASH_BAD_INDEX(m_index, m_size) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), true); \
GENERATE_TRAP \
} \
} while (0); // (*)
/**
* If `m_index` is greater than or equal to `m_size`,
* prints a generic error message and returns the value specified in `m_retval`.
* This macro should be preferred to `ERR_FAIL_COND_V` for unsigned bounds checking.
*/
#define ERR_FAIL_UNSIGNED_INDEX(m_index, m_size) \
do { \
if (unlikely((m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
return; \
} \
} while (0); // (*)
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
/**
* If `m_index` is greater than or equal to `m_size`,
* prints a generic error message and returns the value specified in `m_retval`.
* This macro should be preferred to `ERR_FAIL_COND_V` for unsigned bounds checking.
*/
#define ERR_FAIL_UNSIGNED_INDEX_V(m_index, m_size, m_retval) \
do { \
if (unlikely((m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size)); \
return m_retval; \
} \
} while (0); // (*)
/**
* If `m_index` is greater than or equal to `m_size`,
* prints a custom error message and returns the value specified in `m_retval`.
* This macro should be preferred to `ERR_FAIL_COND_V_MSG` for unsigned bounds checking.
*/
#define ERR_FAIL_UNSIGNED_INDEX_V_MSG(m_index, m_size, m_retval, m_msg) \
do { \
if (unlikely((m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), DEBUG_STR(m_msg)); \
return m_retval; \
} \
} while (0); // (*)
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`,
* crashes the engine immediately with a generic error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
* This macro should be preferred to `CRASH_COND` for bounds checking.
*/
#define CRASH_BAD_INDEX(m_index, m_size) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
GENERATE_TRAP \
} \
} while (0); // (*)
/**
* If `m_index` is less than 0 or greater than or equal to `m_size`,
* crashes the engine immediately with a custom error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
* This macro should be preferred to `CRASH_COND` for bounds checking.
*/
#define CRASH_BAD_INDEX_MSG(m_index, m_size, m_msg) \
do { \
if (unlikely((m_index) < 0 || (m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), m_msg, true); \
GENERATE_TRAP \
} \
} while (0); // (*)
/**
* If `m_index` is greater than or equal to `m_size`,
* crashes the engine immediately with a generic error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
* This macro should be preferred to `CRASH_COND` for bounds checking.
*/
#define CRASH_BAD_UNSIGNED_INDEX(m_index, m_size) \
do { \
if (unlikely((m_index) >= (m_size))) { \
_err_print_index_error(FUNCTION_STR, __FILE__, __LINE__, m_index, m_size, _STR(m_index), _STR(m_size), "", true); \
GENERATE_TRAP \
} \
} while (0); // (*)
/**
* If `m_param` is `null`, prints a generic error message and returns from the function.
*/
#define ERR_FAIL_NULL(m_param) \
{ \
if (unlikely(!m_param)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return; \
} \
} else \
_err_error_exists = false; \
}
/**
* If `m_param` is `null`, prints a custom error message and returns from the function.
*/
#define ERR_FAIL_NULL_MSG(m_param, m_msg) \
{ \
if (unlikely(!m_param)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
return; \
} \
}
/**
* If `m_param` is `null`, prints a generic error message and returns the value specified in `m_retval`.
*/
#define ERR_FAIL_NULL_V(m_param, m_retval) \
{ \
if (unlikely(!m_param)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null."); \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter ' " _STR(m_param) " ' is null."); \
return m_retval; \
} \
} else \
_err_error_exists = false; \
}
/**
* If `m_param` is `null`, prints a custom error message and returns the value specified in `m_retval`.
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
*/
#define ERR_FAIL_NULL_V_MSG(m_param, m_retval, m_msg) \
{ \
if (unlikely(!m_param)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Parameter \"" _STR(m_param) "\" is null.", DEBUG_STR(m_msg)); \
return m_retval; \
} \
}
/**
* If `m_cond` evaluates to `true`, prints a generic error message and returns from the function.
*/
#define ERR_FAIL_COND(m_cond) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true."); \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true."); \
return; \
} \
} else \
_err_error_exists = false; \
}
/**
* If `m_cond` evaluates to `true`, prints a custom error message and returns from the function.
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
*/
#define ERR_FAIL_COND_MSG(m_cond, m_msg) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
return; \
} \
}
/**
* If `m_cond` evaluates to `true`, crashes the engine immediately with a generic error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
*/
#define CRASH_COND(m_cond) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true."); \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \
GENERATE_TRAP \
} \
}
/**
* If `m_cond` evaluates to `true`, crashes the engine immediately with a custom error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the function will exit.
* This function returns an error value, if returning Error, please select the most
* appropriate error condition from error_macros.h
*/
#define CRASH_COND_MSG(m_cond, m_msg) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition \"" _STR(m_cond) "\" is true.", DEBUG_STR(m_msg)); \
GENERATE_TRAP \
} \
}
/**
* If `m_cond` evaluates to `true`, prints a generic error message and returns the value specified in `m_retval`.
*/
#define ERR_FAIL_COND_V(m_cond, m_retval) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval)); \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. returned: " _STR(m_retval)); \
return m_retval; \
} \
} else \
_err_error_exists = false; \
}
/**
* If `m_cond` evaluates to `true`, prints a custom error message and returns the value specified in `m_retval`.
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will skip to the next iteration.
*/
#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returned: " _STR(m_retval), DEBUG_STR(m_msg)); \
return m_retval; \
} \
#define ERR_CONTINUE(m_cond) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Continuing..:"); \
continue; \
} else \
_err_error_exists = false; \
}
/**
* If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
/** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert().
* the loop will break
*/
#define ERR_CONTINUE(m_cond) \
#define ERR_BREAK(m_cond) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing."); \
continue; \
} \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition ' " _STR(m_cond) " ' is true. Breaking..:"); \
break; \
} else \
_err_error_exists = false; \
}
/**
* If `m_cond` evaluates to `true`, prints a custom error message and continues the loop the macro is located in.
/** Print an error string and return
*/
#define ERR_CONTINUE_MSG(m_cond, m_msg) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Continuing.", DEBUG_STR(m_msg)); \
continue; \
} \
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
_err_error_exists = false; \
return; \
}
/**
* If `m_cond` evaluates to `true`, prints a generic error message and breaks from the loop the macro is located in.
/** Print an error string and return with value
*/
#define ERR_BREAK(m_cond) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking."); \
break; \
} \
#define ERR_FAIL_V(m_value) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " __STR(m_value)); \
_err_error_exists = false; \
return m_value; \
}
/**
* If `m_cond` evaluates to `true`, prints a custom error message and breaks from the loop the macro is located in.
/** Use this one if there is no sensible fallback, that is, the error is unrecoverable.
*/
#define ERR_BREAK_MSG(m_cond, m_msg) \
{ \
if (unlikely(m_cond)) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Breaking.", DEBUG_STR(m_msg)); \
break; \
} \
#define CRASH_NOW() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \
GENERATE_TRAP \
}
/**
* Prints a generic error message and returns from the function.
/** Print an error string.
*/
#define ERR_FAIL() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed."); \
return; \
}
/**
* Prints a custom error message and returns from the function.
*/
#define ERR_FAIL_MSG(m_msg) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed.", DEBUG_STR(m_msg)); \
return; \
}
/**
* Prints a generic error message and returns the value specified in `m_retval`.
*/
#define ERR_FAIL_V(m_retval) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval)); \
return m_retval; \
}
/**
* Prints a custom error message and returns the value specified in `m_retval`.
*/
#define ERR_FAIL_V_MSG(m_retval, m_msg) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method failed. Returning: " __STR(m_retval), DEBUG_STR(m_msg)); \
return m_retval; \
}
/**
* Crashes the engine immediately with a generic error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
*/
#define CRASH_NOW() \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed."); \
GENERATE_TRAP \
}
/**
* Crashes the engine immediately with a custom error message.
* Only use this if there's no sensible fallback (i.e. the error is unrecoverable).
*/
#define CRASH_NOW_MSG(m_msg) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed.", DEBUG_STR(m_msg)); \
GENERATE_TRAP \
}
/**
* Prints an error message without returning.
*/
#define ERR_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
_err_error_exists = false; \
}
/**
* Prints an error message without returning.
* FIXME: Remove this macro and replace all uses with `ERR_PRINT` as it's identical.
*/
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
#define ERR_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data()); \
_err_error_exists = false; \
}
/**
* Prints an error message without returning, but only do so once in the application lifecycle.
* This can be used to avoid spamming the console with error messages.
/** Print a warning string.
*/
#define ERR_PRINT_ONCE(m_string) \
{ \
static bool first_print = true; \
if (first_print) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
first_print = false; \
} \
}
/**
* Prints a warning message without returning. To warn about deprecated usage,
* use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
#define WARN_PRINT(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
/**
* Prints a warning message without returning.
* FIXME: Remove this macro and replace all uses with `WARN_PRINT` as it's identical.
*/
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
}
/**
* Prints a warning message without returning, but only do so once in the application lifecycle.
* This can be used to avoid spamming the console with warning messages.
*/
#define WARN_PRINT_ONCE(m_string) \
{ \
static bool first_print = true; \
if (first_print) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
first_print = false; \
} \
}
/**
* Prints a generic deprecation warning message without returning.
* This should be preferred to `WARN_PRINT` for deprecation warnings.
*/
#define WARN_DEPRECATED \
{ \
static SafeFlag warning_shown; \
if (!warning_shown.is_set()) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", ERR_HANDLER_WARNING); \
warning_shown.set(); \
} \
}
/**
* Prints a custom deprecation warning message without returning.
* This should be preferred to `WARN_PRINT` for deprecation warnings.
*/
#define WARN_DEPRECATED_MSG(m_msg) \
{ \
static SafeFlag warning_shown; \
if (!warning_shown.is_set()) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future.", m_msg, ERR_HANDLER_WARNING); \
warning_shown.set(); \
} \
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, String(m_string).utf8().get_data(), ERR_HANDLER_WARNING); \
_err_error_exists = false; \
}
#endif

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -46,43 +46,16 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Variant::Call
return obj->call(function, p_args, p_argcount, r_error);
}
Variant FuncRef::call_funcv(const Array &p_args) {
ERR_FAIL_COND_V(id == 0, Variant());
Object *obj = ObjectDB::get_instance(id);
ERR_FAIL_COND_V(!obj, Variant());
return obj->callv(function, p_args);
}
void FuncRef::set_instance(Object *p_obj) {
ERR_FAIL_NULL(p_obj);
id = p_obj->get_instance_id();
}
void FuncRef::set_function(const StringName &p_func) {
function = p_func;
}
StringName FuncRef::get_function() {
return function;
}
bool FuncRef::is_valid() const {
if (id == 0)
return false;
Object *obj = ObjectDB::get_instance(id);
if (!obj)
return false;
return obj->has_method(function);
}
void FuncRef::_bind_methods() {
{
@ -92,17 +65,11 @@ void FuncRef::_bind_methods() {
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "call_func", &FuncRef::call_func, mi, defargs);
}
ClassDB::bind_method(D_METHOD("call_funcv", "arg_array"), &FuncRef::call_funcv);
ClassDB::bind_method(D_METHOD("set_instance", "instance"), &FuncRef::set_instance);
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &FuncRef::get_function);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "function"), "set_function", "get_function");
}
FuncRef::FuncRef() :
id(0) {
FuncRef::FuncRef() {
id = 0;
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef FUNC_REF_H
#define FUNC_REF_H
#include "core/reference.h"
#include "reference.h"
class FuncRef : public Reference {
@ -44,11 +44,8 @@ protected:
public:
Variant call_func(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
Variant call_funcv(const Array &p_args);
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
StringName get_function();
bool is_valid() const;
FuncRef();
};

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,10 +30,10 @@
#include "global_constants.h"
#include "core/object.h"
#include "core/os/input_event.h"
#include "core/os/keyboard.h"
#include "core/variant.h"
#include "object.h"
#include "os/input_event.h"
#include "os/keyboard.h"
#include "variant.h"
struct _GlobalConstant {
@ -89,7 +89,6 @@ VARIANT_ENUM_CAST(KeyList);
VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(ButtonList);
VARIANT_ENUM_CAST(JoystickList);
VARIANT_ENUM_CAST(MidiMessageList);
void register_global_constants() {
@ -379,8 +378,6 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_LEFT);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_RIGHT);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MIDDLE);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_XBUTTON1);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_XBUTTON2);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_UP);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_DOWN);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_WHEEL_LEFT);
@ -388,11 +385,8 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_LEFT);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_RIGHT);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_MIDDLE);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON1);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON2);
//joypads
BIND_GLOBAL_ENUM_CONSTANT(JOY_INVALID_OPTION);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_0);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_1);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_2);
@ -409,12 +403,6 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_13);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_14);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_15);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_16);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_17);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_18);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_19);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_20);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_21);
BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_MAX);
BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CIRCLE);
@ -432,28 +420,12 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_X);
BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_Y);
BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_GRIP);
BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_PAD);
BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_TRIGGER);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_AX);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_BY);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_MENU);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_MENU);
BIND_GLOBAL_ENUM_CONSTANT(JOY_SELECT);
BIND_GLOBAL_ENUM_CONSTANT(JOY_START);
BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_UP);
BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_DOWN);
BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_LEFT);
BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_RIGHT);
BIND_GLOBAL_ENUM_CONSTANT(JOY_MISC1);
BIND_GLOBAL_ENUM_CONSTANT(JOY_PADDLE1);
BIND_GLOBAL_ENUM_CONSTANT(JOY_PADDLE2);
BIND_GLOBAL_ENUM_CONSTANT(JOY_PADDLE3);
BIND_GLOBAL_ENUM_CONSTANT(JOY_PADDLE4);
BIND_GLOBAL_ENUM_CONSTANT(JOY_TOUCHPAD);
BIND_GLOBAL_ENUM_CONSTANT(JOY_L);
BIND_GLOBAL_ENUM_CONSTANT(JOY_L2);
BIND_GLOBAL_ENUM_CONSTANT(JOY_L3);
@ -482,72 +454,49 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_L2);
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_R2);
BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_TRIGGER);
BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_GRIP);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADX);
BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADY);
// midi
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_AFTERTOUCH);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CONTROL_CHANGE);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PROGRAM_CHANGE);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_CHANNEL_PRESSURE);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_PITCH_BEND);
// error list
BIND_GLOBAL_ENUM_CONSTANT(OK); // (0)
BIND_GLOBAL_ENUM_CONSTANT(FAILED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAVAILABLE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNCONFIGURED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAUTHORIZED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_PARAMETER_RANGE_ERROR); // (5)
BIND_GLOBAL_ENUM_CONSTANT(ERR_OUT_OF_MEMORY);
BIND_GLOBAL_ENUM_CONSTANT(OK);
BIND_GLOBAL_ENUM_CONSTANT(FAILED); ///< Generic fail error
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAVAILABLE); ///< What is requested is unsupported/unavailable
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNCONFIGURED); ///< The object being used hasn't been properly set up yet
BIND_GLOBAL_ENUM_CONSTANT(ERR_UNAUTHORIZED); ///< Missing credentials for requested resource
BIND_GLOBAL_ENUM_CONSTANT(ERR_PARAMETER_RANGE_ERROR); ///< Parameter given out of range
BIND_GLOBAL_ENUM_CONSTANT(ERR_OUT_OF_MEMORY); ///< Out of memory
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_NOT_FOUND);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_BAD_DRIVE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_BAD_PATH);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_NO_PERMISSION); // (10)
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_NO_PERMISSION);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_ALREADY_IN_USE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_OPEN);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_WRITE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CANT_READ);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_UNRECOGNIZED); // (15)
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_UNRECOGNIZED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_CORRUPT);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_MISSING_DEPENDENCIES);
BIND_GLOBAL_ENUM_CONSTANT(ERR_FILE_EOF);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_OPEN);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_CREATE); // (20)
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_OPEN); ///< Can't open a resource/socket/file
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_CREATE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_PARSE_ERROR);
BIND_GLOBAL_ENUM_CONSTANT(ERR_QUERY_FAILED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_IN_USE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_LOCKED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_LOCKED); ///< resource is locked
BIND_GLOBAL_ENUM_CONSTANT(ERR_TIMEOUT);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_CONNECT); // (25)
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_RESOLVE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CONNECTION_ERROR);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_ACQUIRE_RESOURCE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CANT_FORK);
BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DATA); // (30)
BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_PARAMETER);
BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_EXISTS);
BIND_GLOBAL_ENUM_CONSTANT(ERR_DOES_NOT_EXIST);
BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_READ);
BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_WRITE); // (35)
BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DATA); ///< Data passed is invalid
BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_PARAMETER); ///< Parameter passed is invalid
BIND_GLOBAL_ENUM_CONSTANT(ERR_ALREADY_EXISTS); ///< When adding ), item already exists
BIND_GLOBAL_ENUM_CONSTANT(ERR_DOES_NOT_EXIST); ///< When retrieving/erasing ), it item does not exist
BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_READ); ///< database is full
BIND_GLOBAL_ENUM_CONSTANT(ERR_DATABASE_CANT_WRITE); ///< database is full
BIND_GLOBAL_ENUM_CONSTANT(ERR_COMPILATION_FAILED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_METHOD_NOT_FOUND);
BIND_GLOBAL_ENUM_CONSTANT(ERR_LINK_FAILED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_SCRIPT_FAILED);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CYCLIC_LINK); // (40)
BIND_GLOBAL_ENUM_CONSTANT(ERR_INVALID_DECLARATION);
BIND_GLOBAL_ENUM_CONSTANT(ERR_DUPLICATE_SYMBOL);
BIND_GLOBAL_ENUM_CONSTANT(ERR_PARSE_ERROR);
BIND_GLOBAL_ENUM_CONSTANT(ERR_CYCLIC_LINK);
BIND_GLOBAL_ENUM_CONSTANT(ERR_BUSY);
BIND_GLOBAL_ENUM_CONSTANT(ERR_SKIP); // (45)
BIND_GLOBAL_ENUM_CONSTANT(ERR_HELP);
BIND_GLOBAL_ENUM_CONSTANT(ERR_BUG);
BIND_GLOBAL_ENUM_CONSTANT(ERR_PRINTER_ON_FIRE);
BIND_GLOBAL_ENUM_CONSTANT(ERR_HELP); ///< user requested help!!
BIND_GLOBAL_ENUM_CONSTANT(ERR_BUG); ///< a bug in the software certainly happened ), due to a double check failing or unexpected behavior.
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_NONE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
@ -569,7 +518,6 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_GLOBAL_DIR);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RESOURCE_TYPE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_MULTILINE_TEXT);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_PLACEHOLDER_TEXT);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_COLOR_NO_ALPHA);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSY);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS);
@ -584,9 +532,8 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
//deprecated, replaced by ClassDB function to check default value
//BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO);
//BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONZERO);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_STORE_IF_NONONE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef GLOBAL_CONSTANTS_H
#define GLOBAL_CONSTANTS_H
#include "core/string_name.h"
#include "string_db.h"
class GlobalConstants {
public:

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,12 +31,12 @@
#ifndef HASH_MAP_H
#define HASH_MAP_H
#include "core/error_macros.h"
#include "core/hashfuncs.h"
#include "core/list.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
#include "core/ustring.h"
#include "error_macros.h"
#include "hashfuncs.h"
#include "list.h"
#include "math_funcs.h"
#include "os/memory.h"
#include "ustring.h"
/**
* @class HashMap
@ -112,7 +112,7 @@ private:
void erase_hash_table() {
ERR_FAIL_COND_MSG(elements, "Cannot erase hash table if there are still elements inside.");
ERR_FAIL_COND(elements);
memdelete_arr(hash_table);
hash_table = 0;
@ -150,29 +150,32 @@ private:
if (new_hash_table_power == -1)
return;
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory.");
Element **new_hash_table = memnew_arr(Element *, (1 << new_hash_table_power));
if (!new_hash_table) {
ERR_PRINT("Out of Memory");
return;
}
for (int i = 0; i < (1 << new_hash_table_power); i++) {
new_hash_table[i] = 0;
}
if (hash_table) {
for (int i = 0; i < (1 << hash_table_power); i++) {
for (int i = 0; i < (1 << hash_table_power); i++) {
while (hash_table[i]) {
while (hash_table[i]) {
Element *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
se->next = new_hash_table[new_pos];
new_hash_table[new_pos] = se;
}
Element *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
se->next = new_hash_table[new_pos];
new_hash_table[new_pos] = se;
}
memdelete_arr(hash_table);
}
if (hash_table)
memdelete_arr(hash_table);
hash_table = new_hash_table;
hash_table_power = new_hash_table_power;
}
@ -204,13 +207,12 @@ private:
/* if element doesn't exist, create it */
Element *e = memnew(Element);
ERR_FAIL_COND_V_MSG(!e, NULL, "Out of memory.");
ERR_FAIL_COND_V(!e, NULL); /* out of memory */
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
e->next = hash_table[index];
e->hash = hash;
e->pair.key = p_key;
e->pair.data = TData();
hash_table[index] = e;
elements++;
@ -228,7 +230,7 @@ private:
if (!p_t.hash_table || p_t.hash_table_power == 0)
return; /* not copying from empty table */
hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power);
hash_table = memnew_arr(Element *, 1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
@ -294,14 +296,14 @@ public:
const TData &get(const TKey &p_key) const {
const TData *res = getptr(p_key);
CRASH_COND_MSG(!res, "Map key not found.");
ERR_FAIL_COND_V(!res, *res);
return *res;
}
TData &get(const TKey &p_key) {
TData *res = getptr(p_key);
CRASH_COND_MSG(!res, "Map key not found.");
ERR_FAIL_COND_V(!res, *res);
return *res;
}
@ -492,7 +494,8 @@ public:
} else { /* get the next key */
const Element *e = get_element(*p_key);
ERR_FAIL_COND_V_MSG(!e, NULL, "Invalid key supplied.");
ERR_FAIL_COND_V(!e, NULL); /* invalid key supplied */
if (e->next) {
/* if there is a "next" in the list, return that */
return &e->next->pair.key;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,12 +31,10 @@
#ifndef HASHFUNCS_H
#define HASHFUNCS_H
#include "core/math/math_defs.h"
#include "core/math/math_funcs.h"
#include "core/node_path.h"
#include "core/string_name.h"
#include "core/typedefs.h"
#include "core/ustring.h"
#include "math_defs.h"
#include "math_funcs.h"
#include "typedefs.h"
#include "ustring.h"
/**
* Hashing functions
@ -133,7 +131,6 @@ static inline uint64_t make_uint64_t(T p_in) {
}
struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
@ -148,10 +145,6 @@ struct HashMapHasherDefault {
static _FORCE_INLINE_ uint32_t hash(const uint8_t p_int) { return p_int; }
static _FORCE_INLINE_ uint32_t hash(const int8_t p_int) { return (uint32_t)p_int; }
static _FORCE_INLINE_ uint32_t hash(const wchar_t p_wchar) { return (uint32_t)p_wchar; }
static _FORCE_INLINE_ uint32_t hash(const StringName &p_string_name) { return p_string_name.hash(); }
static _FORCE_INLINE_ uint32_t hash(const NodePath &p_path) { return p_path.hash(); }
//static _FORCE_INLINE_ uint32_t hash(const void* p_ptr) { return uint32_t(uint64_t(p_ptr))*(0x9e3779b1L); }
};

7
core/helper/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')

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,7 +30,7 @@
#ifdef TOOLS_ENABLED
#include "math_fieldwise.h"
#include "core/helper/math_fieldwise.h"
#define SETUP_TYPE(m_type) \
m_type source = p_source; \

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */

View File

@ -0,0 +1,46 @@
/*************************************************************************/
/* value_evaluator.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 VALUE_EVALUATOR_H
#define VALUE_EVALUATOR_H
#include "core/object.h"
class ValueEvaluator : public Object {
GDCLASS(ValueEvaluator, Object);
public:
virtual double eval(const String &p_text) {
return p_text.to_double();
}
};
#endif // VALUE_EVALUATOR_H

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,10 +31,10 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "core/color.h"
#include "core/math/rect2.h"
#include "core/pool_vector.h"
#include "core/resource.h"
#include "color.h"
#include "dvector.h"
#include "math_2d.h"
#include "resource.h"
/**
* @author Juan Linietsky <reduzio@gmail.com>
@ -47,24 +47,18 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
typedef PoolVector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
class Image : public Resource {
GDCLASS(Image, Resource);
public:
static SavePNGFunc save_png_func;
static SaveEXRFunc save_exr_func;
static SavePNGBufferFunc save_png_buffer_func;
enum {
MAX_WIDTH = 16384, // force a limit somehow
MAX_HEIGHT = 16384 // force a limit somehow
};
public:
static SavePNGFunc save_png_func;
enum Format {
FORMAT_L8, //luminance
@ -113,29 +107,21 @@ public:
INTERPOLATE_NEAREST,
INTERPOLATE_BILINEAR,
INTERPOLATE_CUBIC,
INTERPOLATE_TRILINEAR,
INTERPOLATE_LANCZOS,
/* INTERPOLATE_TRICUBIC, */
/* INTERPOLATE GAUSS */
};
enum CompressSource {
COMPRESS_SOURCE_GENERIC,
COMPRESS_SOURCE_SRGB,
COMPRESS_SOURCE_NORMAL,
COMPRESS_SOURCE_LAYERED,
COMPRESS_SOURCE_NORMAL
};
//some functions provided by something else
static ImageMemLoadFunc _png_mem_loader_func;
static ImageMemLoadFunc _jpg_mem_loader_func;
static ImageMemLoadFunc _webp_mem_loader_func;
static ImageMemLoadFunc _tga_mem_loader_func;
static ImageMemLoadFunc _bmp_mem_loader_func;
static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
static void (*_image_compress_bc_func)(Image *, float, CompressSource p_source);
static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, CompressSource p_source);
static void (*_image_compress_bc_func)(Image *, CompressSource p_source);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
static void (*_image_compress_etc1_func)(Image *, float);
@ -143,7 +129,6 @@ public:
static void (*_image_decompress_pvrtc)(Image *);
static void (*_image_decompress_bc)(Image *);
static void (*_image_decompress_bptc)(Image *);
static void (*_image_decompress_etc1)(Image *);
static void (*_image_decompress_etc2)(Image *);
@ -190,17 +175,6 @@ private:
void _set_data(const Dictionary &p_data);
Dictionary _get_data() const;
Error _load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader);
static void average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d);
static void average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d);
static void average_4_half(uint16_t &p_out, const uint16_t &p_a, const uint16_t &p_b, const uint16_t &p_c, const uint16_t &p_d);
static void average_4_rgbe9995(uint32_t &p_out, const uint32_t &p_a, const uint32_t &p_b, const uint32_t &p_c, const uint32_t &p_d);
static void renormalize_uint8(uint8_t *p_rgb);
static void renormalize_float(float *p_rgb);
static void renormalize_half(uint16_t *p_rgb);
static void renormalize_rgbe9995(uint32_t *p_rgb);
public:
int get_width() const; ///< Get image width
int get_height() const; ///< Get image height
@ -224,12 +198,13 @@ public:
/**
* Resize the image, using the preferred interpolation method.
* Indexed-Color images always use INTERPOLATE_NEAREST.
*/
void resize_to_po2(bool p_square = false, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
void expand_x2_hq2x();
bool is_size_po2() const;
/**
* Crop the image to a specific size, if larger, then the image is filled by black
*/
@ -242,10 +217,9 @@ public:
/**
* Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1)
*/
Error generate_mipmaps(bool p_renormalize = false);
Error generate_mipmaps();
void clear_mipmaps();
void normalize(); //for normal maps
/**
* Create a new image of a given size and format. Current image will be lost
@ -263,8 +237,6 @@ public:
Error load(const String &p_path);
Error save_png(const String &p_path) const;
PoolVector<uint8_t> save_png_to_buffer() const;
Error save_exr(const String &p_path, bool p_grayscale) const;
/**
* create an empty image
@ -293,9 +265,8 @@ public:
static int get_format_block_size(Format p_format);
static void get_format_min_pixel_size(Format p_format, int &r_w, int &r_h);
static int get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps = false);
static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
static int get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap);
enum CompressMode {
COMPRESS_S3TC,
@ -303,7 +274,6 @@ public:
COMPRESS_PVRTC4,
COMPRESS_ETC,
COMPRESS_ETC2,
COMPRESS_BPTC
};
Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7);
@ -314,8 +284,6 @@ public:
void premultiply_alpha();
void srgb_to_linear();
void normalmap_to_xy();
Ref<Image> rgbe_to_srgb();
void bumpmap_to_normalmap(float bump_scale = 1.0);
void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
@ -326,15 +294,11 @@ public:
Rect2 get_used_rect() const;
Ref<Image> get_rect(const Rect2 &p_area) const;
static void set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource));
static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource));
static void set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource));
static String get_format_name(Format p_format);
Error load_png_from_buffer(const PoolVector<uint8_t> &p_array);
Error load_jpg_from_buffer(const PoolVector<uint8_t> &p_array);
Error load_webp_from_buffer(const PoolVector<uint8_t> &p_array);
Error load_tga_from_buffer(const PoolVector<uint8_t> &p_array);
Error load_bmp_from_buffer(const PoolVector<uint8_t> &p_array);
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
Image(const char **p_xpm);
@ -355,15 +319,12 @@ public:
};
DetectChannels get_detected_channels();
void optimize_channels();
Color get_pixelv(const Point2 &p_src) const;
Color get_pixel(int p_x, int p_y) const;
void set_pixelv(const Point2 &p_dst, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);
void copy_internals_from(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object.");
ERR_FAIL_COND(p_image.is_null());
format = p_image->format;
width = p_image->width;
height = p_image->height;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,74 +30,38 @@
#include "input_map.h"
#include "core/os/input.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "os/keyboard.h"
#include "project_settings.h"
InputMap *InputMap::singleton = NULL;
int InputMap::ALL_DEVICES = -1;
void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f));
ClassDB::bind_method(D_METHOD("add_action", "action"), &InputMap::add_action);
ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action);
ClassDB::bind_method(D_METHOD("action_set_deadzone", "action", "deadzone"), &InputMap::action_set_deadzone);
ClassDB::bind_method(D_METHOD("action_add_event", "action", "event"), &InputMap::action_add_event);
ClassDB::bind_method(D_METHOD("action_has_event", "action", "event"), &InputMap::action_has_event);
ClassDB::bind_method(D_METHOD("action_erase_event", "action", "event"), &InputMap::action_erase_event);
ClassDB::bind_method(D_METHOD("action_erase_events", "action"), &InputMap::action_erase_events);
ClassDB::bind_method(D_METHOD("get_action_list", "action"), &InputMap::_get_action_list);
ClassDB::bind_method(D_METHOD("event_is_action", "event", "action"), &InputMap::event_is_action);
ClassDB::bind_method(D_METHOD("load_from_globals"), &InputMap::load_from_globals);
}
/**
* Returns an nonexistent action error message with a suggestion of the closest
* matching action name (if possible).
*/
String InputMap::_suggest_actions(const StringName &p_action) const {
void InputMap::add_action(const StringName &p_action) {
List<StringName> actions = get_actions();
StringName closest_action;
float closest_similarity = 0.0;
// Find the most action with the most similar name.
for (List<StringName>::Element *E = actions.front(); E; E = E->next()) {
const float similarity = String(E->get()).similarity(p_action);
if (similarity > closest_similarity) {
closest_action = E->get();
closest_similarity = similarity;
}
}
String error_message = vformat("The InputMap action \"%s\" doesn't exist.", p_action);
if (closest_similarity >= 0.4) {
// Only include a suggestion in the error message if it's similar enough.
error_message += vformat(" Did you mean \"%s\"?", closest_action);
}
return error_message;
}
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\".");
ERR_FAIL_COND(input_map.has(p_action));
input_map[p_action] = Action();
static int last_id = 1;
input_map[p_action].id = last_id;
input_map[p_action].deadzone = p_deadzone;
last_id++;
}
void InputMap::erase_action(const StringName &p_action) {
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
ERR_FAIL_COND(!input_map.has(p_action));
input_map.erase(p_action);
}
@ -130,22 +94,19 @@ List<StringName> InputMap::get_actions() const {
return actions;
}
List<Ref<InputEvent> >::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const {
ERR_FAIL_COND_V(!p_event.is_valid(), NULL);
List<Ref<InputEvent> >::Element *InputMap::_find_event(List<Ref<InputEvent> > &p_list, const Ref<InputEvent> &p_event, bool p_action_test) const {
for (List<Ref<InputEvent> >::Element *E = p_action.inputs.front(); E; E = E->next()) {
for (List<Ref<InputEvent> >::Element *E = p_list.front(); E; E = E->next()) {
const Ref<InputEvent> e = E->get();
//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
// continue;
int device = e->get_device();
if (device == ALL_DEVICES || device == p_event->get_device()) {
if (e->action_match(p_event, p_pressed, p_strength, p_action.deadzone)) {
return E;
}
}
if (e->get_device() != p_event->get_device())
continue;
if (e->action_match(p_event))
return E;
}
return NULL;
@ -156,19 +117,11 @@ bool InputMap::has_action(const StringName &p_action) const {
return input_map.has(p_action);
}
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
input_map[p_action].deadzone = p_deadzone;
}
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
if (_find_event(input_map[p_action], p_event))
ERR_FAIL_COND(p_event.is_null());
ERR_FAIL_COND(!input_map.has(p_action));
if (_find_event(input_map[p_action].inputs, p_event))
return; //already gots
input_map[p_action].inputs.push_back(p_event);
@ -176,29 +129,17 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, _suggest_actions(p_action));
return (_find_event(input_map[p_action], p_event) != NULL);
ERR_FAIL_COND_V(!input_map.has(p_action), false);
return (_find_event(input_map[p_action].inputs, p_event) != NULL);
}
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
ERR_FAIL_COND(!input_map.has(p_action));
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action], p_event);
if (E) {
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action].inputs, p_event);
if (E)
input_map[p_action].inputs.erase(E);
if (Input::get_singleton()->is_action_pressed(p_action)) {
Input::get_singleton()->action_release(p_action);
}
}
}
void InputMap::action_erase_events(const StringName &p_action) {
ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
input_map[p_action].inputs.clear();
}
Array InputMap::_get_action_list(const StringName &p_action) {
@ -225,34 +166,19 @@ const List<Ref<InputEvent> > *InputMap::get_action_list(const StringName &p_acti
}
bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const {
return event_get_action_status(p_event, p_action);
}
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed, float *p_strength) const {
Map<StringName, Action>::Element *E = input_map.find(p_action);
ERR_FAIL_COND_V_MSG(!E, false, _suggest_actions(p_action));
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
if (p_pressed != NULL)
*p_pressed = input_event_action->is_pressed();
if (p_strength != NULL)
*p_strength = (p_pressed != NULL && *p_pressed) ? input_event_action->get_strength() : 0.0f;
return input_event_action->get_action() == p_action;
if (!E) {
ERR_EXPLAIN("Request for nonexistent InputMap action: " + String(p_action));
ERR_FAIL_COND_V(!E, false);
}
bool pressed;
float strength;
List<Ref<InputEvent> >::Element *event = _find_event(E->get(), p_event, &pressed, &strength);
if (event != NULL) {
if (p_pressed != NULL)
*p_pressed = pressed;
if (p_strength != NULL)
*p_strength = strength;
return true;
} else {
return false;
Ref<InputEventAction> iea = p_event;
if (iea.is_valid()) {
return iea->get_action() == p_action;
}
return _find_event(E->get().inputs, p_event, true) != NULL;
}
const Map<StringName, InputMap::Action> &InputMap::get_action_map() const {
@ -274,16 +200,16 @@ void InputMap::load_from_globals() {
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
Dictionary action = ProjectSettings::get_singleton()->get(pi.name);
float deadzone = action.has("deadzone") ? (float)action["deadzone"] : 0.5f;
Array events = action["events"];
add_action(name);
add_action(name, deadzone);
for (int i = 0; i < events.size(); i++) {
Ref<InputEvent> event = events[i];
if (event.is_null())
Array va = ProjectSettings::get_singleton()->get(pi.name);
for (int i = 0; i < va.size(); i++) {
Ref<InputEvent> ie = va[i];
if (ie.is_null())
continue;
action_add_event(name, event);
action_add_event(name, ie);
}
}
}
@ -356,19 +282,11 @@ void InputMap::load_default() {
key->set_scancode(KEY_PAGEDOWN);
action_add_event("ui_page_down", key);
add_action("ui_home");
key.instance();
key->set_scancode(KEY_HOME);
action_add_event("ui_home", key);
add_action("ui_end");
key.instance();
key->set_scancode(KEY_END);
action_add_event("ui_end", key);
//set("display/window/handheld/orientation", "landscape");
}
InputMap::InputMap() {
ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exist.");
ERR_FAIL_COND(singleton);
singleton = this;
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,22 +31,16 @@
#ifndef INPUT_MAP_H
#define INPUT_MAP_H
#include "core/object.h"
#include "core/os/input_event.h"
#include "object.h"
#include "os/input_event.h"
class InputMap : public Object {
GDCLASS(InputMap, Object);
public:
/**
* A special value used to signify that a given Action can be triggered by any device
*/
static int ALL_DEVICES;
struct Action {
int id;
float deadzone;
List<Ref<InputEvent> > inputs;
};
@ -55,11 +49,10 @@ private:
mutable Map<StringName, Action> input_map;
List<Ref<InputEvent> >::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed = NULL, float *p_strength = NULL) const;
List<Ref<InputEvent> >::Element *_find_event(List<Ref<InputEvent> > &p_list, const Ref<InputEvent> &p_event, bool p_action_test = false) const;
Array _get_action_list(const StringName &p_action);
Array _get_actions();
String _suggest_actions(const StringName &p_action) const;
protected:
static void _bind_methods();
@ -69,18 +62,15 @@ public:
bool has_action(const StringName &p_action) const;
List<StringName> get_actions() const;
void add_action(const StringName &p_action, float p_deadzone = 0.5);
void add_action(const StringName &p_action);
void erase_action(const StringName &p_action);
void action_set_deadzone(const StringName &p_action, float p_deadzone);
void action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event);
bool action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event);
void action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event);
void action_erase_events(const StringName &p_action);
const List<Ref<InputEvent> > *get_action_list(const StringName &p_action);
bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const;
bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool *p_pressed = NULL, float *p_strength = NULL) const;
const Map<StringName, Action> &get_action_map() const;
void load_from_globals();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */

View File

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

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -29,10 +29,9 @@
/*************************************************************************/
#include "compression.h"
#include "core/io/zip_io.h"
#include "core/os/copymem.h"
#include "core/project_settings.h"
#include "os/copymem.h"
#include "project_settings.h"
#include "zip_io.h"
#include "thirdparty/misc/fastlz.h"
@ -81,10 +80,10 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
} break;
case MODE_ZSTD: {
ZSTD_CCtx *cctx = ZSTD_createCCtx();
ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd_level);
ZSTD_CCtx_setParameter(cctx, ZSTD_p_compressionLevel, zstd_level);
if (zstd_long_distance_matching) {
ZSTD_CCtx_setParameter(cctx, ZSTD_c_enableLongDistanceMatching, 1);
ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, zstd_window_log_size);
ZSTD_CCtx_setParameter(cctx, ZSTD_p_enableLongDistanceMatching, 1);
ZSTD_CCtx_setParameter(cctx, ZSTD_p_windowLog, zstd_window_log_size);
}
int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD);
int ret = ZSTD_compressCCtx(cctx, p_dst, max_dst_size, p_src, p_src_size, zstd_level);
@ -175,9 +174,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
} break;
case MODE_ZSTD: {
ZSTD_DCtx *dctx = ZSTD_createDCtx();
if (zstd_long_distance_matching) {
ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, zstd_window_log_size);
}
if (zstd_long_distance_matching) ZSTD_DCtx_setMaxWindowSize(dctx, 1 << zstd_window_log_size);
int ret = ZSTD_decompressDCtx(dctx, p_dst, p_dst_max_size, p_src, p_src_size);
ZSTD_freeDCtx(dctx);
return ret;
@ -191,4 +188,4 @@ int Compression::zlib_level = Z_DEFAULT_COMPRESSION;
int Compression::gzip_level = Z_DEFAULT_COMPRESSION;
int Compression::zstd_level = 3;
bool Compression::zstd_long_distance_matching = false;
int Compression::zstd_window_log_size = 27; // ZSTD_WINDOWLOG_LIMIT_DEFAULT
int Compression::zstd_window_log_size = 27;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef COMPRESSION_H
#define COMPRESSION_H
#include "core/typedefs.h"
#include "typedefs.h"
class Compression {

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -29,10 +29,9 @@
/*************************************************************************/
#include "config_file.h"
#include "core/io/file_access_encrypted.h"
#include "core/os/keyboard.h"
#include "core/variant_parser.h"
#include "os/file_access.h"
#include "os/keyboard.h"
#include "variant_parser.h"
PoolStringArray ConfigFile::_get_sections() const {
@ -86,8 +85,10 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
if (!values.has(p_section) || !values[p_section].has(p_key)) {
ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(),
vformat("Couldn't find the given section \"%s\" and key \"%s\", and no default was given.", p_section, p_key));
if (p_default.get_type() == Variant::NIL) {
ERR_EXPLAIN("Couldn't find the given section/key and no default was given");
ERR_FAIL_V(p_default);
}
return p_default;
}
return values[p_section][p_key];
@ -112,7 +113,7 @@ void ConfigFile::get_sections(List<String> *r_sections) const {
}
void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section));
ERR_FAIL_COND(!values.has(p_section));
for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) {
r_keys->push_back(E.key());
@ -121,18 +122,9 @@ void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys)
void ConfigFile::erase_section(const String &p_section) {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase nonexistent section \"%s\".", p_section));
values.erase(p_section);
}
void ConfigFile::erase_section_key(const String &p_section, const String &p_key) {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase key \"%s\" from nonexistent section \"%s\".", p_key, p_section));
ERR_FAIL_COND_MSG(!values[p_section].has(p_key), vformat("Cannot erase nonexistent key \"%s\" from section \"%s\".", p_key, p_section));
values[p_section].erase(p_key);
}
Error ConfigFile::save(const String &p_path) {
Error err;
@ -144,48 +136,6 @@ Error ConfigFile::save(const String &p_path) {
return err;
}
return _internal_save(file);
}
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err)
return err;
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_save(fae);
}
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err)
return err;
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_save(fae);
}
Error ConfigFile::_internal_save(FileAccess *file) {
for (OrderedHashMap<String, OrderedHashMap<String, Variant> >::Element E = values.front(); E; E = E.next()) {
if (E != values.front())
@ -211,69 +161,11 @@ Error ConfigFile::load(const String &p_path) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f)
return err;
return _internal_load(p_path, f);
}
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err)
return err;
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_load(p_path, fae);
}
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err)
return err;
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);
if (err) {
memdelete(fae);
memdelete(f);
return err;
}
return _internal_load(p_path, fae);
}
Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
return ERR_CANT_OPEN;
VariantParser::StreamFile stream;
stream.f = f;
Error err = _parse(p_path, &stream);
memdelete(f);
return err;
}
Error ConfigFile::parse(const String &p_data) {
VariantParser::StreamString stream;
stream.s = p_data;
return _parse("<string>", &stream);
}
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) {
String assign;
Variant value;
VariantParser::Tag next_tag;
@ -289,11 +181,13 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
next_tag.fields.clear();
next_tag.name = String();
Error err = VariantParser::parse_tag_assign_eof(p_stream, lines, error_text, next_tag, assign, value, NULL, true);
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
if (err == ERR_FILE_EOF) {
memdelete(f);
return OK;
} else if (err != OK) {
ERR_PRINT(vformat("ConfigFile parse error at %s:%d: %s.", p_path, lines, error_text));
ERR_PRINTS("ConfgFile::load - " + p_path + ":" + itos(lines) + " error: " + error_text);
memdelete(f);
return err;
}
@ -304,12 +198,11 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
}
}
memdelete(f);
return OK;
}
void ConfigFile::clear() {
values.clear();
}
void ConfigFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_value", "section", "key", "value"), &ConfigFile::set_value);
@ -322,17 +215,10 @@ void ConfigFile::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_section_keys", "section"), &ConfigFile::_get_section_keys);
ClassDB::bind_method(D_METHOD("erase_section", "section"), &ConfigFile::erase_section);
ClassDB::bind_method(D_METHOD("erase_section_key", "section", "key"), &ConfigFile::erase_section_key);
ClassDB::bind_method(D_METHOD("load", "path"), &ConfigFile::load);
ClassDB::bind_method(D_METHOD("parse", "data"), &ConfigFile::parse);
ClassDB::bind_method(D_METHOD("save", "path"), &ConfigFile::save);
ClassDB::bind_method(D_METHOD("load_encrypted", "path", "key"), &ConfigFile::load_encrypted);
ClassDB::bind_method(D_METHOD("load_encrypted_pass", "path", "password"), &ConfigFile::load_encrypted_pass);
ClassDB::bind_method(D_METHOD("save_encrypted", "path", "key"), &ConfigFile::save_encrypted);
ClassDB::bind_method(D_METHOD("save_encrypted_pass", "path", "password"), &ConfigFile::save_encrypted_pass);
ClassDB::bind_method(D_METHOD("clear"), &ConfigFile::clear);
}
ConfigFile::ConfigFile() {
}

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -32,9 +32,7 @@
#define CONFIG_FILE_H
#include "core/ordered_hash_map.h"
#include "core/os/file_access.h"
#include "core/reference.h"
#include "core/variant_parser.h"
#include "reference.h"
class ConfigFile : public Reference {
@ -44,10 +42,6 @@ class ConfigFile : public Reference {
PoolStringArray _get_sections() const;
PoolStringArray _get_section_keys(const String &p_section) const;
Error _internal_load(const String &p_path, FileAccess *f);
Error _internal_save(FileAccess *file);
Error _parse(const String &p_path, VariantParser::Stream *p_stream);
protected:
static void _bind_methods();
@ -63,19 +57,11 @@ public:
void get_section_keys(const String &p_section, List<String> *r_keys) const;
void erase_section(const String &p_section);
void erase_section_key(const String &p_section, const String &p_key);
Error save(const String &p_path);
Error load(const String &p_path);
Error parse(const String &p_data);
void clear();
Error load_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error load_encrypted_pass(const String &p_path, const String &p_pass);
Error save_encrypted(const String &p_path, const Vector<uint8_t> &p_key);
Error save_encrypted_pass(const String &p_path, const String &p_pass);
ConfigFile();
};
#endif // CONFIG_FILE_H

View File

@ -1,57 +0,0 @@
/*************************************************************************/
/* dtls_server.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 "dtls_server.h"
#include "core/os/file_access.h"
#include "core/project_settings.h"
DTLSServer *(*DTLSServer::_create)() = NULL;
bool DTLSServer::available = false;
DTLSServer *DTLSServer::create() {
if (_create) {
return _create();
}
return NULL;
}
bool DTLSServer::is_available() {
return available;
}
void DTLSServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("setup", "key", "certificate", "chain"), &DTLSServer::setup, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("take_connection", "udp_peer"), &DTLSServer::take_connection);
}
DTLSServer::DTLSServer() {
}

View File

@ -1,57 +0,0 @@
/*************************************************************************/
/* dtls_server.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 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 DTLS_SERVER_H
#define DTLS_SERVER_H
#include "core/io/net_socket.h"
#include "core/io/packet_peer_dtls.h"
class DTLSServer : public Reference {
GDCLASS(DTLSServer, Reference);
protected:
static DTLSServer *(*_create)();
static void _bind_methods();
static bool available;
public:
static bool is_available();
static DTLSServer *create();
virtual Error setup(Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain = Ref<X509Certificate>()) = 0;
virtual void stop() = 0;
virtual Ref<PacketPeerDTLS> take_connection(Ref<PacketPeerUDP> p_peer) = 0;
DTLSServer();
};
#endif // DTLS_SERVER_H

View File

@ -0,0 +1,184 @@
/*************************************************************************/
/* file_access_buffered.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 "file_access_buffered.h"
#include <string.h>
#include "error_macros.h"
Error FileAccessBuffered::set_error(Error p_error) const {
return (last_error = p_error);
};
void FileAccessBuffered::set_cache_size(int p_size) {
cache_size = p_size;
};
int FileAccessBuffered::get_cache_size() {
return cache_size;
};
int FileAccessBuffered::cache_data_left() const {
if (file.offset >= file.size) {
return 0;
};
if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) {
return read_data_block(file.offset, cache_size);
} else {
return cache.buffer.size() - (file.offset - cache.offset);
};
return 0;
};
void FileAccessBuffered::seek(size_t p_position) {
file.offset = p_position;
};
void FileAccessBuffered::seek_end(int64_t p_position) {
file.offset = file.size + p_position;
};
size_t FileAccessBuffered::get_position() const {
return file.offset;
};
size_t FileAccessBuffered::get_len() const {
return file.size;
};
bool FileAccessBuffered::eof_reached() const {
return file.offset > file.size;
};
uint8_t FileAccessBuffered::get_8() const {
ERR_FAIL_COND_V(!file.open, 0);
uint8_t byte = 0;
if (cache_data_left() >= 1) {
byte = cache.buffer[file.offset - cache.offset];
};
++file.offset;
return byte;
};
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
ERR_FAIL_COND_V(!file.open, -1);
if (p_length > cache_size) {
int total_read = 0;
if (!(cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size())) {
int size = (cache.buffer.size() - (file.offset - cache.offset));
size = size - (size % 4);
//PoolVector<uint8_t>::Read read = cache.buffer.read();
//memcpy(p_dest, read.ptr() + (file.offset - cache.offset), size);
memcpy(p_dest, cache.buffer.ptr() + (file.offset - cache.offset), size);
p_dest += size;
p_length -= size;
file.offset += size;
total_read += size;
};
int err = read_data_block(file.offset, p_length, p_dest);
if (err >= 0) {
total_read += err;
file.offset += err;
};
return total_read;
};
int to_read = p_length;
int total_read = 0;
while (to_read > 0) {
int left = cache_data_left();
if (left == 0) {
if (to_read > 0) {
file.offset += to_read;
};
return total_read;
};
if (left < 0) {
return left;
};
int r = MIN(left, to_read);
//PoolVector<uint8_t>::Read read = cache.buffer.read();
//memcpy(p_dest+total_read, &read.ptr()[file.offset - cache.offset], r);
memcpy(p_dest + total_read, cache.buffer.ptr() + (file.offset - cache.offset), r);
file.offset += r;
total_read += r;
to_read -= r;
};
return p_length;
};
bool FileAccessBuffered::is_open() const {
return file.open;
};
Error FileAccessBuffered::get_error() const {
return last_error;
};
FileAccessBuffered::FileAccessBuffered() {
cache_size = DEFAULT_CACHE_SIZE;
};
FileAccessBuffered::~FileAccessBuffered() {
}

View File

@ -0,0 +1,95 @@
/*************************************************************************/
/* file_access_buffered.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 FILE_ACCESS_BUFFERED_H
#define FILE_ACCESS_BUFFERED_H
#include "os/file_access.h"
#include "dvector.h"
#include "ustring.h"
class FileAccessBuffered : public FileAccess {
public:
enum {
DEFAULT_CACHE_SIZE = 128 * 1024,
};
private:
int cache_size;
int cache_data_left() const;
mutable Error last_error;
protected:
Error set_error(Error p_error) const;
mutable struct File {
bool open;
int size;
int offset;
String name;
int access_flags;
} file;
mutable struct Cache {
Vector<uint8_t> buffer;
int offset;
} cache;
virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const = 0;
void set_cache_size(int p_size);
int get_cache_size();
public:
virtual size_t get_position() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual bool eof_reached() const;
virtual uint8_t get_8() const;
virtual int get_buffer(uint8_t *p_dest, int p_length) const; ///< get an array of bytes
virtual bool is_open() const;
virtual Error get_error() const;
FileAccessBuffered();
virtual ~FileAccessBuffered();
};
#endif

View File

@ -0,0 +1,151 @@
/*************************************************************************/
/* file_access_buffered_fa.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 FILE_ACCESS_BUFFERED_FA_H
#define FILE_ACCESS_BUFFERED_FA_H
#include "core/io/file_access_buffered.h"
template <class T>
class FileAccessBufferedFA : public FileAccessBuffered {
T f;
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
ERR_FAIL_COND_V(!f.is_open(), -1);
((T *)&f)->seek(p_offset);
if (p_dest) {
f.get_buffer(p_dest, p_size);
return p_size;
} else {
cache.offset = p_offset;
cache.buffer.resize(p_size);
// on dvector
//PoolVector<uint8_t>::Write write = cache.buffer.write();
//f.get_buffer(write.ptrw(), p_size);
// on vector
f.get_buffer(cache.buffer.ptrw(), p_size);
return p_size;
};
};
static FileAccess *create() {
return memnew(FileAccessBufferedFA<T>());
};
protected:
virtual void _set_access_type(AccessType p_access) {
f._set_access_type(p_access);
FileAccessBuffered::_set_access_type(p_access);
};
public:
void flush() {
f.flush();
};
void store_8(uint8_t p_dest) {
f.store_8(p_dest);
};
void store_buffer(const uint8_t *p_src, int p_length) {
f.store_buffer(p_src, p_length);
};
bool file_exists(const String &p_name) {
return f.file_exists(p_name);
};
Error _open(const String &p_path, int p_mode_flags) {
close();
Error ret = f._open(p_path, p_mode_flags);
if (ret != OK)
return ret;
//ERR_FAIL_COND_V( ret != OK, ret );
file.size = f.get_len();
file.offset = 0;
file.open = true;
file.name = p_path;
file.access_flags = p_mode_flags;
cache.buffer.resize(0);
cache.offset = 0;
return set_error(OK);
};
void close() {
f.close();
file.offset = 0;
file.size = 0;
file.open = false;
file.name = "";
cache.buffer.resize(0);
cache.offset = 0;
set_error(OK);
};
/*
static void make_default() {
FileAccess::create_func = FileAccessBufferedFA<T>::create;
};
*/
virtual uint64_t _get_modified_time(const String &p_file) {
return f._get_modified_time(p_file);
}
FileAccessBufferedFA(){
};
};
#endif // FILE_ACCESS_BUFFERED_FA_H

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -29,9 +29,7 @@
/*************************************************************************/
#include "file_access_compressed.h"
#include "core/print_string.h"
#include "print_string.h"
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
magic = p_magic.ascii().get_data();
@ -63,10 +61,6 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
f = p_base;
cmode = (Compression::Mode)f->get_32();
block_size = f->get_32();
if (block_size == 0) {
f = NULL; // Let the caller to handle the FileAccess object if failed to open as compressed file.
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted.");
}
read_total = f->get_32();
int bc = (read_total / block_size) + 1;
int acc_ofs = f->get_position() + bc * 4;
@ -129,11 +123,13 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
char rmagic[5];
f->get_buffer((uint8_t *)rmagic, 4);
rmagic[4] = 0;
if (magic != rmagic || open_after_magic(f) != OK) {
if (magic != rmagic) {
memdelete(f);
f = NULL;
return ERR_FILE_UNRECOGNIZED;
}
open_after_magic(f);
}
return OK;
@ -197,7 +193,7 @@ bool FileAccessCompressed::is_open() const {
void FileAccessCompressed::seek(size_t p_position) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND(!f);
if (writing) {
ERR_FAIL_COND(p_position > write_max);
@ -210,8 +206,7 @@ void FileAccessCompressed::seek(size_t p_position) {
if (p_position == read_total) {
at_end = true;
} else {
at_end = false;
read_eof = false;
int block_idx = p_position / block_size;
if (block_idx != read_block) {
@ -229,7 +224,7 @@ void FileAccessCompressed::seek(size_t p_position) {
void FileAccessCompressed::seek_end(int64_t p_position) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND(!f);
if (writing) {
seek(write_max + p_position);
@ -240,7 +235,7 @@ void FileAccessCompressed::seek_end(int64_t p_position) {
}
size_t FileAccessCompressed::get_position() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_pos;
@ -251,7 +246,7 @@ size_t FileAccessCompressed::get_position() const {
}
size_t FileAccessCompressed::get_len() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
ERR_FAIL_COND_V(!f, 0);
if (writing) {
return write_max;
@ -262,7 +257,7 @@ size_t FileAccessCompressed::get_len() const {
bool FileAccessCompressed::eof_reached() const {
ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use.");
ERR_FAIL_COND_V(!f, false);
if (writing) {
return false;
} else {
@ -272,8 +267,8 @@ bool FileAccessCompressed::eof_reached() const {
uint8_t FileAccessCompressed::get_8() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof = true;
@ -296,16 +291,16 @@ uint8_t FileAccessCompressed::get_8() const {
} else {
read_block--;
at_end = true;
ret = 0;
}
}
return ret;
}
int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1);
ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
ERR_FAIL_COND_V(writing, 0);
ERR_FAIL_COND_V(!f, 0);
if (at_end) {
read_eof = true;
@ -345,16 +340,16 @@ Error FileAccessCompressed::get_error() const {
}
void FileAccessCompressed::flush() {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!f);
ERR_FAIL_COND(!writing);
// compressed files keep data in memory till close()
}
void FileAccessCompressed::store_8(uint8_t p_dest) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!f);
ERR_FAIL_COND(!writing);
WRITE_FIT(1);
write_ptr[write_pos++] = p_dest;
@ -377,36 +372,24 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
return 0;
}
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
if (f)
return f->_get_unix_permissions(p_file);
return 0;
}
FileAccessCompressed::FileAccessCompressed() {
Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
if (f) {
return f->_set_unix_permissions(p_file, p_permissions);
}
return FAILED;
}
FileAccessCompressed::FileAccessCompressed() :
cmode(Compression::MODE_ZSTD),
writing(false),
write_ptr(0),
write_buffer_size(0),
write_max(0),
block_size(0),
read_eof(false),
at_end(false),
read_ptr(NULL),
read_block(0),
read_block_count(0),
read_block_size(0),
read_pos(0),
read_total(0),
magic("GCMP"),
f(NULL) {
f = NULL;
magic = "GCMP";
cmode = Compression::MODE_ZSTD;
writing = false;
write_ptr = 0;
write_buffer_size = 0;
write_max = 0;
block_size = 0;
read_eof = false;
at_end = false;
read_total = 0;
read_ptr = NULL;
read_block = 0;
read_block_count = 0;
read_block_size = 0;
read_pos = 0;
}
FileAccessCompressed::~FileAccessCompressed() {

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,8 +31,8 @@
#ifndef FILE_ACCESS_COMPRESSED_H
#define FILE_ACCESS_COMPRESSED_H
#include "core/io/compression.h"
#include "core/os/file_access.h"
#include "io/compression.h"
#include "os/file_access.h"
class FileAccessCompressed : public FileAccess {
@ -91,8 +91,6 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
FileAccessCompressed();
virtual ~FileAccessCompressed();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,10 +30,12 @@
#include "file_access_encrypted.h"
#include "core/crypto/crypto_core.h"
#include "core/os/copymem.h"
#include "core/print_string.h"
#include "core/variant.h"
#include "os/copymem.h"
#include "print_string.h"
#include "thirdparty/misc/aes256.h"
#include "thirdparty/misc/md5.h"
#include <stdio.h>
@ -41,7 +43,8 @@
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
ERR_FAIL_COND_V_MSG(file != NULL, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
//print_line("open and parse!");
ERR_FAIL_COND_V(file != NULL, ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
pos = 0;
@ -81,20 +84,24 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
uint32_t blen = p_base->get_buffer(data.ptrw(), ds);
ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT);
CryptoCore::AESContext ctx;
ctx.set_decode_key(key.ptrw(), 256);
aes256_context ctx;
aes256_init(&ctx, key.ptrw());
for (size_t i = 0; i < ds; i += 16) {
ctx.decrypt_ecb(&data.write[i], &data.write[i]);
aes256_decrypt_ecb(&ctx, &data[i]);
}
aes256_done(&ctx);
data.resize(length);
unsigned char hash[16];
ERR_FAIL_COND_V(CryptoCore::md5(data.ptr(), data.size(), hash) != OK, ERR_BUG);
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, (uint8_t *)data.ptr(), data.size());
MD5Final(&md5);
ERR_FAIL_COND_V_MSG(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT, "The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid.");
ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT);
file = p_base;
}
@ -110,7 +117,7 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
key.resize(32);
for (int i = 0; i < 32; i++) {
key.write[i] = cs[i];
key[i] = cs[i];
}
return open_and_parse(p_base, key, p_mode);
@ -133,27 +140,31 @@ void FileAccessEncrypted::close() {
len += 16 - (len % 16);
}
unsigned char hash[16];
ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug?
MD5_CTX md5;
MD5Init(&md5);
MD5Update(&md5, (uint8_t *)data.ptr(), data.size());
MD5Final(&md5);
compressed.resize(len);
zeromem(compressed.ptrw(), len);
for (int i = 0; i < data.size(); i++) {
compressed.write[i] = data[i];
compressed[i] = data[i];
}
CryptoCore::AESContext ctx;
ctx.set_encode_key(key.ptrw(), 256);
aes256_context ctx;
aes256_init(&ctx, key.ptrw());
for (size_t i = 0; i < len; i += 16) {
ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
aes256_encrypt_ecb(&ctx, &compressed[i]);
}
aes256_done(&ctx);
file->store_32(COMP_MAGIC);
file->store_32(mode);
file->store_buffer(hash, 16);
file->store_buffer(md5.digest, 16);
file->store_64(data.size());
file->store_buffer(compressed.ptr(), compressed.size());
@ -176,22 +187,6 @@ bool FileAccessEncrypted::is_open() const {
return file != NULL;
}
String FileAccessEncrypted::get_path() const {
if (file)
return file->get_path();
else
return "";
}
String FileAccessEncrypted::get_path_absolute() const {
if (file)
return file->get_path_absolute();
else
return "";
}
void FileAccessEncrypted::seek(size_t p_position) {
if (p_position > (size_t)data.size())
@ -221,7 +216,7 @@ bool FileAccessEncrypted::eof_reached() const {
uint8_t FileAccessEncrypted::get_8() const {
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
ERR_FAIL_COND_V(writing, 0);
if (pos >= data.size()) {
eofed = true;
return 0;
@ -231,11 +226,9 @@ uint8_t FileAccessEncrypted::get_8() const {
pos++;
return b;
}
int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1);
ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode.");
ERR_FAIL_COND_V(writing, 0);
int to_copy = MIN(p_length, data.size() - pos);
for (int i = 0; i < to_copy; i++) {
@ -257,7 +250,7 @@ Error FileAccessEncrypted::get_error() const {
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!writing);
if (pos < data.size()) {
@ -270,24 +263,24 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
data.write[pos + i] = p_src[i];
data[pos + i] = p_src[i];
}
pos += p_length;
}
}
void FileAccessEncrypted::flush() {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!writing);
// encrypted files keep data in memory till close()
}
void FileAccessEncrypted::store_8(uint8_t p_dest) {
ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode.");
ERR_FAIL_COND(!writing);
if (pos < data.size()) {
data.write[pos] = p_dest;
data[pos] = p_dest;
pos++;
} else if (pos == data.size()) {
data.push_back(p_dest);
@ -309,16 +302,6 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
return 0;
}
Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
return ERR_UNAVAILABLE;
}
FileAccessEncrypted::FileAccessEncrypted() {
file = NULL;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef FILE_ACCESS_ENCRYPTED_H
#define FILE_ACCESS_ENCRYPTED_H
#include "core/os/file_access.h"
#include "os/file_access.h"
class FileAccessEncrypted : public FileAccess {
public:
@ -60,9 +60,6 @@ public:
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual String get_path() const; /// returns the path for the current open file
virtual String get_path_absolute() const; /// returns the absolute path for the current open file
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file
virtual size_t get_position() const; ///< get position in the file
@ -82,8 +79,6 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
FileAccessEncrypted();
~FileAccessEncrypted();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -30,10 +30,10 @@
#include "file_access_memory.h"
#include "core/map.h"
#include "core/os/copymem.h"
#include "core/os/dir_access.h"
#include "core/project_settings.h"
#include "map.h"
#include "os/copymem.h"
#include "os/dir_access.h"
#include "project_settings.h"
static Map<String, Vector<uint8_t> > *files = NULL;
@ -90,9 +90,9 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
//name = DirAccess::normalize_path(name);
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
ERR_FAIL_COND_V_MSG(!E, ERR_FILE_NOT_FOUND, "Can't find file '" + p_path + "'.");
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
data = E->get().ptrw();
data = &(E->get()[0]);
length = E->get().size();
pos = 0;
@ -150,8 +150,7 @@ uint8_t FileAccessMemory::get_8() const {
}
int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1);
ERR_FAIL_COND_V(!data, -1);
int left = length - pos;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,7 +31,7 @@
#ifndef FILE_ACCESS_MEMORY_H
#define FILE_ACCESS_MEMORY_H
#include "core/os/file_access.h"
#include "os/file_access.h"
class FileAccessMemory : public FileAccess {
@ -70,8 +70,6 @@ public:
virtual bool file_exists(const String &p_name); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
FileAccessMemory();
};

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -29,11 +29,10 @@
/*************************************************************************/
#include "file_access_network.h"
#include "core/io/ip.h"
#include "core/io/marshalls.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "io/ip.h"
#include "marshalls.h"
#include "os/os.h"
#include "project_settings.h"
//#define DEBUG_PRINT(m_p) print_line(m_p)
//#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n",m_what,OS::get_singleton()->get_ticks_usec());
@ -42,14 +41,14 @@
void FileAccessNetworkClient::lock_mutex() {
mutex.lock();
mutex->lock();
lockcount++;
}
void FileAccessNetworkClient::unlock_mutex() {
lockcount--;
mutex.unlock();
mutex->unlock();
}
void FileAccessNetworkClient::put_32(int p_32) {
@ -88,14 +87,18 @@ void FileAccessNetworkClient::_thread_func() {
while (!quit) {
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
sem.wait();
Error err = sem->wait();
if (err != OK)
ERR_PRINT("sem->wait() failed");
DEBUG_TIME("sem_unlock");
//DEBUG_PRINT("semwait returned "+itos(werr));
DEBUG_PRINT("MUTEX LOCK " + itos(lockcount));
DEBUG_PRINT("POPO");
DEBUG_PRINT("PEPE");
lock_mutex();
DEBUG_PRINT("MUTEX PASS");
blockrequest_mutex.lock();
blockrequest_mutex->lock();
while (block_requests.size()) {
put_32(block_requests.front()->get().id);
put_32(FileAccessNetwork::COMMAND_READ_BLOCK);
@ -103,7 +106,7 @@ void FileAccessNetworkClient::_thread_func() {
put_32(block_requests.front()->get().size);
block_requests.pop_front();
}
blockrequest_mutex.unlock();
blockrequest_mutex->unlock();
DEBUG_PRINT("THREAD ITER");
@ -116,10 +119,7 @@ void FileAccessNetworkClient::_thread_func() {
FileAccessNetwork *fa = NULL;
if (response != FileAccessNetwork::RESPONSE_DATA) {
if (!accesses.has(id)) {
unlock_mutex();
ERR_FAIL_COND(!accesses.has(id));
}
ERR_FAIL_COND(!accesses.has(id));
}
if (accesses.has(id))
@ -138,7 +138,7 @@ void FileAccessNetworkClient::_thread_func() {
fa->_respond(len, Error(status));
}
fa->sem.post();
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_DATA: {
@ -158,14 +158,14 @@ void FileAccessNetworkClient::_thread_func() {
int status = get_32();
fa->exists_modtime = status != 0;
fa->sem.post();
fa->sem->post();
} break;
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
uint64_t status = get_64();
fa->exists_modtime = status;
fa->sem.post();
fa->sem->post();
} break;
}
@ -193,7 +193,7 @@ Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const S
DEBUG_PRINT("IP: " + String(ip) + " port " + itos(p_port));
Error err = client->connect_to_host(ip, p_port);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot connect to host with IP: " + String(ip) + " and port: " + itos(p_port));
ERR_FAIL_COND_V(err, err);
while (client->get_status() == StreamPeerTCP::STATUS_CONNECTING) {
//DEBUG_PRINT("trying to connect....");
OS::get_singleton()->delay_usec(1000);
@ -213,7 +213,7 @@ Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const S
return ERR_INVALID_PARAMETER;
}
thread.start(_thread_func, this);
thread = Thread::create(_thread_func, this);
return OK;
}
@ -222,20 +222,29 @@ FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL;
FileAccessNetworkClient::FileAccessNetworkClient() {
thread = NULL;
mutex = Mutex::create();
blockrequest_mutex = Mutex::create();
quit = false;
singleton = this;
last_id = 0;
client.instance();
client = Ref<StreamPeerTCP>(StreamPeerTCP::create_ref());
sem = Semaphore::create();
lockcount = 0;
}
FileAccessNetworkClient::~FileAccessNetworkClient() {
if (thread.is_started()) {
if (thread) {
quit = true;
sem.post();
thread.wait_to_finish();
sem->post();
Thread::wait_to_finish(thread);
memdelete(thread);
}
memdelete(blockrequest_mutex);
memdelete(mutex);
memdelete(sem);
}
void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
@ -248,14 +257,14 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size)));
}
buffer_mutex.lock();
pages.write[page].buffer = p_block;
pages.write[page].queued = false;
buffer_mutex.unlock();
buffer_mutex->lock();
pages[page].buffer = p_block;
pages[page].queued = false;
buffer_mutex->unlock();
if (waiting_on_page == page) {
waiting_on_page = -1;
page_sem.post();
page_sem->post();
}
}
@ -297,9 +306,9 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
nc->unlock_mutex();
DEBUG_PRINT("OPEN POST");
DEBUG_TIME("open_post");
nc->sem.post(); //awaiting answer
nc->sem->post(); //awaiting answer
DEBUG_PRINT("WAIT...");
sem.wait();
sem->wait();
DEBUG_TIME("open_end");
DEBUG_PRINT("WAIT ENDED...");
@ -328,7 +337,7 @@ bool FileAccessNetwork::is_open() const {
void FileAccessNetwork::seek(size_t p_position) {
ERR_FAIL_COND_MSG(!opened, "File must be opened before use.");
ERR_FAIL_COND(!opened);
eof_flag = p_position > total_size;
if (p_position >= total_size) {
@ -344,18 +353,18 @@ void FileAccessNetwork::seek_end(int64_t p_position) {
}
size_t FileAccessNetwork::get_position() const {
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
ERR_FAIL_COND_V(!opened, 0);
return pos;
}
size_t FileAccessNetwork::get_len() const {
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
ERR_FAIL_COND_V(!opened, 0);
return total_size;
}
bool FileAccessNetwork::eof_reached() const {
ERR_FAIL_COND_V_MSG(!opened, false, "File must be opened before use.");
ERR_FAIL_COND_V(!opened, false);
return eof_flag;
}
@ -374,23 +383,21 @@ void FileAccessNetwork::_queue_page(int p_page) const {
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->blockrequest_mutex.lock();
nc->blockrequest_mutex->lock();
FileAccessNetworkClient::BlockRequest br;
br.id = id;
br.offset = size_t(p_page) * page_size;
br.size = page_size;
nc->block_requests.push_back(br);
pages.write[p_page].queued = true;
nc->blockrequest_mutex.unlock();
pages[p_page].queued = true;
nc->blockrequest_mutex->unlock();
DEBUG_PRINT("QUEUE PAGE POST");
nc->sem.post();
nc->sem->post();
DEBUG_PRINT("queued " + itos(p_page));
}
}
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1);
//bool eof=false;
if (pos + p_length > total_size) {
@ -409,16 +416,16 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
int page = pos / page_size;
if (page != last_page) {
buffer_mutex.lock();
buffer_mutex->lock();
if (pages[page].buffer.empty()) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
_queue_page(page + j);
}
buffer_mutex.unlock();
buffer_mutex->unlock();
DEBUG_PRINT("wait");
page_sem.wait();
page_sem->wait();
DEBUG_PRINT("done");
} else {
@ -426,11 +433,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
_queue_page(page + j);
}
buff = pages[page].buffer.ptrw();
//queue pages
buffer_mutex.unlock();
buffer_mutex->unlock();
}
buff = pages.write[page].buffer.ptrw();
buff = pages[page].buffer.ptrw();
last_page_buff = buff;
last_page = page;
}
@ -467,8 +475,8 @@ bool FileAccessNetwork::file_exists(const String &p_path) {
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("FILE EXISTS POST");
nc->sem.post();
sem.wait();
nc->sem->post();
sem->wait();
return exists_modtime != 0;
}
@ -484,28 +492,17 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
nc->client->put_data((const uint8_t *)cs.ptr(), cs.length());
nc->unlock_mutex();
DEBUG_PRINT("MODTIME POST");
nc->sem.post();
sem.wait();
nc->sem->post();
sem->wait();
return exists_modtime;
}
uint32_t FileAccessNetwork::_get_unix_permissions(const String &p_file) {
ERR_PRINT("Getting UNIX permissions from network drives is not implemented yet");
return 0;
}
Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
ERR_PRINT("Setting UNIX permissions on network drives is not implemented yet");
return ERR_UNAVAILABLE;
}
void FileAccessNetwork::configure() {
GLOBAL_DEF("network/remote_fs/page_size", 65536);
ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_size", PropertyInfo(Variant::INT, "network/remote_fs/page_size", PROPERTY_HINT_RANGE, "1,65536,1,or_greater")); //is used as denominator and can't be zero
GLOBAL_DEF("network/remote_fs/page_read_ahead", 4);
ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_read_ahead", PropertyInfo(Variant::INT, "network/remote_fs/page_read_ahead", PROPERTY_HINT_RANGE, "0,8,1,or_greater"));
GLOBAL_DEF("network/remote_fs/max_pages", 20);
}
FileAccessNetwork::FileAccessNetwork() {
@ -513,6 +510,9 @@ FileAccessNetwork::FileAccessNetwork() {
eof_flag = false;
opened = false;
pos = 0;
sem = Semaphore::create();
page_sem = Semaphore::create();
buffer_mutex = Mutex::create();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id = nc->last_id++;
@ -520,6 +520,7 @@ FileAccessNetwork::FileAccessNetwork() {
nc->unlock_mutex();
page_size = GLOBAL_GET("network/remote_fs/page_size");
read_ahead = GLOBAL_GET("network/remote_fs/page_read_ahead");
max_pages = GLOBAL_GET("network/remote_fs/max_pages");
last_activity_val = 0;
waiting_on_page = -1;
last_page = -1;
@ -528,6 +529,9 @@ FileAccessNetwork::FileAccessNetwork() {
FileAccessNetwork::~FileAccessNetwork() {
close();
memdelete(sem);
memdelete(page_sem);
memdelete(buffer_mutex);
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,10 +31,10 @@
#ifndef FILE_ACCESS_NETWORK_H
#define FILE_ACCESS_NETWORK_H
#include "core/io/stream_peer_tcp.h"
#include "core/os/file_access.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
#include "io/stream_peer_tcp.h"
#include "os/file_access.h"
#include "os/semaphore.h"
#include "os/thread.h"
class FileAccessNetwork;
@ -47,13 +47,15 @@ class FileAccessNetworkClient {
int size;
};
int ml;
List<BlockRequest> block_requests;
Semaphore sem;
Thread thread;
Semaphore *sem;
Thread *thread;
bool quit;
Mutex mutex;
Mutex blockrequest_mutex;
Mutex *mutex;
Mutex *blockrequest_mutex;
Map<int, FileAccessNetwork *> accesses;
Ref<StreamPeerTCP> client;
int last_id;
@ -85,9 +87,9 @@ public:
class FileAccessNetwork : public FileAccess {
Semaphore sem;
Semaphore page_sem;
Mutex buffer_mutex;
Semaphore *sem;
Semaphore *page_sem;
Mutex *buffer_mutex;
bool opened;
size_t total_size;
mutable size_t pos;
@ -98,6 +100,7 @@ class FileAccessNetwork : public FileAccess {
int page_size;
int read_ahead;
int max_pages;
mutable int waiting_on_page;
mutable int last_activity_val;
@ -159,8 +162,6 @@ public:
virtual bool file_exists(const String &p_path); ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file);
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
static void configure();

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -29,16 +29,17 @@
/*************************************************************************/
#include "file_access_pack.h"
#include "core/version.h"
#include "version.h"
#include <stdio.h>
Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_offset) {
#define PACK_VERSION 1
Error PackedData::add_pack(const String &p_path) {
for (int i = 0; i < sources.size(); i++) {
if (sources[i]->try_open_pack(p_path, p_replace_files, p_offset)) {
if (sources[i]->try_open_pack(p_path)) {
return OK;
};
@ -47,7 +48,7 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, size_t p_
return ERR_FILE_UNRECOGNIZED;
};
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) {
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) {
PathMD5 pmd5(path.md5_buffer());
//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
@ -62,8 +63,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
pf.md5[i] = p_md5[i];
pf.src = p_src;
if (!exists || p_replace_files)
files[pmd5] = pf;
files[pmd5] = pf;
if (!exists) {
//search for dir
@ -88,11 +88,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
}
}
String filename = path.get_file();
// Don't add as a file if the path points to a directory
if (!filename.empty()) {
cd->files.insert(filename);
}
cd->files.insert(path.get_file());
}
}
@ -132,31 +128,23 @@ PackedData::~PackedData() {
//////////////////////////////////////////////////////////////////
bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) {
bool PackedSourcePCK::try_open_pack(const String &p_path) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f)
return false;
f->seek(p_offset);
//printf("try open %ls!\n", p_path.c_str());
uint32_t magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
// loading with offset feature not supported for self contained exe files
if (p_offset != 0) {
f->close();
memdelete(f);
ERR_FAIL_V_MSG(false, "Loading self-contained executable with offset not supported.");
}
//maybe at the end.... self contained exe
if (magic != 0x43504447) {
//maybe at he end.... self contained exe
f->seek_end();
f->seek(f->get_position() - 4);
magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
if (magic != 0x43504447) {
f->close();
memdelete(f);
return false;
}
@ -166,9 +154,8 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
f->seek(f->get_position() - ds - 8);
magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
if (magic != 0x43504447) {
f->close();
memdelete(f);
return false;
}
@ -177,18 +164,12 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
uint32_t version = f->get_32();
uint32_t ver_major = f->get_32();
uint32_t ver_minor = f->get_32();
f->get_32(); // patch number, not used for validation.
uint32_t ver_rev = f->get_32();
if (version != PACK_FORMAT_VERSION) {
f->close();
memdelete(f);
ERR_FAIL_V_MSG(false, "Pack version unsupported: " + itos(version) + ".");
}
if (ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR)) {
f->close();
memdelete(f);
ERR_FAIL_V_MSG(false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + ".");
}
ERR_EXPLAIN("Pack version unsupported: " + itos(version));
ERR_FAIL_COND_V(version != PACK_VERSION, false);
ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev));
ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false);
for (int i = 0; i < 16; i++) {
//reserved
@ -212,11 +193,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs + p_offset, size, md5, this, p_replace_files);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this);
};
f->close();
memdelete(f);
return true;
};
@ -284,13 +263,11 @@ uint8_t FileAccessPack::get_8() const {
}
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!p_dst && p_length > 0, -1);
ERR_FAIL_COND_V(p_length < 0, -1);
if (eof)
return 0;
uint64_t to_read = p_length;
int64_t to_read = p_length;
if (to_read + pos > pf.size) {
eof = true;
to_read = int64_t(pf.size) - int64_t(pos);
@ -340,9 +317,10 @@ bool FileAccessPack::file_exists(const String &p_name) {
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
pf(p_file),
f(FileAccess::open(pf.pack, FileAccess::READ)) {
ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
if (!f) {
ERR_EXPLAIN("Can't open pack-referenced file: " + String(pf.pack));
ERR_FAIL_COND(!f);
}
f->seek(pf.offset);
pos = 0;
eof = false;
@ -414,15 +392,9 @@ String DirAccessPack::get_drive(int p_drive) {
return "";
}
PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
Error DirAccessPack::change_dir(String p_dir) {
String nd = p_dir.replace("\\", "/");
// Special handling since simplify_path() will forbid it
if (p_dir == "..") {
return current->parent;
}
bool absolute = false;
if (nd.begins_with("res://")) {
nd = nd.replace_first("res://", "");
@ -462,22 +434,13 @@ PackedData::PackedDir *DirAccessPack::_find_dir(String p_dir) {
} else {
return NULL;
return ERR_INVALID_PARAMETER;
}
}
return pd;
}
current = pd;
Error DirAccessPack::change_dir(String p_dir) {
PackedData::PackedDir *pd = _find_dir(p_dir);
if (pd) {
current = pd;
return OK;
} else {
return ERR_INVALID_PARAMETER;
}
return OK;
}
String DirAccessPack::get_current_dir() {
@ -487,7 +450,7 @@ String DirAccessPack::get_current_dir() {
while (pd->parent) {
pd = pd->parent;
p = pd->name.plus_file(p);
p = pd->name + "/" + p;
}
return "res://" + p;
@ -495,20 +458,12 @@ String DirAccessPack::get_current_dir() {
bool DirAccessPack::file_exists(String p_file) {
p_file = fix_path(p_file);
PackedData::PackedDir *pd = _find_dir(p_file.get_base_dir());
if (!pd) {
return false;
}
return pd->files.has(p_file.get_file());
return current->files.has(p_file);
}
bool DirAccessPack::dir_exists(String p_dir) {
p_dir = fix_path(p_dir);
return _find_dir(p_dir) != NULL;
return current->subdirs.has(p_dir);
}
Error DirAccessPack::make_dir(String p_dir) {
@ -530,10 +485,6 @@ size_t DirAccessPack::get_space_left() {
return 0;
}
String DirAccessPack::get_filesystem_type() const {
return "PCK";
}
DirAccessPack::DirAccessPack() {
current = PackedData::get_singleton()->root;

View File

@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* 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 */
@ -31,16 +31,11 @@
#ifndef FILE_ACCESS_PACK_H
#define FILE_ACCESS_PACK_H
#include "core/list.h"
#include "core/map.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/print_string.h"
// Godot's packed file magic header ("GDPC" in ASCII).
#define PACK_HEADER_MAGIC 0x43504447
// The current packed file format version number.
#define PACK_FORMAT_VERSION 1
#include "list.h"
#include "map.h"
#include "os/dir_access.h"
#include "os/file_access.h"
#include "print_string.h"
class PackSource;
@ -107,20 +102,17 @@ private:
public:
void add_pack_source(PackSource *p_source);
void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files); // for PackSource
void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src); // for PackSource
void set_disabled(bool p_disabled) { disabled = p_disabled; }
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; }
Error add_pack(const String &p_path, bool p_replace_files, size_t p_offset);
Error add_pack(const String &p_path);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
_FORCE_INLINE_ DirAccess *try_open_directory(const String &p_path);
_FORCE_INLINE_ bool has_directory(const String &p_path);
PackedData();
~PackedData();
};
@ -128,7 +120,7 @@ public:
class PackSource {
public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset) = 0;
virtual bool try_open_pack(const String &p_path) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
@ -136,7 +128,7 @@ public:
class PackedSourcePCK : public PackSource {
public:
virtual bool try_open_pack(const String &p_path, bool p_replace_files, size_t p_offset);
virtual bool try_open_pack(const String &p_path);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
@ -150,8 +142,6 @@ class FileAccessPack : public FileAccess {
FileAccess *f;
virtual Error _open(const String &p_path, int p_mode_flags);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
public:
virtual void close();
@ -185,6 +175,7 @@ public:
FileAccess *PackedData::try_open_path(const String &p_path) {
//print_line("try open path " + p_path);
PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
if (!E)
@ -200,17 +191,6 @@ bool PackedData::has_path(const String &p_path) {
return files.has(PathMD5(p_path.md5_buffer()));
}
bool PackedData::has_directory(const String &p_path) {
DirAccess *da = try_open_directory(p_path);
if (da) {
memdelete(da);
return true;
} else {
return false;
}
}
class DirAccessPack : public DirAccess {
PackedData::PackedDir *current;
@ -219,8 +199,6 @@ class DirAccessPack : public DirAccess {
List<String> list_files;
bool cdir;
PackedData::PackedDir *_find_dir(String p_dir);
public:
virtual Error list_dir_begin();
virtual String get_next();
@ -244,20 +222,8 @@ public:
size_t get_space_left();
virtual String get_filesystem_type() const;
DirAccessPack();
~DirAccessPack();
};
DirAccess *PackedData::try_open_directory(const String &p_path) {
DirAccess *da = memnew(DirAccessPack());
if (da->change_dir(p_path) != OK) {
memdelete(da);
da = NULL;
}
return da;
}
#endif // FILE_ACCESS_PACK_H

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