diff --git a/BallanceTASEditor.csproj b/BallanceTASEditor.csproj index 1e57390..0c888ac 100644 --- a/BallanceTASEditor.csproj +++ b/BallanceTASEditor.csproj @@ -60,6 +60,7 @@ + AddItem.xaml diff --git a/Core/FileOperation.cs b/Core/FileOperation.cs index eda25f8..861ca6a 100644 --- a/Core/FileOperation.cs +++ b/Core/FileOperation.cs @@ -325,14 +325,26 @@ namespace BallanceTASEditor.Core.FileOperation { long counter = 0; if (isInsertBefore) { foreach (var item in data.IterateFull()) { - mMem.AddBefore(node, item.Value); + if (node == null) { + // insert from tail instead + mMem.AddLast(item.Value); + } else { + mMem.AddBefore(node, item.Value); + } + if (counter == gottenPointerPos) mPointer = node.Previous; counter++; } } else { foreach (var item in data.IterateFullReversed()) { - mMem.AddAfter(node, item.Value); + if (node == null) { + // insert from head instead + mMem.AddFirst(item.Value); + } else { + mMem.AddAfter(node, item.Value); + } + if (counter == gottenPointerPos) mPointer = node.Next; counter++; diff --git a/Core/LimitedStack.cs b/Core/LimitedStack.cs new file mode 100644 index 0000000..c894329 --- /dev/null +++ b/Core/LimitedStack.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BallanceTASEditor.Core { + public class LimitedStack { + private static readonly int STACK_LENGTH = 20; + + public LimitedStack() { + _stack = new LinkedList(); + } + + private LinkedList _stack; + + public void Push(T data) { + _stack.AddLast(data); + if (_stack.Count > STACK_LENGTH) { + _stack.RemoveFirst(); + } + } + + public T Pop() { + if (_stack.Last == null) return default(T); + var data = _stack.Last.Value; + _stack.RemoveLast(); + return data; + } + + public void Clear() { + _stack.Clear(); + } + + public bool IsEmpty() { + return _stack.Count == 0; + } + + } +} diff --git a/Core/TASFile.cs b/Core/TASFile.cs index 5d11fcc..021e8e8 100644 --- a/Core/TASFile.cs +++ b/Core/TASFile.cs @@ -1,4 +1,5 @@ -using BallanceTASEditor.Core.TASStruct; +using BallanceTASEditor.Core.FileOperation; +using BallanceTASEditor.Core.TASStruct; using BallanceTASEditor.UI; using System; using System.Collections.Generic; @@ -18,6 +19,9 @@ namespace BallanceTASEditor.Core { fs.Dispose(); mPointer = mMem.First; mPointerIndex = 0; + + mRedoStack = new LimitedStack(); + mUndoStack = new LimitedStack(); } public string mFilename { get; private set; } @@ -26,6 +30,9 @@ namespace BallanceTASEditor.Core { LinkedListNode mPointer; long mPointerIndex; + LimitedStack mRedoStack; + LimitedStack mUndoStack; + public bool IsEmpty() { return (mPointer == null); } @@ -67,6 +74,11 @@ namespace BallanceTASEditor.Core { // if isSet is null, mean flip state public void Set(SelectionRange field, SelectionRange absoluteRange, bool? isSet) { + var oper = new SetOperation(field, absoluteRange, isSet); + oper.Do(ref mMem, ref mPointer, ref mPointerIndex); + mUndoStack.Push(oper); + mRedoStack.Clear(); + /* if (mPointer == null) return; uint offset = 0; @@ -78,9 +90,15 @@ namespace BallanceTASEditor.Core { else if (isSet == true) item.Value.SetKeyStates(offset); else if (isSet == false) item.Value.UnsetKeyStates(offset); } + */ } public void Remove(SelectionRange absoluteRange) { + var oper = new RemoveOperation(absoluteRange); + oper.Do(ref mMem, ref mPointer, ref mPointerIndex); + mUndoStack.Push(oper); + mRedoStack.Clear(); + /* if (mPointer == null) return; // remove @@ -105,9 +123,15 @@ namespace BallanceTASEditor.Core { mPointerIndex = newIndex; } } + */ } public void Add(long absolutePos, long count, float deltaTime, bool isAddBefore) { + var oper = new AddOperation(absolutePos, count, deltaTime, isAddBefore); + oper.Do(ref mMem, ref mPointer, ref mPointerIndex); + mUndoStack.Push(oper); + mRedoStack.Clear(); + /* if (count <= 0) return; if (mPointer == null) { @@ -132,9 +156,15 @@ namespace BallanceTASEditor.Core { } } } + */ } - public void Insert(long absolutePos, LinkedList data, bool isInsertBefore) { + public void Insert(long absolutePos, LinkedList data, bool isInsertBefore, bool isOverwritten) { + var oper = new InsertOperation(absolutePos, data, isInsertBefore, isOverwritten); + oper.Do(ref mMem, ref mPointer, ref mPointerIndex); + mUndoStack.Push(oper); + mRedoStack.Clear(); + /* if (data.Count == 0) return; // the same process route with add function @@ -156,6 +186,21 @@ namespace BallanceTASEditor.Core { } } } + */ + } + + public void Redo() { + if (mRedoStack.IsEmpty()) return; + var oper = mRedoStack.Pop(); + oper.Do(ref mMem, ref mPointer, ref mPointerIndex); + mUndoStack.Push(oper); + } + + public void Undo() { + if (mUndoStack.IsEmpty()) return; + var oper = mUndoStack.Pop(); + oper.Undo(ref mMem, ref mPointer, ref mPointerIndex); + mRedoStack.Push(oper); } public void Copy(SelectionRange absoluteRange, LinkedList data) {