90 lines
2.9 KiB
C#
90 lines
2.9 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.Pool;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
public class RawResourcesState : IEnumerable<ResourceNode>
|
|
{
|
|
private const int SpatialLookupCellSize = 5;
|
|
|
|
private Dictionary<int, ResourceNode> _resourceNodesById = new();
|
|
|
|
private Dictionary<int, SpatialLookup<(int, bool)>> _spatialLookups = new();
|
|
|
|
public int Count => _resourceNodesById.Count;
|
|
|
|
public void AddResourceNode(in ResourceNode node)
|
|
{
|
|
_resourceNodesById.Add(node.Id, node);
|
|
GetLookup(node.Elevation).Add((node.Id, node.CanBeDeleted), TileRect.OneTile(node.Tile), node.Id);
|
|
}
|
|
|
|
public bool Exists(int id)
|
|
{
|
|
return _resourceNodesById.ContainsKey(id);
|
|
}
|
|
|
|
public bool TryGetResourceNode(int id, out ResourceNode node)
|
|
{
|
|
return _resourceNodesById.TryGetValue(id, out node);
|
|
}
|
|
|
|
public void GetResourceNodes(TileRect rect, int elevation, List<(int, bool)> resourceNodeIds)
|
|
{
|
|
GetLookup(elevation).Find(rect, resourceNodeIds);
|
|
}
|
|
|
|
public bool DeleteResourceNode(int id, int elevation, out ResourceNode resourceNode)
|
|
{
|
|
var result = _resourceNodesById.Remove(id, out resourceNode);
|
|
if (result) GetLookup(elevation).Remove(TileRect.OneTile(resourceNode.Tile), id);
|
|
return result;
|
|
}
|
|
|
|
public void DeleteResourceNodes(TileRect rect, int elevation, List<ResourceNode> deletedResourceNodes = null)
|
|
{
|
|
using var removeIdsScope = ListPool<(int, bool)>.Get(out var removeIds);
|
|
GetLookup(elevation)
|
|
.RemoveAll(
|
|
rect,
|
|
value =>
|
|
{
|
|
var (_, canBeDeleted) = value;
|
|
return canBeDeleted;
|
|
},
|
|
removeIds);
|
|
|
|
foreach (var (id, canBeDeleted) in removeIds)
|
|
{
|
|
_resourceNodesById.Remove(id, out var resourceNode);
|
|
deletedResourceNodes?.Add(resourceNode);
|
|
}
|
|
}
|
|
|
|
private SpatialLookup<(int, bool)> GetLookup(int elevation)
|
|
{
|
|
if (!_spatialLookups.TryGetValue(elevation, out var lookup))
|
|
{
|
|
lookup = new SpatialLookup<(int, bool)>(SpatialLookupCellSize);
|
|
_spatialLookups.Add(elevation, lookup);
|
|
}
|
|
return lookup;
|
|
}
|
|
|
|
public Dictionary<int, ResourceNode>.ValueCollection.Enumerator GetEnumerator()
|
|
{
|
|
return _resourceNodesById.Values.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator<ResourceNode> IEnumerable<ResourceNode>.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return GetEnumerator();
|
|
}
|
|
}
|
|
} |