Merge pull request #58929 from reduz/remove-variant-arg-macros

Remove VARIANT_ARG* macros
This commit is contained in:
Rémi Verschelde 2022-03-09 20:48:45 +01:00 committed by GitHub
commit 33c907f9f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 417 additions and 467 deletions

View file

@ -80,7 +80,7 @@ static void gdnative_variant_call(GDNativeVariantPtr p_self, const GDNativeStrin
const Variant **args = (const Variant **)p_args;
Variant ret;
Callable::CallError error;
self->call(*method, args, p_argcount, ret, error);
self->callp(*method, args, p_argcount, ret, error);
memnew_placement(r_return, Variant(ret));
if (r_error) {
@ -152,7 +152,7 @@ static void gdnative_variant_set_indexed(GDNativeVariantPtr p_self, GDNativeInt
bool valid;
bool oob;
self->set_indexed(p_index, value, valid, oob);
self->set_indexed(p_index, *value, valid, oob);
*r_valid = valid;
*r_oob = oob;
}

View file

@ -1440,7 +1440,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
}
Callable::CallError ce;
base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = vformat(RTR("On call to '%s':"), String(call->method));

View file

@ -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;

View file

@ -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;\\

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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);

View file

@ -182,7 +182,7 @@ struct VariantCasterAndValidate {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
r_error.expected = argtype;
@ -197,7 +197,7 @@ struct VariantCasterAndValidate<T &> {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
r_error.expected = argtype;
@ -212,7 +212,7 @@ struct VariantCasterAndValidate<const T &> {
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype) ||
!VariantObjectClassChecker<T>::check(p_args[p_arg_idx])) {
!VariantObjectClassChecker<T>::check(*p_args[p_arg_idx])) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = p_arg_idx;
r_error.expected = argtype;

View file

@ -37,7 +37,7 @@
#include "core/object/script_language.h"
void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const {
MessageQueue::get_singleton()->push_callable(*this, p_arguments, p_argcount);
MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount);
}
void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
@ -59,7 +59,7 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu
return;
}
#endif
r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error);
r_return_value = obj->callp(method, p_arguments, p_argcount, r_call_error);
}
}
@ -379,7 +379,7 @@ Error Signal::emit(const Variant **p_arguments, int p_argcount) const {
return ERR_INVALID_DATA;
}
return obj->emit_signal(name, p_arguments, p_argcount);
return obj->emit_signalp(name, p_arguments, p_argcount);
}
Error Signal::connect(const Callable &p_callable, uint32_t p_flags) {

View file

@ -1972,7 +1972,7 @@ Variant::operator ::RID() const {
}
#endif
Callable::CallError ce;
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce);
Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::RID) {
return ret;
}
@ -3309,21 +3309,7 @@ bool Variant::is_shared() const {
return false;
}
Variant Variant::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;
Variant ret;
call(p_method, argptr, argc, ret, error);
void Variant::_variant_call_error(const String &p_method, Callable::CallError &error) {
switch (error.error) {
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'.";
@ -3341,8 +3327,6 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
default: {
}
}
return ret;
}
void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) {

View file

@ -282,6 +282,14 @@ private:
static void _register_variant_utility_functions();
static void _unregister_variant_utility_functions();
void _variant_call_error(const String &p_method, Callable::CallError &error);
// Avoid accidental conversion. If you reached this point, it's because you most likely forgot to dereference
// a Variant pointer (so add * like this: *variant_pointer).
Variant(const Variant *) {}
Variant(const Variant **) {}
public:
_FORCE_INLINE_ Type get_type() const {
return type;
@ -527,8 +535,23 @@ public:
static int get_builtin_method_count(Variant::Type p_type);
static uint32_t get_builtin_method_hash(Variant::Type p_type, const StringName &p_method);
void call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);
Variant call(const StringName &p_method, 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());
void callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, 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;
Variant ret;
callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), ret, cerr);
if (cerr.error != Callable::CallError::CALL_OK) {
_variant_call_error(p_method, cerr);
}
return ret;
}
static void call_static(Variant::Type p_type, const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error);

View file

@ -1003,7 +1003,7 @@ static void register_builtin_method(const Vector<String> &p_argnames, const Vect
builtin_method_names[T::get_base_type()].push_back(name);
}
void Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
void Variant::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
if (type == Variant::OBJECT) {
//call object
Object *obj = _get_obj().obj;
@ -1018,7 +1018,7 @@ void Variant::call(const StringName &p_method, const Variant **p_args, int p_arg
}
#endif
r_ret = _get_obj().obj->call(p_method, p_args, p_argcount, r_error);
r_ret = _get_obj().obj->callp(p_method, p_args, p_argcount, r_error);
//else if (type==Variant::METHOD) {
} else {

View file

@ -1277,7 +1277,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_init, refp, 1, ce);
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
valid = false;
@ -1504,7 +1504,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
ref.push_back(r_iter);
Variant vref = ref;
const Variant *refp[] = { &vref };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_next, refp, 1, ce);
if (ref.size() != 1 || ce.error != Callable::CallError::CALL_OK) {
valid = false;
@ -1686,7 +1686,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
Callable::CallError ce;
ce.error = Callable::CallError::CALL_OK;
const Variant *refp[] = { &r_iter };
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
Variant ret = _get_obj().obj->callp(CoreStringNames::get_singleton()->_iter_get, refp, 1, ce);
if (ce.error != Callable::CallError::CALL_OK) {
r_valid = false;

View file

@ -606,8 +606,7 @@ public:
} break;
case Animation::TYPE_METHOD: {
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "name"));
static_assert(VARIANT_ARG_MAX == 8, "PROPERTY_HINT_RANGE needs to be updated if VARIANT_ARG_MAX != 8");
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,8,1"));
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,32,1,or_greater"));
Dictionary d = animation->track_get_key_value(track, key);
ERR_FAIL_COND(!d.has("args"));
@ -1287,8 +1286,8 @@ public:
} break;
case Animation::TYPE_METHOD: {
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "name"));
static_assert(VARIANT_ARG_MAX == 8, "PROPERTY_HINT_RANGE needs to be updated if VARIANT_ARG_MAX != 8");
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,8,1"));
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,32,1,or_greater"));
Dictionary d = animation->track_get_key_value(first_track, first_key);
ERR_FAIL_COND(!d.has("args"));
@ -3189,7 +3188,7 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_value_track_edit(Object *p_
};
Callable::CallError ce;
return Object::cast_to<AnimationTrackEdit>(get_script_instance()->call("create_value_track_edit", (const Variant **)&argptrs, 6, ce).operator Object *());
return Object::cast_to<AnimationTrackEdit>(get_script_instance()->callp("create_value_track_edit", (const Variant **)&argptrs, 6, ce).operator Object *());
}
return nullptr;
}

