diff options
Diffstat (limited to 'core/object/undo_redo.cpp')
-rw-r--r-- | core/object/undo_redo.cpp | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index f04961c760..a8f2ac5bfe 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -71,9 +71,7 @@ bool UndoRedo::_redo(bool p_execute) { } current_action++; - if (p_execute) { - _process_operation_list(actions.write[current_action].do_ops.front()); - } + _process_operation_list(actions.write[current_action].do_ops.front(), p_execute); version++; emit_signal(SNAME("version_changed")); @@ -136,17 +134,22 @@ void UndoRedo::add_do_method(const Callable &p_callable) { ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); - Object *object = p_callable.get_object(); - ERR_FAIL_NULL(object); + ObjectID object_id = p_callable.get_object_id(); + Object *object = ObjectDB::get_instance(object_id); + ERR_FAIL_COND(object_id.is_valid() && object == nullptr); Operation do_op; do_op.callable = p_callable; - do_op.object = p_callable.get_object_id(); + do_op.object = object_id; if (Object::cast_to<RefCounted>(object)) { do_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(object)); } do_op.type = Operation::TYPE_METHOD; do_op.name = p_callable.get_method(); + if (do_op.name == StringName()) { + // There's no `get_method()` for custom callables, so use `operator String()` instead. + do_op.name = static_cast<String>(p_callable); + } actions.write[current_action + 1].do_ops.push_back(do_op); } @@ -161,24 +164,29 @@ void UndoRedo::add_undo_method(const Callable &p_callable) { return; } - Object *object = p_callable.get_object(); - ERR_FAIL_NULL(object); + ObjectID object_id = p_callable.get_object_id(); + Object *object = ObjectDB::get_instance(object_id); + ERR_FAIL_COND(object_id.is_valid() && object == nullptr); Operation undo_op; undo_op.callable = p_callable; - undo_op.object = p_callable.get_object_id(); + undo_op.object = object_id; if (Object::cast_to<RefCounted>(object)) { undo_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(object)); } undo_op.type = Operation::TYPE_METHOD; undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; undo_op.name = p_callable.get_method(); + if (undo_op.name == StringName()) { + // There's no `get_method()` for custom callables, so use `operator String()` instead. + undo_op.name = static_cast<String>(p_callable); + } actions.write[current_action + 1].undo_ops.push_back(undo_op); } void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) { - ERR_FAIL_COND(p_object == nullptr); + ERR_FAIL_NULL(p_object); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); Operation do_op; @@ -194,7 +202,7 @@ void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, c } void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) { - ERR_FAIL_COND(p_object == nullptr); + ERR_FAIL_NULL(p_object); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); @@ -217,7 +225,7 @@ void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, } void UndoRedo::add_do_reference(Object *p_object) { - ERR_FAIL_COND(p_object == nullptr); + ERR_FAIL_NULL(p_object); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); Operation do_op; @@ -231,7 +239,7 @@ void UndoRedo::add_do_reference(Object *p_object) { } void UndoRedo::add_undo_reference(Object *p_object) { - ERR_FAIL_COND(p_object == nullptr); + ERR_FAIL_NULL(p_object); ERR_FAIL_COND(action_level <= 0); ERR_FAIL_COND((current_action + 1) >= actions.size()); @@ -311,7 +319,7 @@ void UndoRedo::commit_action(bool p_execute) { } } -void UndoRedo::_process_operation_list(List<Operation>::Element *E) { +void UndoRedo::_process_operation_list(List<Operation>::Element *E, bool p_execute) { const int PREALLOCATE_ARGS_COUNT = 16; LocalVector<const Variant *> args; @@ -327,18 +335,20 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) { switch (op.type) { case Operation::TYPE_METHOD: { - Callable::CallError ce; - Variant ret; - op.callable.callp(nullptr, 0, ret, ce); - if (ce.error != Callable::CallError::CALL_OK) { - ERR_PRINT("Error calling UndoRedo method operation '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, nullptr, 0, ce)); - } + if (p_execute) { + Callable::CallError ce; + Variant ret; + op.callable.callp(nullptr, 0, ret, ce); + if (ce.error != Callable::CallError::CALL_OK) { + ERR_PRINT("Error calling UndoRedo method operation '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, nullptr, 0, ce)); + } #ifdef TOOLS_ENABLED - Resource *res = Object::cast_to<Resource>(obj); - if (res) { - res->set_edited(true); - } + Resource *res = Object::cast_to<Resource>(obj); + if (res) { + res->set_edited(true); + } #endif + } if (method_callback) { Vector<Variant> binds; @@ -363,13 +373,16 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) { } } break; case Operation::TYPE_PROPERTY: { - obj->set(op.name, op.value); + if (p_execute) { + obj->set(op.name, op.value); #ifdef TOOLS_ENABLED - Resource *res = Object::cast_to<Resource>(obj); - if (res) { - res->set_edited(true); - } + Resource *res = Object::cast_to<Resource>(obj); + if (res) { + res->set_edited(true); + } #endif + } + if (property_callback) { property_callback(prop_callback_ud, obj, op.name, op.value); } @@ -390,7 +403,7 @@ bool UndoRedo::undo() { if (current_action < 0) { return false; //nothing to redo } - _process_operation_list(actions.write[current_action].undo_ops.front()); + _process_operation_list(actions.write[current_action].undo_ops.front(), true); current_action--; version--; emit_signal(SNAME("version_changed")); |