summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/variant_parser.cpp243
-rw-r--r--core/variant_parser.h11
-rw-r--r--scene/resources/packed_scene.cpp83
-rw-r--r--scene/resources/packed_scene.h15
-rw-r--r--scene/resources/scene_format_text.cpp677
-rw-r--r--scene/resources/scene_format_text.h14
-rw-r--r--tools/editor/editor_node.cpp7
7 files changed, 756 insertions, 294 deletions
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 2bf9fd7f32..fed8c28740 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -54,6 +54,10 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
p_stream->saved=0;
} else {
cchar=p_stream->get_char();
+ if (p_stream->is_eof()) {
+ r_token.type=TK_EOF;
+ return OK;
+ }
}
switch(cchar) {
@@ -202,6 +206,9 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
}
}
+ if (p_stream->is_utf8()) {
+ str.parse_utf8( str.ascii(true).get_data() );
+ }
r_token.type=TK_STRING;
r_token.value=str;
return OK;
@@ -215,7 +222,7 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
if (cchar=='-' || (cchar>='0' && cchar<='9')) {
//a number
- print_line("a numbar");
+
String num;
#define READING_SIGN 0
@@ -228,7 +235,6 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
if (cchar=='-') {
num+='-';
cchar=p_stream->get_char();
- print_line("isnegative");
}
@@ -246,14 +252,11 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
if (c>='0' && c<='9') {
//pass
- print_line("num: regular");
} else if (c=='.') {
reading=READING_DEC;
- print_line("num: decimal");
is_float=true;
} else if (c=='e') {
reading=READING_EXP;
- print_line("num: exp");
} else {
reading=READING_DONE;
}
@@ -262,11 +265,10 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
case READING_DEC: {
if (c>='0' && c<='9') {
- print_line("dec: exp");
} else if (c=='e') {
reading=READING_EXP;
- print_line("dec: expe");
+
} else {
reading=READING_DONE;
}
@@ -276,10 +278,10 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
if (c>='0' && c<='9') {
exp_beg=true;
- print_line("exp: num");
+
} else if ((c=='-' || c=='+') && !exp_sign && !exp_beg) {
exp_sign=true;
- print_line("exp: sgn");
+
} else {
reading=READING_DONE;
}
@@ -290,13 +292,13 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
break;
num+=String::chr(c);
c = p_stream->get_char();
- print_line("add to c");
+
}
p_stream->saved=c;
- print_line("num was: "+num);
+
r_token.type=TK_NUMBER;
if (is_float)
r_token.value=num.to_double();
@@ -307,11 +309,13 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
} else if ((cchar>='A' && cchar<='Z') || (cchar>='a' && cchar<='z') || cchar=='_') {
String id;
+ bool first=true;
- while((cchar>='A' && cchar<='Z') || (cchar>='a' && cchar<='z') || cchar=='_') {
+ while((cchar>='A' && cchar<='Z') || (cchar>='a' && cchar<='z') || cchar=='_' || (!first && cchar>='0' && cchar<='9')) {
id+=String::chr(cchar);
cchar=p_stream->get_char();
+ first=false;
}
p_stream->saved=cchar;
@@ -332,14 +336,14 @@ Error VariantParser::get_token(Stream *p_stream, Token& r_token, int &line, Stri
return ERR_PARSE_ERROR;
}
-
-Error VariantParser::_parse_construct(Stream *p_stream,Vector<float>& r_construct,int &line,String &r_err_str) {
+template<class T>
+Error VariantParser::_parse_construct(Stream *p_stream,Vector<T>& r_construct,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 '('";
+ r_err_str="Expected '(' in constructor";
return ERR_PARSE_ERROR;
}
@@ -351,21 +355,23 @@ Error VariantParser::_parse_construct(Stream *p_stream,Vector<float>& r_construc
get_token(p_stream,token,line,r_err_str);
if (token.type==TK_COMMA) {
//do none
- } else if (token.type!=TK_PARENTHESIS_CLOSE) {
+ } else if (token.type==TK_PARENTHESIS_CLOSE) {
break;
} else {
- r_err_str="Expected ',' or ')'";
+ r_err_str="Expected ',' or ')' in constructor";
return ERR_PARSE_ERROR;
}
}
get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_NUMBER) {
- r_err_str="Expected float";
+ r_err_str="Expected float in constructor";
return ERR_PARSE_ERROR;
}
+
r_construct.push_back(token.value);
+ first=false;
}
return OK;
@@ -444,7 +450,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
else if (id=="Vector2"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -457,7 +463,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Vector3"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -470,7 +476,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Matrix32"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -486,7 +492,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Plane") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -499,7 +505,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Quat") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -513,7 +519,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="AABB"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -527,7 +533,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Matrix3"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -540,7 +546,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Transform"){
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -554,7 +560,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Color") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -600,6 +606,8 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
}
int height=token.value;
+
+ get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_COMMA) {
r_err_str="Expected ','";
return ERR_PARSE_ERROR;
@@ -612,6 +620,8 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
}
int mipmaps=token.value;
+
+ get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_COMMA) {
r_err_str="Expected ','";
return ERR_PARSE_ERROR;
@@ -624,6 +634,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
return ERR_PARSE_ERROR;
}
+
String sformat=token.value;
Image::Format format;
@@ -666,12 +677,13 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
DVector<uint8_t>::Write w=buffer.write();
for(int i=0;i<len;i++) {
-
+ get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_COMMA) {
r_err_str="Expected ','";
return ERR_PARSE_ERROR;
}
+ get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_NUMBER) {
r_err_str="Expected number";
return ERR_PARSE_ERROR;
@@ -702,7 +714,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_STRING) {
- r_err_str="Expected string as argument";
+ r_err_str="Expected string as argument for NodePath()";
return ERR_PARSE_ERROR;
}
@@ -741,7 +753,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
return OK;
- } else if (id=="Resource") {
+ } else if (id=="Resource" || id=="SubResource" || id=="ExtResource") {
@@ -751,28 +763,31 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
return ERR_PARSE_ERROR;
}
- get_token(p_stream,token,line,r_err_str);
- if (token.type==TK_STRING) {
- String path=token.value;
- RES res = ResourceLoader::load(path);
- if (res.is_null()) {
- r_err_str="Can't load resource at path: '"+path+"'.";
- return ERR_PARSE_ERROR;
- }
- get_token(p_stream,token,line,r_err_str);
- if (token.type!=TK_PARENTHESIS_CLOSE) {
- r_err_str="Expected ')'";
- return ERR_PARSE_ERROR;
- }
+ if (p_res_parser && id=="Resource" && p_res_parser->func){
+
+ RES res;
+ Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str);
+ if (err)
+ return err;
value=res;
+
return OK;
+ } else if (p_res_parser && id=="ExtResource" && p_res_parser->ext_func){
+
+ RES res;
+ Error err = p_res_parser->ext_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
+ if (err)
+ return err;
+
+ value=res;
- } else if (p_res_parser && p_res_parser->func){
+ return OK;
+ } else if (p_res_parser && id=="SubResource" && p_res_parser->sub_func){
RES res;
- Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str);
+ Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
if (err)
return err;
@@ -781,12 +796,33 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
return OK;
} else {
- r_err_str="Expected string as argument.";
- return ERR_PARSE_ERROR;
+ get_token(p_stream,token,line,r_err_str);
+ if (token.type==TK_STRING) {
+ String path=token.value;
+ RES res = ResourceLoader::load(path);
+ if (res.is_null()) {
+ r_err_str="Can't load resource at path: '"+path+"'.";
+ return ERR_PARSE_ERROR;
+ }
+
+ get_token(p_stream,token,line,r_err_str);
+ if (token.type!=TK_PARENTHESIS_CLOSE) {
+ r_err_str="Expected ')'";
+ return ERR_PARSE_ERROR;
+ }
+
+ value=res;
+ return OK;
+
+ } else {
+ r_err_str="Expected string as argument for Resource().";
+ return ERR_PARSE_ERROR;
+ }
}
return OK;
+
} else if (id=="InputEvent") {
@@ -952,8 +988,8 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="ByteArray") {
- Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Vector<uint8_t> args;
+ Error err = _parse_construct<uint8_t>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -973,8 +1009,8 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="IntArray") {
- Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -984,7 +1020,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
arr.resize(len);
DVector<int32_t>::Write w = arr.write();
for(int i=0;i<len;i++) {
- w[i]=Math::fast_ftoi(args[i]);
+ w[i]=int(args[i]);
}
}
@@ -995,7 +1031,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="FloatArray") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -1066,7 +1102,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Vector2Array") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -1087,7 +1123,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="Vector3Array") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -1108,7 +1144,7 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
} else if (id=="ColorArray") {
Vector<float> args;
- Error err = _parse_construct(p_stream,args,line,r_err_str);
+ Error err = _parse_construct<float>(p_stream,args,line,r_err_str);
if (err)
return err;
@@ -1191,7 +1227,12 @@ Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, Str
bool need_comma=false;
- while(!p_stream->is_eof()) {
+ while(true) {
+
+ if (p_stream->is_eof()) {
+ r_err_str="Unexpected End of File while parsing array";
+ return ERR_FILE_CORRUPT;
+ }
Error err = get_token(p_stream,token,line,r_err_str);
if (err!=OK)
@@ -1236,8 +1277,13 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int
bool need_comma=false;
- while(!p_stream->is_eof()) {
+ while(true) {
+
+ if (p_stream->is_eof()) {
+ r_err_str="Unexpected End of File while parsing dictionary";
+ return ERR_FILE_CORRUPT;
+ }
if (at_key) {
@@ -1301,7 +1347,7 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int
}
-Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String &r_err_str,Tag& r_tag) {
+Error VariantParser::_parse_tag(Token& token, Stream *p_stream, int &line, String &r_err_str, Tag& r_tag, ResourceParser *p_res_parser) {
r_tag.fields.clear();
@@ -1321,10 +1367,13 @@ Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String
r_tag.name=token.value;
- print_line("tag name: "+r_tag.name);
-
while(true) {
+ if (p_stream->is_eof()) {
+ r_err_str="Unexpected End of File while parsing tag: "+r_tag.name;
+ return ERR_FILE_CORRUPT;
+ }
+
get_token(p_stream,token,line,r_err_str);
if (token.type==TK_BRACKET_CLOSE)
break;
@@ -1336,7 +1385,6 @@ Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String
String id=token.value;
- print_line("got ID: "+id);
get_token(p_stream,token,line,r_err_str);
if (token.type!=TK_EQUAL) {
@@ -1344,17 +1392,13 @@ Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String
return ERR_PARSE_ERROR;
}
- print_line("got tk: "+String(tk_name[token.type]));
-
get_token(p_stream,token,line,r_err_str);
Variant value;
- Error err = parse_value(token,value,p_stream,line,r_err_str);
+ Error err = parse_value(token,value,p_stream,line,r_err_str,p_res_parser);
if (err)
return err;
- print_line("id: "+id+" value: "+String(value));
-
- r_tag.fields[id]=value;
+ r_tag.fields[id]=value;
}
@@ -1363,23 +1407,71 @@ Error VariantParser::_parse_tag(Token& token,Stream *p_stream, int &line, String
}
-Error VariantParser::parse_tag(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag) {
+Error VariantParser::parse_tag(Stream *p_stream, int &line, String &r_err_str, Tag& r_tag, ResourceParser *p_res_parser) {
Token token;
get_token(p_stream,token,line,r_err_str);
+
+ if (token.type==TK_EOF) {
+ return ERR_FILE_EOF;
+ }
+
if (token.type!=TK_BRACKET_OPEN) {
r_err_str="Expected '['";
return ERR_PARSE_ERROR;
}
- return _parse_tag(token,p_stream,line,r_err_str,r_tag);
+ return _parse_tag(token,p_stream,line,r_err_str,r_tag,p_res_parser);
}
-Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,String &r_assign) {
+Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str, Tag& r_tag, String &r_assign, Variant &r_value, ResourceParser *p_res_parser) {
- r_tag.name.clear();
- r_assign=String();
+
+ //assign..
+ String what;
+
+ while(true) {
+
+
+ CharType c;
+ if (p_stream->saved) {
+ c=p_stream->saved;
+ p_stream->saved=0;
+
+ } else {
+ c=p_stream->get_char();
+ }
+
+ if (p_stream->is_eof())
+ return ERR_FILE_EOF;
+
+ if (c=='[' && what.length()==0) {
+ //it's a tag!
+ p_stream->saved='['; //go back one
+
+ Error err = parse_tag(p_stream,line,r_err_str,r_tag,p_res_parser);
+
+ return err;
+ }
+
+ if (c>32) {
+ if (c!='=') {
+ what+=String::chr(c);
+ } else {
+ r_assign=what;
+ Token token;
+ get_token(p_stream,token,line,r_err_str);
+ Error err = parse_value(token,r_value,p_stream,line,r_err_str,p_res_parser);
+ if (err) {
+
+ }
+ return err;
+ }
+ } else if (c=='\n') {
+ line++;
+ }
+ }
return OK;
}
@@ -1391,6 +1483,11 @@ Error VariantParser::parse(Stream *p_stream, Variant& r_ret, String &r_err_str,
Error err = get_token(p_stream,token,r_err_line,r_err_str);
if (err)
return err;
+
+ if (token.type==TK_EOF) {
+ return ERR_FILE_EOF;
+ }
+
return parse_value(token,r_ret,p_stream,r_err_line,r_err_str,p_res_parser);
}
diff --git a/core/variant_parser.h b/core/variant_parser.h
index d4ec6c6cf5..e1d25f7512 100644
--- a/core/variant_parser.h
+++ b/core/variant_parser.h
@@ -38,6 +38,8 @@ public:
void *userdata;
ParseResourceFunc func;
+ ParseResourceFunc ext_func;
+ ParseResourceFunc sub_func;
};
@@ -82,15 +84,16 @@ public:
private:
static const char * tk_name[TK_MAX];
- static Error _parse_construct(Stream *p_stream, Vector<float>& r_construct, int &line, String &r_err_str);
+ template<class T>
+ static Error _parse_construct(Stream *p_stream, Vector<T>& r_construct, 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);
+ static Error _parse_tag(Token& token,Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,ResourceParser *p_res_parser=NULL);
public:
- static Error parse_tag(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag);
- static Error parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,String &r_assign);
+ static Error parse_tag(Stream *p_stream, int &line, String &r_err_str,Tag& r_tag,ResourceParser *p_res_parser=NULL);
+ static Error parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str, Tag& r_tag, String &r_assign, Variant &r_value,ResourceParser *p_res_parser=NULL);
static Error parse_value(Token& token,Variant &value, Stream *p_stream, int &line, String &r_err_str,ResourceParser *p_res_parser=NULL);
static Error get_token(Stream *p_stream,Token& r_token,int &line,String &r_err_str);
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 896b4fb2fa..863f2be699 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1280,15 +1280,18 @@ StringName SceneState::get_node_name(int p_idx) const {
Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,nodes.size(),Ref<PackedScene>());
+
if (nodes[p_idx].instance>=0) {
return variants[nodes[p_idx].instance];
- } else if (nodes[p_idx].parent<=0 || nodes[p_idx].parent==NO_PARENT_SAVED) {
+ } else if (nodes[p_idx].parent<0 || nodes[p_idx].parent==NO_PARENT_SAVED) {
if (base_scene_idx>=0) {
return variants[base_scene_idx];
}
}
+
+
return Ref<PackedScene>();
@@ -1438,6 +1441,84 @@ Array SceneState::get_connection_binds(int p_idx) const {
Vector<NodePath> SceneState::get_editable_instances() const {
return editable_instances;
}
+//add
+
+int SceneState::add_name(const StringName& p_name) {
+
+ names.push_back(p_name);
+ return names.size()-1;
+}
+
+int SceneState::add_value(const Variant& p_value) {
+
+ variants.push_back(p_value);
+ return variants.size()-1;
+}
+
+int SceneState::add_node_path(const NodePath& p_path){
+
+ node_paths.push_back(p_path);
+ return (node_paths.size()-1)|FLAG_ID_IS_PATH;
+}
+int SceneState::add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance){
+
+ NodeData nd;
+ nd.parent=p_parent;
+ nd.owner=p_owner;
+ nd.type=p_type;
+ nd.name=p_name;
+ nd.instance=p_instance;
+
+ nodes.push_back(nd);
+
+ return nodes.size()-1;
+}
+void SceneState::add_node_property(int p_node,int p_name,int p_value){
+
+ ERR_FAIL_INDEX(p_node,nodes.size());
+ ERR_FAIL_INDEX(p_name,names.size());
+ ERR_FAIL_INDEX(p_value,variants.size());
+
+ NodeData::Property prop;
+ prop.name=p_name;
+ prop.value=p_value;
+ nodes[p_node].properties.push_back(prop);
+}
+void SceneState::add_node_group(int p_node,int p_group){
+
+ ERR_FAIL_INDEX(p_node,nodes.size());
+ ERR_FAIL_INDEX(p_group,names.size());
+ nodes[p_node].groups.push_back(p_group);
+
+}
+void SceneState::set_base_scene(int p_idx){
+
+ ERR_FAIL_INDEX(p_idx,variants.size());
+ base_scene_idx=p_idx;
+}
+void SceneState::add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds){
+
+ ERR_FAIL_INDEX(p_signal,names.size());
+ ERR_FAIL_INDEX(p_method,names.size());
+
+ for(int i=0;i<p_binds.size();i++) {
+ ERR_FAIL_INDEX(p_binds[i],variants.size());
+ }
+ ConnectionData c;
+ c.from=p_from;
+ c.to=p_to;
+ c.signal=p_signal;
+ c.method=p_method;
+ c.flags=p_flags;
+ c.binds=p_binds;
+ connections.push_back(c);
+
+}
+void SceneState::add_editable_instance(const NodePath& p_path){
+
+ editable_instances.push_back(p_path);
+}
+
SceneState::SceneState() {
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index 3956d2abe4..f3ec0afb6d 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -126,7 +126,7 @@ public:
Node *instance(bool p_gen_edit_state=false) const;
- //build-unbuild API
+ //unbuild API
int get_node_count() const;
StringName get_node_type(int p_idx) const;
@@ -150,6 +150,19 @@ public:
Vector<NodePath> get_editable_instances() const;
+ //build API
+
+ int add_name(const StringName& p_name);
+ int add_value(const Variant& p_value);
+ int add_node_path(const NodePath& p_path);
+ int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance);
+ void add_node_property(int p_node,int p_name,int p_value);
+ void add_node_group(int p_node,int p_group);
+ void set_base_scene(int p_idx);
+ void add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds);
+ void add_editable_instance(const NodePath& p_path);
+
+
SceneState();
};
diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp
index 4fc3ece758..5f41dc2ce8 100644
--- a/scene/resources/scene_format_text.cpp
+++ b/scene/resources/scene_format_text.cpp
@@ -9,6 +9,8 @@
#include "version.h"
#include "os/dir_access.h"
+#define _printerr() ERR_PRINT(String(res_path+":"+itos(lines)+" - Parse Error: "+error_text).utf8().get_data());
+
Error ResourceInteractiveLoaderText::parse_property(Variant& r_v, String &r_name) {
@@ -29,44 +31,114 @@ Ref<Resource> ResourceInteractiveLoaderText::get_resource() {
return resource;
}
-Error ResourceInteractiveLoaderText::poll() {
-#if 0
- if (error!=OK)
- return error;
+Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) {
- bool exit;
- Tag *tag = parse_tag(&exit);
+ VariantParser::Token token;
+ VariantParser::get_token(p_stream,token,line,r_err_str);
+ if (token.type!=VariantParser::TK_NUMBER) {
+ r_err_str="Expected number (sub-resource index)";
+ return ERR_PARSE_ERROR;
+ }
+ int index = token.value;
- if (!tag) {
- error=ERR_FILE_CORRUPT;
- if (!exit) // shouldn't have exited
- ERR_FAIL_V(error);
- error=ERR_FILE_EOF;
- return error;
+ String path = local_path+"::"+itos(index);
+
+ if (!ResourceCache::has(path)) {
+ r_err_str="Can't load cached sub-resource: "+path;
+ return ERR_PARSE_ERROR;
}
- RES res;
- //Object *obj=NULL;
+ r_res=RES(ResourceCache::get(path));
- bool main;
+ VariantParser::get_token(p_stream,token,line,r_err_str);
+ if (token.type!=VariantParser::TK_PARENTHESIS_CLOSE) {
+ r_err_str="Expected ')'";
+ return ERR_PARSE_ERROR;
+ }
- if (tag->name=="ext_resource") {
- error=ERR_FILE_CORRUPT;
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
- ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
+ return OK;
+}
+
+Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str){
+
+ VariantParser::Token token;
+ VariantParser::get_token(p_stream,token,line,r_err_str);
+ if (token.type!=VariantParser::TK_NUMBER) {
+ r_err_str="Expected number (sub-resource index)";
+ return ERR_PARSE_ERROR;
+ }
+
+ int id = token.value;
+
+
+ if (!ext_resources.has(id)) {
+ r_err_str="Can't load cached ext-resource #"+itos(id);
+ return ERR_PARSE_ERROR;
+ }
+
+ String path = ext_resources[id].path;
+ String type = ext_resources[id].type;
+
+ if (path.find("://")==-1 && path.is_rel_path()) {
+ // path is relative to file being loaded, so convert to a resource path
+ path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
+
+ }
+
+ r_res=ResourceLoader::load(path,type);
+
+ if (r_res.is_null()) {
+ r_err_str="Couldn't load external resource: "+path;
+ return ERR_PARSE_ERROR;
+ }
+
+ VariantParser::get_token(p_stream,token,line,r_err_str);
+ if (token.type!=VariantParser::TK_PARENTHESIS_CLOSE) {
+ r_err_str="Expected ')'";
+ return ERR_PARSE_ERROR;
+ }
+
+
+ return OK;
+}
+
+
+Error ResourceInteractiveLoaderText::poll() {
+
+ if (error!=OK)
+ return error;
+
+ if (next_tag.name=="ext_resource") {
+
+
+ if (!next_tag.fields.has("path")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Missing 'path' in external resource tag";
+ _printerr();
+ return error;
+ }
- String type="Resource";
- if (tag->args.has("type"))
- type=tag->args["type"];
+ if (!next_tag.fields.has("type")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Missing 'type' in external resource tag";
+ _printerr();
+ return error;
+ }
- String path = tag->args["path"];
+ if (!next_tag.fields.has("id")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Missing 'id' in external resource tag";
+ _printerr();
+ return error;
+ }
+ String path=next_tag.fields["path"];
+ String type=next_tag.fields["type"];
+ int index=next_tag.fields["id"];
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?.");
- ERR_FAIL_COND_V(path.begins_with("local://"),ERR_FILE_CORRUPT);
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
@@ -82,8 +154,10 @@ Error ResourceInteractiveLoaderText::poll() {
if (res.is_null()) {
if (ResourceLoader::get_abort_on_missing_resources()) {
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path);
- ERR_FAIL_V(error);
+ error=ERR_FILE_CORRUPT;
+ error_text="[ext_resource] referenced nonexistent resource at: "+path;
+ _printerr();
+ return error;
} else {
ResourceLoader::notify_dependency_error(local_path,path,type);
}
@@ -92,236 +166,425 @@ Error ResourceInteractiveLoaderText::poll() {
resource_cache.push_back(res);
}
- if (tag->args.has("index")) {
- ExtResource er;
- er.path=path;
- er.type=type;
- ext_resources[tag->args["index"].to_int()]=er;
+ ExtResource er;
+ er.path=path;
+ er.type=type;
+ ext_resources[index]=er;
+
+ error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
+
+ if (error) {
+ _printerr();
}
+ return error;
+
+
+ } else if (next_tag.name=="sub_resource") {
+
- Error err = close_tag("ext_resource");
- if (err)
+ if (!next_tag.fields.has("type")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Missing 'type' in external resource tag";
+ _printerr();
return error;
+ }
+ if (!next_tag.fields.has("id")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="Missing 'index' in external resource tag";
+ _printerr();
+ return error;
+ }
- error=OK;
- resource_current++;
- return error;
+ String type=next_tag.fields["type"];
+ int id=next_tag.fields["id"];
- } else if (tag->name=="resource") {
+ String path = local_path+"::"+itos(id);
- main=false;
- } else if (tag->name=="main_resource") {
- main=true;
- } else {
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": unexpected main tag: "+tag->name);
- error=ERR_FILE_CORRUPT;
- ERR_FAIL_V(error);
- }
+ //bool exists=ResourceCache::has(path);
- String type;
- String path;
- int subres=0;
+ Ref<Resource> res;
- if (!main) {
- //loading resource
+ if ( !ResourceCache::has(path)) { //only if it doesn't exist
- error=ERR_FILE_CORRUPT;
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'len' field.");
- ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field.");
- ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT);
- path=tag->args["path"];
+ Object *obj = ObjectTypeDB::instance(type);
+ if (!obj) {
+
+ error_text+="Can't create sub resource of type: "+type;
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
- error=OK;
- if (path.begins_with("local://")) {
- //built-in resource (but really external)
+ Resource *r = obj->cast_to<Resource>();
+ if (!r) {
+
+ error_text+="Can't create sub resource of type, because not a resource: "+type;
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ res=Ref<Resource>(r);
+ resource_cache.push_back(res);
+ res->set_path(path);
- path=path.replace("local://","");
- subres=path.to_int();
- path=local_path+"::"+path;
}
+ while(true) {
+
+ String assign;
+ Variant value;
+
+ error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);
- if (ResourceCache::has(path)) {
- Error err = close_tag(tag->name);
- if (err) {
+ if (error) {
+ _printerr();
+ return error;
+ }
+
+ if (assign!=String()) {
+ if (res.is_valid()) {
+ res->set(assign,value);
+ }
+ //it's assignment
+ } else if (next_tag.name!=String()) {
+
+ error=OK;
+ break;
+ } else {
error=ERR_FILE_CORRUPT;
+ error_text="Premature end of file while parsing [sub_resource]";
+ _printerr();
+ return error;
}
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Unable to close <resource> tag.");
- ERR_FAIL_COND_V( err, err );
- resource_current++;
- error=OK;
- return OK;
+
+
}
- type = tag->args["type"];
- } else {
- type=resource_type;
- }
+ return OK;
- Object *obj = ObjectTypeDB::instance(type);
- if (!obj) {
- error=ERR_FILE_CORRUPT;
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object of unrecognized type in file: "+type);
- }
- ERR_FAIL_COND_V(!obj,ERR_FILE_CORRUPT);
+ } else if (next_tag.name=="resource") {
- Resource *r = obj->cast_to<Resource>();
- if (!r) {
- error=ERR_FILE_CORRUPT;
- memdelete(obj); //bye
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Object type in resource field not a resource, type is: "+obj->get_type());
- ERR_FAIL_COND_V(!r,ERR_FILE_CORRUPT);
- }
+ if (is_scene) {
- res = RES( r );
- if (path!="")
- r->set_path(path);
- r->set_subindex(subres);
+ error_text+="found the 'resource' tag on a scene file!";
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
- //load properties
+ Object *obj = ObjectTypeDB::instance(res_type);
+ if (!obj) {
- while(true) {
+ error_text+="Can't create sub resource of type: "+res_type;
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
- String name;
- Variant v;
- Error err;
- err = parse_property(v,name);
- if (err==ERR_FILE_EOF) //tag closed
- break;
- if (err!=OK) {
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Text Parsing aborted.");
- ERR_FAIL_COND_V(err!=OK,ERR_FILE_CORRUPT);
+
+ Resource *r = obj->cast_to<Resource>();
+ if (!r) {
+
+ error_text+="Can't create sub resource of type, because not a resource: "+res_type;
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
}
- obj->set(name,v);
- }
-#ifdef TOOLS_ENABLED
- res->set_edited(false);
-#endif
- resource_cache.push_back(res); //keep it in mem until finished loading
- resource_current++;
- if (main) {
- f->close();
- resource=res;
- resource->set_path(res_path);
- error=ERR_FILE_EOF;
- return error;
+ resource=Ref<Resource>(r);
- }
- error=OK;
-#endif
- return OK;
-}
+ while(true) {
-int ResourceInteractiveLoaderText::get_stage() const {
+ String assign;
+ Variant value;
- return resource_current;
-}
-int ResourceInteractiveLoaderText::get_stage_count() const {
+ error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);
- return resources_total;//+ext_resources;
-}
+ if (error) {
+ if (error!=ERR_FILE_EOF) {
+ _printerr();
+ }
+ return error;
+ }
-ResourceInteractiveLoaderText::~ResourceInteractiveLoaderText() {
+ if (assign!=String()) {
+ resource->set(assign,value);
+ //it's assignment
+ } else if (next_tag.name!=String()) {
- memdelete(f);
-}
+ error=ERR_FILE_CORRUPT;
+ error_text="Extra tag found when parsing main resource file";
+ _printerr();
+ return error;
+ } else {
+ error=ERR_FILE_EOF;
+ return error;
+ }
-void ResourceInteractiveLoaderText::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) {
+ }
-#if 0
- open(f);
- ERR_FAIL_COND(error!=OK);
+ return OK;
- while(true) {
- bool exit;
- Tag *tag = parse_tag(&exit);
+ } else if (next_tag.name=="node") {
+ if (!is_scene) {
- if (!tag) {
+ error_text+="found the 'node' tag on a resource file!";
+ _printerr();
error=ERR_FILE_CORRUPT;
- ERR_FAIL_COND(!exit);
- error=ERR_FILE_EOF;
- return;
+ return error;
}
- if (tag->name!="ext_resource") {
+ /*
+ int add_name(const StringName& p_name);
+ int add_value(const Variant& p_value);
+ int add_node_path(const NodePath& p_path);
+ int add_node(int p_parent,int p_owner,int p_type,int p_name, int p_instance);
+ void add_node_property(int p_node,int p_name,int p_value);
+ void add_node_group(int p_node,int p_group);
+ void set_base_scene(int p_idx);
+ void add_connection(int p_from,int p_to, int p_signal, int p_method, int p_flags,const Vector<int>& p_binds);
+ void add_editable_instance(const NodePath& p_path);
+
+ */
+
+ int parent=-1;
+ int owner=-1;
+ int type=-1;
+ int name=-1;
+ int instance=-1;
+ int base_scene=-1;
+
+ if (next_tag.fields.has("name")) {
+ name=packed_scene->get_state()->add_name(next_tag.fields["name"]);
+ }
- return;
+ if (next_tag.fields.has("parent")) {
+ parent=packed_scene->get_state()->add_node_path(next_tag.fields["parent"]);
}
- error=ERR_FILE_CORRUPT;
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
- ERR_FAIL_COND(!tag->args.has("path"));
+ if (next_tag.fields.has("owner")) {
+ owner=packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
+ } else {
+ if (parent!=-1)
+ owner=0; //if no owner, owner is root
+ }
- String path = tag->args["path"];
- ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> can't use a local path, this is a bug?.");
- ERR_FAIL_COND(path.begins_with("local://"));
+ if (next_tag.fields.has("type")) {
+ type=packed_scene->get_state()->add_name(next_tag.fields["type"]);
+ }
- if (path.find("://")==-1 && path.is_rel_path()) {
- // path is relative to file being loaded, so convert to a resource path
- path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path));
+ if (next_tag.fields.has("instance")) {
+
+ instance=packed_scene->get_state()->add_value(next_tag.fields["instance"]);
+
+ if (packed_scene->get_state()->get_node_count()==0 && parent==-1) {
+ packed_scene->get_state()->set_base_scene(instance);
+ instance=-1;
+ }
}
- if (path.ends_with("*")) {
- ERR_FAIL_COND(!tag->args.has("type"));
- String type = tag->args["type"];
- path = ResourceLoader::guess_full_filename(path,type);
+ int node_id = packed_scene->get_state()->add_node(parent,owner,type,name,instance);
+
+
+ while(true) {
+
+ String assign;
+ Variant value;
+
+ error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);
+
+ if (error) {
+ if (error!=ERR_FILE_EOF) {
+ _printerr();
+ } else {
+ resource=packed_scene;
+ }
+ return error;
+ }
+
+ if (assign!=String()) {
+ int nameidx = packed_scene->get_state()->add_name(assign);
+ int valueidx = packed_scene->get_state()->add_value(value);
+ packed_scene->get_state()->add_node_property(node_id,nameidx,valueidx);
+ //it's assignment
+ } else if (next_tag.name!=String()) {
+
+ error=OK;
+ return error;
+ } else {
+
+ resource=packed_scene;
+ error=ERR_FILE_EOF;
+ return error;
+ }
+
}
- if (p_add_types && tag->args.has("type")) {
- path+="::"+tag->args["type"];
+ return OK;
+
+ } else if (next_tag.name=="connection") {
+
+ if (!is_scene) {
+
+ error_text+="found the 'connection' tag on a resource file!";
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
}
- p_dependencies->push_back(path);
+ if (!next_tag.fields.has("from")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="missing 'from' field fron connection tag";
+ return error;
+ }
- Error err = close_tag("ext_resource");
- if (err)
- return;
+ if (!next_tag.fields.has("to")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="missing 'to' field fron connection tag";
+ return error;
+ }
- error=OK;
- }
-#endif
-}
+ if (!next_tag.fields.has("signal")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="missing 'signal' field fron connection tag";
+ return error;
+ }
-Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
+ if (!next_tag.fields.has("method")) {
+ error=ERR_FILE_CORRUPT;
+ error_text="missing 'method' field fron connection tag";
+ return error;
+ }
+ NodePath from = next_tag.fields["from"];
+ NodePath to = next_tag.fields["to"];
+ StringName method = next_tag.fields["method"];
+ StringName signal = next_tag.fields["signal"];
+ int flags=CONNECT_PERSIST;
+ Array binds;
+ if (next_tag.fields.has("flags")) {
+ flags=next_tag.fields["flags"];
+ }
- if (next_tag.name=="ext_resource") {
+ if (next_tag.fields.has("binds")) {
+ binds=next_tag.fields["binds"];
+ }
- Error err;
+ Vector<int> bind_ints;
+ for(int i=9;i<binds.size();i++) {
+ bind_ints.push_back( packed_scene->get_state()->add_value( bind_ints[i] ) );
+ }
+
+ packed_scene->get_state()->add_connection(
+ packed_scene->get_state()->add_node_path(from.simplified()),
+ packed_scene->get_state()->add_node_path(to.simplified()),
+ packed_scene->get_state()->add_name(signal),
+ packed_scene->get_state()->add_name(method),
+ flags,
+ bind_ints
+ );
+
+ error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
+
+ if (error) {
+ if (error!=ERR_FILE_EOF) {
+ _printerr();
+ } else {
+ resource=packed_scene;
+ }
+ }
+
+ return error;
+ } else if (next_tag.name=="editable") {
+
+ if (!is_scene) {
+
+ error_text+="found the 'editable' tag on a resource file!";
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
if (!next_tag.fields.has("path")) {
- err=ERR_FILE_CORRUPT;
- error_text="Missing 'path' in external resource tag";
+ error=ERR_FILE_CORRUPT;
+ error_text="missing 'path' field fron connection tag";
_printerr();
- return err;
+ return error;
+ }
+
+ NodePath path = next_tag.fields["path"];
+
+ packed_scene->get_state()->add_editable_instance(path.simplified());
+
+ error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
+
+ if (error) {
+ if (error!=ERR_FILE_EOF) {
+ _printerr();
+ } else {
+ resource=packed_scene;
+ }
}
+ return error;
+
+ } else {
+
+ error_text+="Unknown tag in file: "+next_tag.name;
+ _printerr();
+ error=ERR_FILE_CORRUPT;
+ return error;
+ }
+
+ return OK;
+}
+
+int ResourceInteractiveLoaderText::get_stage() const {
+
+ return resource_current;
+}
+int ResourceInteractiveLoaderText::get_stage_count() const {
+
+ return resources_total;//+ext_resources;
+}
+
+ResourceInteractiveLoaderText::~ResourceInteractiveLoaderText() {
+
+ memdelete(f);
+}
+
+void ResourceInteractiveLoaderText::get_dependencies(FileAccess *f,List<String> *p_dependencies,bool p_add_types) {
+
+
+ open(f);
+ ERR_FAIL_COND(error!=OK);
+
+ while(next_tag.name=="ext_resource") {
+
if (!next_tag.fields.has("type")) {
- err=ERR_FILE_CORRUPT;
+ error=ERR_FILE_CORRUPT;
error_text="Missing 'type' in external resource tag";
_printerr();
- return err;
+ return;
}
- if (!next_tag.fields.has("index")) {
- err=ERR_FILE_CORRUPT;
+ if (!next_tag.fields.has("id")) {
+ error=ERR_FILE_CORRUPT;
error_text="Missing 'index' in external resource tag";
_printerr();
- return err;
+ return;
}
String path=next_tag.fields["path"];
String type=next_tag.fields["type"];
- int index=next_tag.fields["index"];
if (path.find("://")==-1 && path.is_rel_path()) {
@@ -329,45 +592,29 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
path=Globals::get_singleton()->localize_path(local_path.get_base_dir().plus_file(path));
}
- if (remaps.has(path)) {
- path=remaps[path];
- }
-
- RES res = ResourceLoader::load(path,type);
-
- if (res.is_null()) {
-
- if (ResourceLoader::get_abort_on_missing_resources()) {
- error=ERR_FILE_CORRUPT;
- error_text="[ext_resource] referenced nonexistent resource at: "+path;
- _printerr();
- return error;
- } else {
- ResourceLoader::notify_dependency_error(local_path,path,type);
- }
- } else {
- resource_cache.push_back(res);
+ if (p_add_types) {
+ path+="::"+type;
}
- ExtResource er;
- er.path=path;
- er.type=type;
- ext_resources[index]=er;
+ p_dependencies->push_back(path);
- err = VariantParser::parse_tag(&stream,lines,error_text,next_tag);
+ Error err = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
if (err) {
error_text="Unexpected end of file";
_printerr();
error=ERR_FILE_CORRUPT;
- return error;
}
- return OK;
-
}
+}
+
+Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
+
+
+
#if 0
open(p_f);
@@ -562,10 +809,11 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f) {
}
}
- print_line("TAG NAME: "+tag.name);
if (tag.name=="gd_scene") {
is_scene=true;
+ packed_scene.instance();
+
} else if (tag.name=="gd_resource") {
if (!tag.fields.has("type")) {
error_text="Missing 'type' field in 'gd_resource' tag";
@@ -593,7 +841,7 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f) {
}
- err = VariantParser::parse_tag(&stream,lines,error_text,next_tag);
+ err = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
if (err) {
error_text="Unexpected end of file";
@@ -601,12 +849,14 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f) {
error=ERR_FILE_CORRUPT;
}
+ rp.ext_func=_parse_ext_resources;
+ rp.sub_func=_parse_sub_resources;
+ rp.func=NULL;
+ rp.userdata=this;
+
}
-void ResourceInteractiveLoaderText::_printerr() {
- ERR_PRINT(String(res_path+":"+itos(lines)+" - Parse Error: "+error_text).utf8().get_data());
-}
String ResourceInteractiveLoaderText::recognize(FileAccess *p_f) {
@@ -707,6 +957,8 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const{
String ext=p_path.extension().to_lower();
if (ext=="tscn")
return "PackedScene";
+ else if (ext!="tres")
+ return String();
//for anyhting else must test..
@@ -978,7 +1230,7 @@ void ResourceFormatSaverTextInstance::write_property(const String& p_name,const
if (external_resources.has(res)) {
- f->store_string("Resource( "+itos(external_resources[res]+1)+" )");
+ f->store_string("ExtResource( "+itos(external_resources[res]+1)+" )");
} else {
if (internal_resources.has(res)) {
@@ -1434,6 +1686,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
Ref<PackedScene> instance = state->get_node_instance(i);
Vector<StringName> groups = state->get_node_groups(i);
+ if (instance.is_valid())
+ print_line("for path "+String(path)+" instance "+instance->get_path());
+
String header="[node";
header+=" name=\""+String(name)+"\"";
if (type!=StringName()) {
@@ -1451,7 +1706,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re
for(int j=0;j<groups.size();j++) {
if (j>0)
sgroups+=", ";
- sgroups+="\""+groups[i].operator String().c_escape()+"\"";
+ sgroups+="\""+groups[j].operator String().c_escape()+"\"";
}
sgroups+=" ]";
header+=sgroups;
diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h
index 16260835f8..4f18af2b62 100644
--- a/scene/resources/scene_format_text.h
+++ b/scene/resources/scene_format_text.h
@@ -43,7 +43,19 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
mutable int lines;
Map<String,String> remaps;
- void _printerr();
+ //void _printerr();
+
+ static Error _parse_sub_resources(void* p_self, VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_sub_resource(p_stream,r_res,line,r_err_str); }
+ static Error _parse_ext_resources(void* p_self, VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_ext_resource(p_stream,r_res,line,r_err_str); }
+
+ Error _parse_sub_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
+ Error _parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
+
+ VariantParser::ResourceParser rp;
+
+
+ Ref<PackedScene> packed_scene;
+
friend class ResourceFormatLoaderText;
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 01e53ead18..9d4cb2c8a2 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -3543,13 +3543,14 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bo
if (p_set_inherited) {
Ref<SceneState> state = sdata->get_state();
- state->set_path(lpath);
+ state->set_path(lpath);
new_scene->set_scene_inherited_state(state);
new_scene->set_filename(String());
- if (new_scene->get_scene_instance_state().is_valid())
- new_scene->get_scene_instance_state()->set_path(String());
+ //if (new_scene->get_scene_instance_state().is_valid())
+ // new_scene->get_scene_instance_state()->set_path(String());
}
+ new_scene->set_scene_instance_state(Ref<SceneState>());
set_edited_scene(new_scene);
_get_scene_metadata();