-Changed var2str and str2var in GDScript to use VariantWriter and VariantParser

-It is now finally possible to parse back a variant from text!
This commit is contained in:
Juan Linietsky 2015-12-31 00:54:00 -03:00
parent 335c52ba03
commit b60a3e7202
5 changed files with 52 additions and 129 deletions

View file

@ -33,7 +33,7 @@
#include "scene/gui/control.h"
#include "io/marshalls.h"
#include "core_string_names.h"
#include "variant_parser.h"
String Variant::get_type_name(Variant::Type p_type) {
@ -2973,132 +2973,11 @@ void Variant::construct_from_string(const String& p_string,Variant& r_value,Obje
}
String Variant::get_construct_string(ObjectDeConstruct p_obj_deconstruct,void *p_deconstruct_ud) const {
String Variant::get_construct_string() const {
switch( type ) {
String vars;
VariantWriter::write_to_string(*this,vars);
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 STRING: return "\""+reinterpret_cast<const String*>(_data._mem)->c_escape()+"\"";
case VECTOR2: return "Vector2("+operator Vector2()+")";
case RECT2: return "Rect2("+operator Rect2()+")";
case MATRIX32: return "Matrix32("+operator Matrix32()+")";
case VECTOR3: return "Vector3("+operator Vector3()+")";
case PLANE: return "Plane("+operator Plane()+")";
//case QUAT:
case _AABB: return "AABB("+operator AABB()+")";
case QUAT: return "Quat("+operator Quat()+")";
case MATRIX3: return "Matrix3("+operator Matrix3()+")";
case TRANSFORM: return "Transform("+operator Transform()+")";
case NODE_PATH: return "@\""+String(operator NodePath()).c_escape()+"\"";
case INPUT_EVENT: return "InputEvent()";
case COLOR: return "Color("+String::num( operator Color().r)+","+String::num( operator Color().g)+","+String::num( operator Color().b)+","+String::num( operator Color().a)+")" ;
case DICTIONARY: {
const Dictionary &d =*reinterpret_cast<const Dictionary*>(_data._mem);
//const String *K=NULL;
String str="{";
List<Variant> keys;
d.get_key_list(&keys);
Vector<_VariantStrPair> pairs;
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
_VariantStrPair sp;
sp.key=E->get().get_construct_string(p_obj_deconstruct,p_deconstruct_ud);
sp.value=d[E->get()].get_construct_string(p_obj_deconstruct,p_deconstruct_ud);
pairs.push_back(sp);
}
pairs.sort();
for(int i=0;i<pairs.size();i++) {
if (i>0)
str+=", ";
str+="("+pairs[i].key+":"+pairs[i].value+")";
}
str+="}";
return str;
} break;
case VECTOR3_ARRAY: {
DVector<Vector3> vec = operator DVector<Vector3>();
String str="Vector3Array([";
for(int i=0;i<vec.size();i++) {
if (i>0)
str+=", ";
str+=Variant( vec[i] ).get_construct_string();
}
return str+"])";
} break;
case STRING_ARRAY: {
DVector<String> vec = operator DVector<String>();
String str="StringArray([";
for(int i=0;i<vec.size();i++) {
if (i>0)
str+=", ";
str=str+=Variant( vec[i] ).get_construct_string();
}
return str+"])";
} break;
case INT_ARRAY: {
DVector<int> vec = operator DVector<int>();
String str="IntArray([";
for(int i=0;i<vec.size();i++) {
if (i>0)
str+=", ";
str=str+itos(vec[i]);
}
return str+"])";
} break;
case REAL_ARRAY: {
DVector<real_t> vec = operator DVector<real_t>();
String str="FloatArray([";
for(int i=0;i<vec.size();i++) {
if (i>0)
str+=", ";
str=str+rtos(vec[i]);
}
return str+"])";
} break;
case ARRAY: {
Array arr = operator Array();
String str="[";
for (int i=0; i<arr.size(); i++) {
if (i)
str+=", ";
str += arr[i].get_construct_string(p_obj_deconstruct,p_deconstruct_ud);
};
return str+"]";
} break;
case OBJECT: {
if (_get_obj().obj) {
if (p_obj_deconstruct) {
return "Object(\""+p_obj_deconstruct(Variant(*this),p_deconstruct_ud).c_escape()+")";
} else {
return _get_obj().obj->get_type()+".new()";
}
} else
return "null";
} break;
default: {
return "["+get_type_name(type)+"]";
}
}
return vars;
}

View file

@ -425,7 +425,7 @@ public:
typedef String (*ObjectDeConstruct)(const Variant& p_object,void *ud);
typedef void (*ObjectConstruct)(const String& p_text,void *ud,Variant& r_value);
String get_construct_string(ObjectDeConstruct p_obj_deconstruct=NULL,void *p_deconstruct_ud=NULL) const;
String get_construct_string() const;
static void construct_from_string(const String& p_string,Variant& r_value,ObjectConstruct p_obj_construct=NULL,void *p_construct_ud=NULL);
void operator=(const Variant& p_variant); // only this is enough for all the other types

View file

@ -19,6 +19,20 @@ bool VariantParser::StreamFile::is_eof() const {
}
CharType VariantParser::StreamString::get_char() {
if (pos>=s.length())
return 0;
else
return s[pos++];
}
bool VariantParser::StreamString::is_utf8() const {
return false;
}
bool VariantParser::StreamString::is_eof() const {
return pos>s.length();
}
/////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -32,6 +32,19 @@ public:
};
struct StreamString : public Stream {
String s;
int pos;
virtual CharType get_char();
virtual bool is_utf8() const;
virtual bool is_eof() const;
StreamString() { pos=0; }
};
typedef Error (*ParseResourceFunc)(void* p_self, Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
struct ResourceParser {

View file

@ -33,6 +33,7 @@
#include "gd_script.h"
#include "func_ref.h"
#include "os/os.h"
#include "variant_parser.h"
const char *GDFunctions::get_func_name(Function p_func) {
@ -607,7 +608,9 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
} break;
case VAR_TO_STR: {
VALIDATE_ARG_COUNT(1);
r_ret=p_args[0]->get_construct_string();
String vars;
VariantWriter::write_to_string(*p_args[0],vars);
r_ret=vars;
} break;
case STR_TO_VAR: {
VALIDATE_ARG_COUNT(1);
@ -618,7 +621,21 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
r_ret=Variant();
return;
}
Variant::construct_from_string(*p_args[0],r_ret);
VariantParser::StreamString ss;
ss.s=*p_args[0];
String errs;
int line;
Error err = VariantParser::parse(&ss,r_ret,errs,line);
if (err!=OK) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
r_error.expected=Variant::STRING;
r_ret=Variant();
}
} break;
case GEN_RANGE: {