Skip to content

Commit

Permalink
Pool more types (fixes #31).
Browse files Browse the repository at this point in the history
  • Loading branch information
speps committed Mar 17, 2021
1 parent f550c56 commit 0f7cf44
Show file tree
Hide file tree
Showing 8 changed files with 395 additions and 351 deletions.
38 changes: 34 additions & 4 deletions LibTessDotNet/Sources/Dict.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,58 @@ namespace LibTessDotNet
{
internal class Dict<TValue> where TValue : class
{
public class Node
public class Node : Pooled<Node>
{
internal TValue _key;
internal Node _prev, _next;

public TValue Key { get { return _key; } }
public Node Prev { get { return _prev; } }
public Node Next { get { return _next; } }

public void Init(IPool pool)
{
_key = null;
_prev = null;
_next = null;
}

public void Reset(IPool pool)
{
_key = null;
_prev = null;
_next = null;
}
}

public delegate bool LessOrEqual(TValue lhs, TValue rhs);

private IPool _pool;
private LessOrEqual _leq;
Node _head;

public Dict(LessOrEqual leq)
public bool Empty { get { return _head._next == _head; } }

public Dict(IPool pool, LessOrEqual leq)
{
_pool = pool;
_leq = leq;

_head = new Node { _key = null };
Init();
}

public void Init()
{
_head = _pool.Get<Node>();
_head._prev = _head;
_head._next = _head;
}

public void Reset()
{
_pool.Return(ref _head);
}

public Node Insert(TValue key)
{
return InsertBefore(_head, key);
Expand All @@ -74,7 +102,8 @@ public Node InsertBefore(Node node, TValue key)
node = node._prev;
} while (node._key != null && !_leq(node._key, key));

var newNode = new Node { _key = key };
var newNode = _pool.Get<Node>();
newNode._key = key;
newNode._next = node._next;
node._next._prev = newNode;
newNode._prev = node;
Expand All @@ -101,6 +130,7 @@ public void Remove(Node node)
{
node._next._prev = node._prev;
node._prev._next = node._next;
_pool.Return(ref node);
}
}
}
10 changes: 5 additions & 5 deletions LibTessDotNet/Sources/Mesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,18 @@ public void Reset(IPool pool)
for (MeshUtils.Face f = _fHead, fNext = _fHead; f._next != null; f = fNext)
{
fNext = f._next;
pool.Return(f);
pool.Return(ref f);
}
for (MeshUtils.Vertex v = _vHead, vNext = _vHead; v._next != null; v = vNext)
{
vNext = v._next;
pool.Return(v);
pool.Return(ref v);
}
for (MeshUtils.Edge e = _eHead, eNext = _eHead; e._next != null; e = eNext)
{
eNext = e._next;
pool.Return(e._Sym);
pool.Return(e);
pool.Return(ref e._Sym);
pool.Return(ref e);
}

_vHead = null;
Expand Down Expand Up @@ -389,7 +389,7 @@ public void ZapFace(IPool pool, MeshUtils.Face fZap)
fNext._prev = fPrev;
fPrev._next = fNext;

pool.Return(fZap);
pool.Return(ref fZap);
}

public void MergeConvexFaces(IPool pool, int maxVertsPerFace)
Expand Down
26 changes: 14 additions & 12 deletions LibTessDotNet/Sources/MeshUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,7 @@ public interface ITypePool
{
private Queue<T> _pool = new Queue<T>();

private static readonly Func<T> OptimizedInstantiator = Expression.Lambda<Func<T>>(
Expression.New(typeof(T))
).Compile();
private static readonly Func<T> Creator = Expression.Lambda<Func<T>>(Expression.New(typeof(T))).Compile();

public object Get()
{
Expand All @@ -140,7 +138,7 @@ public object Get()
return _pool.Dequeue();
}
}
return OptimizedInstantiator.Invoke();
return Creator();
}

