using System; using System.Collections.Generic; using System.Linq; namespace Encompass { internal class ComponentUpdateManager { private readonly ComponentStore existingComponentStore; private readonly ComponentStore immediateComponentStore; private readonly ComponentStore existingAndImmediateComponentStore; public ComponentStore UpToDateComponentStore { get; private set; } public Dictionary TypeToIndex { get; } public ComponentUpdateManager(Dictionary typeToIndex) { existingAndImmediateComponentStore = new ComponentStore(typeToIndex); existingComponentStore = new ComponentStore(typeToIndex); immediateComponentStore = new ComponentStore(typeToIndex); UpToDateComponentStore = new ComponentStore(typeToIndex); TypeToIndex = typeToIndex; } public void RegisterComponentType() where TComponent : struct, IComponent { existingAndImmediateComponentStore.RegisterComponentType(); existingComponentStore.RegisterComponentType(); immediateComponentStore.RegisterComponentType(); UpToDateComponentStore.RegisterComponentType(); } internal void Clear() { existingAndImmediateComponentStore.ClearAll(); existingComponentStore.ClearAll(); immediateComponentStore.ClearAll(); UpToDateComponentStore.ClearAll(); } internal void SetStartingComponentStore(ComponentStore componentStore) { UpToDateComponentStore = componentStore; } internal void AddExistingComponent(Entity entity, TComponent component) where TComponent : struct, IComponent { RegisterExistingOrImmediateComponentMessage(entity, component); existingComponentStore.Set(entity.ID, component); } internal bool AddImmediateComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { if (immediateComponentStore.Set(entity.ID, component, priority)) { RegisterExistingOrImmediateComponentMessage(entity, component); return true; } return false; } internal bool RemoveImmediate(Entity entity, int priority) where TComponent : struct, IComponent { if (immediateComponentStore.Remove(entity.ID, priority)) { existingAndImmediateComponentStore.Remove(entity.ID, priority); UpToDateComponentStore.Remove(entity.ID, priority); return true; } return false; } internal bool Remove(Entity entity, int priority) where TComponent : struct, IComponent { if (existingComponentStore.Remove(entity.ID, priority)) { UpToDateComponentStore.Remove(entity.ID, priority); return true; } return false; } private void RegisterExistingOrImmediateComponentMessage(Entity entity, TComponent component) where TComponent : struct, IComponent { existingAndImmediateComponentStore.Set(entity.ID, component); UpToDateComponentStore.Set(entity.ID, component); } public bool UpdateComponent(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { return UpToDateComponentStore.Set(entity.ID, component, priority); } // general component reads by type internal IEnumerable<(TComponent, int)> ReadExistingAndImmediateComponentsByType() where TComponent : struct, IComponent { return existingAndImmediateComponentStore.All(); } internal IEnumerable<(TComponent, int)> ReadExistingComponentsByType() where TComponent : struct, IComponent { return existingComponentStore.All(); } internal IEnumerable<(TComponent, int)> ReadImmediateComponentsByType() where TComponent : struct, IComponent { return immediateComponentStore.All(); } // singular component reads by type internal (TComponent, int) ReadFirstExistingOrImmediateComponentByType() where TComponent : struct, IComponent { if (!SomeExistingOrImmediateComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } var enumerator = ReadExistingAndImmediateComponentsByType().GetEnumerator(); enumerator.MoveNext(); return enumerator.Current; } internal (TComponent, int) ReadFirstExistingComponentByType() where TComponent : struct, IComponent { if (!SomeExistingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } var enumerator = ReadExistingComponentsByType().GetEnumerator(); enumerator.MoveNext(); return enumerator.Current; } internal (TComponent, int) ReadFirstImmediateComponentByType() where TComponent : struct, IComponent { if (!SomeImmediateComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } var enumerator = ReadImmediateComponentsByType().GetEnumerator(); enumerator.MoveNext(); return enumerator.Current; } // check if some component of type exists in the world internal bool SomeExistingOrImmediateComponent() where TComponent : struct, IComponent { return existingAndImmediateComponentStore.Any(); } internal bool SomeExistingComponent() where TComponent : struct, IComponent { return existingComponentStore.Any(); } internal bool SomeImmediateComponent() where TComponent : struct, IComponent { return immediateComponentStore.Any(); } // read components by entity and type internal TComponent ReadExistingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { return existingComponentStore.Get(entity.ID); } internal TComponent ReadImmediateComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { return immediateComponentStore.Get(entity.ID); } // check if entity has component of type internal bool HasExistingOrImmediateComponent(Entity entity) where TComponent : struct, IComponent { return existingAndImmediateComponentStore.Has(entity.ID); } internal bool HasExistingOrImmediateComponent(Entity entity, Type type) { return existingAndImmediateComponentStore.Has(type, entity.ID); } internal bool HasExistingComponent(Entity entity) where TComponent : struct, IComponent { return existingComponentStore.Has(entity.ID); } internal bool HasExistingComponent(Entity entity, Type type) { return existingComponentStore.Has(type, entity.ID); } internal bool HasImmediateComponent(Entity entity) where TComponent : struct, IComponent { return immediateComponentStore.Has(entity.ID); } internal bool HasImmediateComponent(Entity entity, Type type) { return immediateComponentStore.Has(type, entity.ID); } internal ComponentBitSet ImmediateBits { get { return immediateComponentStore.ComponentBitSet; } } internal ComponentBitSet ExistingBits { get { return existingComponentStore.ComponentBitSet; } } } }