diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/command_queue_mt.h | 2 | ||||
-rw-r--r-- | core/input_map.cpp | 2 | ||||
-rw-r--r-- | core/math/math_funcs.cpp | 10 | ||||
-rw-r--r-- | core/message_queue.cpp | 104 | ||||
-rw-r--r-- | core/message_queue.h | 7 | ||||
-rw-r--r-- | core/object.cpp | 120 | ||||
-rw-r--r-- | core/object.h | 1 | ||||
-rw-r--r-- | core/script_language.h | 1 | ||||
-rw-r--r-- | core/ustring.cpp | 10 | ||||
-rw-r--r-- | core/ustring.h | 2 | ||||
-rw-r--r-- | core/variant.cpp | 40 | ||||
-rw-r--r-- | core/variant.h | 4 | ||||
-rw-r--r-- | core/variant_parser.cpp | 1 |
13 files changed, 171 insertions, 133 deletions
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index 84c3687b08..4fd33e3a55 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -983,7 +983,7 @@ public: void flush_all() { - ERR_FAIL_COND(sync); + //ERR_FAIL_COND(sync); lock(); while (true) { bool exit = !flush_one(); diff --git a/core/input_map.cpp b/core/input_map.cpp index fc66d97a86..d4560a1e1b 100644 --- a/core/input_map.cpp +++ b/core/input_map.cpp @@ -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_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; } diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp index 2f0c1a6512..20d9db3375 100644 --- a/core/math/math_funcs.cpp +++ b/core/math/math_funcs.cpp @@ -207,9 +207,15 @@ double Math::ceil(double p_x) { int Math::decimals(double p_step) { int max=4; + double llimit = Math::pow(0.1,max); + double ulimit = 1.0-llimit; int i=0; - while( (p_step - Math::floor(p_step)) != 0.0 && max) { - + while( max) { + + float d = absf(p_step) - Math::floor(absf(p_step)); + + if (d<llimit || d>ulimit) + break; p_step*=10.0; max--; i++; diff --git a/core/message_queue.cpp b/core/message_queue.cpp index 8f2dd622ad..c69021f4f0 100644 --- a/core/message_queue.cpp +++ b/core/message_queue.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "message_queue.h" #include "globals.h" - +#include "script_language.h" MessageQueue *MessageQueue::singleton=NULL; MessageQueue *MessageQueue::get_singleton() { @@ -36,26 +36,11 @@ MessageQueue *MessageQueue::get_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_ - uint8_t room_needed=sizeof(Message); - 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; + int room_needed=sizeof(Message)+sizeof(Variant)*p_argcount; if ((buffer_end+room_needed) >= buffer_size) { String type; @@ -65,53 +50,43 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName& p_method, VARIANT statistics(); } + ERR_FAIL_COND_V( (buffer_end+room_needed) >= buffer_size , ERR_OUT_OF_MEMORY ); Message * msg = memnew_placement( &buffer[ buffer_end ], Message ); - msg->args=args; + msg->args=p_argcount; msg->instance_ID=p_id; msg->target=p_method; msg->type=TYPE_CALL; - buffer_end+=sizeof(Message); + if (p_show_error) + msg->type|=FLAG_SHOW_ERROR; + buffer_end+=sizeof(Message); - if (args>=1) { + for(int i=0;i<p_argcount;i++) { Variant * v = memnew_placement( &buffer[ buffer_end ], Variant ); buffer_end+=sizeof(Variant); - *v=p_arg1; - } - - if (args>=2) { + *v=*p_args[i]; - Variant * v = memnew_placement( &buffer[ buffer_end ], Variant ); - buffer_end+=sizeof(Variant); - *v=p_arg2; } - if (args>=3) { + return OK; +} - Variant * v = memnew_placement( &buffer[ buffer_end ], Variant ); - buffer_end+=sizeof(Variant); - *v=p_arg3; +Error MessageQueue::push_call(ObjectID p_id, const StringName& p_method, VARIANT_ARG_DECLARE) { - } + VARIANT_ARGPTRS; - if (args>=4) { + int argc=0; - Variant * v = memnew_placement( &buffer[ buffer_end ], Variant ); - buffer_end+=sizeof(Variant); - *v=p_arg4; + for(int i=0;i<VARIANT_ARG_MAX;i++) { + if (argptr[i]->get_type()==Variant::NIL) + break; + argc++; } - if (args>=5) { + return push_call(p_id,p_method,argptr,argc,false); - Variant * v = memnew_placement( &buffer[ buffer_end ], Variant ); - buffer_end+=sizeof(Variant); - *v=p_arg5; - } - - - return OK; } Error MessageQueue::push_set(ObjectID p_id, const StringName& p_prop, const Variant& p_value) { @@ -212,7 +187,7 @@ void MessageQueue::statistics() { if (target!=NULL) { - switch(message->type) { + switch(message->type&FLAG_MASK) { case TYPE_CALL: { @@ -251,7 +226,7 @@ void MessageQueue::statistics() { read_pos+=sizeof(Message); - if (message->type!=TYPE_NOTIFICATION) + if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION) read_pos+=sizeof(Variant)*message->args; } @@ -322,6 +297,26 @@ int MessageQueue::get_max_buffer_usage() const { 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() { @@ -347,7 +342,7 @@ void MessageQueue::flush() { if (target!=NULL) { - switch(message->type) { + switch(message->type&FLAG_MASK) { case TYPE_CALL: { Variant *args= (Variant*)(message+1); @@ -355,12 +350,7 @@ void MessageQueue::flush() { // messages don't expect a return value - target->call( message->target, - (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() ); + _call_function(target,message->target,args,message->args,message->type&FLAG_SHOW_ERROR); for(int i=0;i<message->args;i++) { args[i].~Variant(); @@ -386,7 +376,7 @@ void MessageQueue::flush() { } uint32_t advance = sizeof(Message); - if (message->type!=TYPE_NOTIFICATION) + if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION) advance+=sizeof(Variant)*message->args; message->~Message(); @@ -423,14 +413,14 @@ MessageQueue::~MessageQueue() { Message *message = (Message*)&buffer[ read_pos ]; Variant *args= (Variant*)(message+1); int argc = message->args; - if (message->type!=TYPE_NOTIFICATION) { + if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION) { for (int i=0;i<argc;i++) args[i].~Variant(); } message->~Message(); read_pos+=sizeof(Message); - if (message->type!=TYPE_NOTIFICATION) + if ((message->type&FLAG_MASK)!=TYPE_NOTIFICATION) read_pos+=sizeof(Variant)*message->args; } diff --git a/core/message_queue.h b/core/message_queue.h index b6b74d2bd2..6a3ec79732 100644 --- a/core/message_queue.h +++ b/core/message_queue.h @@ -46,7 +46,10 @@ class MessageQueue { enum { TYPE_CALL, TYPE_NOTIFICATION, - TYPE_SET + TYPE_SET, + FLAG_SHOW_ERROR=1<<14, + FLAG_MASK=FLAG_SHOW_ERROR-1 + }; struct Message { @@ -65,12 +68,14 @@ class MessageQueue { uint32_t buffer_max_used; 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; 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_notification(ObjectID p_id, int p_notification); Error push_set(ObjectID p_id, const StringName& p_prop, const Variant& p_value); diff --git a/core/object.cpp b/core/object.cpp index ad9fdf73b9..c92fc35b24 100644 --- a/core/object.cpp +++ b/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; - StringName signal = *p_args[0]; - - Variant v[VARIANT_ARG_MAX]; - - - for(int i=0;i<MIN(5,p_argcount-1);i++) { + StringName method = *p_args[0]; - v[i]=*p_args[i+1]; - } + MessageQueue::get_singleton()->push_call(get_instance_ID(),method,&p_args[1],p_argcount-1); - call_deferred(signal,v[0],v[1],v[2],v[3],v[4]); 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) { + r_error.error=Variant::CallError::CALL_OK; + if (p_method==CoreStringNames::get_singleton()->_free) { //free must be here, before anything, always ready #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]; - Variant v[VARIANT_ARG_MAX]; - - for(int i=0;i<MIN(5,p_argcount-1);i++) { + const Variant**args=NULL; - v[i]=*p_args[i+1]; + int argc=p_argcount-1; + if (argc) { + args=&p_args[1]; } - emit_signal(signal,v[0],v[1],v[2],v[3],v[4]); + emit_signal(signal,args,argc); + return Variant(); -} +} -void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) { +void Object::emit_signal(const StringName& p_name,const Variant** p_args,int p_argcount) { if (_block_signals) return; //no emit, signals blocked @@ -1167,10 +1163,12 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) { OBJ_DEBUG_LOCK + Vector<const Variant*> bind_mem; + + for(int i=0;i<ssize;i++) { const Connection &c = slot_map.getv(i).conn; - VARIANT_ARGPTRS Object *target; #ifdef DEBUG_ENABLED @@ -1181,21 +1179,37 @@ void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) { #endif - int bind_count=c.binds.size(); - int bind=0; + const Variant **args=p_args; + 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) { - argptr[i]=&c.binds[bind]; - bind++; + for(int j=0;j<p_argcount;j++) { + bind_mem[j]=p_args[j]; + } + 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) { - 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 { - 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) { @@ -1208,57 +1222,29 @@ 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 + while (!disconnect_data.empty()) { - int bind_count=c.binds.size(); - int bind=0; + const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get(); + disconnect(dd.signal,dd.target,dd.method); + disconnect_data.pop_front(); + } - 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++; - } - } +void Object::emit_signal(const StringName& p_name,VARIANT_ARG_DECLARE) { - 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 ); - } + VARIANT_ARGPTRS; - 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); - } + int argc=0; + for(int i=0;i<VARIANT_ARG_MAX;i++) { + if (argptr[i]->get_type()==Variant::NIL) + break; + argc++; } - - - s->lock--; -#endif - while (!disconnect_data.empty()) { - - const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get(); - disconnect(dd.signal,dd.target,dd.method); - disconnect_data.pop_front(); - } + emit_signal(p_name,argptr,argc); } diff --git a/core/object.h b/core/object.h index 38a91d7898..dcebf9b2a2 100644 --- a/core/object.h +++ b/core/object.h @@ -593,6 +593,7 @@ public: 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, const Variant** p_args, int p_argcount); 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_all_signal_connections(List<Connection> *p_connections) const; diff --git a/core/script_language.h b/core/script_language.h index a179949c19..3138c88e8e 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -98,6 +98,7 @@ public: virtual bool has_script_signal(const StringName& p_signal) const=0; virtual void get_script_signal_list(List<MethodInfo> *r_signals) const=0; + virtual bool get_property_default_value(const StringName& p_property,Variant& r_value) const=0; virtual void update_exports() {} //editor tool diff --git a/core/ustring.cpp b/core/ustring.cpp index c93fb80ca8..21c0d78fdb 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1636,12 +1636,16 @@ int64_t String::to_int64() const { return integer*sign; } -int String::to_int(const char* p_str) { +int String::to_int(const char* p_str,int p_len) { int to=0; - while(p_str[to]!=0 && p_str[to]!='.') - to++; + if (p_len>=0) + to=p_len; + else { + while(p_str[to]!=0 && p_str[to]!='.') + to++; + } int integer=0; diff --git a/core/ustring.h b/core/ustring.h index 4c76b8e863..2b967d368a 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -144,7 +144,7 @@ public: int to_int() const; int64_t to_int64() const; - static int to_int(const char* p_str); + static int to_int(const char* p_str, int p_len=-1); static double to_double(const char* p_str); static double to_double(const CharType* p_str, const CharType **r_end=NULL); static int64_t to_int(const CharType* p_str,int p_len=-1); diff --git a/core/variant.cpp b/core/variant.cpp index ab560e0d45..3bd8d80528 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -706,6 +706,17 @@ bool Variant::operator==(const Variant& p_variant) const { } +bool Variant::operator!=(const Variant& p_variant) const { + + if (type!=p_variant.type) //evaluation of operator== needs to be more strict + return true; + bool v; + Variant r; + evaluate(OP_NOT_EQUAL,*this,p_variant,r,v); + return r; + +} + bool Variant::operator<(const Variant& p_variant) const { if (type!=p_variant.type) //if types differ, then order by type first return type<p_variant.type; @@ -2981,3 +2992,32 @@ String Variant::get_construct_string() const { 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; +} diff --git a/core/variant.h b/core/variant.h index 05bb5a7328..b58c781bdd 100644 --- a/core/variant.h +++ b/core/variant.h @@ -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_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); void get_method_list(List<MethodInfo> *p_list) const; @@ -411,6 +414,7 @@ public: //argsVariant call() bool operator==(const Variant& p_variant) const; + bool operator!=(const Variant& p_variant) const; bool operator<(const Variant& p_variant) const; uint32_t hash() const; diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 9f2727d33d..9a494b4d57 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1634,6 +1634,7 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r //assign.. + r_assign=""; String what; while(true) { |