CPF/CPF.ReoGrid/Data/RegularTreeArray.cs
2024-06-24 10:15:59 +08:00

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;
}
}
}