Files
riversong-code-showcase/Source/Riversong/Game/CommonServices/Entities/EntityCache/EntityCache.cs
2026-05-21 16:04:49 +02:00

81 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
namespace DanieleMarotta.RiversongCodeShowcase
{
public class EntityCache : IEntityCache
{
private Dictionary<int, Cache> _caches = new();
public void CreateCache<T>(int key, Predicate<T> filter) where T : Entity
{
if (!_caches.TryGetValue(key, out var cache))
{
cache = new Cache<T>();
_caches.Add(key, cache);
}
((Cache<T>)cache).Filter = filter;
}
public List<T> Get<T>(int key) where T : Entity
{
if (!_caches.TryGetValue(key, out var cache))
{
cache = new Cache<T>();
_caches.Add(key, cache);
}
return ((Cache<T>)cache).Entities;
}
public void OnAdded(Entity entity)
{
foreach (var cache in _caches.Values) cache.TryAdd(entity);
}
public void OnRemoved(Entity entity)
{
foreach (var cache in _caches.Values) cache.TryRemove(entity);
}
private abstract class Cache
{
public void TryAdd(Entity entity)
{
if (FilterEntity(entity)) Add(entity);
}
public void TryRemove(Entity entity)
{
if (FilterEntity(entity)) Remove(entity);
}
protected abstract bool FilterEntity(Entity entity);
protected abstract void Add(Entity entity);
protected abstract void Remove(Entity entity);
}
private class Cache<T> : Cache where T : Entity
{
public Predicate<T> Filter { get; set; }
public List<T> Entities { get; } = new();
protected override bool FilterEntity(Entity entity)
{
return entity is T typedEntity && Filter.Invoke(typedEntity);
}
protected override void Add(Entity entity)
{
Entities.Add((T)entity);
}
protected override void Remove(Entity entity)
{
Entities.Remove((T)entity);
}
}
}
}