-make signals throw an error when target method is not found, fixes #2036
-removed 4 arguments limit for emit_signal() from script -remvoed 4 arguments limit for call_deferred() from script
This commit is contained in:
parent
30d4a50b42
commit
3d0bd1a3f3
@ -248,7 +248,7 @@ bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) con
|
|||||||
if (e.joy_motion.axis==p_event.joy_motion.axis) {
|
if (e.joy_motion.axis==p_event.joy_motion.axis) {
|
||||||
if (
|
if (
|
||||||
(e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
|
(e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
|
||||||
ABS(e.joy_motion.axis_value>0.5) && ABS(p_event.joy_motion.axis_value>0.5) )
|
ABS(e.joy_motion.axis_value)>0.5 && ABS(p_event.joy_motion.axis_value)>0.5 )
|
||||||
pressed=true;
|
pressed=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
#include "message_queue.h"
|
#include "message_queue.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "script_language.h"
|
||||||
MessageQueue *MessageQueue::singleton=NULL;
|
MessageQueue *MessageQueue::singleton=NULL;
|
||||||
|
|
||||||
MessageQueue *MessageQueue::get_singleton() {
|
MessageQueue *MessageQueue::get_singleton() {
|
||||||
@ -36,26 +36,11 @@ MessageQueue *MessageQueue::get_singleton() {
|
|||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error MessageQueue::push_call(ObjectID p_id, const StringName& p_method, VARIANT_ARG_DECLARE) {
|
Error MessageQueue::push_call(ObjectID p_id,const StringName& p_method,const Variant** p_args,int p_argcount,bool p_show_error) {
|
||||||
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
uint8_t room_needed=sizeof(Message);
|
int room_needed=sizeof(Message)+sizeof(Variant)*p_argcount;
|
||||||
int args=0;
|
|
||||||
if (p_arg5.get_type()!=Variant::NIL)
|
|
||||||
args=5;
|
|
||||||
else if (p_arg4.get_type()!=Variant::NIL)
|
|
||||||
args=4;
|
|
||||||
else if (p_arg3.get_type()!=Variant::NIL)
|
|
||||||
args=3;
|
|
||||||
else if (p_arg2.get_type()!=Variant::NIL)
|
|
||||||
args=2;
|
|
||||||
else if (p_arg1.get_type()!=Variant::NIL)
|
|
||||||
args=1;
|
|
||||||
else
|
|
||||||
args=0;
|
|
||||||
|
|
||||||
room_needed+=sizeof(Variant)*args;
|
|
||||||
|
|
||||||
if ((buffer_end+room_needed) >= buffer_size) {
|
if ((buffer_end+room_needed) >= buffer_size) {
|
||||||
String type;
|
String type;
|
||||||
@ -65,55 +50,45 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName& p_method, VARIANT
|
|||||||
statistics();
|
statistics();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY );
|
||||||
Message * msg = memnew_placement( &buffer[ buffer_end ], Message );
|
Message * msg = memnew_placement( &buffer[ buffer_end ], Message );
|
||||||
msg->args=args;
|
msg->args=p_argcount;
|
||||||
msg->instance_ID=p_id;
|
msg->instance_ID=p_id;
|
||||||
msg->target=p_method;
|
msg->target=p_method;
|
||||||
msg->type=TYPE_CALL;
|
msg->type=TYPE_CALL;
|
||||||
|
if (p_show_error)
|
||||||
|
msg->type|=FLAG_SHOW_ERROR;
|
||||||
|
|
||||||
buffer_end+=sizeof(Message);
|
buffer_end+=sizeof(Message);
|
||||||
|
|
||||||
|
for(int i=0;i<p_argcount;i++) {
|
||||||
if (args>=1) {
|
|
||||||
|
|
||||||
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
||||||
buffer_end+=sizeof(Variant);
|
buffer_end+=sizeof(Variant);
|
||||||
*v=p_arg1;
|
*v=*p_args[i];
|
||||||
}
|
|
||||||
|
|
||||||
if (args>=2) {
|
|
||||||
|
|
||||||
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
|
||||||
buffer_end+=sizeof(Variant);
|
|
||||||
*v=p_arg2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args>=3) {
|
|
||||||
|
|
||||||
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
|
||||||
buffer_end+=sizeof(Variant);
|
|
||||||
*v=p_arg3;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args>=4) {
|
|
||||||
|
|
||||||
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
|
||||||
buffer_end+=sizeof(Variant);
|
|
||||||
*v=p_arg4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args>=5) {
|
|
||||||
|
|
||||||
Variant * v = memnew_placement( &buffer[ buffer_end ], Variant );
|
|
||||||
buffer_end+=sizeof(Variant);
|
|
||||||
*v=p_arg5;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_set(ObjectID p_id, const StringName& p_prop, const Variant& p_value) {
|
Error MessageQueue::push_set(ObjectID p_id, const StringName& p_prop, const Variant& p_value) {
|
||||||
|
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
@ -212,7 +187,7 @@ void MessageQueue::statistics() {
|
|||||||
if (target!=NULL) {
|
if (target!=NULL) {
|
||||||
|
|
||||||
|
|
||||||
switch(message->type) {
|
switch(message->type&FLAG_MASK) {
|
||||||
|
|
||||||
case TYPE_CALL: {
|
case TYPE_CALL: {
|
||||||
|
|
||||||
@ -251,7 +226,7 @@ void MessageQueue::statistics() {
|
|||||||
|
|
||||||
|
|
||||||
read_pos+=sizeof(Message);
|
read_pos+=sizeof(Message);
|
||||||
if (message->type!=TYPE_NOTIFICATION)
|
if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION)
|
||||||
read_pos+=sizeof(Variant)*message->args;
|
read_pos+=sizeof(Variant)*message->args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +297,26 @@ int MessageQueue::get_max_buffer_usage() const {
|
|||||||
return buffer_max_used;
|
return buffer_max_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MessageQueue::_call_function(Object* p_target, const StringName& p_func, const Variant *p_args, int p_argcount,bool p_show_error) {
|
||||||
|
|
||||||
|
const Variant **argptrs=NULL;
|
||||||
|
if (p_argcount) {
|
||||||
|
argptrs = (const Variant**)alloca(sizeof(Variant*)*p_argcount);
|
||||||
|
for(int i=0;i<p_argcount;i++) {
|
||||||
|
argptrs[i]=&p_args[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant::CallError ce;
|
||||||
|
p_target->call(p_func,argptrs,p_argcount,ce);
|
||||||
|
if (p_show_error && ce.error!=Variant::CallError::CALL_OK) {
|
||||||
|
|
||||||
|
ERR_PRINTS("Error calling deferred method: "+Variant::get_call_error_text(p_target,p_func,argptrs,p_argcount,ce));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MessageQueue::flush() {
|
void MessageQueue::flush() {
|
||||||
|
|
||||||
|
|
||||||
@ -347,7 +342,7 @@ void MessageQueue::flush() {
|
|||||||
|
|
||||||
if (target!=NULL) {
|
if (target!=NULL) {
|
||||||
|
|
||||||
switch(message->type) {
|
switch(message->type&FLAG_MASK) {
|
||||||
case TYPE_CALL: {
|
case TYPE_CALL: {
|
||||||
|
|
||||||
Variant *args= (Variant*)(message+1);
|
Variant *args= (Variant*)(message+1);
|
||||||
@ -355,12 +350,7 @@ void MessageQueue::flush() {
|
|||||||
// messages don't expect a return value
|
// messages don't expect a return value
|
||||||
|
|
||||||
|
|
||||||
target->call( message->target,
|
_call_function(target,message->target,args,message->args,message->type&FLAG_SHOW_ERROR);
|
||||||
(message->args>=1) ? args[0] : Variant(),
|
|
||||||
(message->args>=2) ? args[1] : Variant(),
|
|
||||||
(message->args>=3) ? args[2] : Variant(),
|
|
||||||
(message->args>=4) ? args[3] : Variant(),
|
|
||||||
(message->args>=5) ? args[4] : Variant() );
|
|
||||||
|
|
||||||
for(int i=0;i<message->args;i++) {
|
for(int i=0;i<message->args;i++) {
|
||||||
args[i].~Variant();
|
args[i].~Variant();
|
||||||
@ -386,7 +376,7 @@ void MessageQueue::flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t advance = sizeof(Message);
|
uint32_t advance = sizeof(Message);
|
||||||
if (message->type!=TYPE_NOTIFICATION)
|
if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION)
|
||||||
advance+=sizeof(Variant)*message->args;
|
advance+=sizeof(Variant)*message->args;
|
||||||
message->~Message();
|
message->~Message();
|
||||||
|
|
||||||
@ -423,14 +413,14 @@ MessageQueue::~MessageQueue() {
|
|||||||
Message *message = (Message*)&buffer[ read_pos ];
|
Message *message = (Message*)&buffer[ read_pos ];
|
||||||
Variant *args= (Variant*)(message+1);
|
Variant *args= (Variant*)(message+1);
|
||||||
int argc = message->args;
|
int argc = message->args;
|
||||||
if (message->type!=TYPE_NOTIFICATION) {
|
if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION) {
|
||||||
for (int i=0;i<argc;i++)
|
for (int i=0;i<argc;i++)
|
||||||
args[i].~Variant();
|
args[i].~Variant();
|
||||||
}
|
}
|
||||||
message->~Message();
|
message->~Message();
|
||||||
|
|
||||||
read_pos+=sizeof(Message);
|
read_pos+=sizeof(Message);
|
||||||
if (message->type!=TYPE_NOTIFICATION)
|
if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION)
|
||||||
read_pos+=sizeof(Variant)*message->args;
|
read_pos+=sizeof(Variant)*message->args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,10 @@ class MessageQueue {
|
|||||||
enum {
|
enum {
|
||||||
TYPE_CALL,
|
TYPE_CALL,
|
||||||
TYPE_NOTIFICATION,
|
TYPE_NOTIFICATION,
|
||||||
TYPE_SET
|
TYPE_SET,
|
||||||
|
FLAG_SHOW_ERROR=1<<14,
|
||||||
|
FLAG_MASK=FLAG_SHOW_ERROR-1
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message {
|
struct Message {
|
||||||
@ -65,12 +68,14 @@ class MessageQueue {
|
|||||||
uint32_t buffer_max_used;
|
uint32_t buffer_max_used;
|
||||||
uint32_t buffer_size;
|
uint32_t buffer_size;
|
||||||
|
|
||||||
|
void _call_function(Object* p_target,const StringName& p_func,const Variant *p_args,int p_argcount,bool p_show_error);
|
||||||
|
|
||||||
static MessageQueue *singleton;
|
static MessageQueue *singleton;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static MessageQueue *get_singleton();
|
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_call(ObjectID p_id, const StringName& p_method, VARIANT_ARG_LIST);
|
||||||
Error push_notification(ObjectID p_id, int p_notification);
|
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_set(ObjectID p_id, const StringName& p_prop, const Variant& p_value);
|
||||||
|
124
core/object.cpp
124
core/object.cpp
@ -512,17 +512,10 @@ Variant Object::_call_deferred_bind(const Variant** p_args, int p_argcount, Vari
|
|||||||
|
|
||||||
r_error.error=Variant::CallError::CALL_OK;
|
r_error.error=Variant::CallError::CALL_OK;
|
||||||
|
|
||||||
StringName signal = *p_args[0];
|
StringName method = *p_args[0];
|
||||||
|
|
||||||
Variant v[VARIANT_ARG_MAX];
|
MessageQueue::get_singleton()->push_call(get_instance_ID(),method,&p_args[1],p_argcount-1);
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<MIN(5,p_argcount-1);i++) {
|
|
||||||
|
|
||||||
v[i]=*p_args[i+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
call_deferred(signal,v[0],v[1],v[2],v[3],v[4]);
|
|
||||||
return Variant();
|
return Variant();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -839,6 +832,8 @@ void Object::call_multilevel(const StringName& p_name, VARIANT_ARG_DECLARE) {
|
|||||||
|
|
||||||
Variant Object::call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) {
|
Variant Object::call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) {
|
||||||
|
|
||||||
|
r_error.error=Variant::CallError::CALL_OK;
|
||||||
|
|
||||||
if (p_method==CoreStringNames::get_singleton()->_free) {
|
if (p_method==CoreStringNames::get_singleton()->_free) {
|
||||||
//free must be here, before anything, always ready
|
//free must be here, before anything, always ready
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
@ -1130,21 +1125,22 @@ Variant Object::_emit_signal(const Variant** p_args, int p_argcount, Variant::Ca
|
|||||||
|
|
||||||
StringName signal = *p_args[0];
|
StringName signal = *p_args[0];
|
||||||
|
|
||||||
Variant v[VARIANT_ARG_MAX];
|
|
||||||
|
|
||||||
|
const Variant**args=NULL;
|
||||||
|
|
||||||
for(int i=0;i<MIN(5,p_argcount-1);i++) {
|
int argc=p_argcount-1;
|
||||||
|
if (argc) {
|
||||||
v[i]=*p_args[i+1];
|
args=&p_args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_signal(signal,v[0],v[1],v[2],v[3],v[4]);
|
emit_signal(signal,args,argc);
|
||||||
|
|
||||||
return Variant();
|
return Variant();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Object::emit_signal(const StringName& p_name,const Variant** p_args,int p_argcount) {
|
||||||
void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|
||||||
|
|
||||||
if (_block_signals)
|
if (_block_signals)
|
||||||
return; //no emit, signals blocked
|
return; //no emit, signals blocked
|
||||||
@ -1167,10 +1163,12 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|||||||
|
|
||||||
OBJ_DEBUG_LOCK
|
OBJ_DEBUG_LOCK
|
||||||
|
|
||||||
|
Vector<const Variant*> bind_mem;
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<ssize;i++) {
|
for(int i=0;i<ssize;i++) {
|
||||||
|
|
||||||
const Connection &c = slot_map.getv(i).conn;
|
const Connection &c = slot_map.getv(i).conn;
|
||||||
VARIANT_ARGPTRS
|
|
||||||
|
|
||||||
Object *target;
|
Object *target;
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
@ -1181,21 +1179,37 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int bind_count=c.binds.size();
|
const Variant **args=p_args;
|
||||||
int bind=0;
|
int argc=p_argcount;
|
||||||
|
|
||||||
for(int i=0;bind < bind_count && i<VARIANT_ARG_MAX;i++) {
|
if (c.binds.size()) {
|
||||||
|
//handle binds
|
||||||
|
bind_mem.resize(p_argcount+c.binds.size());
|
||||||
|
|
||||||
if (argptr[i]->get_type()==Variant::NIL) {
|
for(int j=0;j<p_argcount;j++) {
|
||||||
argptr[i]=&c.binds[bind];
|
bind_mem[j]=p_args[j];
|
||||||
bind++;
|
|
||||||
}
|
}
|
||||||
|
for(int j=0;j<c.binds.size();j++) {
|
||||||
|
bind_mem[p_argcount+j]=&c.binds[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
args=bind_mem.ptr();
|
||||||
|
argc=bind_mem.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.flags&CONNECT_DEFERRED) {
|
if (c.flags&CONNECT_DEFERRED) {
|
||||||
MessageQueue::get_singleton()->push_call(target->get_instance_ID(),c.method,VARIANT_ARGPTRS_PASS);
|
MessageQueue::get_singleton()->push_call(target->get_instance_ID(),c.method,args,argc,true);
|
||||||
} else {
|
} else {
|
||||||
target->call( c.method, VARIANT_ARGPTRS_PASS );
|
Variant::CallError ce;
|
||||||
|
target->call( c.method, args, argc,ce );
|
||||||
|
if (ce.error!=Variant::CallError::CALL_OK) {
|
||||||
|
|
||||||
|
if (ce.error==Variant::CallError::CALL_ERROR_INVALID_METHOD && !ObjectTypeDB::type_exists( target->get_type_name() ) ) {
|
||||||
|
//most likely object is not initialized yet, do not throw error.
|
||||||
|
} else {
|
||||||
|
ERR_PRINTS("Error calling method from signal '"+String(p_name)+"': "+Variant::get_call_error_text(target,c.method,args,argc,ce));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.flags&CONNECT_ONESHOT) {
|
if (c.flags&CONNECT_ONESHOT) {
|
||||||
@ -1208,51 +1222,7 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
//old (deprecated and dangerous code)
|
|
||||||
s->lock++;
|
|
||||||
for( Map<Signal::Target,Signal::Slot>::Element *E = s->slot_map.front();E;E=E->next() ) {
|
|
||||||
|
|
||||||
const Signal::Target& t = E->key();
|
|
||||||
const Signal::Slot& s = E->get();
|
|
||||||
const Connection &c = s.cE->get();
|
|
||||||
|
|
||||||
VARIANT_ARGPTRS
|
|
||||||
|
|
||||||
int bind_count=c.binds.size();
|
|
||||||
int bind=0;
|
|
||||||
|
|
||||||
for(int i=0;bind < bind_count && i<VARIANT_ARG_MAX;i++) {
|
|
||||||
|
|
||||||
if (argptr[i]->get_type()==Variant::NIL) {
|
|
||||||
argptr[i]=&c.binds[bind];
|
|
||||||
bind++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.flags&CONNECT_DEFERRED) {
|
|
||||||
MessageQueue::get_singleton()->push_call(t._id,t.method,VARIANT_ARGPTRS_PASS);
|
|
||||||
} else {
|
|
||||||
Object *obj = ObjectDB::get_instance(t._id);
|
|
||||||
ERR_CONTINUE(!obj); //yeah this should always be here
|
|
||||||
obj->call( t.method, VARIANT_ARGPTRS_PASS );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.flags&CONNECT_ONESHOT) {
|
|
||||||
_ObjectSignalDisconnectData dd;
|
|
||||||
dd.signal=p_name;
|
|
||||||
dd.target=ObjectDB::get_instance(t._id);
|
|
||||||
dd.method=t.method;
|
|
||||||
disconnect_data.push_back(dd);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
s->lock--;
|
|
||||||
#endif
|
|
||||||
while (!disconnect_data.empty()) {
|
while (!disconnect_data.empty()) {
|
||||||
|
|
||||||
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
|
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
|
||||||
@ -1262,6 +1232,22 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void 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++;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_signal(p_name,argptr,argc);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Object::_add_user_signal(const String& p_name, const Array& p_args) {
|
void Object::_add_user_signal(const String& p_name, const Array& p_args) {
|
||||||
|
|
||||||
|
@ -593,6 +593,7 @@ public:
|
|||||||
|
|
||||||
void add_user_signal(const MethodInfo& p_signal);
|
void add_user_signal(const MethodInfo& p_signal);
|
||||||
void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
|
void emit_signal(const StringName& p_name,VARIANT_ARG_LIST);
|
||||||
|
void emit_signal(const StringName& p_name, const Variant** p_args, int p_argcount);
|
||||||
void get_signal_list(List<MethodInfo> *p_signals ) const;
|
void get_signal_list(List<MethodInfo> *p_signals ) const;
|
||||||
void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
|
void get_signal_connection_list(const StringName& p_signal,List<Connection> *p_connections) const;
|
||||||
void get_all_signal_connections(List<Connection> *p_connections) const;
|
void get_all_signal_connections(List<Connection> *p_connections) const;
|
||||||
|
@ -2992,3 +2992,32 @@ String Variant::get_construct_string() const {
|
|||||||
return vars;
|
return vars;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String Variant::get_call_error_text(Object* p_base, const StringName& p_method,const Variant** p_argptrs,int p_argcount,const Variant::CallError &ce) {
|
||||||
|
|
||||||
|
|
||||||
|
String err_text;
|
||||||
|
|
||||||
|
if (ce.error==Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
|
||||||
|
int errorarg=ce.argument;
|
||||||
|
err_text="Cannot convert argument "+itos(errorarg+1)+" from "+Variant::get_type_name(p_argptrs[errorarg]->get_type())+" to "+Variant::get_type_name(ce.expected)+".";
|
||||||
|
} else if (ce.error==Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) {
|
||||||
|
err_text="Expected "+itos(ce.argument)+" arguments.";
|
||||||
|
} else if (ce.error==Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) {
|
||||||
|
err_text="Expected "+itos(ce.argument)+" arguments.";
|
||||||
|
} else if (ce.error==Variant::CallError::CALL_ERROR_INVALID_METHOD) {
|
||||||
|
err_text="Method not found.";
|
||||||
|
} else if (ce.error==Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) {
|
||||||
|
err_text="Instance is null";
|
||||||
|
} else if (ce.error==Variant::CallError::CALL_OK){
|
||||||
|
return "Call OK";
|
||||||
|
}
|
||||||
|
|
||||||
|
String class_name = p_base->get_type();
|
||||||
|
Ref<Script> script = p_base->get_script();
|
||||||
|
if (script.is_valid() && script->get_path().is_resource_file()) {
|
||||||
|
|
||||||
|
class_name+="("+script->get_path().get_file()+")";
|
||||||
|
}
|
||||||
|
return "'"+class_name+"::"+String(p_method)+"': "+err_text;
|
||||||
|
}
|
||||||
|
@ -390,6 +390,9 @@ public:
|
|||||||
|
|
||||||
Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error);
|
Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,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());
|
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());
|
||||||
|
|
||||||
|
static String get_call_error_text(Object* p_base, const StringName& p_method,const Variant** p_argptrs,int p_argcount,const Variant::CallError &ce);
|
||||||
|
|
||||||
static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error,bool p_strict=true);
|
static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error,bool p_strict=true);
|
||||||
|
|
||||||
void get_method_list(List<MethodInfo> *p_list) const;
|
void get_method_list(List<MethodInfo> *p_list) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user