372 lines
6.6 KiB
C#
372 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace CPF.ReoGrid.Data
|
|
{
|
|
[Serializable]
|
|
public sealed class RegularTreeArray<T>
|
|
{
|
|
public RegularTreeArray()
|
|
{
|
|
this.root.nodes = new RegularTreeArray<T>.Node[1024, 32];
|
|
}
|
|
|
|
public int MaxRow
|
|
{
|
|
get
|
|
{
|
|
return this.maxRow;
|
|
}
|
|
set
|
|
{
|
|
this.maxRow = value;
|
|
}
|
|
}
|
|
|
|
public int MaxCol
|
|
{
|
|
get
|
|
{
|
|
return this.maxCol;
|
|
}
|
|
set
|
|
{
|
|
this.maxCol = value;
|
|
}
|
|
}
|
|
|
|
public T this[int row, int col]
|
|
{
|
|
get
|
|
{
|
|
RegularTreeArray<T>.Node node = this.root;
|
|
for (int i = 1; i > 0; i--)
|
|
{
|
|
int num = (row >> 10 * i) % 1024;
|
|
int num2 = (col >> 5 * i) % 32;
|
|
node = node.nodes[num, num2];
|
|
bool flag = node == null;
|
|
if (flag)
|
|
{
|
|
return default(T);
|
|
}
|
|
}
|
|
return node.data[row % 1024, col % 32];
|
|
}
|
|
set
|
|
{
|
|
RegularTreeArray<T>.Node node = this.root;
|
|
for (int i = 1; i > 0; i--)
|
|
{
|
|
int num = (row >> 10 * i) % 1024;
|
|
int num2 = (col >> 5 * i) % 32;
|
|
RegularTreeArray<T>.Node node2 = node.nodes[num, num2];
|
|
bool flag = node2 == null;
|
|
if (flag)
|
|
{
|
|
bool flag2 = value == null;
|
|
if (flag2)
|
|
{
|
|
return;
|
|
}
|
|
node2 = (node.nodes[num, num2] = new RegularTreeArray<T>.Node());
|
|
bool flag3 = i > 1;
|
|
if (flag3)
|
|
{
|
|
node2.nodes = new RegularTreeArray<T>.Node[1024, 32];
|
|
}
|
|
}
|
|
node = node2;
|
|
}
|
|
bool flag4 = node.data == null;
|
|
if (flag4)
|
|
{
|
|
bool flag5 = value == null;
|
|
if (flag5)
|
|
{
|
|
return;
|
|
}
|
|
node.data = new T[1024, 32];
|
|
}
|
|
node.data[row % 1024, col % 32] = value;
|
|
bool flag6 = value != null;
|
|
if (flag6)
|
|
{
|
|
bool flag7 = row > this.maxRow;
|
|
if (flag7)
|
|
{
|
|
this.maxRow = row;
|
|
}
|
|
bool flag8 = col > this.maxCol;
|
|
if (flag8)
|
|
{
|
|
this.maxCol = col;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public long RowCapacity
|
|
{
|
|
get
|
|
{
|
|
return (long)Math.Pow(1024.0, 2.0);
|
|
}
|
|
}
|
|
|
|
public long ColCapacity
|
|
{
|
|
get
|
|
{
|
|
return (long)Math.Pow(32.0, 2.0);
|
|
}
|
|
}
|
|
|
|
public bool TryGet(int row, int col, out T value)
|
|
{
|
|
RegularTreeArray<T>.Node node = this.root;
|
|
for (int i = 1; i > 0; i--)
|
|
{
|
|
int num = (row >> 10 * i) % 1024;
|
|
int num2 = (col >> 5 * i) % 32;
|
|
node = node.nodes[num, num2];
|
|
bool flag = node == null;
|
|
if (flag)
|
|
{
|
|
value = default(T);
|
|
return false;
|
|
}
|
|
}
|
|
T t = node.data[row % 1024, col % 32];
|
|
bool flag2 = t == null;
|
|
if (flag2)
|
|
{
|
|
value = default(T);
|
|
return false;
|
|
}
|
|
value = t;
|
|
return true;
|
|
}
|
|
|
|
public bool IsPageNull(int row, int col)
|
|
{
|
|
RegularTreeArray<T>.Node node = this.root;
|
|
for (int i = 1; i > 0; i--)
|
|
{
|
|
int num = (row >> 10 * i) % 1024;
|
|
int num2 = (col >> 5 * i) % 32;
|
|
node = node.nodes[num, num2];
|
|
bool flag = node == null;
|
|
if (flag)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return node.data == null;
|
|
}
|
|
|
|
public void IterateContent(Func<int, int, T, int> iterator)
|
|
{
|
|
this.Iterate(0, 0, this.maxRow + 1, this.maxCol + 1, true, iterator);
|
|
}
|
|
|
|
public void Iterate(int startRow, int startCol, int rows, int cols, bool ignoreNull, Func<int, int, T, int> iterator)
|
|
{
|
|
int num = startRow + rows;
|
|
int num2 = startCol + cols;
|
|
for (int i = startRow; i < num; i++)
|
|
{
|
|
int j = startCol;
|
|
while (j < num2)
|
|
{
|
|
bool flag = this.IsPageNull(i, j);
|
|
if (flag)
|
|
{
|
|
j += 32 - j % 32;
|
|
}
|
|
else
|
|
{
|
|
T t = this[i, j];
|
|
int num3 = 1;
|
|
bool flag2 = !ignoreNull || t != null;
|
|
if (flag2)
|
|
{
|
|
num3 = iterator(i, j, t);
|
|
bool flag3 = num3 <= 0;
|
|
if (flag3)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
j += num3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void IterateEx(int startRow, int startCol, int endRow, int endCol, Func<int, int, bool> isTarget, Func<int, int, T, int> iterator)
|
|
{
|
|
for (int i = startRow; i < endRow; i++)
|
|
{
|
|
int j = startCol;
|
|
while (j < endCol)
|
|
{
|
|
bool flag = this.IsPageNull(i, j);
|
|
if (flag)
|
|
{
|
|
j += 32 - j % 32;
|
|
}
|
|
else
|
|
{
|
|
bool flag2 = !isTarget(i, j);
|
|
if (flag2)
|
|
{
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
T t = this[i, j];
|
|
int num = 1;
|
|
bool flag3 = t != null;
|
|
if (flag3)
|
|
{
|
|
num = iterator(i, j, t);
|
|
bool flag4 = num <= 0;
|
|
if (flag4)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
j += num;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public IEnumerable<T> GetEnumerator(int startRow, int startCol, int rows, int cols)
|
|
{
|
|
int r2 = startRow + rows;
|
|
int c2 = startCol + cols;
|
|
int num;
|
|
for (int r3 = startRow; r3 < r2; r3 = num + 1)
|
|
{
|
|
int c3 = startCol;
|
|
while (c3 < c2)
|
|
{
|
|
bool flag = this.IsPageNull(r3, c3);
|
|
if (flag)
|
|
{
|
|
c3 += 32 - c3 % 32;
|
|
}
|
|
else
|
|
{
|
|
T obj = this[r3, c3];
|
|
bool flag2 = obj != null;
|
|
if (flag2)
|
|
{
|
|
yield return obj;
|
|
}
|
|
c3++;
|
|
obj = default(T);
|
|
}
|
|
}
|
|
num = r3;
|
|
}
|
|
yield break;
|
|
}
|
|
|
|
private bool IterateTree(RegularTreeArray<T>.Node node, int offrow, int offcol, Func<int, int, T, bool> handler)
|
|
{
|
|
bool flag = node.nodes != null;
|
|
if (flag)
|
|
{
|
|
for (int i = 1024; i >= 0; i--)
|
|
{
|
|
for (int j = 32; j >= 0; j--)
|
|
{
|
|
bool flag2 = this.IterateTree(node.nodes[i, j], offrow + i, offcol + j, handler);
|
|
bool flag3 = !flag2;
|
|
if (flag3)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
bool flag4 = node.data != null;
|
|
if (flag4)
|
|
{
|
|
for (int k = 1024; k >= 0; k--)
|
|
{
|
|
for (int l = 32; l >= 0; l--)
|
|
{
|
|
bool flag5 = handler(offrow + k, offcol + l, node.data[k, l]);
|
|
bool flag6 = !flag5;
|
|
if (flag6)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public void FindContentBounds(out int row, out int col)
|
|
{
|
|
int num = this.maxRow;
|
|
int num2 = this.maxCol;
|
|
for (int i = num; i >= 0; i--)
|
|
{
|
|
for (int j = num2; j >= 0; j--)
|
|
{
|
|
bool flag = this.IsPageNull(i, j);
|
|
if (flag)
|
|
{
|
|
j -= j % 32;
|
|
}
|
|
else
|
|
{
|
|
T t = this[i, j];
|
|
bool flag2 = t != null;
|
|
if (flag2)
|
|
{
|
|
row = i;
|
|
col = j;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
row = 0;
|
|
col = 0;
|
|
}
|
|
|
|
public const int RowSize = 1024;
|
|
|
|
public const int RowBitLen = 10;
|
|
|
|
public const int ColSize = 32;
|
|
|
|
public const int ColBitLen = 5;
|
|
|
|
public const int MaxDepth = 2;
|
|
|
|
private RegularTreeArray<T>.Node root = new RegularTreeArray<T>.Node();
|
|
|
|
private int maxRow;
|
|
|
|
private int maxCol;
|
|
|
|
[Serializable]
|
|
public sealed class Node
|
|
{
|
|
internal RegularTreeArray<T>.Node[,] nodes;
|
|
|
|
internal T[,] data;
|
|
}
|
|
}
|
|
}
|