diff options
Diffstat (limited to 'core/object')
-rw-r--r-- | core/object/class_db.cpp | 8 | ||||
-rw-r--r-- | core/object/make_virtuals.py | 2 | ||||
-rw-r--r-- | core/object/message_queue.cpp | 41 | ||||
-rw-r--r-- | core/object/message_queue.h | 43 | ||||
-rw-r--r-- | core/object/object.cpp | 52 | ||||
-rw-r--r-- | core/object/object.h | 43 | ||||
-rw-r--r-- | core/object/script_language.cpp | 14 | ||||
-rw-r--r-- | core/object/script_language.h | 20 | ||||
-rw-r--r-- | core/object/undo_redo.cpp | 49 | ||||
-rw-r--r-- | core/object/undo_redo.h | 30 |
10 files changed, 142 insertions, 160 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index c29316c089..4a71597f84 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1197,7 +1197,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const if (psg->_setptr) { psg->_setptr->call(p_object, arg, 2, ce); } else { - p_object->call(psg->setter, arg, 2, ce); + p_object->callp(psg->setter, arg, 2, ce); } } else { @@ -1205,7 +1205,7 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const if (psg->_setptr) { psg->_setptr->call(p_object, arg, 1, ce); } else { - p_object->call(psg->setter, arg, 1, ce); + p_object->callp(psg->setter, arg, 1, ce); } } @@ -1238,14 +1238,14 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia Variant index = psg->index; const Variant *arg[1] = { &index }; Callable::CallError ce; - r_value = p_object->call(psg->getter, arg, 1, ce); + r_value = p_object->callp(psg->getter, arg, 1, ce); } else { Callable::CallError ce; if (psg->_getptr) { r_value = psg->_getptr->call(p_object, nullptr, 0, ce); } else { - r_value = p_object->call(psg->getter, nullptr, 0, ce); + r_value = p_object->callp(psg->getter, nullptr, 0, ce); } } return true; diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 5de1b49026..552f2fa2bf 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -8,7 +8,7 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ if (script_instance) {\\ Callable::CallError ce; \\ $CALLSIARGS\\ - $CALLSIBEGINscript_instance->call(_gdvirtual_##m_name##_sn, $CALLSIARGPASS, ce);\\ + $CALLSIBEGINscript_instance->callp(_gdvirtual_##m_name##_sn, $CALLSIARGPASS, ce);\\ if (ce.error == Callable::CallError::CALL_OK) {\\ $CALLSIRET\\ return true;\\ diff --git a/core/object/message_queue.cpp b/core/object/message_queue.cpp index 3c828eabd9..79c36ac81f 100644 --- a/core/object/message_queue.cpp +++ b/core/object/message_queue.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/core_string_names.h" +#include "core/object/class_db.h" #include "core/object/script_language.h" MessageQueue *MessageQueue::singleton = nullptr; @@ -40,23 +41,8 @@ MessageQueue *MessageQueue::get_singleton() { return singleton; } -Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) { - return push_callable(Callable(p_id, p_method), p_args, p_argcount, p_show_error); -} - -Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - return push_call(p_id, p_method, argptr, argc, false); +Error MessageQueue::push_callp(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) { + return push_callablep(Callable(p_id, p_method), p_args, p_argcount, p_show_error); } Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value) { @@ -113,8 +99,8 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) { return OK; } -Error MessageQueue::push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) { - return push_call(p_object->get_instance_id(), p_method, VARIANT_ARG_PASS); +Error MessageQueue::push_callp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) { + return push_callp(p_object->get_instance_id(), p_method, p_args, p_argcount, p_show_error); } Error MessageQueue::push_notification(Object *p_object, int p_notification) { @@ -125,7 +111,7 @@ Error MessageQueue::push_set(Object *p_object, const StringName &p_prop, const V return push_set(p_object->get_instance_id(), p_prop, p_value); } -Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error) { +Error MessageQueue::push_callablep(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error) { _THREAD_SAFE_METHOD_ int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount; @@ -155,21 +141,6 @@ Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_ return OK; } -Error MessageQueue::push_callable(const Callable &p_callable, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - return push_callable(p_callable, argptr, argc); -} - void MessageQueue::statistics() { Map<StringName, int> set_count; Map<int, int> notify_count; diff --git a/core/object/message_queue.h b/core/object/message_queue.h index a4449cf473..eaab01d0aa 100644 --- a/core/object/message_queue.h +++ b/core/object/message_queue.h @@ -31,8 +31,11 @@ #ifndef MESSAGE_QUEUE_H #define MESSAGE_QUEUE_H -#include "core/object/class_db.h" +#include "core/object/object_id.h" #include "core/os/thread_safe.h" +#include "core/variant/variant.h" + +class Object; class MessageQueue { _THREAD_SAFE_CLASS_ @@ -73,14 +76,42 @@ class MessageQueue { public: static MessageQueue *get_singleton(); - Error push_call(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error = false); - Error push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_LIST); + Error push_callp(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error = false); + template <typename... VarArgs> + Error push_call(ObjectID p_id, const StringName &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]; + } + return push_callp(p_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + Error push_notification(ObjectID p_id, int p_notification); Error push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value); - Error push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error = false); - Error push_callable(const Callable &p_callable, VARIANT_ARG_LIST); + Error push_callablep(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error = false); + + template <typename... VarArgs> + Error push_callable(const Callable &p_callable, 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]; + } + return push_callablep(p_callable, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + + Error push_callp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error = false); + template <typename... VarArgs> + Error push_call(Object *p_object, const StringName &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]; + } + return push_callp(p_object, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } - Error push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST); Error push_notification(Object *p_object, int p_notification); Error push_set(Object *p_object, const StringName &p_prop, const Variant &p_value); diff --git a/core/object/object.cpp b/core/object/object.cpp index a8a49bd22e..387c765d73 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -679,7 +679,7 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::Cal StringName method = *p_args[0]; - return call(method, &p_args[1], p_argcount - 1, r_error); + return callp(method, &p_args[1], p_argcount - 1, r_error); } Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { @@ -700,7 +700,7 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Call StringName method = *p_args[0]; - MessageQueue::get_singleton()->push_call(get_instance_id(), method, &p_args[1], p_argcount - 1, true); + MessageQueue::get_singleton()->push_callp(get_instance_id(), method, &p_args[1], p_argcount - 1, true); return Variant(); } @@ -750,31 +750,14 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) { } Callable::CallError ce; - Variant ret = call(p_method, argptrs, p_args.size(), ce); + Variant ret = callp(p_method, argptrs, p_args.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + "."); } return ret; } -Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - Callable::CallError error; - - Variant ret = call(p_name, argptr, argc, error); - return ret; -} - -Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { +Variant Object::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_OK; if (p_method == CoreStringNames::get_singleton()->_free) { @@ -808,7 +791,7 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a OBJ_DEBUG_LOCK if (script_instance) { - ret = script_instance->call(p_method, p_args, p_argcount, r_error); + ret = script_instance->callp(p_method, p_args, p_argcount, r_error); //force jumptable switch (r_error.error) { case Callable::CallError::CALL_OK: @@ -1027,12 +1010,12 @@ Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::C args = &p_args[1]; } - emit_signal(signal, args, argc); + emit_signalp(signal, args, argc); return Variant(); } -Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int p_argcount) { +Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount) { if (_block_signals) { return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked } @@ -1091,7 +1074,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int } if (c.flags & CONNECT_DEFERRED) { - MessageQueue::get_singleton()->push_callable(c.callable, args, argc, true); + MessageQueue::get_singleton()->push_callablep(c.callable, args, argc, true); } else { Callable::CallError ce; _emitting = true; @@ -1139,21 +1122,6 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int return err; } -Error Object::emit_signal(const StringName &p_name, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - - int argc = 0; - - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - return emit_signal(p_name, argptr, argc); -} - void Object::_add_user_signal(const String &p_name, const Array &p_args) { // this version of add_user_signal is meant to be used from scripts or external apis // without access to ADD_SIGNAL in bind_methods @@ -1648,10 +1616,6 @@ void Object::_bind_methods() { BIND_ENUM_CONSTANT(CONNECT_REFERENCE_COUNTED); } -void Object::call_deferred(const StringName &p_method, VARIANT_ARG_DECLARE) { - MessageQueue::get_singleton()->push_call(this, p_method, VARIANT_ARG_PASS); -} - void Object::set_deferred(const StringName &p_property, const Variant &p_value) { MessageQueue::get_singleton()->push_set(this, p_property, p_value); } diff --git a/core/object/object.h b/core/object/object.h index b5be1cf0e7..8a8b6b5487 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -32,6 +32,7 @@ #define OBJECT_H #include "core/extension/gdnative_interface.h" +#include "core/object/message_queue.h" #include "core/object/object_id.h" #include "core/os/rw_lock.h" #include "core/os/spin_lock.h" @@ -44,14 +45,6 @@ #include "core/variant/callable_bind.h" #include "core/variant/variant.h" -#define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant() -#define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5, p_arg6, p_arg7, p_arg8 -#define VARIANT_ARG_DECLARE const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8 -#define VARIANT_ARG_MAX 8 -#define VARIANT_ARGPTRS const Variant *argptr[8] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5, &p_arg6, &p_arg7, &p_arg8 }; -#define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7] - enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range. @@ -734,8 +727,18 @@ public: bool has_method(const StringName &p_method) const; void get_method_list(List<MethodInfo> *p_list) const; Variant callv(const StringName &p_method, const Array &p_args); - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + + template <typename... VarArgs> + Variant call(const StringName &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]; + } + Callable::CallError cerr; + return callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), cerr); + } void notification(int p_notification, bool p_reversed = false); virtual String to_string(); @@ -769,8 +772,18 @@ public: void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance); void add_user_signal(const MethodInfo &p_signal); - Error emit_signal(const StringName &p_name, VARIANT_ARG_LIST); - Error emit_signal(const StringName &p_name, const Variant **p_args, int p_argcount); + + template <typename... VarArgs> + Error emit_signal(const StringName &p_name, 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]; + } + return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + + Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount); bool has_signal(const StringName &p_name) const; void get_signal_list(List<MethodInfo> *p_signals) const; void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const; @@ -782,7 +795,11 @@ public: void disconnect(const StringName &p_signal, const Callable &p_callable); bool is_connected(const StringName &p_signal, const Callable &p_callable) const; - void call_deferred(const StringName &p_method, VARIANT_ARG_LIST); + template <typename... VarArgs> + void call_deferred(const StringName &p_name, VarArgs... p_args) { + MessageQueue::get_singleton()->push_call(this, p_name, p_args...); + } + void set_deferred(const StringName &p_property, const Variant &p_value); void set_block_signals(bool p_block); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index b14296b815..11440c37fe 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -310,20 +310,6 @@ void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) } } -Variant ScriptInstance::call(const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS; - int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (argptr[i]->get_type() == Variant::NIL) { - break; - } - argc++; - } - - Callable::CallError error; - return call(p_method, argptr, argc, error); -} - void ScriptInstance::property_set_fallback(const StringName &, const Variant &, bool *r_valid) { if (r_valid) { *r_valid = false; diff --git a/core/object/script_language.h b/core/object/script_language.h index 4b18d9a5e8..2122f785b6 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -176,8 +176,20 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const = 0; virtual bool has_method(const StringName &p_method) const = 0; - virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST); - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0; + + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) = 0; + + template <typename... VarArgs> + Variant call(const StringName &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]; + } + Callable::CallError cerr; + return callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), cerr); + } + virtual void notification(int p_notification) = 0; virtual String to_string(bool *r_valid) { if (r_valid) { @@ -419,8 +431,8 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, VARIANT_ARG_LIST) { return Variant(); } - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { + + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index b78328fb42..f7a12a7528 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -126,8 +126,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { force_keep_in_merge_ends = false; } -void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS +void UndoRedo::add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { ERR_FAIL_COND(p_object == nullptr); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); @@ -140,14 +139,13 @@ void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIA do_op.type = Operation::TYPE_METHOD; do_op.name = p_method; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - do_op.args[i] = *argptr[i]; + for (int i = 0; i < p_argcount; i++) { + do_op.args.push_back(*p_args[i]); } actions.write[current_action + 1].do_ops.push_back(do_op); } -void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) { - VARIANT_ARGPTRS +void UndoRedo::add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { ERR_FAIL_COND(p_object == nullptr); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); @@ -167,8 +165,8 @@ void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VAR undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; undo_op.name = p_method; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - undo_op.args[i] = *argptr[i]; + for (int i = 0; i < p_argcount; i++) { + undo_op.args.push_back(*p_args[i]); } actions.write[current_action + 1].undo_ops.push_back(undo_op); } @@ -185,7 +183,7 @@ void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, c do_op.type = Operation::TYPE_PROPERTY; do_op.name = p_property; - do_op.args[0] = p_value; + do_op.args.push_back(p_value); actions.write[current_action + 1].do_ops.push_back(do_op); } @@ -208,7 +206,7 @@ void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, undo_op.type = Operation::TYPE_PROPERTY; undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; undo_op.name = p_property; - undo_op.args[0] = p_value; + undo_op.args.push_back(p_value); actions.write[current_action + 1].undo_ops.push_back(undo_op); } @@ -315,20 +313,15 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) { switch (op.type) { case Operation::TYPE_METHOD: { Vector<const Variant *> argptrs; - argptrs.resize(VARIANT_ARG_MAX); + argptrs.resize(op.args.size()); int argc = 0; - for (int i = 0; i < VARIANT_ARG_MAX; i++) { - if (op.args[i].get_type() == Variant::NIL) { - break; - } + for (int i = 0; i < op.args.size(); i++) { argptrs.write[i] = &op.args[i]; - argc++; } - argptrs.resize(argc); Callable::CallError ce; - obj->call(op.name, (const Variant **)argptrs.ptr(), argc, ce); + obj->callp(op.name, (const Variant **)argptrs.ptr(), argc, ce); if (ce.error != Callable::CallError::CALL_OK) { ERR_PRINT("Error calling method from signal '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, (const Variant **)argptrs.ptr(), argc, ce)); } @@ -341,7 +334,7 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) { #endif if (method_callback) { - method_callback(method_callbck_ud, obj, op.name, VARIANT_ARGS_FROM_ARRAY(op.args)); + method_callback(method_callbck_ud, obj, op.name, (const Variant **)argptrs.ptr(), argc); } } break; case Operation::TYPE_PROPERTY: { @@ -477,14 +470,7 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callabl Object *object = *p_args[0]; StringName method = *p_args[1]; - Variant v[VARIANT_ARG_MAX]; - - for (int i = 0; i < MIN(VARIANT_ARG_MAX, p_argcount - 2); ++i) { - v[i] = *p_args[i + 2]; - } - - static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8"); - add_do_method(object, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); + add_do_methodp(object, method, p_args + 2, p_argcount - 2); return Variant(); } @@ -514,14 +500,7 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla Object *object = *p_args[0]; StringName method = *p_args[1]; - Variant v[VARIANT_ARG_MAX]; - - for (int i = 0; i < MIN(VARIANT_ARG_MAX, p_argcount - 2); ++i) { - v[i] = *p_args[i + 2]; - } - - static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8"); - add_undo_method(object, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); + add_undo_methodp(object, method, p_args + 2, p_argcount - 2); return Variant(); } diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index 5eede74e2d..8871a549f8 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -49,7 +49,7 @@ public: Variant _add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error); - typedef void (*MethodNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE); + typedef void (*MethodNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount); typedef void (*PropertyNotifyCallback)(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value); private: @@ -65,7 +65,7 @@ private: Ref<RefCounted> ref; ObjectID object; StringName name; - Variant args[VARIANT_ARG_MAX]; + Vector<Variant> args; void delete_reference(); }; @@ -106,8 +106,30 @@ protected: public: void create_action(const String &p_name = "", MergeMode p_mode = MERGE_DISABLE); - void add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST); - void add_undo_method(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST); + void add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount); + void add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount); + + template <typename... VarArgs> + void add_do_method(Object *p_object, const StringName &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]; + } + + add_do_methodp(p_object, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + template <typename... VarArgs> + void add_undo_method(Object *p_object, const StringName &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]; + } + + add_undo_methodp(p_object, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + void add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value); void add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value); void add_do_reference(Object *p_object); |