|
@@ -16,10 +16,7 @@ namespace SharpGLTF.Collections
|
|
|
|
|
|
|
|
private readonly List<T> _Vertices = new List<T>();
|
|
private readonly List<T> _Vertices = new List<T>();
|
|
|
|
|
|
|
|
- private readonly Dictionary<VertexKey, int> _VertexCache = new Dictionary<VertexKey, int>();
|
|
|
|
|
-
|
|
|
|
|
- [ThreadStatic]
|
|
|
|
|
- private readonly T[] _VertexProbe = new T[1];
|
|
|
|
|
|
|
+ private readonly Dictionary<IVertexKey, int> _VertexCache = new Dictionary<IVertexKey, int>(_KeyComparer.Instance);
|
|
|
|
|
|
|
|
#endregion
|
|
#endregion
|
|
|
|
|
|
|
@@ -35,9 +32,7 @@ namespace SharpGLTF.Collections
|
|
|
|
|
|
|
|
public int Use(T v)
|
|
public int Use(T v)
|
|
|
{
|
|
{
|
|
|
- _VertexProbe[0] = v;
|
|
|
|
|
-
|
|
|
|
|
- if (_VertexCache.TryGetValue(new VertexKey(_VertexProbe, 0), out int index))
|
|
|
|
|
|
|
+ if (_VertexCache.TryGetValue(new QueryKey(v), out int index))
|
|
|
{
|
|
{
|
|
|
System.Diagnostics.Debug.Assert(Object.Equals(v, _Vertices[index]), "Vertex equality failed");
|
|
System.Diagnostics.Debug.Assert(Object.Equals(v, _Vertices[index]), "Vertex equality failed");
|
|
|
return index;
|
|
return index;
|
|
@@ -47,7 +42,7 @@ namespace SharpGLTF.Collections
|
|
|
|
|
|
|
|
_Vertices.Add(v);
|
|
_Vertices.Add(v);
|
|
|
|
|
|
|
|
- var key = new VertexKey(_Vertices, index);
|
|
|
|
|
|
|
+ var key = new StoredKey(_Vertices, index);
|
|
|
|
|
|
|
|
_VertexCache[key] = index;
|
|
_VertexCache[key] = index;
|
|
|
|
|
|
|
@@ -62,7 +57,7 @@ namespace SharpGLTF.Collections
|
|
|
{
|
|
{
|
|
|
_Vertices[i] = transformFunc(_Vertices[i]);
|
|
_Vertices[i] = transformFunc(_Vertices[i]);
|
|
|
|
|
|
|
|
- var key = new VertexKey(_Vertices, i);
|
|
|
|
|
|
|
+ var key = new StoredKey(_Vertices, i);
|
|
|
|
|
|
|
|
_VertexCache[key] = i;
|
|
_VertexCache[key] = i;
|
|
|
}
|
|
}
|
|
@@ -76,7 +71,7 @@ namespace SharpGLTF.Collections
|
|
|
|
|
|
|
|
var idx = dst._Vertices.Count;
|
|
var idx = dst._Vertices.Count;
|
|
|
dst._Vertices.Add(v);
|
|
dst._Vertices.Add(v);
|
|
|
- dst._VertexCache[new VertexKey(dst._Vertices, idx)] = idx;
|
|
|
|
|
|
|
+ dst._VertexCache[new StoredKey(dst._Vertices, idx)] = idx;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -84,26 +79,20 @@ namespace SharpGLTF.Collections
|
|
|
|
|
|
|
|
#region types
|
|
#region types
|
|
|
|
|
|
|
|
- [System.Diagnostics.DebuggerDisplay("{_Index} {GetHashCode()}")]
|
|
|
|
|
- private struct VertexKey : IEquatable<VertexKey>
|
|
|
|
|
|
|
+ interface IVertexKey
|
|
|
{
|
|
{
|
|
|
- public VertexKey(IReadOnlyList<T> src, int idx)
|
|
|
|
|
- {
|
|
|
|
|
- _Source = src;
|
|
|
|
|
- _Index = idx;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- private readonly IReadOnlyList<T> _Source;
|
|
|
|
|
- private readonly int _Index;
|
|
|
|
|
|
|
+ T GetValue();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- public T GetValue() { return _Source[_Index]; }
|
|
|
|
|
|
|
+ sealed class _KeyComparer : IEqualityComparer<IVertexKey>
|
|
|
|
|
+ {
|
|
|
|
|
+ static _KeyComparer() { }
|
|
|
|
|
+ private _KeyComparer() { }
|
|
|
|
|
|
|
|
- public override int GetHashCode()
|
|
|
|
|
- {
|
|
|
|
|
- return GetValue().GetHashCode();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ private static readonly _KeyComparer _Instance = new _KeyComparer();
|
|
|
|
|
+ public static _KeyComparer Instance => _Instance;
|
|
|
|
|
|
|
|
- public static bool AreEqual(VertexKey x, VertexKey y)
|
|
|
|
|
|
|
+ public bool Equals(IVertexKey x, IVertexKey y)
|
|
|
{
|
|
{
|
|
|
var xx = x.GetValue();
|
|
var xx = x.GetValue();
|
|
|
var yy = y.GetValue();
|
|
var yy = y.GetValue();
|
|
@@ -111,15 +100,37 @@ namespace SharpGLTF.Collections
|
|
|
return object.Equals(xx, yy);
|
|
return object.Equals(xx, yy);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public override bool Equals(object obj)
|
|
|
|
|
|
|
+ public int GetHashCode(IVertexKey obj)
|
|
|
{
|
|
{
|
|
|
- return AreEqual(this, (VertexKey)obj);
|
|
|
|
|
|
|
+ return obj
|
|
|
|
|
+ .GetValue()
|
|
|
|
|
+ .GetHashCode();
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [System.Diagnostics.DebuggerDisplay("{GetValue()} {GetHashCode()}")]
|
|
|
|
|
+ private readonly struct QueryKey : IVertexKey
|
|
|
|
|
+ {
|
|
|
|
|
+ public QueryKey(T value) { _Value = value; }
|
|
|
|
|
+
|
|
|
|
|
+ private readonly T _Value;
|
|
|
|
|
|
|
|
- public bool Equals(VertexKey other)
|
|
|
|
|
|
|
+ public T GetValue() { return _Value; }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ [System.Diagnostics.DebuggerDisplay("{GetValue()} {GetHashCode()}")]
|
|
|
|
|
+ private readonly struct StoredKey : IVertexKey
|
|
|
|
|
+ {
|
|
|
|
|
+ public StoredKey(IReadOnlyList<T> src, int idx)
|
|
|
{
|
|
{
|
|
|
- return AreEqual(this, other);
|
|
|
|
|
|
|
+ _Source = src;
|
|
|
|
|
+ _Index = idx;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ private readonly IReadOnlyList<T> _Source;
|
|
|
|
|
+ private readonly int _Index;
|
|
|
|
|
+
|
|
|
|
|
+ public T GetValue() { return _Source[_Index]; }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
#endregion
|