diff options
| -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;  |