diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-02-21 11:17:50 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-02-21 11:18:31 -0300 |
commit | b91b89cf60c31ec15c7f4f2ee51cc51e0e11c4ee (patch) | |
tree | 9eecd866991efbf70211b10b12f68065d8be61f6 /scene/resources | |
parent | d27b83d4bd5643ac42666735e8df8a8059d31aca (diff) |
Add support for placeholders in tscn, which was missing. Closes #3652
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/packed_scene.cpp | 29 | ||||
-rw-r--r-- | scene/resources/packed_scene.h | 11 | ||||
-rw-r--r-- | scene/resources/scene_format_text.cpp | 31 |
3 files changed, 64 insertions, 7 deletions
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 4c23ddbaf7..a9010e79a2 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -1316,11 +1316,23 @@ StringName SceneState::get_node_name(int p_idx) const { return names[nodes[p_idx].name]; } + +bool SceneState::is_node_instance_placeholder(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,nodes.size(),false); + + return nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER; + +} + 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]; + if (nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER) + return Ref<PackedScene>(); + else + return variants[nodes[p_idx].instance&FLAG_MASK]; } else if (nodes[p_idx].parent<0 || nodes[p_idx].parent==NO_PARENT_SAVED) { if (base_scene_idx>=0) { @@ -1334,6 +1346,19 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const { } + +String SceneState::get_node_instance_placeholder(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,nodes.size(),String()); + + if (nodes[p_idx].instance>=0 && nodes[p_idx].instance&FLAG_INSTANCE_IS_PLACEHOLDER) { + return variants[nodes[p_idx].instance&FLAG_MASK]; + } + + return String(); + +} + Vector<StringName> SceneState::get_node_groups(int p_idx) const{ ERR_FAIL_INDEX_V(p_idx,nodes.size(),Vector<StringName>()); Vector<StringName> groups; @@ -1577,6 +1602,8 @@ void SceneState::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_node_name","idx"),&SceneState::get_node_name); ObjectTypeDB::bind_method(_MD("get_node_path","idx","for_parent"),&SceneState::get_node_path,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_node_owner_path","idx"),&SceneState::get_node_owner_path); + ObjectTypeDB::bind_method(_MD("is_node_instance_placeholder","idx"),&SceneState::is_node_instance_placeholder); + ObjectTypeDB::bind_method(_MD("get_node_instance_placeholder","idx"),&SceneState::get_node_instance_placeholder); ObjectTypeDB::bind_method(_MD("get_node_instance:PackedScene","idx"),&SceneState::get_node_instance); ObjectTypeDB::bind_method(_MD("get_node_groups","idx"),&SceneState::_get_node_groups); ObjectTypeDB::bind_method(_MD("get_node_property_count","idx"),&SceneState::get_node_property_count); diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 7fda4392d8..6a26cc472c 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -48,11 +48,7 @@ class SceneState : public Reference { int base_scene_idx; enum { - FLAG_ID_IS_PATH=(1<<30), - FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30), - FLAG_MASK=(1<<24)-1, NO_PARENT_SAVED=0x7FFFFFFF, - }; struct NodeData { @@ -115,7 +111,10 @@ protected: public: enum { - TYPE_INSTANCED=0x7FFFFFFF + FLAG_ID_IS_PATH=(1<<30), + TYPE_INSTANCED=0x7FFFFFFF, + FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30), + FLAG_MASK=(1<<24)-1, }; static void set_disable_placeholders(bool p_disable); @@ -148,6 +147,8 @@ public: NodePath get_node_path(int p_idx,bool p_for_parent=false) const; NodePath get_node_owner_path(int p_idx) const; Ref<PackedScene> get_node_instance(int p_idx) const; + String get_node_instance_placeholder(int p_idx) const; + bool is_node_instance_placeholder(int p_idx) const; Vector<StringName> get_node_groups(int p_idx) const; int get_node_property_count(int p_idx) const; diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index d9f6beabc0..46f1d5c02e 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -389,6 +389,22 @@ Error ResourceInteractiveLoaderText::poll() { } } + if (next_tag.fields.has("instance_placeholder")) { + + String path=next_tag.fields["instance_placeholder"]; + + int path_v = packed_scene->get_state()->add_value(path); + + if (packed_scene->get_state()->get_node_count()==0) { + error=ERR_FILE_CORRUPT; + error_text="Instance Placeholder can't be used for inheritance."; + _printerr(); + return error; + } + + instance=path_v|SceneState::FLAG_INSTANCE_IS_PLACEHOLDER; + } + if (next_tag.fields.has("owner")) { owner=packed_scene->get_state()->add_node_path(next_tag.fields["owner"]); } else { @@ -1124,7 +1140,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re if (packed_scene.is_valid()) { //add instances to external resources if saving a packed scene for(int i=0;i<packed_scene->get_state()->get_node_count();i++) { - Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i); + if (packed_scene->get_state()->is_node_instance_placeholder(i)) + continue; + + Ref<PackedScene> instance=packed_scene->get_state()->get_node_instance(i); if (instance.is_valid() && !external_resources.has(instance)) { int index = external_resources.size(); external_resources[instance]=index; @@ -1268,8 +1287,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re NodePath path = state->get_node_path(i,true); NodePath owner = state->get_node_owner_path(i); Ref<PackedScene> instance = state->get_node_instance(i); + String instance_placeholder = state->get_node_instance_placeholder(i); Vector<StringName> groups = state->get_node_groups(i); + if (instance.is_valid()) print_line("for path "+String(path)+" instance "+instance->get_path()); @@ -1298,6 +1319,14 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_re f->store_string(header); + if (instance_placeholder!=String()) { + + String vars; + f->store_string(" instance_placeholder="); + VariantWriter::write_to_string(instance_placeholder,vars,_write_resources,this); + f->store_string(vars); + } + if (instance.is_valid()) { String vars; |