86 lines
3.3 KiB
C#
86 lines
3.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Assets.ThoMagic.Renderer
|
|
{
|
|
internal class CellLayoutPool
|
|
{
|
|
private static readonly Dictionary<CellLayout, int> _hashLookup = new Dictionary<CellLayout, int>();
|
|
private static readonly Dictionary<int, CellLayout> _sharedCells = new Dictionary<int, CellLayout>();
|
|
private static readonly Dictionary<int, HashSet<int>> _usageTracker = new Dictionary<int, HashSet<int>>();
|
|
|
|
public static int Count => CellLayoutPool._sharedCells.Count;
|
|
|
|
internal static bool Validate() => CellLayoutPool._hashLookup.Count == CellLayoutPool._sharedCells.Count && CellLayoutPool._hashLookup.Count == CellLayoutPool._usageTracker.Count;
|
|
|
|
public static CellLayout Get(
|
|
object owner,
|
|
float cellSizeX,
|
|
float cellSizeZ,
|
|
int cellsX,
|
|
int cellsZ,
|
|
Bounds bounds)
|
|
{
|
|
if (owner == null)
|
|
throw new ArgumentNullException(nameof(owner));
|
|
int hashCode = CellLayoutPool.GetHashCode(cellSizeX, cellSizeZ, cellsX, cellsZ, bounds.min);
|
|
CellLayout key;
|
|
if (!CellLayoutPool._sharedCells.TryGetValue(hashCode, out key))
|
|
{
|
|
CellLayoutPool._sharedCells[hashCode] = key = new CellLayout(cellSizeX, cellSizeZ, bounds);
|
|
CellLayoutPool._hashLookup[key] = hashCode;
|
|
}
|
|
CellLayoutPool.IncreaseUsage(hashCode, owner);
|
|
return key;
|
|
}
|
|
|
|
public static void Return(object owner, CellLayout layout)
|
|
{
|
|
if (owner == null)
|
|
throw new ArgumentNullException(nameof(owner));
|
|
int hash = layout != null ? CellLayoutPool.GetHashCode(layout) : throw new ArgumentNullException(nameof(layout));
|
|
if (CellLayoutPool.DecreaseUsage(hash, owner) != 0)
|
|
return;
|
|
CellLayoutPool.Dispose(hash, layout);
|
|
}
|
|
|
|
private static void Dispose(int hash, CellLayout layout)
|
|
{
|
|
CellLayoutPool._usageTracker.Remove(hash);
|
|
CellLayoutPool._sharedCells.Remove(hash);
|
|
CellLayoutPool._hashLookup.Remove(layout);
|
|
}
|
|
|
|
private static int GetHashCode(CellLayout layout) => CellLayoutPool._hashLookup[layout];
|
|
|
|
private static void IncreaseUsage(int hash, object owner)
|
|
{
|
|
HashSet<int> intSet;
|
|
if (!CellLayoutPool._usageTracker.TryGetValue(hash, out intSet) || intSet == null)
|
|
CellLayoutPool._usageTracker[hash] = intSet = new HashSet<int>();
|
|
int hashCode = owner.GetHashCode();
|
|
if (intSet.Contains(hashCode))
|
|
return;
|
|
intSet.Add(hashCode);
|
|
}
|
|
|
|
private static int DecreaseUsage(int hash, object owner)
|
|
{
|
|
HashSet<int> intSet = CellLayoutPool._usageTracker[hash];
|
|
intSet.Remove(owner.GetHashCode());
|
|
return intSet.Count;
|
|
}
|
|
|
|
private static int GetHashCode(
|
|
float cellSizeX,
|
|
float cellSizeZ,
|
|
int cellsX,
|
|
int cellsZ,
|
|
Vector3 initialOrigin)
|
|
{
|
|
return HashCode.Combine<float, float, int, int, Vector3>(cellSizeX, cellSizeZ, cellsX, cellsZ, initialOrigin);
|
|
}
|
|
}
|
|
}
|