Merge pull request #46270 from RandomShaper/fix_can_reset

Rationalize property reversion
This commit is contained in:
Rémi Verschelde 2021-07-31 14:13:24 +02:00 committed by GitHub
commit 20d46c5b9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 74 deletions

View file

@ -493,6 +493,7 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
if (ss.is_valid()) { if (ss.is_valid()) {
found_state = true; found_state = true;
break;
} }
if (node == edited_scene) { if (node == edited_scene) {
//just in case //just in case
@ -506,59 +507,71 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
} }
} }
if (p_current.get_type() == Variant::FLOAT && p_orig.get_type() == Variant::FLOAT) { return is_property_value_different(p_current, p_orig);
float a = p_current;
float b = p_orig;
return !Math::is_equal_approx(a, b); //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
}
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL, p_current, p_orig));
} }
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) { bool EditorPropertyRevert::is_property_value_different(const Variant &p_a, const Variant &p_b) {
bool has_revert = false; if (p_a.get_type() == Variant::FLOAT && p_b.get_type() == Variant::FLOAT) {
//this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
Node *node = Object::cast_to<Node>(p_object); return !Math::is_equal_approx((float)p_a, (float)p_b);
if (node && EditorPropertyRevert::may_node_be_in_instance(node)) {
//check for difference including instantiation
Variant vorig;
if (EditorPropertyRevert::get_instantiated_node_original_property(node, p_property, vorig)) {
Variant v = p_object->get(p_property);
if (EditorPropertyRevert::is_node_property_different(node, v, vorig)) {
has_revert = true;
}
}
} else { } else {
//check for difference against default class value instead return p_a != p_b;
Variant default_value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property);
if (default_value != Variant() && default_value != p_object->get(p_property)) {
has_revert = true;
}
} }
}
Variant EditorPropertyRevert::get_property_revert_value(Object *p_object, const StringName &p_property) {
// If the object implements property_can_revert, rely on that completely // If the object implements property_can_revert, rely on that completely
// (i.e. don't then try to revert to default value - the property_get_revert implementation // (i.e. don't then try to revert to default value - the property_get_revert implementation
// can do that if so desired) // can do that if so desired)
if (p_object->has_method("property_can_revert")) { if (p_object->has_method("property_can_revert") && p_object->call("property_can_revert", p_property)) {
has_revert = p_object->call("property_can_revert", p_property).operator bool(); return p_object->call("property_get_revert", p_property);
} else { }
if (!has_revert && !p_object->get_script().is_null()) {
Ref<Script> scr = p_object->get_script(); Ref<Script> scr = p_object->get_script();
if (scr.is_valid()) { Node *node = Object::cast_to<Node>(p_object);
Variant orig_value; if (node && EditorPropertyRevert::may_node_be_in_instance(node)) {
if (scr->get_property_default_value(p_property, orig_value)) { //if this node is an instance or inherits, but it has a script attached which is unrelated
if (orig_value != p_object->get(p_property)) { //to the one set for the parent and also has a default value for the property, consider that
has_revert = true; //has precedence over the value from the parent, because that is an explicit source of defaults
} //closer in the tree to the current node
bool ignore_parent = false;
if (scr.is_valid()) {
Variant sorig;
if (EditorPropertyRevert::get_instantiated_node_original_property(node, "script", sorig) && !scr->inherits_script(sorig)) {
Variant dummy;
if (scr->get_property_default_value(p_property, dummy)) {
ignore_parent = true;
} }
} }
} }
if (!ignore_parent) {
//check for difference including instantiation
Variant vorig;
if (EditorPropertyRevert::get_instantiated_node_original_property(node, p_property, vorig)) {
return vorig;
}
}
} }
return has_revert; if (scr.is_valid()) {
Variant orig_value;
if (scr->get_property_default_value(p_property, orig_value)) {
return orig_value;
}
}
//report default class value instead
return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property);
}
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
Variant revert_value = EditorPropertyRevert::get_property_revert_value(p_object, p_property);
if (revert_value.get_type() == Variant::NIL) {
return false;
}
Variant current_value = p_object->get(p_property);
return EditorPropertyRevert::is_property_value_different(current_value, revert_value);
} }
void EditorProperty::update_reload_status() { void EditorProperty::update_reload_status() {
@ -761,41 +774,11 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
} }
if (revert_rect.has_point(mpos)) { if (revert_rect.has_point(mpos)) {
Variant vorig; Variant revert_value = EditorPropertyRevert::get_property_revert_value(object, property);
emit_changed(property, revert_value);
Node *node = Object::cast_to<Node>(object); update_property();
if (node && EditorPropertyRevert::may_node_be_in_instance(node) && EditorPropertyRevert::get_instantiated_node_original_property(node, property, vorig)) {
emit_changed(property, vorig.duplicate(true));
update_property();
return;
}
if (object->call("property_can_revert", property).operator bool()) {
Variant rev = object->call("property_get_revert", property);
emit_changed(property, rev);
update_property();
return;
}
if (!object->get_script().is_null()) {
Ref<Script> scr = object->get_script();
if (scr.is_valid()) {
Variant orig_value;
if (scr->get_property_default_value(property, orig_value)) {
emit_changed(property, orig_value);
update_property();
return;
}
}
}
Variant default_value = ClassDB::class_get_default_property_value(object->get_class_name(), property);
if (default_value != Variant()) {
emit_changed(property, default_value);
update_property();
return;
}
} }
if (check_rect.has_point(mpos)) { if (check_rect.has_point(mpos)) {
checked = !checked; checked = !checked;
update(); update();

View file

@ -42,6 +42,8 @@ public:
static bool may_node_be_in_instance(Node *p_node); static bool may_node_be_in_instance(Node *p_node);
static bool get_instantiated_node_original_property(Node *p_node, const StringName &p_prop, Variant &value); static bool get_instantiated_node_original_property(Node *p_node, const StringName &p_prop, Variant &value);
static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig); static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig);
static bool is_property_value_different(const Variant &p_a, const Variant &p_b);
static Variant get_property_revert_value(Object *p_object, const StringName &p_property);
static bool can_property_revert(Object *p_object, const StringName &p_property); static bool can_property_revert(Object *p_object, const StringName &p_property);
}; };