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) {