Compare commits
636 Commits
3.1
...
3.0.6-stab
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ac39d8863 | |||
| 83140541dc | |||
| 4491151aa9 | |||
| 5262d1bbcc | |||
| 1a325e3580 | |||
| fc678567d7 | |||
| 286ff21dd1 | |||
| cf1c127c23 | |||
| e7110984f3 | |||
| 31f8d3525d | |||
| e1cf8dc2cb | |||
| 291be24742 | |||
| 3304c7620a | |||
| ba441c48b0 | |||
| e5aedf130f | |||
| 94debea0a9 | |||
| c6a48e11e9 | |||
| 327452cb09 | |||
| c751b66d38 | |||
| 5928b18cf3 | |||
| f37779ba20 | |||
| ef67ef3155 | |||
| ba3406fffe | |||
| 68bfea5aa0 | |||
| be588f9493 | |||
| c3fcb18bc6 | |||
| 4897227d04 | |||
| 11cbf850a4 | |||
| c00c3f10a4 | |||
| 00fa61f8f5 | |||
| d3a482ab65 | |||
| b64850e732 | |||
| bc2ee93758 | |||
| 2843a3f7e7 | |||
| 33a9bda1d9 | |||
| d3c4f91c9c | |||
| 5c6c88ef15 | |||
| 69cdb35820 | |||
| 4d89153e5f | |||
| c709dff1a2 | |||
| d859aa1438 | |||
| 4fcb0d036c | |||
| b5338b640f | |||
| 6a88e22423 | |||
| 861d341dff | |||
| a34daf6851 | |||
| 59a00c3cdd | |||
| e86ef017f2 | |||
| d4a226500b | |||
| 16550339ba | |||
| 84e1551c64 | |||
| af902dc042 | |||
| d99b247cc7 | |||
| 139185e543 | |||
| 64bcefb7cd | |||
| 4ac9932128 | |||
| 9190ae2be7 | |||
| a03cf8964f | |||
| 4bf441c32b | |||
| b116a45f07 | |||
| d91613592b | |||
| e6df472e8f | |||
| f6abffdb4a | |||
| a1930b1772 | |||
| 9530ce9d3f | |||
| 3d8e49d9e8 | |||
| 64419a2ea1 | |||
| 34eabc0602 | |||
| ade470352c | |||
| ae48b1b94a | |||
| 394838901d | |||
| f49fcc960b | |||
| 2f3e4c1a7a | |||
| d04cc2855a | |||
| 909eaede4c | |||
| 4d7aa0b762 | |||
| 98609279b6 | |||
| 25047050b7 | |||
| 38e6ba10b4 | |||
| e649ec71df | |||
| 711aa196af | |||
| 518a691231 | |||
| e8bfc09b81 | |||
| 74808e71d2 | |||
| 403f7dc35f | |||
| e09170dffa | |||
| f640639867 | |||
| d24f77be99 | |||
| f697b53eba | |||
| 8231b3cef8 | |||
| b95cc40640 | |||
| 9294978596 | |||
| 3d3e4e62af | |||
| d00926894e | |||
| 5d2ad1e5c7 | |||
| 9945da3efc | |||
| d1e5677fe6 | |||
| 49ddd7b0e7 | |||
| e29800ea7b | |||
| 97ad6b813a | |||
| 77542276f8 | |||
| 0a3779135d | |||
| edf423a7aa | |||
| 02b1586de2 | |||
| a2a136ea02 | |||
| 9b8388dab1 | |||
| fbad7c2dd9 | |||
| 12fe774844 | |||
| 8dc021925f | |||
| 6843ccf462 | |||
| b27352a401 | |||
| 8461d6b5f9 | |||
| 0febfa9eea | |||
| 232a3a524b | |||
| b04c9a1b66 | |||
| dd026c77e3 | |||
| 00bf66d7f2 | |||
| 6224f02c56 | |||
| 31ce9ba07f | |||
| 94b4bb2a12 | |||
| 188bfd2ac9 | |||
| 04defcca4f | |||
| 81eb60434a | |||
| 6635f2a108 | |||
| 1d3be8c453 | |||
| 4de1d0905a | |||
| c461b15720 | |||
| 5c93f887ba | |||
| 9dc5ca0e7c | |||
| c7b141d20a | |||
| 0b3b3de2cd | |||
| 5e551a584e | |||
| fd95935fef | |||
| 4fbb460a02 | |||
| 4aad40d249 | |||
| 8ccb27ce18 | |||
| 9a0a40042e | |||
| 09277c8fd8 | |||
| faceb5b75d | |||
| 9dc5ba1aaf | |||
| a187fb381e | |||
| 868c44b239 | |||
| 10c12b37ec | |||
| ae32bcf4c3 | |||
| 3491e776dd | |||
| 5f632391ca | |||
| 2e61ca6193 | |||
| 3013f4cf2b | |||
| 31c4b743cb | |||
| 78e2e48d57 | |||
| 736e574a5e | |||
| 664052824e | |||
| 0b9f61c9a6 | |||
| 41bb321962 | |||
| 0c030d6e08 | |||
| c8ce9c0080 | |||
| a519dcd576 | |||
| 66c0be642f | |||
| 2fa54c1df6 | |||
| 7f65584f28 | |||
| 7e09206e5c | |||
| ecb4c4268c | |||
| db76c54117 | |||
| c2a8eb2081 | |||
| 5917063192 | |||
| bcb38393a5 | |||
| 1905e1c8a2 | |||
| a6c9527c2f | |||
| f4c469f1b7 | |||
| 196107cd9e | |||
| 33b78c0ad6 | |||
| fa19d01c7b | |||
| f847837fb2 | |||
| 056348a8c0 | |||
| ddbe559c04 | |||
| 63e70e3cd1 | |||
| 4866733a74 | |||
| 01e64eb247 | |||
| 4fe0a8efd8 | |||
| 0551c5c2cd | |||
| e10a2e5999 | |||
| cd9b0d7cc3 | |||
| 8e301c69cb | |||
| 3ee4d6af2e | |||
| 00c55bb2eb | |||
| fe9da69f96 | |||
| c358e4c728 | |||
| 7645c539c8 | |||
| e7837828f6 | |||
| 272fb05270 | |||
| 41f360f9c2 | |||
| 4ce6a8f5f9 | |||
| dfe6d42a01 | |||
| c20776945d | |||
| 0d6c64b38a | |||
| c968c787e5 | |||
| 6e658fdcc1 | |||
| aedc4a4e80 | |||
| 7417b6adb4 | |||
| 66b36235c9 | |||
| e317ab9abe | |||
| 6a48c552e2 | |||
| a1fd60f7d2 | |||
| b5ecdd8ce8 | |||
| 20ea59332f | |||
| 57b895338b | |||
| 2f82b67071 | |||
| 56b8c4b0eb | |||
| bae5f9feb8 | |||
| e95f542204 | |||
| e7c42f132c | |||
| 1608f04851 | |||
| 93ebac318b | |||
| c4d66d087f | |||
| feee8ddd3c | |||
| 659df8cbd8 | |||
| 19a010cc3a | |||
| 307fcb2713 | |||
| ec017f4c01 | |||
| f12db4013e | |||
| e53f01a7af | |||
| 46de6afc40 | |||
| 90bf0b7aec | |||
| 6cdf6d3044 | |||
| 1da969736f | |||
| 486f4d2769 | |||
| 199a54d5ac | |||
| 57c281557a | |||
| d330bee1c2 | |||
| 72bcacf2b6 | |||
| 3876a8776e | |||
| 37ce381e3d | |||
| 939d50243b | |||
| 57f18194f5 | |||
| 58f2953ddf | |||
| 31171ea5a2 | |||
| e7b97af276 | |||
| 95004aafb2 | |||
| 3f6ea30f8d | |||
| 58918b629d | |||
| 736d8db007 | |||
| 1e8ff7460a | |||
| b5425e3d87 | |||
| 3acd6fb728 | |||
| 94ddb499df | |||
| 5a947ebc42 | |||
| 44f4c8e745 | |||
| 4eed7cb9b2 | |||
| ca00323e7f | |||
| d49fc76ab8 | |||
| d89015cfe3 | |||
| 826108efec | |||
| 739c14b07d | |||
| 7f64090401 | |||
| 3bda257163 | |||
| 02f767fe0d | |||
| 20fa30bde6 | |||
| b5b0e42b85 | |||
| a525ea128d | |||
| 3b57b95efb | |||
| 4002da9603 | |||
| e5a17617e6 | |||
| 4e756d61c8 | |||
| 0f5a3d23ea | |||
| 2e31c9fe10 | |||
| cf3c1d878d | |||
| c5dfe6824c | |||
| 640063334d | |||
| ac9e87aae3 | |||
| 5e09cf3e89 | |||
| 6989a7ac53 | |||
| 060f9f2cd7 | |||
| 4c19fc2eb1 | |||
| 5e70e4469a | |||
| 287f169f2a | |||
| 60bc0f79a7 | |||
| c8d0d38cab | |||
| d3ffc8ad0c | |||
| 393e1ef4ee | |||
| 78b44eab0a | |||
| 0f6626977b | |||
| 71885e5ae4 | |||
| 038c4d3a83 | |||
| de66976ff0 | |||
| b08aa6fb3c | |||
| ce944bc3fb | |||
| 5485939233 | |||
| 3cc2eee4e8 | |||
| 56395b03e1 | |||
| 448d281222 | |||
| c07d588e80 | |||
| 52c710f25a | |||
| 29a02a78df | |||
| 91525e3075 | |||
| 7563c17113 | |||
| 43dcf23990 | |||
| 1182637ec9 | |||
| d40f40e1c9 | |||
| fa831f0224 | |||
| 141e389c3f | |||
| 72350eebb2 | |||
| 80fbea28fb | |||
| 7ec8a6e756 | |||
| ddb31e9c5a | |||
| dc97f91a18 | |||
| 171542d96a | |||
| b855bc44ae | |||
| c39e32ae60 | |||
| 5eef26b64e | |||
| 0d2a2a9300 | |||
| 6d767b0f9a | |||
| d49579b038 | |||
| a3ba1b0280 | |||
| c2e02e2066 | |||
| 3503ee4be6 | |||
| 069b429795 | |||
| 2f7aa6c2aa | |||
| a29680c25a | |||
| 3a430e46b9 | |||
| b4733a1da9 | |||
| 8ebd4bb874 | |||
| 63a88c69ac | |||
| bfc94dd4c9 | |||
| 6472d8c7d4 | |||
| e4fadebc3b | |||
| 548ec63f76 | |||
| 9e4d34aebb | |||
| d02c891a4b | |||
| 3bd414786c | |||
| c7adcc8dca | |||
| 577f3ccaf9 | |||
| bffd4f0548 | |||
| 4c8c383876 | |||
| 125b403c0f | |||
| 5f5ec7e162 | |||
| a91d9cb918 | |||
| a7ea441504 | |||
| 4b5472b100 | |||
| 3dc4447cb8 | |||
| 9a21f964ba | |||
| 1f07f71b6c | |||
| 259b9664ef | |||
| b5a55810c5 | |||
| 4fc6256010 | |||
| ce1b62a01f | |||
| 28d4271e3e | |||
| 30b5265417 | |||
| 2f53325bed | |||
| 7ad6a9aeea | |||
| 8018dc6599 | |||
| aaed3ef5ed | |||
| 99cf2ffb19 | |||
| 3b200c55b6 | |||
| 13e9b605cf | |||
| 5d7b7f798a | |||
| 710b57d493 | |||
| ef44ed93a7 | |||
| 4f0b5f7307 | |||
| 1c25e50490 | |||
| a9ec1e3913 | |||
| 46101928bd | |||
| 74e72c995d | |||
| b6f30f1b5b | |||
| b09d06fcf7 | |||
| 9567297a66 | |||
| 607884139c | |||
| 42f351db0d | |||
| 9ab9dd73b0 | |||
| fa9e03996c | |||
| 814b610ed3 | |||
| a5ccaa919e | |||
| 5042d0c30a | |||
| 27f5e404a7 | |||
| 2e9c9f7d74 | |||
| 6063e74e06 | |||
| 449e75455b | |||
| 73cc3a96c0 | |||
| 683511310e | |||
| 12336dc253 | |||
| 8da76f3bb8 | |||
| 8289f8628d | |||
| 91bc845152 | |||
| d8a0b6ba63 | |||
| bf4d8ee69c | |||
| 2c93def09d | |||
| 9cbcff4e91 | |||
| 985b84689f | |||
| 89e4125241 | |||
| 209acbaac7 | |||
| 8a0966a8cb | |||
| 99331ca395 | |||
| ec362d54a9 | |||
| 5e8e2a8730 | |||
| df7d60a9d3 | |||
| fe20a1e35b | |||
| 55a66efa38 | |||
| 5eebe51014 | |||
| 9febb6f747 | |||
| 626525d23a | |||
| a026e2626c | |||
| cf2e30b30c | |||
| f7efa9d43a | |||
| dfb739aff0 | |||
| 89bff17cd2 | |||
| 3e1716b2c3 | |||
| e6200de73a | |||
| 593e616a48 | |||
| eeb7385f02 | |||
| 2ff3b08583 | |||
| 6ab8fb04af | |||
| 498d177cfe | |||
| 06a60bb6ef | |||
| c0132f30c4 | |||
| 649cb70ddb | |||
| 65d214d3da | |||
| 9ee98e999b | |||
| 5bcc7f88b6 | |||
| 93e99846b0 | |||
| 5c2e554853 | |||
| c4468aef5d | |||
| f967334f53 | |||
| 4132f2ea7e | |||
| 262c97098d | |||
| cee20e24bd | |||
| 87476c057a | |||
| 53693e393d | |||
| 3f7e036c4f | |||
| 0aab429453 | |||
| 61fd30c00e | |||
| 44b206a3fa | |||
| 675899a521 | |||
| 61a9ef5d81 | |||
| 9c27e4d885 | |||
| c800653c6f | |||
| 3e931e258c | |||
| 7e5a374825 | |||
| a850ebf352 | |||
| 4e1d19b20c | |||
| d7430ef077 | |||
| 17408bea9c | |||
| 2c55064708 | |||
| 42e82b9377 | |||
| a4b077a0ba | |||
| f6c65d9d15 | |||
| 990bddcf36 | |||
| c730a6ce44 | |||
| 115c0a7415 | |||
| 87242c7b92 | |||
| 4eb9ee9355 | |||
| 48ed52184d | |||
| 69274ef368 | |||
| 039fc750d5 | |||
| 58a7d78c22 | |||
| c0386f0124 | |||
| b6f958965b | |||
| dde14e15c6 | |||
| 1ea805a4aa | |||
| 3b96b3fd12 | |||
| e499b9b4b6 | |||
| 8ea709a7a9 | |||
| f2e19a26f5 | |||
| be771e7165 | |||
| cb65617897 | |||
| bcbe7a8a6f | |||
| ae540c2efe | |||
| 5f15642fde | |||
| 17d7084780 | |||
| fe38b648b0 | |||
| ad325be5a0 | |||
| d69d58deea | |||
| 34591f9451 | |||
| d79a7a2773 | |||
| 05fec82f31 | |||
| 370f84f41c | |||
| 689dfcd9ec | |||
| 46b594054c | |||
| 07e2461995 | |||
| ca5f3b9f8d | |||
| 3d804778fd | |||
| 3e8c214a19 | |||
| e9d8dfbf0e | |||
| 3687faa78f | |||
| eacd66e784 | |||
| b5f8c1a53b | |||
| f04cd405ac | |||
| f55b376d78 | |||
| fdac09a0aa | |||
| 751806b5c7 | |||
| 40018e995c | |||
| be6323d848 | |||
| 29089b715d | |||
| 7e89cc46dd | |||
| a86829211a | |||
| f01821b60a | |||
| 245c11be08 | |||
| fa98637aca | |||
| 723613dbc3 | |||
| 99efa7ce62 | |||
| c7040f3218 | |||
| 5975b44ded | |||
| 8efb9c8cdd | |||
| 75289b4017 | |||
| ccf27376a6 | |||
| 23b9f09c58 | |||
| e1fc7776f6 | |||
| c6a96fc360 | |||
| 4383fae5a4 | |||
| 9cfcf102a0 | |||
| 8dc946c89c | |||
| 327fea741a | |||
| 317cb336eb | |||
| 83b76a8171 | |||
| 70b082c0d9 | |||
| bbfec2a7cc | |||
| 8849377f6d | |||
| 149ffcb1a4 | |||
| fb4a784319 | |||
| 8f231d82bb | |||
| cc280545dc | |||
| fa02b58b46 | |||
| 000caef623 | |||
| b7faa76485 | |||
| a76dfe9c72 | |||
| a423adbee6 | |||
| c5b5fd61d4 | |||
| 5bb269d01d | |||
| d5535d9357 | |||
| 2714b851bf | |||
| 2abbdcaa20 | |||
| 9cba5ef772 | |||
| 416cd9c8b8 | |||
| 7a20495a80 | |||
| bafbd73b51 | |||
| ac6811c4fa | |||
| 8372a404bb | |||
| 5b04dcfabd | |||
| 4b581104e7 | |||
| f49601a934 | |||
| 3e6ab9f3d5 | |||
| 9f9731da3a | |||
| 18735ff6f2 | |||
| 237cf72f89 | |||
| 5c2b2ca95b | |||
| 57f707f951 | |||
| 2f87e7ffe9 | |||
| 12da8dcdeb | |||
| c5388fb0cf | |||
| 02e910275c | |||
| 285f47f037 | |||
| 9fb843db06 | |||
| 4bdcee2b9d | |||
| fd033473c7 | |||
| a39930c5b9 | |||
| c94d8e6577 | |||
| eb5e5200cc | |||
| d54ac732ae | |||
| 62fcd772be | |||
| 150423203b | |||
| ef60123938 | |||
| 0d03b5f162 | |||
| 148e059940 | |||
| 7af43c4ca3 | |||
| 5b32be4701 | |||
| 47b49200b0 | |||
| a7d7f763d0 | |||
| eda94419df | |||
| e6252bda5e | |||
| 069658f1be | |||
| a0e59a7259 | |||
| 82b9a13e0c | |||
| 79ef5f92a9 | |||
| 5d7867082d | |||
| fda35b3f42 | |||
| a0e9d751a3 | |||
| d4a70c6c08 | |||
| 65aa9063c4 | |||
| 9eb546e7ff | |||
| f031e2f665 | |||
| 4bed14f69b | |||
| 91692ce72a | |||
| 05e97db6f2 | |||
| 617bcd1b91 | |||
| 34d8625d82 | |||
| 79b931d093 | |||
| 9173819b71 | |||
| 8787850286 | |||
| 2515d42a14 | |||
| 1a9a40fe31 | |||
| eda3169cd1 | |||
| d7f73031fb | |||
| ba36ef5465 | |||
| 41f9904e71 | |||
| a206d3d2fc | |||
| a6ca62ac79 | |||
| 85dedc09a8 | |||
| 9e7c3016d1 | |||
| 906cf28dae | |||
| 801b544ee1 | |||
| 097f95993f | |||
| c04d868476 | |||
| 50674dbe15 | |||
| 71607d9198 | |||
| 3548f71cc4 | |||
| a1455f6a03 | |||
| f64b68d870 | |||
| f1d26c1c72 | |||
| 7f5fde6459 | |||
| 611caa06a5 | |||
| 3f6e8d70cf | |||
| 40c779fb70 | |||
| 532abf228c | |||
| 248fea2a79 | |||
| 7de47fbabb | |||
| 62dc7ba82f | |||
| 4a3a597377 | |||
| 501880e9ba | |||
| bd02969263 | |||
| 0fa4325153 | |||
| acf01c955f | |||
| 0a75a38db4 | |||
| 845f44b976 | |||
| 77ee4ced30 | |||
| 780a7a281b | |||
| 5481ece976 | |||
| ef49c166f6 | |||
| 77cc0a023b | |||
| 1036a76bc5 | |||
| e44bef4404 | |||
| c77047d6a3 | |||
| a34afa3820 | |||
| 77d27053c3 | |||
| 187c40d64d | |||
| e69b30b276 | |||
| 99e72894a2 | |||
| 258119a9cf | |||
| 3f6694b894 |
@ -4,7 +4,7 @@ environment:
|
||||
HOME: "%HOMEDRIVE%%HOMEPATH%"
|
||||
PYTHON: C:\Python27
|
||||
SCONS_CACHE_ROOT: "%HOME%\\scons_cache"
|
||||
SCONS_CACHE_LIMIT: 1024
|
||||
SCONS_CACHE_LIMIT: 512
|
||||
matrix:
|
||||
- VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
||||
GD_PLATFORM: windows
|
||||
@ -12,16 +12,13 @@ environment:
|
||||
TARGET: release_debug
|
||||
ARCH: amd64
|
||||
|
||||
init:
|
||||
- ps: if ($env:APPVEYOR_REPO_BRANCH -ne "master") { $env:APPVEYOR_CACHE_SKIP_SAVE = "true" }
|
||||
|
||||
cache:
|
||||
- "%SCONS_CACHE_ROOT%"
|
||||
|
||||
install:
|
||||
- SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
|
||||
- pip install -U wheel # needed for pip install scons to work, otherwise a flag is missing
|
||||
- pip install scons==3.0.1
|
||||
- pip install scons
|
||||
- if defined VS call "%VS%" %ARCH% # if defined - so we can also use mingw
|
||||
|
||||
before_build:
|
||||
@ -29,7 +26,7 @@ before_build:
|
||||
- python --version
|
||||
- scons --version
|
||||
- cl.exe
|
||||
- set "SCONS_CACHE=%SCONS_CACHE_ROOT%\%APPVEYOR_REPO_BRANCH%"
|
||||
- SET "SCONS_CACHE=%SCONS_CACHE_ROOT%\master"
|
||||
|
||||
build_script:
|
||||
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no verbose=yes progress=no gdnative_wrapper=yes
|
||||
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% verbose=yes progress=no gdnative_wrapper=yes
|
||||
|
||||
@ -116,7 +116,6 @@ Standard: Cpp03
|
||||
---
|
||||
### ObjC specific config ###
|
||||
Language: ObjC
|
||||
Standard: Cpp03
|
||||
ObjCBlockIndentWidth: 4
|
||||
# ObjCSpaceAfterProperty: false
|
||||
# ObjCSpaceBeforeProtocolList: true
|
||||
|
||||
@ -9,7 +9,7 @@ insert_final_newline = true
|
||||
[*.{cpp,hpp,c,h,mm}]
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[{*.{py,cs},SCsub}]
|
||||
[*.py]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9,4 +9,3 @@ drivers/* linguist-vendored
|
||||
*.py eol=lf
|
||||
*.hpp eol=lf
|
||||
*.xml eol=lf
|
||||
*.natvis eol=lf
|
||||
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@ -91,9 +91,6 @@ bld/
|
||||
*.debug
|
||||
*.dSYM
|
||||
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
@ -101,6 +98,9 @@ bld/
|
||||
# Hints for improving IntelliSense, created together with VS project
|
||||
cpp.hint
|
||||
|
||||
# Visualizers for the VS debugger
|
||||
*.natvis
|
||||
|
||||
#NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
@ -238,7 +238,6 @@ ClientBin/
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
__pycache__/
|
||||
|
||||
# KDE
|
||||
.directory
|
||||
@ -292,7 +291,6 @@ logo.h
|
||||
TAGS
|
||||
!TAGS/
|
||||
tags
|
||||
*.tags
|
||||
!tags/
|
||||
gtags.files
|
||||
GTAGS
|
||||
@ -311,15 +309,5 @@ platform/windows/godot_res.res
|
||||
/.vs
|
||||
/.vscode
|
||||
|
||||
# Visual Studio Code workspace file
|
||||
*.code-workspace
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
111
.mailmap
111
.mailmap
@ -1,120 +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>
|
||||
Andreas Haas <liu.gam3@gmail.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <hinsbart@gmail.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <hinsbart@users.noreply.github.com>
|
||||
Andreas Haas <liu.gam3@gmail.com> <entenflugstuhl@gmail.com>
|
||||
Anish Bhobe <anishbhobe@hotmail.com>
|
||||
Anutrix <numaanzaheerahmed@yahoo.com>
|
||||
Aren Villanueva <arenvillanueva@yomogi-soft.com> <aren@displaysweet.com>
|
||||
Andreas Haas <Hinsbart@users.noreply.github.com>
|
||||
Andreas Haas <entenflugstuhl@gmail.com>
|
||||
Ariel Manzur <ariel@godotengine.org>
|
||||
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>
|
||||
Emmanuel Barroga <emmanuelbarroga@gmail.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>
|
||||
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>
|
||||
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>
|
||||
Manuel Strey <manuel.strey@gmx.de>
|
||||
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>
|
||||
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>
|
||||
Max Hilbrunner <m.hilbrunner@gmail.com>
|
||||
Max Hilbrunner <m.hilbrunner@gmail.com> <mhilbrunner@users.noreply.github.com>
|
||||
Michael Alexsander <michaelalexsander@protonmail.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 <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>
|
||||
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>
|
||||
Zak Stam <zakscomputers@hotmail.com>
|
||||
Zher Huei Lee <lee.zh.92@gmail.com>
|
||||
|
||||
89
.travis.yml
89
.travis.yml
@ -1,15 +1,15 @@
|
||||
language: cpp
|
||||
|
||||
# OS config, depends on actual 'os' in build matrix
|
||||
dist: xenial
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
env:
|
||||
global:
|
||||
- SCONS_CACHE=$HOME/.scons_cache/$TRAVIS_BRANCH
|
||||
- SCONS_CACHE=$HOME/.scons_cache
|
||||
- SCONS_CACHE_LIMIT=1024
|
||||
- OPTIONS="debug_symbols=no verbose=yes progress=no"
|
||||
- secure: "uch9QszCgsl1qVbuzY41P7S2hWL2IiNFV4SbAYRCdi0oJ9MIu+pVyrQdpf3+jG4rH6j4Rffl+sN17Zz4dIDDioFL1JwqyCqyCyswR8uACC0Rr8gr4Mi3+HIRbv+2s2P4cIQq41JM8FJe84k9jLEMGCGh69w+ibCWoWs74CokYVA="
|
||||
- OPTIONS="verbose=yes progress=no gdnative_wrapper=yes"
|
||||
- secure: "QLFRizqry/Y5pnEZvDlQz5S3YydQ+600u4rHEzFgUTd0heYeQaETXAQeMzp0ymuG1BkdRAl5YJoLVJgAzjwI9hrvugvoUlh2//SfpqZCHN/Q1fYbtGgNTn01R3VFEpcfYQL93I2EjrxVm0WTM4PwCvMO+hU0aWTRDvCt1Lty0kMR+RMDQOO/woqunoXh5wvFNxTJJkAmuLe0v962DJYOIwJAnqMLR0aFYjmeQJ20bc/2X5oLt+WuJDuf/lGj6WSlD6z/o/kL3YxHoUyw4A/HAZ2IX0IfNHKuay60ESWzl/NlobnePiPwHAE2pdDVu//q16fanb9VeYnBYRFse49TpFRb86Lo+Qz8nKDJqpQEIY0YKNCFqekrubqTM++Lj6QvGpykQZNxUhybmELcEsRG4PS0UMvCpebdnJD46nNB+DtO2Lgb4xXDLQwpq19z1wizq/XDQ5hz61TIIx8+i8TsgdSQKCTeWovd4HcD4CVjAD5XTLGgyRmI/zC2d+lTnKo6W9diLq/bX/Goq2QPeaTPABqv817IaJka2JyugQ7Qal/+gNTjYRRsimRCL9B2tVh+Uh8rWhTFhQL4QbP5P65HF+p8qojUzqtAhPMbZ8mxUtNukUI3liVgPgiMss96sG0nTVglFgkkAkEjIMFnqMSKnTfG812K4jIhp2jCO2Q3NeI="
|
||||
|
||||
cache:
|
||||
directories:
|
||||
@ -23,22 +23,9 @@ matrix:
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-xenial-6.0
|
||||
- llvm-toolchain-trusty-5.0
|
||||
packages:
|
||||
- clang-format-6.0
|
||||
|
||||
- env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc-8 MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" EXTRA_ARGS="module_mono_enabled=yes mono_glue=no warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: gcc-8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- mono
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- &gcc8_deps [gcc-8, g++-8]
|
||||
- &linux_deps [libasound2-dev, libfreetype6-dev, libgl1-mesa-dev, libglu1-mesa-dev, libx11-dev, libxcursor-dev, libxi-dev, libxinerama-dev, libxrandr-dev]
|
||||
- &linux_mono_deps [mono-devel, msbuild, nuget]
|
||||
- clang-format-5.0
|
||||
|
||||
coverity_scan:
|
||||
project:
|
||||
@ -49,38 +36,40 @@ matrix:
|
||||
build_command: "scons p=x11 -j2 $OPTIONS"
|
||||
branch_pattern: coverity_scan
|
||||
|
||||
- env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
|
||||
- env: GODOT_TARGET=x11 TOOLS=yes CACHE_NAME=${GODOT_TARGET}-tools-mono-gcc EXTRA_ARGS="module_mono_enabled=yes mono_glue=no"
|
||||
os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- *linux_deps
|
||||
|
||||
- env: PLATFORM=android TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: clang
|
||||
|
||||
- env: PLATFORM=osx TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-clang
|
||||
os: osx
|
||||
compiler: clang
|
||||
|
||||
- env: PLATFORM=iphone TOOLS=no TARGET=debug CACHE_NAME=${PLATFORM}-clang
|
||||
os: osx
|
||||
compiler: clang
|
||||
|
||||
- env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-8 MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" EXTRA_ARGS="warnings=extra werror=yes"
|
||||
os: linux
|
||||
compiler: gcc-8
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- mono
|
||||
packages:
|
||||
- &linux_deps [libasound2-dev, libfreetype6-dev, libgl1-mesa-dev, libglu1-mesa-dev, libx11-dev, libxcursor-dev, libxi-dev, libxinerama-dev, libxrandr-dev]
|
||||
- &linux_mono_deps [mono-devel, msbuild]
|
||||
|
||||
- env: GODOT_TARGET=x11 TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
|
||||
os: linux
|
||||
compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- *gcc8_deps
|
||||
- *linux_deps
|
||||
|
||||
- env: PLATFORM=x11 TOOLS=no TARGET=release_debug CACHE_NAME=${PLATFORM}-gcc-5
|
||||
- env: GODOT_TARGET=android TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
|
||||
os: linux
|
||||
compiler: clang
|
||||
|
||||
- env: GODOT_TARGET=osx TOOLS=yes CACHE_NAME=${GODOT_TARGET}-tools-clang
|
||||
os: osx
|
||||
osx_image: xcode9.3
|
||||
compiler: clang
|
||||
|
||||
- env: GODOT_TARGET=iphone TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
|
||||
os: osx
|
||||
osx_image: xcode9.3
|
||||
compiler: clang
|
||||
|
||||
- env: GODOT_TARGET=server TOOLS=yes CACHE_NAME=${GODOT_TARGET}-tools-gcc
|
||||
os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
@ -89,25 +78,23 @@ matrix:
|
||||
- *linux_deps
|
||||
|
||||
before_install:
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- if [ "$STATIC_CHECKS" = "yes" ]; then
|
||||
unset SCONS_CACHE;
|
||||
fi
|
||||
|
||||
install:
|
||||
- pip install --user scons;
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$PLATFORM" = "android" ]; then
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ "$GODOT_TARGET" = "android" ]; then
|
||||
misc/travis/android-tools-linux.sh;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
export PATH=${PATH}:/Users/travis/Library/Python/2.7/bin;
|
||||
misc/travis/scons-local-osx.sh;
|
||||
fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$PLATFORM" = "android" ]; then
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then
|
||||
misc/travis/android-tools-osx.sh;
|
||||
fi
|
||||
|
||||
before_script:
|
||||
- if [ "$PLATFORM" = "android" ]; then
|
||||
- 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
|
||||
@ -116,5 +103,5 @@ script:
|
||||
- if [ "$STATIC_CHECKS" = "yes" ]; then
|
||||
sh ./misc/travis/clang-format.sh;
|
||||
else
|
||||
scons -j2 CC=$CC CXX=$CXX platform=$PLATFORM tools=$TOOLS target=$TARGET $OPTIONS $EXTRA_ARGS;
|
||||
scons -j2 CC=$CC CXX=$CXX platform=$GODOT_TARGET TOOLS=$TOOLS $EXTRA_ARGS $OPTIONS;
|
||||
fi
|
||||
|
||||
69
AUTHORS.md
69
AUTHORS.md
@ -25,77 +25,51 @@ 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)
|
||||
Andreas Haas (Hinsbart)
|
||||
Andrii Doroshenko (Xrayez)
|
||||
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)
|
||||
Benjamin (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)
|
||||
Carl Olsson (not-surt)
|
||||
Carter Anderson (cart)
|
||||
Chris Bradfield (cbscribe)
|
||||
Clay John (clayjohn)
|
||||
Dana Olson (adolson)
|
||||
Daniel J. Ramirez (djrm)
|
||||
Daniel Rakos (aqnuep)
|
||||
dankan1890
|
||||
David Sichma (DavidSichma)
|
||||
Dharkael (lupoDharkael)
|
||||
Dmitry Koteroff (Krakean)
|
||||
DualMatrix
|
||||
Emmanuel Barroga (codecustard)
|
||||
Emmanuel Leblond (touilleMan)
|
||||
Eoin O'Neill (Eoin-ONeill-Yokai)
|
||||
Eric Lasota (elasota)
|
||||
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)
|
||||
Jérôme Gully (Nutriz)
|
||||
Joan Fons Sanchez (JFonS)
|
||||
Jérôme GULLY (Nutriz)
|
||||
JFonS
|
||||
Johan Manuel (29jm)
|
||||
Joshua Grams (JoshuaGrams)
|
||||
Juan Linietsky (reduz)
|
||||
@ -103,66 +77,45 @@ name is available.
|
||||
Justo Delgado (mrcdk)
|
||||
Kelly Thomas (KellyThomas)
|
||||
Kostadin Damyanov (Max-Might)
|
||||
K. S. Ernest (iFire) Lee (fire)
|
||||
Leon Krause (eska014)
|
||||
Lucien Menassol (Kanabenki)
|
||||
m4nu3lf
|
||||
Marcel Admiraal (madmiraal)
|
||||
Marcelo Fernandez (marcelofg55)
|
||||
Marc Gilleron (Zylann)
|
||||
Marcin Zawiejski (dragmz)
|
||||
Mariano Javier Suligoy (MarianoGnu)
|
||||
Mario Schlack (hurikhan)
|
||||
Martin Capitanio (capnm)
|
||||
Martin Liška (marxin)
|
||||
Martin Sjursen (binbitten)
|
||||
marynate
|
||||
Masoud BH (masoudbh3)
|
||||
Matthias Hölzl (hoelzl)
|
||||
Max Hilbrunner (mhilbrunner)
|
||||
merumelu
|
||||
Michael Alexsander (YeldhamDev)
|
||||
MichiRecRoom (LikeLakers2)
|
||||
Michael Alexsander Silva Dias (YeldhamDev)
|
||||
mrezai
|
||||
muiroc
|
||||
Nathan Warden (NathanWarden)
|
||||
Nils André-Chang (NilsIrl)
|
||||
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)
|
||||
Roberto F. Arroyo (robfram)
|
||||
Robin Hübner (profan)
|
||||
romulox-x
|
||||
rraallvv
|
||||
Ruslan Mustakov (endragor)
|
||||
Saniko (sanikoyes)
|
||||
santouits
|
||||
SaracenOne
|
||||
sersoong
|
||||
Shiqing (kawa-yoiko)
|
||||
Simon Wenner (swenner)
|
||||
Swarnim Arun (minraws)
|
||||
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)
|
||||
@ -171,7 +124,7 @@ name is available.
|
||||
Wilson E. Alvarez (Rubonnek)
|
||||
Xavier Cho (mysticfall)
|
||||
yg2f (SuperUserNameMan)
|
||||
Yuri Roubinsky (Chaosus)
|
||||
Zak Stam (zaksnet)
|
||||
Yuri Roubinski (Chaosus)
|
||||
Zher Huei Lee (leezh)
|
||||
ZuBsPaCe
|
||||
Дмитрий Сальников (DmitriySalnikov)
|
||||
|
||||
378
CHANGELOG.md
378
CHANGELOG.md
@ -4,264 +4,151 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [3.1] - 2019-03-13
|
||||
## [3.0.6] - 2018-07-29
|
||||
|
||||
### Added
|
||||
|
||||
- OpenGL ES 2.0 renderer.
|
||||
- [Visual shader editor.](https://godotengine.org/article/visual-shader-editor-back)
|
||||
- New PBR output nodes.
|
||||
- Conversion between Vector3 and scalar types is now automatic.
|
||||
- Ability to create custom nodes via scripting.
|
||||
- Ports can now be previewed.
|
||||
- [3D soft body physics.](https://godotengine.org/article/soft-body)
|
||||
- [3D ragdoll system.](https://godotengine.org/article/godot-ragdoll-system)
|
||||
- [Constructive solid geometry in 3D.](https://godotengine.org/article/godot-gets-csg-support)
|
||||
- [2D meshes and skeletal deformation.](https://godotengine.org/article/godot-gets-2d-skeletal-deform)
|
||||
- [Various improvements to KinematicBody2D.](https://godotengine.org/article/godot-31-will-get-many-improvements-kinematicbody)
|
||||
- Support for snapping the body to the floor.
|
||||
- Support for RayCast shapes in kinematic bodies.
|
||||
- Support for synchronizing kinematic movement to physics, avoiding an one-frame delay.
|
||||
- WebSockets support using [libwebsockets](https://libwebsockets.org/).
|
||||
- UPnP support using [MiniUPnP](http://miniupnp.free.fr).
|
||||
- [Revamped inspector.](https://godotengine.org/article/godot-gets-new-inspector)
|
||||
- Improved visualization and editing of numeric properties.
|
||||
- Vector and matrix types can now be edited directly (no pop-ups).
|
||||
- Subresources can now be edited directly within the same inspector.
|
||||
- Layer names can now be displayed in the inspector.
|
||||
- Proper editing of arrays and dictionaries.
|
||||
- Ability to reset any property to its default value.
|
||||
- [Improved animation editor.](https://godotengine.org/article/godot-gets-brand-new-animation-editor-cinematic-support)
|
||||
- Simpler, less cluttered layout.
|
||||
- New Bezier, Audio and Animation tracks.
|
||||
- Several key types can be previewed directly in the track editor.
|
||||
- Tracks can now be grouped and filtered on a per-node basis.
|
||||
- Copying and pasting tracks between animations is now possible.
|
||||
- New Capture mode to blend from a node's current value to the first key in a track.
|
||||
- [Improved animation tree and new state machine.](https://godotengine.org/article/godot-gets-new-animation-tree-state-machine)
|
||||
- More visual feedback in the blend tree editor.
|
||||
- 1D and 2D blend spaces are now supported.
|
||||
- Ability to write custom blending logic.
|
||||
- Support for root motion.
|
||||
- [New FileSystem dock.](https://godotengine.org/article/godot-gets-new-filesystem-dock-3-1)
|
||||
- Unified view of folders and files in the same panel.
|
||||
- Files can now be marked as favorites, not only folders.
|
||||
- Files now have icons representing their type, or thumbnail previews when relevant.
|
||||
- New search field to filter entries in the tree.
|
||||
- [OpenSimplexNoise and NoiseTexture resources.](https://godotengine.org/article/simplex-noise-lands-godot-31)
|
||||
- [Optional static typing in GDScript.](https://godotengine.org/article/optional-typing-gdscript)
|
||||
- Does not currently improve performance, but helps write more robust code.
|
||||
- Warning system in GDScript.
|
||||
- Reports potential code issues such as:
|
||||
- unused variables,
|
||||
- standalone expressions,
|
||||
- discarded return values from functions,
|
||||
- unreachable code after a `return` statement,
|
||||
- …
|
||||
- Warnings can be disabled in the Project Settings or by writing special comments.
|
||||
- [GDScript keyword `class_name` to register scripts as classes.](http://docs.godotengine.org/en/latest/getting_started/step_by_step/scripting_continued.html#register-scripts-as-classes)
|
||||
- Simple expression language independent from GDScript, used by inspector boxes that accept numeric values.
|
||||
- Can also be used in projects.
|
||||
- C# projects can now be exported for Windows, Linux, and macOS targets.
|
||||
- The `server` platform is back as it was in Godot 2.1.
|
||||
- It is now again possible to run a headless Godot instance on Linux.
|
||||
- Support for BPTC texture compression on desktop platforms.
|
||||
- New properties for SpatialMaterial.
|
||||
- Dithering-based distance fade, for fading materials without making them transparent.
|
||||
- Disable ambient light on a per-material basis.
|
||||
- Option to link Mono statically on Windows.
|
||||
- Unified class and reference search in the editor.
|
||||
- Revamped TileSet editor with support for undo/redo operations.
|
||||
- Various quality-of-life improvements to the Polygon2D and TextureRegion editors.
|
||||
- RandomNumberGenerator class that allows for multiple instances at once.
|
||||
- Array methods `min()` and `max()` to return the smallest and largest value respectively.
|
||||
- Dictionary method `get(key[, default])` where `default` is returned if the key does not exist.
|
||||
- Node method `print_tree_pretty()` to print a graphical view of the scene tree.
|
||||
- String methods `trim_prefix()`, `trim_suffix()`, `lstrip()`, `rstrip()`.
|
||||
- OS methods:
|
||||
- `get_system_time_msecs()`: Return the system time with milliseconds.
|
||||
- `get_audio_driver_name()` and `get_audio_driver_count()` to query audio driver information.
|
||||
- `get_video_driver_count()` and `get_video_driver_name()` to query renderer information.
|
||||
- `center_window()`: Center the window on the screen.
|
||||
- `move_window_to_foreground()`: Move the window to the foreground.
|
||||
- StreamPeerTCP method `set_no_delay()` to enable the `TCP_NODELAY` option.
|
||||
- EditorPlugin method `remove_control_from_container()`.
|
||||
- Ability to set Godot windows as "always on top".
|
||||
- Ability to create windows with per-pixel transparency.
|
||||
- New GLSL built-in functions in the shader language:
|
||||
- `radians()`
|
||||
- `degrees()`
|
||||
- `asinh()`
|
||||
- `acosh()`
|
||||
- `atanh()`
|
||||
- `exp2()`
|
||||
- `log2()`
|
||||
- `roundEven()`
|
||||
- New command-line options:
|
||||
- `--build-solutions`: Build C# solutions without starting the editor.
|
||||
- `--print-fps`: Display frames per second to standard output.
|
||||
- `--quit`: Quit the engine after the first main loop iteration.
|
||||
- Debugger button to copy error messages.
|
||||
- Support for `.escn` scenes has been added for use with the new Blender exporter.
|
||||
- It is now possible to scale an OBJ mesh when importing.
|
||||
- `popup_closed` signal for `ColorPickerButton`.
|
||||
- Methods that are deprecated can now print warnings.
|
||||
- Input actions can now provide an analog value.
|
||||
- Input actions can now be mapped to either a specific device or all devices.
|
||||
- DNS resolution for high-level networking.
|
||||
- Servers can now kick/disconnect peers in high-level networking.
|
||||
- Servers can now access IP and port information of peers in high-level networking.
|
||||
- High-level multiplayer API decoupled from SceneTree (see `SceneTree.multiplayer_api`/`SceneTree.custom_multiplayer_api`), can now be extended.
|
||||
- `Input.set_default_cursor_shape()` to change the default shape in the viewport.
|
||||
- Custom cursors can now be as large as 256×256 (needed to be exactly 32×32 before).
|
||||
- Support for radio-looking items with icon in `PopupMenu`s.
|
||||
- Drag and drop to rearrange Editor docks.
|
||||
- TileSet's `TileMode` is now exposed to GDScript.
|
||||
- `OS.get_ticks_usec()` is now exposed to GDScript.
|
||||
- Normals can now be flipped when generated via `SurfaceTool`.
|
||||
- TextureProgress bars can now be bilinear (extending in both directions).
|
||||
- The character used for masking secrets in LineEdit can now be changed.
|
||||
- Improved DynamicFont:
|
||||
- DynamicFonts can now use high-quality outlines generated by FreeType.
|
||||
- DynamicFonts can now have their anti-aliasing disabled.
|
||||
- DynamicFonts can now have their hinting tweaked ("Normal", "Light" or "None").
|
||||
- Colored glyphs such as emoji are now supported.
|
||||
- Universal translation of touch input to mouse input.
|
||||
- AudioStreamPlayer, AudioStreamPlayer2D, and AudioStreamPlayer3D now have a pitch scale property.
|
||||
- Support for MIDI input.
|
||||
- Support for audio capture from microphones.
|
||||
- `GROW_DIRECTION_BOTH` for Controls.
|
||||
- Selected tiles can be moved in the tile map editor.
|
||||
- The editor can now be configured to display the project window on the previous or next monitor (relative to the editor).
|
||||
- If either end is reached, then the project will start on the last or first monitor (respectively).
|
||||
- Signal in VideoPlayer to notify when the video finished playing.
|
||||
- `Image.bumpmap_to_normalmap()` to convert bump maps to normal maps.
|
||||
- `File.get_path()` and `File.get_path_absolute()`.
|
||||
- Unselected tabs in the editor now have a subtle background for easier identification.
|
||||
- The depth fog's end distance is now configurable independently of the far plane distance.
|
||||
- The alpha component of the fog color can now be used to control fog density.
|
||||
- The 3D editor's information panel now displays the camera's coordinates.
|
||||
- New options to hide the origin and viewport in the 2D editor.
|
||||
- Improved 3D editor grid:
|
||||
- The grid size and number of subdivisions can now be configured.
|
||||
- Its primary and secondary colors can now also be changed.
|
||||
- <kbd>Ctrl</kbd> now toggles snapping in the 3D viewport.
|
||||
- Find & replace in files (<kbd>Ctrl + Shift + F</kbd> by default).
|
||||
- Batch node renaming tool (<kbd>Ctrl + F2</kbd> by default).
|
||||
- More editor scaling options to support HiDPI displays.
|
||||
- Type icons can now be enabled in the editor again.
|
||||
- Buttons in the editor to open common directories in the OS file manager:
|
||||
- project data directory,
|
||||
- user data directory,
|
||||
- user settings directory.
|
||||
- Projects can now be sorted by name or modification date in the project manager.
|
||||
- Projects can now be imported from ZIP archives in the project manager.
|
||||
- Improved autocompletion.
|
||||
- Keywords are now present in autocompletion results.
|
||||
- `editor` and `standalone` feature tags to check whether the project is running from an editor or non-editor binary.
|
||||
- `android_add_asset_dir("...")` method to Android module Gradle build configuration.
|
||||
- **iOS:** Support for exporting to the iPhone X.
|
||||
- **iOS:** Readded support for in-app purchases.
|
||||
|
||||
### Changed
|
||||
|
||||
- [Built-in vector types now use copy-on-write mode as originally intended](https://godotengine.org/article/why-we-broke-your-pr), resulting in increased engine performance.
|
||||
- The [mbedtls](https://tls.mbed.org/) library is now used instead of OpenSSL.
|
||||
- [Renamed several core files](https://github.com/godotengine/godot/pull/25821).
|
||||
- Third-party modules may have to be updated to reflect this.
|
||||
- SSL certificates are now bundled in exported projects unless a custom bundle is specified.
|
||||
- Improved buffer writing performance on Windows and Linux.
|
||||
- Removed many debugging prints in the console.
|
||||
- Export templates now display an error dialog if no project was found when starting.
|
||||
- DynamicFont oversampling is now enabled by default.
|
||||
- Nodes' internal logic now consistently use internal physics processing.
|
||||
- Allow attaching and clearing scripts on multiple nodes at once.
|
||||
- Default values are no longer saved in scene and resource files.
|
||||
- The selection rectangle of 2D nodes is now hidden when not pertinent (no more rectangle for collision shapes).
|
||||
- SSE2 is now enabled in libsquish, resulting in improved S3TC encoding performance.
|
||||
- Tangent and binormal coordinates are now more consistent across mesh types (primitive/imported), resulting in more predictable normal map and depth map appearance.
|
||||
- Better defaults for 3D scenes.
|
||||
- The default procedural sky now has a more neutral blue tone.
|
||||
- The default SpatialMaterial now has a roughness value of 1 and metallic value of 0.
|
||||
- The fallback material now uses the same values as the default SpatialMaterial.
|
||||
- Text editor themes are now sorted alphabetically in the selection dropdown.
|
||||
- The 3D manipulator gizmo now has a smoother, more detailed appearance.
|
||||
- The 3D viewport menu button now has a background to make it easier to read.
|
||||
- QuadMeshes are now built using two triangles (6 vertices) instead of one quad (4 vertices).
|
||||
- This was done because quads are deprecated in OpenGL.
|
||||
- Controls inside containers are no longer movable or resizable but can still be selected.
|
||||
- The `is` GDScript keyword can now be used to compare a value against built-in types.
|
||||
- Exported variables with type hints are now always initialized.
|
||||
- For example, `export(int) var a` will be initialized to `0`.
|
||||
- Named enums in GDScript no longer create script constants.
|
||||
- This means `enum Name { VALUE }` must now be accessed with `Name.VALUE` instead of `VALUE`.
|
||||
- Cyclic references to other scripts with `preload()` are no longer allowed.
|
||||
- `load()` should be used in at least one of the scripts instead.
|
||||
- `switch`, `case` and `do` are no longer reserved identifiers in GDScript.
|
||||
- Shadowing variables from parent scopes is no longer allowed in GDScript.
|
||||
- Function parameters' default values can no longer depend on other parameters in GDScript.
|
||||
- Indentation guides are now displayed in a more subtle way in the script editor.
|
||||
- Indentation guides are now displayed when indenting using spaces.
|
||||
- Multi-line strings are now highlighted as strings rather than as comments in the script editor.
|
||||
- This is because GDScript does not officially support multiline comments.
|
||||
- Increased the script editor's line spacing (4 pixels → 6 pixels).
|
||||
- Increased the caret width in the script editor (1 pixel → 2 pixels).
|
||||
- The project manager window is now resized to match the editor scale.
|
||||
- The asset library now makes use of threading, making loading more responsive.
|
||||
- Line spacing in the script editor, underlines and caret widths are now resized to match the editor scale.
|
||||
- Replaced editor icons for checkboxes and radio buttons with simpler designs.
|
||||
- Tweaked the editor's success, error, and warning text colors for better readability and consistency.
|
||||
- **Android:** Custom permissions are now stored in an array and their amount is no longer limited to 20.
|
||||
- Custom permissions will have to be redefined in projects imported from older versions.
|
||||
- **Android:** Provide error details when an in-app purchase fails.
|
||||
- **Linux:** `OS.alert()` now uses Zenity or KDialog if available instead of xmessage.
|
||||
- **Mono:** Display stack traces for inner exceptions.
|
||||
- **Mono:** Bundle `mscorlib.dll` with Godot to improve portability.
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed the RtAudio backend on Windows in favor of WASAPI, which is the default since 3.0.
|
||||
- **macOS:** Support for 32-bit and fat binaries.
|
||||
- Upgrade bundled OpenSSL to 1.0.2o.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [`move_and_slide()` now behaves differently at low velocities](https://github.com/godotengine/godot/issues/21683), which makes it function as originally intended.
|
||||
- AnimatedSprite2D's `animation_finished` signal is now triggered at the end of the animation, instead of as soon as the last frame displays.
|
||||
- Audio buses can now be removed in the editor while they are used by AudioStreamPlayer2D/3D nodes.
|
||||
- Do not show the project manager unless no project was found at all.
|
||||
- The animation editor time offset indicator no longer "walks" when resizing the editor.
|
||||
- Allow creation of a built-in GDScript file even if the filename suggested already exists.
|
||||
- Show tooltips in the editor when physics object picking is disabled.
|
||||
- Button shortcuts can now be triggered by gamepad buttons.
|
||||
- Fix a serialization bug that could cause TSCN files to grow very large.
|
||||
- Gizmos are now properly hidden on scene load if the object they control is hidden.
|
||||
- Camera gizmos in the 3D viewport no longer look twice as wide as they actually are.
|
||||
- Copy/pasting from the editor on X11 will now work more reliably.
|
||||
- `libgcc_s` and `libstdc++` are now linked statically for better Linux binary portability.
|
||||
- The FPS cap set by `force_fps` in the Project Settings is no longer applied to the editor.
|
||||
- Low FPS caps no longer cause the editor to feel sluggish.
|
||||
- hiDPI is now detected and used if needed in the project manager.
|
||||
- The Visual Studio Code external editor option now recognizes more binary names such as `code-oss`, making detection more reliable.
|
||||
- The `-ffast-math` flag is no longer used when compiling Godot, resulting in increased floating-point determinism.
|
||||
- Security issue relating to deserializing Variants.
|
||||
- Several editor crashes.
|
||||
- GLTF import fixes.
|
||||
- Windows: Fix touch/pen input.
|
||||
- Mono: --build-solutions now forces editor mode.
|
||||
- Mono: Several bugfixes.
|
||||
- Headless: Fix scene imports.
|
||||
|
||||
## [3.0.5] - 2018-07-08
|
||||
|
||||
### Added
|
||||
|
||||
- 'android_add_asset_dir('...') method to Android module gradle build config.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Android exporter no longer writes unnecessary permissions to the exported APK.
|
||||
- Segfault when quitting the editor.
|
||||
- Debugger 'focus stealing' now works more reliably.
|
||||
- Subresources are now always saved when saving a scene.
|
||||
- WebAssembly: Supply proper CORS heards.
|
||||
- Mono: Annotated signal loading in exported projects.
|
||||
- Mono: Serveral fixes.
|
||||
|
||||
## [3.0.4] - 2018-06-23
|
||||
|
||||
### Added
|
||||
|
||||
- Fix for Bullet's heightmap collider.
|
||||
- Several documentation fixes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Threading problem causing asset library to crash on low threadcount systems.
|
||||
|
||||
## [3.0.3] - 2018-06-13
|
||||
|
||||
### Added
|
||||
|
||||
- C# projects can now be exported for Windows, Linux, and MacOS targets.
|
||||
- Universal translation of touch to mouse.
|
||||
- Dynamic fonts can now have a hinting mode set.
|
||||
- print_tree_pretty() was added allowing a graphical view of the scene tree.
|
||||
- Restore purchases feature for iOS.
|
||||
- AudioStreamPlayer, AudioStreamPlayer2D, and AudioStreamPlayer3D now have a pitch scale property.
|
||||
- Show origin and Show viewport setting in 2D editor.
|
||||
- You can now set Godot windows as 'always on top'.
|
||||
- --print-fps options to print FPS to stdout.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Mono: Signal parameters no longer crash the engine.
|
||||
- Asset library thread usage, this makes the asset library more responsive.
|
||||
- Several GLTF import fixes.
|
||||
- Several memory leaks.
|
||||
- iPhone X support.
|
||||
- Several fixes to audio drivers (WASAPI and PulseAudio).
|
||||
- Several crashes.
|
||||
- Export PCK/ZIP now works again.
|
||||
|
||||
## [3.0.2] - 2018-03-03
|
||||
|
||||
### Added
|
||||
|
||||
- Mono: We now display stack traces for inner exceptions.
|
||||
- Mono: Bundle mscorlib.dll with Godot to improve portability.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Running a scene from a project with a main scene now works again (regression in 3.0.1).
|
||||
- Correct line spacing in RichTextLabel (regression in 3.0.1).
|
||||
- TextureProgress now correctly displays when progress > 62 (regression in 3.0.1).
|
||||
- The editor no longer complains about using an enum from an autoloaded resource (regression in 3.0.1).
|
||||
- Pressing Escape no longer closes unexpected subwindows (regression in 3.0.1).
|
||||
- Fix spelling of `apply_torque_impulse()` and deprecate the misspelled method.
|
||||
- Escape sequences like `\n` and `\t` are now recognized in CSV translation files.
|
||||
- Gizmos are now properly hidden on scene load if the object they control is hidden.
|
||||
- Remove spurious errors when using a PanoramaSky without textures.
|
||||
- Show tooltips in the editor when physics object picking is disabled.
|
||||
- Fix a serialization bug that could cause tscn files to grow very large.
|
||||
- Do not show the project manager unless no project was found at all.
|
||||
- The animation editor time offset indicator no longer 'walks' when resizing the editor.
|
||||
- Allow creation of an in-tscn file GDScript function even if the filename suggested already exists.
|
||||
- Mono: Godot no longer crashes when opening a project created with an older release.
|
||||
- Mono: Fix builds of tools=no builds.
|
||||
- Mono: Fix transformation regression since 3.0.1
|
||||
- Android: We now require GLESv3 support in the manifest.
|
||||
- Android: Fix intermittent audio driver crash.
|
||||
|
||||
## [3.0.1] - 2018-02-25
|
||||
|
||||
### Added
|
||||
|
||||
- The 'server' platform is back as it was in Godot 2.1.
|
||||
- It is now again possible to run a headless Godot on Linux.
|
||||
- New CLI options
|
||||
- --build-solutions: build C# solutions without starting the editor.
|
||||
- --quit: quit the engine after the first main loop iteration.
|
||||
- It is now possible to scale an .obj mesh when importing.
|
||||
- Type icons can now be enabled in the editor again.
|
||||
- New GLSL built-in functions in the shader language
|
||||
- radians
|
||||
- degrees
|
||||
- asinh
|
||||
- acosh
|
||||
- atanh
|
||||
- exp2
|
||||
- log2
|
||||
- roundEven
|
||||
- New GDScript features
|
||||
- `OS.center_window()`.
|
||||
- `StreamPeerTCP.set_no_delay()`.
|
||||
- `EditorPlugin.remove_control_from_container()`.
|
||||
- A button has been added to the debugger to copy the error messages.
|
||||
- The Ctrl toggles snapping in the 3D viewport.
|
||||
- Support has been added for a new .escn, for use with the new Blender exporter.
|
||||
- CA certificates have been updated to the latest Mozilla bundle.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Copy/pasting from the editor on X11 will now work more reliably.
|
||||
- The lightmap baker will now use all available cores on Windows.
|
||||
- Fixed missing text in some FileDialog buttons.
|
||||
- Fixes to HTTP requests on the HTML5 platform.
|
||||
- Many, many fixes and improvements to C# support (including a [Signal] attribute).
|
||||
- Static linking of `libgcc_s` as well as `libstdc++` for better Linux binary portability.
|
||||
- Fix broken APK expansion on Android.
|
||||
- Several crashes in the editor have been fixed.
|
||||
- Many documentation fixes.
|
||||
- Several hiDPI fixes.
|
||||
|
||||
## Changed
|
||||
|
||||
- Bullet physics now correctly calculates effective gravity on KinematicBodies.
|
||||
- Setting the color `v` member now correctly sets the `s` member.
|
||||
- RichTextLabels now correctly determine the baseline for all fonts.
|
||||
- SpinBoxes now correctly calculate their initial size.
|
||||
- OGG streams now correctly signal the end of playback.
|
||||
- Android exporter no longer writes unnecessary permissions to the exported APK.
|
||||
- Debugger "focus stealing" now works more reliably.
|
||||
- Subresources are now always saved when saving a scene.
|
||||
- Many fixes related to importers (glTF, Collada, audio), physics (Bullet), Mono/C#, GDNative, Android/iOS.
|
||||
- **Mono:** Many fixes and improvements to C# support (including a `[Signal]` attribute).
|
||||
- **WebAssembly:** Supply proper CORS headers.
|
||||
|
||||
### Security
|
||||
|
||||
- Fixed a security issue relating to deserializing Variants.
|
||||
|
||||
## [3.0] - 2018-01-29
|
||||
|
||||
@ -306,7 +193,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
||||
- Setters and getters for node properties.
|
||||
- Underscores in number literals are now allowed for improved readability (for example,`1_000_000`).
|
||||
- Improved performance (+20% to +40%, based on various benchmarks).
|
||||
- [Feature tags](http://docs.godotengine.org/en/latest/getting_started/workflow/export/feature_tags.html) in the Project Settings, for custom per-platform settings.
|
||||
- [Feature tags](http://docs.godotengine.org/en/latest/learning/workflow/export/feature_tags.html) in the Project Settings, for custom per-platform settings.
|
||||
- Full support for the [glTF 2.0](https://www.khronos.org/gltf/) 3D interchange format.
|
||||
- Freelook and fly navigation to the 3D editor.
|
||||
- Built-in editor logging (logging standard output to a file), disabled by default.
|
||||
@ -396,5 +283,4 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
|
||||
- HTML5 export using asm.js.
|
||||
- Only WebAssembly is supported now, since all browsers supporting WebGL 2.0 also support WebAssembly.
|
||||
|
||||
[Unreleased]: https://github.com/godotengine/godot/compare/3.0-stable...HEAD
|
||||
[3.0]: https://github.com/godotengine/godot/compare/2.1-stable...3.0-stable
|
||||
|
||||
57
CODEOWNERS
57
CODEOWNERS
@ -1,57 +0,0 @@
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
# Owners can be @users, @org/teams or emails
|
||||
|
||||
/core/ @reduz
|
||||
|
||||
/doc/ @godotengine/documentation
|
||||
doc_classes/* @godotengine/documentation
|
||||
|
||||
# Rendering
|
||||
/drivers/gl_context/ @reduz
|
||||
/drivers/gles2/ @reduz
|
||||
/drivers/gles3/ @reduz
|
||||
|
||||
# Audio
|
||||
/drivers/alsa/ @marcelofg55
|
||||
/drivers/alsamidi/ @marcelofg55
|
||||
/drivers/coreaudio/ @marcelofg55
|
||||
/drivers/coremidi/ @marcelofg55
|
||||
/drivers/pulseaudio/ @marcelofg55
|
||||
/drivers/wasapi/ @marcelofg55
|
||||
/drivers/winmidi/ @marcelofg55
|
||||
/drivers/xaudio2/ @marcelofg55
|
||||
|
||||
# Porting
|
||||
/drivers/unix/ @reduz @hpvb
|
||||
/drivers/windows/ @reduz @hpvb
|
||||
|
||||
/editor/icons/ @djrm
|
||||
|
||||
/main/ @reduz
|
||||
|
||||
/misc/ @akien-mga
|
||||
|
||||
/modules/bullet/ @AndreaCatania
|
||||
/modules/csg/ @reduz @BastiaanOlij
|
||||
/modules/enet/ @godotengine/network
|
||||
/modules/gdnative/ @karroffel
|
||||
/modules/gdnative/*arvr/ @BastiaanOlij
|
||||
/modules/gdscript/ @reduz @vnen @bojidar-bg
|
||||
/modules/mbedtls/ @godotengine/network
|
||||
/modules/mobile_vr/ @BastiaanOlij
|
||||
/modules/mono/ @neikeq
|
||||
/modules/opensimplex/ @JFonS
|
||||
/modules/regex/ @LeeZH
|
||||
/modules/upnp/ @godotengine/network
|
||||
/modules/websocket/ @godotengine/network
|
||||
|
||||
/platform/javascript/ @eska014
|
||||
/platform/uwp/ @vnen
|
||||
|
||||
/scene/main/ @reduz
|
||||
|
||||
/server/physics*/ @reduz @AndreaCatania
|
||||
/server/visual*/ @reduz @karroffel
|
||||
|
||||
/thirdparty/ @akien-mga
|
||||
@ -59,8 +59,7 @@ by drag and dropping the file in the GitHub edition field.
|
||||
|
||||
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.
|
||||
* 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).
|
||||
@ -71,23 +70,11 @@ 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.
|
||||
|
||||
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](http://docs.godotengine.org/en/latest/community/contributing/index.html)
|
||||
also have important information on the PR workflow and the code style we use.
|
||||
|
||||
#### 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
|
||||
@ -102,9 +89,6 @@ Internet).
|
||||
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](http://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
|
||||
|
||||
The way you format your commit logs is quite important to ensure that the
|
||||
@ -150,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
|
||||
|
||||
1556
COPYRIGHT.txt
1556
COPYRIGHT.txt
File diff suppressed because it is too large
Load Diff
571
DONORS.md
571
DONORS.md
@ -12,516 +12,281 @@ generous deed immortalized in the next stable release of Godot Engine.
|
||||
|
||||
## Platinum sponsors
|
||||
|
||||
Heroic Labs <https://heroiclabs.com>
|
||||
Interblock <http://interblockgaming.com>
|
||||
Enjin Coin <https://enjincoin.io>
|
||||
|
||||
## Gold sponsors
|
||||
|
||||
Gamblify <https://www.gamblify.com>
|
||||
Moonwards <https://www.moonwards.com>
|
||||
GameDev.TV <https://www.gamedev.tv>
|
||||
Skirmish <https://skirmish.io>
|
||||
|
||||
## Mini sponsors
|
||||
|
||||
AD Ford
|
||||
Alan Beauchamp
|
||||
Anand Mallik
|
||||
Andres Hernandez
|
||||
Andrew Dunai
|
||||
Brandon Lamb
|
||||
Christian Baune
|
||||
Christopher Montesano
|
||||
Darkhan Baimyrza
|
||||
Darrin Massena
|
||||
Dov Zimring
|
||||
Edward Flick
|
||||
Gamechuck
|
||||
GameDev.net
|
||||
GameDev.tv
|
||||
Grady
|
||||
Christian Uldall Pedersen
|
||||
Christopher Igoe
|
||||
Christoph Woinke
|
||||
Claudiu Dumitru
|
||||
E Hewert
|
||||
Hein-Pieter van Braam
|
||||
Jacob McKenney
|
||||
Javary Co.
|
||||
Jeffery Chiu
|
||||
Justin Arnold
|
||||
Justo Delgado Baudí
|
||||
Kyle Szklenski
|
||||
Igors Vaitkus
|
||||
Jamal Alyafei
|
||||
Jay Sistar
|
||||
Matthieu Huvé
|
||||
Maxim Karsten
|
||||
Mike King
|
||||
Nathan Warden
|
||||
Neal Gompa (Conan Kudo)
|
||||
Péter Magyar
|
||||
Pascal Julien
|
||||
Ruslan Mustakov
|
||||
Sébastien Manin
|
||||
Slobodan Milnovic
|
||||
Stephan Lanfermann
|
||||
Steve
|
||||
Tristan Pemble
|
||||
Stoney Meyerhoeffer
|
||||
Thomas Mathews
|
||||
VilliHaukka
|
||||
|
||||
## Gold donors
|
||||
|
||||
Andrei
|
||||
Dave
|
||||
David Gehrig
|
||||
David Snopek
|
||||
Ed Morley
|
||||
Florian Krick
|
||||
Florian Rämisch
|
||||
Jakub Grzesik
|
||||
3Dexplorer
|
||||
Alexander Otto
|
||||
Asdf
|
||||
cheese65536
|
||||
K9Kraken
|
||||
Kris Michael
|
||||
Manuele Finocchiaro
|
||||
Nathanael Beisiegel
|
||||
Officine Pixel S.n.c.
|
||||
Retro Village
|
||||
Ronan Zeegers
|
||||
Sofox
|
||||
Taylor Ritenour
|
||||
Zaven Muradyan
|
||||
|
||||
Asher Glick
|
||||
Allen Schade
|
||||
Andreas Schüle
|
||||
Austen McRae
|
||||
Bernhard Werner
|
||||
beVR
|
||||
Carlo Cabanilla
|
||||
Daniel James
|
||||
David Giardi
|
||||
Default Name
|
||||
eggs
|
||||
Felix Bohmann
|
||||
Bernhard Liebl
|
||||
Catalin Moldovan
|
||||
DeepSquid
|
||||
Fidget Sinner
|
||||
Florian Breisch
|
||||
Gamejunkey
|
||||
Javier Roman
|
||||
Jay Horton
|
||||
Jon Woodward
|
||||
Karl Werf
|
||||
Keinan Powers
|
||||
Klavdij Voncina
|
||||
Lex Steers
|
||||
Luke
|
||||
Maciej Pendolski
|
||||
Matthew Hillier
|
||||
Mohamed Ikbel Boulabiar
|
||||
Mored4u
|
||||
Rob Messick
|
||||
Ryan Badour
|
||||
Sandro Jenny
|
||||
Scott Wadden
|
||||
Sergey
|
||||
thechris
|
||||
Tom Langwaldt
|
||||
tukon
|
||||
William Wold
|
||||
Gary Oberbrunner
|
||||
Johannes Wuensch
|
||||
Josep G. Camarasa
|
||||
Joshua Lesperance
|
||||
Kyle Szklenski
|
||||
Libre-Dépanne
|
||||
Matthew Bennett
|
||||
Olafur Gislason
|
||||
Paul LaMotte
|
||||
Ranoller
|
||||
Svenne Krap
|
||||
Timothy Hagberg
|
||||
|
||||
Alex Khayrullin
|
||||
Chris Goddard
|
||||
BanjoNode2D
|
||||
Beliar
|
||||
Chris Serino
|
||||
Christian Padilla
|
||||
Conrad Curry
|
||||
Craig Smith
|
||||
Darrian Little
|
||||
Horváth Péter
|
||||
Ivan Trombley
|
||||
Jakub Dering
|
||||
Joan Fons
|
||||
Joshua Flores
|
||||
Krzysztof Jankowski
|
||||
Lord Bloodhound
|
||||
Pascal Grüter
|
||||
Petr Malac
|
||||
Daniel Egger
|
||||
David Churchill
|
||||
Dean Harmon
|
||||
Dexter Miguel
|
||||
John
|
||||
Justo Delgado Baudí
|
||||
KTL
|
||||
Laurence Bannister
|
||||
paul gruenbacher
|
||||
Rami
|
||||
Reneator
|
||||
Rob
|
||||
Robert Willes
|
||||
Robin Arys
|
||||
Rodrigo Loli
|
||||
Ronnie Ashlock
|
||||
SKison
|
||||
Rufus Xavier Sarsaparilla
|
||||
ScottMakesGames
|
||||
Thomas Bjarnelöf
|
||||
Unseen Domains
|
||||
Valryia
|
||||
Vincent Henderson
|
||||
William Connell
|
||||
Wojciech Chojnacki
|
||||
Xavier PATRICELLI
|
||||
Zaq Poi
|
||||
|
||||
Adam Nakonieczny
|
||||
Adam Neumann
|
||||
Alexander J Maynard
|
||||
Alessandra Pereyra
|
||||
Alexey Dyadchenko
|
||||
Alex Z
|
||||
Andreas Funke
|
||||
André Frélicot
|
||||
aoshiwik
|
||||
Ben Powell
|
||||
Carlos de Sousa Marques
|
||||
Charlie Whitfield
|
||||
Chase Taranto
|
||||
Amanda Haldy
|
||||
Chris Brown
|
||||
Chris Petrich
|
||||
Christian Leth Jeppesen
|
||||
Christoph Schröder
|
||||
Chris Wilson
|
||||
Cody Parker
|
||||
Coldragon
|
||||
Craig Ostrin
|
||||
Corey Auger
|
||||
D
|
||||
Daniel Eichler
|
||||
David White
|
||||
Denis Janßen
|
||||
Easypete
|
||||
E.G.
|
||||
Eric
|
||||
Eric Monson
|
||||
ethan ball
|
||||
Eugenio Hugo Salgüero Jáñez
|
||||
Fain
|
||||
flesk
|
||||
Gary Hulst
|
||||
gavlig
|
||||
floopf
|
||||
G Barnes
|
||||
GGGames.org
|
||||
Green Fox
|
||||
Giovanni Solimeno
|
||||
Guilherme Felipe de C. G. da Silva
|
||||
Halom Vered
|
||||
Hasen Judy
|
||||
Heath Hayes
|
||||
Idzard Kwadijk
|
||||
Isaac Clausman
|
||||
Jared White
|
||||
Jeff Nyte
|
||||
Jeremy Sims
|
||||
Jerry Ling
|
||||
Joe Flood
|
||||
John G Gentzel
|
||||
Jon Hermansen
|
||||
Jose Malheiro
|
||||
Joshua Lesperance
|
||||
Juan Velandia
|
||||
Jay Horton
|
||||
Jeppe Zapp
|
||||
joe513
|
||||
Jordan M Lucas
|
||||
Juraj Móza
|
||||
kinfox
|
||||
Marcelo Dornbusch Lopes
|
||||
Markus Fehr
|
||||
Justin Arnold
|
||||
Leandro Voltolino
|
||||
Lisandro Lorea
|
||||
Markus Wiesner
|
||||
Martin Eigel
|
||||
Matt Eunson
|
||||
Max Bulai
|
||||
MuffinManKen
|
||||
Marvin
|
||||
Mohammad Taleb
|
||||
Neal Barry
|
||||
Nick Nikitin
|
||||
Oliver Dick
|
||||
Patrick Ting
|
||||
Paul Hocker
|
||||
Paul Von Zimmerman
|
||||
Pablo Cholaky
|
||||
Patrick Schnorbus
|
||||
Pete Goodwin
|
||||
pl
|
||||
Ranoller
|
||||
Robert Larnach
|
||||
Rocknight Studios
|
||||
Romildo Franco
|
||||
Samuel Judd
|
||||
Scott Pilet
|
||||
Sean Morgan
|
||||
SleepCircle
|
||||
spilldata
|
||||
Steve Hyatt
|
||||
Phyronnaz
|
||||
Ruben Soares Luis
|
||||
Sindre Sømme
|
||||
Sofox
|
||||
Stoned Xander
|
||||
TheLevelOfDetail .
|
||||
Thomas Krampl
|
||||
Thomas Kurz
|
||||
Tobias Bocanegra
|
||||
Tricky Fat Cat
|
||||
Urho
|
||||
William Foster
|
||||
Zhou Tuizhi
|
||||
Zie Weaver
|
||||
蕭惟允
|
||||
Tim Dalporto
|
||||
Trent McPheron
|
||||
|
||||
## Silver donors
|
||||
|
||||
1D_Inc
|
||||
Abraham Haskins
|
||||
Adam
|
||||
Adam Brunnmeier
|
||||
Adam Carr
|
||||
Adam Long
|
||||
Adam McCurdy
|
||||
Adam N Webber
|
||||
Adam Smeltzer
|
||||
Adam Szymański
|
||||
Adisibio
|
||||
Adrian Demetrescu
|
||||
Agustinus Arya
|
||||
Aidan O'Flannagain
|
||||
Aki Mimoto
|
||||
Alan Mervitz
|
||||
Alan Stice
|
||||
Albin Jonasson Svärdsby
|
||||
Alder Stefano
|
||||
Alessandro Senese
|
||||
Alexander Erlemann
|
||||
alex clavelle
|
||||
Allan Davis
|
||||
Allen Schade
|
||||
Andreas Evers
|
||||
Andreas Krampitz
|
||||
André Simões
|
||||
Andrew Thomas
|
||||
Anthony Staunton
|
||||
AP Condomines
|
||||
Anders Jensen-Urstad
|
||||
Anthony Bongiovanni
|
||||
Arda Erol
|
||||
Armin Preiml
|
||||
Arseniy M
|
||||
Arthur S. Muszynski
|
||||
Asger
|
||||
Artur Barichello
|
||||
Aubrey Falconer
|
||||
Avencherus
|
||||
B A
|
||||
Balázs Batári
|
||||
Bailey
|
||||
Bastian Böhm
|
||||
Benedikt
|
||||
Ben G
|
||||
Ben Phelan
|
||||
Benjamin Beshara
|
||||
Ben Vercammen
|
||||
Bernd Jänichen
|
||||
Black Block
|
||||
Blair Allen
|
||||
Bobby CC Wong
|
||||
brian
|
||||
bugcaptor
|
||||
Burney Waring
|
||||
Cameron Meyer
|
||||
Carl van der Geest
|
||||
Brandon
|
||||
Bryan Stevenson
|
||||
Carl Winder
|
||||
Carwyn Edwards
|
||||
Cassidy James
|
||||
Chris Brown
|
||||
Casey Foote
|
||||
Chris Chapin
|
||||
Christian Baune
|
||||
Christian Winter
|
||||
Christoffer Sundbom
|
||||
Christoph Brodmann
|
||||
Christopher Schmitt
|
||||
Christoph Woinke
|
||||
Clay Heaton
|
||||
Curt King
|
||||
Dancin Liao
|
||||
Collin Shooltz
|
||||
Daniel Johnson
|
||||
Daniel Kimblad
|
||||
Daniel Pontillo
|
||||
Daniel Kaplan
|
||||
DanielMaximiano
|
||||
Daniel Mircea
|
||||
David
|
||||
David Cravens
|
||||
David May
|
||||
David Woodard
|
||||
DiCola Jamn
|
||||
Dominic Cooney
|
||||
Dominik Wetzel
|
||||
Donn Eddy
|
||||
Donovan Hutcheon
|
||||
Dragontrapper
|
||||
Dr Ewan Murray
|
||||
Duobix
|
||||
Duodecimal
|
||||
Dylan Todd
|
||||
Eduardo Teixeira
|
||||
Duy Kevin Nguyen
|
||||
Edward Herbert
|
||||
Edward Moulsdale
|
||||
Edward Swartz
|
||||
Egon Elbre
|
||||
Elias Nykrem
|
||||
Elmeri '- Duy Kevin Nguyen
|
||||
Ephemeral
|
||||
Eric Ellingson
|
||||
Eric Rogers
|
||||
Eric Williams
|
||||
Erkki Seppälä
|
||||
Evan Rose
|
||||
Fancy Ants Studios
|
||||
Fekinox
|
||||
Felix Kollmann
|
||||
Flaredown
|
||||
Forty Doubleu
|
||||
FuDiggity
|
||||
Gadzhi Kharkharov
|
||||
gamedev by Celio
|
||||
Gary Thomas
|
||||
George Marques
|
||||
GiulianoB
|
||||
Gordian Arragon
|
||||
Greg Olson
|
||||
GREGORY C FEIN
|
||||
Greg P
|
||||
Greyson Richey
|
||||
Grid
|
||||
Edwin Acosta
|
||||
Eric Martini
|
||||
Fabian Becker
|
||||
fengjiongmax
|
||||
Francesco Lisi
|
||||
G3Dev sàrl
|
||||
Gerrit Großkopf
|
||||
Gerrit Procee
|
||||
Gilberto K. Otubo
|
||||
Guillaume Laforte
|
||||
Guldoman
|
||||
Hal A
|
||||
Gumichan01
|
||||
Heribert Hirth
|
||||
Hudson Thorpe-Doubble
|
||||
Hunter Jones
|
||||
Hylpher
|
||||
Ichiro Dohi
|
||||
Iiari
|
||||
iKlem
|
||||
IndustrialRobot
|
||||
Jaiden Gerig
|
||||
ialex32x
|
||||
Ivan Vodopiviz
|
||||
Jahn Johansen
|
||||
Jaime Ruiz-Borau Vizárraga
|
||||
Jako Danar
|
||||
James A F Manley
|
||||
Janders
|
||||
Jannik Gröger
|
||||
JARKKO PARVIAINEN
|
||||
Jarrod Davis
|
||||
Jed
|
||||
Jeff Hungerford
|
||||
Jennifer Graves
|
||||
Jeremy Kahn
|
||||
Jesse Dubay
|
||||
Joel Fivat
|
||||
Joel Höglund
|
||||
Joel Setterberg
|
||||
Johannes Wuensch
|
||||
John Gabriel
|
||||
Jomei Jackson
|
||||
Johan Lindberg
|
||||
Jonas Rudlang
|
||||
Jonas Yamazaki
|
||||
Jonathan G
|
||||
Jonathan Martin
|
||||
Jonathan Nieto
|
||||
Jonathon
|
||||
Jon Bonazza
|
||||
Jon Sully
|
||||
Jorge Caballero
|
||||
Jose Aleman
|
||||
Jose C. Rubio
|
||||
Joseph Catrambone
|
||||
Juanfran
|
||||
Josh 'Cheeseness' Bush
|
||||
Juan Negrier
|
||||
Judd
|
||||
Julian Murgia
|
||||
JungleRobba
|
||||
Justin Spedding
|
||||
KaDokta
|
||||
Kauzig
|
||||
Keedong Park
|
||||
Keith Bradner
|
||||
Kevin McPhillips
|
||||
kickmaniac
|
||||
Kiyohiro Kawamura (kyorohiro)
|
||||
Kjetil Haugland
|
||||
Klagsam
|
||||
KR McGinley
|
||||
KsyTek Games
|
||||
Kuan Cheang
|
||||
kycho
|
||||
Kyle Appelgate
|
||||
Laurent Tréguier
|
||||
Leonardo Dimano
|
||||
Levi Lindsey
|
||||
Justin Luk
|
||||
KC Chan
|
||||
Kevin Boyer
|
||||
Kevin Kamper Meejach Petersen
|
||||
Klavdij Voncina
|
||||
Krzysztof Jankowski
|
||||
Linus Lind Lundgren
|
||||
Lionel Gaillard
|
||||
Luigi Renna
|
||||
LunaticInAHat
|
||||
Lurkars
|
||||
Major Haul
|
||||
Malcolm
|
||||
Malik Ahmed
|
||||
Malik Nejer
|
||||
Markus Michael Egger
|
||||
Martin Holas
|
||||
Martin Liška
|
||||
Marvin
|
||||
Mathieu Rimelen
|
||||
Matt Edwards
|
||||
Matthew Little
|
||||
Matti Pohjanvirta
|
||||
Maxime Blade
|
||||
Luis Moraes
|
||||
Macil
|
||||
magodev
|
||||
Martin Eigel
|
||||
Martins Odabi
|
||||
Max R.R. Collada
|
||||
Maxwell
|
||||
medecau
|
||||
Megasploot
|
||||
Melissa Mears
|
||||
mewin
|
||||
Mertcan Mermerkaya
|
||||
mhilbrunner
|
||||
Michael Haney
|
||||
Michael Dürwald
|
||||
Michael Gringauz
|
||||
Michael Labbe
|
||||
Mikael Olsson
|
||||
Mikayla
|
||||
Mike Birkhead
|
||||
Mike Cunningham
|
||||
Mitchell J. Wagner
|
||||
MoM
|
||||
Nathan Fish
|
||||
Moritz Laass
|
||||
Natrim
|
||||
nee
|
||||
Neil Blakey-Milner
|
||||
Neil Wang
|
||||
Nerdforge
|
||||
Nicholas
|
||||
Nicholas Girga
|
||||
Nick Macholl
|
||||
Nicolás Montaña
|
||||
Nick Pavlica
|
||||
Niclas Eriksen
|
||||
Nicolas SAN AGUSTIN
|
||||
Nima Farid
|
||||
NZ
|
||||
Oleg Reva
|
||||
Olivier
|
||||
Omar Delarosa
|
||||
Oscar Norlander
|
||||
Niko Leopold
|
||||
Noi Sek
|
||||
Oleg Tyshchenko
|
||||
Pablo Seibelt
|
||||
Pan Ip
|
||||
Pat LaBine
|
||||
Patrick Nafarrete
|
||||
Paul Gieske
|
||||
Patric Vormstein
|
||||
Paul Mason
|
||||
Paweł Kowal
|
||||
Pedro Assuncao
|
||||
Penguin
|
||||
Petrus Prinsloo
|
||||
Philip Cohoe
|
||||
Point08
|
||||
Rad Cat
|
||||
Rafa Laguna
|
||||
rainerLinux
|
||||
Raphael Leroux
|
||||
Remi Rampin
|
||||
Pierre-Igor Berthet
|
||||
Pietro Vertechi
|
||||
Piotr Kaczmarski
|
||||
Rémi Verschelde
|
||||
Ricardo Alcantara
|
||||
Richard Diss
|
||||
Richard Ivánek
|
||||
Robert Farr (Larington)
|
||||
Robert Hernandez
|
||||
Roberto Sánchez
|
||||
Richman Stewart
|
||||
Roger Burgess
|
||||
Roger Smith
|
||||
Roland Rząsa
|
||||
Roman Tinkov
|
||||
Ronald Ho Hip (CrimsonZA)
|
||||
Ronan
|
||||
Ryan Groom
|
||||
Ryan Hentz
|
||||
Sam.C
|
||||
Sam Edson
|
||||
Samuele Zolfanelli
|
||||
Ryan Whited
|
||||
Sasori Olkof
|
||||
Scott D. Yelich
|
||||
Scott Longley
|
||||
Sebastian Michailidis
|
||||
Sergio Mello-Grand
|
||||
sgnsajgon
|
||||
Shane
|
||||
Shane Sicienski
|
||||
Shane Spoor
|
||||
Siim Raidma
|
||||
Simon Wenner
|
||||
SK
|
||||
smbe19
|
||||
smo1704
|
||||
Svenne Krap
|
||||
Terry
|
||||
tezuvholovdr
|
||||
thomas
|
||||
Thomas Bechtold
|
||||
Thomas Detoy
|
||||
Thomas Kelly
|
||||
Tim Drumheller
|
||||
Timothy B. MacDonald
|
||||
Tobbun
|
||||
Torgeir Lilleskog
|
||||
Torsten Crass
|
||||
Travis O'Brien
|
||||
Trent Skinner
|
||||
Troy Bonneau
|
||||
Tryggve Sollid
|
||||
Turgut Temucin
|
||||
Tyler Compton
|
||||
Sootstone
|
||||
Stefan Butucea
|
||||
Theo Cranmore
|
||||
Thibault Barbaroux
|
||||
Thomas Bell
|
||||
Thomas Hermansen
|
||||
Thomas Holmes
|
||||
Thomas Kurz
|
||||
Tom Larrow
|
||||
Tyler Stafos
|
||||
UltyX
|
||||
Vaughan Ling
|
||||
Victor
|
||||
Vigilant Watch
|
||||
Vincent Cloutier
|
||||
Victor Gonzalez Fernandez
|
||||
Viktor Ferenczi
|
||||
waka nya
|
||||
Wayne Haak
|
||||
werner mendizabal
|
||||
Wiley Thompson
|
||||
Will
|
||||
William Hogben
|
||||
Wyatt Goodin
|
||||
Yegor
|
||||
Yuri Sizov
|
||||
Wout Standaert
|
||||
Yu He
|
||||
|
||||
## Bronze donors
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.
|
||||
Copyright (c) 2014-2019 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
|
||||
|
||||
@ -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>.
|
||||
|
||||
12
README.md
12
README.md
@ -26,7 +26,7 @@ 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.
|
||||
|
||||

|
||||

|
||||
|
||||
### Getting the engine
|
||||
|
||||
@ -37,10 +37,10 @@ Official binaries for the Godot editor and the export templates can be found
|
||||
|
||||
#### 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).
|
||||
@ -49,14 +49,12 @@ 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
|
||||
|
||||
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/)
|
||||
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)
|
||||
|
||||
286
SConstruct
286
SConstruct
@ -2,15 +2,16 @@
|
||||
|
||||
EnsureSConsVersion(0, 98, 1)
|
||||
|
||||
# System
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Local
|
||||
import string
|
||||
import os
|
||||
import os.path
|
||||
import glob
|
||||
import sys
|
||||
import methods
|
||||
import gles_builders
|
||||
from platform_methods import run_in_subprocess
|
||||
|
||||
# moved below to compensate with module version string
|
||||
# methods.update_version()
|
||||
|
||||
# scan possible build platforms
|
||||
|
||||
@ -22,19 +23,22 @@ active_platforms = []
|
||||
active_platform_ids = []
|
||||
platform_exporters = []
|
||||
platform_apis = []
|
||||
global_defaults = []
|
||||
|
||||
for x in sorted(glob.glob("platform/*")):
|
||||
for x in glob.glob("platform/*"):
|
||||
if (not os.path.isdir(x) or not os.path.exists(x + "/detect.py")):
|
||||
continue
|
||||
tmppath = "./" + x
|
||||
|
||||
sys.path.insert(0, tmppath)
|
||||
sys.path.append(tmppath)
|
||||
import detect
|
||||
|
||||
if (os.path.exists(x + "/export/export.cpp")):
|
||||
platform_exporters.append(x[9:])
|
||||
if (os.path.exists(x + "/api/api.cpp")):
|
||||
platform_apis.append(x[9:])
|
||||
if (os.path.exists(x + "/globals/global_defaults.cpp")):
|
||||
global_defaults.append(x[9:])
|
||||
if (detect.is_active()):
|
||||
active_platforms.append(detect.get_name())
|
||||
active_platform_ids.append(x)
|
||||
@ -49,23 +53,27 @@ for x in sorted(glob.glob("platform/*")):
|
||||
|
||||
module_list = methods.detect_modules()
|
||||
|
||||
|
||||
# print "Detected Platforms: "+str(platform_list)
|
||||
|
||||
methods.save_active_platforms(active_platforms, active_platform_ids)
|
||||
|
||||
custom_tools = ['default']
|
||||
|
||||
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
|
||||
|
||||
if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)):
|
||||
custom_tools = ['mingw']
|
||||
elif platform_arg == 'javascript':
|
||||
# Use generic POSIX build toolchain for Emscripten.
|
||||
custom_tools = ['cc', 'c++', 'ar', 'link', 'textfile', 'zip']
|
||||
if (os.name == "posix"):
|
||||
pass
|
||||
elif (os.name == "nt"):
|
||||
if (os.getenv("VCINSTALLDIR") == None or platform_arg == "android" or platform_arg == "javascript"):
|
||||
custom_tools = ['mingw']
|
||||
|
||||
env_base = Environment(tools=custom_tools)
|
||||
if 'TERM' in os.environ:
|
||||
env_base['ENV']['TERM'] = os.environ['TERM']
|
||||
env_base.AppendENVPath('PATH', os.getenv('PATH'))
|
||||
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
|
||||
env_base.global_defaults = global_defaults
|
||||
env_base.android_maven_repos = []
|
||||
env_base.android_flat_dirs = []
|
||||
env_base.android_dependencies = []
|
||||
@ -82,8 +90,17 @@ env_base.android_permission_chunk = ""
|
||||
env_base.android_appattributes_chunk = ""
|
||||
env_base.disabled_modules = []
|
||||
env_base.use_ptrcall = False
|
||||
env_base.split_drivers = False
|
||||
env_base.split_modules = False
|
||||
env_base.module_version_string = ""
|
||||
env_base.msvc = False
|
||||
|
||||
# To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
|
||||
env_base.Decider('MD5-timestamp')
|
||||
# Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06s04.html
|
||||
env_base.SetOption('implicit_cache', 1)
|
||||
|
||||
|
||||
env_base.__class__.android_add_maven_repository = methods.android_add_maven_repository
|
||||
env_base.__class__.android_add_flat_dir = methods.android_add_flat_dir
|
||||
@ -111,7 +128,6 @@ env_base.__class__.add_shared_library = methods.add_shared_library
|
||||
env_base.__class__.add_library = methods.add_library
|
||||
env_base.__class__.add_program = methods.add_program
|
||||
env_base.__class__.CommandNoCache = methods.CommandNoCache
|
||||
env_base.__class__.disable_warnings = methods.disable_warnings
|
||||
|
||||
env_base["x86_libtheora_opt_gcc"] = False
|
||||
env_base["x86_libtheora_opt_vc"] = False
|
||||
@ -122,6 +138,7 @@ customs = ['custom.py']
|
||||
|
||||
profile = ARGUMENTS.get("profile", False)
|
||||
if profile:
|
||||
import os.path
|
||||
if os.path.isfile(profile):
|
||||
customs.append(profile)
|
||||
elif os.path.isfile(profile + ".py"):
|
||||
@ -130,58 +147,52 @@ if profile:
|
||||
opts = Variables(customs, ARGUMENTS)
|
||||
|
||||
# Target build options
|
||||
opts.Add('arch', "Platform-dependent architecture (arm/arm64/x86/x64/mips/...)", '')
|
||||
opts.Add(EnumVariable('bits', "Target platform bits", 'default', ('default', '32', '64')))
|
||||
opts.Add('arch', "Platform-dependent architecture (arm/arm64/x86/x64/mips/etc)", '')
|
||||
opts.Add(EnumVariable('bits', "Target platform bits", 'default', ('default', '32', '64', 'fat')))
|
||||
opts.Add('p', "Platform (alias for 'platform')", '')
|
||||
opts.Add('platform', "Target platform (%s)" % ('|'.join(platform_list), ), '')
|
||||
opts.Add(EnumVariable('target', "Compilation target", 'debug', ('debug', 'release_debug', 'release')))
|
||||
opts.Add(EnumVariable('optimize', "Optimization type", 'speed', ('speed', 'size')))
|
||||
opts.Add(BoolVariable('tools', "Build the tools (a.k.a. the Godot editor)", True))
|
||||
opts.Add(BoolVariable('use_lto', 'Use link-time optimization', False))
|
||||
opts.Add(BoolVariable('use_precise_math_checks', 'Math checks use very precise epsilon (useful to debug the engine)', False))
|
||||
opts.Add(BoolVariable('tools', "Build the tools a.k.a. the Godot editor", True))
|
||||
opts.Add(BoolVariable('use_lto', 'Use linking time optimization', False))
|
||||
|
||||
# Components
|
||||
opts.Add(BoolVariable('deprecated', "Enable deprecated features", True))
|
||||
opts.Add(BoolVariable('gdscript', "Enable GDScript support", True))
|
||||
opts.Add(BoolVariable('minizip', "Enable ZIP archive support using minizip", True))
|
||||
opts.Add(BoolVariable('xaudio2', "Enable the XAudio2 audio driver", False))
|
||||
opts.Add(BoolVariable('gdscript', "Build GDSCript support", True))
|
||||
opts.Add(BoolVariable('minizip', "Build minizip archive support", True))
|
||||
opts.Add(BoolVariable('xaudio2', "XAudio2 audio driver", False))
|
||||
opts.Add(BoolVariable('xml', "XML format support for resources", True))
|
||||
|
||||
# Advanced options
|
||||
opts.Add(BoolVariable('verbose', "Enable verbose output for the compilation", False))
|
||||
opts.Add(BoolVariable('progress', "Show a progress indicator during compilation", True))
|
||||
opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during compilation", 'all', ('extra', 'all', 'moderate', 'no')))
|
||||
opts.Add(BoolVariable('werror', "Treat compiler warnings as errors. Depends on the level of warnings set with 'warnings'", False))
|
||||
opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False))
|
||||
opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for smaller executable", False))
|
||||
opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced 3D gui nodes and behaviors", False))
|
||||
opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all generated binary files", '')
|
||||
opts.Add(BoolVariable('vsproj', "Generate a Visual Studio solution", False))
|
||||
opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
|
||||
opts.Add(BoolVariable('split_libmodules', "Split intermediate libmodules.a in smaller chunks to prevent exceeding linker command line size (forced to True when using MinGW)", False))
|
||||
opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for a smaller executable", False))
|
||||
opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced GUI nodes and behaviors", False))
|
||||
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
|
||||
opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
|
||||
opts.Add('unix_global_settings_path', "UNIX-specific path to system-wide settings. Currently only used for templates", '')
|
||||
opts.Add(BoolVariable('verbose', "Enable verbose output for the compilation", False))
|
||||
opts.Add(BoolVariable('vsproj', "Generate Visual Studio Project", False))
|
||||
opts.Add(EnumVariable('warnings', "Set the level of warnings emitted during compilation", 'no', ('extra', 'all', 'moderate', 'no')))
|
||||
opts.Add(BoolVariable('progress', "Show a progress indicator during build", True))
|
||||
opts.Add(BoolVariable('dev', "If yes, alias for verbose=yes warnings=all", False))
|
||||
opts.Add(EnumVariable('macports_clang', "Build using clang from MacPorts", 'no', ('no', '5.0', 'devel')))
|
||||
|
||||
# Thirdparty libraries
|
||||
opts.Add(BoolVariable('builtin_bullet', "Use the built-in Bullet library", True))
|
||||
opts.Add(BoolVariable('builtin_certs', "Bundle default SSL certificates to be used if you don't specify an override in the project settings", True))
|
||||
opts.Add(BoolVariable('builtin_enet', "Use the built-in ENet library", True))
|
||||
opts.Add(BoolVariable('builtin_freetype', "Use the built-in FreeType library", True))
|
||||
opts.Add(BoolVariable('builtin_libogg', "Use the built-in libogg library", True))
|
||||
opts.Add(BoolVariable('builtin_libpng', "Use the built-in libpng library", True))
|
||||
opts.Add(BoolVariable('builtin_libtheora', "Use the built-in libtheora library", True))
|
||||
opts.Add(BoolVariable('builtin_libvorbis', "Use the built-in libvorbis library", True))
|
||||
opts.Add(BoolVariable('builtin_libvpx', "Use the built-in libvpx library", True))
|
||||
opts.Add(BoolVariable('builtin_libwebp', "Use the built-in libwebp library", True))
|
||||
opts.Add(BoolVariable('builtin_libwebsockets', "Use the built-in libwebsockets library", True))
|
||||
opts.Add(BoolVariable('builtin_mbedtls', "Use the built-in mbedTLS library", True))
|
||||
opts.Add(BoolVariable('builtin_miniupnpc', "Use the built-in miniupnpc library", True))
|
||||
opts.Add(BoolVariable('builtin_opus', "Use the built-in Opus library", True))
|
||||
opts.Add(BoolVariable('builtin_pcre2', "Use the built-in PCRE2 library)", True))
|
||||
opts.Add(BoolVariable('builtin_recast', "Use the built-in Recast library", True))
|
||||
opts.Add(BoolVariable('builtin_squish', "Use the built-in squish library", True))
|
||||
opts.Add(BoolVariable('builtin_xatlas', "Use the built-in xatlas library", True))
|
||||
opts.Add(BoolVariable('builtin_zlib', "Use the built-in zlib library", True))
|
||||
opts.Add(BoolVariable('builtin_zstd', "Use the built-in Zstd library", True))
|
||||
opts.Add(BoolVariable('builtin_bullet', "Use the builtin bullet library", True))
|
||||
opts.Add(BoolVariable('builtin_enet', "Use the builtin enet library", True))
|
||||
opts.Add(BoolVariable('builtin_freetype', "Use the builtin freetype library", True))
|
||||
opts.Add(BoolVariable('builtin_libogg', "Use the builtin libogg library", True))
|
||||
opts.Add(BoolVariable('builtin_libpng', "Use the builtin libpng library", True))
|
||||
opts.Add(BoolVariable('builtin_libtheora', "Use the builtin libtheora library", True))
|
||||
opts.Add(BoolVariable('builtin_libvorbis', "Use the builtin libvorbis library", True))
|
||||
opts.Add(BoolVariable('builtin_libvpx', "Use the builtin libvpx library", True))
|
||||
opts.Add(BoolVariable('builtin_libwebp', "Use the builtin libwebp library", True))
|
||||
opts.Add(BoolVariable('builtin_openssl', "Use the builtin openssl library", True))
|
||||
opts.Add(BoolVariable('builtin_opus', "Use the builtin opus library", True))
|
||||
opts.Add(BoolVariable('builtin_pcre2', "Use the builtin pcre2 library)", True))
|
||||
opts.Add(BoolVariable('builtin_recast', "Use the builtin recast library", True))
|
||||
opts.Add(BoolVariable('builtin_squish', "Use the builtin squish library", True))
|
||||
opts.Add(BoolVariable('builtin_thekla_atlas', "Use the builtin thekla_altas library", True))
|
||||
opts.Add(BoolVariable('builtin_zlib', "Use the builtin zlib library", True))
|
||||
opts.Add(BoolVariable('builtin_zstd', "Use the builtin zstd library", True))
|
||||
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
|
||||
|
||||
# Compilation environment setup
|
||||
opts.Add("CXX", "C++ compiler")
|
||||
@ -192,6 +203,7 @@ opts.Add("CXXFLAGS", "Custom flags for the C++ compiler")
|
||||
opts.Add("CFLAGS", "Custom flags for the C compiler")
|
||||
opts.Add("LINKFLAGS", "Custom flags for the linker")
|
||||
|
||||
|
||||
# add platform specific options
|
||||
|
||||
for k in platform_opts.keys():
|
||||
@ -202,7 +214,7 @@ for k in platform_opts.keys():
|
||||
for x in module_list:
|
||||
module_enabled = True
|
||||
tmppath = "./modules/" + x
|
||||
sys.path.insert(0, tmppath)
|
||||
sys.path.append(tmppath)
|
||||
import config
|
||||
enabled_attr = getattr(config, "is_enabled", None)
|
||||
if (callable(enabled_attr) and not config.is_enabled()):
|
||||
@ -216,36 +228,33 @@ Help(opts.GenerateHelpText(env_base)) # generate help
|
||||
|
||||
# add default include paths
|
||||
|
||||
env_base.Append(CPPPATH=['#editor', '#'])
|
||||
env_base.Append(CPPPATH=['#core', '#core/math', '#editor', '#drivers', '#'])
|
||||
|
||||
# configure ENV for platform
|
||||
env_base.platform_exporters = platform_exporters
|
||||
env_base.platform_apis = platform_apis
|
||||
|
||||
if (env_base["use_precise_math_checks"]):
|
||||
env_base.Append(CPPDEFINES=['PRECISE_MATH_CHECKS'])
|
||||
"""
|
||||
sys.path.append("./platform/"+env_base["platform"])
|
||||
import detect
|
||||
detect.configure(env_base)
|
||||
sys.path.remove("./platform/"+env_base["platform"])
|
||||
sys.modules.pop('detect')
|
||||
"""
|
||||
|
||||
if (env_base['target'] == 'debug'):
|
||||
env_base.Append(CPPDEFINES=['DEBUG_MEMORY_ALLOC','DISABLE_FORCED_INLINE'])
|
||||
|
||||
# The two options below speed up incremental builds, but reduce the certainty that all files
|
||||
# will properly be rebuilt. As such, we only enable them for debug (dev) builds, not release.
|
||||
|
||||
# To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
|
||||
env_base.Decider('MD5-timestamp')
|
||||
# Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
|
||||
# http://scons.org/doc/production/HTML/scons-user/ch06s04.html
|
||||
env_base.SetOption('implicit_cache', 1)
|
||||
env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
|
||||
env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE'])
|
||||
|
||||
if (env_base['no_editor_splash']):
|
||||
env_base.Append(CPPDEFINES=['NO_EDITOR_SPLASH'])
|
||||
env_base.Append(CPPFLAGS=['-DNO_EDITOR_SPLASH'])
|
||||
|
||||
if not env_base['deprecated']:
|
||||
env_base.Append(CPPDEFINES=['DISABLE_DEPRECATED'])
|
||||
env_base.Append(CPPFLAGS=['-DDISABLE_DEPRECATED'])
|
||||
|
||||
env_base.platforms = {}
|
||||
|
||||
|
||||
selected_platform = ""
|
||||
|
||||
if env_base['platform'] != "":
|
||||
@ -254,9 +263,10 @@ elif env_base['p'] != "":
|
||||
selected_platform = env_base['p']
|
||||
env_base["platform"] = selected_platform
|
||||
|
||||
|
||||
if selected_platform in platform_list:
|
||||
tmppath = "./platform/" + selected_platform
|
||||
sys.path.insert(0, tmppath)
|
||||
|
||||
sys.path.append("./platform/" + selected_platform)
|
||||
import detect
|
||||
if "create" in dir(detect):
|
||||
env = detect.create(env_base)
|
||||
@ -319,60 +329,45 @@ if selected_platform in platform_list:
|
||||
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
|
||||
detect.configure(env)
|
||||
|
||||
# Configure compiler warnings
|
||||
if env.msvc:
|
||||
# Truncations, narrowing conversions, signed/unsigned comparisons...
|
||||
disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4018', '/wd4800']
|
||||
if (env["warnings"] == 'yes'):
|
||||
print("WARNING: warnings=yes is deprecated; assuming warnings=all")
|
||||
|
||||
env.msvc = 0
|
||||
if (os.name == "nt" and os.getenv("VCINSTALLDIR") and (platform_arg == "windows" or platform_arg == "uwp")): # MSVC, needs to stand out of course
|
||||
env.msvc = 1
|
||||
disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4800'] # Truncations, narrowing conversions...
|
||||
if (env["warnings"] == 'extra'):
|
||||
env.Append(CCFLAGS=['/Wall']) # Implies /W4
|
||||
elif (env["warnings"] == 'all'):
|
||||
elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
|
||||
env.Append(CCFLAGS=['/W3'] + disable_nonessential_warnings)
|
||||
elif (env["warnings"] == 'moderate'):
|
||||
# C4244 shouldn't be needed here being a level-3 warning, but it is
|
||||
env.Append(CCFLAGS=['/W2'] + disable_nonessential_warnings)
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=['/w'])
|
||||
# Set exception handling model to avoid warnings caused by Windows system headers.
|
||||
env.Append(CCFLAGS=['/EHsc'])
|
||||
if (env["werror"]):
|
||||
env.Append(CCFLAGS=['/WX'])
|
||||
else: # Rest of the world
|
||||
shadow_local_warning = []
|
||||
all_plus_warnings = ['-Wwrite-strings']
|
||||
|
||||
if methods.using_gcc(env):
|
||||
version = methods.get_compiler_version(env)
|
||||
if version != None and version[0] >= '7':
|
||||
shadow_local_warning = ['-Wshadow-local']
|
||||
|
||||
if (env["warnings"] == 'extra'):
|
||||
# FIXME: enable -Wclobbered once #26351 is fixed
|
||||
# Note: enable -Wimplicit-fallthrough for Clang (already part of -Wextra for GCC)
|
||||
# once we switch to C++11 or later (necessary for our FALLTHROUGH macro).
|
||||
env.Append(CCFLAGS=['-Wall', '-Wextra', '-Wno-unused-parameter'] + all_plus_warnings + shadow_local_warning)
|
||||
if methods.using_gcc(env):
|
||||
env['CCFLAGS'] += ['-Wno-clobbered']
|
||||
elif (env["warnings"] == 'all'):
|
||||
env.Append(CCFLAGS=['-Wall'] + shadow_local_warning)
|
||||
env.Append(CCFLAGS=['-Wall', '-Wextra'])
|
||||
elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
|
||||
env.Append(CCFLAGS=['-Wall'])
|
||||
elif (env["warnings"] == 'moderate'):
|
||||
env.Append(CCFLAGS=['-Wall', '-Wno-unused'] + shadow_local_warning)
|
||||
env.Append(CCFLAGS=['-Wall', '-Wno-unused'])
|
||||
else: # 'no'
|
||||
env.Append(CCFLAGS=['-w'])
|
||||
if (env["werror"]):
|
||||
env.Append(CCFLAGS=['-Werror'])
|
||||
else: # always enable those errors
|
||||
env.Append(CCFLAGS=['-Werror=return-type'])
|
||||
env.Append(CCFLAGS=['-Werror=return-type'])
|
||||
|
||||
if (hasattr(detect, 'get_program_suffix')):
|
||||
suffix = "." + detect.get_program_suffix()
|
||||
else:
|
||||
suffix = "." + selected_platform
|
||||
#env['platform_libsuffix'] = env['LIBSUFFIX']
|
||||
|
||||
suffix = "." + selected_platform
|
||||
|
||||
if (env["target"] == "release"):
|
||||
if env["tools"]:
|
||||
print("Tools can only be built with targets 'debug' and 'release_debug'.")
|
||||
sys.exit(255)
|
||||
suffix += ".opt"
|
||||
env.Append(CPPDEFINES=['NDEBUG'])
|
||||
env.Append(CCFLAGS=['-DNDEBUG'])
|
||||
|
||||
elif (env["target"] == "release_debug"):
|
||||
if env["tools"]:
|
||||
@ -391,10 +386,12 @@ if selected_platform in platform_list:
|
||||
suffix += ".32"
|
||||
elif (env["bits"] == "64"):
|
||||
suffix += ".64"
|
||||
elif (env["bits"] == "fat"):
|
||||
suffix += ".fat"
|
||||
|
||||
suffix += env.extra_suffix
|
||||
|
||||
sys.path.remove(tmppath)
|
||||
sys.path.remove("./platform/" + selected_platform)
|
||||
sys.modules.pop('detect')
|
||||
|
||||
env.module_list = []
|
||||
@ -404,20 +401,10 @@ if selected_platform in platform_list:
|
||||
if not env['module_' + x + '_enabled']:
|
||||
continue
|
||||
tmppath = "./modules/" + x
|
||||
sys.path.insert(0, tmppath)
|
||||
sys.path.append(tmppath)
|
||||
env.current_module = x
|
||||
import config
|
||||
# can_build changed number of arguments between 3.0 (1) and 3.1 (2),
|
||||
# so try both to preserve compatibility for 3.0 modules
|
||||
can_build = False
|
||||
try:
|
||||
can_build = config.can_build(env, selected_platform)
|
||||
except TypeError:
|
||||
print("Warning: module '%s' uses a deprecated `can_build` "
|
||||
"signature in its config.py file, it should be "
|
||||
"`can_build(env, platform)`." % x)
|
||||
can_build = config.can_build(selected_platform)
|
||||
if (can_build):
|
||||
if (config.can_build(selected_platform)):
|
||||
config.configure(env)
|
||||
env.module_list.append(x)
|
||||
try:
|
||||
@ -435,46 +422,35 @@ if selected_platform in platform_list:
|
||||
|
||||
env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"]
|
||||
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
|
||||
# (SH)LIBSUFFIX will be used for our own built libraries
|
||||
# LIBSUFFIXES contains LIBSUFFIX and SHLIBSUFFIX by default,
|
||||
# so we need to append the default suffixes to keep the ability
|
||||
# to link against thirdparty libraries (.a, .so, .lib, etc.).
|
||||
if os.name == "nt":
|
||||
# On Windows, only static libraries and import libraries can be
|
||||
# statically linked - both using .lib extension
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"]]
|
||||
else:
|
||||
env["LIBSUFFIXES"] += [env["LIBSUFFIX"], env["SHLIBSUFFIX"]]
|
||||
env["LIBSUFFIX"] = suffix + env["LIBSUFFIX"]
|
||||
env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"]
|
||||
|
||||
if (env.use_ptrcall):
|
||||
env.Append(CPPDEFINES=['PTRCALL_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DPTRCALL_ENABLED'])
|
||||
|
||||
# to test 64 bits compiltion
|
||||
# env.Append(CPPFLAGS=['-m64'])
|
||||
|
||||
if env['tools']:
|
||||
env.Append(CPPDEFINES=['TOOLS_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DTOOLS_ENABLED'])
|
||||
if env['disable_3d']:
|
||||
if env['tools']:
|
||||
print("Build option 'disable_3d=yes' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
|
||||
sys.exit(255)
|
||||
else:
|
||||
env.Append(CPPDEFINES=['_3D_DISABLED'])
|
||||
env.Append(CPPFLAGS=['-D_3D_DISABLED'])
|
||||
if env['gdscript']:
|
||||
env.Append(CPPDEFINES=['GDSCRIPT_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DGDSCRIPT_ENABLED'])
|
||||
if env['disable_advanced_gui']:
|
||||
if env['tools']:
|
||||
print("Build option 'disable_advanced_gui=yes' cannot be used with 'tools=yes' (editor), only with 'tools=no' (export template).")
|
||||
sys.exit(255)
|
||||
else:
|
||||
env.Append(CPPDEFINES=['ADVANCED_GUI_DISABLED'])
|
||||
env.Append(CPPFLAGS=['-DADVANCED_GUI_DISABLED'])
|
||||
|
||||
if env['minizip']:
|
||||
env.Append(CPPDEFINES=['MINIZIP_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DMINIZIP_ENABLED'])
|
||||
|
||||
if env['xml']:
|
||||
env.Append(CPPFLAGS=['-DXML_ENABLED'])
|
||||
|
||||
if not env['verbose']:
|
||||
methods.no_verbose(sys, env)
|
||||
|
||||
if (not env["platform"] == "server"): # FIXME: detect GLES3
|
||||
env.Append(BUILDERS = { 'GLES3_GLSL' : env.Builder(action=run_in_subprocess(gles_builders.build_gles3_headers), suffix='glsl.gen.h', src_suffix='.glsl')})
|
||||
env.Append(BUILDERS = { 'GLES2_GLSL' : env.Builder(action=run_in_subprocess(gles_builders.build_gles2_headers), suffix='glsl.gen.h', src_suffix='.glsl')})
|
||||
env.Append( BUILDERS = { 'GLES3_GLSL' : env.Builder(action = methods.build_gles3_headers, suffix = 'glsl.gen.h',src_suffix = '.glsl') } )
|
||||
|
||||
scons_cache_path = os.environ.get("SCONS_CACHE")
|
||||
if scons_cache_path != None:
|
||||
@ -508,15 +484,19 @@ if selected_platform in platform_list:
|
||||
if ("check_c_headers" in env):
|
||||
for header in env["check_c_headers"]:
|
||||
if (conf.CheckCHeader(header[0])):
|
||||
env.AppendUnique(CPPDEFINES=[header[1]])
|
||||
if (env.msvc):
|
||||
env.Append(CCFLAGS=['/D' + header[1]])
|
||||
else:
|
||||
env.Append(CCFLAGS=['-D' + header[1]])
|
||||
|
||||
else:
|
||||
|
||||
print("No valid target platform selected.")
|
||||
print("The following platforms were detected:")
|
||||
print("The following were detected:")
|
||||
for x in platform_list:
|
||||
print("\t" + x)
|
||||
print("\nPlease run SCons again with the argument: platform=<string>")
|
||||
print("\nPlease run scons again with argument: platform=<string>")
|
||||
|
||||
|
||||
# The following only makes sense when the env is defined, and assumes it is
|
||||
if 'env' in locals():
|
||||
@ -565,7 +545,7 @@ if 'env' in locals():
|
||||
[os.remove(f) for f in files]
|
||||
|
||||
def file_list(self):
|
||||
if self.path is None:
|
||||
if self.path == None:
|
||||
# Nothing to do
|
||||
return []
|
||||
# Gather a list of (filename, (size, atime)) within the
|
||||
@ -590,7 +570,7 @@ if 'env' in locals():
|
||||
if sum > self.limit:
|
||||
mark = i
|
||||
break
|
||||
if mark is None:
|
||||
if mark == None:
|
||||
return []
|
||||
else:
|
||||
return [x[0] for x in file_stat[mark:]]
|
||||
|
||||
@ -16,8 +16,6 @@ if sys.version_info < (3,):
|
||||
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')
|
||||
@ -46,8 +44,6 @@ else:
|
||||
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:
|
||||
|
||||
159
core/SCsub
159
core/SCsub
@ -2,13 +2,27 @@
|
||||
|
||||
Import('env')
|
||||
|
||||
import core_builders
|
||||
import make_binders
|
||||
from platform_methods import run_in_subprocess
|
||||
|
||||
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"
|
||||
@ -33,141 +47,64 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ):
|
||||
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
|
||||
"base64.c",
|
||||
"fastlz.c",
|
||||
"sha256.c",
|
||||
"smaz.c",
|
||||
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",
|
||||
# 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.Append(CPPPATH=[thirdparty_zlib_dir])
|
||||
# Needs to be available in main env too
|
||||
env.Append(CPPPATH=[thirdparty_zlib_dir])
|
||||
|
||||
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",
|
||||
"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.Append(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"])
|
||||
env_thirdparty.Append(CCFLAGS="-DZSTD_STATIC_LINKING_ONLY")
|
||||
env.Append(CPPPATH=thirdparty_zstd_dir)
|
||||
# Also needed in main env includes will trigger warnings
|
||||
env.Append(CCFLAGS="-DZSTD_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'], 'make_binders.py', run_in_subprocess(make_binders.run))
|
||||
import make_binders
|
||||
env.CommandNoCache(['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('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
194
core/allocators.h
Normal 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
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
@ -211,13 +211,13 @@ 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;
|
||||
@ -259,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) {
|
||||
|
||||
@ -355,58 +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;
|
||||
}
|
||||
|
||||
Array::Array(const Array &p_from) {
|
||||
|
||||
_p = NULL;
|
||||
_ref(p_from);
|
||||
}
|
||||
|
||||
Array::Array() {
|
||||
|
||||
_p = memnew(ArrayPrivate);
|
||||
|
||||
13
core/array.h
13
core/array.h
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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;
|
||||
@ -72,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();
|
||||
@ -89,10 +87,7 @@ public:
|
||||
Variant pop_back();
|
||||
Variant pop_front();
|
||||
|
||||
Array duplicate(bool p_deep = false) const;
|
||||
|
||||
Variant min() const;
|
||||
Variant max() const;
|
||||
Array duplicate() const;
|
||||
|
||||
Array(const Array &p_from);
|
||||
Array();
|
||||
|
||||
@ -3,3 +3,5 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,14 +30,14 @@
|
||||
|
||||
#include "core_bind.h"
|
||||
|
||||
#include "core/io/file_access_compressed.h"
|
||||
#include "core/io/file_access_encrypted.h"
|
||||
#include "core/io/json.h"
|
||||
#include "core/io/marshalls.h"
|
||||
#include "core/math/geometry.h"
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/project_settings.h"
|
||||
#include "geometry.h"
|
||||
#include "io/file_access_compressed.h"
|
||||
#include "io/file_access_encrypted.h"
|
||||
#include "io/json.h"
|
||||
#include "io/marshalls.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#include "thirdparty/misc/base64.h"
|
||||
|
||||
@ -112,35 +112,20 @@ PoolStringArray _ResourceLoader::get_dependencies(const String &p_path) {
|
||||
return ret;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
bool _ResourceLoader::has(const String &p_path) {
|
||||
WARN_PRINTS("ResourceLoader.has() is deprecated, please replace it with the equivalent has_cached() or the new exists().");
|
||||
return has_cached(p_path);
|
||||
}
|
||||
#endif // DISABLE_DEPRECATED
|
||||
|
||||
bool _ResourceLoader::has_cached(const String &p_path) {
|
||||
|
||||
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
|
||||
return ResourceCache::has(local_path);
|
||||
}
|
||||
|
||||
bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
|
||||
return ResourceLoader::exists(p_path, p_type_hint);
|
||||
}
|
||||
};
|
||||
|
||||
void _ResourceLoader::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("load_interactive", "path", "type_hint"), &_ResourceLoader::load_interactive, DEFVAL(""));
|
||||
ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "p_no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type);
|
||||
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources);
|
||||
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies);
|
||||
ClassDB::bind_method(D_METHOD("has_cached", "path"), &_ResourceLoader::has_cached);
|
||||
ClassDB::bind_method(D_METHOD("exists", "path", "type_hint"), &_ResourceLoader::exists, DEFVAL(""));
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
ClassDB::bind_method(D_METHOD("has", "path"), &_ResourceLoader::has);
|
||||
#endif // DISABLE_DEPRECATED
|
||||
}
|
||||
|
||||
_ResourceLoader::_ResourceLoader() {
|
||||
@ -180,7 +165,6 @@ void _ResourceSaver::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(FLAG_OMIT_EDITOR_PROPERTIES);
|
||||
BIND_ENUM_CONSTANT(FLAG_SAVE_BIG_ENDIAN);
|
||||
BIND_ENUM_CONSTANT(FLAG_COMPRESS);
|
||||
BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS);
|
||||
}
|
||||
|
||||
_ResourceSaver::_ResourceSaver() {
|
||||
@ -221,38 +205,6 @@ String _OS::get_clipboard() const {
|
||||
return OS::get_singleton()->get_clipboard();
|
||||
}
|
||||
|
||||
int _OS::get_video_driver_count() const {
|
||||
return OS::get_singleton()->get_video_driver_count();
|
||||
}
|
||||
|
||||
String _OS::get_video_driver_name(VideoDriver p_driver) const {
|
||||
return OS::get_singleton()->get_video_driver_name((int)p_driver);
|
||||
}
|
||||
|
||||
_OS::VideoDriver _OS::get_current_video_driver() const {
|
||||
return (VideoDriver)OS::get_singleton()->get_current_video_driver();
|
||||
}
|
||||
|
||||
int _OS::get_audio_driver_count() const {
|
||||
return OS::get_singleton()->get_audio_driver_count();
|
||||
}
|
||||
|
||||
String _OS::get_audio_driver_name(int p_driver) const {
|
||||
return OS::get_singleton()->get_audio_driver_name(p_driver);
|
||||
}
|
||||
|
||||
PoolStringArray _OS::get_connected_midi_inputs() {
|
||||
return OS::get_singleton()->get_connected_midi_inputs();
|
||||
}
|
||||
|
||||
void _OS::open_midi_inputs() {
|
||||
return OS::get_singleton()->open_midi_inputs();
|
||||
}
|
||||
|
||||
void _OS::close_midi_inputs() {
|
||||
return OS::get_singleton()->close_midi_inputs();
|
||||
}
|
||||
|
||||
void _OS::set_video_mode(const Size2 &p_size, bool p_fullscreen, bool p_resizeable, int p_screen) {
|
||||
|
||||
OS::VideoMode vm;
|
||||
@ -368,34 +320,13 @@ void _OS::set_borderless_window(bool p_borderless) {
|
||||
OS::get_singleton()->set_borderless_window(p_borderless);
|
||||
}
|
||||
|
||||
bool _OS::get_window_per_pixel_transparency_enabled() const {
|
||||
return OS::get_singleton()->get_window_per_pixel_transparency_enabled();
|
||||
}
|
||||
|
||||
void _OS::set_window_per_pixel_transparency_enabled(bool p_enabled) {
|
||||
OS::get_singleton()->set_window_per_pixel_transparency_enabled(p_enabled);
|
||||
}
|
||||
|
||||
bool _OS::get_borderless_window() const {
|
||||
return OS::get_singleton()->get_borderless_window();
|
||||
}
|
||||
|
||||
void _OS::set_ime_active(const bool p_active) {
|
||||
|
||||
OS::get_singleton()->set_ime_active(p_active);
|
||||
}
|
||||
|
||||
void _OS::set_ime_position(const Point2 &p_pos) {
|
||||
|
||||
OS::get_singleton()->set_ime_position(p_pos);
|
||||
}
|
||||
|
||||
Point2 _OS::get_ime_selection() const {
|
||||
return OS::get_singleton()->get_ime_selection();
|
||||
}
|
||||
|
||||
String _OS::get_ime_text() const {
|
||||
return OS::get_singleton()->get_ime_text();
|
||||
return OS::get_singleton()->set_ime_position(p_pos);
|
||||
}
|
||||
|
||||
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
|
||||
@ -444,7 +375,7 @@ Error _OS::shell_open(String p_uri) {
|
||||
|
||||
int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output) {
|
||||
|
||||
OS::ProcessID pid = -2;
|
||||
OS::ProcessID pid;
|
||||
List<String> args;
|
||||
for (int i = 0; i < p_arguments.size(); i++)
|
||||
args.push_back(p_arguments[i]);
|
||||
@ -457,7 +388,6 @@ int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p
|
||||
else
|
||||
return pid;
|
||||
}
|
||||
|
||||
Error _OS::kill(int p_pid) {
|
||||
|
||||
return OS::get_singleton()->kill(p_pid);
|
||||
@ -596,17 +526,17 @@ struct Time {
|
||||
};
|
||||
*/
|
||||
|
||||
uint64_t _OS::get_static_memory_usage() const {
|
||||
int _OS::get_static_memory_usage() const {
|
||||
|
||||
return OS::get_singleton()->get_static_memory_usage();
|
||||
}
|
||||
|
||||
uint64_t _OS::get_static_memory_peak_usage() const {
|
||||
int _OS::get_static_memory_peak_usage() const {
|
||||
|
||||
return OS::get_singleton()->get_static_memory_peak_usage();
|
||||
}
|
||||
|
||||
uint64_t _OS::get_dynamic_memory_usage() const {
|
||||
int _OS::get_dynamic_memory_usage() const {
|
||||
|
||||
return OS::get_singleton()->get_dynamic_memory_usage();
|
||||
}
|
||||
@ -679,7 +609,7 @@ Dictionary _OS::get_time(bool utc) const {
|
||||
*
|
||||
* @return epoch calculated
|
||||
*/
|
||||
int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||
uint64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||
|
||||
// Bunch of conversion constants
|
||||
static const unsigned int SECONDS_PER_MINUTE = 60;
|
||||
@ -724,18 +654,13 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||
// Calculate all the seconds from months past in this year
|
||||
uint64_t SECONDS_FROM_MONTHS_PAST_THIS_YEAR = DAYS_PAST_THIS_YEAR_TABLE[LEAPYEAR(year)][month - 1] * SECONDS_PER_DAY;
|
||||
|
||||
int64_t SECONDS_FROM_YEARS_PAST = 0;
|
||||
if (year >= EPOCH_YR) {
|
||||
for (unsigned int iyear = EPOCH_YR; iyear < year; iyear++) {
|
||||
SECONDS_FROM_YEARS_PAST += YEARSIZE(iyear) * SECONDS_PER_DAY;
|
||||
}
|
||||
} else {
|
||||
for (unsigned int iyear = EPOCH_YR - 1; iyear >= year; iyear--) {
|
||||
SECONDS_FROM_YEARS_PAST -= YEARSIZE(iyear) * SECONDS_PER_DAY;
|
||||
}
|
||||
uint64_t SECONDS_FROM_YEARS_PAST = 0;
|
||||
for (unsigned int iyear = EPOCH_YR; iyear < year; iyear++) {
|
||||
|
||||
SECONDS_FROM_YEARS_PAST += YEARSIZE(iyear) * SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
int64_t epoch =
|
||||
uint64_t epoch =
|
||||
second +
|
||||
minute * SECONDS_PER_MINUTE +
|
||||
hour * SECONDS_PER_HOUR +
|
||||
@ -758,41 +683,39 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
|
||||
*
|
||||
* @return dictionary of date and time values
|
||||
*/
|
||||
Dictionary _OS::get_datetime_from_unix_time(int64_t unix_time_val) const {
|
||||
Dictionary _OS::get_datetime_from_unix_time(uint64_t unix_time_val) const {
|
||||
|
||||
// Just fail if unix time is negative (when interpreted as an int).
|
||||
// This means the user passed in a negative value by accident
|
||||
ERR_EXPLAIN("unix_time_val was really huge!" + itos(unix_time_val) + " You probably passed in a negative value!");
|
||||
ERR_FAIL_COND_V((int64_t)unix_time_val < 0, Dictionary());
|
||||
|
||||
OS::Date date;
|
||||
OS::Time time;
|
||||
|
||||
long dayclock, dayno;
|
||||
unsigned long dayclock, dayno;
|
||||
int year = EPOCH_YR;
|
||||
|
||||
if (unix_time_val >= 0) {
|
||||
dayno = unix_time_val / SECS_DAY;
|
||||
dayclock = unix_time_val % SECS_DAY;
|
||||
/* day 0 was a thursday */
|
||||
date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7);
|
||||
while (dayno >= YEARSIZE(year)) {
|
||||
dayno -= YEARSIZE(year);
|
||||
year++;
|
||||
}
|
||||
} else {
|
||||
dayno = (unix_time_val - SECS_DAY + 1) / SECS_DAY;
|
||||
dayclock = unix_time_val - dayno * SECS_DAY;
|
||||
date.weekday = static_cast<OS::Weekday>((dayno - 3) % 7 + 7);
|
||||
do {
|
||||
year--;
|
||||
dayno += YEARSIZE(year);
|
||||
} while (dayno < 0);
|
||||
}
|
||||
dayclock = (unsigned long)unix_time_val % SECS_DAY;
|
||||
dayno = (unsigned long)unix_time_val / SECS_DAY;
|
||||
|
||||
time.sec = dayclock % 60;
|
||||
time.min = (dayclock % 3600) / 60;
|
||||
time.hour = dayclock / 3600;
|
||||
|
||||
/* day 0 was a thursday */
|
||||
date.weekday = static_cast<OS::Weekday>((dayno + 4) % 7);
|
||||
|
||||
while (dayno >= YEARSIZE(year)) {
|
||||
dayno -= YEARSIZE(year);
|
||||
year++;
|
||||
}
|
||||
|
||||
date.year = year;
|
||||
|
||||
size_t imonth = 0;
|
||||
|
||||
while ((unsigned long)dayno >= MONTH_DAYS_TABLE[LEAPYEAR(year)][imonth]) {
|
||||
while (dayno >= MONTH_DAYS_TABLE[LEAPYEAR(year)][imonth]) {
|
||||
dayno -= MONTH_DAYS_TABLE[LEAPYEAR(year)][imonth];
|
||||
imonth++;
|
||||
}
|
||||
@ -831,10 +754,6 @@ uint64_t _OS::get_system_time_secs() const {
|
||||
return OS::get_singleton()->get_system_time_secs();
|
||||
}
|
||||
|
||||
uint64_t _OS::get_system_time_msecs() const {
|
||||
return OS::get_singleton()->get_system_time_msecs();
|
||||
}
|
||||
|
||||
void _OS::delay_usec(uint32_t p_usec) const {
|
||||
|
||||
OS::get_singleton()->delay_usec(p_usec);
|
||||
@ -850,11 +769,6 @@ uint32_t _OS::get_ticks_msec() const {
|
||||
return OS::get_singleton()->get_ticks_msec();
|
||||
}
|
||||
|
||||
uint64_t _OS::get_ticks_usec() const {
|
||||
|
||||
return OS::get_singleton()->get_ticks_usec();
|
||||
}
|
||||
|
||||
uint32_t _OS::get_splash_tick_msec() const {
|
||||
|
||||
return OS::get_singleton()->get_splash_tick_msec();
|
||||
@ -1036,11 +950,6 @@ void _OS::center_window() {
|
||||
OS::get_singleton()->center_window();
|
||||
}
|
||||
|
||||
void _OS::move_window_to_foreground() {
|
||||
|
||||
OS::get_singleton()->move_window_to_foreground();
|
||||
}
|
||||
|
||||
bool _OS::is_debug_build() const {
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
@ -1093,11 +1002,6 @@ void _OS::alert(const String &p_alert, const String &p_title) {
|
||||
OS::get_singleton()->alert(p_alert, p_title);
|
||||
}
|
||||
|
||||
bool _OS::request_permission(const String &p_name) {
|
||||
|
||||
return OS::get_singleton()->request_permission(p_name);
|
||||
}
|
||||
|
||||
_OS *_OS::singleton = NULL;
|
||||
|
||||
void _OS::_bind_methods() {
|
||||
@ -1115,16 +1019,6 @@ void _OS::_bind_methods() {
|
||||
//ClassDB::bind_method(D_METHOD("is_video_mode_resizable","screen"),&_OS::is_video_mode_resizable,DEFVAL(0));
|
||||
//ClassDB::bind_method(D_METHOD("get_fullscreen_mode_list","screen"),&_OS::get_fullscreen_mode_list,DEFVAL(0));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_video_driver_count"), &_OS::get_video_driver_count);
|
||||
ClassDB::bind_method(D_METHOD("get_video_driver_name", "driver"), &_OS::get_video_driver_name);
|
||||
ClassDB::bind_method(D_METHOD("get_current_video_driver"), &_OS::get_current_video_driver);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_audio_driver_count"), &_OS::get_audio_driver_count);
|
||||
ClassDB::bind_method(D_METHOD("get_audio_driver_name", "driver"), &_OS::get_audio_driver_name);
|
||||
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
|
||||
ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs);
|
||||
ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_screen_count"), &_OS::get_screen_count);
|
||||
ClassDB::bind_method(D_METHOD("get_current_screen"), &_OS::get_current_screen);
|
||||
ClassDB::bind_method(D_METHOD("set_current_screen", "screen"), &_OS::set_current_screen);
|
||||
@ -1149,18 +1043,11 @@ void _OS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("request_attention"), &_OS::request_attention);
|
||||
ClassDB::bind_method(D_METHOD("get_real_window_size"), &_OS::get_real_window_size);
|
||||
ClassDB::bind_method(D_METHOD("center_window"), &_OS::center_window);
|
||||
ClassDB::bind_method(D_METHOD("move_window_to_foreground"), &_OS::move_window_to_foreground);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_borderless_window", "borderless"), &_OS::set_borderless_window);
|
||||
ClassDB::bind_method(D_METHOD("get_borderless_window"), &_OS::get_borderless_window);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_window_per_pixel_transparency_enabled"), &_OS::get_window_per_pixel_transparency_enabled);
|
||||
ClassDB::bind_method(D_METHOD("set_window_per_pixel_transparency_enabled", "enabled"), &_OS::set_window_per_pixel_transparency_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_ime_active", "active"), &_OS::set_ime_active);
|
||||
ClassDB::bind_method(D_METHOD("set_ime_position", "position"), &_OS::set_ime_position);
|
||||
ClassDB::bind_method(D_METHOD("get_ime_selection"), &_OS::get_ime_selection);
|
||||
ClassDB::bind_method(D_METHOD("get_ime_text"), &_OS::get_ime_text);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_screen_orientation", "orientation"), &_OS::set_screen_orientation);
|
||||
ClassDB::bind_method(D_METHOD("get_screen_orientation"), &_OS::get_screen_orientation);
|
||||
@ -1197,7 +1084,6 @@ void _OS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_datetime_from_unix_time", "unix_time_val"), &_OS::get_datetime_from_unix_time);
|
||||
ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime", "datetime"), &_OS::get_unix_time_from_datetime);
|
||||
ClassDB::bind_method(D_METHOD("get_system_time_secs"), &_OS::get_system_time_secs);
|
||||
ClassDB::bind_method(D_METHOD("get_system_time_msecs"), &_OS::get_system_time_msecs);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_icon", "icon"), &_OS::set_icon);
|
||||
|
||||
@ -1207,7 +1093,6 @@ void _OS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("delay_usec", "usec"), &_OS::delay_usec);
|
||||
ClassDB::bind_method(D_METHOD("delay_msec", "msec"), &_OS::delay_msec);
|
||||
ClassDB::bind_method(D_METHOD("get_ticks_msec"), &_OS::get_ticks_msec);
|
||||
ClassDB::bind_method(D_METHOD("get_ticks_usec"), &_OS::get_ticks_usec);
|
||||
ClassDB::bind_method(D_METHOD("get_splash_tick_msec"), &_OS::get_splash_tick_msec);
|
||||
ClassDB::bind_method(D_METHOD("get_locale"), &_OS::get_locale);
|
||||
ClassDB::bind_method(D_METHOD("get_latin_keyboard_variant"), &_OS::get_latin_keyboard_variant);
|
||||
@ -1270,8 +1155,6 @@ void _OS::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_power_seconds_left"), &_OS::get_power_seconds_left);
|
||||
ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "clipboard"), "set_clipboard", "get_clipboard");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
|
||||
@ -1281,7 +1164,6 @@ void _OS::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait,Reverse Landscape,Reverse Portrait,Sensor Landscape,Sensor Portrait,Sensor"), "set_screen_orientation", "get_screen_orientation");
|
||||
ADD_GROUP("Window", "window_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_borderless"), "set_borderless_window", "get_borderless_window");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_per_pixel_transparency_enabled"), "set_window_per_pixel_transparency_enabled", "get_window_per_pixel_transparency_enabled");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_fullscreen"), "set_window_fullscreen", "is_window_fullscreen");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_maximized"), "set_window_maximized", "is_window_maximized");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "window_minimized"), "set_window_minimized", "is_window_minimized");
|
||||
@ -1289,9 +1171,6 @@ void _OS::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_position"), "set_window_position", "get_window_position");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "window_size"), "set_window_size", "get_window_size");
|
||||
|
||||
BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES2);
|
||||
BIND_ENUM_CONSTANT(VIDEO_DRIVER_GLES3);
|
||||
|
||||
BIND_ENUM_CONSTANT(DAY_SUNDAY);
|
||||
BIND_ENUM_CONSTANT(DAY_MONDAY);
|
||||
BIND_ENUM_CONSTANT(DAY_TUESDAY);
|
||||
@ -1381,16 +1260,6 @@ Variant _Geometry::segment_intersects_segment_2d(const Vector2 &p_from_a, const
|
||||
};
|
||||
};
|
||||
|
||||
Variant _Geometry::line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b) {
|
||||
|
||||
Vector2 result;
|
||||
if (Geometry::line_intersects_line_2d(p_from_a, p_dir_a, p_from_b, p_dir_b, result)) {
|
||||
return result;
|
||||
} else {
|
||||
return Variant();
|
||||
}
|
||||
}
|
||||
|
||||
PoolVector<Vector2> _Geometry::get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) {
|
||||
|
||||
Vector2 r1, r2;
|
||||
@ -1546,7 +1415,6 @@ void _Geometry::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &_Geometry::build_capsule_planes, DEFVAL(Vector3::AXIS_Z));
|
||||
ClassDB::bind_method(D_METHOD("segment_intersects_circle", "segment_from", "segment_to", "circle_position", "circle_radius"), &_Geometry::segment_intersects_circle);
|
||||
ClassDB::bind_method(D_METHOD("segment_intersects_segment_2d", "from_a", "to_a", "from_b", "to_b"), &_Geometry::segment_intersects_segment_2d);
|
||||
ClassDB::bind_method(D_METHOD("line_intersects_line_2d", "from_a", "dir_a", "from_b", "dir_b"), &_Geometry::line_intersects_line_2d);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_closest_points_between_segments_2d", "p1", "q1", "p2", "q2"), &_Geometry::get_closest_points_between_segments_2d);
|
||||
ClassDB::bind_method(D_METHOD("get_closest_points_between_segments", "p1", "p2", "q1", "q2"), &_Geometry::get_closest_points_between_segments);
|
||||
@ -1786,9 +1654,9 @@ String _File::get_line() const {
|
||||
return f->get_line();
|
||||
}
|
||||
|
||||
Vector<String> _File::get_csv_line(const String &p_delim) const {
|
||||
Vector<String> _File::get_csv_line(String delim) const {
|
||||
ERR_FAIL_COND_V(!f, Vector<String>());
|
||||
return f->get_csv_line(p_delim);
|
||||
return f->get_csv_line(delim);
|
||||
}
|
||||
|
||||
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
|
||||
@ -1885,11 +1753,6 @@ void _File::store_line(const String &p_string) {
|
||||
f->store_line(p_string);
|
||||
}
|
||||
|
||||
void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim) {
|
||||
ERR_FAIL_COND(!f);
|
||||
f->store_csv_line(p_values, p_delim);
|
||||
}
|
||||
|
||||
void _File::store_buffer(const PoolVector<uint8_t> &p_buffer) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
@ -1908,18 +1771,18 @@ bool _File::file_exists(const String &p_name) const {
|
||||
return FileAccess::exists(p_name);
|
||||
}
|
||||
|
||||
void _File::store_var(const Variant &p_var, bool p_full_objects) {
|
||||
void _File::store_var(const Variant &p_var) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
int len;
|
||||
Error err = encode_variant(p_var, NULL, len, p_full_objects);
|
||||
Error err = encode_variant(p_var, NULL, len);
|
||||
ERR_FAIL_COND(err != OK);
|
||||
|
||||
PoolVector<uint8_t> buff;
|
||||
buff.resize(len);
|
||||
PoolVector<uint8_t>::Write w = buff.write();
|
||||
|
||||
err = encode_variant(p_var, &w[0], len, p_full_objects);
|
||||
err = encode_variant(p_var, &w[0], len);
|
||||
ERR_FAIL_COND(err != OK);
|
||||
w = PoolVector<uint8_t>::Write();
|
||||
|
||||
@ -1927,7 +1790,7 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) {
|
||||
store_buffer(buff);
|
||||
}
|
||||
|
||||
Variant _File::get_var(bool p_allow_objects) const {
|
||||
Variant _File::get_var() const {
|
||||
|
||||
ERR_FAIL_COND_V(!f, Variant());
|
||||
uint32_t len = get_32();
|
||||
@ -1937,7 +1800,7 @@ Variant _File::get_var(bool p_allow_objects) const {
|
||||
PoolVector<uint8_t>::Read r = buff.read();
|
||||
|
||||
Variant v;
|
||||
Error err = decode_variant(v, &r[0], len, NULL, p_allow_objects);
|
||||
Error err = decode_variant(v, &r[0], len);
|
||||
ERR_FAIL_COND_V(err != OK, Variant());
|
||||
|
||||
return v;
|
||||
@ -1973,14 +1836,14 @@ void _File::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real);
|
||||
ClassDB::bind_method(D_METHOD("get_buffer", "len"), &_File::get_buffer);
|
||||
ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line);
|
||||
ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(","));
|
||||
ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text);
|
||||
ClassDB::bind_method(D_METHOD("get_md5", "path"), &_File::get_md5);
|
||||
ClassDB::bind_method(D_METHOD("get_sha256", "path"), &_File::get_sha256);
|
||||
ClassDB::bind_method(D_METHOD("get_endian_swap"), &_File::get_endian_swap);
|
||||
ClassDB::bind_method(D_METHOD("set_endian_swap", "enable"), &_File::set_endian_swap);
|
||||
ClassDB::bind_method(D_METHOD("get_error"), &_File::get_error);
|
||||
ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &_File::get_var, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_var"), &_File::get_var);
|
||||
ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(","));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("store_8", "value"), &_File::store_8);
|
||||
ClassDB::bind_method(D_METHOD("store_16", "value"), &_File::store_16);
|
||||
@ -1991,9 +1854,8 @@ void _File::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("store_real", "value"), &_File::store_real);
|
||||
ClassDB::bind_method(D_METHOD("store_buffer", "buffer"), &_File::store_buffer);
|
||||
ClassDB::bind_method(D_METHOD("store_line", "line"), &_File::store_line);
|
||||
ClassDB::bind_method(D_METHOD("store_csv_line", "values", "delim"), &_File::store_csv_line, DEFVAL(","));
|
||||
ClassDB::bind_method(D_METHOD("store_string", "string"), &_File::store_string);
|
||||
ClassDB::bind_method(D_METHOD("store_var", "value", "full_objects"), &_File::store_var, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("store_var", "value"), &_File::store_var);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("store_pascal_string", "string"), &_File::store_pascal_string);
|
||||
ClassDB::bind_method(D_METHOD("get_pascal_string"), &_File::get_pascal_string);
|
||||
@ -2223,17 +2085,17 @@ _Marshalls *_Marshalls::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) {
|
||||
String _Marshalls::variant_to_base64(const Variant &p_var) {
|
||||
|
||||
int len;
|
||||
Error err = encode_variant(p_var, NULL, len, p_full_objects);
|
||||
Error err = encode_variant(p_var, NULL, len);
|
||||
ERR_FAIL_COND_V(err != OK, "");
|
||||
|
||||
PoolVector<uint8_t> buff;
|
||||
buff.resize(len);
|
||||
PoolVector<uint8_t>::Write w = buff.write();
|
||||
|
||||
err = encode_variant(p_var, &w[0], len, p_full_objects);
|
||||
err = encode_variant(p_var, &w[0], len);
|
||||
ERR_FAIL_COND_V(err != OK, "");
|
||||
|
||||
int b64len = len / 3 * 4 + 4 + 1;
|
||||
@ -2249,7 +2111,7 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects)
|
||||
return ret;
|
||||
};
|
||||
|
||||
Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) {
|
||||
Variant _Marshalls::base64_to_variant(const String &p_str) {
|
||||
|
||||
int strlen = p_str.length();
|
||||
CharString cstr = p_str.ascii();
|
||||
@ -2261,7 +2123,7 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
|
||||
int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen);
|
||||
|
||||
Variant v;
|
||||
Error err = decode_variant(v, &w[0], len, NULL, p_allow_objects);
|
||||
Error err = decode_variant(v, &w[0], len);
|
||||
ERR_FAIL_COND_V(err != OK, Variant());
|
||||
|
||||
return v;
|
||||
@ -2340,8 +2202,8 @@ String _Marshalls::base64_to_utf8(const String &p_str) {
|
||||
|
||||
void _Marshalls::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("variant_to_base64", "variant", "full_objects"), &_Marshalls::variant_to_base64, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str", "allow_objects"), &_Marshalls::base64_to_variant, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("variant_to_base64", "variant"), &_Marshalls::variant_to_base64);
|
||||
ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str"), &_Marshalls::base64_to_variant);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("raw_to_base64", "array"), &_Marshalls::raw_to_base64);
|
||||
ClassDB::bind_method(D_METHOD("base64_to_raw", "base64_str"), &_Marshalls::base64_to_raw);
|
||||
@ -2439,7 +2301,7 @@ void _Thread::_start_func(void *ud) {
|
||||
} break;
|
||||
case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
|
||||
|
||||
reason = "Too Few Arguments";
|
||||
reason = "Too Many Arguments";
|
||||
} break;
|
||||
case Variant::CallError::CALL_ERROR_INVALID_METHOD: {
|
||||
|
||||
@ -2532,7 +2394,7 @@ _Thread::~_Thread() {
|
||||
if (active) {
|
||||
ERR_EXPLAIN("Reference to a Thread object object was lost while the thread is still running...");
|
||||
}
|
||||
ERR_FAIL_COND(active);
|
||||
ERR_FAIL_COND(active == true);
|
||||
}
|
||||
/////////////////////////////////////
|
||||
|
||||
@ -2758,14 +2620,6 @@ int _Engine::get_iterations_per_second() const {
|
||||
return Engine::get_singleton()->get_iterations_per_second();
|
||||
}
|
||||
|
||||
void _Engine::set_physics_jitter_fix(float p_threshold) {
|
||||
Engine::get_singleton()->set_physics_jitter_fix(p_threshold);
|
||||
}
|
||||
|
||||
float _Engine::get_physics_jitter_fix() const {
|
||||
return Engine::get_singleton()->get_physics_jitter_fix();
|
||||
}
|
||||
|
||||
void _Engine::set_target_fps(int p_fps) {
|
||||
Engine::get_singleton()->set_target_fps(p_fps);
|
||||
}
|
||||
@ -2804,26 +2658,6 @@ Dictionary _Engine::get_version_info() const {
|
||||
return Engine::get_singleton()->get_version_info();
|
||||
}
|
||||
|
||||
Dictionary _Engine::get_author_info() const {
|
||||
return Engine::get_singleton()->get_author_info();
|
||||
}
|
||||
|
||||
Array _Engine::get_copyright_info() const {
|
||||
return Engine::get_singleton()->get_copyright_info();
|
||||
}
|
||||
|
||||
Dictionary _Engine::get_donor_info() const {
|
||||
return Engine::get_singleton()->get_donor_info();
|
||||
}
|
||||
|
||||
Dictionary _Engine::get_license_info() const {
|
||||
return Engine::get_singleton()->get_license_info();
|
||||
}
|
||||
|
||||
String _Engine::get_license_text() const {
|
||||
return Engine::get_singleton()->get_license_text();
|
||||
}
|
||||
|
||||
bool _Engine::is_in_physics_frame() const {
|
||||
return Engine::get_singleton()->is_in_physics_frame();
|
||||
}
|
||||
@ -2852,8 +2686,6 @@ void _Engine::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_iterations_per_second", "iterations_per_second"), &_Engine::set_iterations_per_second);
|
||||
ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second);
|
||||
ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_jitter_fix"), &_Engine::get_physics_jitter_fix);
|
||||
ClassDB::bind_method(D_METHOD("set_target_fps", "target_fps"), &_Engine::set_target_fps);
|
||||
ClassDB::bind_method(D_METHOD("get_target_fps"), &_Engine::get_target_fps);
|
||||
|
||||
@ -2866,11 +2698,6 @@ void _Engine::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_main_loop"), &_Engine::get_main_loop);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_version_info"), &_Engine::get_version_info);
|
||||
ClassDB::bind_method(D_METHOD("get_author_info"), &_Engine::get_author_info);
|
||||
ClassDB::bind_method(D_METHOD("get_copyright_info"), &_Engine::get_copyright_info);
|
||||
ClassDB::bind_method(D_METHOD("get_donor_info"), &_Engine::get_donor_info);
|
||||
ClassDB::bind_method(D_METHOD("get_license_info"), &_Engine::get_license_info);
|
||||
ClassDB::bind_method(D_METHOD("get_license_text"), &_Engine::get_license_text);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("is_in_physics_frame"), &_Engine::is_in_physics_frame);
|
||||
|
||||
@ -2884,7 +2711,6 @@ void _Engine::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "iterations_per_second"), "set_iterations_per_second", "get_iterations_per_second");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "target_fps"), "set_target_fps", "get_target_fps");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "time_scale"), "set_time_scale", "get_time_scale");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "physics_jitter_fix"), "set_physics_jitter_fix", "get_physics_jitter_fix");
|
||||
}
|
||||
|
||||
_Engine *_Engine::singleton = NULL;
|
||||
@ -2904,10 +2730,10 @@ void JSONParseResult::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_error_line", "error_line"), &JSONParseResult::set_error_line);
|
||||
ClassDB::bind_method(D_METHOD("set_result", "result"), &JSONParseResult::set_result);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "error", PROPERTY_HINT_NONE, "Error", PROPERTY_USAGE_CLASS_IS_ENUM), "set_error", "get_error");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "error_string"), "set_error_string", "get_error_string");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "error_line"), "set_error_line", "get_error_line");
|
||||
ADD_PROPERTYNZ(PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "set_result", "get_result");
|
||||
}
|
||||
|
||||
void JSONParseResult::set_error(Error p_error) {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,15 +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 "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);
|
||||
@ -55,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();
|
||||
};
|
||||
@ -80,7 +76,6 @@ 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; }
|
||||
@ -103,11 +98,6 @@ 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 */
|
||||
@ -156,17 +146,6 @@ 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);
|
||||
@ -191,18 +170,11 @@ public:
|
||||
virtual bool is_window_always_on_top() const;
|
||||
virtual void request_attention();
|
||||
virtual void center_window();
|
||||
virtual void move_window_to_foreground();
|
||||
|
||||
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();
|
||||
@ -282,21 +254,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(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;
|
||||
@ -356,14 +326,11 @@ public:
|
||||
|
||||
bool has_feature(const String &p_feature) const;
|
||||
|
||||
bool request_permission(const String &p_name);
|
||||
|
||||
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);
|
||||
@ -385,7 +352,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);
|
||||
@ -463,11 +429,10 @@ public:
|
||||
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
|
||||
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;
|
||||
@ -493,14 +458,15 @@ 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();
|
||||
|
||||
Vector<String> get_csv_line(String delim = ",") const;
|
||||
|
||||
void store_buffer(const PoolVector<uint8_t> &p_buffer); ///< store an array of bytes
|
||||
|
||||
void store_var(const Variant &p_var, bool p_full_objects = false);
|
||||
void store_var(const Variant &p_var);
|
||||
|
||||
bool file_exists(const String &p_name) const; ///< return true if a file exists
|
||||
|
||||
@ -569,8 +535,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);
|
||||
@ -697,9 +663,6 @@ 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;
|
||||
|
||||
void set_target_fps(int p_fps);
|
||||
int get_target_fps() const;
|
||||
|
||||
@ -713,11 +676,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;
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,24 +257,17 @@ 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() {
|
||||
}
|
||||
|
||||
@ -518,12 +519,7 @@ Object *ClassDB::instance(const StringName &p_class) {
|
||||
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) {
|
||||
@ -664,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()) {
|
||||
@ -682,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
|
||||
}
|
||||
@ -738,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;
|
||||
@ -806,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) {
|
||||
|
||||
@ -814,10 +812,10 @@ 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) {
|
||||
if (check->signal_map.has(sname)) {
|
||||
ERR_EXPLAIN("Type " + String(p_class) + " already has signal: " + String(sname));
|
||||
@ -897,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) {
|
||||
|
||||
#ifndef NO_THREADS
|
||||
lock->read_lock();
|
||||
#endif
|
||||
|
||||
ClassInfo *type = classes.getptr(p_class);
|
||||
|
||||
#ifndef NO_THREADS
|
||||
lock->read_unlock();
|
||||
#endif
|
||||
|
||||
ERR_FAIL_COND(!type);
|
||||
|
||||
@ -941,8 +945,9 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
|
||||
}
|
||||
|
||||
#ifdef DEBUG_METHODS_ENABLED
|
||||
|
||||
if (type->property_setget.has(p_pinfo.name)) {
|
||||
ERR_EXPLAIN("Object " + p_class + " already has property: " + p_pinfo.name);
|
||||
ERR_EXPLAIN("Object already has property: " + p_class);
|
||||
ERR_FAIL();
|
||||
}
|
||||
#endif
|
||||
@ -1256,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);
|
||||
@ -1371,46 +1376,14 @@ void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<StringName, HashMap<StringName, Variant> > ClassDB::default_values;
|
||||
|
||||
Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property) {
|
||||
|
||||
if (!default_values.has(p_class)) {
|
||||
|
||||
default_values[p_class] = HashMap<StringName, Variant>();
|
||||
|
||||
if (ClassDB::can_instance(p_class)) {
|
||||
|
||||
Object *c = ClassDB::instance(p_class);
|
||||
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)) {
|
||||
|
||||
Variant v = c->get(E->get().name);
|
||||
default_values[p_class][E->get().name] = v;
|
||||
}
|
||||
}
|
||||
memdelete(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (!default_values.has(p_class)) {
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (!default_values[p_class].has(p_property)) {
|
||||
return Variant();
|
||||
}
|
||||
|
||||
return default_values[p_class][p_property];
|
||||
}
|
||||
|
||||
RWLock *ClassDB::lock = NULL;
|
||||
|
||||
void ClassDB::init() {
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
lock = RWLock::create();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ClassDB::cleanup() {
|
||||
@ -1432,9 +1405,11 @@ void ClassDB::cleanup() {
|
||||
classes.clear();
|
||||
resource_base_extensions.clear();
|
||||
compat_classes.clear();
|
||||
default_values.clear();
|
||||
|
||||
#ifndef NO_THREADS
|
||||
|
||||
memdelete(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,18 +31,14 @@
|
||||
#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"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
|
||||
/** To bind more then 6 parameters include this:
|
||||
* #include "core/method_bind_ext.gen.inc"
|
||||
*/
|
||||
|
||||
#define DEFVAL(m_defval) (m_defval)
|
||||
|
||||
//#define SIMPLE_METHODDEF
|
||||
@ -118,19 +114,19 @@ public:
|
||||
|
||||
APIType api;
|
||||
ClassInfo *inherits_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;
|
||||
@ -147,9 +143,9 @@ public:
|
||||
}
|
||||
|
||||
static RWLock *lock;
|
||||
static HashMap<StringName, ClassInfo> classes;
|
||||
static HashMap<StringName, StringName> resource_base_extensions;
|
||||
static HashMap<StringName, StringName> compat_classes;
|
||||
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);
|
||||
@ -161,8 +157,6 @@ public:
|
||||
|
||||
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
|
||||
|
||||
static HashMap<StringName, HashMap<StringName, Variant> > default_values;
|
||||
|
||||
public:
|
||||
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
|
||||
template <class T>
|
||||
@ -350,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);
|
||||
#endif
|
||||
|
||||
static StringName get_category(const StringName &p_node);
|
||||
|
||||
@ -371,7 +365,6 @@ public:
|
||||
static void init();
|
||||
|
||||
static void set_current_api(APIType p_api);
|
||||
static APIType get_current_api();
|
||||
static void cleanup();
|
||||
};
|
||||
|
||||
|
||||
162
core/color.cpp
162
core/color.cpp
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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;
|
||||
}
|
||||
@ -240,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;
|
||||
@ -436,7 +368,7 @@ Color Color::named(const String &p_name) {
|
||||
|
||||
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;
|
||||
|
||||
@ -468,64 +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 {
|
||||
|
||||
p_h = Math::fmod(p_h * 360.0f, 360.0f);
|
||||
if (p_h < 0.0)
|
||||
p_h += 360.0f;
|
||||
|
||||
const float h_ = p_h / 60.0f;
|
||||
const float c = p_v * p_s;
|
||||
const float x = c * (1.0f - Math::abs(Math::fmod(h_, 2.0f) - 1.0f));
|
||||
float r, g, b;
|
||||
|
||||
switch ((int)h_) {
|
||||
case 0: {
|
||||
r = c;
|
||||
g = x;
|
||||
b = 0;
|
||||
} break;
|
||||
case 1: {
|
||||
r = x;
|
||||
g = c;
|
||||
b = 0;
|
||||
} break;
|
||||
case 2: {
|
||||
r = 0;
|
||||
g = c;
|
||||
b = x;
|
||||
} break;
|
||||
case 3: {
|
||||
r = 0;
|
||||
g = x;
|
||||
b = c;
|
||||
} break;
|
||||
case 4: {
|
||||
r = x;
|
||||
g = 0;
|
||||
b = c;
|
||||
} break;
|
||||
case 5: {
|
||||
r = c;
|
||||
g = 0;
|
||||
b = x;
|
||||
} break;
|
||||
default: {
|
||||
r = 0;
|
||||
g = 0;
|
||||
b = 0;
|
||||
} break;
|
||||
}
|
||||
|
||||
const float m = p_v - c;
|
||||
return Color(m + r, m + g, m + b, p_a);
|
||||
}
|
||||
|
||||
// FIXME: Remove once Godot 3.1 has been released
|
||||
float Color::gray() const {
|
||||
|
||||
ERR_EXPLAIN("Color.gray() is deprecated and will be removed in a future version. Use Color.get_v() for a better grayscale approximation.");
|
||||
WARN_DEPRECATED
|
||||
return (r + g + b) / 3.0;
|
||||
}
|
||||
|
||||
|
||||
14
core/color.h
14
core/color.h
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 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>
|
||||
*/
|
||||
@ -55,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;
|
||||
@ -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_color);
|
||||
|
||||
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
|
||||
operator String() const;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
// 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 "core/map.h"
|
||||
#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));
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "command_queue_mt.h"
|
||||
|
||||
#include "core/os/os.h"
|
||||
#include "os/os.h"
|
||||
|
||||
void CommandQueueMT::lock() {
|
||||
|
||||
@ -97,7 +97,7 @@ tryagain:
|
||||
return false;
|
||||
}
|
||||
|
||||
dealloc_ptr += (size >> 1) + 8;
|
||||
dealloc_ptr += (size >> 1) + sizeof(uint32_t);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -105,9 +105,7 @@ CommandQueueMT::CommandQueueMT(bool p_sync) {
|
||||
|
||||
read_ptr = 0;
|
||||
write_ptr = 0;
|
||||
dealloc_ptr = 0;
|
||||
mutex = Mutex::create();
|
||||
command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
|
||||
|
||||
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
|
||||
|
||||
@ -129,5 +127,4 @@ CommandQueueMT::~CommandQueueMT() {
|
||||
|
||||
memdelete(sync_sems[i].sem);
|
||||
}
|
||||
memfree(command_mem);
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,11 @@
|
||||
#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>
|
||||
*/
|
||||
@ -55,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)
|
||||
@ -102,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)
|
||||
@ -145,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)
|
||||
@ -255,7 +244,6 @@
|
||||
unlock(); \
|
||||
if (sync) sync->post(); \
|
||||
ss->sem->wait(); \
|
||||
ss->in_use = false; \
|
||||
}
|
||||
|
||||
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
|
||||
@ -272,10 +260,9 @@
|
||||
unlock(); \
|
||||
if (sync) sync->post(); \
|
||||
ss->sem->wait(); \
|
||||
ss->in_use = false; \
|
||||
}
|
||||
|
||||
#define MAX_CMD_PARAMS 13
|
||||
#define MAX_CMD_PARAMS 12
|
||||
|
||||
class CommandQueueMT {
|
||||
|
||||
@ -298,19 +285,20 @@ class CommandQueueMT {
|
||||
|
||||
virtual void 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 *******/
|
||||
|
||||
@ -320,10 +308,10 @@ class CommandQueueMT {
|
||||
SYNC_SEMAPHORES = 8
|
||||
};
|
||||
|
||||
uint8_t *command_mem;
|
||||
uint32_t read_ptr;
|
||||
uint32_t write_ptr;
|
||||
uint32_t dealloc_ptr;
|
||||
uint8_t command_mem[COMMAND_MEM_SIZE];
|
||||
uint32_t read_ptr = 0;
|
||||
uint32_t write_ptr = 0;
|
||||
uint32_t dealloc_ptr = 0;
|
||||
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
|
||||
Mutex *mutex;
|
||||
Semaphore *sync;
|
||||
@ -332,7 +320,7 @@ class CommandQueueMT {
|
||||
T *allocate() {
|
||||
|
||||
// alloc size is size+T+safeguard
|
||||
uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
|
||||
uint32_t alloc_size = sizeof(T) + sizeof(uint32_t);
|
||||
|
||||
tryagain:
|
||||
|
||||
@ -362,7 +350,7 @@ 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];
|
||||
@ -374,13 +362,12 @@ class CommandQueueMT {
|
||||
// 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 += sizeof(T);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
@ -418,7 +405,7 @@ class CommandQueueMT {
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
read_ptr += 8;
|
||||
read_ptr += sizeof(uint32_t);
|
||||
|
||||
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]);
|
||||
|
||||
@ -445,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);
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,10 +136,13 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
|
||||
}
|
||||
}
|
||||
|
||||
hfunc_table.write[i] = d;
|
||||
hfunc_table[i] = d;
|
||||
bucket_table_size += 2 + b.size() * 4;
|
||||
}
|
||||
|
||||
print_line("bucket table size: " + itos(bucket_table_size * 4));
|
||||
print_line("hash table size: " + itos(size * 4));
|
||||
|
||||
hash_table.resize(size);
|
||||
bucket_table.resize(bucket_table_size);
|
||||
|
||||
@ -150,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;
|
||||
@ -171,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();
|
||||
|
||||
@ -189,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;
|
||||
@ -235,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
|
||||
}
|
||||
|
||||
@ -254,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();
|
||||
}
|
||||
|
||||
@ -262,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 {
|
||||
@ -271,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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
@ -1,269 +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", "Mini sponsors",
|
||||
"Gold donors", "Silver donors", "Bronze donors"]
|
||||
sections_id = ["DONORS_SPONSOR_PLAT", "DONORS_SPONSOR_GOLD", "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]) + "\", "
|
||||
+ "©RIGHT_INFO_DATA[" + str(part["file_index"]) + "], "
|
||||
+ "©RIGHT_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) + "\", "
|
||||
+ "©RIGHT_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())
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -47,27 +47,28 @@ CoreStringNames::CoreStringNames() :
|
||||
#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");
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
372
core/cowdata.h
372
core/cowdata.h
@ -1,372 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* cowdata.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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/os/memory.h"
|
||||
#include "core/safe_refcount.h"
|
||||
|
||||
template <class T>
|
||||
class Vector;
|
||||
class String;
|
||||
class CharString;
|
||||
template <class T, class V>
|
||||
class VMap;
|
||||
|
||||
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_ uint32_t *_get_refcount() const {
|
||||
|
||||
if (!_ptr)
|
||||
return NULL;
|
||||
|
||||
return reinterpret_cast<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);
|
||||
void _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;
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
if (atomic_decrement(refc) > 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>
|
||||
void CowData<T>::_copy_on_write() {
|
||||
|
||||
if (!_ptr)
|
||||
return;
|
||||
|
||||
uint32_t *refc = _get_refcount();
|
||||
|
||||
if (unlikely(*refc > 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);
|
||||
|
||||
*(mem_new - 2) = 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;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Error CowData<T>::resize(int p_size) {
|
||||
|
||||
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
|
||||
|
||||
if (p_size == size())
|
||||
return OK;
|
||||
|
||||
if (p_size == 0) {
|
||||
// wants to clean up
|
||||
_unref(_ptr);
|
||||
_ptr = NULL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
// possibly changing size, copy on write
|
||||
_copy_on_write();
|
||||
|
||||
size_t alloc_size;
|
||||
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
|
||||
|
||||
if (p_size > size()) {
|
||||
|
||||
if (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
|
||||
*(ptr - 2) = 1; //refcount
|
||||
|
||||
_ptr = (T *)ptr;
|
||||
|
||||
} else {
|
||||
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||
_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 < 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();
|
||||
}
|
||||
}
|
||||
|
||||
void *_ptrnew = (T *)Memory::realloc_static(_ptr, alloc_size, true);
|
||||
ERR_FAIL_COND_V(!_ptrnew, ERR_OUT_OF_MEMORY);
|
||||
|
||||
_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 (atomic_conditional_increment(p_from._get_refcount()) > 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_ */
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,7 +109,12 @@ 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) {
|
||||
|
||||
_p->variant_map.erase(p_key);
|
||||
}
|
||||
|
||||
bool Dictionary::erase_checked(const Variant &p_key) {
|
||||
|
||||
return _p->variant_map.erase(p_key);
|
||||
}
|
||||
@ -154,11 +124,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)
|
||||
@ -251,7 +216,7 @@ const Variant *Dictionary::next(const Variant *p_key) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
Dictionary Dictionary::duplicate() const {
|
||||
|
||||
Dictionary n;
|
||||
|
||||
@ -259,7 +224,7 @@ Dictionary Dictionary::duplicate(bool p_deep) const {
|
||||
get_key_list(&keys);
|
||||
|
||||
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
|
||||
n[E->get()] = p_deep ? operator[](E->get()).duplicate(p_deep) : operator[](E->get());
|
||||
n[E->get()] = operator[](E->get());
|
||||
}
|
||||
|
||||
return n;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,10 @@ 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 erase_checked(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,7 +76,7 @@ public:
|
||||
Array keys() const;
|
||||
Array values() const;
|
||||
|
||||
Dictionary duplicate(bool p_deep = false) const;
|
||||
Dictionary duplicate() const;
|
||||
|
||||
Dictionary(const Dictionary &p_from);
|
||||
Dictionary();
|
||||
|
||||
71
core/dvector.cpp
Normal file
71
core/dvector.cpp
Normal 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
643
core/dvector.h
Normal 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
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,11 +30,8 @@
|
||||
|
||||
#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) {
|
||||
|
||||
@ -45,16 +42,6 @@ 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;
|
||||
}
|
||||
@ -98,7 +85,6 @@ Dictionary Engine::get_version_info() const {
|
||||
#else
|
||||
dict["patch"] = 0;
|
||||
#endif
|
||||
dict["hex"] = VERSION_HEX;
|
||||
dict["status"] = VERSION_STATUS;
|
||||
dict["build"] = VERSION_BUILD;
|
||||
dict["year"] = VERSION_YEAR;
|
||||
@ -115,78 +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_PLAT);
|
||||
donors["gold_sponsors"] = array_from_info(DONORS_SPONSOR_GOLD);
|
||||
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);
|
||||
@ -223,7 +137,6 @@ Engine::Engine() {
|
||||
singleton = this;
|
||||
frames_drawn = 0;
|
||||
ips = 60;
|
||||
physics_jitter_fix = 0.5;
|
||||
_frame_delay = 0;
|
||||
_fps = 1;
|
||||
_target_fps = 0;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
@ -57,7 +57,6 @@ private:
|
||||
float _frame_step;
|
||||
|
||||
int ips;
|
||||
float physics_jitter_fix;
|
||||
float _fps;
|
||||
int _target_fps;
|
||||
float _time_scale;
|
||||
@ -80,9 +79,6 @@ 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 float get_target_fps() const;
|
||||
|
||||
@ -118,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
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "error_macros.h"
|
||||
|
||||
#include "core/io/logger.h"
|
||||
#include "io/logger.h"
|
||||
#include "os/os.h"
|
||||
|
||||
bool _err_error_exists = false;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 ERROR_MACROS_H
|
||||
#define ERROR_MACROS_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
|
||||
@ -154,20 +154,6 @@ extern bool _err_error_exists;
|
||||
_err_error_exists = false; \
|
||||
} while (0); // (*)
|
||||
|
||||
/** An index has failed if 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
|
||||
*/
|
||||
|
||||
#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; \
|
||||
} else \
|
||||
_err_error_exists = false; \
|
||||
} while (0); // (*)
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
@ -310,16 +296,6 @@ extern bool _err_error_exists;
|
||||
_err_error_exists = false; \
|
||||
}
|
||||
|
||||
#define ERR_PRINT_ONCE(m_string) \
|
||||
{ \
|
||||
static bool first_print = true; \
|
||||
if (first_print) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
|
||||
_err_error_exists = false; \
|
||||
first_print = false; \
|
||||
} \
|
||||
}
|
||||
|
||||
/** Print a warning string.
|
||||
*/
|
||||
|
||||
@ -335,24 +311,4 @@ extern bool _err_error_exists;
|
||||
_err_error_exists = false; \
|
||||
}
|
||||
|
||||
#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); \
|
||||
_err_error_exists = false; \
|
||||
first_print = false; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WARN_DEPRECATED \
|
||||
{ \
|
||||
static volatile bool warning_shown = false; \
|
||||
if (!warning_shown) { \
|
||||
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "This method has been deprecated and will be removed in the future", ERR_HANDLER_WARNING); \
|
||||
_err_error_exists = false; \
|
||||
warning_shown = true; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -69,6 +69,7 @@ void FuncRef::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
|
||||
}
|
||||
|
||||
FuncRef::FuncRef() :
|
||||
id(0) {
|
||||
FuncRef::FuncRef() {
|
||||
|
||||
id = 0;
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,8 +385,6 @@ 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_BUTTON_0);
|
||||
@ -459,66 +454,49 @@ void register_global_constants() {
|
||||
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_L2);
|
||||
BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_R2);
|
||||
|
||||
// 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);
|
||||
@ -540,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);
|
||||
@ -555,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);
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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:
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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
|
||||
@ -150,7 +150,7 @@ private:
|
||||
if (new_hash_table_power == -1)
|
||||
return;
|
||||
|
||||
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
|
||||
Element **new_hash_table = memnew_arr(Element *, (1 << new_hash_table_power));
|
||||
if (!new_hash_table) {
|
||||
|
||||
ERR_PRINT("Out of Memory");
|
||||
@ -230,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;
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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
7
core/helper/SCsub
Normal file
@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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; \
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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
core/helper/value_evaluator.h
Normal file
46
core/helper/value_evaluator.h
Normal 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
|
||||
819
core/image.cpp
819
core/image.cpp
File diff suppressed because it is too large
Load Diff
61
core/image.h
61
core/image.h
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,19 +47,18 @@
|
||||
class Image;
|
||||
|
||||
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
|
||||
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
|
||||
|
||||
class Image : public Resource {
|
||||
GDCLASS(Image, Resource);
|
||||
|
||||
public:
|
||||
static SavePNGFunc save_png_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
|
||||
@ -108,26 +107,21 @@ public:
|
||||
INTERPOLATE_NEAREST,
|
||||
INTERPOLATE_BILINEAR,
|
||||
INTERPOLATE_CUBIC,
|
||||
INTERPOLATE_TRILINEAR,
|
||||
/* 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 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);
|
||||
@ -135,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 *);
|
||||
|
||||
@ -182,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
|
||||
@ -223,7 +205,6 @@ public:
|
||||
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
|
||||
*/
|
||||
@ -236,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
|
||||
@ -285,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,
|
||||
@ -295,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);
|
||||
@ -306,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);
|
||||
@ -318,13 +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);
|
||||
|
||||
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
|
||||
Image(const char **p_xpm);
|
||||
@ -345,11 +319,8 @@ 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_dest, 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) {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,37 +30,32 @@
|
||||
|
||||
#include "input_map.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);
|
||||
}
|
||||
|
||||
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
|
||||
void InputMap::add_action(const StringName &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++;
|
||||
}
|
||||
|
||||
@ -99,21 +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 {
|
||||
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;
|
||||
@ -124,18 +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(!input_map.has(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(p_event.is_null());
|
||||
ERR_FAIL_COND(!input_map.has(p_action));
|
||||
if (_find_event(input_map[p_action], p_event))
|
||||
if (_find_event(input_map[p_action].inputs, p_event))
|
||||
return; //already gots
|
||||
|
||||
input_map[p_action].inputs.push_back(p_event);
|
||||
@ -144,25 +130,18 @@ 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(!input_map.has(p_action), false);
|
||||
return (_find_event(input_map[p_action], p_event) != NULL);
|
||||
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(!input_map.has(p_action));
|
||||
|
||||
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action], p_event);
|
||||
List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action].inputs, p_event);
|
||||
if (E)
|
||||
input_map[p_action].inputs.erase(E);
|
||||
}
|
||||
|
||||
void InputMap::action_erase_events(const StringName &p_action) {
|
||||
|
||||
ERR_FAIL_COND(!input_map.has(p_action));
|
||||
|
||||
input_map[p_action].inputs.clear();
|
||||
}
|
||||
|
||||
Array InputMap::_get_action_list(const StringName &p_action) {
|
||||
|
||||
Array ret;
|
||||
@ -187,37 +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);
|
||||
if (!E) {
|
||||
ERR_EXPLAIN("Request for nonexistent InputMap action: " + String(p_action));
|
||||
ERR_FAIL_COND_V(!E, false);
|
||||
}
|
||||
|
||||
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) ? 1.0f : 0.0f;
|
||||
return input_event_action->get_action() == p_action;
|
||||
Ref<InputEventAction> iea = p_event;
|
||||
if (iea.is_valid()) {
|
||||
return iea->get_action() == p_action;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return _find_event(E->get().inputs, p_event, true) != NULL;
|
||||
}
|
||||
|
||||
const Map<StringName, InputMap::Action> &InputMap::get_action_map() const {
|
||||
@ -239,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,16 +282,6 @@ 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");
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,7 +49,7 @@ 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();
|
||||
@ -68,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();
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
|
||||
@ -3,3 +3,6 @@
|
||||
Import('env')
|
||||
|
||||
env.add_source_files(env.core_sources, "*.cpp")
|
||||
|
||||
Export('env')
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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/os/file_access.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 {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,7 +32,7 @@
|
||||
#define CONFIG_FILE_H
|
||||
|
||||
#include "core/ordered_hash_map.h"
|
||||
#include "core/reference.h"
|
||||
#include "reference.h"
|
||||
|
||||
class ConfigFile : public Reference {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,9 @@
|
||||
|
||||
#include "file_access_buffered.h"
|
||||
|
||||
#include "core/error_macros.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "error_macros.h"
|
||||
|
||||
Error FileAccessBuffered::set_error(Error p_error) const {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,10 @@
|
||||
#ifndef FILE_ACCESS_BUFFERED_H
|
||||
#define FILE_ACCESS_BUFFERED_H
|
||||
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/pool_vector.h"
|
||||
#include "core/ustring.h"
|
||||
#include "os/file_access.h"
|
||||
|
||||
#include "dvector.h"
|
||||
#include "ustring.h"
|
||||
|
||||
class FileAccessBuffered : public FileAccess {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -54,7 +54,7 @@ class FileAccessBufferedFA : public FileAccessBuffered {
|
||||
cache.offset = p_offset;
|
||||
cache.buffer.resize(p_size);
|
||||
|
||||
// on PoolVector
|
||||
// on dvector
|
||||
//PoolVector<uint8_t>::Write write = cache.buffer.write();
|
||||
//f.get_buffer(write.ptrw(), p_size);
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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();
|
||||
@ -208,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) {
|
||||
|
||||
@ -294,6 +291,7 @@ uint8_t FileAccessCompressed::get_8() const {
|
||||
} else {
|
||||
read_block--;
|
||||
at_end = true;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -374,23 +372,24 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
FileAccessCompressed::FileAccessCompressed() {
|
||||
|
||||
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() {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "file_access_encrypted.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"
|
||||
@ -43,6 +43,7 @@
|
||||
|
||||
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
|
||||
|
||||
//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);
|
||||
|
||||
@ -88,7 +89,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
|
||||
|
||||
for (size_t i = 0; i < ds; i += 16) {
|
||||
|
||||
aes256_decrypt_ecb(&ctx, &data.write[i]);
|
||||
aes256_decrypt_ecb(&ctx, &data[i]);
|
||||
}
|
||||
|
||||
aes256_done(&ctx);
|
||||
@ -116,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);
|
||||
@ -147,7 +148,7 @@ void FileAccessEncrypted::close() {
|
||||
compressed.resize(len);
|
||||
zeromem(compressed.ptrw(), len);
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
compressed.write[i] = data[i];
|
||||
compressed[i] = data[i];
|
||||
}
|
||||
|
||||
aes256_context ctx;
|
||||
@ -155,7 +156,7 @@ void FileAccessEncrypted::close() {
|
||||
|
||||
for (size_t i = 0; i < len; i += 16) {
|
||||
|
||||
aes256_encrypt_ecb(&ctx, &compressed.write[i]);
|
||||
aes256_encrypt_ecb(&ctx, &compressed[i]);
|
||||
}
|
||||
|
||||
aes256_done(&ctx);
|
||||
@ -262,7 +263,7 @@ 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;
|
||||
}
|
||||
@ -279,7 +280,7 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
|
||||
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);
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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:
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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;
|
||||
|
||||
@ -92,7 +92,7 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
|
||||
Map<String, Vector<uint8_t> >::Element *E = files->find(name);
|
||||
ERR_FAIL_COND_V(!E, ERR_FILE_NOT_FOUND);
|
||||
|
||||
data = E->get().ptrw();
|
||||
data = &(E->get()[0]);
|
||||
length = E->get().size();
|
||||
pos = 0;
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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());
|
||||
@ -94,6 +93,8 @@ void FileAccessNetworkClient::_thread_func() {
|
||||
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");
|
||||
|
||||
@ -227,7 +228,7 @@ FileAccessNetworkClient::FileAccessNetworkClient() {
|
||||
quit = false;
|
||||
singleton = this;
|
||||
last_id = 0;
|
||||
client.instance();
|
||||
client = Ref<StreamPeerTCP>(StreamPeerTCP::create_ref());
|
||||
sem = Semaphore::create();
|
||||
lockcount = 0;
|
||||
}
|
||||
@ -257,8 +258,8 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
|
||||
}
|
||||
|
||||
buffer_mutex->lock();
|
||||
pages.write[page].buffer = p_block;
|
||||
pages.write[page].queued = false;
|
||||
pages[page].buffer = p_block;
|
||||
pages[page].queued = false;
|
||||
buffer_mutex->unlock();
|
||||
|
||||
if (waiting_on_page == page) {
|
||||
@ -388,7 +389,7 @@ void FileAccessNetwork::_queue_page(int p_page) const {
|
||||
br.offset = size_t(p_page) * page_size;
|
||||
br.size = page_size;
|
||||
nc->block_requests.push_back(br);
|
||||
pages.write[p_page].queued = true;
|
||||
pages[p_page].queued = true;
|
||||
nc->blockrequest_mutex->unlock();
|
||||
DEBUG_PRINT("QUEUE PAGE POST");
|
||||
nc->sem->post();
|
||||
@ -432,12 +433,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
_queue_page(page + j);
|
||||
}
|
||||
buff = pages.write[page].buffer.ptrw();
|
||||
buff = pages[page].buffer.ptrw();
|
||||
//queue pages
|
||||
buffer_mutex->unlock();
|
||||
}
|
||||
|
||||
buff = pages.write[page].buffer.ptrw();
|
||||
buff = pages[page].buffer.ptrw();
|
||||
last_page_buff = buff;
|
||||
last_page = page;
|
||||
}
|
||||
@ -500,9 +501,8 @@ uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
|
||||
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() {
|
||||
@ -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;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,6 +47,8 @@ class FileAccessNetworkClient {
|
||||
int size;
|
||||
};
|
||||
|
||||
int ml;
|
||||
|
||||
List<BlockRequest> block_requests;
|
||||
|
||||
Semaphore *sem;
|
||||
@ -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;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,8 +29,7 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "file_access_pack.h"
|
||||
|
||||
#include "core/version.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -90,7 +89,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
|
||||
// Don't add as a file if the path points to a directoryy
|
||||
if (!filename.empty()) {
|
||||
cd->files.insert(filename);
|
||||
}
|
||||
@ -169,11 +168,11 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) {
|
||||
uint32_t version = f->get_32();
|
||||
uint32_t ver_major = f->get_32();
|
||||
uint32_t ver_minor = f->get_32();
|
||||
f->get_32(); // ver_rev
|
||||
uint32_t ver_rev = f->get_32();
|
||||
|
||||
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));
|
||||
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++) {
|
||||
@ -272,7 +271,7 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
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);
|
||||
@ -455,7 +454,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;
|
||||
@ -463,15 +462,11 @@ String DirAccessPack::get_current_dir() {
|
||||
|
||||
bool DirAccessPack::file_exists(String p_file) {
|
||||
|
||||
p_file = fix_path(p_file);
|
||||
|
||||
return current->files.has(p_file);
|
||||
}
|
||||
|
||||
bool DirAccessPack::dir_exists(String p_dir) {
|
||||
|
||||
p_dir = fix_path(p_dir);
|
||||
|
||||
return current->subdirs.has(p_dir);
|
||||
}
|
||||
|
||||
@ -494,10 +489,6 @@ size_t DirAccessPack::get_space_left() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String DirAccessPack::get_filesystem_type() const {
|
||||
return "PCK";
|
||||
}
|
||||
|
||||
DirAccessPack::DirAccessPack() {
|
||||
|
||||
current = PackedData::get_singleton()->root;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,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"
|
||||
#include "list.h"
|
||||
#include "map.h"
|
||||
#include "os/dir_access.h"
|
||||
#include "os/file_access.h"
|
||||
#include "print_string.h"
|
||||
|
||||
class PackSource;
|
||||
|
||||
@ -175,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)
|
||||
@ -221,8 +222,6 @@ public:
|
||||
|
||||
size_t get_space_left();
|
||||
|
||||
virtual String get_filesystem_type() const;
|
||||
|
||||
DirAccessPack();
|
||||
~DirAccessPack();
|
||||
};
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -43,31 +43,31 @@ static void *godot_open(void *data, const char *p_fname, int mode) {
|
||||
|
||||
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
FileAccess *f = (FileAccess *)data;
|
||||
f->open(p_fname, FileAccess::READ);
|
||||
|
||||
return f->is_open() ? data : NULL;
|
||||
}
|
||||
};
|
||||
|
||||
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
|
||||
|
||||
FileAccess *f = (FileAccess *)data;
|
||||
f->get_buffer((uint8_t *)buf, size);
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static long godot_tell(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
return f->get_position();
|
||||
}
|
||||
};
|
||||
|
||||
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
|
||||
|
||||
@ -84,36 +84,36 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
f->seek(pos);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static int godot_close(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
f->close();
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static int godot_testerror(voidpf opaque, voidpf stream) {
|
||||
|
||||
FileAccess *f = (FileAccess *)opaque;
|
||||
return f->get_error() != OK ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
|
||||
|
||||
return memalloc(items * size);
|
||||
}
|
||||
};
|
||||
|
||||
static void godot_free(voidpf opaque, voidpf address) {
|
||||
|
||||
memfree(address);
|
||||
}
|
||||
};
|
||||
|
||||
} // extern "C"
|
||||
}; // extern "C"
|
||||
|
||||
void ZipArchive::close_handle(unzFile p_file) const {
|
||||
|
||||
@ -122,7 +122,7 @@ void ZipArchive::close_handle(unzFile p_file) const {
|
||||
unzCloseCurrentFile(p_file);
|
||||
unzClose(p_file);
|
||||
memdelete(f);
|
||||
}
|
||||
};
|
||||
|
||||
unzFile ZipArchive::get_file_handle(String p_file) const {
|
||||
|
||||
@ -155,10 +155,10 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
|
||||
|
||||
unzClose(pkg);
|
||||
ERR_FAIL_V(NULL);
|
||||
}
|
||||
};
|
||||
|
||||
return pkg;
|
||||
}
|
||||
};
|
||||
|
||||
bool ZipArchive::try_open_pack(const String &p_path) {
|
||||
|
||||
@ -168,10 +168,10 @@ bool ZipArchive::try_open_pack(const String &p_path) {
|
||||
|
||||
zlib_filefunc_def io;
|
||||
|
||||
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!fa)
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f)
|
||||
return false;
|
||||
io.opaque = fa;
|
||||
io.opaque = f;
|
||||
io.zopen_file = godot_open;
|
||||
io.zread_file = godot_read;
|
||||
io.zwrite_file = godot_write;
|
||||
@ -215,36 +215,36 @@ bool ZipArchive::try_open_pack(const String &p_path) {
|
||||
|
||||
if ((i + 1) < gi.number_entry) {
|
||||
unzGoToNextFile(zfile);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
bool ZipArchive::file_exists(String p_name) const {
|
||||
|
||||
return files.has(p_name);
|
||||
}
|
||||
};
|
||||
|
||||
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
|
||||
|
||||
return memnew(FileAccessZip(p_path, *p_file));
|
||||
}
|
||||
};
|
||||
|
||||
ZipArchive *ZipArchive::get_singleton() {
|
||||
|
||||
if (instance == NULL) {
|
||||
instance = memnew(ZipArchive);
|
||||
}
|
||||
};
|
||||
|
||||
return instance;
|
||||
}
|
||||
};
|
||||
|
||||
ZipArchive::ZipArchive() {
|
||||
|
||||
instance = this;
|
||||
//fa_create_func = FileAccess::get_create_func();
|
||||
}
|
||||
};
|
||||
|
||||
ZipArchive::~ZipArchive() {
|
||||
|
||||
@ -253,10 +253,10 @@ ZipArchive::~ZipArchive() {
|
||||
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
|
||||
unzClose(packages[i].zfile);
|
||||
memdelete(f);
|
||||
}
|
||||
};
|
||||
|
||||
packages.clear();
|
||||
}
|
||||
};
|
||||
|
||||
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
|
||||
|
||||
@ -272,7 +272,7 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
|
||||
ERR_FAIL_COND_V(err != UNZ_OK, FAILED);
|
||||
|
||||
return OK;
|
||||
}
|
||||
};
|
||||
|
||||
void FileAccessZip::close() {
|
||||
|
||||
@ -283,50 +283,50 @@ void FileAccessZip::close() {
|
||||
ERR_FAIL_COND(!arch);
|
||||
arch->close_handle(zfile);
|
||||
zfile = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
bool FileAccessZip::is_open() const {
|
||||
|
||||
return zfile != NULL;
|
||||
}
|
||||
};
|
||||
|
||||
void FileAccessZip::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!zfile);
|
||||
unzSeekCurrentFile(zfile, p_position);
|
||||
}
|
||||
};
|
||||
|
||||
void FileAccessZip::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!zfile);
|
||||
unzSeekCurrentFile(zfile, get_len() + p_position);
|
||||
}
|
||||
};
|
||||
|
||||
size_t FileAccessZip::get_position() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, 0);
|
||||
return unztell(zfile);
|
||||
}
|
||||
};
|
||||
|
||||
size_t FileAccessZip::get_len() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, 0);
|
||||
return file_info.uncompressed_size;
|
||||
}
|
||||
};
|
||||
|
||||
bool FileAccessZip::eof_reached() const {
|
||||
|
||||
ERR_FAIL_COND_V(!zfile, true);
|
||||
|
||||
return at_eof;
|
||||
}
|
||||
};
|
||||
|
||||
uint8_t FileAccessZip::get_8() const {
|
||||
|
||||
uint8_t ret = 0;
|
||||
get_buffer(&ret, 1);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
@ -339,20 +339,20 @@ int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
if (read < p_length)
|
||||
at_eof = true;
|
||||
return read;
|
||||
}
|
||||
};
|
||||
|
||||
Error FileAccessZip::get_error() const {
|
||||
|
||||
if (!zfile) {
|
||||
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
};
|
||||
if (eof_reached()) {
|
||||
return ERR_FILE_EOF;
|
||||
}
|
||||
};
|
||||
|
||||
return OK;
|
||||
}
|
||||
};
|
||||
|
||||
void FileAccessZip::flush() {
|
||||
|
||||
@ -362,21 +362,22 @@ void FileAccessZip::flush() {
|
||||
void FileAccessZip::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
};
|
||||
|
||||
bool FileAccessZip::file_exists(const String &p_name) {
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) :
|
||||
zfile(NULL) {
|
||||
FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) {
|
||||
|
||||
zfile = NULL;
|
||||
_open(p_path, FileAccess::READ);
|
||||
}
|
||||
};
|
||||
|
||||
FileAccessZip::~FileAccessZip() {
|
||||
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -34,7 +34,7 @@
|
||||
#define FILE_ACCESS_ZIP_H
|
||||
|
||||
#include "core/io/file_access_pack.h"
|
||||
#include "core/map.h"
|
||||
#include "map.h"
|
||||
|
||||
#include "thirdparty/minizip/unzip.h"
|
||||
|
||||
@ -90,6 +90,8 @@ class FileAccessZip : public FileAccess {
|
||||
|
||||
mutable bool at_eof;
|
||||
|
||||
ZipArchive *archive;
|
||||
|
||||
public:
|
||||
virtual Error _open(const String &p_path, int p_mode_flags); ///< open a file
|
||||
virtual void close(); ///< close a file
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,8 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "http_client.h"
|
||||
|
||||
#include "core/io/stream_peer_ssl.h"
|
||||
#include "core/version.h"
|
||||
#include "io/stream_peer_ssl.h"
|
||||
#include "version.h"
|
||||
|
||||
const char *HTTPClient::_methods[METHOD_MAX] = {
|
||||
"GET",
|
||||
@ -275,13 +274,10 @@ void HTTPClient::close() {
|
||||
|
||||
response_headers.clear();
|
||||
response_str.clear();
|
||||
body_size = -1;
|
||||
body_size = 0;
|
||||
body_left = 0;
|
||||
chunk_left = 0;
|
||||
chunk_trailer_part = 0;
|
||||
read_until_eof = false;
|
||||
response_num = 0;
|
||||
handshaking = false;
|
||||
}
|
||||
|
||||
Error HTTPClient::poll() {
|
||||
@ -330,46 +326,16 @@ Error HTTPClient::poll() {
|
||||
} break;
|
||||
case StreamPeerTCP::STATUS_CONNECTED: {
|
||||
if (ssl) {
|
||||
Ref<StreamPeerSSL> ssl;
|
||||
if (!handshaking) {
|
||||
// Connect the StreamPeerSSL and start handshaking
|
||||
ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
|
||||
ssl->set_blocking_handshake_enabled(false);
|
||||
Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
|
||||
if (err != OK) {
|
||||
close();
|
||||
status = STATUS_SSL_HANDSHAKE_ERROR;
|
||||
return ERR_CANT_CONNECT;
|
||||
}
|
||||
connection = ssl;
|
||||
handshaking = true;
|
||||
} else {
|
||||
// We are already handshaking, which means we can use your already active SSL connection
|
||||
ssl = static_cast<Ref<StreamPeerSSL> >(connection);
|
||||
if (ssl.is_null()) {
|
||||
close();
|
||||
status = STATUS_SSL_HANDSHAKE_ERROR;
|
||||
return ERR_CANT_CONNECT;
|
||||
}
|
||||
|
||||
ssl->poll(); // Try to finish the handshake
|
||||
}
|
||||
|
||||
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
|
||||
// Handshake has been successful
|
||||
handshaking = false;
|
||||
status = STATUS_CONNECTED;
|
||||
return OK;
|
||||
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
|
||||
// Handshake has failed
|
||||
Ref<StreamPeerSSL> ssl = StreamPeerSSL::create();
|
||||
Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
|
||||
if (err != OK) {
|
||||
close();
|
||||
status = STATUS_SSL_HANDSHAKE_ERROR;
|
||||
return ERR_CANT_CONNECT;
|
||||
}
|
||||
// ... we will need to poll more for handshake to finish
|
||||
} else {
|
||||
status = STATUS_CONNECTED;
|
||||
connection = ssl;
|
||||
}
|
||||
status = STATUS_CONNECTED;
|
||||
return OK;
|
||||
} break;
|
||||
case StreamPeerTCP::STATUS_ERROR:
|
||||
@ -381,20 +347,7 @@ Error HTTPClient::poll() {
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case STATUS_BODY:
|
||||
case STATUS_CONNECTED: {
|
||||
// Check if we are still connected
|
||||
if (ssl) {
|
||||
Ref<StreamPeerSSL> tmp = connection;
|
||||
tmp->poll();
|
||||
if (tmp->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
return ERR_CONNECTION_ERROR;
|
||||
}
|
||||
} else if (tcp_connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
return ERR_CONNECTION_ERROR;
|
||||
}
|
||||
// Connection established, requests can now be made
|
||||
return OK;
|
||||
} break;
|
||||
@ -424,21 +377,14 @@ Error HTTPClient::poll() {
|
||||
String response;
|
||||
response.parse_utf8((const char *)response_str.ptr());
|
||||
Vector<String> responses = response.split("\n");
|
||||
body_size = -1;
|
||||
body_size = 0;
|
||||
chunked = false;
|
||||
body_left = 0;
|
||||
chunk_left = 0;
|
||||
chunk_trailer_part = false;
|
||||
read_until_eof = false;
|
||||
response_str.clear();
|
||||
response_headers.clear();
|
||||
response_num = RESPONSE_OK;
|
||||
|
||||
// Per the HTTP 1.1 spec, keep-alive is the default.
|
||||
// Not following that specification breaks standard implemetations.
|
||||
// Broken web servers should be fixed.
|
||||
bool keep_alive = true;
|
||||
|
||||
for (int i = 0; i < responses.size(); i++) {
|
||||
|
||||
String header = responses[i].strip_edges();
|
||||
@ -448,14 +394,13 @@ Error HTTPClient::poll() {
|
||||
if (s.begins_with("content-length:")) {
|
||||
body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int();
|
||||
body_left = body_size;
|
||||
}
|
||||
|
||||
} else if (s.begins_with("transfer-encoding:")) {
|
||||
if (s.begins_with("transfer-encoding:")) {
|
||||
String encoding = header.substr(header.find(":") + 1, header.length()).strip_edges();
|
||||
if (encoding == "chunked") {
|
||||
chunked = true;
|
||||
}
|
||||
} else if (s.begins_with("connection: close")) {
|
||||
keep_alive = false;
|
||||
}
|
||||
|
||||
if (i == 0 && responses[i].begins_with("HTTP")) {
|
||||
@ -468,16 +413,11 @@ Error HTTPClient::poll() {
|
||||
}
|
||||
}
|
||||
|
||||
if (body_size != -1 || chunked) {
|
||||
if (body_size == 0 && !chunked) {
|
||||
|
||||
status = STATUS_BODY;
|
||||
} else if (!keep_alive) {
|
||||
|
||||
read_until_eof = true;
|
||||
status = STATUS_BODY;
|
||||
status = STATUS_CONNECTED; // Ready for new requests
|
||||
} else {
|
||||
|
||||
status = STATUS_CONNECTED;
|
||||
status = STATUS_BODY;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@ -488,8 +428,7 @@ Error HTTPClient::poll() {
|
||||
case STATUS_DISCONNECTED: {
|
||||
return ERR_UNCONFIGURED;
|
||||
} break;
|
||||
case STATUS_CONNECTION_ERROR:
|
||||
case STATUS_SSL_HANDSHAKE_ERROR: {
|
||||
case STATUS_CONNECTION_ERROR: {
|
||||
return ERR_CONNECTION_ERROR;
|
||||
} break;
|
||||
case STATUS_CANT_CONNECT: {
|
||||
@ -512,37 +451,13 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
|
||||
ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray());
|
||||
|
||||
PoolByteArray ret;
|
||||
Error err = OK;
|
||||
|
||||
if (chunked) {
|
||||
|
||||
while (true) {
|
||||
|
||||
if (chunk_trailer_part) {
|
||||
// We need to consume the trailer part too or keep-alive will break
|
||||
uint8_t b;
|
||||
int rec = 0;
|
||||
err = _get_http_data(&b, 1, rec);
|
||||
|
||||
if (rec == 0)
|
||||
break;
|
||||
|
||||
chunk.push_back(b);
|
||||
int cs = chunk.size();
|
||||
if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) {
|
||||
if (cs == 2) {
|
||||
// Finally over
|
||||
chunk_trailer_part = false;
|
||||
status = STATUS_CONNECTED;
|
||||
chunk.clear();
|
||||
break;
|
||||
} else {
|
||||
// We do not process nor return the trailer data
|
||||
chunk.clear();
|
||||
}
|
||||
}
|
||||
} else if (chunk_left == 0) {
|
||||
if (chunk_left == 0) {
|
||||
// Reading length
|
||||
uint8_t b;
|
||||
int rec = 0;
|
||||
@ -556,7 +471,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
if (chunk.size() > 32) {
|
||||
ERR_PRINT("HTTP Invalid chunk hex len");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
break;
|
||||
return PoolByteArray();
|
||||
}
|
||||
|
||||
if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') {
|
||||
@ -574,22 +489,22 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
else {
|
||||
ERR_PRINT("HTTP Chunk len not in hex!!");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
break;
|
||||
return PoolByteArray();
|
||||
}
|
||||
len <<= 4;
|
||||
len |= v;
|
||||
if (len > (1 << 24)) {
|
||||
ERR_PRINT("HTTP Chunk too big!! >16mb");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
break;
|
||||
return PoolByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
// End reached!
|
||||
chunk_trailer_part = true;
|
||||
status = STATUS_CONNECTED;
|
||||
chunk.clear();
|
||||
break;
|
||||
return PoolByteArray();
|
||||
}
|
||||
|
||||
chunk_left = len + 2;
|
||||
@ -598,7 +513,7 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
} else {
|
||||
|
||||
int rec = 0;
|
||||
err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
|
||||
err = _get_http_data(&chunk[chunk.size() - chunk_left], chunk_left, rec);
|
||||
if (rec == 0) {
|
||||
break;
|
||||
}
|
||||
@ -609,13 +524,18 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') {
|
||||
ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)");
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
break;
|
||||
return PoolByteArray();
|
||||
}
|
||||
|
||||
PoolByteArray ret;
|
||||
ret.resize(chunk.size() - 2);
|
||||
PoolByteArray::Write w = ret.write();
|
||||
copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
|
||||
{
|
||||
PoolByteArray::Write w = ret.write();
|
||||
copymem(w.ptr(), chunk.ptr(), chunk.size() - 2);
|
||||
}
|
||||
chunk.clear();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -624,7 +544,8 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
|
||||
} else {
|
||||
|
||||
int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size;
|
||||
int to_read = MIN(body_left, read_chunk_size);
|
||||
PoolByteArray ret;
|
||||
ret.resize(to_read);
|
||||
int _offset = 0;
|
||||
while (to_read > 0) {
|
||||
@ -633,25 +554,24 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
PoolByteArray::Write w = ret.write();
|
||||
err = _get_http_data(w.ptr() + _offset, to_read, rec);
|
||||
}
|
||||
if (rec <= 0) { // Ended up reading less
|
||||
ret.resize(_offset);
|
||||
break;
|
||||
} else {
|
||||
_offset += rec;
|
||||
if (rec > 0) {
|
||||
body_left -= rec;
|
||||
to_read -= rec;
|
||||
if (!read_until_eof) {
|
||||
body_left -= rec;
|
||||
}
|
||||
}
|
||||
if (err != OK)
|
||||
_offset += rec;
|
||||
} else {
|
||||
if (to_read > 0) // Ended up reading less
|
||||
ret.resize(_offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (body_left == 0) {
|
||||
status = STATUS_CONNECTED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (err != OK) {
|
||||
|
||||
close();
|
||||
|
||||
if (err == ERR_FILE_EOF) {
|
||||
|
||||
status = STATUS_DISCONNECTED; // Server disconnected
|
||||
@ -659,12 +579,12 @@ PoolByteArray HTTPClient::read_response_body_chunk() {
|
||||
|
||||
status = STATUS_CONNECTION_ERROR;
|
||||
}
|
||||
} else if (body_left == 0 && !chunked && !read_until_eof) {
|
||||
} else if (body_left == 0 && !chunked) {
|
||||
|
||||
status = STATUS_CONNECTED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return PoolByteArray();
|
||||
}
|
||||
|
||||
HTTPClient::Status HTTPClient::get_status() const {
|
||||
@ -686,24 +606,11 @@ Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received
|
||||
|
||||
if (blocking) {
|
||||
|
||||
// We can't use StreamPeer.get_data, since when reaching EOF we will get an
|
||||
// error without knowing how many bytes we received.
|
||||
Error err = ERR_FILE_EOF;
|
||||
int read = 0;
|
||||
int left = p_bytes;
|
||||
r_received = 0;
|
||||
while (left > 0) {
|
||||
err = connection->get_partial_data(p_buffer + r_received, left, read);
|
||||
if (err == OK) {
|
||||
r_received += read;
|
||||
} else if (err == ERR_FILE_EOF) {
|
||||
r_received += read;
|
||||
return err;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
left -= read;
|
||||
}
|
||||
Error err = connection->get_data(p_buffer, p_bytes);
|
||||
if (err == OK)
|
||||
r_received = p_bytes;
|
||||
else
|
||||
r_received = 0;
|
||||
return err;
|
||||
} else {
|
||||
return connection->get_partial_data(p_buffer, p_bytes, r_received);
|
||||
@ -717,20 +624,17 @@ void HTTPClient::set_read_chunk_size(int p_size) {
|
||||
|
||||
HTTPClient::HTTPClient() {
|
||||
|
||||
tcp_connection.instance();
|
||||
tcp_connection = StreamPeerTCP::create_ref();
|
||||
resolving = IP::RESOLVER_INVALID_ID;
|
||||
status = STATUS_DISCONNECTED;
|
||||
conn_port = -1;
|
||||
body_size = -1;
|
||||
body_size = 0;
|
||||
chunked = false;
|
||||
body_left = 0;
|
||||
read_until_eof = false;
|
||||
chunk_left = 0;
|
||||
chunk_trailer_part = false;
|
||||
response_num = 0;
|
||||
ssl = false;
|
||||
blocking = false;
|
||||
handshaking = false;
|
||||
read_chunk_size = 4096;
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 HTTP_CLIENT_H
|
||||
#define HTTP_CLIENT_H
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/stream_peer.h"
|
||||
#include "core/io/stream_peer_tcp.h"
|
||||
#include "core/reference.h"
|
||||
#include "io/ip.h"
|
||||
#include "io/stream_peer.h"
|
||||
#include "io/stream_peer_tcp.h"
|
||||
#include "reference.h"
|
||||
|
||||
class HTTPClient : public Reference {
|
||||
|
||||
@ -165,17 +165,14 @@ private:
|
||||
bool ssl;
|
||||
bool ssl_verify_host;
|
||||
bool blocking;
|
||||
bool handshaking;
|
||||
|
||||
Vector<uint8_t> response_str;
|
||||
|
||||
bool chunked;
|
||||
Vector<uint8_t> chunk;
|
||||
int chunk_left;
|
||||
bool chunk_trailer_part;
|
||||
int body_size;
|
||||
int body_left;
|
||||
bool read_until_eof;
|
||||
|
||||
Ref<StreamPeerTCP> tcp_connection;
|
||||
Ref<StreamPeer> connection;
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,8 +30,7 @@
|
||||
|
||||
#include "image_loader.h"
|
||||
|
||||
#include "core/print_string.h"
|
||||
|
||||
#include "print_string.h"
|
||||
bool ImageFormatLoader::recognize(const String &p_extension) const {
|
||||
|
||||
List<String> extensions;
|
||||
@ -60,7 +59,7 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
|
||||
|
||||
String extension = p_file.get_extension();
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
for (int i = 0; i < loader_count; i++) {
|
||||
|
||||
if (!loader[i]->recognize(extension))
|
||||
continue;
|
||||
@ -83,122 +82,28 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
|
||||
|
||||
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
for (int i = 0; i < loader_count; i++) {
|
||||
|
||||
loader[i]->get_recognized_extensions(p_extensions);
|
||||
}
|
||||
}
|
||||
|
||||
ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
|
||||
bool ImageLoader::recognize(const String &p_extension) {
|
||||
|
||||
for (int i = 0; i < loader.size(); i++) {
|
||||
for (int i = 0; i < loader_count; i++) {
|
||||
|
||||
if (loader[i]->recognize(p_extension))
|
||||
return loader[i];
|
||||
return true;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector<ImageFormatLoader *> ImageLoader::loader;
|
||||
ImageFormatLoader *ImageLoader::loader[MAX_LOADERS];
|
||||
int ImageLoader::loader_count = 0;
|
||||
|
||||
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
|
||||
|
||||
loader.push_back(p_loader);
|
||||
}
|
||||
|
||||
void ImageLoader::remove_image_format_loader(ImageFormatLoader *p_loader) {
|
||||
|
||||
loader.erase(p_loader);
|
||||
}
|
||||
|
||||
const Vector<ImageFormatLoader *> &ImageLoader::get_image_format_loaders() {
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
void ImageLoader::cleanup() {
|
||||
|
||||
while (loader.size()) {
|
||||
remove_image_format_loader(loader[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////
|
||||
|
||||
RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error) {
|
||||
|
||||
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
|
||||
if (!f) {
|
||||
if (r_error) {
|
||||
*r_error = ERR_CANT_OPEN;
|
||||
}
|
||||
return RES();
|
||||
}
|
||||
|
||||
uint8_t header[4] = { 0, 0, 0, 0 };
|
||||
f->get_buffer(header, 4);
|
||||
|
||||
bool unrecognized = header[0] != 'G' || header[1] != 'D' || header[2] != 'I' || header[3] != 'M';
|
||||
if (unrecognized) {
|
||||
memdelete(f);
|
||||
if (r_error) {
|
||||
*r_error = ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
ERR_FAIL_V(RES());
|
||||
}
|
||||
|
||||
String extension = f->get_pascal_string();
|
||||
|
||||
int idx = -1;
|
||||
|
||||
for (int i = 0; i < ImageLoader::loader.size(); i++) {
|
||||
if (ImageLoader::loader[i]->recognize(extension)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx == -1) {
|
||||
memdelete(f);
|
||||
if (r_error) {
|
||||
*r_error = ERR_FILE_UNRECOGNIZED;
|
||||
}
|
||||
ERR_FAIL_V(RES());
|
||||
}
|
||||
|
||||
Ref<Image> image;
|
||||
image.instance();
|
||||
|
||||
Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0);
|
||||
|
||||
memdelete(f);
|
||||
|
||||
if (err != OK) {
|
||||
if (r_error) {
|
||||
*r_error = err;
|
||||
}
|
||||
return RES();
|
||||
}
|
||||
|
||||
if (r_error) {
|
||||
*r_error = OK;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {
|
||||
|
||||
p_extensions->push_back("image");
|
||||
}
|
||||
|
||||
bool ResourceFormatLoaderImage::handles_type(const String &p_type) const {
|
||||
|
||||
return p_type == "Image";
|
||||
}
|
||||
|
||||
String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {
|
||||
|
||||
return p_path.get_extension().to_lower() == "image" ? "Image" : String();
|
||||
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
|
||||
loader[loader_count++] = p_loader;
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 IMAGE_LOADER_H
|
||||
#define IMAGE_LOADER_H
|
||||
|
||||
#include "core/image.h"
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/list.h"
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#include "image.h"
|
||||
#include "list.h"
|
||||
#include "os/file_access.h"
|
||||
#include "ustring.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
@ -57,7 +55,6 @@ class ImageLoader;
|
||||
|
||||
class ImageFormatLoader {
|
||||
friend class ImageLoader;
|
||||
friend class ResourceFormatLoaderImage;
|
||||
|
||||
protected:
|
||||
virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear, float p_scale) = 0;
|
||||
@ -70,30 +67,20 @@ public:
|
||||
|
||||
class ImageLoader {
|
||||
|
||||
static Vector<ImageFormatLoader *> loader;
|
||||
friend class ResourceFormatLoaderImage;
|
||||
enum {
|
||||
MAX_LOADERS = 8
|
||||
};
|
||||
|
||||
static ImageFormatLoader *loader[MAX_LOADERS];
|
||||
static int loader_count;
|
||||
|
||||
protected:
|
||||
public:
|
||||
static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false, float p_scale = 1.0);
|
||||
static void get_recognized_extensions(List<String> *p_extensions);
|
||||
static ImageFormatLoader *recognize(const String &p_extension);
|
||||
static bool recognize(const String &p_extension);
|
||||
|
||||
static void add_image_format_loader(ImageFormatLoader *p_loader);
|
||||
static void remove_image_format_loader(ImageFormatLoader *p_loader);
|
||||
|
||||
static const Vector<ImageFormatLoader *> &get_image_format_loaders();
|
||||
|
||||
static void cleanup();
|
||||
};
|
||||
|
||||
class ResourceFormatLoaderImage : public ResourceFormatLoader {
|
||||
GDCLASS(ResourceFormatLoaderImage, 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;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "ip.h"
|
||||
|
||||
#include "core/hash_map.h"
|
||||
#include "core/os/semaphore.h"
|
||||
#include "core/os/thread.h"
|
||||
#include "hash_map.h"
|
||||
#include "os/semaphore.h"
|
||||
#include "os/thread.h"
|
||||
|
||||
VARIANT_ENUM_CAST(IP::ResolverStatus);
|
||||
|
||||
@ -118,7 +117,7 @@ IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
|
||||
resolver->mutex->lock();
|
||||
|
||||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
||||
if (resolver->cache.has(key)) {
|
||||
IP_Address res = resolver->cache[key];
|
||||
resolver->mutex->unlock();
|
||||
return res;
|
||||
@ -145,7 +144,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
|
||||
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
|
||||
resolver->queue[id].hostname = p_hostname;
|
||||
resolver->queue[id].type = p_type;
|
||||
if (resolver->cache.has(key) && resolver->cache[key].is_valid()) {
|
||||
if (resolver->cache.has(key)) {
|
||||
resolver->queue[id].response = resolver->cache[key];
|
||||
resolver->queue[id].status = IP::RESOLVER_STATUS_DONE;
|
||||
} else {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 IP_H
|
||||
#define IP_H
|
||||
|
||||
#include "core/io/ip_address.h"
|
||||
#include "core/os/os.h"
|
||||
#include "io/ip_address.h"
|
||||
#include "os/os.h"
|
||||
|
||||
struct _IP_ResolverPrivate;
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 */
|
||||
@ -184,7 +184,7 @@ bool IP_Address::is_ipv4() const {
|
||||
}
|
||||
|
||||
const uint8_t *IP_Address::get_ipv4() const {
|
||||
ERR_FAIL_COND_V(!is_ipv4(), &(field8[12])); // Not the correct IPv4 (it's an IPv6), but we don't want to return a null pointer risking an engine crash.
|
||||
ERR_FAIL_COND_V(!is_ipv4(), 0);
|
||||
return &(field8[12]);
|
||||
}
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 IP_ADDRESS_H
|
||||
#define IP_ADDRESS_H
|
||||
|
||||
#include "core/ustring.h"
|
||||
#include "ustring.h"
|
||||
|
||||
struct IP_Address {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,8 +29,7 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "json.h"
|
||||
|
||||
#include "core/print_string.h"
|
||||
#include "print_string.h"
|
||||
|
||||
const char *JSON::tk_name[TK_MAX] = {
|
||||
"'{'",
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 JSON_H
|
||||
#define JSON_H
|
||||
|
||||
#include "core/variant.h"
|
||||
#include "variant.h"
|
||||
|
||||
class JSON {
|
||||
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "logger.h"
|
||||
|
||||
#include "core/os/dir_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/print_string.h"
|
||||
#include "os/dir_access.h"
|
||||
#include "os/os.h"
|
||||
#include "print_string.h"
|
||||
|
||||
// va_copy was defined in the C99, but not in C++ standards before C++11.
|
||||
// When you compile C++ without --std=c++<XX> option, compilers still define
|
||||
@ -45,10 +45,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
|
||||
#define sprintf sprintf_s
|
||||
#endif
|
||||
|
||||
bool Logger::should_log(bool p_err) {
|
||||
return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled);
|
||||
}
|
||||
@ -116,7 +112,7 @@ void RotatedFileLogger::clear_old_backups() {
|
||||
int max_backups = max_files - 1; // -1 for the current file
|
||||
|
||||
String basename = base_path.get_file().get_basename();
|
||||
String extension = base_path.get_extension();
|
||||
String extension = "." + base_path.get_extension();
|
||||
|
||||
DirAccess *da = DirAccess::open(base_path.get_base_dir());
|
||||
if (!da) {
|
||||
@ -127,7 +123,7 @@ void RotatedFileLogger::clear_old_backups() {
|
||||
String f = da->get_next();
|
||||
Set<String> backups;
|
||||
while (f != String()) {
|
||||
if (!da->current_is_dir() && f.begins_with(basename) && f.get_extension() == extension && f != base_path.get_file()) {
|
||||
if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path.get_file()) {
|
||||
backups.insert(f);
|
||||
}
|
||||
f = da->get_next();
|
||||
@ -156,10 +152,7 @@ void RotatedFileLogger::rotate_file() {
|
||||
OS::Time time = OS::get_singleton()->get_time();
|
||||
sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day, time.hour, time.min, time.sec);
|
||||
|
||||
String backup_name = base_path.get_basename() + timestamp;
|
||||
if (base_path.get_extension() != String()) {
|
||||
backup_name += "." + base_path.get_extension();
|
||||
}
|
||||
String backup_name = base_path.get_basename() + timestamp + "." + base_path.get_extension();
|
||||
|
||||
DirAccess *da = DirAccess::open(base_path.get_base_dir());
|
||||
if (da) {
|
||||
@ -179,10 +172,11 @@ void RotatedFileLogger::rotate_file() {
|
||||
file = FileAccess::open(base_path, FileAccess::WRITE);
|
||||
}
|
||||
|
||||
RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) :
|
||||
base_path(p_base_path.simplify_path()),
|
||||
max_files(p_max_files > 0 ? p_max_files : 1),
|
||||
file(NULL) {
|
||||
RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) {
|
||||
file = NULL;
|
||||
base_path = p_base_path.simplify_path();
|
||||
max_files = p_max_files > 0 ? p_max_files : 1;
|
||||
|
||||
rotate_file();
|
||||
}
|
||||
|
||||
@ -239,8 +233,8 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
|
||||
StdLogger::~StdLogger() {}
|
||||
|
||||
CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) :
|
||||
loggers(p_loggers) {
|
||||
CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) {
|
||||
loggers = p_loggers;
|
||||
}
|
||||
|
||||
void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/vector.h"
|
||||
|
||||
#include "os/file_access.h"
|
||||
#include "ustring.h"
|
||||
#include "vector.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
class Logger {
|
||||
@ -49,11 +48,11 @@ public:
|
||||
ERR_SHADER
|
||||
};
|
||||
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0 = 0;
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0;
|
||||
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||
|
||||
void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||
void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
|
||||
void logf(const char *p_format, ...);
|
||||
void logf_error(const char *p_format, ...);
|
||||
|
||||
virtual ~Logger();
|
||||
};
|
||||
@ -64,7 +63,7 @@ public:
|
||||
class StdLogger : public Logger {
|
||||
|
||||
public:
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||
virtual ~StdLogger();
|
||||
};
|
||||
|
||||
@ -88,7 +87,7 @@ class RotatedFileLogger : public Logger {
|
||||
public:
|
||||
RotatedFileLogger(const String &p_base_path, int p_max_files = 10);
|
||||
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||
|
||||
virtual ~RotatedFileLogger();
|
||||
};
|
||||
@ -99,7 +98,7 @@ class CompositeLogger : public Logger {
|
||||
public:
|
||||
CompositeLogger(Vector<Logger *> p_loggers);
|
||||
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
|
||||
|
||||
void add_logger(Logger *p_logger);
|
||||
@ -107,4 +106,4 @@ public:
|
||||
virtual ~CompositeLogger();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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,19 +29,19 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "marshalls.h"
|
||||
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/print_string.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
#include "os/keyboard.h"
|
||||
#include "print_string.h"
|
||||
#include "reference.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define _S(a) ((int32_t)a)
|
||||
#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err)
|
||||
#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err)
|
||||
|
||||
void EncodedObjectAsID::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_object_id", "id"), &EncodedObjectAsID::set_object_id);
|
||||
ClassDB::bind_method(D_METHOD("get_object_id"), &EncodedObjectAsID::get_object_id);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "object_id"), "set_object_id", "get_object_id");
|
||||
}
|
||||
|
||||
void EncodedObjectAsID::set_object_id(ObjectID p_id) {
|
||||
@ -53,13 +53,10 @@ ObjectID EncodedObjectAsID::get_object_id() const {
|
||||
return id;
|
||||
}
|
||||
|
||||
EncodedObjectAsID::EncodedObjectAsID() :
|
||||
id(0) {
|
||||
}
|
||||
EncodedObjectAsID::EncodedObjectAsID() {
|
||||
|
||||
#define _S(a) ((int32_t)a)
|
||||
#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err)
|
||||
#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err)
|
||||
id = 0;
|
||||
}
|
||||
|
||||
#define ENCODE_MASK 0xFF
|
||||
#define ENCODE_FLAG_64 1 << 16
|
||||
@ -796,7 +793,7 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
|
||||
}
|
||||
}
|
||||
|
||||
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects) {
|
||||
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id) {
|
||||
|
||||
uint8_t *buf = r_buffer;
|
||||
|
||||
@ -808,7 +805,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
|
||||
case Variant::INT: {
|
||||
int64_t val = p_variant;
|
||||
if (val > (int64_t)INT_MAX || val < (int64_t)INT_MIN) {
|
||||
if (val > 0x7FFFFFFF || val < -0x80000000) {
|
||||
flags |= ENCODE_FLAG_64;
|
||||
}
|
||||
} break;
|
||||
@ -821,11 +818,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
}
|
||||
} break;
|
||||
case Variant::OBJECT: {
|
||||
if (!p_full_objects) {
|
||||
if (p_object_as_id) {
|
||||
flags |= ENCODE_FLAG_OBJECT_AS_ID;
|
||||
}
|
||||
} break;
|
||||
default: {} // nothing to do at this stage
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
@ -851,16 +847,17 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
||||
if (flags & ENCODE_FLAG_64) {
|
||||
int64_t val = p_variant;
|
||||
if (val > 0x7FFFFFFF || val < -0x80000000) {
|
||||
//64 bits
|
||||
if (buf) {
|
||||
encode_uint64(p_variant.operator int64_t(), buf);
|
||||
encode_uint64(val, buf);
|
||||
}
|
||||
|
||||
r_len += 8;
|
||||
} else {
|
||||
if (buf) {
|
||||
encode_uint32(p_variant.operator int32_t(), buf);
|
||||
encode_uint32(int32_t(val), buf);
|
||||
}
|
||||
|
||||
r_len += 4;
|
||||
@ -868,7 +865,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
||||
if (flags & ENCODE_FLAG_64) {
|
||||
double d = p_variant;
|
||||
float f = d;
|
||||
if (double(f) != d) {
|
||||
if (buf) {
|
||||
encode_double(p_variant.operator double(), buf);
|
||||
}
|
||||
@ -891,11 +890,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
if (buf) {
|
||||
encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format
|
||||
encode_uint32(np.get_subname_count(), buf + 4);
|
||||
uint32_t np_flags = 0;
|
||||
uint32_t flags = 0;
|
||||
if (np.is_absolute())
|
||||
np_flags |= 1;
|
||||
flags |= 1;
|
||||
|
||||
encode_uint32(np_flags, buf + 8);
|
||||
encode_uint32(flags, buf + 8);
|
||||
|
||||
buf += 12;
|
||||
}
|
||||
@ -1088,8 +1087,22 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
} break;
|
||||
case Variant::OBJECT: {
|
||||
|
||||
if (p_full_objects) {
|
||||
if (p_object_as_id) {
|
||||
|
||||
if (buf) {
|
||||
|
||||
Object *obj = p_variant;
|
||||
ObjectID id = 0;
|
||||
if (obj && ObjectDB::instance_validate(obj)) {
|
||||
id = obj->get_instance_id();
|
||||
}
|
||||
|
||||
encode_uint64(id, buf);
|
||||
}
|
||||
|
||||
r_len += 8;
|
||||
|
||||
} else {
|
||||
Object *obj = p_variant;
|
||||
if (!obj) {
|
||||
if (buf) {
|
||||
@ -1127,7 +1140,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
_encode_string(E->get().name, buf, r_len);
|
||||
|
||||
int len;
|
||||
Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects);
|
||||
Error err = encode_variant(obj->get(E->get().name), buf, len, p_object_as_id);
|
||||
if (err)
|
||||
return err;
|
||||
ERR_FAIL_COND_V(len % 4, ERR_BUG);
|
||||
@ -1136,19 +1149,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
buf += len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (buf) {
|
||||
|
||||
Object *obj = p_variant;
|
||||
ObjectID id = 0;
|
||||
if (obj && ObjectDB::instance_validate(obj)) {
|
||||
id = obj->get_instance_id();
|
||||
}
|
||||
|
||||
encode_uint64(id, buf);
|
||||
}
|
||||
|
||||
r_len += 8;
|
||||
}
|
||||
|
||||
} break;
|
||||
@ -1181,14 +1181,12 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
r_len++; //pad
|
||||
*/
|
||||
int len;
|
||||
encode_variant(E->get(), buf, len, p_full_objects);
|
||||
encode_variant(E->get(), buf, len, p_object_as_id);
|
||||
ERR_FAIL_COND_V(len % 4, ERR_BUG);
|
||||
r_len += len;
|
||||
if (buf)
|
||||
buf += len;
|
||||
Variant *v = d.getptr(E->get());
|
||||
ERR_FAIL_COND_V(!v, ERR_BUG);
|
||||
encode_variant(*v, buf, len, p_full_objects);
|
||||
encode_variant(d[E->get()], buf, len, p_object_as_id);
|
||||
ERR_FAIL_COND_V(len % 4, ERR_BUG);
|
||||
r_len += len;
|
||||
if (buf)
|
||||
@ -1210,7 +1208,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
for (int i = 0; i < v.size(); i++) {
|
||||
|
||||
int len;
|
||||
encode_variant(v.get(i), buf, len, p_full_objects);
|
||||
encode_variant(v.get(i), buf, len, p_object_as_id);
|
||||
ERR_FAIL_COND_V(len % 4, ERR_BUG);
|
||||
r_len += len;
|
||||
if (buf)
|
||||
@ -1230,15 +1228,11 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
|
||||
buf += 4;
|
||||
PoolVector<uint8_t>::Read r = data.read();
|
||||
copymem(buf, &r[0], datalen * datasize);
|
||||
buf += datalen * datasize;
|
||||
}
|
||||
|
||||
r_len += 4 + datalen * datasize;
|
||||
while (r_len % 4) {
|
||||
while (r_len % 4)
|
||||
r_len++;
|
||||
if (buf)
|
||||
*(buf++) = 0;
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::POOL_INT_ARRAY: {
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 MARSHALLS_H
|
||||
#define MARSHALLS_H
|
||||
|
||||
#include "core/reference.h"
|
||||
#include "core/typedefs.h"
|
||||
#include "core/variant.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
#include "reference.h"
|
||||
#include "variant.h"
|
||||
/**
|
||||
* Miscellaneous helpers for marshalling data types, and encoding
|
||||
* in an endian independent way
|
||||
@ -199,7 +199,7 @@ public:
|
||||
EncodedObjectAsID();
|
||||
};
|
||||
|
||||
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = false);
|
||||
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false);
|
||||
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = NULL, bool p_allow_objects = true);
|
||||
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_object_as_id = false);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,888 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* multiplayer_api.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "multiplayer_api.h"
|
||||
|
||||
#include "core/io/marshalls.h"
|
||||
#include "scene/main/node.h"
|
||||
|
||||
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case MultiplayerAPI::RPC_MODE_DISABLED: {
|
||||
// Do nothing.
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_REMOTE: {
|
||||
// Do nothing also. Remote cannot produce a local call.
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
|
||||
if (is_master)
|
||||
r_skip_rpc = true; // I am the master, so skip remote call.
|
||||
FALLTHROUGH;
|
||||
}
|
||||
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
|
||||
case MultiplayerAPI::RPC_MODE_PUPPETSYNC: {
|
||||
// Call it, sync always results in a local call.
|
||||
return true;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_MASTER: {
|
||||
if (is_master)
|
||||
r_skip_rpc = true; // I am the master, so skip remote call.
|
||||
return is_master;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_PUPPET: {
|
||||
return !is_master;
|
||||
} break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) {
|
||||
switch (mode) {
|
||||
|
||||
case MultiplayerAPI::RPC_MODE_DISABLED: {
|
||||
return false;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_REMOTE:
|
||||
case MultiplayerAPI::RPC_MODE_REMOTESYNC: {
|
||||
return true;
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_MASTERSYNC:
|
||||
case MultiplayerAPI::RPC_MODE_MASTER: {
|
||||
return p_node->is_network_master();
|
||||
} break;
|
||||
case MultiplayerAPI::RPC_MODE_PUPPETSYNC:
|
||||
case MultiplayerAPI::RPC_MODE_PUPPET: {
|
||||
return !p_node->is_network_master() && p_remote_id == p_node->get_network_master();
|
||||
} break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::poll() {
|
||||
|
||||
if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED)
|
||||
return;
|
||||
|
||||
network_peer->poll();
|
||||
|
||||
if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here.
|
||||
return;
|
||||
|
||||
while (network_peer->get_available_packet_count()) {
|
||||
|
||||
int sender = network_peer->get_packet_peer();
|
||||
const uint8_t *packet;
|
||||
int len;
|
||||
|
||||
Error err = network_peer->get_packet(&packet, len);
|
||||
if (err != OK) {
|
||||
ERR_PRINT("Error getting packet!");
|
||||
}
|
||||
|
||||
rpc_sender_id = sender;
|
||||
_process_packet(sender, packet, len);
|
||||
rpc_sender_id = 0;
|
||||
|
||||
if (!network_peer.is_valid()) {
|
||||
break; // It's also possible that a packet or RPC caused a disconnection, so also check here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerAPI::clear() {
|
||||
connected_peers.clear();
|
||||
path_get_cache.clear();
|
||||
path_send_cache.clear();
|
||||
packet_cache.clear();
|
||||
last_send_cache_id = 1;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_root_node(Node *p_node) {
|
||||
root_node = p_node;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
|
||||
|
||||
if (p_peer == network_peer) return; // Nothing to do
|
||||
|
||||
if (network_peer.is_valid()) {
|
||||
network_peer->disconnect("peer_connected", this, "_add_peer");
|
||||
network_peer->disconnect("peer_disconnected", this, "_del_peer");
|
||||
network_peer->disconnect("connection_succeeded", this, "_connected_to_server");
|
||||
network_peer->disconnect("connection_failed", this, "_connection_failed");
|
||||
network_peer->disconnect("server_disconnected", this, "_server_disconnected");
|
||||
clear();
|
||||
}
|
||||
|
||||
network_peer = p_peer;
|
||||
|
||||
ERR_EXPLAIN("Supplied NetworkedNetworkPeer must be connecting or connected.");
|
||||
ERR_FAIL_COND(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED);
|
||||
|
||||
if (network_peer.is_valid()) {
|
||||
network_peer->connect("peer_connected", this, "_add_peer");
|
||||
network_peer->connect("peer_disconnected", this, "_del_peer");
|
||||
network_peer->connect("connection_succeeded", this, "_connected_to_server");
|
||||
network_peer->connect("connection_failed", this, "_connection_failed");
|
||||
network_peer->connect("server_disconnected", this, "_server_disconnected");
|
||||
}
|
||||
}
|
||||
|
||||
Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const {
|
||||
return network_peer;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_EXPLAIN("Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it");
|
||||
ERR_FAIL_COND(root_node == NULL);
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_packet_len < 1);
|
||||
|
||||
uint8_t packet_type = p_packet[0];
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
case NETWORK_COMMAND_SIMPLIFY_PATH: {
|
||||
|
||||
_process_simplify_path(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_CONFIRM_PATH: {
|
||||
|
||||
_process_confirm_path(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_REMOTE_CALL:
|
||||
case NETWORK_COMMAND_REMOTE_SET: {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_packet_len < 6);
|
||||
|
||||
Node *node = _process_get_node(p_from, p_packet, p_packet_len);
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Requested node was not found.");
|
||||
ERR_FAIL_COND(node == NULL);
|
||||
|
||||
// Detect cstring end.
|
||||
int len_end = 5;
|
||||
for (; len_end < p_packet_len; len_end++) {
|
||||
if (p_packet[len_end] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(len_end >= p_packet_len);
|
||||
|
||||
StringName name = String::utf8((const char *)&p_packet[5]);
|
||||
|
||||
if (packet_type == NETWORK_COMMAND_REMOTE_CALL) {
|
||||
|
||||
_process_rpc(node, name, p_from, p_packet, p_packet_len, len_end + 1);
|
||||
|
||||
} else {
|
||||
|
||||
_process_rset(node, name, p_from, p_packet, p_packet_len, len_end + 1);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case NETWORK_COMMAND_RAW: {
|
||||
|
||||
_process_raw(p_from, p_packet, p_packet_len);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
uint32_t target = decode_uint32(&p_packet[1]);
|
||||
Node *node = NULL;
|
||||
|
||||
if (target & 0x80000000) {
|
||||
// Use full path (not cached yet).
|
||||
|
||||
int ofs = target & 0x7FFFFFFF;
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size smaller than declared.");
|
||||
ERR_FAIL_COND_V(ofs >= p_packet_len, NULL);
|
||||
|
||||
String paths;
|
||||
paths.parse_utf8((const char *)&p_packet[ofs], p_packet_len - ofs);
|
||||
|
||||
NodePath np = paths;
|
||||
|
||||
node = root_node->get_node(np);
|
||||
|
||||
if (!node)
|
||||
ERR_PRINTS("Failed to get path from RPC: " + String(np));
|
||||
} else {
|
||||
// Use cached path.
|
||||
int id = target;
|
||||
|
||||
Map<int, PathGetCache>::Element *E = path_get_cache.find(p_from);
|
||||
ERR_EXPLAIN("Invalid packet received. Requests invalid peer cache.");
|
||||
ERR_FAIL_COND_V(!E, NULL);
|
||||
|
||||
Map<int, PathGetCache::NodeInfo>::Element *F = E->get().nodes.find(id);
|
||||
ERR_EXPLAIN("Invalid packet received. Unabled to find requested cached node.");
|
||||
ERR_FAIL_COND_V(!F, NULL);
|
||||
|
||||
PathGetCache::NodeInfo *ni = &F->get();
|
||||
// Do proper caching later.
|
||||
|
||||
node = root_node->get_node(ni->path);
|
||||
if (!node)
|
||||
ERR_PRINTS("Failed to get cached path from RPC: " + String(ni->path));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_offset >= p_packet_len);
|
||||
|
||||
// Check that remote can call the RPC on this node.
|
||||
RPCMode rpc_mode = RPC_MODE_DISABLED;
|
||||
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_name);
|
||||
if (E) {
|
||||
rpc_mode = E->get();
|
||||
} else if (p_node->get_script_instance()) {
|
||||
rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_name);
|
||||
}
|
||||
|
||||
bool can_call = _can_call_mode(p_node, rpc_mode, p_from);
|
||||
ERR_EXPLAIN("RPC '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!can_call);
|
||||
|
||||
int argc = p_packet[p_offset];
|
||||
Vector<Variant> args;
|
||||
Vector<const Variant *> argp;
|
||||
args.resize(argc);
|
||||
argp.resize(argc);
|
||||
|
||||
p_offset++;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_offset >= p_packet_len);
|
||||
|
||||
int vlen;
|
||||
Error err = decode_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
ERR_EXPLAIN("Invalid packet received. Unable to decode RPC argument.");
|
||||
ERR_FAIL_COND(err != OK);
|
||||
|
||||
argp.write[i] = &args[i];
|
||||
p_offset += vlen;
|
||||
}
|
||||
|
||||
Variant::CallError ce;
|
||||
|
||||
p_node->call(p_name, (const Variant **)argp.ptr(), argc, ce);
|
||||
if (ce.error != Variant::CallError::CALL_OK) {
|
||||
String error = Variant::get_call_error_text(p_node, p_name, (const Variant **)argp.ptr(), argc, ce);
|
||||
error = "RPC - " + error;
|
||||
ERR_PRINTS(error);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_offset >= p_packet_len);
|
||||
|
||||
// Check that remote can call the RSET on this node.
|
||||
RPCMode rset_mode = RPC_MODE_DISABLED;
|
||||
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_name);
|
||||
if (E) {
|
||||
rset_mode = E->get();
|
||||
} else if (p_node->get_script_instance()) {
|
||||
rset_mode = p_node->get_script_instance()->get_rset_mode(p_name);
|
||||
}
|
||||
|
||||
bool can_call = _can_call_mode(p_node, rset_mode, p_from);
|
||||
ERR_EXPLAIN("RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
|
||||
ERR_FAIL_COND(!can_call);
|
||||
|
||||
Variant value;
|
||||
Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Unable to decode RSET value.");
|
||||
ERR_FAIL_COND(err != OK);
|
||||
|
||||
bool valid;
|
||||
|
||||
p_node->set(p_name, value, &valid);
|
||||
if (!valid) {
|
||||
String error = "Error setting remote property '" + String(p_name) + "', not found in object of type " + p_node->get_class();
|
||||
ERR_PRINTS(error);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_packet_len < 5);
|
||||
int id = decode_uint32(&p_packet[1]);
|
||||
|
||||
String paths;
|
||||
paths.parse_utf8((const char *)&p_packet[5], p_packet_len - 5);
|
||||
|
||||
NodePath path = paths;
|
||||
|
||||
if (!path_get_cache.has(p_from)) {
|
||||
path_get_cache[p_from] = PathGetCache();
|
||||
}
|
||||
|
||||
PathGetCache::NodeInfo ni;
|
||||
ni.path = path;
|
||||
ni.instance = 0;
|
||||
|
||||
path_get_cache[p_from].nodes[id] = ni;
|
||||
|
||||
// Encode path to send ack.
|
||||
CharString pname = String(path).utf8();
|
||||
int len = encode_cstring(pname.get_data(), NULL);
|
||||
|
||||
Vector<uint8_t> packet;
|
||||
|
||||
packet.resize(1 + len);
|
||||
packet.write[0] = NETWORK_COMMAND_CONFIRM_PATH;
|
||||
encode_cstring(pname.get_data(), &packet.write[1]);
|
||||
|
||||
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
network_peer->set_target_peer(p_from);
|
||||
network_peer->put_packet(packet.ptr(), packet.size());
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_packet_len < 2);
|
||||
|
||||
String paths;
|
||||
paths.parse_utf8((const char *)&p_packet[1], p_packet_len - 1);
|
||||
|
||||
NodePath path = paths;
|
||||
|
||||
PathSentCache *psc = path_send_cache.getptr(path);
|
||||
ERR_EXPLAIN("Invalid packet received. Tries to confirm a path which was not found in cache.");
|
||||
ERR_FAIL_COND(!psc);
|
||||
|
||||
Map<int, bool>::Element *E = psc->confirmed_peers.find(p_from);
|
||||
ERR_EXPLAIN("Invalid packet received. Source peer was not found in cache for the given path.");
|
||||
ERR_FAIL_COND(!E);
|
||||
E->get() = true;
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::_send_confirm_path(NodePath p_path, PathSentCache *psc, int p_target) {
|
||||
bool has_all_peers = true;
|
||||
List<int> peers_to_add; // If one is missing, take note to add it.
|
||||
|
||||
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
|
||||
|
||||
if (p_target < 0 && E->get() == -p_target)
|
||||
continue; // Continue, excluded.
|
||||
|
||||
if (p_target > 0 && E->get() != p_target)
|
||||
continue; // Continue, not for this peer.
|
||||
|
||||
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
|
||||
|
||||
if (!F || !F->get()) {
|
||||
// Path was not cached, or was cached but is unconfirmed.
|
||||
if (!F) {
|
||||
// Not cached at all, take note.
|
||||
peers_to_add.push_back(E->get());
|
||||
}
|
||||
|
||||
has_all_peers = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Those that need to be added, send a message for this.
|
||||
|
||||
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
|
||||
|
||||
// Encode function name.
|
||||
CharString pname = String(p_path).utf8();
|
||||
int len = encode_cstring(pname.get_data(), NULL);
|
||||
|
||||
Vector<uint8_t> packet;
|
||||
|
||||
packet.resize(1 + 4 + len);
|
||||
packet.write[0] = NETWORK_COMMAND_SIMPLIFY_PATH;
|
||||
encode_uint32(psc->id, &packet.write[1]);
|
||||
encode_cstring(pname.get_data(), &packet.write[5]);
|
||||
|
||||
network_peer->set_target_peer(E->get()); // To all of you.
|
||||
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
network_peer->put_packet(packet.ptr(), packet.size());
|
||||
|
||||
psc->confirmed_peers.insert(E->get(), false); // Insert into confirmed, but as false since it was not confirmed.
|
||||
}
|
||||
|
||||
return has_all_peers;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {
|
||||
|
||||
if (network_peer.is_null()) {
|
||||
ERR_EXPLAIN("Attempt to remote call/set when networking is not active in SceneTree.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING) {
|
||||
ERR_EXPLAIN("Attempt to remote call/set when networking is not connected yet in SceneTree.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
if (network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
|
||||
ERR_EXPLAIN("Attempt to remote call/set when networking is disconnected.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
if (p_argcount > 255) {
|
||||
ERR_EXPLAIN("Too many arguments >255.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
if (p_to != 0 && !connected_peers.has(ABS(p_to))) {
|
||||
if (p_to == network_peer->get_unique_id()) {
|
||||
ERR_EXPLAIN("Attempt to remote call/set yourself! unique ID: " + itos(network_peer->get_unique_id()));
|
||||
} else {
|
||||
ERR_EXPLAIN("Attempt to remote call unexisting ID: " + itos(p_to));
|
||||
}
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
NodePath from_path = (root_node->get_path()).rel_path_to(p_from->get_path());
|
||||
ERR_EXPLAIN("Unable to send RPC. Relative path is empty. THIS IS LIKELY A BUG IN THE ENGINE!");
|
||||
ERR_FAIL_COND(from_path.is_empty());
|
||||
|
||||
// See if the path is cached.
|
||||
PathSentCache *psc = path_send_cache.getptr(from_path);
|
||||
if (!psc) {
|
||||
// Path is not cached, create.
|
||||
path_send_cache[from_path] = PathSentCache();
|
||||
psc = path_send_cache.getptr(from_path);
|
||||
psc->id = last_send_cache_id++;
|
||||
}
|
||||
|
||||
// Create base packet, lots of hardcode because it must be tight.
|
||||
|
||||
int ofs = 0;
|
||||
|
||||
#define MAKE_ROOM(m_amount) \
|
||||
if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
|
||||
|
||||
// Encode type.
|
||||
MAKE_ROOM(1);
|
||||
packet_cache.write[0] = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL;
|
||||
ofs += 1;
|
||||
|
||||
// Encode ID.
|
||||
MAKE_ROOM(ofs + 4);
|
||||
encode_uint32(psc->id, &(packet_cache.write[ofs]));
|
||||
ofs += 4;
|
||||
|
||||
// Encode function name.
|
||||
CharString name = String(p_name).utf8();
|
||||
int len = encode_cstring(name.get_data(), NULL);
|
||||
MAKE_ROOM(ofs + len);
|
||||
encode_cstring(name.get_data(), &(packet_cache.write[ofs]));
|
||||
ofs += len;
|
||||
|
||||
if (p_set) {
|
||||
// Set argument.
|
||||
Error err = encode_variant(*p_arg[0], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
ERR_EXPLAIN("Unable to encode RSET value. THIS IS LIKELY A BUG IN THE ENGINE!");
|
||||
ERR_FAIL_COND(err != OK);
|
||||
MAKE_ROOM(ofs + len);
|
||||
encode_variant(*p_arg[0], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
ofs += len;
|
||||
|
||||
} else {
|
||||
// Call arguments.
|
||||
MAKE_ROOM(ofs + 1);
|
||||
packet_cache.write[ofs] = p_argcount;
|
||||
ofs += 1;
|
||||
for (int i = 0; i < p_argcount; i++) {
|
||||
Error err = encode_variant(*p_arg[i], NULL, len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
ERR_EXPLAIN("Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!");
|
||||
ERR_FAIL_COND(err != OK);
|
||||
MAKE_ROOM(ofs + len);
|
||||
encode_variant(*p_arg[i], &(packet_cache.write[ofs]), len, allow_object_decoding || network_peer->is_object_decoding_allowed());
|
||||
ofs += len;
|
||||
}
|
||||
}
|
||||
|
||||
// See if all peers have cached path (is so, call can be fast).
|
||||
bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
|
||||
|
||||
// Take chance and set transfer mode, since all send methods will use it.
|
||||
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
|
||||
if (has_all_peers) {
|
||||
|
||||
// They all have verified paths, so send fast.
|
||||
network_peer->set_target_peer(p_to); // To all of you.
|
||||
network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
|
||||
} else {
|
||||
// Not all verified path, so send one by one.
|
||||
|
||||
// Append path at the end, since we will need it for some packets.
|
||||
CharString pname = String(from_path).utf8();
|
||||
int path_len = encode_cstring(pname.get_data(), NULL);
|
||||
MAKE_ROOM(ofs + path_len);
|
||||
encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
|
||||
|
||||
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
|
||||
|
||||
if (p_to < 0 && E->get() == -p_to)
|
||||
continue; // Continue, excluded.
|
||||
|
||||
if (p_to > 0 && E->get() != p_to)
|
||||
continue; // Continue, not for this peer.
|
||||
|
||||
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
|
||||
ERR_CONTINUE(!F); // Should never happen.
|
||||
|
||||
network_peer->set_target_peer(E->get()); // To this one specifically.
|
||||
|
||||
if (F->get()) {
|
||||
// This one confirmed path, so use id.
|
||||
encode_uint32(psc->id, &(packet_cache.write[1]));
|
||||
network_peer->put_packet(packet_cache.ptr(), ofs);
|
||||
} else {
|
||||
// This one did not confirm path yet, so use entire path (sorry!).
|
||||
encode_uint32(0x80000000 | ofs, &(packet_cache.write[1])); // Offset to path and flag.
|
||||
network_peer->put_packet(packet_cache.ptr(), ofs + path_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_add_peer(int p_id) {
|
||||
connected_peers.insert(p_id);
|
||||
path_get_cache.insert(p_id, PathGetCache());
|
||||
emit_signal("network_peer_connected", p_id);
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_del_peer(int p_id) {
|
||||
connected_peers.erase(p_id);
|
||||
path_get_cache.erase(p_id); // I no longer need your cache, sorry.
|
||||
emit_signal("network_peer_disconnected", p_id);
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_connected_to_server() {
|
||||
|
||||
emit_signal("connected_to_server");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_connection_failed() {
|
||||
|
||||
emit_signal("connection_failed");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_server_disconnected() {
|
||||
|
||||
emit_signal("server_disconnected");
|
||||
}
|
||||
|
||||
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
|
||||
|
||||
ERR_EXPLAIN("Trying to call an RPC while no network peer is active.");
|
||||
ERR_FAIL_COND(!network_peer.is_valid());
|
||||
ERR_EXPLAIN("Trying to call an RPC on a node which is not inside SceneTree.");
|
||||
ERR_FAIL_COND(!p_node->is_inside_tree());
|
||||
ERR_EXPLAIN("Trying to call an RPC via a network peer which is not connected.");
|
||||
ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
|
||||
|
||||
int node_id = network_peer->get_unique_id();
|
||||
bool skip_rpc = false;
|
||||
bool call_local_native = false;
|
||||
bool call_local_script = false;
|
||||
bool is_master = p_node->is_network_master();
|
||||
|
||||
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
|
||||
// Check that send mode can use local call.
|
||||
|
||||
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rpc_mode(p_method);
|
||||
if (E) {
|
||||
call_local_native = _should_call_local(E->get(), is_master, skip_rpc);
|
||||
}
|
||||
|
||||
if (call_local_native) {
|
||||
// Done below.
|
||||
} else if (p_node->get_script_instance()) {
|
||||
// Attempt with script.
|
||||
RPCMode rpc_mode = p_node->get_script_instance()->get_rpc_mode(p_method);
|
||||
call_local_script = _should_call_local(rpc_mode, is_master, skip_rpc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!skip_rpc) {
|
||||
_send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
|
||||
}
|
||||
|
||||
if (call_local_native) {
|
||||
Variant::CallError ce;
|
||||
p_node->call(p_method, p_arg, p_argcount, ce);
|
||||
if (ce.error != Variant::CallError::CALL_OK) {
|
||||
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
|
||||
error = "rpc() aborted in local call: - " + error;
|
||||
ERR_PRINTS(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (call_local_script) {
|
||||
Variant::CallError ce;
|
||||
ce.error = Variant::CallError::CALL_OK;
|
||||
p_node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
|
||||
if (ce.error != Variant::CallError::CALL_OK) {
|
||||
String error = Variant::get_call_error_text(p_node, p_method, p_arg, p_argcount, ce);
|
||||
error = "rpc() aborted in script local call: - " + error;
|
||||
ERR_PRINTS(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
|
||||
|
||||
ERR_EXPLAIN("Trying to RSET while no network peer is active.");
|
||||
ERR_FAIL_COND(!network_peer.is_valid());
|
||||
ERR_EXPLAIN("Trying to RSET on a node which is not inside SceneTree.");
|
||||
ERR_FAIL_COND(!p_node->is_inside_tree());
|
||||
ERR_EXPLAIN("Trying to send an RSET via a network peer which is not connected.");
|
||||
ERR_FAIL_COND(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED);
|
||||
|
||||
int node_id = network_peer->get_unique_id();
|
||||
bool is_master = p_node->is_network_master();
|
||||
bool skip_rset = false;
|
||||
|
||||
if (p_peer_id == 0 || p_peer_id == node_id || (p_peer_id < 0 && p_peer_id != -node_id)) {
|
||||
// Check that send mode can use local call.
|
||||
|
||||
bool set_local = false;
|
||||
|
||||
const Map<StringName, RPCMode>::Element *E = p_node->get_node_rset_mode(p_property);
|
||||
if (E) {
|
||||
|
||||
set_local = _should_call_local(E->get(), is_master, skip_rset);
|
||||
}
|
||||
|
||||
if (set_local) {
|
||||
bool valid;
|
||||
p_node->set(p_property, p_value, &valid);
|
||||
|
||||
if (!valid) {
|
||||
String error = "rset() aborted in local set, property not found: - " + String(p_property);
|
||||
ERR_PRINTS(error);
|
||||
return;
|
||||
}
|
||||
} else if (p_node->get_script_instance()) {
|
||||
// Attempt with script.
|
||||
RPCMode rpc_mode = p_node->get_script_instance()->get_rset_mode(p_property);
|
||||
|
||||
set_local = _should_call_local(rpc_mode, is_master, skip_rset);
|
||||
|
||||
if (set_local) {
|
||||
|
||||
bool valid = p_node->get_script_instance()->set(p_property, p_value);
|
||||
|
||||
if (!valid) {
|
||||
String error = "rset() aborted in local script set, property not found: - " + String(p_property);
|
||||
ERR_PRINTS(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skip_rset)
|
||||
return;
|
||||
|
||||
const Variant *vptr = &p_value;
|
||||
|
||||
_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
|
||||
}
|
||||
|
||||
Error MultiplayerAPI::send_bytes(PoolVector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
|
||||
|
||||
ERR_EXPLAIN("Trying to send an empty raw packet.");
|
||||
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
|
||||
ERR_EXPLAIN("Trying to send a raw packet while no network peer is active.");
|
||||
ERR_FAIL_COND_V(!network_peer.is_valid(), ERR_UNCONFIGURED);
|
||||
ERR_EXPLAIN("Trying to send a raw packet via a network peer which is not connected.");
|
||||
ERR_FAIL_COND_V(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED);
|
||||
|
||||
MAKE_ROOM(p_data.size() + 1);
|
||||
PoolVector<uint8_t>::Read r = p_data.read();
|
||||
packet_cache.write[0] = NETWORK_COMMAND_RAW;
|
||||
memcpy(&packet_cache.write[1], &r[0], p_data.size());
|
||||
|
||||
network_peer->set_target_peer(p_to);
|
||||
network_peer->set_transfer_mode(p_mode);
|
||||
|
||||
return network_peer->put_packet(packet_cache.ptr(), p_data.size() + 1);
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
|
||||
|
||||
ERR_EXPLAIN("Invalid packet received. Size too small.");
|
||||
ERR_FAIL_COND(p_packet_len < 2);
|
||||
|
||||
PoolVector<uint8_t> out;
|
||||
int len = p_packet_len - 1;
|
||||
out.resize(len);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = out.write();
|
||||
memcpy(&w[0], &p_packet[1], len);
|
||||
}
|
||||
emit_signal("network_peer_packet", p_from, out);
|
||||
}
|
||||
|
||||
int MultiplayerAPI::get_network_unique_id() const {
|
||||
|
||||
ERR_EXPLAIN("No network peer is assigned. Unable to get unique network ID.");
|
||||
ERR_FAIL_COND_V(!network_peer.is_valid(), 0);
|
||||
return network_peer->get_unique_id();
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_network_server() const {
|
||||
|
||||
// XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
|
||||
ERR_EXPLAIN("No network peer is assigned. I can't be a server.");
|
||||
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
|
||||
return network_peer->is_server();
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
|
||||
|
||||
ERR_EXPLAIN("No network peer is assigned. Unable to set 'refuse_new_connections'.");
|
||||
ERR_FAIL_COND(!network_peer.is_valid());
|
||||
network_peer->set_refuse_new_connections(p_refuse);
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_refusing_new_network_connections() const {
|
||||
|
||||
ERR_EXPLAIN("No network peer is assigned. Unable to get 'refuse_new_connections'.");
|
||||
ERR_FAIL_COND_V(!network_peer.is_valid(), false);
|
||||
return network_peer->is_refusing_new_connections();
|
||||
}
|
||||
|
||||
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
|
||||
|
||||
ERR_EXPLAIN("No network peer is assigned. Assume no peers are connected.");
|
||||
ERR_FAIL_COND_V(!network_peer.is_valid(), Vector<int>());
|
||||
|
||||
Vector<int> ret;
|
||||
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
|
||||
ret.push_back(E->get());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::set_allow_object_decoding(bool p_enable) {
|
||||
|
||||
allow_object_decoding = p_enable;
|
||||
}
|
||||
|
||||
bool MultiplayerAPI::is_object_decoding_allowed() const {
|
||||
|
||||
return allow_object_decoding;
|
||||
}
|
||||
|
||||
void MultiplayerAPI::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
|
||||
ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
|
||||
ClassDB::bind_method(D_METHOD("has_network_peer"), &MultiplayerAPI::has_network_peer);
|
||||
ClassDB::bind_method(D_METHOD("get_network_peer"), &MultiplayerAPI::get_network_peer);
|
||||
ClassDB::bind_method(D_METHOD("get_network_unique_id"), &MultiplayerAPI::get_network_unique_id);
|
||||
ClassDB::bind_method(D_METHOD("is_network_server"), &MultiplayerAPI::is_network_server);
|
||||
ClassDB::bind_method(D_METHOD("get_rpc_sender_id"), &MultiplayerAPI::get_rpc_sender_id);
|
||||
ClassDB::bind_method(D_METHOD("_add_peer", "id"), &MultiplayerAPI::_add_peer);
|
||||
ClassDB::bind_method(D_METHOD("_del_peer", "id"), &MultiplayerAPI::_del_peer);
|
||||
ClassDB::bind_method(D_METHOD("set_network_peer", "peer"), &MultiplayerAPI::set_network_peer);
|
||||
ClassDB::bind_method(D_METHOD("poll"), &MultiplayerAPI::poll);
|
||||
ClassDB::bind_method(D_METHOD("clear"), &MultiplayerAPI::clear);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_connected_to_server"), &MultiplayerAPI::_connected_to_server);
|
||||
ClassDB::bind_method(D_METHOD("_connection_failed"), &MultiplayerAPI::_connection_failed);
|
||||
ClassDB::bind_method(D_METHOD("_server_disconnected"), &MultiplayerAPI::_server_disconnected);
|
||||
ClassDB::bind_method(D_METHOD("get_network_connected_peers"), &MultiplayerAPI::get_network_connected_peers);
|
||||
ClassDB::bind_method(D_METHOD("set_refuse_new_network_connections", "refuse"), &MultiplayerAPI::set_refuse_new_network_connections);
|
||||
ClassDB::bind_method(D_METHOD("is_refusing_new_network_connections"), &MultiplayerAPI::is_refusing_new_network_connections);
|
||||
ClassDB::bind_method(D_METHOD("set_allow_object_decoding", "enable"), &MultiplayerAPI::set_allow_object_decoding);
|
||||
ClassDB::bind_method(D_METHOD("is_object_decoding_allowed"), &MultiplayerAPI::is_object_decoding_allowed);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_object_decoding"), "set_allow_object_decoding", "is_object_decoding_allowed");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "refuse_new_network_connections"), "set_refuse_new_network_connections", "is_refusing_new_network_connections");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "network_peer", PROPERTY_HINT_RESOURCE_TYPE, "NetworkedMultiplayerPeer", 0), "set_network_peer", "get_network_peer");
|
||||
|
||||
ADD_SIGNAL(MethodInfo("network_peer_connected", PropertyInfo(Variant::INT, "id")));
|
||||
ADD_SIGNAL(MethodInfo("network_peer_disconnected", PropertyInfo(Variant::INT, "id")));
|
||||
ADD_SIGNAL(MethodInfo("network_peer_packet", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "packet")));
|
||||
ADD_SIGNAL(MethodInfo("connected_to_server"));
|
||||
ADD_SIGNAL(MethodInfo("connection_failed"));
|
||||
ADD_SIGNAL(MethodInfo("server_disconnected"));
|
||||
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_DISABLED);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_REMOTE);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_MASTER);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_PUPPET);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_SLAVE); // Deprecated.
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_REMOTESYNC);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_SYNC); // Deprecated.
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_MASTERSYNC);
|
||||
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
|
||||
}
|
||||
|
||||
MultiplayerAPI::MultiplayerAPI() :
|
||||
allow_object_decoding(false) {
|
||||
rpc_sender_id = 0;
|
||||
root_node = NULL;
|
||||
clear();
|
||||
}
|
||||
|
||||
MultiplayerAPI::~MultiplayerAPI() {
|
||||
clear();
|
||||
}
|
||||
@ -1,139 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* multiplayer_api.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 MULTIPLAYER_PROTOCOL_H
|
||||
#define MULTIPLAYER_PROTOCOL_H
|
||||
|
||||
#include "core/io/networked_multiplayer_peer.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
class MultiplayerAPI : public Reference {
|
||||
|
||||
GDCLASS(MultiplayerAPI, Reference);
|
||||
|
||||
private:
|
||||
//path sent caches
|
||||
struct PathSentCache {
|
||||
Map<int, bool> confirmed_peers;
|
||||
int id;
|
||||
};
|
||||
|
||||
//path get caches
|
||||
struct PathGetCache {
|
||||
struct NodeInfo {
|
||||
NodePath path;
|
||||
ObjectID instance;
|
||||
};
|
||||
|
||||
Map<int, NodeInfo> nodes;
|
||||
};
|
||||
|
||||
Ref<NetworkedMultiplayerPeer> network_peer;
|
||||
int rpc_sender_id;
|
||||
Set<int> connected_peers;
|
||||
HashMap<NodePath, PathSentCache> path_send_cache;
|
||||
Map<int, PathGetCache> path_get_cache;
|
||||
int last_send_cache_id;
|
||||
Vector<uint8_t> packet_cache;
|
||||
Node *root_node;
|
||||
bool allow_object_decoding;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
void _process_packet(int p_from, const uint8_t *p_packet, int p_packet_len);
|
||||
void _process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len);
|
||||
void _process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len);
|
||||
Node *_process_get_node(int p_from, const uint8_t *p_packet, int p_packet_len);
|
||||
void _process_rpc(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
|
||||
void _process_rset(Node *p_node, const StringName &p_name, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset);
|
||||
void _process_raw(int p_from, const uint8_t *p_packet, int p_packet_len);
|
||||
|
||||
void _send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount);
|
||||
bool _send_confirm_path(NodePath p_path, PathSentCache *psc, int p_from);
|
||||
|
||||
public:
|
||||
enum NetworkCommands {
|
||||
NETWORK_COMMAND_REMOTE_CALL,
|
||||
NETWORK_COMMAND_REMOTE_SET,
|
||||
NETWORK_COMMAND_SIMPLIFY_PATH,
|
||||
NETWORK_COMMAND_CONFIRM_PATH,
|
||||
NETWORK_COMMAND_RAW,
|
||||
};
|
||||
|
||||
enum RPCMode {
|
||||
|
||||
RPC_MODE_DISABLED, // No rpc for this method, calls to this will be blocked (default)
|
||||
RPC_MODE_REMOTE, // Using rpc() on it will call method / set property in all remote peers
|
||||
RPC_MODE_MASTER, // Using rpc() on it will call method on wherever the master is, be it local or remote
|
||||
RPC_MODE_PUPPET, // Using rpc() on it will call method for all puppets
|
||||
RPC_MODE_SLAVE = RPC_MODE_PUPPET, // Deprecated, same as puppet
|
||||
RPC_MODE_REMOTESYNC, // Using rpc() on it will call method / set property in all remote peers and locally
|
||||
RPC_MODE_SYNC = RPC_MODE_REMOTESYNC, // Deprecated. Same as RPC_MODE_REMOTESYNC
|
||||
RPC_MODE_MASTERSYNC, // Using rpc() on it will call method / set property in the master peer and locally
|
||||
RPC_MODE_PUPPETSYNC, // Using rpc() on it will call method / set property in all puppets peers and locally
|
||||
};
|
||||
|
||||
void poll();
|
||||
void clear();
|
||||
void set_root_node(Node *p_node);
|
||||
void set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer);
|
||||
Ref<NetworkedMultiplayerPeer> get_network_peer() const;
|
||||
Error send_bytes(PoolVector<uint8_t> p_data, int p_to = NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST, NetworkedMultiplayerPeer::TransferMode p_mode = NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
|
||||
|
||||
// Called by Node.rpc
|
||||
void rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount);
|
||||
// Called by Node.rset
|
||||
void rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value);
|
||||
|
||||
void _add_peer(int p_id);
|
||||
void _del_peer(int p_id);
|
||||
void _connected_to_server();
|
||||
void _connection_failed();
|
||||
void _server_disconnected();
|
||||
|
||||
bool has_network_peer() const { return network_peer.is_valid(); }
|
||||
Vector<int> get_network_connected_peers() const;
|
||||
int get_rpc_sender_id() const { return rpc_sender_id; }
|
||||
int get_network_unique_id() const;
|
||||
bool is_network_server() const;
|
||||
void set_refuse_new_network_connections(bool p_refuse);
|
||||
bool is_refusing_new_network_connections() const;
|
||||
|
||||
void set_allow_object_decoding(bool p_enable);
|
||||
bool is_object_decoding_allowed() const;
|
||||
|
||||
MultiplayerAPI();
|
||||
~MultiplayerAPI();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(MultiplayerAPI::RPCMode);
|
||||
|
||||
#endif // MULTIPLAYER_PROTOCOL_H
|
||||
@ -1,42 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* net_socket.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 "net_socket.h"
|
||||
|
||||
NetSocket *(*NetSocket::_create)() = NULL;
|
||||
|
||||
NetSocket *NetSocket::create() {
|
||||
|
||||
if (_create)
|
||||
return _create();
|
||||
|
||||
ERR_PRINT("Unable to create network socket, platform not supported");
|
||||
return NULL;
|
||||
}
|
||||
@ -1,79 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* net_socket.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2019 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 NET_SOCKET_H
|
||||
#define NET_SOCKET_H
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/reference.h"
|
||||
|
||||
class NetSocket : public Reference {
|
||||
|
||||
protected:
|
||||
static NetSocket *(*_create)();
|
||||
|
||||
public:
|
||||
static NetSocket *create();
|
||||
|
||||
enum PollType {
|
||||
POLL_TYPE_IN,
|
||||
POLL_TYPE_OUT,
|
||||
POLL_TYPE_IN_OUT
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TYPE_NONE,
|
||||
TYPE_TCP,
|
||||
TYPE_UDP,
|
||||
};
|
||||
|
||||
virtual Error open(Type p_type, IP::Type &ip_type) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual Error bind(IP_Address p_addr, uint16_t p_port) = 0;
|
||||
virtual Error listen(int p_max_pending) = 0;
|
||||
virtual Error connect_to_host(IP_Address p_addr, uint16_t p_port) = 0;
|
||||
virtual Error poll(PollType p_type, int timeout) const = 0;
|
||||
virtual Error recv(uint8_t *p_buffer, int p_len, int &r_read) = 0;
|
||||
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
|
||||
virtual Error send(const uint8_t *p_buffer, int p_len, int &r_sent) = 0;
|
||||
virtual Error sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP_Address p_ip, uint16_t p_port) = 0;
|
||||
virtual Ref<NetSocket> accept(IP_Address &r_ip, uint16_t &r_port) = 0;
|
||||
|
||||
virtual bool is_open() const = 0;
|
||||
virtual int get_available_bytes() const = 0;
|
||||
|
||||
virtual void set_broadcasting_enabled(bool p_enabled) = 0;
|
||||
virtual void set_blocking_enabled(bool p_enabled) = 0;
|
||||
virtual void set_ipv6_only_enabled(bool p_enabled) = 0;
|
||||
virtual void set_tcp_no_delay_enabled(bool p_enabled) = 0;
|
||||
virtual void set_reuse_address_enabled(bool p_enabled) = 0;
|
||||
};
|
||||
|
||||
#endif // NET_SOCKET_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user