public void Return(object obj)
Expand All @@ -165,14 +163,16 @@ public abstract class IPool
{
public IPool()
{
Register<Mesh>(new DefaultTypePool<Mesh>());
Register<MeshUtils.Vertex>(new DefaultTypePool<MeshUtils.Vertex>());
Register<MeshUtils.Face>(new DefaultTypePool<MeshUtils.Face>());
Register<MeshUtils.Edge>(new DefaultTypePool<MeshUtils.Edge>());
Register<Tess.ActiveRegion>(new DefaultTypePool<Tess.ActiveRegion>());
Register<Dict<Tess.ActiveRegion>.Node>(new DefaultTypePool<Dict<Tess.ActiveRegion>.Node>());
}
public abstract void Register<T>(ITypePool typePool) where T : class, Pooled<T>, new();
public abstract T Get<T>() where T : class, Pooled<T>, new();
public abstract void Return<T>(T obj) where T : class, Pooled<T>, new();
public abstract void Return<T>(ref T obj) where T : class, Pooled<T>, new();
}

public class NullPool : IPool
Expand All @@ -188,8 +188,9 @@ public override void Register<T>(ITypePool typePool)
{
}

public override void Return<T>(T obj)
public override void Return<T>(ref T obj)
{
obj = null;
}
}

Expand Down Expand Up @@ -217,13 +218,13 @@ public override T Get<T>()
}
if (obj == null)
{
obj = new T();
throw new InvalidOperationException("Type not registered with type tool");
}
obj.Init(this);
return obj;
}

public override void Return<T>(T obj)
public override void Return<T>(ref T obj)
{
if (obj == null)
{
Expand All @@ -235,6 +236,7 @@ public override void Return<T>(T obj)
{
typePool.Return(obj);
}
obj = null;
}
}

Expand Down Expand Up @@ -514,8 +516,8 @@ public static void KillEdge(IPool pool, Edge eDel)
eNext._Sym._next = ePrev;
ePrev._Sym._next = eNext;

pool.Return(eDel._Sym);
pool.Return(eDel);
pool.Return(ref eDel._Sym);
pool.Return(ref eDel);
}

/// <summary>
Expand All @@ -539,7 +541,7 @@ public static void KillVertex(IPool pool, Vertex vDel, Vertex newOrg)
vNext._prev = vPrev;
vPrev._next = vNext;

pool.Return(vDel);
pool.Return(ref vDel);
}

/// <summary>
Expand All @@ -563,7 +565,7 @@ public static void KillFace(IPool pool, Face fDel, Face newLFace)
fNext._prev = fPrev;
fPrev._next = fNext;

pool.Return(fDel);
pool.Return(ref fDel);
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions LibTessDotNet/Sources/PriorityHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal class PriorityHeap<TValue> where TValue : class
{
public delegate bool LessOrEqual(TValue lhs, TValue rhs);

protected class HandleElem
internal class HandleElem
{
internal TValue _key;
internal int _node;
Expand Down Expand Up @@ -78,7 +78,7 @@ public PriorityHeap(int initialSize, LessOrEqual leq)
_initialized = false;

_nodes[1] = 1;
_handles[1] = new HandleElem { _key = null };
_handles[1] = new HandleElem();
}

private void FloatDown(int curr)
Expand Down
2 changes: 1 addition & 1 deletion LibTessDotNet/Sources/PriorityQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public PriorityQueue(int initialSize, PriorityHeap<TValue>.LessOrEqual leq)
_initialized = false;
}

class StackItem
struct StackItem
{
internal int p, r;
};
Expand Down
37 changes: 24 additions & 13 deletions LibTessDotNet/Sources/Sweep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void Init(IPool pool)
public void Reset(IPool pool)
{
_eUp = null;
_nodeUp = null;
_nodeUp = null; // don't return to pool as Dict takes care of that
_windingNumber = 0;
_inside = false;
_sentinel = false;
Expand Down Expand Up @@ -129,7 +129,7 @@ private void DeleteRegion(ActiveRegion reg)
}
reg._eUp._activeRegion = null;
_dict.Remove(reg._nodeUp);
_pool.Return(reg);
_pool.Return(ref reg);
}

/// <summary>
Expand Down Expand Up @@ -609,7 +609,7 @@ private bool CheckForIntersect(ActiveRegion regUp)
{
// Easy case -- intersection at one of the right endpoints
CheckForRightSplice(regUp);
_pool.Return(isect);
_pool.Return(ref isect);
return false;
}