View file

@ -180,9 +180,6 @@ void ConnectDialog::_unbind_count_changed(double p_count) {
* Adds a new parameter bind to connection.
*/
void ConnectDialog::_add_bind() {
if (cdbinds->params.size() >= VARIANT_ARG_MAX) {
return;
}
Variant::Type vt = (Variant::Type)type_list->get_item_id(type_list->get_selected());
Variant value;

View file

@ -610,12 +610,12 @@ void EditorDebuggerNode::_save_node_requested(ObjectID p_id, const String &p_fil
}
// Remote inspector/edit.
void EditorDebuggerNode::_method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE) {
void EditorDebuggerNode::_method_changeds(void *p_ud, Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount) {
if (!singleton) {
return;
}
_for_all(singleton->tabs, [&](ScriptEditorDebugger *dbg) {
dbg->_method_changed(p_base, p_name, VARIANT_ARG_PASS);
dbg->_method_changed(p_base, p_name, p_args, p_argcount);
});
}

View file

@ -171,7 +171,7 @@ public:
// Remote inspector/edit.
void request_remote_tree();
static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount);
static void _property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);
// LiveDebug

View file

@ -1064,18 +1064,16 @@ int ScriptEditorDebugger::_get_res_path_cache(const String &p_path) {
return last_path_id;
}
void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE) {
void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount) {
if (!p_base || !live_debug || !is_session_active() || !EditorNode::get_singleton()->get_edited_scene()) {
return;
}
Node *node = Object::cast_to<Node>(p_base);
VARIANT_ARGPTRS
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
for (int i = 0; i < p_argcount; i++) {
//no pointers, sorry
if (argptr[i] && (argptr[i]->get_type() == Variant::OBJECT || argptr[i]->get_type() == Variant::RID)) {
if (p_args[i]->get_type() == Variant::OBJECT || p_args[i]->get_type() == Variant::RID) {
return;
}
}
@ -1087,9 +1085,9 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
Array msg;
msg.push_back(pathid);
msg.push_back(p_name);
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
for (int i = 0; i < p_argcount; i++) {
//no pointers, sorry
msg.push_back(*argptr[i]);
msg.push_back(*p_args[i]);
}
_put_msg("scene:live_node_call", msg);
@ -1105,9 +1103,9 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
Array msg;
msg.push_back(pathid);
msg.push_back(p_name);
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
for (int i = 0; i < p_argcount; i++) {
//no pointers, sorry
msg.push_back(*argptr[i]);
msg.push_back(*p_args[i]);
}
_put_msg("scene:live_res_call", msg);

View file

@ -187,7 +187,7 @@ private:
void _live_edit_set();
void _live_edit_clear();
void _method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
void _method_changed(Object *p_base, const StringName &p_name, const Variant **p_args, int p_argcount);
void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value);
void _error_activated();

View file

@ -99,7 +99,7 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p
const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] };
cache[p_property] = p_value;
emit_signal(SNAME("property_changed"), (const Variant **)argptrs, 4);
emit_signalp(SNAME("property_changed"), (const Variant **)argptrs, 4);
}
void EditorProperty::_notification(int p_what) {
@ -3314,7 +3314,7 @@ void EditorInspector::_property_keyed(const String &p_path, bool p_advance) {
// The second parameter could be null, causing the event to fire with less arguments, so use the pointer call which preserves it.
const Variant args[3] = { p_path, object->get(p_path), p_advance };
const Variant *argp[3] = { &args[0], &args[1], &args[2] };
emit_signal(SNAME("property_keyed"), argp, 3);
emit_signalp(SNAME("property_keyed"), argp, 3);
}
void EditorInspector::_property_deleted(const String &p_path) {
@ -3333,7 +3333,7 @@ void EditorInspector::_property_keyed_with_value(const String &p_path, const Var
// The second parameter could be null, causing the event to fire with less arguments, so use the pointer call which preserves it.
const Variant args[3] = { p_path, p_value, p_advance };
const Variant *argp[3] = { &args[0], &args[1], &args[2] };
emit_signal(SNAME("property_keyed"), argp, 3);
emit_signalp(SNAME("property_keyed"), argp, 3);
}
void EditorInspector::_property_checked(const String &p_path, bool p_checked) {

View file

@ -3059,7 +3059,7 @@ void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_prope
// The second parameter could be null, causing the event to fire with less arguments, so use the pointer call which preserves it.
const Variant args[3] = { String(get_edited_property()) + ":" + p_property, p_value, p_advance };
const Variant *argp[3] = { &args[0], &args[1], &args[2] };
emit_signal(SNAME("property_keyed_with_value"), argp, 3);
emit_signalp(SNAME("property_keyed_with_value"), argp, 3);
}
void EditorPropertyResource::_sub_inspector_resource_selected(const RES &p_resource, const String &p_property) {

View file

@ -938,7 +938,7 @@ const Vector<Multiplayer::RPCConfig> GDScript::get_rpc_methods() const {
return rpc_functions;
}
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant GDScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *top = this;
while (top) {
Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method);
@ -952,7 +952,7 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
//none found, regular
return Script::call(p_method, p_args, p_argcount, r_error);
return Script::callp(p_method, p_args, p_argcount, r_error);
}
bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
@ -1273,7 +1273,7 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
if (member->setter) {
const Variant *val = &p_value;
Callable::CallError err;
call(member->setter, &val, 1, err);
callp(member->setter, &val, 1, err);
if (err.error == Callable::CallError::CALL_OK) {
return true; //function exists, call was successful
} else {
@ -1335,7 +1335,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
if (E) {
if (E->get().getter) {
Callable::CallError err;
r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, nullptr, 0, err);
r_ret = const_cast<GDScriptInstance *>(this)->callp(E->get().getter, nullptr, 0, err);
if (err.error == Callable::CallError::CALL_OK) {
return true;
}
@ -1520,7 +1520,7 @@ bool GDScriptInstance::has_method(const StringName &p_method) const {
return false;
}
Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant GDScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
@ -1555,7 +1555,7 @@ void GDScriptInstance::notification(int p_notification) {
String GDScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
Callable::CallError ce;
Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid) {

View file

@ -166,7 +166,7 @@ protected:
bool _set(const StringName &p_name, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_properties) const;
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
static void _bind_methods();
@ -285,7 +285,7 @@ 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, 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);
Variant debug_get_member_by_index(int p_idx) const { return members[p_idx]; }

View file

@ -64,7 +64,7 @@ ObjectID GDScriptRPCCallable::get_object() const {
}
void GDScriptRPCCallable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
r_return_value = object->call(method, p_arguments, p_argcount, r_call_error);
r_return_value = object->callp(method, p_arguments, p_argcount, r_call_error);
}
GDScriptRPCCallable::GDScriptRPCCallable(Object *p_object, const StringName &p_method) {

View file

@ -1447,7 +1447,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
const StringName native_type = _global_names_ptr[native_type_idx];
Array array;
array.set_typed(builtin_type, native_type, script_type);
array.set_typed(builtin_type, native_type, *script_type);
array.resize(argc);
for (int i = 0; i < argc; i++) {
@ -1517,7 +1517,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
Callable::CallError err;
if (call_ret) {
GET_INSTRUCTION_ARG(ret, argc + 1);
base->call(*methodname, (const Variant **)argptrs, argc, *ret, err);
base->callp(*methodname, (const Variant **)argptrs, argc, *ret, err);
#ifdef DEBUG_ENABLED
if (!call_async && ret->get_type() == Variant::OBJECT) {
// Check if getting a function state without await.
@ -1536,7 +1536,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
} else {
Variant ret;
base->call(*methodname, (const Variant **)argptrs, argc, ret, err);
base->callp(*methodname, (const Variant **)argptrs, argc, ret, err);
}
#ifdef DEBUG_ENABLED
if (GDScriptLanguage::get_singleton()->profiling) {
@ -2340,7 +2340,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
Array array;
array.set_typed(builtin_type, native_type, script_type);
array.set_typed(builtin_type, native_type, *script_type);
#ifdef DEBUG_ENABLED
bool valid = array.typed_assign(*VariantInternal::get_array(r));
@ -2810,7 +2810,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
args[0] = &vref;
Callable::CallError ce;
Variant has_next = obj->call(CoreStringNames::get_singleton()->_iter_init, (const Variant **)args, 1, ce);
Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_init, (const Variant **)args, 1, ce);
#ifdef DEBUG_ENABLED
if (ce.error != Callable::CallError::CALL_OK) {
@ -2824,7 +2824,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
ip = jumpto;
} else {
GET_INSTRUCTION_ARG(iterator, 2);
*iterator = obj->call(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce);
*iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce);
#ifdef DEBUG_ENABLED
if (ce.error != Callable::CallError::CALL_OK) {
err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container);
@ -3141,7 +3141,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
args[0] = &vref;
Callable::CallError ce;
Variant has_next = obj->call(CoreStringNames::get_singleton()->_iter_next, (const Variant **)args, 1, ce);
Variant has_next = obj->callp(CoreStringNames::get_singleton()->_iter_next, (const Variant **)args, 1, ce);
#ifdef DEBUG_ENABLED
if (ce.error != Callable::CallError::CALL_OK) {
@ -3155,7 +3155,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
ip = jumpto;
} else {
GET_INSTRUCTION_ARG(iterator, 2);
*iterator = obj->call(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce);
*iterator = obj->callp(CoreStringNames::get_singleton()->_iter_get, (const Variant **)args, 1, ce);
#ifdef DEBUG_ENABLED
if (ce.error != Callable::CallError::CALL_OK) {
err_text = vformat(R"(There was an error calling "_iter_get" on iterator object of type %s.)", *container);

View file

@ -573,7 +573,7 @@ GDScriptTest::TestResult GDScriptTest::execute_test_code(bool p_is_generating) {
// Call test function.
Callable::CallError call_err;
instance->call(GDScriptTestRunner::test_function_name, nullptr, 0, call_err);
instance->callp(GDScriptTestRunner::test_function_name, nullptr, 0, call_err);
// Tear down output handlers.
remove_print_handler(&_print_handler);

View file

@ -1893,7 +1893,7 @@ bool CSharpInstance::has_method(const StringName &p_method) const {
return false;
}
Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant CSharpInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
ERR_FAIL_COND_V(!script.is_valid(), Variant());
GD_MONO_SCOPE_THREAD_ATTACH;
@ -2908,7 +2908,7 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
}
#endif
Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant CSharpScript::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (unlikely(GDMono::get_singleton() == nullptr)) {
// Probably not the best error but eh.
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
@ -2936,7 +2936,7 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i
}
// No static method found. Try regular instance calls
return Script::call(p_method, p_args, p_argcount, r_error);
return Script::callp(p_method, p_args, p_argcount, r_error);
}
void CSharpScript::_resource_path_changed() {

View file

@ -184,7 +184,7 @@ private:
protected:
static void _bind_methods();
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
void _resource_path_changed() override;
bool _get(const StringName &p_name, Variant &r_ret) const;
bool _set(const StringName &p_name, const Variant &p_value);
@ -295,7 +295,7 @@ public:
void get_method_list(List<MethodInfo> *p_list) const override;
bool has_method(const StringName &p_method) const override;
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
void mono_object_disposed(MonoObject *p_obj);

View file

@ -199,7 +199,7 @@ MonoBoolean godot_icall_DynamicGodotObject_InvokeMember(Object *p_ptr, MonoStrin
}
Callable::CallError error;
Variant result = p_ptr->call(StringName(name), args.ptr(), argc, error);
Variant result = p_ptr->callp(StringName(name), args.ptr(), argc, error);
*r_result = GDMonoMarshal::variant_to_mono_object(result);

View file

@ -75,5 +75,5 @@ void RvoAgent::dispatch_callback() {
const Variant *vp[2] = { &callback.new_velocity, &callback.udata };
int argc = (callback.udata.get_type() == Variant::NIL) ? 1 : 2;
obj->call(callback.method, vp, argc, responseCallError);
obj->callp(callback.method, vp, argc, responseCallError);
}

View file

@ -1621,7 +1621,7 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
conn_map.get_key_list(&keys);
for (const int &E : keys) {
for (const Set<int>::Element *F = conn_map[E].front(); F; F = F->next()) {
undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F);
undo_redo->add_undo_method(script.ptr(), "data_connect", p_id, p_port, E, F->get());
}
}

View file

@ -1705,7 +1705,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
return return_value;
}
Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant VisualScriptInstance::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK; //ok by default
Map<StringName, Function>::Element *F = functions.find(p_method);
@ -1798,13 +1798,13 @@ void VisualScriptInstance::notification(int p_notification) {
Variant what = p_notification;
const Variant *whatp = &what;
Callable::CallError ce;
call(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call.
callp(VisualScriptLanguage::singleton->notification, &whatp, 1, ce); // Do as call.
}
String VisualScriptInstance::to_string(bool *r_valid) {
if (has_method(CoreStringNames::get_singleton()->_to_string)) {
Callable::CallError ce;
Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
Variant ret = callp(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
if (r_valid) {

View file

@ -410,7 +410,7 @@ 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, 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);
virtual void notification(int p_notification);
String to_string(bool *r_valid);

View file

@ -1500,7 +1500,7 @@ public:
argp.write[i] = &arr[i];
}
base.call(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
base.callp(call->method, (const Variant **)argp.ptr(), argp.size(), r_ret, ce);
if (ce.error != Callable::CallError::CALL_OK) {
r_error_str = "On call to '" + String(call->method) + "':";

View file

@ -772,9 +772,9 @@ public:
if (rpc_mode) {
call_rpc(object, p_inputs, input_args);
} else if (returns) {
*p_outputs[0] = object->call(function, p_inputs, input_args, r_error);
*p_outputs[0] = object->callp(function, p_inputs, input_args, r_error);
} else {
object->call(function, p_inputs, input_args, r_error);
object->callp(function, p_inputs, input_args, r_error);
}
} break;
case VisualScriptFunctionCall::CALL_MODE_NODE_PATH: {
@ -795,9 +795,9 @@ public:
if (rpc_mode) {
call_rpc(node, p_inputs, input_args);
} else if (returns) {
*p_outputs[0] = another->call(function, p_inputs, input_args, r_error);
*p_outputs[0] = another->callp(function, p_inputs, input_args, r_error);
} else {
another->call(function, p_inputs, input_args, r_error);
another->callp(function, p_inputs, input_args, r_error);
}
} break;
@ -813,21 +813,21 @@ public:
} else if (returns) {
if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
if (returns >= 2) {
v.call(function, p_inputs + 1, input_args, *p_outputs[1], r_error);
v.callp(function, p_inputs + 1, input_args, *p_outputs[1], r_error);
} else if (returns == 1) {
Variant ret;
v.call(function, p_inputs + 1, input_args, ret, r_error);
v.callp(function, p_inputs + 1, input_args, ret, r_error);
} else {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = "Invalid returns count for call_mode == CALL_MODE_INSTANCE";
return 0;
}
} else {
v.call(function, p_inputs + 1, input_args, *p_outputs[0], r_error);
v.callp(function, p_inputs + 1, input_args, *p_outputs[0], r_error);
}
} else {
Variant ret;
v.call(function, p_inputs + 1, input_args, ret, r_error);
v.callp(function, p_inputs + 1, input_args, ret, r_error);
}
if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
@ -846,9 +846,9 @@ public:
if (rpc_mode) {
call_rpc(object, p_inputs, input_args);
} else if (returns) {
*p_outputs[0] = object->call(function, p_inputs, input_args, r_error);
*p_outputs[0] = object->callp(function, p_inputs, input_args, r_error);
} else {
object->call(function, p_inputs, input_args, r_error);
object->callp(function, p_inputs, input_args, r_error);
}
} break;
}
@ -2373,7 +2373,7 @@ public:
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
Object *obj = instance->get_owner_ptr();
obj->emit_signal(name, p_inputs, argcount);
obj->emit_signalp(name, p_inputs, argcount);
return 0;
}

View file

@ -3174,7 +3174,7 @@ public:
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return 0;
}
*p_outputs[0] = subcall->call(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error);
*p_outputs[0] = subcall->callp(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error);
return 0;
}
};

View file

@ -64,14 +64,14 @@ void JavaClassWrapper::_bind_methods() {
#if !defined(ANDROID_ENABLED)
Variant JavaClass::call(const StringName &, const Variant **, int, Callable::CallError &) {
Variant JavaClass::callp(const StringName &, const Variant **, int, Callable::CallError &) {
return Variant();
}
JavaClass::JavaClass() {
}
Variant JavaObject::call(const StringName &, const Variant **, int, Callable::CallError &) {
Variant JavaObject::callp(const StringName &, const Variant **, int, Callable::CallError &) {
return Variant();
}

View file

@ -179,7 +179,7 @@ class JavaClass : public RefCounted {
#endif
public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
JavaClass();
};
@ -195,7 +195,7 @@ class JavaObject : public RefCounted {
#endif
public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override;
#ifdef ANDROID_ENABLED
JavaObject(const Ref<JavaClass> &p_base, jobject *p_instance);

View file

@ -52,7 +52,7 @@ class JNISingleton : public Object {
#endif
public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
#ifdef ANDROID_ENABLED
Map<StringName, MethodData>::Element *E = method_map.find(p_method);
@ -70,7 +70,7 @@ public:
if (call_error) {
// The method is not in this map, defaulting to the regular instance calls.
return Object::call(p_method, p_args, p_argcount, r_error);
return Object::callp(p_method, p_args, p_argcount, r_error);
}
ERR_FAIL_COND_V(!instance, Variant());
@ -176,7 +176,7 @@ public:
#else // ANDROID_ENABLED
// Defaulting to the regular instance calls.
return Object::call(p_method, p_args, p_argcount, r_error);
return Object::callp(p_method, p_args, p_argcount, r_error);
#endif
}

View file

@ -485,14 +485,14 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
return success;
}
Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant JavaClass::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant ret;
bool found = _call_method(nullptr, p_method, p_args, p_argcount, r_error, ret);
if (found) {
return ret;
}
return RefCounted::call(p_method, p_args, p_argcount, r_error);
return RefCounted::callp(p_method, p_args, p_argcount, r_error);
}
JavaClass::JavaClass() {
@ -500,7 +500,7 @@ JavaClass::JavaClass() {
/////////////////////
Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
Variant JavaObject::callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
return Variant();
}

View file

@ -446,7 +446,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en
}
Callable::CallError err;
obj->call(str_method, (const Variant **)vptr, count, err);
obj->callp(str_method, (const Variant **)vptr, count, err);
// something
env->PopLocalFrame(nullptr);
@ -462,18 +462,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *
String str_method = jstring_to_string(method, env);
int count = env->GetArrayLength(params);
Variant args[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(count, VARIANT_ARG_MAX); i++) {
Variant *args = (Variant *)alloca(sizeof(Variant) * count);
const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *) * count);
for (int i = 0; i < count; i++) {
jobject obj = env->GetObjectArrayElement(params, i);
if (obj) {
args[i] = _jobject_to_variant(env, obj);
}
env->DeleteLocalRef(obj);
argptrs[i] = &args[i];
}
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
obj->call_deferred(str_method, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
MessageQueue::get_singleton()->push_callp(obj, str_method, (const Variant **)argptrs, count);
// something
env->PopLocalFrame(nullptr);
}

View file

@ -114,10 +114,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
String signal_name = jstring_to_string(j_signal_name, env);
int count = env->GetArrayLength(j_signal_params);
ERR_FAIL_COND_MSG(count > VARIANT_ARG_MAX, "Maximum argument count exceeded!");
Variant variant_params[VARIANT_ARG_MAX];
const Variant *args[VARIANT_ARG_MAX];
Variant *variant_params = (Variant *)alloca(sizeof(Variant) * count);
const Variant **args = (const Variant **)alloca(sizeof(Variant *) * count);
for (int i = 0; i < count; i++) {
jobject j_param = env->GetObjectArrayElement(j_signal_params, i);
@ -126,7 +125,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
env->DeleteLocalRef(j_param);
};
singleton->emit_signal(StringName(signal_name), args, count);
singleton->emit_signalp(StringName(signal_name), args, count);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) {

View file

@ -81,7 +81,7 @@ protected:
public:
Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const override;
void setvar(const Variant &p_key, const Variant &p_value, bool *r_valid = nullptr) override;
Variant call(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) override;
Variant callp(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) override;
JavaScriptObjectImpl() {}
JavaScriptObjectImpl(int p_id) { _js_id = p_id; }
~JavaScriptObjectImpl() {
@ -231,7 +231,7 @@ int JavaScriptObjectImpl::_variant2js(const void **p_args, int p_pos, godot_js_w
return type;
}
Variant JavaScriptObjectImpl::call(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) {
Variant JavaScriptObjectImpl::callp(const StringName &p_method, const Variant **p_args, int p_argc, Callable::CallError &r_error) {
godot_js_wrapper_ex exchange;
const String method = p_method;
void *lock = nullptr;

View file

@ -401,6 +401,22 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim, Node *p_root_ov
}
}
static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
// Separate function to use alloca() more efficiently
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
const Variant *args = p_params.ptr();
uint32_t argcount = p_params.size();
for (uint32_t i = 0; i < argcount; i++) {
argptrs[i] = &args[i];
}
if (p_deferred) {
MessageQueue::get_singleton()->push_callp(p_object, p_method, argptrs, argcount);
} else {
Callable::CallError ce;
p_object->callp(p_method, argptrs, argcount, ce);
}
}
void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double p_time, double p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started, int p_pingponged) {
_ensure_node_caches(p_anim);
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
@ -677,41 +693,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
StringName method = a->method_track_get_name(i, E);
Vector<Variant> params = a->method_track_get_params(i, E);
int s = params.size();
ERR_CONTINUE(s > VARIANT_ARG_MAX);
#ifdef DEBUG_ENABLED
if (!nc->node->has_method(method)) {
ERR_PRINT("Invalid method call '" + method + "'. '" + a->get_name() + "' at node '" + get_path() + "'.");
}
#endif
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
if (can_call) {
if (method_call_mode == ANIMATION_METHOD_CALL_DEFERRED) {
MessageQueue::get_singleton()->push_call(
nc->node,
method,
s >= 1 ? params[0] : Variant(),
s >= 2 ? params[1] : Variant(),
s >= 3 ? params[2] : Variant(),
s >= 4 ? params[3] : Variant(),
s >= 5 ? params[4] : Variant(),
s >= 6 ? params[5] : Variant(),
s >= 7 ? params[6] : Variant(),
s >= 8 ? params[7] : Variant());
} else {
nc->node->call(
method,
s >= 1 ? params[0] : Variant(),
s >= 2 ? params[1] : Variant(),
s >= 3 ? params[2] : Variant(),
s >= 4 ? params[3] : Variant(),
s >= 5 ? params[4] : Variant(),
s >= 6 ? params[5] : Variant(),
s >= 7 ? params[6] : Variant(),
s >= 8 ? params[7] : Variant());
}
_call_object(nc->node, method, params, method_call_mode == ANIMATION_METHOD_CALL_DEFERRED);
}
}
@ -754,7 +743,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
nc->node->call("stop");
nc->node->call(SNAME("stop"));
nc->audio_playing = false;
playing_caches.erase(nc);
} else {
@ -764,14 +753,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
float len = stream->get_length();
if (start_ofs > len - end_ofs) {
nc->node->call("stop");
nc->node->call(SNAME("stop"));
nc->audio_playing = false;
playing_caches.erase(nc);
continue;
}
nc->node->call("set_stream", stream);
nc->node->call("play", start_ofs);
nc->node->call(SNAME("set_stream"), stream);
nc->node->call(SNAME("play"), start_ofs);
nc->audio_playing = true;
playing_caches.insert(nc);
@ -793,7 +782,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
nc->node->call("stop");
nc->node->call(SNAME("stop"));
nc->audio_playing = false;
playing_caches.erase(nc);
} else {
@ -801,8 +790,8 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
float end_ofs = a->audio_track_get_key_end_offset(i, idx);
float len = stream->get_length();
nc->node->call("set_stream", stream);
nc->node->call("play", start_ofs);
nc->node->call(SNAME("set_stream"), stream);
nc->node->call(SNAME("play"), start_ofs);
nc->audio_playing = true;
playing_caches.insert(nc);
@ -833,7 +822,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
if (stop) {
//time to stop
nc->node->call("stop");
nc->node->call(SNAME("stop"));
nc->audio_playing = false;
playing_caches.erase(nc);
}
@ -1544,7 +1533,7 @@ void AnimationPlayer::_animation_changed() {
void AnimationPlayer::_stop_playing_caches() {
for (Set<TrackNodeCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
if (E->get()->node && E->get()->audio_playing) {
E->get()->node->call("stop");
E->get()->node->call(SNAME("stop"));
}
if (E->get()->node && E->get()->animation_playing) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(E->get()->node);

View file

@ -490,7 +490,7 @@ void AnimationTree::set_active(bool p_active) {
if (!active && is_inside_tree()) {
for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
if (ObjectDB::get_instance(E->get()->object_id)) {
E->get()->object->call("stop");
E->get()->object->call(SNAME("stop"));
}
}
@ -796,6 +796,21 @@ void AnimationTree::_clear_caches() {
cache_valid = false;
}
static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
// Separate function to use alloca() more efficiently
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
const Variant *args = p_params.ptr();
uint32_t argcount = p_params.size();
for (uint32_t i = 0; i < argcount; i++) {
argptrs[i] = &args[i];
}
if (p_deferred) {
MessageQueue::get_singleton()->push_callp(p_object, p_method, argptrs, argcount);
} else {
Callable::CallError ce;
p_object->callp(p_method, argptrs, argcount, ce);
}
}
void AnimationTree::_process_graph(double p_delta) {
_update_properties(); //if properties need updating, update them
@ -1286,25 +1301,10 @@ void AnimationTree::_process_graph(double p_delta) {
for (int &F : indices) {
StringName method = a->method_track_get_name(i, F);
Vector<Variant> params = a->method_track_get_params(i, F);
int s = params.size();
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
ERR_CONTINUE(s > VARIANT_ARG_MAX);
if (can_call) {
t->object->call_deferred(
method,
s >= 1 ? params[0] : Variant(),
s >= 2 ? params[1] : Variant(),
s >= 3 ? params[2] : Variant(),
s >= 4 ? params[3] : Variant(),
s >= 5 ? params[4] : Variant(),
s >= 6 ? params[5] : Variant(),
s >= 7 ? params[6] : Variant(),
s >= 8 ? params[7] : Variant());
_call_object(t->object, method, params, true);
}
}
} break;
case Animation::TYPE_BEZIER: {
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
@ -1331,7 +1331,7 @@ void AnimationTree::_process_graph(double p_delta) {
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
t->object->call("stop");
t->object->call(SNAME("stop"));
t->playing = false;
playing_caches.erase(t);
} else {
@ -1341,14 +1341,14 @@ void AnimationTree::_process_graph(double p_delta) {
double len = stream->get_length();
if (start_ofs > len - end_ofs) {
t->object->call("stop");
t->object->call(SNAME("stop"));
t->playing = false;
playing_caches.erase(t);
continue;
}
t->object->call("set_stream", stream);
t->object->call("play", start_ofs);
t->object->call(SNAME("set_stream"), stream);
t->object->call(SNAME("play"), start_ofs);
t->playing = true;
playing_caches.insert(t);
@ -1370,7 +1370,7 @@ void AnimationTree::_process_graph(double p_delta) {
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
t->object->call("stop");
t->object->call(SNAME("stop"));
t->playing = false;
playing_caches.erase(t);
} else {
@ -1378,8 +1378,8 @@ void AnimationTree::_process_graph(double p_delta) {
double end_ofs = a->audio_track_get_key_end_offset(i, idx);
double len = stream->get_length();
t->object->call("set_stream", stream);
t->object->call("play", start_ofs);
t->object->call(SNAME("set_stream"), stream);
t->object->call(SNAME("play"), start_ofs);
t->playing = true;
playing_caches.insert(t);
@ -1416,7 +1416,7 @@ void AnimationTree::_process_graph(double p_delta) {
if (stop) {
//time to stop
t->object->call("stop");
t->object->call(SNAME("stop"));
t->playing = false;
playing_caches.erase(t);
}
@ -1424,10 +1424,10 @@ void AnimationTree::_process_graph(double p_delta) {
}
real_t db = Math::linear2db(MAX(blend, 0.00001));
if (t->object->has_method("set_unit_db")) {
t->object->call("set_unit_db", db);
if (t->object->has_method(SNAME("set_unit_db"))) {
t->object->call(SNAME("set_unit_db"), db);
} else {
t->object->call("set_volume_db", db);
t->object->call(SNAME("set_volume_db"), db);
}
} break;
case Animation::TYPE_ANIMATION: {

View file

@ -34,6 +34,7 @@
#include "core/debugger/engine_profiler.h"
#include "core/io/marshalls.h"
#include "core/object/script_language.h"
#include "core/templates/local_vector.h"
#include "scene/main/scene_tree.h"
#include "scene/main/window.h"
#include "scene/resources/packed_scene.h"
@ -236,12 +237,28 @@ Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Arra
live_editor->_res_set_func(p_args[0], p_args[1], p_args[2]);
} else if (p_msg == "live_node_call") {
ERR_FAIL_COND_V(p_args.size() < 10, ERR_INVALID_DATA);
live_editor->_node_call_func(p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5], p_args[6], p_args[7], p_args[8], p_args[9]);
LocalVector<Variant> args;
LocalVector<Variant *> argptrs;
args.resize(p_args.size() - 2);
argptrs.resize(args.size());
for (uint32_t i = 0; i < args.size(); i++) {
args[i] = p_args[i + 2];
argptrs[i] = &args[i];
}
live_editor->_node_call_func(p_args[0], p_args[1], (const Variant **)argptrs.ptr(), argptrs.size());
} else if (p_msg == "live_res_call") {
ERR_FAIL_COND_V(p_args.size() < 10, ERR_INVALID_DATA);
live_editor->_res_call_func(p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5], p_args[6], p_args[7], p_args[8], p_args[9]);
LocalVector<Variant> args;
LocalVector<Variant *> argptrs;
args.resize(p_args.size() - 2);
argptrs.resize(args.size());
for (uint32_t i = 0; i < args.size(); i++) {
args[i] = p_args[i + 2];
argptrs[i] = &args[i];
}
live_editor->_res_call_func(p_args[0], p_args[1], (const Variant **)argptrs.ptr(), argptrs.size());
} else if (p_msg == "live_create_node") {
ERR_FAIL_COND_V(p_args.size() < 3, ERR_INVALID_DATA);
@ -636,7 +653,7 @@ void LiveEditor::_node_set_res_func(int p_id, const StringName &p_prop, const St
_node_set_func(p_id, p_prop, r);
}
void LiveEditor::_node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
void LiveEditor::_node_call_func(int p_id, const StringName &p_method, const Variant **p_args, int p_argcount) {
SceneTree *scene_tree = SceneTree::get_singleton();
if (!scene_tree) {
return;
@ -668,7 +685,8 @@ void LiveEditor::_node_call_func(int p_id, const StringName &p_method, VARIANT_A
}
Node *n2 = n->get_node(np);
n2->call(p_method, VARIANT_ARG_PASS);
Callable::CallError ce;
n2->callp(p_method, p_args, p_argcount, ce);
}
}
@ -699,7 +717,7 @@ void LiveEditor::_res_set_res_func(int p_id, const StringName &p_prop, const Str
_res_set_func(p_id, p_prop, r);
}
void LiveEditor::_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
void LiveEditor::_res_call_func(int p_id, const StringName &p_method, const Variant **p_args, int p_argcount) {
if (!live_edit_resource_cache.has(p_id)) {
return;
}
@ -715,7 +733,8 @@ void LiveEditor::_res_call_func(int p_id, const StringName &p_method, VARIANT_AR
return;
}
r->call(p_method, VARIANT_ARG_PASS);
Callable::CallError ce;
r->callp(p_method, p_args, p_argcount, ce);
}
void LiveEditor::_root_func(const NodePath &p_scene_path, const String &p_scene_from) {

View file

@ -148,10 +148,10 @@ private:
void _node_set_func(int p_id, const StringName &p_prop, const Variant &p_value);
void _node_set_res_func(int p_id, const StringName &p_prop, const String &p_value);
void _node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
void _node_call_func(int p_id, const StringName &p_method, const Variant **p_args, int p_argcount);
void _res_set_func(int p_id, const StringName &p_prop, const Variant &p_value);
void _res_set_res_func(int p_id, const StringName &p_prop, const String &p_value);
void _res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE);
void _res_call_func(int p_id, const StringName &p_method, const Variant **p_args, int p_argcount);
void _root_func(const NodePath &p_scene_path, const String &p_scene_from);
void _create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name);

View file

@ -1186,7 +1186,7 @@ void recursive_call_aux(TreeItem *p_item, const StringName &p_method, const Vari
if (!p_item) {
return;
}
p_item->call(p_method, p_args, p_argcount, r_error);
p_item->callp(p_method, p_args, p_argcount, r_error);
TreeItem *c = p_item->get_first_child();
while (c) {
recursive_call_aux(c, p_method, p_args, p_argcount, r_error);

View file

@ -211,7 +211,7 @@ void Node::_propagate_enter_tree() {
if (data.parent) {
Variant c = this;
const Variant *cptr = &c;
data.parent->emit_signal(SNAME("child_entered_tree"), &cptr, 1);
data.parent->emit_signalp(SNAME("child_entered_tree"), &cptr, 1);
}
data.blocked++;
@ -287,7 +287,7 @@ void Node::_propagate_exit_tree() {
if (data.parent) {
Variant c = this;
const Variant *cptr = &c;
data.parent->emit_signal(SNAME("child_exited_tree"), &cptr, 1);
data.parent->emit_signalp(SNAME("child_exited_tree"), &cptr, 1);
}
// exit groups
@ -582,34 +582,6 @@ uint16_t Node::rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc
/***** RPC FUNCTIONS ********/
void Node::rpc(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++;
}
rpcp(0, p_method, argptr, argc);
}
void Node::rpc_id(int p_peer_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++;
}
rpcp(p_peer_id, p_method, argptr, argc);
}
Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
@ -2389,42 +2361,6 @@ void Node::_replace_connections_target(Node *p_new_target) {
}
}
Vector<Variant> Node::make_binds(VARIANT_ARG_DECLARE) {
Vector<Variant> ret;
if (p_arg1.get_type() == Variant::NIL) {
return ret;
} else {
ret.push_back(p_arg1);
}
if (p_arg2.get_type() == Variant::NIL) {
return ret;
} else {
ret.push_back(p_arg2);
}
if (p_arg3.get_type() == Variant::NIL) {
return ret;
} else {
ret.push_back(p_arg3);
}
if (p_arg4.get_type() == Variant::NIL) {
return ret;
} else {
ret.push_back(p_arg4);
}
if (p_arg5.get_type() == Variant::NIL) {
return ret;
} else {
ret.push_back(p_arg5);
}
return ret;
}
bool Node::has_node_and_resource(const NodePath &p_path) const {
if (!has_node(p_path)) {
return false;

View file

@ -420,7 +420,11 @@ public:
void set_scene_instance_load_placeholder(bool p_enable);
bool get_scene_instance_load_placeholder() const;
static Vector<Variant> make_binds(VARIANT_ARG_LIST);
template <typename... VarArgs>
Vector<Variant> make_binds(VarArgs... p_args) {
Vector<Variant> binds = { p_args... };
return binds;
}
void replace_by(Node *p_node, bool p_keep_data = false);
@ -472,8 +476,26 @@ public:
uint16_t rpc_config(const StringName &p_method, Multiplayer::RPCMode p_rpc_mode, bool p_call_local = false, Multiplayer::TransferMode p_transfer_mode = Multiplayer::TRANSFER_MODE_RELIABLE, int p_channel = 0); // config a local method for RPC
Vector<Multiplayer::RPCConfig> get_node_rpc_methods() const;
void rpc(const StringName &p_method, VARIANT_ARG_LIST); // RPC, honors RPCMode, TransferMode, channel
void rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_LIST); // RPC to specific peer(s), honors RPCMode, TransferMode, channel
template <typename... VarArgs>
void rpc(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];
}
rpcp(0, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
template <typename... VarArgs>
void rpc_id(int p_peer_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];
}
rpcp(p_peer_id, p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
void rpcp(int p_peer_id, const StringName &p_method, const Variant **p_arg, int p_argcount);
Ref<MultiplayerAPI> get_multiplayer() const;

View file

@ -175,13 +175,13 @@ void SceneTree::_flush_ugc() {
while (unique_group_calls.size()) {
Map<UGCall, Vector<Variant>>::Element *E = unique_group_calls.front();
Variant v[VARIANT_ARG_MAX];
const Variant **argptrs = (const Variant **)alloca(E->get().size() * sizeof(Variant *));
for (int i = 0; i < E->get().size(); i++) {
v[i] = E->get()[i];
argptrs[i] = &E->get()[i];
}
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
call_group_flags(GROUP_CALL_REALTIME, E->key().group, E->key().call, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
call_group_flagsp(GROUP_CALL_REALTIME, E->key().group, E->key().call, argptrs, E->get().size());
unique_group_calls.erase(E);
}
@ -210,7 +210,7 @@ void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
g.changed = false;
}
void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, VARIANT_ARG_DECLARE) {
void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, const Variant **p_args, int p_argcount) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
return;
@ -231,14 +231,9 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
return;
}
VARIANT_ARGPTRS;
Vector<Variant> args;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
if (argptr[i]->get_type() == Variant::NIL) {
break;
}
args.push_back(*argptr[i]);
for (int i = 0; i < p_argcount; i++) {
args.push_back(*p_args[i]);
}
unique_group_calls[ug] = args;
@ -260,9 +255,10 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
}
if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->call(p_function, VARIANT_ARG_PASS);
Callable::CallError ce;
nodes[i]->callp(p_function, p_args, p_argcount, ce);
} else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
MessageQueue::get_singleton()->push_callp(nodes[i], p_function, p_args, p_argcount);
}
}
@ -273,9 +269,10 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
}
if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->call(p_function, VARIANT_ARG_PASS);
Callable::CallError ce;
nodes[i]->callp(p_function, p_args, p_argcount, ce);
} else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
MessageQueue::get_singleton()->push_callp(nodes[i], p_function, p_args, p_argcount);
}
}
}
@ -388,10 +385,6 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
}
}
void SceneTree::call_group(const StringName &p_group, const StringName &p_function, VARIANT_ARG_DECLARE) {
call_group_flags(0, p_group, p_function, VARIANT_ARG_PASS);
}
void SceneTree::notify_group(const StringName &p_group, int p_notification) {
notify_group_flags(0, p_group, p_notification);
}
@ -930,14 +923,8 @@ Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Cal
int flags = *p_args[0];
StringName group = *p_args[1];
StringName method = *p_args[2];
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(p_argcount - 3, 5); i++) {
v[i] = *p_args[i + 3];
}
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
call_group_flags(flags, group, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
call_group_flagsp(flags, group, method, p_args + 3, p_argcount - 3);
return Variant();
}
@ -950,14 +937,8 @@ Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Callable:
StringName group = *p_args[0];
StringName method = *p_args[1];
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(p_argcount - 2, 5); i++) {
v[i] = *p_args[i + 2];
}
static_assert(VARIANT_ARG_MAX == 8, "This code needs to be updated if VARIANT_ARG_MAX != 8");
call_group_flags(0, group, method, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]);
call_group_flagsp(0, group, method, p_args + 2, p_argcount - 2);
return Variant();
}

