using System; using System.Collections.Generic; namespace DanieleMarotta.RiversongCodeShowcase { public class EntityCache : IEntityCache { private Dictionary _caches = new(); public void CreateCache(int key, Predicate filter) where T : Entity { if (!_caches.TryGetValue(key, out var cache)) { cache = new Cache(); _caches.Add(key, cache); } ((Cache)cache).Filter = filter; } public List Get(int key) where T : Entity { if (!_caches.TryGetValue(key, out var cache)) { cache = new Cache(); _caches.Add(key, cache); } return ((Cache)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 : Cache where T : Entity { public Predicate Filter { get; set; } public List 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); } } } }