From fd836cad270f7eb9645356cd583c8f11bf737b0f Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Thu, 31 Dec 2015 00:31:00 -0300 Subject: -Ensure .tscn and .tres always save in a deterministic way, fixes #2495 -Scene edit state is saved outside the scene now, to avoid changes .tscn files when nothing really changed -Created a VariantWriter helper to unify all variant to text writing -Moved SceneFormatText writing to VariantWriter -Moved ConfigFile to use VariantWriter and VariantParser, added compatibility mode for old .cfg files that use engine.cfg format --- core/globals.cpp | 1 + core/io/config_file.cpp | 585 +++--------------------------------------------- core/variant_parser.cpp | 543 ++++++++++++++++++++++++++++++++++++++++++++ core/variant_parser.h | 21 ++ 4 files changed, 592 insertions(+), 558 deletions(-) (limited to 'core') diff --git a/core/globals.cpp b/core/globals.cpp index eed37c2308..b48f34d2df 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -304,6 +304,7 @@ Error Globals::setup(const String& p_path,const String & p_main_pack) { return OK; } + if (OS::get_singleton()->get_resource_dir()!="") { //OS will call Globals->get_resource_path which will be empty if not overriden! //if the OS would rather use somewhere else, then it will not be empty. diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index 75388f514a..7f74b61630 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -29,6 +29,7 @@ #include "config_file.h" #include "os/keyboard.h" #include "os/file_access.h" +#include "variant_parser.h" StringArray ConfigFile::_get_sections() const { @@ -118,151 +119,6 @@ void ConfigFile::get_section_keys(const String& p_section,List *r_keys) } -static String _encode_variant(const Variant& p_variant) { - - switch(p_variant.get_type()) { - - case Variant::BOOL: { - bool val = p_variant; - return (val?"true":"false"); - } break; - case Variant::INT: { - int val = p_variant; - return itos(val); - } break; - case Variant::REAL: { - float val = p_variant; - return rtos(val)+(val==int(val)?".0":""); - } break; - case Variant::STRING: { - String val = p_variant; - return "\""+val.xml_escape()+"\""; - } break; - case Variant::COLOR: { - - Color val = p_variant; - return "#"+val.to_html(); - } break; - case Variant::STRING_ARRAY: - case Variant::INT_ARRAY: - case Variant::REAL_ARRAY: - case Variant::ARRAY: { - Array arr = p_variant; - String str="["; - for(int i=0;i0) - str+=", "; - str+=_encode_variant(arr[i]); - } - str+="]"; - return str; - } break; - case Variant::DICTIONARY: { - Dictionary d = p_variant; - String str="{"; - List keys; - d.get_key_list(&keys); - for(List::Element *E=keys.front();E;E=E->next()) { - - if (E!=keys.front()) - str+=", "; - str+=_encode_variant(E->get()); - str+=":"; - str+=_encode_variant(d[E->get()]); - - } - str+="}"; - return str; - } break; - case Variant::IMAGE: { - String str="img("; - - Image img=p_variant; - if (!img.empty()) { - - String format; - switch(img.get_format()) { - - case Image::FORMAT_GRAYSCALE: format="grayscale"; break; - case Image::FORMAT_INTENSITY: format="intensity"; break; - case Image::FORMAT_GRAYSCALE_ALPHA: format="grayscale_alpha"; break; - case Image::FORMAT_RGB: format="rgb"; break; - case Image::FORMAT_RGBA: format="rgba"; break; - case Image::FORMAT_INDEXED : format="indexed"; break; - case Image::FORMAT_INDEXED_ALPHA: format="indexed_alpha"; break; - case Image::FORMAT_BC1: format="bc1"; break; - case Image::FORMAT_BC2: format="bc2"; break; - case Image::FORMAT_BC3: format="bc3"; break; - case Image::FORMAT_BC4: format="bc4"; break; - case Image::FORMAT_BC5: format="bc5"; break; - case Image::FORMAT_CUSTOM: format="custom custom_size="+itos(img.get_data().size())+""; break; - default: {} - } - - str+=format+", "; - str+=itos(img.get_mipmaps())+", "; - str+=itos(img.get_width())+", "; - str+=itos(img.get_height())+", "; - DVector data = img.get_data(); - int ds=data.size(); - DVector::Read r = data.read(); - for(int i=0;i>4], hex[byte&0xF], 0}; - str+=bstr; - } - } - str+=")"; - return str; - } break; - case Variant::INPUT_EVENT: { - - InputEvent ev = p_variant; - - switch(ev.type) { - - case InputEvent::KEY: { - - String mods; - if (ev.key.mod.control) - mods+="C"; - if (ev.key.mod.shift) - mods+="S"; - if (ev.key.mod.alt) - mods+="A"; - if (ev.key.mod.meta) - mods+="M"; - if (mods!="") - mods=", "+mods; - - return "key("+keycode_get_string(ev.key.scancode)+mods+")"; - } break; - case InputEvent::MOUSE_BUTTON: { - - return "mbutton("+itos(ev.device)+", "+itos(ev.mouse_button.button_index)+")"; - } break; - case InputEvent::JOYSTICK_BUTTON: { - - return "jbutton("+itos(ev.device)+", "+itos(ev.joy_button.button_index)+")"; - } break; - case InputEvent::JOYSTICK_MOTION: { - - return "jaxis("+itos(ev.device)+", "+itos(ev.joy_motion.axis)+")"; - } break; - default: { - - return "nil"; - } break; - - } - } break; - default: {} - } - - return "nil"; //don't know wha to do with this -} Error ConfigFile::save(const String& p_path){ @@ -283,7 +139,9 @@ Error ConfigFile::save(const String& p_path){ for(Map::Element *F=E->get().front();F;F=F->next()) { - file->store_string(F->key()+"="+_encode_variant(F->get())+"\n"); + String vstr; + VariantWriter::write_to_string(F->get(),vstr); + file->store_string(F->key()+"="+vstr+"\n"); } } @@ -292,432 +150,43 @@ Error ConfigFile::save(const String& p_path){ return OK; } -static Vector _decode_params(const String& p_string) { - - int begin=p_string.find("("); - ERR_FAIL_COND_V(begin==-1,Vector()); - begin++; - int end=p_string.find(")"); - ERR_FAIL_COND_V(end()); - return p_string.substr(begin,end-begin).split(","); -} - -static String _get_chunk(const String& str,int &pos, int close_pos) { - - - enum { - MIN_COMMA, - MIN_COLON, - MIN_CLOSE, - MIN_QUOTE, - MIN_PARENTHESIS, - MIN_CURLY_OPEN, - MIN_OPEN - }; - - int min_pos=close_pos; - int min_what=MIN_CLOSE; - -#define TEST_MIN(m_how,m_what) \ -{\ -int res = str.find(m_how,pos);\ -if (res!=-1 && res < min_pos) {\ - min_pos=res;\ - min_what=m_what;\ -}\ -}\ - - - TEST_MIN(",",MIN_COMMA); - TEST_MIN("[",MIN_OPEN); - TEST_MIN("{",MIN_CURLY_OPEN); - TEST_MIN("(",MIN_PARENTHESIS); - TEST_MIN("\"",MIN_QUOTE); - - int end=min_pos; - - - switch(min_what) { - - case MIN_COMMA: { - } break; - case MIN_CLOSE: { - //end because it's done - } break; - case MIN_QUOTE: { - end=str.find("\"",min_pos+1)+1; - ERR_FAIL_COND_V(end==-1,Variant()); - - } break; - case MIN_PARENTHESIS: { - - end=str.find(")",min_pos+1)+1; - ERR_FAIL_COND_V(end==-1,Variant()); - - } break; - case MIN_OPEN: { - int level=1; - end++; - while(end params = _decode_params(p_string); - ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,Variant()); - int scode=0; - - if (params[0].is_numeric()) { - scode=params[0].to_int(); - if (scode < 10) { - scode=KEY_0+scode; - } - } else - scode=find_keycode(params[0]); - - InputEvent ie; - ie.type=InputEvent::KEY; - ie.key.scancode=scode; - - if (params.size()==2) { - String mods=params[1]; - if (mods.findn("C")!=-1) - ie.key.mod.control=true; - if (mods.findn("A")!=-1) - ie.key.mod.alt=true; - if (mods.findn("S")!=-1) - ie.key.mod.shift=true; - if (mods.findn("M")!=-1) - ie.key.mod.meta=true; - } - return ie; - - } - - if (str.begins_with("mbutton")) { - Vector params = _decode_params(p_string); - ERR_FAIL_COND_V(params.size()!=2,Variant()); - - InputEvent ie; - ie.type=InputEvent::MOUSE_BUTTON; - ie.device=params[0].to_int(); - ie.mouse_button.button_index=params[1].to_int(); - - return ie; - } - - if (str.begins_with("jbutton")) { - Vector params = _decode_params(p_string); - ERR_FAIL_COND_V(params.size()!=2,Variant()); - - InputEvent ie; - ie.type=InputEvent::JOYSTICK_BUTTON; - ie.device=params[0].to_int(); - ie.joy_button.button_index=params[1].to_int(); - - return ie; - } - - if (str.begins_with("jaxis")) { - Vector params = _decode_params(p_string); - ERR_FAIL_COND_V(params.size()!=2,Variant()); - - InputEvent ie; - ie.type=InputEvent::JOYSTICK_MOTION; - ie.device=params[0].to_int(); - ie.joy_motion.axis=params[1].to_int(); - - return ie; - } - if (str.begins_with("img")) { - Vector params = _decode_params(p_string); - if (params.size()==0) { - return Image(); - } - - ERR_FAIL_COND_V(params.size()!=5,Image()); - - String format=params[0].strip_edges(); - - Image::Format imgformat; - - if (format=="grayscale") { - imgformat=Image::FORMAT_GRAYSCALE; - } else if (format=="intensity") { - imgformat=Image::FORMAT_INTENSITY; - } else if (format=="grayscale_alpha") { - imgformat=Image::FORMAT_GRAYSCALE_ALPHA; - } else if (format=="rgb") { - imgformat=Image::FORMAT_RGB; - } else if (format=="rgba") { - imgformat=Image::FORMAT_RGBA; - } else if (format=="indexed") { - imgformat=Image::FORMAT_INDEXED; - } else if (format=="indexed_alpha") { - imgformat=Image::FORMAT_INDEXED_ALPHA; - } else if (format=="bc1") { - imgformat=Image::FORMAT_BC1; - } else if (format=="bc2") { - imgformat=Image::FORMAT_BC2; - } else if (format=="bc3") { - imgformat=Image::FORMAT_BC3; - } else if (format=="bc4") { - imgformat=Image::FORMAT_BC4; - } else if (format=="bc5") { - imgformat=Image::FORMAT_BC5; - } else if (format=="custom") { - imgformat=Image::FORMAT_CUSTOM; - } else { - - ERR_FAIL_V( Image() ); - } - - int mipmaps=params[1].to_int(); - int w=params[2].to_int(); - int h=params[3].to_int(); - - if (w == 0 && h == 0) { - //r_v = Image(w, h, imgformat); - return Image(); - }; - - - String data=params[4]; - int datasize=data.length()/2; - DVector pixels; - pixels.resize(datasize); - DVector::Write wb = pixels.write(); - const CharType *cptr=data.c_str(); - - int idx=0; - uint8_t byte; - while( idx='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f') ) { - - if (idx&1) { - - byte|=HEX2CHR(c); - wb[idx>>1]=byte; - } else { - - byte=HEX2CHR(c)<<4; - } - - idx++; - } - - } - - wb = DVector::Write(); - - return Image(w,h,mipmaps,imgformat,pixels); - } - - if (str.find(",")!=-1) { //vector2 or vector3 - Vector farr = str.split_floats(",",true); - if (farr.size()==2) { - return Point2(farr[0],farr[1]); - } - if (farr.size()==3) { - return Vector3(farr[0],farr[1],farr[2]); - } - ERR_FAIL_V(Variant()); - } - - - return Variant(); -} Error ConfigFile::load(const String& p_path) { Error err; FileAccess *f= FileAccess::open(p_path,FileAccess::READ,&err); - if (err!=OK) { - - return err; - } - - - String line; - String section; - String subpath; - - int line_count = 0; - - while(!f->eof_reached()) { - - String line = f->get_line().strip_edges(); - line_count++; - - if (line=="") - continue; - - // find comments - - { + if (!f) + return ERR_CANT_OPEN; - int pos=0; - while (true) { - int ret = line.find(";",pos); - if (ret==-1) - break; + VariantParser::StreamFile stream; + stream.f=f; - int qc=0; - for(int i=0;i 0) { - ERR_PRINT(String("Syntax error on line "+itos(line_count)+" of file "+p_path).ascii().get_data()); - }; - }; + if (assign!=String()) { + set_value(section,assign,value); + } else if (next_tag.name!=String()) { + section=next_tag.name; + } } memdelete(f); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 239b129388..82ab8ab690 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -336,6 +336,42 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri return ERR_PARSE_ERROR; } +Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector& strings, int &line, String &r_err_str) { + + Token token; + get_token(p_stream,token,line,r_err_str); + if (token.type!=TK_PARENTHESIS_OPEN) { + r_err_str="Expected '(' in old-style engine.cfg construct"; + return ERR_PARSE_ERROR; + } + + + String accum; + + while(true) { + + CharType c=p_stream->get_char(); + + if (p_stream->is_eof()) { + r_err_str="Unexpected EOF while parsing old-style engine.cfg construct"; + return ERR_PARSE_ERROR; + } + + if (c==',') { + strings.push_back(accum.strip_edges()); + accum=String(); + } else if (c==')') { + strings.push_back(accum.strip_edges()); + return OK; + } else if (c=='\n') { + line++; + } + + } + + return OK; +} + template Error VariantParser::_parse_construct(Stream *p_stream,Vector& r_construct,int &line,String &r_err_str) { @@ -1173,6 +1209,88 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in value=arr; + return OK; + } else if (id=="key") { // compatibility with engine.cfg + + Vector params; + Error err = _parse_enginecfg(p_stream,params,line,r_err_str); + if (err) + return err; + ERR_FAIL_COND_V(params.size()!=1 && params.size()!=2,ERR_PARSE_ERROR); + + int scode=0; + + if (params[0].is_numeric()) { + scode=params[0].to_int(); + if (scode < 10) { + scode=KEY_0+scode; + } + } else + scode=find_keycode(params[0]); + + InputEvent ie; + ie.type=InputEvent::KEY; + ie.key.scancode=scode; + + if (params.size()==2) { + String mods=params[1]; + if (mods.findn("C")!=-1) + ie.key.mod.control=true; + if (mods.findn("A")!=-1) + ie.key.mod.alt=true; + if (mods.findn("S")!=-1) + ie.key.mod.shift=true; + if (mods.findn("M")!=-1) + ie.key.mod.meta=true; + } + value=ie; + return OK; + + } else if (id=="mbutton") { // compatibility with engine.cfg + + Vector params; + Error err = _parse_enginecfg(p_stream,params,line,r_err_str); + if (err) + return err; + ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); + + InputEvent ie; + ie.type=InputEvent::MOUSE_BUTTON; + ie.device=params[0].to_int(); + ie.mouse_button.button_index=params[1].to_int(); + + value=ie; + return OK; + } else if (id=="jbutton") { // compatibility with engine.cfg + + Vector params; + Error err = _parse_enginecfg(p_stream,params,line,r_err_str); + if (err) + return err; + ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); + InputEvent ie; + ie.type=InputEvent::JOYSTICK_BUTTON; + ie.device=params[0].to_int(); + ie.joy_button.button_index=params[1].to_int(); + + value=ie; + + return OK; + } else if (id=="jaxis") { // compatibility with engine.cfg + + Vector params; + Error err = _parse_enginecfg(p_stream,params,line,r_err_str); + if (err) + return err; + ERR_FAIL_COND_V(params.size()!=2,ERR_PARSE_ERROR); + + InputEvent ie; + ie.type=InputEvent::JOYSTICK_MOTION; + ie.device=params[0].to_int(); + ie.joy_motion.axis=params[1].to_int(); + + value= ie; + return OK; } else { @@ -1506,3 +1624,428 @@ Error VariantParser::parse(Stream *p_stream, Variant& r_ret, String &r_err_str, } + +////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + + +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) { + + switch( p_variant.get_type() ) { + + case Variant::NIL: { + p_store_string_func(p_store_string_ud,"null"); + } break; + case Variant::BOOL: { + + p_store_string_func(p_store_string_ud,p_variant.operator bool() ? "true":"false" ); + } break; + case Variant::INT: { + + p_store_string_func(p_store_string_ud, itos(p_variant.operator int()) ); + } break; + case Variant::REAL: { + + p_store_string_func(p_store_string_ud, rtoss(p_variant.operator real_t()) ); + } break; + case Variant::STRING: { + + String str=p_variant; + + str="\""+str.c_escape()+"\""; + p_store_string_func(p_store_string_ud, str ); + } break; + case Variant::VECTOR2: { + + Vector2 v = p_variant; + p_store_string_func(p_store_string_ud,"Vector2( "+rtoss(v.x) +", "+rtoss(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)+" )" ); + + } 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)+" )"); + } 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)+" )" ); + + } 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)+" )" ); + + } 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)+" )"); + + } break; + case Variant::MATRIX32: { + + String s="Matrix32( "; + Matrix32 m3 = p_variant; + for (int i=0;i<3;i++) { + for (int j=0;j<2;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + p_store_string_func(p_store_string_ud,s+" )"); + + } break; + case Variant::MATRIX3: { + + String s="Matrix3( "; + Matrix3 m3 = p_variant; + for (int i=0;i<3;i++) { + for (int j=0;j<3;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + p_store_string_func(p_store_string_ud,s+" )"); + + } break; + case Variant::TRANSFORM: { + + String s="Transform( "; + Transform t = p_variant; + Matrix3 &m3 = t.basis; + for (int i=0;i<3;i++) { + for (int j=0;j<3;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z); + + p_store_string_func(p_store_string_ud,s+" )"); + } break; + + // misc types + 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)+" )"); + + } break; + case Variant::IMAGE: { + + + Image img=p_variant; + + if (img.empty()) { + p_store_string_func(p_store_string_ud,"Image()"); + break; + } + + String imgstr="Image( "; + imgstr+=itos(img.get_width()); + imgstr+=", "+itos(img.get_height()); + imgstr+=", "+itos(img.get_mipmaps()); + imgstr+=", "; + + switch(img.get_format()) { + + case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break; + case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break; + case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break; + case Image::FORMAT_RGB: imgstr+="RGB"; break; + case Image::FORMAT_RGBA: imgstr+="RGBA"; break; + case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break; + case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break; + case Image::FORMAT_BC1: imgstr+="BC1"; break; + case Image::FORMAT_BC2: imgstr+="BC2"; break; + case Image::FORMAT_BC3: imgstr+="BC3"; break; + case Image::FORMAT_BC4: imgstr+="BC4"; break; + case Image::FORMAT_BC5: imgstr+="BC5"; break; + case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break; + case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break; + case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break; + case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break; + case Image::FORMAT_ETC: imgstr+="ETC"; break; + case Image::FORMAT_ATC: imgstr+="ATC"; break; + case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break; + case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break; + case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break; + default: {} + } + + + String s; + + DVector data = img.get_data(); + int len = data.size(); + DVector::Read r = data.read(); + const uint8_t *ptr=r.ptr();; + for (int i=0;i0) + s+=", "; + s+=itos(ptr[i]); + } + + imgstr+=", "; + p_store_string_func(p_store_string_ud,imgstr); + p_store_string_func(p_store_string_ud,s); + p_store_string_func(p_store_string_ud," )"); + } break; + case Variant::NODE_PATH: { + + String str=p_variant; + + str="NodePath(\""+str.c_escape()+"\")"; + p_store_string_func(p_store_string_ud,str); + + } break; + + case Variant::OBJECT: { + + RES res = p_variant; + if (res.is_null()) { + p_store_string_func(p_store_string_ud,"null"); + break; // don't save it + } + + String res_text; + + if (p_encode_res_func) { + + res_text=p_encode_res_func(p_encode_res_ud,res); + } + + if (res_text==String() && res->get_path().is_resource_file()) { + + //external resource + String path=res->get_path(); + res_text="Resource( \""+path+"\")"; + } + + if (res_text==String()) + res_text="null"; + + p_store_string_func(p_store_string_ud,res_text); + + } break; + case Variant::INPUT_EVENT: { + + p_store_string_func(p_store_string_ud,"InputEvent()"); //will be added later + } break; + case Variant::DICTIONARY: { + + Dictionary dict = p_variant; + + List keys; + dict.get_key_list(&keys); + keys.sort(); + + p_store_string_func(p_store_string_ud,"{ "); + for(List::Element *E=keys.front();E;E=E->next()) { + + //if (!_check_type(dict[E->get()])) + // continue; + write(E->get(),p_store_string_func,p_store_string_ud,p_encode_res_func,p_encode_res_ud); + p_store_string_func(p_store_string_ud,":"); + write(dict[E->get()],p_store_string_func,p_store_string_ud,p_encode_res_func,p_encode_res_ud); + if (E->next()) + p_store_string_func(p_store_string_ud,", "); + } + + + p_store_string_func(p_store_string_ud," }"); + + + } break; + case Variant::ARRAY: { + + p_store_string_func(p_store_string_ud,"[ "); + Array array = p_variant; + int len=array.size(); + for (int i=0;i0) + p_store_string_func(p_store_string_ud,", "); + write(array[i],p_store_string_func,p_store_string_ud,p_encode_res_func,p_encode_res_ud); + + } + p_store_string_func(p_store_string_ud," ]"); + + } break; + + case Variant::RAW_ARRAY: { + + p_store_string_func(p_store_string_ud,"ByteArray( "); + String s; + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const uint8_t *ptr=r.ptr();; + for (int i=0;i0) + p_store_string_func(p_store_string_ud,", "); + + p_store_string_func(p_store_string_ud,itos(ptr[i])); + + } + + p_store_string_func(p_store_string_ud," )"); + + } break; + case Variant::INT_ARRAY: { + + p_store_string_func(p_store_string_ud,"IntArray( "); + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const int *ptr=r.ptr();; + + for (int i=0;i0) + p_store_string_func(p_store_string_ud,", "); + + p_store_string_func(p_store_string_ud,itos(ptr[i])); + } + + + p_store_string_func(p_store_string_ud," )"); + + } break; + case Variant::REAL_ARRAY: { + + p_store_string_func(p_store_string_ud,"FloatArray( "); + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const real_t *ptr=r.ptr();; + + for (int i=0;i0) + 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," )"); + + } break; + case Variant::STRING_ARRAY: { + + p_store_string_func(p_store_string_ud,"StringArray( "); + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const String *ptr=r.ptr();; + String s; + //write_string("\n"); + + + + for (int i=0;i0) + p_store_string_func(p_store_string_ud,", "); + String str=ptr[i]; + p_store_string_func(p_store_string_ud,""+str.c_escape()+"\""); + } + + p_store_string_func(p_store_string_ud," )"); + + } break; + case Variant::VECTOR2_ARRAY: { + + p_store_string_func(p_store_string_ud,"Vector2Array( "); + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const Vector2 *ptr=r.ptr();; + + for (int i=0;i0) + 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," )"); + + } break; + case Variant::VECTOR3_ARRAY: { + + p_store_string_func(p_store_string_ud,"Vector3Array( "); + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const Vector3 *ptr=r.ptr();; + + for (int i=0;i0) + 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," )"); + + } break; + case Variant::COLOR_ARRAY: { + + p_store_string_func(p_store_string_ud,"ColorArray( "); + + DVector data = p_variant; + int len = data.size(); + DVector::Read r = data.read(); + const Color *ptr=r.ptr();; + + for (int i=0;i0) + 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," )"); + + } break; + default: {} + + } + + return OK; +} + +static Error _write_to_str(void *ud,const String& p_string) { + + String *str=(String*)ud; + (*str)+=p_string; + return OK; +} + +Error VariantWriter::write_to_string(const Variant& p_variant, String& r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) { + + r_string=String(); + + return write(p_variant,_write_to_str,&r_string,p_encode_res_func,p_encode_res_ud); + +} diff --git a/core/variant_parser.h b/core/variant_parser.h index e1d25f7512..2bfb244fc8 100644 --- a/core/variant_parser.h +++ b/core/variant_parser.h @@ -86,6 +86,7 @@ private: template static Error _parse_construct(Stream *p_stream, Vector& r_construct, int &line, String &r_err_str); + static Error _parse_enginecfg(Stream *p_stream, Vector& strings, int &line, String &r_err_str); static Error _parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL); static Error _parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL); static Error _parse_tag(Token& token,Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,ResourceParser *p_res_parser=NULL); @@ -100,4 +101,24 @@ public: static Error parse(Stream *p_stream, Variant &r_ret, String &r_err_str, int &r_err_line,ResourceParser *p_res_parser=NULL); }; + + + +class VariantWriter { +public: + + typedef Error (*StoreStringFunc)(void *ud,const String& p_string); + typedef String (*EncodeResourceFunc)(void *ud,const RES& p_resource); + + static Error 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); + static Error write_to_string(const Variant& p_variant, String& r_string, EncodeResourceFunc p_encode_res_func=NULL,void* p_encode_res_ud=NULL); + + +}; + + + + + + #endif // VARIANT_PARSER_H -- cgit v1.2.3