Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rationalize property reversion #46270

Merged
merged 1 commit into from
Jul 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 55 additions & 72 deletions editor/editor_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian

if (ss.is_valid()) {
found_state = true;
break;
}
if (node == edited_scene) {
//just in case
Expand All @@ -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) {
float a = p_current;
float b = p_orig;
return is_property_value_different(p_current, 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
bool EditorPropertyRevert::is_property_value_different(const Variant &p_a, const Variant &p_b) {
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
return !Math::is_equal_approx((float)p_a, (float)p_b);
} else {
return p_a != p_b;
}

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 has_revert = false;
Variant EditorPropertyRevert::get_property_revert_value(Object *p_object, const StringName &p_property) {
// 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
// can do that if so desired)
if (p_object->has_method("property_can_revert") && p_object->call("property_can_revert", p_property)) {
return p_object->call("property_get_revert", p_property);
}

Ref<Script> scr = p_object->get_script();
Node *node = Object::cast_to<Node>(p_object);

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;
//if this node is an instance or inherits, but it has a script attached which is unrelated
//to the one set for the parent and also has a default value for the property, consider that
//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;
}
}
}
} else {
//check for difference against default class value instead
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;

if (!ignore_parent) {
//check for difference including instantiation
Variant vorig;
if (EditorPropertyRevert::get_instantiated_node_original_property(node, p_property, vorig)) {
return vorig;
}
}
}

// 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
// can do that if so desired)
if (p_object->has_method("property_can_revert")) {
has_revert = p_object->call("property_can_revert", p_property).operator bool();
} else {
if (!has_revert && !p_object->get_script().is_null()) {
Ref<Script> scr = p_object->get_script();
if (scr.is_valid()) {
Variant orig_value;
if (scr->get_property_default_value(p_property, orig_value)) {
if (orig_value != p_object->get(p_property)) {
has_revert = true;
}
}
}
if (scr.is_valid()) {
Variant orig_value;
if (scr->get_property_default_value(p_property, orig_value)) {
return orig_value;
}
}

return has_revert;
//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() {
Expand Down Expand Up @@ -761,41 +774,11 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
}

if (revert_rect.has_point(mpos)) {
Variant vorig;

Node *node = Object::cast_to<Node>(object);
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;
}
Variant revert_value = EditorPropertyRevert::get_property_revert_value(object, property);
emit_changed(property, revert_value);
update_property();
}

if (check_rect.has_point(mpos)) {
checked = !checked;
update();
Expand Down
2 changes: 2 additions & 0 deletions editor/editor_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class EditorPropertyRevert {
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 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);
};
Expand Down