-Fixed bug with scene inheritance, should work again

-Proper .tscn and .tres parsing, should work, please test well!
This commit is contained in:
Juan Linietsky 2015-11-28 20:56:14 -03:00
parent bd10df93ec
commit 7aa39b7cae
7 changed files with 812 additions and 350 deletions

View file

@ -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,25 +763,8 @@ 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;
}
value=res;
return OK;
} else if (p_res_parser && p_res_parser->func){
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);
@ -778,15 +773,56 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
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;
return OK;
} else if (p_res_parser && id=="SubResource" && p_res_parser->sub_func){
RES res;
Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
if (err)
return err;
value=res;
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,9 +1277,14 @@ 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) {
Error err = get_token(p_stream,token,line,r_err_str);
@ -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);
}

View file

@ -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);

View file

@ -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() {

View file

@ -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();
};

View file

@ -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,299 +31,113 @@ 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);
if (!tag) {
error=ERR_FILE_CORRUPT;
if (!exit) // shouldn't have exited
ERR_FAIL_V(error);
error=ERR_FILE_EOF;
return error;
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;
}
RES res;
//Object *obj=NULL;
int index = token.value;
bool main;
String path = local_path+"::"+itos(index);
if (tag->name=="ext_resource") {
if (!ResourceCache::has(path)) {
r_err_str="Can't load cached sub-resource: "+path;
return ERR_PARSE_ERROR;
}
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);
r_res=RES(ResourceCache::get(path));
String type="Resource";
if (tag->args.has("type"))
type=tag->args["type"];
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_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
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()) {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> referenced nonexistent resource at: "+path);
ERR_FAIL_V(error);
} else {
ResourceLoader::notify_dependency_error(local_path,path,type);
}
} else {
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;
}
Error err = close_tag("ext_resource");
if (err)
return error;
error=OK;
resource_current++;
return error;
} else if (tag->name=="resource") {
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);
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;
}
String type;
String path;
int subres=0;
if (!main) {
//loading resource
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"];
error=OK;
if (path.begins_with("local://")) {
//built-in resource (but really external)
path=path.replace("local://","");
subres=path.to_int();
path=local_path+"::"+path;
}
if (ResourceCache::has(path)) {
Error err = close_tag(tag->name);
if (err) {
error=ERR_FILE_CORRUPT;
}
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;
}
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);
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);
}
res = RES( r );
if (path!="")
r->set_path(path);
r->set_subindex(subres);
//load properties
while(true) {
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);
}
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;
}
error=OK;
#endif
return OK;
}
int ResourceInteractiveLoaderText::get_stage() const {
Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str){
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) {
#if 0
open(f);
ERR_FAIL_COND(error!=OK);
while(true) {
bool exit;
Tag *tag = parse_tag(&exit);
if (!tag) {
error=ERR_FILE_CORRUPT;
ERR_FAIL_COND(!exit);
error=ERR_FILE_EOF;
return;
}
if (tag->name!="ext_resource") {
return;
}
error=ERR_FILE_CORRUPT;
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
ERR_FAIL_COND(!tag->args.has("path"));
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 (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 (path.ends_with("*")) {
ERR_FAIL_COND(!tag->args.has("type"));
String type = tag->args["type"];
path = ResourceLoader::guess_full_filename(path,type);
}
if (p_add_types && tag->args.has("type")) {
path+="::"+tag->args["type"];
}
p_dependencies->push_back(path);
Error err = close_tag("ext_resource");
if (err)
return;
error=OK;
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;
}
#endif
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::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
Error ResourceInteractiveLoaderText::poll() {
if (error!=OK)
return error;
if (next_tag.name=="ext_resource") {
Error err;
if (!next_tag.fields.has("path")) {
err=ERR_FILE_CORRUPT;
error=ERR_FILE_CORRUPT;
error_text="Missing 'path' in external resource tag";
_printerr();
return err;
return error;
}
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 error;
}
if (!next_tag.fields.has("index")) {
err=ERR_FILE_CORRUPT;
error_text="Missing 'index' in external resource tag";
if (!next_tag.fields.has("id")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'id' in external resource tag";
_printerr();
return err;
return error;
}
String path=next_tag.fields["path"];
String type=next_tag.fields["type"];
int index=next_tag.fields["index"];
int index=next_tag.fields["id"];
if (path.find("://")==-1 && path.is_rel_path()) {
@ -355,19 +171,450 @@ Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const
er.type=type;
ext_resources[index]=er;
err = VariantParser::parse_tag(&stream,lines,error_text,next_tag);
error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp);
if (err) {
error_text="Unexpected end of file";
if (error) {
_printerr();
}
return error;
} else if (next_tag.name=="sub_resource") {
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;
}
String type=next_tag.fields["type"];
int id=next_tag.fields["id"];
String path = local_path+"::"+itos(id);
//bool exists=ResourceCache::has(path);
Ref<Resource> res;
if ( !ResourceCache::has(path)) { //only if it doesn't exist
Object *obj = ObjectTypeDB::instance(type);
if (!obj) {
error_text+="Can't create sub resource of type: "+type;
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
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);
}
while(true) {
String assign;
Variant value;
error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp);
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;
}
}
return OK;
} else if (next_tag.name=="resource") {
if (is_scene) {
error_text+="found the 'resource' tag on a scene file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
Object *obj = ObjectTypeDB::instance(res_type);
if (!obj) {
error_text+="Can't create sub resource of type: "+res_type;
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
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;
}
resource=Ref<Resource>(r);
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();
}
return error;
}
if (assign!=String()) {
resource->set(assign,value);
//it's assignment
} else if (next_tag.name!=String()) {
error=ERR_FILE_CORRUPT;
error_text="Extra tag found when parsing main resource file";
_printerr();
return error;
} else {
error=ERR_FILE_EOF;
return error;
}
}
return OK;
} else if (next_tag.name=="node") {
if (!is_scene) {
error_text+="found the 'node' tag on a resource file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
/*
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"]);
}
if (next_tag.fields.has("parent")) {
parent=packed_scene->get_state()->add_node_path(next_tag.fields["parent"]);
}
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
}
if (next_tag.fields.has("type")) {
type=packed_scene->get_state()->add_name(next_tag.fields["type"]);
}
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;
}
}
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;
}
}
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;
}
if (!next_tag.fields.has("from")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'from' field fron connection tag";
return error;
}
if (!next_tag.fields.has("to")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'to' field fron connection tag";
return error;
}
if (!next_tag.fields.has("signal")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'signal' field fron connection tag";
return error;
}
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.fields.has("binds")) {
binds=next_tag.fields["binds"];
}
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")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'path' field fron connection tag";
_printerr();
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")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'type' in external resource tag";
_printerr();
return;
}
if (!next_tag.fields.has("id")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'index' in external resource tag";
_printerr();
return;
}
String path=next_tag.fields["path"];
String type=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 (p_add_types) {
path+="::"+type;
}
p_dependencies->push_back(path);
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;
}
}
}
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;

View file

@ -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;

View file

@ -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();