From 13cdccf23ba639d7a30a590698cfd36ee558c794 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 8 Jan 2017 20:58:39 -0300 Subject: [PATCH] Variant INT and REAL are now 64 bits (other types remain at 32) --- core/io/marshalls.cpp | 100 +++++++++++++++++++++++------ core/io/resource_format_binary.cpp | 40 ++++++++++-- core/ustring.cpp | 96 ++++++++++++++++++++------- core/ustring.h | 1 + core/variant.cpp | 6 +- core/variant.h | 2 +- core/variant_op.cpp | 12 ++-- modules/gdscript/gd_tokenizer.cpp | 6 +- scene/gui/box_container.cpp | 2 +- 9 files changed, 202 insertions(+), 63 deletions(-) diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index b65ca9a696a..0765fc86c78 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -31,6 +31,10 @@ #include "os/keyboard.h" #include + +#define ENCODE_MASK 0xFF +#define ENCODE_FLAG_64 1<<16 + Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int *r_len) { const uint8_t * buf=p_buffer; @@ -44,14 +48,14 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * uint32_t type=decode_uint32(buf); - ERR_FAIL_COND_V(type>=Variant::VARIANT_MAX,ERR_INVALID_DATA); + ERR_FAIL_COND_V((type&ENCODE_MASK)>=Variant::VARIANT_MAX,ERR_INVALID_DATA); buf+=4; len-=4; if (r_len) *r_len=4; - switch(type) { + switch(type&ENCODE_MASK) { case Variant::NIL: { @@ -68,19 +72,35 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * case Variant::INT: { ERR_FAIL_COND_V(len<4,ERR_INVALID_DATA); - int val = decode_uint32(buf); - r_variant=val; - if (r_len) - (*r_len)+=4; + if (type&ENCODE_FLAG_64) { + int64_t val = decode_uint64(buf); + r_variant=val; + if (r_len) + (*r_len)+=8; + + } else { + int32_t val = decode_uint32(buf); + r_variant=val; + if (r_len) + (*r_len)+=4; + } } break; case Variant::REAL: { ERR_FAIL_COND_V(len<(int)4,ERR_INVALID_DATA); - float val = decode_float(buf); - r_variant=val; - if (r_len) - (*r_len)+=4; + + if (type&ENCODE_FLAG_64) { + double val = decode_double(buf); + r_variant=val; + if (r_len) + (*r_len)+=8; + } else { + float val = decode_float(buf); + r_variant=val; + if (r_len) + (*r_len)+=4; + } } break; case Variant::STRING: { @@ -796,8 +816,28 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { r_len=0; + uint32_t flags=0; + + switch(p_variant.get_type()) { + + case Variant::INT: { + int64_t val = p_variant; + if (val>0x7FFFFFFF || val < -0x80000000) { + flags|=ENCODE_FLAG_64; + } + } break; + case Variant::REAL: { + + double d = p_variant; + float f = d; + if (double(f)!=d) { + flags|=ENCODE_FLAG_64; //always encode real as double + } + } break; + } + if (buf) { - encode_uint32(p_variant.get_type(),buf); + encode_uint32(p_variant.get_type()|flags,buf); buf+=4; } r_len+=4; @@ -819,20 +859,42 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { } break; case Variant::INT: { - if (buf) { - encode_uint32(p_variant.operator int(),buf); + int64_t val = p_variant; + if (val>0x7FFFFFFF || val < -0x80000000) { + //64 bits + if (buf) { + encode_uint64(val,buf); + } + + r_len+=8; + } else { + if (buf) { + encode_uint32(int32_t(val),buf); + } + + r_len+=4; } - - r_len+=4; - } break; case Variant::REAL: { - if (buf) { - encode_float(p_variant.operator float(),buf); + double d = p_variant; + float f = d; + if (double(f)!=d) { + if (buf) { + encode_double(p_variant.operator double(),buf); + } + + r_len+=8; + + } else { + + if (buf) { + encode_double(p_variant.operator float(),buf); + } + + r_len+=4; } - r_len+=4; } break; case Variant::NODE_PATH: { diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 2a9089e8e89..16da74fdf19 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -68,6 +68,8 @@ enum { VARIANT_VECTOR3_ARRAY=35, VARIANT_COLOR_ARRAY=36, VARIANT_VECTOR2_ARRAY=37, + VARIANT_INT64=40, + VARIANT_DOUBLE=41, IMAGE_ENCODING_EMPTY=0, IMAGE_ENCODING_RAW=1, @@ -116,10 +118,18 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { r_v=int(f->get_32()); } break; + case VARIANT_INT64: { + + r_v=int64_t(f->get_64()); + } break; case VARIANT_REAL: { r_v=f->get_real(); } break; + case VARIANT_DOUBLE: { + + r_v=f->get_double(); + } break; case VARIANT_STRING: { r_v=get_unicode_string(); @@ -1416,15 +1426,33 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property, } break; case Variant::INT: { - f->store_32(VARIANT_INT); - int val=p_property; - f->store_32(val); + int64_t val = p_property; + if (val>0x7FFFFFFF || val < -0x80000000) { + f->store_32(VARIANT_INT64); + f->store_64(val); + + } else { + f->store_32(VARIANT_INT); + int val=p_property; + f->store_32(int32_t(val)); + + } + } break; case Variant::REAL: { - f->store_32(VARIANT_REAL); - real_t val=p_property; - f->store_real(val); + + double d = p_property; + float fl = d; + if (double(fl)!=d) { + f->store_32(VARIANT_DOUBLE); + f->store_double(d); + } else { + + f->store_32(VARIANT_REAL); + f->store_real(fl); + + } } break; case Variant::STRING: { diff --git a/core/ustring.cpp b/core/ustring.cpp index 0c26fe90c6d..27bb8eac725 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -1547,20 +1547,20 @@ String::String(const StrRange& p_range) { int String::hex_to_int(bool p_with_prefix) const { - int l = length(); + int l = length(); if (p_with_prefix && l<3) return 0; - const CharType *s=ptr(); + const CharType *s=ptr(); - int sign = s[0]=='-' ? -1 : 1; + int sign = s[0]=='-' ? -1 : 1; - if (sign<0) { - s++; - l--; + if (sign<0) { + s++; + l--; if (p_with_prefix && l<2) - return 0; - } + return 0; + } if (p_with_prefix) { if (s[0]!='0' || s[1]!='x') @@ -1569,26 +1569,74 @@ int String::hex_to_int(bool p_with_prefix) const { l-=2; }; - int hex=0; + int hex=0; - while(*s) { + while(*s) { - CharType c = LOWERCASE(*s); - int n; - if (c>='0' && c<='9') { - n=c-'0'; - } else if (c>='a' && c<='f') { - n=(c-'a')+10; - } else { - return 0; - } + CharType c = LOWERCASE(*s); + int n; + if (c>='0' && c<='9') { + n=c-'0'; + } else if (c>='a' && c<='f') { + n=(c-'a')+10; + } else { + return 0; + } - hex*=16; - hex+=n; - s++; - } + hex*=16; + hex+=n; + s++; + } - return hex*sign; + return hex*sign; + +} + + +int64_t String::hex_to_int64(bool p_with_prefix) const { + + int l = length(); + if (p_with_prefix && l<3) + return 0; + + const CharType *s=ptr(); + + int64_t sign = s[0]=='-' ? -1 : 1; + + if (sign<0) { + s++; + l--; + if (p_with_prefix && l<2) + return 0; + } + + if (p_with_prefix) { + if (s[0]!='0' || s[1]!='x') + return 0; + s+=2; + l-=2; + }; + + int64_t hex=0; + + while(*s) { + + CharType c = LOWERCASE(*s); + int64_t n; + if (c>='0' && c<='9') { + n=c-'0'; + } else if (c>='a' && c<='f') { + n=(c-'a')+10; + } else { + return 0; + } + + hex*=16; + hex+=n; + s++; + } + + return hex*sign; } diff --git a/core/ustring.h b/core/ustring.h index 8b008c2ba4c..9a145143d08 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -147,6 +147,7 @@ public: int hex_to_int(bool p_with_prefix = true) const; int to_int() const; + int64_t hex_to_int64(bool p_with_prefix = true) const; int64_t to_int64() const; static int to_int(const char* p_str, int p_len=-1); static double to_double(const char* p_str); diff --git a/core/variant.cpp b/core/variant.cpp index 6b504438542..69160fffa7f 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -1467,7 +1467,7 @@ Variant::operator double() const { case NIL: return 0; case BOOL: return _data._bool ? 1.0 : 0.0; - case INT: return (float)_data._int; + case INT: return (double)_data._int; case REAL: return _data._real; case STRING: return operator String().to_double(); default: { @@ -1504,8 +1504,8 @@ Variant::operator String() const { case NIL: return "Null"; case BOOL: return _data._bool ? "True" : "False"; - case INT: return String::num(_data._int); - case REAL: return String::num(_data._real); + case INT: return itos(_data._int); + case REAL: return rtos(_data._real); case STRING: return *reinterpret_cast(_data._mem); case VECTOR2: return "("+operator Vector2()+")"; case RECT2: return "("+operator Rect2()+")"; diff --git a/core/variant.h b/core/variant.h index a2b9a88b3e6..764ba9ae60a 100644 --- a/core/variant.h +++ b/core/variant.h @@ -141,7 +141,7 @@ private: union { bool _bool; - int _int; + int64_t _int; double _real; Matrix32 *_matrix32; AABB* _aabb; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 84edb51c73b..00baffdd3bb 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -683,7 +683,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& case INT: { switch(p_b.type) { case BOOL: { - int b = p_b._data._bool; + int64_t b = p_b._data._bool; if (b==0) { r_valid=false; @@ -693,7 +693,7 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& } break; case INT: { - int b = p_b._data._int; + int64_t b = p_b._data._int; if (b==0) { r_valid=false; @@ -3358,8 +3358,8 @@ void Variant::blend(const Variant& a, const Variant& b, float c, Variant &r_dst) switch(a.type) { case NIL: { r_dst=Variant(); } return; case INT:{ - int va=a._data._int; - int vb=b._data._int; + int64_t va=a._data._int; + int64_t vb=b._data._int; r_dst=int(va + vb * c + 0.5); } return; case REAL:{ @@ -3423,8 +3423,8 @@ void Variant::interpolate(const Variant& a, const Variant& b, float c,Variant &r case NIL:{ r_dst=Variant(); } return; case BOOL:{ r_dst=a; } return; case INT:{ - int va=a._data._int; - int vb=b._data._int; + int64_t va=a._data._int; + int64_t vb=b._data._int; r_dst=int((1.0-c) * va + vb * c); } return; case REAL:{ diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp index 865c07f3b2f..fcf2d258065 100644 --- a/modules/gdscript/gd_tokenizer.cpp +++ b/modules/gdscript/gd_tokenizer.cpp @@ -731,14 +731,14 @@ void GDTokenizerText::_advance() { INCPOS(str.length()); if (hexa_found) { - int val = str.hex_to_int(); + int64_t val = str.hex_to_int64(); _make_constant(val); } else if (period_found || exponent_found) { - real_t val = str.to_double(); + double val = str.to_double(); //print_line("*%*%*%*% to convert: "+str+" result: "+rtos(val)); _make_constant(val); } else { - int val = str.to_int(); + int64_t val = str.to_int64(); _make_constant(val); } diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index 95e796ab56d..f31f51a5cd6 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -280,7 +280,7 @@ BoxContainer::AlignMode BoxContainer::get_alignment() const { void BoxContainer::add_spacer(bool p_begin) { Control *c = memnew( Control ); - c->set_mouse_filter(MOUSE_FILTER_PASS); + c->set_mouse_filter(MOUSE_FILTER_PASS); //allow spacer to pass mouse events if (vertical) c->set_v_size_flags(SIZE_EXPAND_FILL);