diff --git a/encompass-cs/Collections/ComponentStore.cs b/encompass-cs/Collections/ComponentStore.cs index 5d857b1..ee72406 100644 --- a/encompass-cs/Collections/ComponentStore.cs +++ b/encompass-cs/Collections/ComponentStore.cs @@ -1,48 +1,141 @@ using System; using System.Collections.Generic; +using System.Linq; namespace Encompass { internal class ComponentStore { - private readonly Dictionary Stores = new Dictionary(); - private readonly Dictionary ClearMethods = new Dictionary(); + interface IComponentStore + { + T All() where T : struct, IComponent; + } - private Dictionary Lookup() where TComponent : 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 dictionary = new Dictionary(); - Stores.Add(typeof(TComponent), dictionary); - ClearMethods.Add(typeof(TComponent), dictionary.Clear); + var store = new TypedComponentStore(); + Stores.Add(typeof(TComponent), store); } - - return Stores[typeof(TComponent)] as Dictionary; } - public bool Has(Guid id) where TComponent : struct, IComponent + private TypedComponentStore Lookup() where TComponent : struct, IComponent { - return Lookup().ContainsKey(id); + return Stores[typeof(TComponent)] as TypedComponentStore; } - public TComponent Get(Guid id) where TComponent : struct, IComponent + public bool Has(Entity entity) where TComponent : struct, IComponent { - return Lookup()[id]; + return Lookup().Has(entity); } - public void Set(Type type, Guid id, IComponent component) + public bool Has(Type type, Entity entity) { - (Stores[type] as Dictionary)[id] = component; + return Stores[type].Has(entity); } - public void Set(Guid id, TComponent component) where TComponent : struct, IComponent + public TComponent Get(Entity entity) where TComponent : struct, IComponent { - Lookup()[id] = component; + return Lookup().Get(entity); } - public void Remove(Guid id) where TComponent : struct, IComponent + public void Set(Entity entity, TComponent component) where TComponent : struct, IComponent { - Lookup().Remove(id); + 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 @@ -52,9 +145,9 @@ namespace Encompass public void ClearAll() { - foreach (var type in Stores.Keys) + foreach (var store in Stores.Values) { - ClearMethods[type](); + store.Clear(); } } } diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index 08340f4..6ea8a00 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -10,66 +10,35 @@ namespace Encompass { private readonly DrawLayerManager drawLayerManager; - private readonly Dictionary componentIDToType = new Dictionary(); - private readonly ComponentStore IDToComponent = new ComponentStore(); - private readonly Dictionary> entityIDToComponentIDs = new Dictionary>(); - private readonly Dictionary componentIDToEntityID = new Dictionary(); + private readonly ComponentStore componentStore = new ComponentStore(); - private readonly Dictionary> entityIDToComponentTypeToComponentID = new Dictionary>(); - - private readonly Dictionary> typeToComponentIDs = new Dictionary>(); - - private readonly Dictionary<(Entity, Type), (Guid, IComponent)> componentWriteData = new Dictionary<(Entity, Type), (Guid, IComponent)>(); + private readonly Dictionary<(Entity, Type), IComponent> componentWriteData = new Dictionary<(Entity, Type), IComponent>(); private readonly Dictionary<(Entity, Type), int> componentWritePriorities = new Dictionary<(Entity, Type), int>(); - private readonly HashSet componentIDsMarkedForWrite = new HashSet(); - private readonly HashSet componentsMarkedForRemoval = new HashSet(); + private readonly HashSet entitiesMarkedForRemoval = new HashSet(); public ComponentManager(DrawLayerManager drawLayerManager) { this.drawLayerManager = drawLayerManager; } - internal void RegisterEntity(Guid entityID) + internal void MarkComponentForWrite(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent { - entityIDToComponentIDs.Add(entityID, new PooledSet()); - entityIDToComponentTypeToComponentID.Add(entityID, new PooledDictionary()); - } - - private Guid NextID() - { - return Guid.NewGuid(); - } - - internal Guid MarkComponentForWrite(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent - { - Guid id; - if (EntityHasComponentOfType(entity)) - { - id = GetComponentByEntityAndType(entity).Item1; - } - else - { - id = NextID(); - } + componentStore.RegisterComponentType(); if (componentWriteData.ContainsKey((entity, typeof(TComponent)))) { var currentPriority = componentWritePriorities[(entity, typeof(TComponent))]; if (priority < currentPriority) { - componentWriteData[(entity, typeof(TComponent))] = (id, component); + componentWriteData[(entity, typeof(TComponent))] = component; componentWritePriorities[(entity, typeof(TComponent))] = priority; - componentIDsMarkedForWrite.Add(id); } } else { - componentWriteData.Add((entity, typeof(TComponent)), (id, component)); + componentWriteData.Add((entity, typeof(TComponent)), component); componentWritePriorities[(entity, typeof(TComponent))] = priority; - componentIDsMarkedForWrite.Add(id); } - - return id; } internal void RegisterDrawableComponent(Guid componentID, TComponent component) where TComponent : IDrawableComponent @@ -77,23 +46,9 @@ namespace Encompass drawLayerManager.RegisterComponentWithLayer(componentID, component.Layer); } - internal void AddComponent(Entity entity, Type type, Guid componentID, IComponent component) + internal void AddComponent(Entity entity, TComponent component) where TComponent : struct, IComponent { - IDToComponent.Set(type, componentID, component); - componentIDToEntityID[componentID] = entity.ID; - componentIDToType[componentID] = type; - entityIDToComponentTypeToComponentID[entity.ID][type] = componentID; - if (!typeToComponentIDs.ContainsKey(type)) - { - typeToComponentIDs.Add(type, new HashSet()); - } - typeToComponentIDs[type].Add(componentID); - entityIDToComponentIDs[entity.ID].Add(componentID); - } - - internal void UpdateComponent(Guid componentID, IComponent component) - { - IDToComponent[componentID] = component; + componentStore.Set(entity, component); } internal void WriteComponents() @@ -101,165 +56,59 @@ namespace Encompass foreach (var keyValuePair in componentWriteData) { var (entity, type) = keyValuePair.Key; - var (componentID, component) = keyValuePair.Value; + var component = keyValuePair.Value; - if (!componentIDsMarkedForWrite.Contains(componentID) || !entityIDToComponentTypeToComponentID.ContainsKey(entity.ID)) { continue; } - - if (entityIDToComponentTypeToComponentID[entity.ID].ContainsKey(type)) - { - UpdateComponent(componentID, component); - } - else - { - AddComponent(entity, type, componentID, component); - } + AddComponent(entity, component); } componentWriteData.Clear(); - componentIDsMarkedForWrite.Clear(); componentWritePriorities.Clear(); } - internal IEnumerable GetComponentIDsByEntityID(Guid entityID) + internal IEnumerable GetComponentsByType() where TComponent : struct, IComponent { - if (entityIDToComponentIDs.TryGetValue(entityID, out PooledSet idSet)) - { - return idSet; - } - return Enumerable.Empty(); + return componentStore.All().Select(pair => pair.Item2); } - internal IEnumerable<(Guid, TComponent)> GetComponentsByType() where TComponent : struct, IComponent + internal TComponent GetComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { - if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Select(id => (id, IDToComponent.Get(id))); - } - return Enumerable.Empty<(Guid, TComponent)>(); - } - - internal (Guid, TComponent) GetComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent - { - if (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].TryGetValue(typeof(TComponent), out Guid id)) - { - return (id, IDToComponent.Get(id)); - } - - throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID); + return componentStore.Get(entity); } internal bool EntityHasComponentOfType(Entity entity) where TComponent : struct, IComponent { - return (entityIDToComponentTypeToComponentID.ContainsKey(entity.ID) && entityIDToComponentTypeToComponentID[entity.ID].ContainsKey(typeof(TComponent))); + return componentStore.Has(entity); } internal bool ComponentOfTypeExists() where TComponent : struct, IComponent { - if (typeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Count > 0; - } - - return false; + return componentStore.Any(); } - internal IComponent GetComponentByID(Guid componentID) + internal void MarkAllComponentsOnEntityForRemoval(Entity entity) { - if (IDToComponent.Has(componentID)) - { - return IDToComponent[componentID]; - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } - } - - internal Type GetComponentTypeByID(Guid componentID) - { - if (componentIDToType.ContainsKey(componentID)) - { - return componentIDToType[componentID]; - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } - } - - internal Guid GetEntityIDByComponentID(Guid componentID) - { - if (componentIDToEntityID.ContainsKey(componentID)) - { - return componentIDToEntityID[componentID]; - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } - } - - internal void MarkAllComponentsOnEntityForRemoval(Guid entityID) - { - foreach (var componentID in GetComponentIDsByEntityID(entityID)) - { - MarkForRemoval(componentID); - } - } - - internal void MarkForRemoval(Guid componentID) - { - componentsMarkedForRemoval.Add(componentID); + entitiesMarkedForRemoval.Add(entity); } internal void RemoveMarkedComponents() { - foreach (var componentID in componentsMarkedForRemoval) + foreach (var entity in entitiesMarkedForRemoval) { - if (componentIDsMarkedForWrite.Contains(componentID)) - { - componentIDsMarkedForWrite.Remove(componentID); - } - - if (IDToComponent.ContainsKey(componentID)) - { - Remove(componentID); - } + componentStore.Remove(entity); + drawLayerManager.UnRegisterComponentWithLayer(entity); } - componentsMarkedForRemoval.Clear(); + entitiesMarkedForRemoval.Clear(); } - private void Remove(Guid componentID) where TComponent : struct, IComponent + public void Remove(Entity entity) where TComponent : struct, IComponent { - var type = componentIDToType[componentID]; - - var entityID = componentIDToEntityID[componentID]; - if (entityIDToComponentIDs.ContainsKey(entityID)) - { - entityIDToComponentIDs[entityID].Remove(componentID); - } - - if (entityIDToComponentTypeToComponentID.ContainsKey(entityID)) - { - entityIDToComponentTypeToComponentID[entityID].Remove(type); - } - - IDToComponent.Remove(componentID); - componentIDToType.Remove(componentID); - componentIDToEntityID.Remove(componentID); - typeToComponentIDs[type].Remove(componentID); - - drawLayerManager.UnRegisterComponentWithLayer(componentID); + componentStore.Remove(entity); } - public void RegisterDestroyedEntity(Guid entityID) + private void Remove(Entity entity) { - entityIDToComponentIDs[entityID].Dispose(); - entityIDToComponentIDs.Remove(entityID); - - entityIDToComponentTypeToComponentID[entityID].Dispose(); - entityIDToComponentTypeToComponentID.Remove(entityID); + componentStore.Remove(entity); } } } diff --git a/encompass-cs/ComponentMessageManager.cs b/encompass-cs/ComponentMessageManager.cs index d9d6d59..15da58d 100644 --- a/encompass-cs/ComponentMessageManager.cs +++ b/encompass-cs/ComponentMessageManager.cs @@ -7,56 +7,18 @@ namespace Encompass { class ComponentMessageManager { - private readonly ComponentStore componentIDToComponent = new ComponentStore(); - private readonly Dictionary componentIDToType = new Dictionary(); + private readonly ComponentStore componentStore = new ComponentStore(); - private readonly Dictionary componentIDToEntityID = new Dictionary(); - - private readonly Dictionary> componentMessageTypeToExistingComponentIDs = new Dictionary>(); - private readonly Dictionary> componentMessageTypeToPendingComponentIDs = new Dictionary>(); - private readonly Dictionary> componentMessageTypeToComponentIDs = new Dictionary>(); - - private readonly Dictionary> typeToEntityToExistingComponentID = new Dictionary>(); - private readonly Dictionary> typeToEntityToPendingComponentID = new Dictionary>(); - private readonly Dictionary> typeToEntityToComponentID = new Dictionary>(); + private readonly ComponentStore existingComponentStore = new ComponentStore(); + private readonly ComponentStore pendingComponentStore = new ComponentStore(); private readonly Dictionary> typeToEntityToPendingComponentPriority = new Dictionary>(); internal void ClearMessages() { - componentIDToComponent.ClearAll(); - componentIDToType.Clear(); - componentIDToEntityID.Clear(); - - foreach (var set in componentMessageTypeToExistingComponentIDs.Values) - { - set.Clear(); - } - - foreach (var set in componentMessageTypeToPendingComponentIDs.Values) - { - set.Clear(); - } - - foreach (var set in componentMessageTypeToComponentIDs.Values) - { - set.Clear(); - } - - foreach (var dictionary in typeToEntityToExistingComponentID.Values) - { - dictionary.Clear(); - } - - foreach (var dictionary in typeToEntityToPendingComponentID.Values) - { - dictionary.Clear(); - } - - foreach (var dictionary in typeToEntityToComponentID.Values) - { - dictionary.Clear(); - } + componentStore.ClearAll(); + existingComponentStore.ClearAll(); + pendingComponentStore.ClearAll(); foreach (var dictionary in typeToEntityToPendingComponentPriority.Values) { @@ -66,129 +28,55 @@ namespace Encompass internal void AddExistingComponentMessage(ComponentMessage componentMessage) where TComponent : struct, IComponent { - RegisterExistingOrPendingComponentMessage(componentMessage.entity, componentMessage.componentID, componentMessage.component); + RegisterExistingOrPendingComponentMessage(componentMessage.entity, componentMessage.component); - if (!componentMessageTypeToExistingComponentIDs.ContainsKey(typeof(TComponent))) - { - componentMessageTypeToExistingComponentIDs.Add(typeof(TComponent), new HashSet()); - } - - componentMessageTypeToExistingComponentIDs[typeof(TComponent)].Add(componentMessage.componentID); - - if (!typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent))) - { - typeToEntityToExistingComponentID.Add(typeof(TComponent), new Dictionary()); - } - - if (!typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(componentMessage.entity)) - { - typeToEntityToExistingComponentID[typeof(TComponent)].Add(componentMessage.entity, componentMessage.componentID); - } - else - { - throw new MultipleComponentOfSameTypeException("Entity {0} cannot have multiple components of type {1}", componentMessage.entity.ID, typeof(TComponent).Name); - } + existingComponentStore.Set(componentMessage.entity, componentMessage.component); } internal void AddPendingComponentMessage(PendingComponentMessage pendingComponentMessage) where TComponent : struct, IComponent { - RegisterExistingOrPendingComponentMessage(pendingComponentMessage.entity, pendingComponentMessage.componentID, pendingComponentMessage.component); + RegisterExistingOrPendingComponentMessage(pendingComponentMessage.entity, pendingComponentMessage.component); - if (!componentMessageTypeToPendingComponentIDs.ContainsKey(typeof(TComponent))) - { - componentMessageTypeToPendingComponentIDs.Add(typeof(TComponent), new HashSet()); - } - - if (!typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent))) - { - typeToEntityToPendingComponentID.Add(typeof(TComponent), new Dictionary()); - typeToEntityToPendingComponentPriority.Add(typeof(TComponent), new Dictionary()); - } - - if (!typeToEntityToPendingComponentID[typeof(TComponent)].ContainsKey(pendingComponentMessage.entity)) - { - typeToEntityToPendingComponentID[typeof(TComponent)].Add(pendingComponentMessage.entity, pendingComponentMessage.componentID); - typeToEntityToPendingComponentPriority[typeof(TComponent)].Add(pendingComponentMessage.entity, pendingComponentMessage.priority); - componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID); - } - else - { - if (pendingComponentMessage.priority < typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity]) - { - componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Remove(typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity]); - typeToEntityToPendingComponentID[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.componentID; - typeToEntityToPendingComponentPriority[typeof(TComponent)][pendingComponentMessage.entity] = pendingComponentMessage.priority; - componentMessageTypeToPendingComponentIDs[typeof(TComponent)].Add(pendingComponentMessage.componentID); - } - } + pendingComponentStore.Set(pendingComponentMessage.entity, pendingComponentMessage.component, pendingComponentMessage.priority); } - private void RegisterExistingOrPendingComponentMessage(Entity entity, Guid componentID, TComponent component) where TComponent : struct, IComponent + private void RegisterExistingOrPendingComponentMessage(Entity entity, TComponent component) where TComponent : struct, IComponent { - componentIDToComponent.Set(componentID, component); - componentIDToEntityID[componentID] = entity.ID; - componentIDToType[componentID] = typeof(TComponent); - - if (!componentMessageTypeToComponentIDs.ContainsKey(typeof(TComponent))) - { - componentMessageTypeToComponentIDs.Add(typeof(TComponent), new HashSet()); - } - componentMessageTypeToComponentIDs[typeof(TComponent)].Add(componentID); - - if (!typeToEntityToComponentID.ContainsKey(typeof(TComponent))) - { - typeToEntityToComponentID.Add(typeof(TComponent), new Dictionary()); - } - typeToEntityToComponentID[typeof(TComponent)][entity] = componentID; + componentStore.Set(entity, component); } // general component reads by type - internal IEnumerable<(Guid, TComponent)> ReadExistingAndPendingComponentsByType() where TComponent : struct, IComponent + internal IEnumerable<(Entity, TComponent)> ReadExistingAndPendingComponentsByType() where TComponent : struct, IComponent { - if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Select(id => (id, componentIDToComponent.Get(id))); - } - - return Enumerable.Empty<(Guid, TComponent)>(); + return componentStore.All(); } - internal IEnumerable<(Guid, TComponent)> ReadExistingComponentsByType() where TComponent : struct, IComponent + internal IEnumerable<(Entity, TComponent)> ReadExistingComponentsByType() where TComponent : struct, IComponent { - if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Select(id => (id, componentIDToComponent.Get(id))); - } - - return Enumerable.Empty<(Guid, TComponent)>(); + return existingComponentStore.All(); } - internal IEnumerable<(Guid, TComponent)> ReadPendingComponentsByType() where TComponent : struct, IComponent + internal IEnumerable<(Entity, TComponent)> ReadPendingComponentsByType() where TComponent : struct, IComponent { - if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Select(id => (id, componentIDToComponent.Get(id))); - } - - return Enumerable.Empty<(Guid, TComponent)>(); + return pendingComponentStore.All(); } // singular component reads by type - internal (Guid, TComponent) ReadFirstExistingOrPendingComponentByType() where TComponent : struct, IComponent + 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 (Guid, TComponent) ReadFirstExistingComponentByType() where TComponent : struct, IComponent + 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 (Guid, TComponent) ReadFirstPendingComponentByType() where TComponent : struct, IComponent + internal (Entity, TComponent) ReadFirstPendingComponentByType() where TComponent : struct, IComponent { if (!SomeExistingComponent()) { throw new Exceptions.NoComponentOfTypeException($"No Component with type {typeof(TComponent)} exists"); } return ReadPendingComponentsByType().First(); @@ -198,126 +86,61 @@ namespace Encompass internal bool SomeExistingOrPendingComponent() where TComponent : struct, IComponent { - if (componentMessageTypeToComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Count > 0; - } - - return false; + return componentStore.Any(); } internal bool SomeExistingComponent() where TComponent : struct, IComponent { - if (componentMessageTypeToExistingComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Count > 0; - } - - return false; + return existingComponentStore.Any(); } internal bool SomePendingComponent() where TComponent : struct, IComponent { - if (componentMessageTypeToPendingComponentIDs.TryGetValue(typeof(TComponent), out HashSet idSet)) - { - return idSet.Count > 0; - } - - return false; + return pendingComponentStore.Any(); } // read components by entity and type - internal (Guid, TComponent) ReadExistingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent + internal TComponent ReadExistingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { - if (typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id)) - { - return (id, componentIDToComponent.Get(id)); - } - else - { - throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID); - } + return existingComponentStore.Get(entity); } - internal (Guid, TComponent) ReadPendingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent + internal TComponent ReadPendingComponentByEntityAndType(Entity entity) where TComponent : struct, IComponent { - if (typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].TryGetValue(entity, out Guid id)) - { - return (id, componentIDToComponent.Get(id)); - } - else - { - throw new NoComponentOfTypeOnEntityException("No Component of type {0} exists on Entity {1}", typeof(TComponent).Name, entity.ID); - } + return pendingComponentStore.Get(entity); } // check if entity has component of type internal bool HasExistingOrPendingComponent(Entity entity) where TComponent : struct, IComponent { - return typeToEntityToComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToComponentID[typeof(TComponent)].ContainsKey(entity); + return componentStore.Has(entity); } internal bool HasExistingOrPendingComponent(Entity entity, Type type) { - return typeToEntityToComponentID.ContainsKey(type) && typeToEntityToComponentID[type].ContainsKey(entity); + return componentStore.Has(type, entity); } internal bool HasExistingComponent(Entity entity) where TComponent : struct, IComponent { - return typeToEntityToExistingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToExistingComponentID[typeof(TComponent)].ContainsKey(entity); + return existingComponentStore.Has(entity); } internal bool HasExistingComponent(Entity entity, Type type) { - return typeToEntityToExistingComponentID.ContainsKey(type) && typeToEntityToExistingComponentID[type].ContainsKey(entity); + return existingComponentStore.Has(type, entity); } internal bool HasPendingComponent(Entity entity) where TComponent : struct, IComponent { - return typeToEntityToPendingComponentID.ContainsKey(typeof(TComponent)) && typeToEntityToPendingComponentID[typeof(TComponent)].ContainsKey(entity); + return pendingComponentStore.Has(entity); } internal bool HasPendingComponent(Entity entity, Type type) { - return typeToEntityToPendingComponentID.ContainsKey(type) && typeToEntityToPendingComponentID[type].ContainsKey(entity); - } - - internal TComponent GetComponentByID(Guid componentID) where TComponent : struct, IComponent - { - if (componentIDToComponent.Has(componentID)) - { - return componentIDToComponent.Get(componentID); - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } - } - - internal Type GetComponentTypeByID(Guid componentID) - { - if (componentIDToType.ContainsKey(componentID)) - { - return componentIDToType[componentID]; - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } - } - - internal Guid GetEntityIDByComponentID(Guid componentID) - { - if (componentIDToEntityID.ContainsKey(componentID)) - { - return componentIDToEntityID[componentID]; - } - else - { - throw new ComponentNotFoundException("Component with ID {0} does not exist.", componentID); - } + return pendingComponentStore.Has(type, entity); } } } diff --git a/encompass-cs/DrawLayerManager.cs b/encompass-cs/DrawLayerManager.cs index 926be6f..a00e669 100644 --- a/encompass-cs/DrawLayerManager.cs +++ b/encompass-cs/DrawLayerManager.cs @@ -73,7 +73,7 @@ namespace Encompass } } - public void UnRegisterComponentWithLayer(Guid id) + public void UnRegisterComponentWithLayer(Entity entity) { if (componentIDToLayerIndex.ContainsKey(id)) { diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index fcf6288..eb9a1b4 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -20,7 +20,7 @@ namespace Encompass internal readonly Dictionary writePriorities = new Dictionary(); /// - /// If false, the Engine will ignore time dilation. + /// If false, the Engine will ignore time dilation. /// internal bool usesTimeDilation = true; public bool TimeDilationActive { get => usesTimeDilation && timeManager.TimeDilationActive; } @@ -154,37 +154,12 @@ namespace Encompass return entityManager.GetEntity(entityID); } - /// - /// Returns the Entity ID associated with the specified Component Type and ID. - /// - private Guid GetEntityIDByComponentID(Guid componentID) where TComponent : struct, IComponent - { - var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage)); - var existingRead = receiveTypes.Contains(typeof(ComponentMessage)); - - if (!pendingRead && !existingRead) - { - throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name); - } - - return componentMessageManager.GetEntityIDByComponentID(componentID); - } - - /// - /// Returns the Entity associated with the specified Component Type and ID. - /// - private Entity GetEntityByComponentID(Guid componentID) where TComponent : struct, IComponent - { - return GetEntity(GetEntityIDByComponentID(componentID)); - } - /// /// Returns an Entity containing the specified Component type. /// protected Entity ReadEntity() where TComponent : struct, IComponent { - var (id, _) = ReadComponentHelper(); - return GetEntityByComponentID(id); + return ReadComponentHelper().Item1; } /// @@ -192,46 +167,17 @@ namespace Encompass /// protected IEnumerable ReadEntities() where TComponent : struct, IComponent { - foreach (var (id, _) in ReadComponentsHelper()) - { - yield return GetEntityByComponentID(id); - } - } - - /// - /// Returns the Component struct with the specified Component Type and ID. - /// - internal TComponent GetComponentByID(Guid componentID) where TComponent : struct, IComponent - { - var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage)); - var existingRead = receiveTypes.Contains(typeof(ComponentMessage)); - - if (!pendingRead && !existingRead) - { - throw new IllegalReadException("Engine {0} tried to read undeclared Component {1}", GetType().Name, typeof(TComponent).Name); - } - - if (componentMessageManager.GetComponentTypeByID(componentID) != typeof(TComponent)) - { - throw new ComponentTypeMismatchException("Expected Component to be of type {0} but was actually of type {1}", typeof(TComponent).Name, componentMessageManager.GetComponentTypeByID(componentID).Name); - } - - return componentMessageManager.GetComponentByID(componentID); + return ReadComponentsHelper().Select(pair => pair.Item1); } // these next two are for the ComponentMessageEmitter only - internal IEnumerable<(Guid, TComponent)> ReadComponentsFromWorld() where TComponent : struct, IComponent + internal IEnumerable ReadComponentsFromWorld() where TComponent : struct, IComponent { return componentManager.GetComponentsByType(); } - internal Entity ReadEntityFromWorld(Guid componentID) - { - return GetEntity(componentManager.GetEntityIDByComponentID(componentID)); - } - - private IEnumerable<(Guid, TComponent)> ReadComponentsHelper() where TComponent : struct, IComponent + private IEnumerable<(Entity, TComponent)> ReadComponentsHelper() where TComponent : struct, IComponent { var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage)); var existingRead = receiveTypes.Contains(typeof(ComponentMessage)); @@ -266,10 +212,10 @@ namespace Encompass /// protected IEnumerable<(TComponent, Entity)> ReadComponentsIncludingEntity() where TComponent : struct, IComponent { - return ReadComponentsHelper().Select((tuple) => (tuple.Item2, GetEntityByComponentID(tuple.Item1))); + return ReadComponentsHelper().Select((tuple) => (tuple.Item2, tuple.Item1)); } - private (Guid, TComponent) ReadComponentHelper() where TComponent : struct, IComponent + private (Entity, TComponent) ReadComponentHelper() where TComponent : struct, IComponent { var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage)); var existingRead = receiveTypes.Contains(typeof(ComponentMessage)); @@ -304,8 +250,8 @@ namespace Encompass /// protected (TComponent, Entity) ReadComponentIncludingEntity() where TComponent : struct, IComponent { - var (id, component) = ReadComponentHelper(); - return (component, GetEntityByComponentID(id)); + var (entity, component) = ReadComponentHelper(); + return (component, entity); } /// @@ -333,7 +279,7 @@ namespace Encompass } } - private (Guid, TComponent) GetComponentHelper(Entity entity) where TComponent : struct, IComponent + private TComponent GetComponentHelper(Entity entity) where TComponent : struct, IComponent { var pendingRead = receiveTypes.Contains(typeof(PendingComponentMessage)); var existingRead = receiveTypes.Contains(typeof(ComponentMessage)); @@ -377,7 +323,7 @@ namespace Encompass /// protected TComponent GetComponent(Entity entity) where TComponent : struct, IComponent { - return GetComponentHelper(entity).Item2; + return GetComponentHelper(entity); } /// @@ -451,7 +397,7 @@ namespace Encompass { var priority = writePriorities.ContainsKey(typeof(TComponent)) ? writePriorities[typeof(TComponent)] : 0; - var componentID = componentManager.MarkComponentForWrite(entity, component, priority); + componentManager.MarkComponentForWrite(entity, component, priority); if (!sendTypes.Contains(typeof(ComponentWriteMessage))) { @@ -462,7 +408,6 @@ namespace Encompass { PendingComponentMessage newComponentMessage; newComponentMessage.entity = entity; - newComponentMessage.componentID = componentID; newComponentMessage.component = component; newComponentMessage.priority = priority; SendPendingComponentMessage(newComponentMessage); @@ -622,21 +567,10 @@ namespace Encompass { if (!HasComponent(entity)) { return false; } - var (componentID, _) = GetComponentHelper(entity); - - RemoveComponent(componentID); - + componentManager.Remove(entity); return true; } - /// - /// Removes the Component with the specified ID from its Entity. - /// - private void RemoveComponent(Guid componentID) - { - componentManager.MarkForRemoval(componentID); - } - /// /// Activates the Encompass time dilation system. /// Engines that have the IgnoresTimeDilation property will ignore all time dilation. diff --git a/encompass-cs/Engines/ComponentMessageEmitter.cs b/encompass-cs/Engines/ComponentMessageEmitter.cs index 5addc68..4d12515 100644 --- a/encompass-cs/Engines/ComponentMessageEmitter.cs +++ b/encompass-cs/Engines/ComponentMessageEmitter.cs @@ -9,15 +9,14 @@ namespace Encompass public override void Update(double dt) { - foreach (var (componentID, component) in ReadComponentsFromWorld()) + foreach (var (component, entity) in ReadComponentsIncludingEntity()) { ComponentMessage componentMessage; - componentMessage.entity = ReadEntityFromWorld(componentID); - componentMessage.componentID = componentID; + componentMessage.entity = entity; componentMessage.component = component; SendMessage(componentMessage); SendExistingComponentMessage(componentMessage); } } } -} \ No newline at end of file +} diff --git a/encompass-cs/EntityManager.cs b/encompass-cs/EntityManager.cs index 466b7da..fa96910 100644 --- a/encompass-cs/EntityManager.cs +++ b/encompass-cs/EntityManager.cs @@ -9,7 +9,7 @@ namespace Encompass { private readonly Dictionary IDToEntity = new Dictionary(); - private readonly HashSet entitiesMarkedForDestroy = new HashSet(); + private readonly HashSet entitiesMarkedForDestroy = new HashSet(); private readonly ComponentManager componentManager; @@ -23,7 +23,6 @@ namespace Encompass var id = NextID(); var entity = new Entity(id); IDToEntity[id] = entity; - componentManager.RegisterEntity(id); return entity; } @@ -44,18 +43,17 @@ namespace Encompass } } - public void MarkForDestroy(Guid entityID) + public void MarkForDestroy(Entity entity) { - entitiesMarkedForDestroy.Add(entityID); + entitiesMarkedForDestroy.Add(entity); } public void DestroyMarkedEntities() { - foreach (var entityID in entitiesMarkedForDestroy) + foreach (var entity in entitiesMarkedForDestroy) { - componentManager.MarkAllComponentsOnEntityForRemoval(entityID); - IDToEntity.Remove(entityID); - componentManager.RegisterDestroyedEntity(entityID); + componentManager.MarkAllComponentsOnEntityForRemoval(entity); + IDToEntity.Remove(entity.ID); } entitiesMarkedForDestroy.Clear(); diff --git a/encompass-cs/Messages/ComponentMessage.cs b/encompass-cs/Messages/ComponentMessage.cs index c1b74ee..1153815 100644 --- a/encompass-cs/Messages/ComponentMessage.cs +++ b/encompass-cs/Messages/ComponentMessage.cs @@ -1,11 +1,8 @@ -using System; - namespace Encompass { internal struct ComponentMessage : IMessage where TComponent : struct, IComponent { public Entity entity; - public Guid componentID; public TComponent component; } -} \ No newline at end of file +} diff --git a/encompass-cs/Messages/PendingComponentMessage.cs b/encompass-cs/Messages/PendingComponentMessage.cs index 4a051b4..8dfcc36 100644 --- a/encompass-cs/Messages/PendingComponentMessage.cs +++ b/encompass-cs/Messages/PendingComponentMessage.cs @@ -1,12 +1,9 @@ -using System; - namespace Encompass { internal struct PendingComponentMessage : IMessage where TComponent : struct, IComponent { public Entity entity; - public Guid componentID; public TComponent component; public int priority; } -} \ No newline at end of file +} diff --git a/encompass-cs/RenderManager.cs b/encompass-cs/RenderManager.cs index 35c2405..839c5fd 100644 --- a/encompass-cs/RenderManager.cs +++ b/encompass-cs/RenderManager.cs @@ -42,8 +42,8 @@ namespace Encompass foreach (var componentID in componentIDSet) { - var component = componentManager.GetComponentByID(componentID); var componentType = componentManager.GetComponentTypeByID(componentID); + var component = componentManager.GetComponentByID(componentType, componentID); var entityID = componentManager.GetEntityIDByComponentID(componentID); var entity = entityManager.GetEntity(entityID); diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index 65b9c28..491e6da 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -75,7 +75,7 @@ namespace Encompass /// public void SetComponent(Entity entity, TComponent component, int priority = 0) where TComponent : struct, IComponent { - var componentID = componentManager.MarkComponentForWrite(entity, component, priority); + componentManager.MarkComponentForWrite(entity, component, priority); if (component is IDrawableComponent drawableComponent) { componentManager.RegisterDrawableComponent(componentID, drawableComponent);