summaryrefslogtreecommitdiff
path: root/core/object
diff options
context:
space:
mode:
Diffstat (limited to 'core/object')
-rw-r--r--core/object/class_db.h29
-rw-r--r--core/object/message_queue.cpp12
-rw-r--r--core/object/method_bind.h4
-rw-r--r--core/object/script_language.cpp18
-rw-r--r--core/object/script_language.h4
5 files changed, 54 insertions, 13 deletions
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 0e408e8845..0b62cf40f7 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -40,6 +40,8 @@
#include "core/object/callable_method_pointer.h"
#include "core/templates/hash_set.h"
+#include <type_traits>
+
#define DEFVAL(m_defval) (m_defval)
#ifdef DEBUG_METHODS_ENABLED
@@ -241,6 +243,24 @@ public:
static uint64_t get_api_hash(APIType p_api);
+ template <typename>
+ struct member_function_traits;
+
+ template <typename R, typename T, typename... Args>
+ struct member_function_traits<R (T::*)(Args...)> {
+ using return_type = R;
+ };
+
+ template <typename R, typename T, typename... Args>
+ struct member_function_traits<R (T::*)(Args...) const> {
+ using return_type = R;
+ };
+
+ template <typename R, typename... Args>
+ struct member_function_traits<R (*)(Args...)> {
+ using return_type = R;
+ };
+
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.
@@ -249,6 +269,9 @@ public:
argptrs[i] = &args[i];
}
MethodBind *bind = create_method_bind(p_method);
+ if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ bind->set_return_type_is_raw_object_ptr(true);
+ }
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
@@ -261,6 +284,9 @@ public:
}
MethodBind *bind = create_static_method_bind(p_method);
bind->set_instance_class(p_class);
+ if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ bind->set_return_type_is_raw_object_ptr(true);
+ }
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
@@ -273,6 +299,9 @@ public:
bind->set_name(p_name);
bind->set_default_arguments(p_default_args);
+ if constexpr (std::is_same<typename member_function_traits<M>::return_type, Object *>::value) {
+ bind->set_return_type_is_raw_object_ptr(true);
+ }
String instance_type = bind->get_instance_class();
diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp
index ebed6c21e9..decf030e27 100644
--- a/core/object/message_queue.cpp
+++ b/core/object/message_queue.cpp
@@ -55,9 +55,9 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
if (ObjectDB::get_instance(p_id)) {
type = ObjectDB::get_instance(p_id)->get_class();
}
- print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id));
+ ERR_PRINT("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
statistics();
- ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
+ return ERR_OUT_OF_MEMORY;
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
@@ -82,9 +82,9 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
uint8_t room_needed = sizeof(Message);
if ((buffer_end + room_needed) >= buffer_size) {
- print_line("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id));
+ ERR_PRINT("Failed notification: " + itos(p_notification) + " target ID: " + itos(p_id) + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
statistics();
- ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
+ return ERR_OUT_OF_MEMORY;
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
@@ -117,9 +117,9 @@ Error MessageQueue::push_callablep(const Callable &p_callable, const Variant **p
int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
if ((buffer_end + room_needed) >= buffer_size) {
- print_line("Failed method: " + p_callable);
+ ERR_PRINT("Failed method: " + p_callable + ". Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
statistics();
- ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
+ return ERR_OUT_OF_MEMORY;
}
Message *msg = memnew_placement(&buffer[buffer_end], Message);
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index 8334a7eef6..d37479f45b 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -49,6 +49,7 @@ class MethodBind {
bool _static = false;
bool _const = false;
bool _returns = false;
+ bool _returns_raw_obj_ptr = false;
protected:
Variant::Type *argument_types = nullptr;
@@ -121,6 +122,9 @@ public:
_FORCE_INLINE_ bool has_return() const { return _returns; }
virtual bool is_vararg() const { return false; }
+ _FORCE_INLINE_ bool is_return_type_raw_object_ptr() { return _returns_raw_obj_ptr; }
+ _FORCE_INLINE_ void set_return_type_is_raw_object_ptr(bool p_returns_raw_obj) { _returns_raw_obj_ptr = p_returns_raw_obj; }
+
void set_default_arguments(const Vector<Variant> &p_defargs);
uint32_t get_hash() const;
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 1d53cf66d4..71f40660f4 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -165,22 +165,30 @@ ScriptLanguage *ScriptServer::get_language(int p_idx) {
return _languages[p_idx];
}
-void ScriptServer::register_language(ScriptLanguage *p_language) {
- ERR_FAIL_NULL(p_language);
- ERR_FAIL_COND(_language_count >= MAX_LANGUAGES);
+Error ScriptServer::register_language(ScriptLanguage *p_language) {
+ ERR_FAIL_NULL_V(p_language, ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V_MSG(_language_count >= MAX_LANGUAGES, ERR_UNAVAILABLE, "Script languages limit has been reach, cannot register more.");
+ for (int i = 0; i < _language_count; i++) {
+ const ScriptLanguage *other_language = _languages[i];
+ ERR_FAIL_COND_V_MSG(other_language->get_extension() == p_language->get_extension(), ERR_ALREADY_EXISTS, "A script language with extension '" + p_language->get_extension() + "' is already registered.");
+ ERR_FAIL_COND_V_MSG(other_language->get_name() == p_language->get_name(), ERR_ALREADY_EXISTS, "A script language with name '" + p_language->get_name() + "' is already registered.");
+ ERR_FAIL_COND_V_MSG(other_language->get_type() == p_language->get_type(), ERR_ALREADY_EXISTS, "A script language with type '" + p_language->get_type() + "' is already registered.");
+ }
_languages[_language_count++] = p_language;
+ return OK;
}
-void ScriptServer::unregister_language(const ScriptLanguage *p_language) {
+Error ScriptServer::unregister_language(const ScriptLanguage *p_language) {
for (int i = 0; i < _language_count; i++) {
if (_languages[i] == p_language) {
_language_count--;
if (i < _language_count) {
SWAP(_languages[i], _languages[_language_count]);
}
- return;
+ return OK;
}
}
+ return ERR_DOES_NOT_EXIST;
}
void ScriptServer::init_languages() {
diff --git a/core/object/script_language.h b/core/object/script_language.h
index 14cc30e029..3ef121a8e7 100644
--- a/core/object/script_language.h
+++ b/core/object/script_language.h
@@ -70,8 +70,8 @@ public:
static bool is_scripting_enabled();
_FORCE_INLINE_ static int get_language_count() { return _language_count; }
static ScriptLanguage *get_language(int p_idx);
- static void register_language(ScriptLanguage *p_language);
- static void unregister_language(const ScriptLanguage *p_language);
+ static Error register_language(ScriptLanguage *p_language);
+ static Error unregister_language(const ScriptLanguage *p_language);
static void set_reload_scripts_on_save(bool p_enable);
static bool is_reload_scripts_on_save_enabled();