diff options
author | Franklin Sobrinho <franklin_gs@hotmail.com> | 2016-08-17 17:14:51 -0300 |
---|---|---|
committer | Franklin Sobrinho <franklin_gs@hotmail.com> | 2016-08-17 17:14:51 -0300 |
commit | debf574df35caf8e0880b65120e3c79c45e1c92a (patch) | |
tree | 10e512fc5bca08cc20ad593ef70c9c6d85fba125 /core | |
parent | 56fa741b7a729bd5a00cff17e4382af547de92ad (diff) |
Implemented UndoRedo mergeable modes
Diffstat (limited to 'core')
-rw-r--r-- | core/undo_redo.cpp | 61 | ||||
-rw-r--r-- | core/undo_redo.h | 12 |
2 files changed, 58 insertions, 15 deletions
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index d6d32ccaef..99740b365c 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -52,26 +52,46 @@ void UndoRedo::_discard_redo() { } - -void UndoRedo::create_action(const String& p_name,bool p_mergeable) { +void UndoRedo::create_action(const String& p_name,MergeMode p_mode) { if (action_level==0) { _discard_redo(); - if (p_mergeable && actions.size() && actions[actions.size()-1].name==p_name) { - //old will replace new (it's mergeable after all) - // should check references though! + // Check if the merge operation is valid + if (p_mode!=MERGE_DISABLE && actions.size() && actions[actions.size()-1].name==p_name) { + current_action=actions.size()-2; - actions[current_action+1].do_ops.clear(); - //actions[current_action+1].undo_ops.clear(); - no, this is kept - merging=true; + + if (p_mode==MERGE_ENDS) { + + // Clear all do ops from last action, and delete all object references + List<Operation>::Element *E=actions[current_action+1].do_ops.front(); + + while (E) { + + if (E->get().type==Operation::TYPE_REFERENCE) { + + Object *obj=ObjectDB::get_instance(E->get().object); + + if (obj) + memdelete(obj); + } + + E=E->next(); + actions[current_action+1].do_ops.pop_front(); + } + } + + merge_mode=p_mode; } else { + Action new_action; new_action.name=p_name; actions.push_back(new_action); - merging=false; + + merge_mode=MERGE_DISABLE; } } @@ -102,8 +122,10 @@ void UndoRedo::add_undo_method(Object *p_object,const String& p_method,VARIANT_A VARIANT_ARGPTRS ERR_FAIL_COND(action_level<=0); ERR_FAIL_COND((current_action+1)>=actions.size()); - if (merging) - return; //- no undo if merging + + // No undo if the merge mode is MERGE_ENDS + if (merge_mode==MERGE_ENDS) + return; Operation undo_op; undo_op.object=p_object->get_instance_ID(); @@ -139,6 +161,10 @@ void UndoRedo::add_undo_property(Object *p_object,const String& p_property,const ERR_FAIL_COND(action_level<=0); ERR_FAIL_COND((current_action+1)>=actions.size()); + // No undo if the merge mode is MERGE_ENDS + if (merge_mode==MERGE_ENDS) + return; + Operation undo_op; undo_op.object=p_object->get_instance_ID(); if (p_object->cast_to<Resource>()) @@ -167,6 +193,11 @@ void UndoRedo::add_undo_reference(Object *p_object) { ERR_FAIL_COND(action_level<=0); ERR_FAIL_COND((current_action+1)>=actions.size()); + + // No undo if the merge mode is MERGE_ENDS + if (merge_mode==MERGE_ENDS) + return; + Operation undo_op; undo_op.object=p_object->get_instance_ID(); if (p_object->cast_to<Resource>()) @@ -352,7 +383,7 @@ UndoRedo::UndoRedo() { action_level=0; current_action=-1; max_steps=-1; - merging=true; + merge_mode=MERGE_DISABLE; callback=NULL; callback_ud=NULL; @@ -448,7 +479,7 @@ Variant UndoRedo::_add_undo_method(const Variant** p_args, int p_argcount, Varia void UndoRedo::_bind_methods() { - ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) ); + ObjectTypeDB::bind_method(_MD("create_action","name","merge_mode"),&UndoRedo::create_action, DEFVAL(MERGE_DISABLE) ); ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action); //ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method); @@ -489,4 +520,8 @@ void UndoRedo::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_history"),&UndoRedo::clear_history); ObjectTypeDB::bind_method(_MD("get_current_action_name"),&UndoRedo::get_current_action_name); ObjectTypeDB::bind_method(_MD("get_version"),&UndoRedo::get_version); + + BIND_CONSTANT(MERGE_DISABLE); + BIND_CONSTANT(MERGE_ENDS); + BIND_CONSTANT(MERGE_ALL); } diff --git a/core/undo_redo.h b/core/undo_redo.h index 7f63ba9ed6..208eb6ed5e 100644 --- a/core/undo_redo.h +++ b/core/undo_redo.h @@ -41,6 +41,12 @@ class UndoRedo : public Object { OBJ_SAVE_TYPE( UndoRedo ); public: + enum MergeMode { + MERGE_DISABLE, + MERGE_ENDS, + MERGE_ALL + }; + typedef void (*CommitNotifyCallback)(void *p_ud,const String& p_name); Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error); Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error); @@ -76,7 +82,7 @@ private: int current_action; int action_level; int max_steps; - bool merging; + MergeMode merge_mode; uint64_t version; void _pop_history_tail(); @@ -98,7 +104,7 @@ protected: public: - void create_action(const String& p_name="",bool p_mergeable=false); + void create_action(const String& p_name="",MergeMode p_mode=MERGE_DISABLE); void add_do_method(Object *p_object,const String& p_method,VARIANT_ARG_LIST); void add_undo_method(Object *p_object,const String& p_method,VARIANT_ARG_LIST); @@ -128,4 +134,6 @@ public: ~UndoRedo(); }; +VARIANT_ENUM_CAST( UndoRedo::MergeMode ); + #endif // UNDO_REDO_H |