diff options
30 files changed, 324 insertions, 139 deletions
diff --git a/.github/actions/godot-build/action.yml b/.github/actions/godot-build/action.yml index 5ed64e7de2..13d4abe2a7 100644 --- a/.github/actions/godot-build/action.yml +++ b/.github/actions/godot-build/action.yml @@ -20,7 +20,8 @@ inputs: default: "${{ github.workspace }}/.scons-cache/" scons-cache-limit: description: The scons cache size limit. - default: 4096 + # actions/cache has 10 GiB limit. Allow 10 GiB minus 256 MiB. + default: 9984 runs: using: "composite" steps: diff --git a/.github/actions/godot-cache/action.yml b/.github/actions/godot-cache/action.yml index db14a0b97a..2d7afc8514 100644 --- a/.github/actions/godot-cache/action.yml +++ b/.github/actions/godot-cache/action.yml @@ -12,7 +12,7 @@ runs: steps: # Upload cache on completion and check it out now - name: Load .scons_cache directory - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: ${{inputs.scons-cache}} key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml index dd3622f1f0..a9a580247b 100644 --- a/.github/workflows/android_builds.yml +++ b/.github/workflows/android_builds.yml @@ -3,6 +3,7 @@ on: [push, pull_request] # Global Settings env: + # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml index cd9c7ec117..40f091e234 100644 --- a/.github/workflows/ios_builds.yml +++ b/.github/workflows/ios_builds.yml @@ -3,6 +3,7 @@ on: [push, pull_request] # Global Settings env: + # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml index 9163baab0f..395dfdd7f5 100644 --- a/.github/workflows/javascript_builds.yml +++ b/.github/workflows/javascript_builds.yml @@ -3,6 +3,7 @@ on: [push, pull_request] # Global Settings env: + # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no EM_VERSION: 2.0.27 diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 0776dc77eb..c9f1b2f41e 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -3,7 +3,8 @@ on: [push, pull_request] # Global Settings env: - GODOT_BASE_BRANCH: master + # Only used for the cache key. Increment version to force clean build. + GODOT_BASE_BRANCH: master-v2 SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes concurrency: @@ -36,6 +37,8 @@ jobs: tests: true sconsflags: float=64 use_asan=yes use_ubsan=yes proj-test: true + # Can be turned off for PRs that intentionally break compat with godot-cpp, + # until both the upstream PR and the matching godot-cpp changes are merged. godot-cpp-test: true bin: "./bin/godot.linuxbsd.double.tools.64.san" build-mono: false diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index ad870ae58f..8c88c8fa64 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -4,6 +4,7 @@ on: [push, pull_request] # Global Settings # SCONS_CACHE for windows must be set in the build environment env: + # Only used for the cache key. Increment version to force clean build. GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=all werror=yes module_text_server_fb_enabled=yes SCONS_CACHE_MSVC_CONFIG: true @@ -56,7 +57,6 @@ jobs: target: ${{ matrix.target }} tools: ${{ matrix.tools }} tests: ${{ matrix.tests }} - scons-cache-limit: 3072 # Execute unit tests for the editor - name: Unit tests diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 2d0eaadbdf..7150459d84 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1334,7 +1334,7 @@ void File::store_buffer(const Vector<uint8_t> &p_buffer) { f->store_buffer(&r[0], len); } -bool File::file_exists(const String &p_name) const { +bool File::file_exists(const String &p_name) { return FileAccess::exists(p_name); } @@ -1424,7 +1424,7 @@ void File::_bind_methods() { 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); - ClassDB::bind_method(D_METHOD("file_exists", "path"), &File::file_exists); + ClassDB::bind_static_method("File", D_METHOD("file_exists", "path"), &File::file_exists); ClassDB::bind_method(D_METHOD("get_modified_time", "file"), &File::get_modified_time); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian"); diff --git a/core/core_bind.h b/core/core_bind.h index 4a7eb718f1..a0fdf26dff 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -436,7 +436,7 @@ public: void store_var(const Variant &p_var, bool p_full_objects = false); - bool file_exists(const String &p_name) const; // Return true if a file exists. + static bool file_exists(const String &p_name); // Return true if a file exists. uint64_t get_modified_time(const String &p_file) const; diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 31af28b783..9acc28f51e 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -666,6 +666,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { Dictionary d2; d2["name"] = String(method_name); d2["is_const"] = (F.flags & METHOD_FLAG_CONST) ? true : false; + d2["is_static"] = (F.flags & METHOD_FLAG_STATIC) ? true : false; d2["is_vararg"] = false; d2["is_virtual"] = true; // virtual functions have no hash since no MethodBind is involved @@ -708,6 +709,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { d2["is_const"] = method->is_const(); d2["is_vararg"] = method->is_vararg(); + d2["is_static"] = method->is_static(); d2["is_virtual"] = false; d2["hash"] = method->get_hash(); diff --git a/core/io/dir_access.h b/core/io/dir_access.h index d63453e947..b97d097842 100644 --- a/core/io/dir_access.h +++ b/core/io/dir_access.h @@ -137,6 +137,10 @@ struct DirAccessRef { DirAccess *f = nullptr; DirAccessRef(DirAccess *fa) { f = fa; } + DirAccessRef(DirAccessRef &&other) { + f = other.f; + other.f = nullptr; + } ~DirAccessRef() { if (f) { memdelete(f); diff --git a/core/io/file_access.h b/core/io/file_access.h index 5413665440..a6cb5d9fc6 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -188,6 +188,10 @@ struct FileAccessRef { operator FileAccess *() { return f; } FileAccessRef(FileAccess *fa) { f = fa; } + FileAccessRef(FileAccessRef &&other) { + f = other.f; + other.f = nullptr; + } ~FileAccessRef() { if (f) { memdelete(f); diff --git a/core/math/bvh.h b/core/math/bvh.h index e686e27445..f429ce189b 100644 --- a/core/math/bvh.h +++ b/core/math/bvh.h @@ -196,6 +196,7 @@ public: //////////////////////////////////////////////////// void move(BVHHandle p_handle, const BOUNDS &p_aabb) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION if (tree.item_move(p_handle, p_aabb)) { if (USE_PAIRS) { @@ -205,10 +206,12 @@ public: } void recheck_pairs(BVHHandle p_handle) { + DEV_ASSERT(!p_handle.is_invalid()); force_collision_check(p_handle); } void erase(BVHHandle p_handle) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION // call unpair and remove all references to the item // before deleting from the tree @@ -225,6 +228,7 @@ public: // set pairable has never been called. // (deferred collision checks are a workaround for visual server for historical reasons) void force_collision_check(BVHHandle p_handle) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION if (USE_PAIRS) { // the aabb should already be up to date in the BVH @@ -243,6 +247,7 @@ public: // but generically this makes items add or remove from the // tree internally, to speed things up by ignoring inactive items bool activate(BVHHandle p_handle, const BOUNDS &p_aabb, bool p_delay_collision_check = false) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION // sending the aabb here prevents the need for the BVH to maintain // a redundant copy of the aabb. @@ -267,6 +272,7 @@ public: } bool deactivate(BVHHandle p_handle) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION // returns success if (tree.item_deactivate(p_handle)) { @@ -285,6 +291,7 @@ public: } bool get_active(BVHHandle p_handle) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION return tree.item_get_active(p_handle); } @@ -307,6 +314,7 @@ public: // prefer calling this directly as type safe void set_tree(const BVHHandle &p_handle, uint32_t p_tree_id, uint32_t p_tree_collision_mask, bool p_force_collision_check = true) { + DEV_ASSERT(!p_handle.is_invalid()); BVH_LOCKED_FUNCTION // Returns true if the pairing state has changed. bool state_changed = tree.item_set_tree(p_handle, p_tree_id, p_tree_collision_mask); @@ -465,13 +473,6 @@ private: continue; } -#ifdef BVH_CHECKS - // if neither are pairable, they should ignore each other - // THIS SHOULD NEVER HAPPEN .. now we only test the pairable tree - // if the changed item is not pairable - CRASH_COND(params.test_pairable_only && !tree._extra[ref_id].pairable); -#endif - // checkmasks is already done in the cull routine. BVHHandle h_collidee; h_collidee.set_id(ref_id); @@ -485,6 +486,7 @@ private: public: void item_get_AABB(BVHHandle p_handle, BOUNDS &r_aabb) { + DEV_ASSERT(!p_handle.is_invalid()); BVHABB_CLASS abb; tree.item_get_ABB(p_handle, abb); abb.to(r_aabb); diff --git a/core/math/bvh_structs.inc b/core/math/bvh_structs.inc index b0d9ae3615..58c8f0479a 100644 --- a/core/math/bvh_structs.inc +++ b/core/math/bvh_structs.inc @@ -60,11 +60,23 @@ private: public: // accessors - BVHABB_CLASS &get_aabb(uint32_t p_id) { return aabbs[p_id]; } - const BVHABB_CLASS &get_aabb(uint32_t p_id) const { return aabbs[p_id]; } + BVHABB_CLASS &get_aabb(uint32_t p_id) { + BVH_ASSERT(p_id < MAX_ITEMS); + return aabbs[p_id]; + } + const BVHABB_CLASS &get_aabb(uint32_t p_id) const { + BVH_ASSERT(p_id < MAX_ITEMS); + return aabbs[p_id]; + } - uint32_t &get_item_ref_id(uint32_t p_id) { return item_ref_ids[p_id]; } - const uint32_t &get_item_ref_id(uint32_t p_id) const { return item_ref_ids[p_id]; } + uint32_t &get_item_ref_id(uint32_t p_id) { + BVH_ASSERT(p_id < MAX_ITEMS); + return item_ref_ids[p_id]; + } + const uint32_t &get_item_ref_id(uint32_t p_id) const { + BVH_ASSERT(p_id < MAX_ITEMS); + return item_ref_ids[p_id]; + } bool is_dirty() const { return dirty; } void set_dirty(bool p) { dirty = p; } diff --git a/core/math/bvh_tree.h b/core/math/bvh_tree.h index da9b307778..cdb2bb4413 100644 --- a/core/math/bvh_tree.h +++ b/core/math/bvh_tree.h @@ -54,7 +54,7 @@ #define BVH_EXPAND_LEAF_AABBS // never do these checks in release -#if defined(TOOLS_ENABLED) && defined(DEBUG_ENABLED) +#ifdef DEV_ENABLED //#define BVH_VERBOSE //#define BVH_VERBOSE_TREE //#define BVH_VERBOSE_PAIRING @@ -217,7 +217,7 @@ private: BVH_ASSERT(!parent.is_leaf()); int child_num = parent.find_child(p_old_child_id); - BVH_ASSERT(child_num != BVHCommon::INVALID); + BVH_ASSERT(child_num != -1); parent.children[child_num] = p_new_child_id; TNode &new_child = _nodes[p_new_child_id]; @@ -229,7 +229,7 @@ private: BVH_ASSERT(!parent.is_leaf()); int child_num = parent.find_child(p_child_id); - BVH_ASSERT(child_num != BVHCommon::INVALID); + BVH_ASSERT(child_num != -1); parent.remove_child_internal(child_num); diff --git a/core/object/class_db.h b/core/object/class_db.h index 32e4bf7644..4211601d15 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -227,75 +227,27 @@ public: static uint64_t get_api_hash(APIType p_api); - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method) { - MethodBind *bind = create_method_bind(p_method); - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, nullptr, 0); //use static function, much smaller binary usage - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[1] = { &p_def1 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 1); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[2] = { &p_def1, &p_def2 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 2); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 3); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 4); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 5); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 6); - } - - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) { + template <class N, class M, typename... VarArgs> + static MethodBind *bind_method(N p_method_name, M p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 7); + return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); } - template <class N, class M> - static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) { - MethodBind *bind = create_method_bind(p_method); - const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 }; - - return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, ptr, 8); + template <class N, class M, typename... VarArgs> + static MethodBind *bind_static_method(const StringName &p_class, N p_method_name, M p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + MethodBind *bind = create_static_method_bind(p_method); + bind->set_instance_class(p_class); + return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); } template <class M> diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp index 32269b5f19..a79adb7c6c 100644 --- a/core/object/method_bind.cpp +++ b/core/object/method_bind.cpp @@ -83,6 +83,10 @@ void MethodBind::_set_const(bool p_const) { _const = p_const; } +void MethodBind::_set_static(bool p_static) { + _static = p_static; +} + void MethodBind::_set_returns(bool p_returns) { _returns = p_returns; } diff --git a/core/object/method_bind.h b/core/object/method_bind.h index 02b73fa273..1518c8d793 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -60,6 +60,7 @@ class MethodBind { int default_argument_count = 0; int argument_count = 0; + bool _static = false; bool _const = false; bool _returns = false; @@ -69,6 +70,7 @@ protected: Vector<StringName> arg_names; #endif void _set_const(bool p_const); + void _set_static(bool p_static); void _set_returns(bool p_returns); virtual Variant::Type _gen_argument_type(int p_arg) const = 0; virtual PropertyInfo _gen_argument_type_info(int p_arg) const = 0; @@ -116,7 +118,7 @@ public: #endif void set_hint_flags(uint32_t p_hint) { hint_flags = p_hint; } - uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0); } + uint32_t get_hint_flags() const { return hint_flags | (is_const() ? METHOD_FLAG_CONST : 0) | (is_vararg() ? METHOD_FLAG_VARARG : 0) | (is_static() ? METHOD_FLAG_STATIC : 0); } _FORCE_INLINE_ StringName get_instance_class() const { return instance_class; } _FORCE_INLINE_ void set_instance_class(const StringName &p_class) { instance_class = p_class; } @@ -129,6 +131,7 @@ public: void set_name(const StringName &p_name); _FORCE_INLINE_ int get_method_id() const { return method_id; } _FORCE_INLINE_ bool is_const() const { return _const; } + _FORCE_INLINE_ bool is_static() const { return _static; } _FORCE_INLINE_ bool has_return() const { return _returns; } virtual bool is_vararg() const { return false; } @@ -308,7 +311,7 @@ MethodBind *create_method_bind(void (T::*p_method)(P...)) { return a; } -// no return, not const +// no return, const #ifdef TYPED_METHOD_BIND template <class T, class... P> @@ -558,4 +561,139 @@ MethodBind *create_method_bind(R (T::*p_method)(P...) const) { return a; } +/* STATIC BINDS */ + +// no return + +template <class... P> +class MethodBindTS : public MethodBind { + void (*function)(P...); + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual Variant::Type _gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return Variant::NIL; + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + virtual PropertyInfo _gen_argument_type_info(int p_arg) const { + PropertyInfo pi; + call_get_argument_type_info<P...>(p_arg, pi); + return pi; + } + +public: +#ifdef DEBUG_METHODS_ENABLED + virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { + return call_get_argument_metadata<P...>(p_arg); + } + +#endif + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + (void)p_object; // unused + call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments()); + return Variant(); + } + + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) { + (void)p_object; + (void)r_ret; + call_with_ptr_args_static_method(function, p_args); + } + + MethodBindTS(void (*p_function)(P...)) { + function = p_function; + _generate_argument_types(sizeof...(P)); + set_argument_count(sizeof...(P)); + _set_static(true); + } +}; + +template <class... P> +MethodBind *create_static_method_bind(void (*p_method)(P...)) { + MethodBind *a = memnew((MethodBindTS<P...>)(p_method)); + return a; +} + +// return + +template <class R, class... P> +class MethodBindTRS : public MethodBind { + R(*function) + (P...); + +protected: +// GCC raises warnings in the case P = {} as the comparison is always false... +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif + virtual Variant::Type _gen_argument_type(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + return call_get_argument_type<P...>(p_arg); + } else { + return GetTypeInfo<R>::VARIANT_TYPE; + } + } +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif + + virtual PropertyInfo _gen_argument_type_info(int p_arg) const { + if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { + PropertyInfo pi; + call_get_argument_type_info<P...>(p_arg, pi); + return pi; + } else { + return GetTypeInfo<R>::get_class_info(); + } + } + +public: +#ifdef DEBUG_METHODS_ENABLED + virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { + if (p_arg >= 0) { + return call_get_argument_metadata<P...>(p_arg); + } else { + return GetTypeInfo<R>::METADATA; + } + } + +#endif + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) { + Variant ret; + call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments()); + return ret; + } + + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) { + (void)p_object; + call_with_ptr_args_static_method_ret(function, p_args, r_ret); + } + + MethodBindTRS(R (*p_function)(P...)) { + function = p_function; + _generate_argument_types(sizeof...(P)); + set_argument_count(sizeof...(P)); + _set_static(true); + _set_returns(true); + } +}; + +template <class R, class... P> +MethodBind *create_static_method_bind(R (*p_method)(P...)) { + MethodBind *a = memnew((MethodBindTRS<R, P...>)(p_method)); + return a; +} + #endif // METHOD_BIND_H diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index f692a49ba1..a2b310ca82 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2405,7 +2405,8 @@ Additionally, other keywords can be included: "exp" for exponential range editing, "radians" for editing radian angles in degrees, "degrees" to hint at an angle and "noslider" to hide the slider. </constant> <constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint"> - Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code]. + Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string. + The hint string is a comma separated list of names such as [code]"Hello,Something,Else"[/code]. For integer and float properties, the first name in the list has value 0, the next 1, and so on. Explicit values can also be specified by appending [code]:integer[/code] to the name, e.g. [code]"Zero,One,Three:3,Four,Six:6"[/code]. </constant> <constant name="PROPERTY_HINT_ENUM_SUGGESTION" value="3" enum="PropertyHint"> Hints that a string property can be an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code]. diff --git a/doc/classes/File.xml b/doc/classes/File.xml index 29283e107d..0b4a8fa46e 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -74,7 +74,7 @@ [/codeblocks] </description> </method> - <method name="file_exists" qualifiers="const"> + <method name="file_exists" qualifiers="static"> <return type="bool" /> <argument index="0" name="path" type="String" /> <description> diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index e7358c0b80..ad77f4641d 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1866,7 +1866,6 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr if (err == OK && !so_files.is_empty()) { // If shared object files, copy them. - da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < so_files.size() && err == OK; i++) { String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path); String target_path; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 28feac5d2b..4bd4e073d7 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -288,17 +288,40 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = dark_icon_color_dictionary[Color::html("#5fff97")] = success_color; dark_icon_color_dictionary[Color::html("#ffdd65")] = warning_color; + // Use the accent color for some icons (checkbox, radio, toggle, etc.). + Dictionary accent_color_icon_color_dictionary; + Set<StringName> accent_color_icons; + + const Color accent_color = p_theme->get_color(SNAME("accent_color"), SNAME("Editor")); + accent_color_icon_color_dictionary[Color::html("699ce8")] = accent_color; + if (accent_color.get_luminance() > 0.75) { + accent_color_icon_color_dictionary[Color::html("ffffff")] = Color(0.2, 0.2, 0.2); + } + + accent_color_icons.insert("GuiChecked"); + accent_color_icons.insert("GuiRadioChecked"); + accent_color_icons.insert("GuiIndeterminate"); + accent_color_icons.insert("GuiToggleOn"); + accent_color_icons.insert("GuiToggleOnMirrored"); + accent_color_icons.insert("PlayOverlay"); + // Generate icons. if (!p_only_thumbs) { for (int i = 0; i < editor_icons_count; i++) { - float saturation = p_icon_saturation; + Ref<ImageTexture> icon; - if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) { - saturation = 1.0; - } + if (accent_color_icons.has(editor_icons_names[i])) { + icon = editor_generate_icon(i, true, EDSCALE, 1.0, accent_color_icon_color_dictionary); + } else { + float saturation = p_icon_saturation; + + if (strcmp(editor_icons_names[i], "DefaultProjectIcon") == 0 || strcmp(editor_icons_names[i], "Godot") == 0 || strcmp(editor_icons_names[i], "Logo") == 0) { + saturation = 1.0; + } - const int is_exception = exceptions.has(editor_icons_names[i]); - const Ref<ImageTexture> icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation, dark_icon_color_dictionary); + const int is_exception = exceptions.has(editor_icons_names[i]); + icon = editor_generate_icon(i, !is_exception, EDSCALE, saturation, dark_icon_color_dictionary); + } p_theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), icon); } @@ -514,8 +537,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Register icons + font - // The resolution and the icon color (dark_theme bool) has not changed, so we do not regenerate the icons. - if (p_theme != nullptr && fabs(p_theme->get_constant(SNAME("scale"), SNAME("Editor")) - EDSCALE) < 0.00001 && (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")) == dark_theme && prev_icon_saturation == icon_saturation) { + // The editor scale, icon color (dark_theme bool), icon saturation, and accent color has not changed, so we do not regenerate the icons. + if (p_theme != nullptr && fabs(p_theme->get_constant(SNAME("scale"), SNAME("Editor")) - EDSCALE) < 0.00001 && (bool)p_theme->get_constant(SNAME("dark_theme"), SNAME("Editor")) == dark_theme && prev_icon_saturation == icon_saturation && p_theme->get_color(SNAME("accent_color"), SNAME("Editor")) == accent_color) { // Register already generated icons. for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons"))); diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 1468d63daf..20bd145299 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -997,7 +997,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int hbc->add_theme_constant_override("separation", 5 * EDSCALE); Button *first = memnew(Button); - first->set_text(TTR("First")); + first->set_text(TTR("First", "Pagination")); if (p_page != 0) { first->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(0)); } else { @@ -1007,7 +1007,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int hbc->add_child(first); Button *prev = memnew(Button); - prev->set_text(TTR("Previous")); + prev->set_text(TTR("Previous", "Pagination")); if (p_page > 0) { prev->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page - 1)); } else { @@ -1037,7 +1037,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int } Button *next = memnew(Button); - next->set_text(TTR("Next")); + next->set_text(TTR("Next", "Pagination")); if (p_page < p_page_count - 1) { next->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page + 1)); } else { @@ -1048,7 +1048,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int hbc->add_child(next); Button *last = memnew(Button); - last->set_text(TTR("Last")); + last->set_text(TTR("Last", "Pagination")); if (p_page != p_page_count - 1) { last->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(p_page_count - 1)); } else { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index c12c1a43a3..d415684d10 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -827,10 +827,6 @@ Error GDScript::reload(bool p_keep_state) { if (basedir.begins_with(EditorSettings::get_singleton()->get_project_script_templates_dir())) { return OK; } -#else - if (source.contains("_BASE_")) { - return OK; - } #endif { diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index eea7ed89cc..d8f5b814e4 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -802,10 +802,13 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) { const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type); - String im_sig = "IntPtr " CS_PARAM_METHODBIND ", "; - String im_unique_sig = imethod.return_type.cname.operator String() + ",IntPtr,IntPtr"; + String im_sig = "IntPtr " CS_PARAM_METHODBIND; + String im_unique_sig = imethod.return_type.cname.operator String() + ",IntPtr"; - im_sig += "IntPtr " CS_PARAM_INSTANCE; + if (!imethod.is_static) { + im_sig += ", IntPtr " CS_PARAM_INSTANCE; + im_unique_sig += ",IntPtr"; + } // Get arguments information int i = 0; @@ -1733,8 +1736,10 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf String arguments_sig; String cs_in_statements; - String icall_params = method_bind_field + ", "; - icall_params += sformat(p_itype.cs_in, "this"); + String icall_params = method_bind_field; + if (!p_imethod.is_static) { + icall_params += ", " + sformat(p_itype.cs_in, "this"); + } StringBuilder default_args_doc; @@ -1892,7 +1897,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf p_output.append(MEMBER_BEGIN); p_output.append(p_imethod.is_internal ? "internal " : "public "); - if (p_itype.is_singleton) { + if (p_itype.is_singleton || p_imethod.is_static) { p_output.append("static "); } else if (p_imethod.is_virtual) { p_output.append("virtual "); @@ -2271,7 +2276,10 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte String argc_str = itos(p_imethod.arguments.size()); - String c_func_sig = "MethodBind* " CS_PARAM_METHODBIND ", " + p_itype.c_type_in + " " CS_PARAM_INSTANCE; + String c_func_sig = "MethodBind* " CS_PARAM_METHODBIND; + if (!p_imethod.is_static) { + c_func_sig += ", " + p_itype.c_type_in + " " CS_PARAM_INSTANCE; + } String c_in_statements; String c_args_var_content; @@ -2363,17 +2371,21 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte String fail_ret = return_type->c_type_out.ends_with("*") && !return_type->ret_as_byref_arg ? "nullptr" : return_type->c_type_out + "()"; - if (return_type->ret_as_byref_arg) { - p_output.append("\tif (" CS_PARAM_INSTANCE " == nullptr) { *arg_ret = "); - p_output.append(fail_ret); - p_output.append("; ERR_FAIL_MSG(\"Parameter ' " CS_PARAM_INSTANCE " ' is null.\"); }\n"); - } else { - p_output.append("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE ", "); - p_output.append(fail_ret); - p_output.append(");\n"); + if (!p_imethod.is_static) { + if (return_type->ret_as_byref_arg) { + p_output.append("\tif (" CS_PARAM_INSTANCE " == nullptr) { *arg_ret = "); + p_output.append(fail_ret); + p_output.append("; ERR_FAIL_MSG(\"Parameter ' " CS_PARAM_INSTANCE " ' is null.\"); }\n"); + } else { + p_output.append("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE ", "); + p_output.append(fail_ret); + p_output.append(");\n"); + } } } else { - p_output.append("\tERR_FAIL_NULL(" CS_PARAM_INSTANCE ");\n"); + if (!p_imethod.is_static) { + p_output.append("\tERR_FAIL_NULL(" CS_PARAM_INSTANCE ");\n"); + } } if (p_imethod.arguments.size()) { @@ -2417,7 +2429,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte } } - p_output.append(CS_PARAM_METHODBIND "->call(" CS_PARAM_INSTANCE ", "); + p_output.append(CS_PARAM_METHODBIND "->call("); + p_output.append(p_imethod.is_static ? "nullptr" : CS_PARAM_INSTANCE); + p_output.append(", "); p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ".ptr()" : "nullptr"); p_output.append(", total_length, vcall_error);\n"); @@ -2428,7 +2442,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte } } } else { - p_output.append("\t" CS_PARAM_METHODBIND "->ptrcall(" CS_PARAM_INSTANCE ", "); + p_output.append("\t" CS_PARAM_METHODBIND "->ptrcall("); + p_output.append(p_imethod.is_static ? "nullptr" : CS_PARAM_INSTANCE); + p_output.append(", "); p_output.append(p_imethod.arguments.size() ? C_LOCAL_PTRCALL_ARGS ", " : "nullptr, "); p_output.append(!ret_void ? "&" C_LOCAL_RET ");\n" : "nullptr);\n"); } @@ -2772,6 +2788,10 @@ bool BindingsGenerator::_populate_object_type_interfaces() { imethod.name = method_info.name; imethod.cname = cname; + if (method_info.flags & METHOD_FLAG_STATIC) { + imethod.is_static = true; + } + if (method_info.flags & METHOD_FLAG_VIRTUAL) { imethod.is_virtual = true; } diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index f601ffde2b..dec4fae8cd 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -137,6 +137,11 @@ class BindingsGenerator { bool is_vararg = false; /** + * Determines if the method is static. + */ + bool is_static = false; + + /** * Virtual methods ("virtual" as defined by the Godot API) are methods that by default do nothing, * but can be overridden by the user to add custom functionality. * e.g.: _ready, _process, etc. diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json index 35f864f01a..f72cde955a 100644 --- a/platform/javascript/package-lock.json +++ b/platform/javascript/package-lock.json @@ -1884,9 +1884,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "node_modules/mkdirp": { @@ -4444,9 +4444,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "mkdirp": { diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp index 043c0f464c..f79c68671c 100644 --- a/scene/gui/texture_progress_bar.cpp +++ b/scene/gui/texture_progress_bar.cpp @@ -629,26 +629,30 @@ void TextureProgressBar::_bind_methods() { ClassDB::bind_method(D_METHOD("set_nine_patch_stretch", "stretch"), &TextureProgressBar::set_nine_patch_stretch); ClassDB::bind_method(D_METHOD("get_nine_patch_stretch"), &TextureProgressBar::get_nine_patch_stretch); + ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom),Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "nine_patch_stretch"), "set_nine_patch_stretch", "get_nine_patch_stretch"); + + ADD_GROUP("Stretch Margin", "stretch_margin_"); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_LEFT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_TOP); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_RIGHT); + ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_BOTTOM); + ADD_GROUP("Textures", "texture_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_under", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_under_texture", "get_under_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_over", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_over_texture", "get_over_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_progress", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_progress_texture", "get_progress_texture"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "texture_progress_offset"), "set_texture_progress_offset", "get_texture_progress_offset"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "fill_mode", PROPERTY_HINT_ENUM, "Left to Right,Right to Left,Top to Bottom,Bottom to Top,Clockwise,Counter Clockwise,Bilinear (Left and Right),Bilinear (Top and Bottom),Clockwise and Counter Clockwise"), "set_fill_mode", "get_fill_mode"); + ADD_GROUP("Tint", "tint_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_under"), "set_tint_under", "get_tint_under"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_over"), "set_tint_over", "get_tint_over"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "tint_progress"), "set_tint_progress", "get_tint_progress"); + ADD_GROUP("Radial Fill", "radial_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radial_initial_angle", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_radial_initial_angle", "get_radial_initial_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radial_fill_degrees", PROPERTY_HINT_RANGE, "0.0,360.0,0.1,slider"), "set_fill_degrees", "get_fill_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "radial_center_offset"), "set_radial_center_offset", "get_radial_center_offset"); - ADD_GROUP("Stretch", "stretch_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "nine_patch_stretch"), "set_nine_patch_stretch", "get_nine_patch_stretch"); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_left", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_LEFT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_top", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_TOP); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_right", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_RIGHT); - ADD_PROPERTYI(PropertyInfo(Variant::INT, "stretch_margin_bottom", PROPERTY_HINT_RANGE, "0,16384,1"), "set_stretch_margin", "get_stretch_margin", SIDE_BOTTOM); BIND_ENUM_CONSTANT(FILL_LEFT_TO_RIGHT); BIND_ENUM_CONSTANT(FILL_RIGHT_TO_LEFT); diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp index 06f035a506..2cc60fc765 100644 --- a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp @@ -39,31 +39,37 @@ GodotBroadPhase2D::ID GodotBroadPhase2DBVH::create(GodotCollisionObject2D *p_obj } void GodotBroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { + ERR_FAIL_COND(!p_id); bvh.move(p_id - 1, p_aabb); } void GodotBroadPhase2DBVH::set_static(ID p_id, bool p_static) { + ERR_FAIL_COND(!p_id); uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase2DBVH::remove(ID p_id) { + ERR_FAIL_COND(!p_id); bvh.erase(p_id - 1); } GodotCollisionObject2D *GodotBroadPhase2DBVH::get_object(ID p_id) const { + ERR_FAIL_COND_V(!p_id, nullptr); GodotCollisionObject2D *it = bvh.get(p_id - 1); ERR_FAIL_COND_V(!it, nullptr); return it; } bool GodotBroadPhase2DBVH::is_static(ID p_id) const { + ERR_FAIL_COND_V(!p_id, false); uint32_t tree_id = bvh.get_tree_id(p_id - 1); return tree_id == 0; } int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { + ERR_FAIL_COND_V(!p_id, 0); return bvh.get_subindex(p_id - 1); } diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp index ecdf74fd41..b34f9d214f 100644 --- a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp @@ -40,31 +40,37 @@ GodotBroadPhase3DBVH::ID GodotBroadPhase3DBVH::create(GodotCollisionObject3D *p_ } void GodotBroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { + ERR_FAIL_COND(!p_id); bvh.move(p_id - 1, p_aabb); } void GodotBroadPhase3DBVH::set_static(ID p_id, bool p_static) { + ERR_FAIL_COND(!p_id); uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase3DBVH::remove(ID p_id) { + ERR_FAIL_COND(!p_id); bvh.erase(p_id - 1); } GodotCollisionObject3D *GodotBroadPhase3DBVH::get_object(ID p_id) const { + ERR_FAIL_COND_V(!p_id, nullptr); GodotCollisionObject3D *it = bvh.get(p_id - 1); ERR_FAIL_COND_V(!it, nullptr); return it; } bool GodotBroadPhase3DBVH::is_static(ID p_id) const { + ERR_FAIL_COND_V(!p_id, false); uint32_t tree_id = bvh.get_tree_id(p_id - 1); return tree_id == 0; } int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { + ERR_FAIL_COND_V(!p_id, 0); return bvh.get_subindex(p_id - 1); } |