Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/TriangleNet/TrianglePool.cs
2026-03-04 10:03:45 +08:00

224 lines
3.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using TriangleNet.Topology;
namespace TriangleNet
{
public class TrianglePool : ICollection<Triangle>, IEnumerable<Triangle>, IEnumerable
{
private class Enumerator : IEnumerator<Triangle>, IEnumerator, IDisposable
{
private int count;
private Triangle[][] pool;
private Triangle current;
private int index;
private int offset;
public Triangle Current => current;
object IEnumerator.Current => current;
public Enumerator(TrianglePool pool)
{
count = pool.Count;
this.pool = pool.pool;
index = 0;
offset = 0;
}
public void Dispose()
{
}
public bool MoveNext()
{
while (index < count)
{
current = pool[offset / 1024][offset % 1024];
offset++;
if (current.hash >= 0)
{
index++;
return true;
}
}
return false;
}
public void Reset()
{
index = (offset = 0);
}
}
private const int BLOCKSIZE = 1024;
private int size;
private int count;
private Triangle[][] pool;
private Stack<Triangle> stack;
public int Count => count - stack.Count;
public bool IsReadOnly => true;
public TrianglePool()
{
size = 0;
int num = Math.Max(1, 64);
pool = new Triangle[num][];
pool[0] = new Triangle[1024];
stack = new Stack<Triangle>(1024);
}
public Triangle Get()
{
Triangle triangle;
if (stack.Count > 0)
{
triangle = stack.Pop();
triangle.hash = -triangle.hash - 1;
Cleanup(triangle);
}
else if (count < size)
{
triangle = pool[count / 1024][count % 1024];
triangle.id = triangle.hash;
Cleanup(triangle);
count++;
}
else
{
triangle = new Triangle();
triangle.hash = size;
triangle.id = triangle.hash;
int num = size / 1024;
if (pool[num] == null)
{
pool[num] = new Triangle[1024];
if (num + 1 == pool.Length)
{
Array.Resize(ref pool, 2 * pool.Length);
}
}
pool[num][size % 1024] = triangle;
count = ++size;
}
return triangle;
}
public void Release(Triangle triangle)
{
stack.Push(triangle);
triangle.hash = -triangle.hash - 1;
}
public TrianglePool Restart()
{
foreach (Triangle item in stack)
{
item.hash = -item.hash - 1;
}
stack.Clear();
count = 0;
return this;
}
internal IEnumerable<Triangle> Sample(int k, Random random)
{
int count = Count;
if (k > count)
{
k = count;
}
while (k > 0)
{
int num = random.Next(0, count);
Triangle triangle = pool[num / 1024][num % 1024];
if (triangle.hash >= 0)
{
k--;
yield return triangle;
}
}
}
private void Cleanup(Triangle triangle)
{
triangle.label = 0;
triangle.area = 0.0;
triangle.infected = false;
for (int i = 0; i < 3; i++)
{
triangle.vertices[i] = null;
triangle.subsegs[i] = default(Osub);
triangle.neighbors[i] = default(Otri);
}
}
public void Add(Triangle item)
{
throw new NotImplementedException();
}
public void Clear()
{
stack.Clear();
int num = size / 1024 + 1;
for (int i = 0; i < num; i++)
{
Triangle[] array = pool[i];
int num2 = (size - i * 1024) % 1024;
for (int j = 0; j < num2; j++)
{
array[j] = null;
}
}
size = (count = 0);
}
public bool Contains(Triangle item)
{
int hash = item.hash;
if (hash < 0 || hash > size)
{
return false;
}
return pool[hash / 1024][hash % 1024].hash >= 0;
}
public void CopyTo(Triangle[] array, int index)
{
IEnumerator<Triangle> enumerator = GetEnumerator();
while (enumerator.MoveNext())
{
array[index] = enumerator.Current;
index++;
}
}
public bool Remove(Triangle item)
{
throw new NotImplementedException();
}
public IEnumerator<Triangle> GetEnumerator()
{
return new Enumerator(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}