Ver código fonte

-Some changes to how scenes and scripts are overriden in scene instance and inheritance
-Fixes #3127 and also properly fixes #2958

Juan Linietsky 9 anos atrás
pai
commit
a74138a0dc
3 arquivos alterados com 49 adições e 5 exclusões
  1. 16 0
      core/script_language.cpp
  2. 2 0
      core/script_language.h
  3. 31 5
      scene/resources/packed_scene.cpp

+ 16 - 0
core/script_language.cpp

@@ -92,6 +92,22 @@ void ScriptServer::init_languages() {
 	}
 }
 
+void ScriptInstance::get_property_state(List<Pair<StringName, Variant> > &state) {
+
+	List<PropertyInfo> pinfo;
+	get_property_list(&pinfo);
+	for (List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
+
+		if (E->get().usage&PROPERTY_USAGE_STORAGE) {
+			Pair<StringName,Variant> p;
+			p.first=E->get().name;
+			if (get(p.first,p.second))
+				state.push_back(p);
+		}
+	}
+}
+
+
 Variant ScriptInstance::call(const StringName& p_method,VARIANT_ARG_DECLARE) {
 
 	VARIANT_ARGPTRS;

+ 2 - 0
core/script_language.h

@@ -113,6 +113,8 @@ public:
 	virtual void get_property_list(List<PropertyInfo> *p_properties) const=0;
 	virtual Variant::Type get_property_type(const StringName& p_name,bool *r_is_valid=NULL) const=0;
 
+	virtual void get_property_state(List<Pair<StringName,Variant> > &state);
+
 	virtual void get_method_list(List<MethodInfo> *p_list) const=0;
 	virtual bool has_method(const StringName& p_method) const=0;
 	virtual Variant call(const StringName& p_method,VARIANT_ARG_LIST);

+ 31 - 5
scene/resources/packed_scene.cpp

@@ -33,7 +33,7 @@
 #include "scene/gui/control.h"
 #include "scene/2d/node_2d.h"
 #include "scene/main/instance_placeholder.h"
-
+#include "core/core_string_names.h"
 #define PACK_VERSION 2
 
 bool SceneState::can_instance() const {
@@ -99,6 +99,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
 
 		Node *node=NULL;
 
+
 		if (i==0 && base_scene_idx>=0) {
 			//scene inheritance on root node
             //print_line("scene inherit");
@@ -193,7 +194,26 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
 					ERR_FAIL_INDEX_V( nprops[j].name, sname_count, NULL );
 					ERR_FAIL_INDEX_V( nprops[j].value, prop_count, NULL );
 
-					node->set(snames[ nprops[j].name ],props[ nprops[j].value ],&valid);
+					if (snames[ nprops[j].name ]==CoreStringNames::get_singleton()->_script) {
+						//work around to avoid old script variables from disappearing, should be the proper fix to:
+						//https://github.com/godotengine/godot/issues/2958
+
+						//store old state
+						List<Pair<StringName,Variant> > old_state;
+						if (node->get_script_instance()) {
+							node->get_script_instance()->get_property_state(old_state);
+						}
+
+						node->set(snames[ nprops[j].name ],props[ nprops[j].value ],&valid);
+
+						//restore old state for new script, if exists
+						for (List<Pair<StringName,Variant> >::Element *E=old_state.front();E;E=E->next()) {
+							node->set(E->get().first,E->get().second);
+						}
+					} else {
+
+						node->set(snames[ nprops[j].name ],props[ nprops[j].value ],&valid);
+					}
 				}
 			}
 
@@ -460,6 +480,7 @@ Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<S
 	List<PropertyInfo> plist;
 	p_node->get_property_list(&plist);
 
+	bool saved_script=false;
 
 	for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) {
 
@@ -508,8 +529,10 @@ Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<S
 					break;
 				}
 			}
-
-			if (exists && p_node->get_script_instance()) {
+#if 0
+// this workaround ended up causing problems:
+https://github.com/godotengine/godot/issues/3127
+			if (saved_script && exists && p_node->get_script_instance()) {
 				//if this is an overriden value by another script, save it anyway
 				//as the script change will erase it
 				//https://github.com/godotengine/godot/issues/2958
@@ -522,7 +545,7 @@ Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<S
 				}
 			}
 
-
+#endif
 			if (exists && bool(Variant::evaluate(Variant::OP_EQUAL,value,original))) {
 				//exists and did not change
 				continue;
@@ -543,6 +566,9 @@ Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<S
 			}
 		}
 
+		if (name=="script/script")
+			saved_script=true;
+
 		NodeData::Property prop;
 		prop.name=_nm_get_string( name,name_map);
 		prop.value=_vm_get_variant( value, variant_map);