Merge pull request #71644 from RandomShaper/mq_call_static
Complete support of callables of static methods
This commit is contained in:
commit
5860b02b63
|
@ -198,7 +198,7 @@ class CallableCustomMethodPointerRetC : public CallableCustomMethodPointerBase {
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const {
|
virtual ObjectID get_object() const override {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
|
@ -207,7 +207,7 @@ public:
|
||||||
return data.instance->get_instance_id();
|
return data.instance->get_instance_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
|
||||||
#endif
|
#endif
|
||||||
|
@ -254,11 +254,15 @@ class CallableCustomStaticMethodPointer : public CallableCustomMethodPointerBase
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const {
|
virtual bool is_valid() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ObjectID get_object() const override {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
|
||||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
r_return_value = Variant();
|
r_return_value = Variant();
|
||||||
}
|
}
|
||||||
|
@ -292,11 +296,15 @@ class CallableCustomStaticMethodPointerRet : public CallableCustomMethodPointerB
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ObjectID get_object() const {
|
virtual bool is_valid() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ObjectID get_object() const override {
|
||||||
return ObjectID();
|
return ObjectID();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override {
|
||||||
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
call_with_variant_args_static_ret(data.method, p_arguments, p_argcount, r_return_value, r_call_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,10 @@ Error CallQueue::push_callablep(const Callable &p_callable, const Variant **p_ar
|
||||||
if (p_show_error) {
|
if (p_show_error) {
|
||||||
msg->type |= FLAG_SHOW_ERROR;
|
msg->type |= FLAG_SHOW_ERROR;
|
||||||
}
|
}
|
||||||
|
// Support callables of static methods.
|
||||||
|
if (p_callable.get_object_id().is_null() && p_callable.is_valid()) {
|
||||||
|
msg->type |= FLAG_NULL_IS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
buffer_end += sizeof(Message);
|
buffer_end += sizeof(Message);
|
||||||
|
|
||||||
|
@ -238,28 +242,24 @@ Error CallQueue::flush() {
|
||||||
|
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
if (target != nullptr) {
|
switch (message->type & FLAG_MASK) {
|
||||||
switch (message->type & FLAG_MASK) {
|
case TYPE_CALL: {
|
||||||
case TYPE_CALL: {
|
if (target || (message->type & FLAG_NULL_IS_OK)) {
|
||||||
Variant *args = (Variant *)(message + 1);
|
Variant *args = (Variant *)(message + 1);
|
||||||
|
|
||||||
// messages don't expect a return value
|
|
||||||
|
|
||||||
_call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
|
_call_function(message->callable, args, message->args, message->type & FLAG_SHOW_ERROR);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_NOTIFICATION: {
|
case TYPE_NOTIFICATION: {
|
||||||
// messages don't expect a return value
|
if (target) {
|
||||||
target->notification(message->notification);
|
target->notification(message->notification);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case TYPE_SET: {
|
case TYPE_SET: {
|
||||||
|
if (target) {
|
||||||
Variant *arg = (Variant *)(message + 1);
|
Variant *arg = (Variant *)(message + 1);
|
||||||
// messages don't expect a return value
|
|
||||||
target->set(message->callable.get_method(), *arg);
|
target->set(message->callable.get_method(), *arg);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
|
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
|
||||||
|
@ -355,36 +355,41 @@ void CallQueue::statistics() {
|
||||||
|
|
||||||
Object *target = message->callable.get_object();
|
Object *target = message->callable.get_object();
|
||||||
|
|
||||||
if (target != nullptr) {
|
bool null_target = true;
|
||||||
switch (message->type & FLAG_MASK) {
|
switch (message->type & FLAG_MASK) {
|
||||||
case TYPE_CALL: {
|
case TYPE_CALL: {
|
||||||
|
if (target || (message->type & FLAG_NULL_IS_OK)) {
|
||||||
if (!call_count.has(message->callable)) {
|
if (!call_count.has(message->callable)) {
|
||||||
call_count[message->callable] = 0;
|
call_count[message->callable] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
call_count[message->callable]++;
|
call_count[message->callable]++;
|
||||||
|
null_target = false;
|
||||||
} break;
|
}
|
||||||
case TYPE_NOTIFICATION: {
|
} break;
|
||||||
|
case TYPE_NOTIFICATION: {
|
||||||
|
if (target) {
|
||||||
if (!notify_count.has(message->notification)) {
|
if (!notify_count.has(message->notification)) {
|
||||||
notify_count[message->notification] = 0;
|
notify_count[message->notification] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_count[message->notification]++;
|
notify_count[message->notification]++;
|
||||||
|
null_target = false;
|
||||||
} break;
|
}
|
||||||
case TYPE_SET: {
|
} break;
|
||||||
|
case TYPE_SET: {
|
||||||
|
if (target) {
|
||||||
StringName t = message->callable.get_method();
|
StringName t = message->callable.get_method();
|
||||||
if (!set_count.has(t)) {
|
if (!set_count.has(t)) {
|
||||||
set_count[t] = 0;
|
set_count[t] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_count[t]++;
|
set_count[t]++;
|
||||||
|
null_target = false;
|
||||||
} break;
|
}
|
||||||
}
|
} break;
|
||||||
|
}
|
||||||
} else {
|
if (null_target) {
|
||||||
//object was deleted
|
//object was deleted
|
||||||
print_line("Object was deleted while awaiting a callback");
|
print_line("Object was deleted while awaiting a callback");
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,9 @@ private:
|
||||||
TYPE_NOTIFICATION,
|
TYPE_NOTIFICATION,
|
||||||
TYPE_SET,
|
TYPE_SET,
|
||||||
TYPE_END, // End marker.
|
TYPE_END, // End marker.
|
||||||
|
FLAG_NULL_IS_OK = 1 << 13,
|
||||||
FLAG_SHOW_ERROR = 1 << 14,
|
FLAG_SHOW_ERROR = 1 << 14,
|
||||||
FLAG_MASK = FLAG_SHOW_ERROR - 1,
|
FLAG_MASK = FLAG_NULL_IS_OK - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Page {
|
struct Page {
|
||||||
|
|
|
@ -122,7 +122,11 @@ Callable Callable::unbind(int p_argcount) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Callable::is_valid() const {
|
bool Callable::is_valid() const {
|
||||||
return get_object() && (is_custom() || get_object()->has_method(get_method()));
|
if (is_custom()) {
|
||||||
|
return get_custom()->is_valid();
|
||||||
|
} else {
|
||||||
|
return get_object() && get_object()->has_method(get_method());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *Callable::get_object() const {
|
Object *Callable::get_object() const {
|
||||||
|
@ -373,6 +377,11 @@ Callable::~Callable() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CallableCustom::is_valid() const {
|
||||||
|
// Sensible default implementation so most custom callables don't need their own.
|
||||||
|
return ObjectDB::get_instance(get_object());
|
||||||
|
}
|
||||||
|
|
||||||
StringName CallableCustom::get_method() const {
|
StringName CallableCustom::get_method() const {
|
||||||
ERR_FAIL_V_MSG(StringName(), vformat("Can't get method on CallableCustom \"%s\".", get_as_text()));
|
ERR_FAIL_V_MSG(StringName(), vformat("Can't get method on CallableCustom \"%s\".", get_as_text()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,8 +145,9 @@ public:
|
||||||
virtual String get_as_text() const = 0;
|
virtual String get_as_text() const = 0;
|
||||||
virtual CompareEqualFunc get_compare_equal_func() const = 0;
|
virtual CompareEqualFunc get_compare_equal_func() const = 0;
|
||||||
virtual CompareLessFunc get_compare_less_func() const = 0;
|
virtual CompareLessFunc get_compare_less_func() const = 0;
|
||||||
|
virtual bool is_valid() const;
|
||||||
virtual StringName get_method() const;
|
virtual StringName get_method() const;
|
||||||
virtual ObjectID get_object() const = 0; //must always be able to provide an object
|
virtual ObjectID get_object() const = 0;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
|
||||||
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
|
virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
|
||||||
virtual const Callable *get_base_comparator() const;
|
virtual const Callable *get_base_comparator() const;
|
||||||
|
|
|
@ -75,6 +75,10 @@ CallableCustom::CompareLessFunc CallableCustomBind::get_compare_less_func() cons
|
||||||
return _less_func;
|
return _less_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CallableCustomBind::is_valid() const {
|
||||||
|
return callable.is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
StringName CallableCustomBind::get_method() const {
|
StringName CallableCustomBind::get_method() const {
|
||||||
return callable.get_method();
|
return callable.get_method();
|
||||||
}
|
}
|
||||||
|
@ -193,6 +197,10 @@ CallableCustom::CompareLessFunc CallableCustomUnbind::get_compare_less_func() co
|
||||||
return _less_func;
|
return _less_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CallableCustomUnbind::is_valid() const {
|
||||||
|
return callable.is_valid();
|
||||||
|
}
|
||||||
|
|
||||||
StringName CallableCustomUnbind::get_method() const {
|
StringName CallableCustomUnbind::get_method() const {
|
||||||
return callable.get_method();
|
return callable.get_method();
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,9 @@ public:
|
||||||
virtual String get_as_text() const override;
|
virtual String get_as_text() const override;
|
||||||
virtual CompareEqualFunc get_compare_equal_func() const override;
|
virtual CompareEqualFunc get_compare_equal_func() const override;
|
||||||
virtual CompareLessFunc get_compare_less_func() const override;
|
virtual CompareLessFunc get_compare_less_func() const override;
|
||||||
|
virtual bool is_valid() const override;
|
||||||
virtual StringName get_method() const override;
|
virtual StringName get_method() const override;
|
||||||
virtual ObjectID get_object() const override; //must always be able to provide an object
|
virtual ObjectID get_object() const override;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
||||||
virtual const Callable *get_base_comparator() const override;
|
virtual const Callable *get_base_comparator() const override;
|
||||||
virtual int get_bound_arguments_count() const override;
|
virtual int get_bound_arguments_count() const override;
|
||||||
|
@ -73,8 +74,9 @@ public:
|
||||||
virtual String get_as_text() const override;
|
virtual String get_as_text() const override;
|
||||||
virtual CompareEqualFunc get_compare_equal_func() const override;
|
virtual CompareEqualFunc get_compare_equal_func() const override;
|
||||||
virtual CompareLessFunc get_compare_less_func() const override;
|
virtual CompareLessFunc get_compare_less_func() const override;
|
||||||
|
virtual bool is_valid() const override;
|
||||||
virtual StringName get_method() const override;
|
virtual StringName get_method() const override;
|
||||||
virtual ObjectID get_object() const override; //must always be able to provide an object
|
virtual ObjectID get_object() const override;
|
||||||
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override;
|
||||||
virtual const Callable *get_base_comparator() const override;
|
virtual const Callable *get_base_comparator() const override;
|
||||||
virtual int get_bound_arguments_count() const override;
|
virtual int get_bound_arguments_count() const override;
|
||||||
|
|
Loading…
Reference in New Issue