diff options
author | David Snopek <dsnopek@gmail.com> | 2023-11-17 13:18:19 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-17 13:18:19 -0600 |
commit | 8d17966e81e60f9a899a02e04349bf2e01c6391a (patch) | |
tree | 53d39ba39ca910536d2cda4ef5b5db3e47630a04 /src/variant/callable_method_pointer.cpp | |
parent | 4439a4a569b641934a0e1c2320c11b5bb7c61fa7 (diff) | |
parent | f426b12b5bc16689c4d06717fe276fafa9741280 (diff) | |
download | redot-cpp-8d17966e81e60f9a899a02e04349bf2e01c6391a.tar.gz |
Merge pull request #1294 from dsnopek/is-connected
Fix comparison of `Callable`s from `callable_mp()` of the same method
Diffstat (limited to 'src/variant/callable_method_pointer.cpp')
-rw-r--r-- | src/variant/callable_method_pointer.cpp | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/src/variant/callable_method_pointer.cpp b/src/variant/callable_method_pointer.cpp index 10f2920..520ed05 100644 --- a/src/variant/callable_method_pointer.cpp +++ b/src/variant/callable_method_pointer.cpp @@ -30,18 +30,66 @@ #include <godot_cpp/variant/callable_method_pointer.hpp> +#include <godot_cpp/templates/hashfuncs.hpp> + namespace godot { -static void custom_callable_mp_call(void *userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) { - CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)userdata; +static void custom_callable_mp_call(void *p_userdata, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) { + CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata; callable_method_pointer->call((const Variant **)p_args, p_argument_count, *(Variant *)r_return, *r_error); } -static void custom_callable_mp_free(void *userdata) { - CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)userdata; +static GDExtensionBool custom_callable_mp_is_valid(void *p_userdata) { + CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata; + ObjectID object = callable_method_pointer->get_object(); + return object == ObjectID() || ObjectDB::get_instance(object); +} + +static void custom_callable_mp_free(void *p_userdata) { + CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata; memdelete(callable_method_pointer); } +static uint32_t custom_callable_mp_hash(void *p_userdata) { + CallableCustomMethodPointerBase *callable_method_pointer = (CallableCustomMethodPointerBase *)p_userdata; + return callable_method_pointer->get_hash(); +} + +static GDExtensionBool custom_callable_mp_equal_func(void *p_a, void *p_b) { + CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a; + CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b; + + if (a->get_comp_size() != b->get_comp_size()) { + return false; + } + + return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) == 0; +} + +static GDExtensionBool custom_callable_mp_less_than_func(void *p_a, void *p_b) { + CallableCustomMethodPointerBase *a = (CallableCustomMethodPointerBase *)p_a; + CallableCustomMethodPointerBase *b = (CallableCustomMethodPointerBase *)p_b; + + if (a->get_comp_size() != b->get_comp_size()) { + return a->get_comp_size() < b->get_comp_size(); + } + + return memcmp(a->get_comp_ptr(), b->get_comp_ptr(), a->get_comp_size() * 4) < 0; +} + +void CallableCustomMethodPointerBase::_setup(uint32_t *p_base_ptr, uint32_t p_ptr_size) { + comp_ptr = p_base_ptr; + comp_size = p_ptr_size / 4; + + for (uint32_t i = 0; i < comp_size; i++) { + if (i == 0) { + h = hash_murmur3_one_32(comp_ptr[i]); + } else { + h = hash_murmur3_one_32(comp_ptr[i], h); + } + } +} + namespace internal { Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_method_pointer) { @@ -50,7 +98,11 @@ Callable create_callable_from_ccmp(CallableCustomMethodPointerBase *p_callable_m info.token = internal::token; info.object_id = p_callable_method_pointer->get_object(); info.call_func = &custom_callable_mp_call; + info.is_valid_func = &custom_callable_mp_is_valid; info.free_func = &custom_callable_mp_free; + info.hash_func = &custom_callable_mp_hash; + info.equal_func = &custom_callable_mp_equal_func; + info.less_than_func = &custom_callable_mp_less_than_func; Callable callable; ::godot::internal::gdextension_interface_callable_custom_create(callable._native_ptr(), &info); |