using System; using System.Collections.Generic; using System.Linq; namespace Encompass { internal class ComponentStore { interface IComponentStore { T All() where T : struct, IComponent; } abstract class TypedComponentStore { public abstract int Count { get; } public abstract bool Has(Entity entity); public abstract bool Remove(Entity entity); public abstract void Clear(); } class TypedComponentStore : TypedComponentStore where TComponent : struct, IComponent { private readonly Dictionary store = new Dictionary(); private readonly Dictionary priorities = new Dictionary(); public override int Count { get => store.Count; } public TComponent Get(Entity entity) { return store[entity]; } public void Set(Entity entity, TComponent component) { store[entity] = component; } public void Set(Entity entity, TComponent component, int priority) { if (!priorities.ContainsKey(entity) || priority < priorities[entity]) { store[entity] = component; } } public override bool Has(Entity entity) { return store.ContainsKey(entity); } public override void Clear() { store.Clear(); } public IEnumerable<(Entity, TComponent)> All() { return store.Select(kvp => (kvp.Key, kvp.Value)); } // public override IEnumerable All() // { // return store.Values.Cast(); // } public override bool Remove(Entity entity) { throw new NotImplementedException(); } } private readonly Dictionary Stores = new Dictionary(); public void RegisterComponentType() where TComponent : struct, IComponent { if (!Stores.ContainsKey(typeof(TComponent))) { var store = new TypedComponentStore(); Stores.Add(typeof(TComponent), store); } } private TypedComponentStore Lookup() where TComponent : struct, IComponent { return Stores[typeof(TComponent)] as TypedComponentStore; } public bool Has(Entity entity) where TComponent : struct, IComponent { return Lookup().Has(entity); } public bool Has(Type type, Entity entity) { return Stores[type].Has(entity); } public TComponent Get(Entity entity) where TComponent : struct, IComponent { return Lookup().Get(entity); } public void Set(Entity entity, TComponent component) where TComponent : struct, IComponent { Lookup().Set(entity, component); } public void Set(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { Lookup().Set(entity, component, priority); } public void Remove(Entity entity) where TComponent : struct, IComponent { Lookup().Remove(entity); } public void Remove(Entity entity) { foreach (var entry in Stores.Values) { entry.Remove(entity); } } public bool Any() where TComponent : struct, IComponent { return Lookup().Count > 0; } // public IEnumerable All() where TComponent : struct, IComponent // { // return Lookup().All(); // } public IEnumerable<(Entity, TComponent)> All() where TComponent : struct, IComponent { return Lookup().All(); } public void Clear() where TComponent : struct, IComponent { Lookup().Clear(); } public void ClearAll() { foreach (var store in Stores.Values) { store.Clear(); } } } }