summaryrefslogtreecommitdiffstats
path: root/core/object
diff options
context:
space:
mode:
Diffstat (limited to 'core/object')
-rw-r--r--core/object/callable_method_pointer.cpp22
-rw-r--r--core/object/class_db.cpp4
-rw-r--r--core/object/class_db.h4
-rw-r--r--core/object/message_queue.cpp51
-rw-r--r--core/object/object.h10
-rw-r--r--core/object/script_language.h1
6 files changed, 53 insertions, 39 deletions
diff --git a/core/object/callable_method_pointer.cpp b/core/object/callable_method_pointer.cpp
index b53985e6b7..ed400788b1 100644
--- a/core/object/callable_method_pointer.cpp
+++ b/core/object/callable_method_pointer.cpp
@@ -38,13 +38,10 @@ bool CallableCustomMethodPointerBase::compare_equal(const CallableCustom *p_a, c
return false;
}
- for (uint32_t i = 0; i < a->comp_size; i++) {
- if (a->comp_ptr[i] != b->comp_ptr[i]) {
- return false;
- }
- }
-
- return true;
+ // Avoid sorting by memory address proximity, which leads to unpredictable performance over time
+ // due to the reuse of old addresses for newer objects. Use byte-wise comparison to leverage the
+ // backwards encoding of little-endian systems as a way to decouple spatiality and time.
+ return memcmp(a->comp_ptr, b->comp_ptr, a->comp_size * 4) == 0;
}
bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
@@ -55,15 +52,8 @@ bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, co
return a->comp_size < b->comp_size;
}
- for (uint32_t i = 0; i < a->comp_size; i++) {
- if (a->comp_ptr[i] == b->comp_ptr[i]) {
- continue;
- }
-
- return a->comp_ptr[i] < b->comp_ptr[i];
- }
-
- return false;
+ // See note in compare_equal().
+ return memcmp(a->comp_ptr, b->comp_ptr, a->comp_size * 4) < 0;
}
CallableCustom::CompareEqualFunc CallableCustomMethodPointerBase::get_compare_equal_func() const {
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index cc4a29164d..c8c50fb957 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -53,7 +53,7 @@ MethodDefinition D_METHODP(const char *p_name, const char *const **p_args, uint3
#endif
ClassDB::APIType ClassDB::current_api = API_CORE;
-HashMap<ClassDB::APIType, uint64_t> ClassDB::api_hashes_cache;
+HashMap<ClassDB::APIType, uint32_t> ClassDB::api_hashes_cache;
void ClassDB::set_current_api(APIType p_api) {
DEV_ASSERT(!api_hashes_cache.has(p_api)); // This API type may not be suitable for caching of hash if it can change later.
@@ -163,7 +163,7 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
return ti->api;
}
-uint64_t ClassDB::get_api_hash(APIType p_api) {
+uint32_t ClassDB::get_api_hash(APIType p_api) {
OBJTYPE_RLOCK;
#ifdef DEBUG_METHODS_ENABLED
diff --git a/core/object/class_db.h b/core/object/class_db.h
index ce64336a45..3aae3b452e 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -155,7 +155,7 @@ public:
#endif
static APIType current_api;
- static HashMap<APIType, uint64_t> api_hashes_cache;
+ static HashMap<APIType, uint32_t> api_hashes_cache;
static void _add_class2(const StringName &p_class, const StringName &p_inherits);
@@ -246,7 +246,7 @@ public:
static APIType get_api_type(const StringName &p_class);
- static uint64_t get_api_hash(APIType p_api);
+ static uint32_t get_api_hash(APIType p_api);
template <typename>
struct member_function_traits;
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index 506f8291eb..dd7aba1384 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -35,6 +35,10 @@
#include "core/object/class_db.h"
#include "core/object/script_language.h"
+#ifdef DEBUG_ENABLED
+#include "core/config/engine.h"
+#endif
+
#ifdef DEV_ENABLED
// Includes sanity checks to ensure that a queue set as a thread singleton override
// is only ever called from the thread it was set for.
@@ -316,25 +320,34 @@ Error CallQueue::flush() {
Object *target = message->callable.get_object();
UNLOCK_MUTEX;
-
- switch (message->type & FLAG_MASK) {
- case TYPE_CALL: {
- if (target || (message->type & FLAG_NULL_IS_OK)) {
- Variant *args = (Variant *)(message + 1);
- _call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
- }
- } break;
- case TYPE_NOTIFICATION: {
- if (target) {
- target->notification(message->notification);
- }
- } break;
- case TYPE_SET: {
- if (target) {
- Variant *arg = (Variant *)(message + 1);
- target->set(message->callable.get_method(), *arg);
- }
- } break;
+#ifdef DEBUG_ENABLED
+ if (!message->callable.is_valid()) {
+ // The editor would cause many of these.
+ if (!Engine::get_singleton()->is_editor_hint()) {
+ ERR_PRINT("Trying to execute a deferred call/notification/set on a previously freed instance. Consider using queue_free() instead of free().");
+ }
+ } else
+#endif
+ {
+ switch (message->type & FLAG_MASK) {
+ case TYPE_CALL: {
+ if (target || (message->type & FLAG_NULL_IS_OK)) {
+ Variant *args = (Variant *)(message + 1);
+ _call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
+ }
+ } break;
+ case TYPE_NOTIFICATION: {
+ if (target) {
+ target->notification(message->notification);
+ }
+ } break;
+ case TYPE_SET: {
+ if (target) {
+ Variant *arg = (Variant *)(message + 1);
+ target->set(message->callable.get_method(), *arg);
+ }
+ } break;
+ }
}
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
diff --git a/core/object/object.h b/core/object/object.h
index a3e9d025ea..318dbf98de 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -430,6 +430,9 @@ protected:
_FORCE_INLINE_ static void (*_get_bind_methods())() { \
return &m_class::_bind_methods; \
} \
+ _FORCE_INLINE_ static void (*_get_bind_compatibility_methods())() { \
+ return &m_class::_bind_compatibility_methods; \
+ } \
\
public: \
static void initialize_class() { \
@@ -442,6 +445,9 @@ public:
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
_bind_methods(); \
} \
+ if (m_class::_get_bind_compatibility_methods() != m_inherits::_get_bind_compatibility_methods()) { \
+ _bind_compatibility_methods(); \
+ } \
initialized = true; \
} \
\
@@ -674,6 +680,7 @@ protected:
virtual void _notificationv(int p_notification, bool p_reversed) {}
static void _bind_methods();
+ static void _bind_compatibility_methods() {}
bool _set(const StringName &p_name, const Variant &p_property) { return false; };
bool _get(const StringName &p_name, Variant &r_property) const { return false; };
void _get_property_list(List<PropertyInfo> *p_list) const {};
@@ -685,6 +692,9 @@ protected:
_FORCE_INLINE_ static void (*_get_bind_methods())() {
return &Object::_bind_methods;
}
+ _FORCE_INLINE_ static void (*_get_bind_compatibility_methods())() {
+ return &Object::_bind_compatibility_methods;
+ }
_FORCE_INLINE_ bool (Object::*_get_get() const)(const StringName &p_name, Variant &r_ret) const {
return &Object::_get;
}
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 2b685c77a3..3ea6a6e4c3 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -263,6 +263,7 @@ public:
};
struct ScriptError {
+ String path;
int line = -1;
int column = -1;
String message;