write shit

This commit is contained in:
2021-05-21 22:37:25 +08:00
parent 2adefe86f4
commit 4aacc76a49
9 changed files with 320 additions and 131 deletions

View File

@ -17,29 +17,32 @@ namespace BallanceTASEditor.Core {
fs.Close();
fs.Dispose();
mPointer = mMem.First;
mPointerIndex = 0;
}
public string mFilename { get; private set; }
public long mFrameCount { get { return mMem.Count; } }
LinkedList<FrameData> mMem;
LinkedListNode<FrameData> mPointer;
long mPointerIndex;
public void Shift(long shiftNum) {
if (mPointer == null) return;
if (shiftNum == 0) return;
var absNum = Math.Abs(shiftNum);
if (shiftNum > 0) {
for(long num = 0; num < absNum && mPointer.Next != null; num++) {
mPointer = mPointer.Next;
}
} else {
for (long num = 0; num < absNum && mPointer.Previous != null; num++) {
mPointer = mPointer.Previous;
}
}
public bool IsEmpty() {
return (mPointer == null);
}
public void Get(List<FrameDataDisplay> container, long startIndex, int count) {
public long GetPointerIndex() {
if (mPointer == null) throw new Exception("Data is not ready");
return mPointerIndex;
}
public void Shift(long absoluteIndex) {
if (mPointer == null) return;
mPointer = mMem.FastGetNode(mPointer, mPointerIndex, absoluteIndex);
mPointerIndex = absoluteIndex;
}
public void Get(List<FrameDataDisplay> container, int count) {
// no item. clean container
if (mPointer == null) {
for(int j = 0; j < count; j++) {
@ -50,6 +53,7 @@ namespace BallanceTASEditor.Core {
// fill container
var cachePointer = mPointer;
var startIndex = mPointerIndex;
int i;
for(i = 0; i < count && cachePointer != null; i++, startIndex++) {
container[i].Reload(startIndex, cachePointer.Value);
@ -62,41 +66,102 @@ namespace BallanceTASEditor.Core {
}
// if isSet is null, mean flip state
public void Set(SelectionRange field, SelectionRange relativeRange, bool? isSet) {
public void Set(SelectionRange field, SelectionRange absoluteRange, bool? isSet) {
if (mPointer == null) return;
var cachePointer = mPointer;
uint offset = 0;
for(int i = (int)field.start; i <= (int)field.end; i++) {
offset |= ConstValue.Mapping[(FrameDataField)i];
}
foreach(var item in mMem.IterateWithSelectionRange(relativeRange, mPointer)) {
foreach(var item in mMem.IterateWithSelectionRange(absoluteRange, mPointer, mPointerIndex)) {
if (isSet == null) item.Value.ReverseKeyStates(offset);
else if (isSet == true) item.Value.SetKeyStates(offset);
else if (isSet == false) item.Value.UnsetKeyStates(offset);
}
}
public void Remove(SelectionRange relativeRange) {
public void Remove(SelectionRange absoluteRange) {
if (mPointer == null) return;
mMem.RemoveWithSelectionRange(relativeRange, mPointer);
// todo: fix pointer point to invalid item
// remove
foreach(var item in mMem.IterateWithSelectionRange(absoluteRange, mPointer, mPointerIndex)) {
mMem.Remove(item);
}
// correct index data
// if state is true, it mean the deleted content is placed before pointer previously.
// so we need shift the pointer to the head of selection range.
// and we should consider 2 situations, the full delete of LinkedList and delete from head
if (mPointerIndex <= absoluteRange.end) {
var newIndex = absoluteRange.start - 1;
if (newIndex < 0) {
// this contains 2 situation
// if full delete, mPointer is null and mPointerIndex is invalid(with wrong data: 0)
// if delete from head, mPointer and mPointerIndex all are valid.
mPointer = mMem.First;
mPointerIndex = 0;
} else {
mPointer = mMem.FastGetNode(mPointer, mPointerIndex, newIndex);
mPointerIndex = newIndex;
}
}
}
public void Add(long relativePos, bool isAddBefore) {
public void Add(long absolutePos, long count, float deltaTime, bool isAddBefore) {
if (count <= 0) return;
if (mPointer == null) {
// add into blank list, absolutePos and isAddBefore parameters are invalid
// specially process
for(long i = 0; i < count; i++) {
mMem.AddFirst(new FrameData(deltaTime, 0));
}
mPointer = mMem.First;
mPointerIndex = 0;
} else {
// normal add
// normal add doesn't affect pointer
LinkedListNode<FrameData> node = mMem.FastGetNode(mPointer, mPointerIndex, absolutePos);
if (isAddBefore) {
for (long i = 0; i < count; i++) {
mMem.AddBefore(node, new FrameData(deltaTime, 0));
}
} else {
for (long i = 0; i < count; i++) {
mMem.AddAfter(node, new FrameData(deltaTime, 0));
}
}
}
}
public void Insert(long relativePos, LinkedList<FrameData> data, bool isInsertBefore) {
public void Insert(long absolutePos, LinkedList<FrameData> data, bool isInsertBefore) {
if (data.Count == 0) return;
// the same process route with add function
if (mPointer == null) {
foreach (var item in data.IterateFull()) {
mMem.AddFirst(item.Value);
}
mPointer = mMem.First;
mPointerIndex = 0;
} else {
LinkedListNode<FrameData> node = mMem.FastGetNode(mPointer, mPointerIndex, absolutePos);
if (isInsertBefore) {
foreach (var item in data.IterateFull()) {
mMem.AddBefore(node, item.Value);
}
} else {
foreach (var item in data.IterateFull()) {
mMem.AddAfter(node, item.Value);
}
}
}
}
public void Copy(SelectionRange absoluteRange, LinkedList<FrameData> data) {
if (mPointer == null) return;
}
public void Copy(SelectionRange relativeRange, LinkedList<FrameData> data) {
if (mPointer == null) return;
foreach (var item in mMem.IterateWithSelectionRange(relativeRange, mPointer)) {
foreach (var item in mMem.IterateWithSelectionRange(absoluteRange, mPointer, mPointerIndex)) {
data.AddLast(item.Value);
}
}

View File

@ -28,52 +28,66 @@ namespace BallanceTASEditor.Core {
}
}
public static LinkedListNode<FrameData> FastGetNode(this LinkedList<FrameData> ls, LinkedListNode<FrameData> refNode, long refIndex, long targetIndex) {
long count = ls.Count;
if (targetIndex >= count || refIndex >= count) throw new Exception("Index is invalid!");
var span = new StupidSortStruct[3] {
new StupidSortStruct() { type = 1, data = targetIndex },
new StupidSortStruct() { type = 2, data = count - targetIndex },
new StupidSortStruct() { type = 3, data = targetIndex - refIndex }
};
public static IEnumerable<LinkedListNode<FrameData>> IterateWithSelectionRange(this LinkedList<FrameData> ls, SelectionRange relativeRange, LinkedListNode<FrameData> current) {
if (current == null) goto end;
// goto header first
long counter;
var cache = current.TryShiftTo(relativeRange.start, out counter);
while (counter <= relativeRange.end && cache != null) {
yield return cache;
cache = cache.Next;
counter++;
// sort to get the min value
StupidSortStruct tmp;
if (Math.Abs(span[0].data) < Math.Abs(span[1].data)) {
tmp = span[0];
span[0] = span[1];
span[1] = tmp;
}
end:;
if (Math.Abs(span[1].data) < Math.Abs(span[2].data)) {
tmp = span[1];
span[2] = span[1];
span[2] = tmp;
}
LinkedListNode<FrameData> iterateNode;
if (span[2].type == 1) iterateNode = ls.First;
else if (span[2].type == 2) iterateNode = ls.Last;
else if (span[2].type == 3) iterateNode = refNode;
else throw new Exception("Unknow node type");
return iterateNode.ShiftTo(span[2].data);
}
public static void RemoveWithSelectionRange(this LinkedList<FrameData> ls, SelectionRange relativeRange, LinkedListNode<FrameData> current) {
if (current == null) goto end;
// remove safety. because it store the next node.
public static IEnumerable<LinkedListNode<FrameData>> IterateWithSelectionRange(this LinkedList<FrameData> ls, SelectionRange absoluteRange, LinkedListNode<FrameData> refNode, long refIndex) {
// goto header first
long counter;
var cache = current.TryShiftTo(relativeRange.start, out counter);
var cache = ls.FastGetNode(refNode, refIndex, absoluteRange.start);
var counter = absoluteRange.start;
LinkedListNode<FrameData> cacheNextNode;
while (counter <= relativeRange.end && cache != null) {
while (counter <= absoluteRange.end) {
if (cache == null) throw new Exception("Unexpected head or tail of linked list!");
cacheNextNode = cache.Next;
ls.Remove(cache);
yield return cache;
cache = cacheNextNode;
counter++;
}
end:;
}
public static LinkedListNode<FrameData> TryShiftTo(this LinkedListNode<FrameData> node, long offset, out long realShifted) {
public static LinkedListNode<FrameData> ShiftTo(this LinkedListNode<FrameData> node, long offset) {
var cache = node;
realShifted = 0;
long realShifted = 0;
if (offset < 0) {
while (realShifted != offset && cache.Previous != null) {
while (realShifted != offset) {
if (cache.Previous == null) throw new Exception("Unexpected head or tail of linked list!");
cache = cache.Previous;
realShifted--;
}
} else if (offset > 0) {
while (realShifted != offset && cache.Next != null) {
while (realShifted != offset) {
if (cache.Next == null) throw new Exception("Unexpected head or tail of linked list!");
cache = cache.Next;
realShifted++;
}
@ -82,4 +96,37 @@ namespace BallanceTASEditor.Core {
return cache;
}
}
public struct SelectionRange {
public SelectionRange(long value1, long value2) {
if (value1 > value2) {
start = value2;
end = value1;
} else {
start = value1;
end = value2;
}
}
public long start;
public long end;
public SelectionRange GetRelative(long refer) {
var res = new SelectionRange();
res.start = start - refer;
res.end = end - refer;
return res;
}
public bool Within(long num) {
return (num >= start && num <= end);
}
public long GetCount() {
return end - start;
}
}
public struct StupidSortStruct {
public int type;
public long data;
}
}