using System; using System.Collections.Generic; using System.Linq; using Encompass.Exceptions; namespace Encompass { class ComponentMessageManager { private readonly ComponentStore componentStore = new ComponentStore(); private readonly ComponentStore existingComponentStore = new ComponentStore(); private readonly ComponentStore pendingComponentStore = new ComponentStore(); private readonly Dictionary> typeToEntityToPendingComponentPriority = new Dictionary>(); internal void ClearMessages() { componentStore.ClearAll(); existingComponentStore.ClearAll(); pendingComponentStore.ClearAll(); foreach (var dictionary in typeToEntityToPendingComponentPriority.Values) { dictionary.Clear(); } } internal void AddExistingComponentMessage(ComponentMessage componentMessage) where TComponent : struct, IComponent { RegisterExistingOrPendingComponentMessage(componentMessage.entity, componentMessage.component); existingComponentStore.Set(componentMessage.entity, componentMessage.component); } internal void AddPendingComponentMessage(PendingComponentMessage pendingComponentMessage) where TComponent : struct, IComponent { RegisterExistingOrPendingComponentMessage(pendingComponentMessage.entity, pendingComponentMessage.component); pendingComponentStore.Set(pendingComponentMessage.entity, pendingComponentMessage.component, pendingComponentMessage.priority); } private void RegisterExistingOrPendingComponentMessage(Entity entity, TComponent component) where TComponent : struct, IComponent { componentStore.Set(entity, component); } // general component reads by type internal IEnumerable<(Entity, TComponent)> ReadExistingAndPendingComponentsByType() where TComponent : struct, IComponent { return componentStore.All(); } internal IEnumerable<(Entity, TComponent)> ReadExistingComponentsByType() where TComponent : struct, IComponent { return existingComponentStore.All(); } internal IEnumerable<(Entity, TComponent)> ReadPendingComponentsByType() where TComponent : struct, IComponent { return pendingComponentStore.All(); } // singular component reads by type internal (Entity, TComponent) ReadFirstExistingOrPendingComponentByType() where TComponent : struct, IComponent { if (!SomeExistingOrPendingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } return ReadExistingAndPendingComponentsByType().First(); } internal (Entity, TComponent) ReadFirstExistingComponentByType() where TComponent : struct, IComponent { if (!SomeExistingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } return ReadExistingComponentsByType().First(); } internal (Entity, TComponent) ReadFirstPendingComponentByType() where TComponent : struct, IComponent { if (!SomeExistingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } return ReadPendingComponentsByType().First(); } // check if some component of type exists in the world internal bool SomeExistingOrPendingComponent() where TComponent : struct, IComponent { return componentStore.Any(); } internal bool SomeExistingComponent() where TComponent : struct, IComponent { return existingComponentStore.Any(); } internal bool SomePendingComponent() where TComponent : struct, IComponent { return pendingComponentStore.Any(); } // read components by entity and type internal TComponent ReadExistingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { return existingComponentStore.Get(entity); } internal TComponent ReadPendingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { return pendingComponentStore.Get(entity); } // check if entity has component of type internal bool HasExistingOrPendingComponent(Entity entity) where TComponent : struct, IComponent { return componentStore.Has(entity); } internal bool HasExistingOrPendingComponent(Entity entity, Type type) { return componentStore.Has(type, entity); } internal bool HasExistingComponent(Entity entity) where TComponent : struct, IComponent { return existingComponentStore.Has(entity); } internal bool HasExistingComponent(Entity entity, Type type) { return existingComponentStore.Has(type, entity); } internal bool HasPendingComponent(Entity entity) where TComponent : struct, IComponent { return pendingComponentStore.Has(entity); } internal bool HasPendingComponent(Entity entity, Type type) { return pendingComponentStore.Has(type, entity); } } }