View file

@ -229,14 +229,33 @@ public:
_FORCE_INLINE_ Window *get_root() const { return root; }
void call_group_flags(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, VARIANT_ARG_LIST);
void call_group_flagsp(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, const Variant **p_args, int p_argcount);
void notify_group_flags(uint32_t p_call_flags, const StringName &p_group, int p_notification);
void set_group_flags(uint32_t p_call_flags, const StringName &p_group, const String &p_name, const Variant &p_value);
void call_group(const StringName &p_group, const StringName &p_function, VARIANT_ARG_LIST);
void notify_group(const StringName &p_group, int p_notification);
void set_group(const StringName &p_group, const String &p_name, const Variant &p_value);
template <typename... VarArgs>
void call_group(const StringName &p_group, const StringName &p_function, 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];
}
call_group_flagsp(0, p_group, p_function, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
template <typename... VarArgs>
void call_group_flags(uint32_t p_flags, const StringName &p_group, const StringName &p_function, 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];
}
call_group_flagsp(p_flags, p_group, p_function, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
void flush_transform_notifications();
virtual void initialize() override;

View file

@ -278,7 +278,7 @@ void SceneRPCInterface::_process_rpc(Node *p_node, const uint16_t p_rpc_method_i
Callable::CallError ce;
p_node->call(config.name, (const Variant **)argp.ptr(), argc, ce);
p_node->callp(config.name, (const Variant **)argp.ptr(), argc, ce);
if (ce.error != Callable::CallError::CALL_OK) {
String error = Variant::get_call_error_text(p_node, config.name, (const Variant **)argp.ptr(), argc, ce);
error = "RPC - " + error;
@ -480,7 +480,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m
Callable::CallError ce;
multiplayer->set_remote_sender_override(peer->get_unique_id());
node->call(p_method, p_arg, p_argcount, ce);
node->callp(p_method, p_arg, p_argcount, ce);
multiplayer->set_remote_sender_override(0);
if (ce.error != Callable::CallError::CALL_OK) {
@ -496,7 +496,7 @@ void SceneRPCInterface::rpcp(Object *p_obj, int p_peer_id, const StringName &p_m
ce.error = Callable::CallError::CALL_OK;
multiplayer->set_remote_sender_override(peer->get_unique_id());
node->get_script_instance()->call(p_method, p_arg, p_argcount, ce);
node->get_script_instance()->callp(p_method, p_arg, p_argcount, ce);
multiplayer->set_remote_sender_override(0);
if (ce.error != Callable::CallError::CALL_OK) {

View file

@ -87,7 +87,7 @@ public:
bool has_method(const StringName &p_method) const override {
return false;
}
Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override {
return Variant();
}
void notification(int p_notification) override {