diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/array.cpp | 24 | ||||
-rw-r--r-- | core/array.h | 3 | ||||
-rw-r--r-- | core/global_constants.cpp | 1 | ||||
-rw-r--r-- | core/io/unzip.c | 17 | ||||
-rw-r--r-- | core/object.h | 1 | ||||
-rw-r--r-- | core/os/file_access.cpp | 2 | ||||
-rw-r--r-- | core/os/file_access.h | 8 | ||||
-rw-r--r-- | core/script_language.cpp | 12 | ||||
-rw-r--r-- | core/script_language.h | 5 | ||||
-rw-r--r-- | core/ustring.cpp | 44 | ||||
-rw-r--r-- | core/ustring.h | 3 | ||||
-rw-r--r-- | core/variant.cpp | 4 | ||||
-rw-r--r-- | core/variant_call.cpp | 10 | ||||
-rw-r--r-- | core/variant_parser.cpp | 40 | ||||
-rw-r--r-- | core/vector.h | 10 |
15 files changed, 147 insertions, 37 deletions
diff --git a/core/array.cpp b/core/array.cpp index 1d283a14aa..bb8e527304 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -150,17 +150,26 @@ void Array::erase(const Variant& p_value) { _p->array.erase(p_value); } -int Array::find(const Variant& p_value) const { +int Array::find(const Variant& p_value, int p_from) const { - return _p->array.find(p_value); + return _p->array.find(p_value, p_from); } -int Array::find_last(const Variant& p_value) const { +int Array::rfind(const Variant& p_value, int p_from) const { - if(_p->array.size() == 0) + if (_p->array.size() == 0) return -1; - for (int i=_p->array.size()-1; i>=0; i--) { + if (p_from < 0) { + // Relative offset from the end + p_from = _p->array.size() + p_from; + } + if (p_from < 0 || p_from >= _p->array.size()) { + // Limit to array boundaries + p_from = _p->array.size() - 1; + } + + for (int i=p_from; i>=0; i--) { if(_p->array[i] == p_value){ return i; @@ -170,6 +179,11 @@ int Array::find_last(const Variant& p_value) const { return -1; } +int Array::find_last(const Variant& p_value) const { + + return rfind(p_value); +} + int Array::count(const Variant& p_value) const { if(_p->array.size() == 0) diff --git a/core/array.h b/core/array.h index 9472a6dd21..096660653e 100644 --- a/core/array.h +++ b/core/array.h @@ -71,7 +71,8 @@ public: void sort_custom(Object *p_obj,const StringName& p_function); void invert(); - int find(const Variant& p_value) const; + int find(const Variant& p_value, int p_from=0) const; + int rfind(const Variant& p_value, int p_from=-1) const; int find_last(const Variant& p_value) const; int count(const Variant& p_value) const; diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 63764383ff..2594be63ac 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -489,6 +489,7 @@ static _GlobalConstant _global_constants[]={ BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONONE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NO_INSTANCE_STATE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_RESTART_IF_CHANGED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_SCRIPT_VARIABLE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT_INTL ), diff --git a/core/io/unzip.c b/core/io/unzip.c index 78672677f9..7aa0a86d13 100644 --- a/core/io/unzip.c +++ b/core/io/unzip.c @@ -1031,10 +1031,19 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file, if (lSeek!=0) { - if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; + if (lSeek<0) { + // WORKAROUND for backwards seeking + z_off_t pos = ZTELL64(s->z_filefunc, s->filestream); + if (ZSEEK64(s->z_filefunc, s->filestream,pos+lSeek,ZLIB_FILEFUNC_SEEK_SET)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } else { + if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + } } while(acc < file_info.size_file_extra) diff --git a/core/object.h b/core/object.h index 9359f4d4b2..a27e8c7dd8 100644 --- a/core/object.h +++ b/core/object.h @@ -86,6 +86,7 @@ enum PropertyUsageFlags { PROPERTY_USAGE_STORE_IF_NONONE=1024, //only store if false PROPERTY_USAGE_NO_INSTANCE_STATE=2048, PROPERTY_USAGE_RESTART_IF_CHANGED=4096, + PROPERTY_USAGE_SCRIPT_VARIABLE=8192, PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED, diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index a3ee9395de..1f23e8f33d 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -35,6 +35,8 @@ FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX]={0,0}; +FileAccess::FileCloseFailNotify FileAccess::close_fail_notify=NULL; + bool FileAccess::backup_save=false; diff --git a/core/os/file_access.h b/core/os/file_access.h index 2c894c94eb..8d5823663e 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -47,6 +47,8 @@ public: ACCESS_MAX }; + typedef void (*FileCloseFailNotify)(const String&); + typedef FileAccess*(*CreateFunc)(); bool endian_swap; bool real_is_double; @@ -56,7 +58,7 @@ protected: virtual Error _open(const String& p_path, int p_mode_flags)=0; ///< open a file virtual uint64_t _get_modified_time(const String& p_file)=0; - + static FileCloseFailNotify close_fail_notify; private: static bool backup_save; @@ -69,8 +71,12 @@ private: return memnew( T ); } + + public: + static void set_file_close_fail_notify_callback(FileCloseFailNotify p_cbk) { close_fail_notify=p_cbk; } + virtual void _set_access_type(AccessType p_access); enum ModeFlags { diff --git a/core/script_language.cpp b/core/script_language.cpp index b3116a0297..68a694398a 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -32,7 +32,7 @@ ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES]; int ScriptServer::_language_count=0; bool ScriptServer::scripting_enabled=true; - +bool ScriptServer::reload_scripts_on_save=false; void Script::_notification( int p_what) { @@ -92,6 +92,16 @@ void ScriptServer::init_languages() { } } +void ScriptServer::set_reload_scripts_on_save(bool p_enable) { + + reload_scripts_on_save=p_enable; +} + +bool ScriptServer::is_reload_scripts_on_save_enabled() { + + return reload_scripts_on_save; +} + void ScriptInstance::get_property_state(List<Pair<StringName, Variant> > &state) { List<PropertyInfo> pinfo; diff --git a/core/script_language.h b/core/script_language.h index d8b4c61b6c..478ebd88ed 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -47,6 +47,7 @@ class ScriptServer { static ScriptLanguage *_languages[MAX_LANGUAGES]; static int _language_count; static bool scripting_enabled; + static bool reload_scripts_on_save; public: static void set_scripting_enabled(bool p_enabled); @@ -55,6 +56,9 @@ public: static ScriptLanguage *get_language(int p_idx); static void register_language(ScriptLanguage *p_language); + static void set_reload_scripts_on_save(bool p_enable); + static bool is_reload_scripts_on_save_enabled(); + static void init_languages(); }; @@ -192,6 +196,7 @@ public: virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); } virtual void reload_all_scripts()=0; + virtual void reload_tool_script(const Ref<Script>& p_script,bool p_soft_reload)=0; /* LOADER FUNCTIONS */ virtual void get_recognized_extensions(List<String> *p_extensions) const=0; diff --git a/core/ustring.cpp b/core/ustring.cpp index a039ba11cd..309b9e08fa 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2752,6 +2752,50 @@ bool String::begins_with(const char* p_string) const { } +bool String::is_subsequence_of(const String& p_string) const { + + return _base_is_subsequence_of(p_string, false); +} + +bool String::is_subsequence_ofi(const String& p_string) const { + + return _base_is_subsequence_of(p_string, true); +} + +bool String::_base_is_subsequence_of(const String& p_string, bool case_insensitive) const { + + int len=length(); + if (len == 0) { + // Technically an empty string is subsequence of any string + return true; + } + + if (len > p_string.length()) { + return false; + } + + const CharType *src = &operator[](0); + const CharType *tgt = &p_string[0]; + + for (;*src && *tgt;tgt++) { + bool match = false; + if (case_insensitive) { + CharType srcc = _find_lower(*src); + CharType tgtc = _find_lower(*tgt); + match = srcc == tgtc; + } else { + match = *src == *tgt; + } + if (match) { + src++; + if(!*src) { + return true; + } + } + } + + return false; +} static bool _wildcard_match(const CharType* p_pattern, const CharType* p_string,bool p_case_sensitive) { switch (*p_pattern) { diff --git a/core/ustring.h b/core/ustring.h index e03f74f506..fddb77b040 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -66,6 +66,7 @@ class String : public Vector<CharType> { void copy_from(const char *p_cstr); void copy_from(const CharType* p_cstr, int p_clip_to=-1); void copy_from(const CharType& p_char); + bool _base_is_subsequence_of(const String& p_string, bool case_insensitive) const; public: @@ -122,6 +123,8 @@ public: bool begins_with(const String& p_string) const; bool begins_with(const char* p_string) const; bool ends_with(const String& p_string) const; + bool is_subsequence_of(const String& p_string) const; + bool is_subsequence_ofi(const String& p_string) const; String replace_first(String p_key,String p_with) const; String replace(String p_key,String p_with) const; String replacen(String p_key,String p_with) const; diff --git a/core/variant.cpp b/core/variant.cpp index 38f5e69cc0..472d6cf568 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -3029,9 +3029,9 @@ String Variant::get_call_error_text(Object* p_base, const StringName& p_method,c 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."; + err_text="Method expected "+itos(ce.argument)+" arguments, but called with "+itos(p_argcount)+"."; } else if (ce.error==Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { - err_text="Expected "+itos(ce.argument)+" arguments."; + err_text="Method expected "+itos(ce.argument)+" arguments, but called with "+itos(p_argcount)+"."; } 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) { diff --git a/core/variant_call.cpp b/core/variant_call.cpp index d427a80541..94ab93d55c 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -247,6 +247,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1R(String,matchn); VCALL_LOCALMEM1R(String,begins_with); VCALL_LOCALMEM1R(String,ends_with); + VCALL_LOCALMEM1R(String,is_subsequence_of); + VCALL_LOCALMEM1R(String,is_subsequence_ofi); VCALL_LOCALMEM2R(String,replace); VCALL_LOCALMEM2R(String,replacen); VCALL_LOCALMEM2R(String,insert); @@ -464,7 +466,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1(Array,resize); VCALL_LOCALMEM2(Array,insert); VCALL_LOCALMEM1(Array,remove); - VCALL_LOCALMEM1R(Array,find); + VCALL_LOCALMEM2R(Array,find); + VCALL_LOCALMEM2R(Array,rfind); VCALL_LOCALMEM1R(Array,find_last); VCALL_LOCALMEM1R(Array,count); VCALL_LOCALMEM1(Array,erase); @@ -1268,6 +1271,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(STRING,BOOL,String,matchn,STRING,"expr",varray()); ADDFUNC1(STRING,BOOL,String,begins_with,STRING,"text",varray()); ADDFUNC1(STRING,BOOL,String,ends_with,STRING,"text",varray()); + ADDFUNC1(STRING,BOOL,String,is_subsequence_of,STRING,"text",varray()); + ADDFUNC1(STRING,BOOL,String,is_subsequence_ofi,STRING,"text",varray()); ADDFUNC2(STRING,STRING,String,replace,STRING,"what",STRING,"forwhat",varray()); ADDFUNC2(STRING,STRING,String,replacen,STRING,"what",STRING,"forwhat",varray()); @@ -1453,7 +1458,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC2(ARRAY,NIL,Array,insert,INT,"pos",NIL,"value",varray()); ADDFUNC1(ARRAY,NIL,Array,remove,INT,"pos",varray()); ADDFUNC1(ARRAY,NIL,Array,erase,NIL,"value",varray()); - ADDFUNC1(ARRAY,INT,Array,find,NIL,"value",varray()); + ADDFUNC2(ARRAY,INT,Array,find,NIL,"what",INT,"from",varray(0)); + ADDFUNC2(ARRAY,INT,Array,rfind,NIL,"what",INT,"from",varray(-1)); ADDFUNC1(ARRAY,INT,Array,find_last,NIL,"value",varray()); ADDFUNC1(ARRAY,INT,Array,count,NIL,"value",varray()); ADDFUNC0(ARRAY,NIL,Array,pop_back,varray()); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index e2786b8099..875a144fef 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -1789,6 +1789,14 @@ Error VariantParser::parse(Stream *p_stream, Variant& r_ret, String &r_err_str, ////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +static String rtosfix(double p_value) { + + + if (p_value==0.0) + return "0"; //avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist. + else + return rtoss(p_value); +} Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud,EncodeResourceFunc p_encode_res_func,void* p_encode_res_ud) { @@ -1807,7 +1815,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str } break; case Variant::REAL: { - String s = rtoss(p_variant.operator real_t()); + String s = rtosfix(p_variant.operator real_t()); if (s.find(".")==-1 && s.find("e")==-1) s+=".0"; p_store_string_func(p_store_string_ud, s ); @@ -1822,35 +1830,35 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str case Variant::VECTOR2: { Vector2 v = p_variant; - p_store_string_func(p_store_string_ud,"Vector2( "+rtoss(v.x) +", "+rtoss(v.y)+" )" ); + p_store_string_func(p_store_string_ud,"Vector2( "+rtosfix(v.x) +", "+rtosfix(v.y)+" )" ); } break; case Variant::RECT2: { Rect2 aabb = p_variant; - p_store_string_func(p_store_string_ud,"Rect2( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y)+" )" ); + p_store_string_func(p_store_string_ud,"Rect2( "+rtosfix(aabb.pos.x) +", "+rtosfix(aabb.pos.y) +", "+rtosfix(aabb.size.x) +", "+rtosfix(aabb.size.y)+" )" ); } break; case Variant::VECTOR3: { Vector3 v = p_variant; - p_store_string_func(p_store_string_ud,"Vector3( "+rtoss(v.x) +", "+rtoss(v.y)+", "+rtoss(v.z)+" )"); + p_store_string_func(p_store_string_ud,"Vector3( "+rtosfix(v.x) +", "+rtosfix(v.y)+", "+rtosfix(v.z)+" )"); } break; case Variant::PLANE: { Plane p = p_variant; - p_store_string_func(p_store_string_ud,"Plane( "+rtoss(p.normal.x) +", "+rtoss(p.normal.y)+", "+rtoss(p.normal.z)+", "+rtoss(p.d)+" )" ); + p_store_string_func(p_store_string_ud,"Plane( "+rtosfix(p.normal.x) +", "+rtosfix(p.normal.y)+", "+rtosfix(p.normal.z)+", "+rtosfix(p.d)+" )" ); } break; case Variant::_AABB: { AABB aabb = p_variant; - p_store_string_func(p_store_string_ud,"AABB( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.pos.z) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) +", "+rtoss(aabb.size.z)+" )" ); + p_store_string_func(p_store_string_ud,"AABB( "+rtosfix(aabb.pos.x) +", "+rtosfix(aabb.pos.y) +", "+rtosfix(aabb.pos.z) +", "+rtosfix(aabb.size.x) +", "+rtosfix(aabb.size.y) +", "+rtosfix(aabb.size.z)+" )" ); } break; case Variant::QUAT: { Quat quat = p_variant; - p_store_string_func(p_store_string_ud,"Quat( "+rtoss(quat.x)+", "+rtoss(quat.y)+", "+rtoss(quat.z)+", "+rtoss(quat.w)+" )"); + p_store_string_func(p_store_string_ud,"Quat( "+rtosfix(quat.x)+", "+rtosfix(quat.y)+", "+rtosfix(quat.z)+", "+rtosfix(quat.w)+" )"); } break; case Variant::MATRIX32: { @@ -1862,7 +1870,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i!=0 || j!=0) s+=", "; - s+=rtoss( m3.elements[i][j] ); + s+=rtosfix( m3.elements[i][j] ); } } @@ -1878,7 +1886,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i!=0 || j!=0) s+=", "; - s+=rtoss( m3.elements[i][j] ); + s+=rtosfix( m3.elements[i][j] ); } } @@ -1895,11 +1903,11 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i!=0 || j!=0) s+=", "; - s+=rtoss( m3.elements[i][j] ); + s+=rtosfix( m3.elements[i][j] ); } } - s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z); + s=s+", "+rtosfix(t.origin.x) +", "+rtosfix(t.origin.y)+", "+rtosfix(t.origin.z); p_store_string_func(p_store_string_ud,s+" )"); } break; @@ -1908,7 +1916,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str case Variant::COLOR: { Color c = p_variant; - p_store_string_func(p_store_string_ud,"Color( "+rtoss(c.r) +", "+rtoss(c.g)+", "+rtoss(c.b)+", "+rtoss(c.a)+" )"); + p_store_string_func(p_store_string_ud,"Color( "+rtosfix(c.r) +", "+rtosfix(c.g)+", "+rtosfix(c.b)+", "+rtosfix(c.a)+" )"); } break; case Variant::IMAGE: { @@ -2143,7 +2151,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i>0) p_store_string_func(p_store_string_ud,", "); - p_store_string_func(p_store_string_ud,rtoss(ptr[i])); + p_store_string_func(p_store_string_ud,rtosfix(ptr[i])); } p_store_string_func(p_store_string_ud," )"); @@ -2184,7 +2192,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i>0) p_store_string_func(p_store_string_ud,", "); - p_store_string_func(p_store_string_ud,rtoss(ptr[i].x)+", "+rtoss(ptr[i].y) ); + p_store_string_func(p_store_string_ud,rtosfix(ptr[i].x)+", "+rtosfix(ptr[i].y) ); } p_store_string_func(p_store_string_ud," )"); @@ -2202,7 +2210,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i>0) p_store_string_func(p_store_string_ud,", "); - p_store_string_func(p_store_string_ud,rtoss(ptr[i].x)+", "+rtoss(ptr[i].y)+", "+rtoss(ptr[i].z) ); + p_store_string_func(p_store_string_ud,rtosfix(ptr[i].x)+", "+rtosfix(ptr[i].y)+", "+rtosfix(ptr[i].z) ); } p_store_string_func(p_store_string_ud," )"); @@ -2222,7 +2230,7 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str if (i>0) p_store_string_func(p_store_string_ud,", "); - p_store_string_func(p_store_string_ud,rtoss(ptr[i].r)+", "+rtoss(ptr[i].g)+", "+rtoss(ptr[i].b)+", "+rtoss(ptr[i].a) ); + p_store_string_func(p_store_string_ud,rtosfix(ptr[i].r)+", "+rtosfix(ptr[i].g)+", "+rtosfix(ptr[i].b)+", "+rtosfix(ptr[i].a) ); } p_store_string_func(p_store_string_ud," )"); diff --git a/core/vector.h b/core/vector.h index 87248ccf68..cafb4a4aa3 100644 --- a/core/vector.h +++ b/core/vector.h @@ -120,7 +120,7 @@ public: template <class T_val> - int find(const T_val& p_val) const; + int find(const T_val& p_val, int p_from=0) const; void set(int p_index,T p_elem); T get(int p_index) const; @@ -238,13 +238,13 @@ void Vector<T>::_copy_on_write() { } template<class T> template<class T_val> -int Vector<T>::find(const T_val &p_val) const { +int Vector<T>::find(const T_val &p_val, int p_from) const { int ret = -1; - if (size() == 0) + if (p_from < 0 || size() == 0) return ret; - for (int i=0; i<size(); i++) { + for (int i=p_from; i<size(); i++) { if (operator[](i) == p_val) { ret = i; @@ -253,7 +253,7 @@ int Vector<T>::find(const T_val &p_val) const { }; return ret; -}; +} template<class T> Error Vector<T>::resize(int p_size) { |