Expand All @@ -630,7 +630,7 @@ private bool CheckForIntersect(ActiveRegion regUp)
eUp = RegionBelow(regUp)._eUp;
FinishLeftRegions(RegionBelow(regUp), regLo);
AddRightEdges(regUp, eUp._Oprev, eUp, eUp, true);
_pool.Return(isect);
_pool.Return(ref isect);
return true;
}
if( dstUp == _event ) {
Expand All @@ -643,7 +643,7 @@ private bool CheckForIntersect(ActiveRegion regUp)
regLo._eUp = eLo._Oprev;
eLo = FinishLeftRegions(regLo, null);
AddRightEdges(regUp, eLo._Onext, eUp._Rprev, e, true);
_pool.Return(isect);
_pool.Return(ref isect);
return true;
}
// Special case: called from ConnectRightVertex. If either
Expand All @@ -664,7 +664,7 @@ private bool CheckForIntersect(ActiveRegion regUp)
eLo._Org._t = _event._t;
}
// leave the rest for ConnectRightVertex
_pool.Return(isect);
_pool.Return(ref isect);
return false;
}

Expand All @@ -680,7 +680,7 @@ private bool CheckForIntersect(ActiveRegion regUp)
_mesh.Splice(_pool, eLo._Oprev, eUp);
eUp._Org._s = isect._s;
eUp._Org._t = isect._t;
_pool.Return(isect);
_pool.Return(ref isect);
isect = null;
eUp._Org._pqHandle = _pq.Insert(eUp._Org);
if (eUp._Org._pqHandle._handle == PQHandle.Invalid)
Expand Down Expand Up @@ -933,7 +933,7 @@ private void ConnectLeftVertex(MeshUtils.Vertex vEvent)
// Get a pointer to the active region containing vEvent
tmp._eUp = vEvent._anEdge._Sym;
var regUp = _dict.Find(tmp).Key;
_pool.Return(tmp);
_pool.Return(ref tmp);
var regLo = RegionBelow(regUp);
if (regLo == null)
{
Expand Down Expand Up @@ -1064,7 +1064,14 @@ private void AddSentinel(Real smin, Real smax, Real t)
/// </summary>
private void InitEdgeDict()
{
_dict = new Dict<ActiveRegion>(EdgeLeq);
if (_dict == null)
{
_dict = new Dict<ActiveRegion>(_pool, EdgeLeq);
}
else
{
_dict.Init();
}

AddSentinel(-SentinelCoord, SentinelCoord, -SentinelCoord);
AddSentinel(-SentinelCoord, SentinelCoord, +SentinelCoord);
Expand All @@ -1089,7 +1096,8 @@ private void DoneEdgeDict()
DeleteRegion(reg);
}

_dict = null;
Debug.Assert(_dict.Empty);
_dict.Reset();
}

/// <summary>
Expand Down Expand Up @@ -1149,8 +1157,11 @@ private void InitPriorityQ()
}
// Make sure there is enough space for sentinels.
vertexCount += 8;

_pq = new PriorityQueue<MeshUtils.Vertex>(vertexCount, Geom.VertLeq);

if (_pq == null)
{
_pq = new PriorityQueue<MeshUtils.Vertex>(vertexCount, Geom.VertLeq);
}

vHead = _mesh._vHead;
for( v = vHead._next; v != vHead; v = v._next ) {
Expand All @@ -1165,7 +1176,7 @@ private void InitPriorityQ()

private void DonePriorityQ()
{
_pq = null;
Debug.Assert(_pq.Empty);
}

/// <summary>
Expand Down
12 changes: 6 additions & 6 deletions LibTessDotNet/Sources/Tess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,16 @@ public Tess()
}
public Tess(IPool pool)
{
if (pool == null)
{
throw new ArgumentNullException("pool");
}

_normal = Vec3.Zero;
_bminX = _bminY = _bmaxX = _bmaxY = 0;

_windingRule = WindingRule.EvenOdd;
_pool = pool;
if (_pool == null)
{
_pool = new NullPool();
}
_mesh = null;

_vertices = null;
Expand Down Expand Up @@ -845,8 +846,7 @@ public void Tessellate(WindingRule windingRule = WindingRule.EvenOdd, ElementTyp
OutputPolymesh(elementType, polySize);
}

_pool.Return(_mesh);
_mesh = null;
_pool.Return(ref _mesh);
}
}
}
Loading

0 comments on commit 0f7cf44

Please sign in to comment.