diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/gui/container.cpp | 8 | ||||
-rw-r--r-- | scene/gui/container.h | 1 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 3 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 13 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 2 | ||||
-rw-r--r-- | scene/resources/packed_scene.cpp | 83 | ||||
-rw-r--r-- | scene/resources/packed_scene.h | 15 | ||||
-rw-r--r-- | scene/resources/scene_format_text.cpp | 677 | ||||
-rw-r--r-- | scene/resources/scene_format_text.h | 14 |
9 files changed, 600 insertions, 216 deletions
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 6c74bc3977..8cdf4dd039 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -52,6 +52,14 @@ void Container::add_child_notify(Node *p_child) { } +void Container::move_child_notify(Node *p_child) { + + if (!p_child->cast_to<Control>()) + return; + + queue_sort(); +} + void Container::remove_child_notify(Node *p_child) { diff --git a/scene/gui/container.h b/scene/gui/container.h index ba9bf2d60f..04d5d6ab36 100644 --- a/scene/gui/container.h +++ b/scene/gui/container.h @@ -42,6 +42,7 @@ protected: void queue_sort(); virtual void add_child_notify(Node *p_child); + virtual void move_child_notify(Node *p_child); virtual void remove_child_notify(Node *p_child); void _notification(int p_what); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index b98fec1bde..3b0425b223 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1689,10 +1689,11 @@ void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_v_scroll"),&RichTextLabel::get_v_scroll); + ObjectTypeDB::bind_method(_MD("scroll_to_line"),&RichTextLabel::scroll_to_line); + ObjectTypeDB::bind_method(_MD("set_tab_size","spaces"),&RichTextLabel::set_tab_size); ObjectTypeDB::bind_method(_MD("get_tab_size"),&RichTextLabel::get_tab_size); - ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled); ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 5415484009..78792dc785 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1610,6 +1610,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { else break; } + if(auto_indent){ + // indent once again if previous line will end with ':' + // (i.e. colon precedes current cursor position) + if(cursor.column>0 && text[cursor.line][cursor.column-1]==':') { + ins+="\t"; + } + } _insert_text_at_cursor(ins); _push_current_op(); @@ -2869,6 +2876,10 @@ bool TextEdit::is_syntax_coloring_enabled() const { return syntax_coloring; } +void TextEdit::set_auto_indent(bool p_auto_indent) { + auto_indent = p_auto_indent; +} + void TextEdit::cut() { if (!selection.active) @@ -3836,7 +3847,7 @@ TextEdit::TextEdit() { next_operation_is_complex=false; auto_brace_completion_enabled=false; brace_matching_enabled=false; - + auto_indent=false; } TextEdit::~TextEdit() diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 059e15dcff..91369309cf 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -213,6 +213,7 @@ class TextEdit : public Control { bool auto_brace_completion_enabled; bool brace_matching_enabled; + bool auto_indent; bool cut_copy_line; uint64_t last_dblclk; @@ -323,6 +324,7 @@ public: brace_matching_enabled=p_enabled; update(); } + void set_auto_indent(bool p_auto_indent); void cursor_set_column(int p_col, bool p_adjust_viewport=true); void cursor_set_line(int p_row, bool p_adjust_viewport=true); 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; |