| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  undo_redo.cpp                                                        */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include "undo_redo.h"
 | 
					
						
							| 
									
										
										
										
											2017-01-16 08:04:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-20 11:46:44 +01:00
										 |  |  | #include "core/io/resource.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/os.h"
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | #include "core/templates/local_vector.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-01 17:59:37 +08:00
										 |  |  | void UndoRedo::Operation::delete_reference() { | 
					
						
							|  |  |  | 	if (type != Operation::TYPE_REFERENCE) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ref.is_valid()) { | 
					
						
							|  |  |  | 		ref.unref(); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		Object *obj = ObjectDB::get_instance(object); | 
					
						
							|  |  |  | 		if (obj) { | 
					
						
							|  |  |  | 			memdelete(obj); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void UndoRedo::_discard_redo() { | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (current_action == actions.size() - 1) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (int i = current_action + 1; i < actions.size(); i++) { | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 		for (Operation &E : actions.write[i].do_ops) { | 
					
						
							| 
									
										
										
										
											2022-03-01 17:59:37 +08:00
										 |  |  | 			E.delete_reference(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		//ERASE do data
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	actions.resize(current_action + 1); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | bool UndoRedo::_redo(bool p_execute) { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(action_level > 0, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((current_action + 1) >= actions.size()) { | 
					
						
							|  |  |  | 		return false; //nothing to redo
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	current_action++; | 
					
						
							|  |  |  | 	if (p_execute) { | 
					
						
							|  |  |  | 		_process_operation_list(actions.write[current_action].do_ops.front()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	version++; | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 	emit_signal(SNAME("version_changed")); | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void UndoRedo::create_action(const String &p_name, MergeMode p_mode) { | 
					
						
							| 
									
										
										
										
											2021-10-26 08:44:50 +02:00
										 |  |  | 	uint64_t ticks = OS::get_singleton()->get_ticks_msec(); | 
					
						
							| 
									
										
										
										
											2017-01-05 09:16:00 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (action_level == 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_discard_redo(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 		// Check if the merge operation is valid
 | 
					
						
							| 
									
										
										
										
											2019-02-25 14:09:33 -03:00
										 |  |  | 		if (p_mode != MERGE_DISABLE && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			current_action = actions.size() - 2; | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-25 14:09:33 -03:00
										 |  |  | 			if (p_mode == MERGE_ENDS) { | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 				// Clear all do ops from last action if they are not forced kept
 | 
					
						
							|  |  |  | 				LocalVector<List<Operation>::Element *> to_remove; | 
					
						
							|  |  |  | 				for (List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front(); E; E = E->next()) { | 
					
						
							|  |  |  | 					if (!E->get().force_keep_in_merge_ends) { | 
					
						
							|  |  |  | 						to_remove.push_back(E); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 				for (unsigned int i = 0; i < to_remove.size(); i++) { | 
					
						
							|  |  |  | 					List<Operation>::Element *E = to_remove[i]; | 
					
						
							|  |  |  | 					// Delete all object references
 | 
					
						
							| 
									
										
										
										
											2022-03-01 17:59:37 +08:00
										 |  |  | 					E->get().delete_reference(); | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 					E->erase(); | 
					
						
							| 
									
										
										
										
											2019-02-25 14:09:33 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 			actions.write[actions.size() - 1].last_tick = ticks; | 
					
						
							| 
									
										
										
										
											2019-02-25 14:09:33 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 10:45:21 +02:00
										 |  |  | 			merge_mode = p_mode; | 
					
						
							| 
									
										
										
										
											2019-03-22 22:06:01 -03:00
										 |  |  | 			merging = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			Action new_action; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			new_action.name = p_name; | 
					
						
							|  |  |  | 			new_action.last_tick = ticks; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			actions.push_back(new_action); | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 10:45:21 +02:00
										 |  |  | 			merge_mode = MERGE_DISABLE; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	action_level++; | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	force_keep_in_merge_ends = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | void UndoRedo::add_do_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Operation do_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	do_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		do_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	do_op.type = Operation::TYPE_METHOD; | 
					
						
							|  |  |  | 	do_op.name = p_method; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	for (int i = 0; i < p_argcount; i++) { | 
					
						
							|  |  |  | 		do_op.args.push_back(*p_args[i]); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].do_ops.push_back(do_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | void UndoRedo::add_undo_methodp(Object *p_object, const StringName &p_method, const Variant **p_args, int p_argcount) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// No undo if the merge mode is MERGE_ENDS
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) { | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Operation undo_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	undo_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		undo_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_op.type = Operation::TYPE_METHOD; | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_op.name = p_method; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	for (int i = 0; i < p_argcount; i++) { | 
					
						
							|  |  |  | 		undo_op.args.push_back(*p_args[i]); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].undo_ops.push_back(undo_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Operation do_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	do_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		do_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	do_op.type = Operation::TYPE_PROPERTY; | 
					
						
							|  |  |  | 	do_op.name = p_property; | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	do_op.args.push_back(p_value); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].do_ops.push_back(do_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 	// No undo if the merge mode is MERGE_ENDS
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) { | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Operation undo_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	undo_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		undo_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_op.type = Operation::TYPE_PROPERTY; | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_op.name = p_property; | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	undo_op.args.push_back(p_value); | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].undo_ops.push_back(undo_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void UndoRedo::add_do_reference(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Operation do_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	do_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		do_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	do_op.type = Operation::TYPE_REFERENCE; | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].do_ops.push_back(do_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void UndoRedo::add_undo_reference(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	ERR_FAIL_COND(p_object == nullptr); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// No undo if the merge mode is MERGE_ENDS
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	if (!force_keep_in_merge_ends && merge_mode == MERGE_ENDS) { | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Operation undo_op; | 
					
						
							| 
									
										
										
										
											2017-08-07 17:17:31 +07:00
										 |  |  | 	undo_op.object = p_object->get_instance_id(); | 
					
						
							| 
									
										
										
										
											2021-06-04 18:03:15 +02:00
										 |  |  | 	if (Object::cast_to<RefCounted>(p_object)) { | 
					
						
							|  |  |  | 		undo_op.ref = Ref<RefCounted>(Object::cast_to<RefCounted>(p_object)); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	undo_op.type = Operation::TYPE_REFERENCE; | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	undo_op.force_keep_in_merge_ends = force_keep_in_merge_ends; | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	actions.write[current_action + 1].undo_ops.push_back(undo_op); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | void UndoRedo::start_force_keep_in_merge_ends() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	force_keep_in_merge_ends = true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void UndoRedo::end_force_keep_in_merge_ends() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							|  |  |  | 	ERR_FAIL_COND((current_action + 1) >= actions.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	force_keep_in_merge_ends = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | void UndoRedo::_pop_history_tail() { | 
					
						
							|  |  |  | 	_discard_redo(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!actions.size()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 	for (Operation &E : actions.write[0].undo_ops) { | 
					
						
							| 
									
										
										
										
											2022-03-01 17:59:37 +08:00
										 |  |  | 		E.delete_reference(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-03 16:17:03 -06:00
										 |  |  | 	actions.remove_at(0); | 
					
						
							| 
									
										
										
										
											2019-02-14 10:19:03 -03:00
										 |  |  | 	if (current_action >= 0) { | 
					
						
							|  |  |  | 		current_action--; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 12:34:40 +02:00
										 |  |  | bool UndoRedo::is_committing_action() const { | 
					
						
							|  |  |  | 	return committing > 0; | 
					
						
							| 
									
										
										
										
											2019-03-03 17:53:59 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | void UndoRedo::commit_action(bool p_execute) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level <= 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	action_level--; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (action_level > 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return; //still nested
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-22 22:06:01 -03:00
										 |  |  | 	if (merging) { | 
					
						
							|  |  |  | 		version--; | 
					
						
							|  |  |  | 		merging = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-19 12:34:40 +02:00
										 |  |  | 	committing++; | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 	_redo(p_execute); // perform action
 | 
					
						
							| 
									
										
										
										
											2019-05-19 12:34:40 +02:00
										 |  |  | 	committing--; | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (callback && actions.size() > 0) { | 
					
						
							|  |  |  | 		callback(callback_ud, actions[actions.size() - 1].name); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void UndoRedo::_process_operation_list(List<Operation>::Element *E) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	for (; E; E = E->next()) { | 
					
						
							|  |  |  | 		Operation &op = E->get(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Object *obj = ObjectDB::get_instance(op.object); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (!obj) { //may have been deleted and this is fine
 | 
					
						
							| 
									
										
										
										
											2019-02-14 10:19:03 -03:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-05-11 21:36:29 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		switch (op.type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			case Operation::TYPE_METHOD: { | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 				int argc = op.args.size(); | 
					
						
							| 
									
										
										
										
											2018-09-08 03:14:13 +02:00
										 |  |  | 				Vector<const Variant *> argptrs; | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 				argptrs.resize(argc); | 
					
						
							| 
									
										
										
										
											2018-09-08 03:14:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 				for (int i = 0; i < argc; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-08 03:14:13 +02:00
										 |  |  | 					argptrs.write[i] = &op.args[i]; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 				Callable::CallError ce; | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 				obj->callp(op.name, (const Variant **)argptrs.ptr(), argc, ce); | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 				if (ce.error != Callable::CallError::CALL_OK) { | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 					ERR_PRINT("Error calling UndoRedo method operation '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, (const Variant **)argptrs.ptr(), argc, ce)); | 
					
						
							| 
									
										
										
										
											2018-09-08 03:14:13 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-05-11 21:36:29 -03:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 				Resource *res = Object::cast_to<Resource>(obj); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (res) { | 
					
						
							| 
									
										
										
										
											2015-05-11 21:36:29 -03:00
										 |  |  | 					res->set_edited(true); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-11 21:36:29 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (method_callback) { | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 					method_callback(method_callback_ud, obj, op.name, (const Variant **)argptrs.ptr(), argc); | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Operation::TYPE_PROPERTY: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				obj->set(op.name, op.args[0]); | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | #ifdef TOOLS_ENABLED
 | 
					
						
							| 
									
										
										
										
											2017-08-24 22:58:51 +02:00
										 |  |  | 				Resource *res = Object::cast_to<Resource>(obj); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				if (res) { | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | 					res->set_edited(true); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-11-02 11:31:01 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | 				if (property_callback) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					property_callback(prop_callback_ud, obj, op.name, op.args[0]); | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Operation::TYPE_REFERENCE: { | 
					
						
							|  |  |  | 				//do nothing
 | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 23:41:19 -03:00
										 |  |  | bool UndoRedo::redo() { | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 	return _redo(true); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 23:41:19 -03:00
										 |  |  | bool UndoRedo::undo() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(action_level > 0, false); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (current_action < 0) { | 
					
						
							| 
									
										
										
										
											2018-05-26 23:41:19 -03:00
										 |  |  | 		return false; //nothing to redo
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-07-25 03:11:03 +02:00
										 |  |  | 	_process_operation_list(actions.write[current_action].undo_ops.front()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	current_action--; | 
					
						
							| 
									
										
										
										
											2015-06-22 00:03:19 -03:00
										 |  |  | 	version--; | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 	emit_signal(SNAME("version_changed")); | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-26 23:41:19 -03:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | int UndoRedo::get_history_count() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(action_level > 0, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return actions.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int UndoRedo::get_current_action() { | 
					
						
							|  |  |  | 	ERR_FAIL_COND_V(action_level > 0, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return current_action; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String UndoRedo::get_action_name(int p_id) { | 
					
						
							|  |  |  | 	ERR_FAIL_INDEX_V(p_id, actions.size(), ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return actions[p_id].name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-18 18:07:38 -02:00
										 |  |  | void UndoRedo::clear_history(bool p_increase_version) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND(action_level > 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	_discard_redo(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	while (actions.size()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_pop_history_tail(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	if (p_increase_version) { | 
					
						
							| 
									
										
										
										
											2018-11-18 18:07:38 -02:00
										 |  |  | 		version++; | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 		emit_signal(SNAME("version_changed")); | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | String UndoRedo::get_current_action_name() const { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ERR_FAIL_COND_V(action_level > 0, ""); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (current_action < 0) { | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 		return ""; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	return actions[current_action].name; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 11:41:46 +08:00
										 |  |  | bool UndoRedo::has_undo() const { | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	return current_action >= 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-17 11:41:46 +08:00
										 |  |  | bool UndoRedo::has_redo() const { | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	return (current_action + 1) < actions.size(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | uint64_t UndoRedo::get_version() const { | 
					
						
							|  |  |  | 	return version; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud) { | 
					
						
							|  |  |  | 	callback = p_callback; | 
					
						
							|  |  |  | 	callback_ud = p_ud; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void UndoRedo::set_method_notify_callback(MethodNotifyCallback p_method_callback, void *p_ud) { | 
					
						
							|  |  |  | 	method_callback = p_method_callback; | 
					
						
							| 
									
										
										
										
											2022-03-09 22:20:39 +01:00
										 |  |  | 	method_callback_ud = p_ud; | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_callback, void *p_ud) { | 
					
						
							|  |  |  | 	property_callback = p_property_callback; | 
					
						
							|  |  |  | 	prop_callback_ud = p_ud; | 
					
						
							| 
									
										
										
										
											2015-08-02 12:29:37 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | UndoRedo::~UndoRedo() { | 
					
						
							|  |  |  | 	clear_history(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | void UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_argcount < 2) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 0; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_args[0]->get_type() != Variant::OBJECT) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 0; | 
					
						
							|  |  |  | 		r_error.expected = Variant::OBJECT; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 	if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 1; | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 		r_error.expected = Variant::STRING_NAME; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 	r_error.error = Callable::CallError::CALL_OK; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Object *object = *p_args[0]; | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 	StringName method = *p_args[1]; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	add_do_methodp(object, method, p_args + 2, p_argcount - 2); | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | void UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_argcount < 2) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 0; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (p_args[0]->get_type() != Variant::OBJECT) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 0; | 
					
						
							|  |  |  | 		r_error.expected = Variant::OBJECT; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 	if (p_args[1]->get_type() != Variant::STRING_NAME && p_args[1]->get_type() != Variant::STRING) { | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 		r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.argument = 1; | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 		r_error.expected = Variant::STRING_NAME; | 
					
						
							| 
									
										
										
										
											2022-02-22 12:15:43 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-19 16:27:19 -03:00
										 |  |  | 	r_error.error = Callable::CallError::CALL_OK; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Object *object = *p_args[0]; | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 	StringName method = *p_args[1]; | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-09 14:58:40 +01:00
										 |  |  | 	add_undo_methodp(object, method, p_args + 2, p_argcount - 2); | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void UndoRedo::_bind_methods() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE)); | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("commit_action", "execute"), &UndoRedo::commit_action, DEFVAL(true)); | 
					
						
							| 
									
										
										
										
											2020-04-08 18:36:08 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		MethodInfo mi; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mi.name = "add_do_method"; | 
					
						
							|  |  |  | 		mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object")); | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 		mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-02 16:31:43 +08:00
										 |  |  | 		ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_do_method", &UndoRedo::_add_do_method, mi, varray(), false); | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		MethodInfo mi; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		mi.name = "add_undo_method"; | 
					
						
							|  |  |  | 		mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object")); | 
					
						
							| 
									
										
										
										
											2020-02-20 18:58:05 -03:00
										 |  |  | 		mi.arguments.push_back(PropertyInfo(Variant::STRING_NAME, "method")); | 
					
						
							| 
									
										
										
										
											2016-09-07 19:39:02 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-02 16:31:43 +08:00
										 |  |  | 		ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "add_undo_method", &UndoRedo::_add_undo_method, mi, varray(), false); | 
					
						
							| 
									
										
										
										
											2015-06-21 21:55:47 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-09 13:19:41 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_do_property", "object", "property", "value"), &UndoRedo::add_do_property); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_undo_property", "object", "property", "value"), &UndoRedo::add_undo_property); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("add_do_reference", "object"), &UndoRedo::add_do_reference); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("add_undo_reference", "object"), &UndoRedo::add_undo_reference); | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 14:03:05 +02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("start_force_keep_in_merge_ends"), &UndoRedo::start_force_keep_in_merge_ends); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("end_force_keep_in_merge_ends"), &UndoRedo::end_force_keep_in_merge_ends); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_history_count"), &UndoRedo::get_history_count); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("get_current_action"), &UndoRedo::get_current_action); | 
					
						
							| 
									
										
										
										
											2021-02-19 13:35:31 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_action_name", "id"), &UndoRedo::get_action_name); | 
					
						
							| 
									
										
										
										
											2018-11-18 18:07:38 -02:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("clear_history", "increase_version"), &UndoRedo::clear_history, DEFVAL(true)); | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_current_action_name"), &UndoRedo::get_current_action_name); | 
					
						
							| 
									
										
										
										
											2021-01-12 12:48:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("has_undo"), &UndoRedo::has_undo); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("has_redo"), &UndoRedo::has_redo); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("get_version"), &UndoRedo::get_version); | 
					
						
							| 
									
										
										
										
											2017-09-13 11:37:01 +08:00
										 |  |  | 	ClassDB::bind_method(D_METHOD("redo"), &UndoRedo::redo); | 
					
						
							|  |  |  | 	ClassDB::bind_method(D_METHOD("undo"), &UndoRedo::undo); | 
					
						
							| 
									
										
										
										
											2016-08-17 17:14:51 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-14 00:52:51 +01:00
										 |  |  | 	ADD_SIGNAL(MethodInfo("version_changed")); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-20 17:45:01 +02:00
										 |  |  | 	BIND_ENUM_CONSTANT(MERGE_DISABLE); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(MERGE_ENDS); | 
					
						
							|  |  |  | 	BIND_ENUM_CONSTANT(MERGE_ALL); | 
					
						
							| 
									
										
										
										
											2015-06-22 23:44:13 -03:00
										 |  |  | } |