From 150043b0e5fe24db573556c03d54024deb055491 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sat, 21 Mar 2020 22:19:31 -0700 Subject: [PATCH] fix bugs in component storage and draw layer manager --- .../Collections/ComponentDeltaStore.cs | 2 +- encompass-cs/Collections/ComponentStore.cs | 6 ++--- .../Collections/TypedComponentStore.cs | 24 ++++++++++--------- encompass-cs/ComponentManager.cs | 14 +++++------ encompass-cs/DrawLayerManager.cs | 11 +++++++-- encompass-cs/Engine.cs | 20 +++++++++++++--- encompass-cs/Renderers/OrderedRenderer.cs | 3 ++- encompass-cs/WorldBuilder.cs | 2 +- 8 files changed, 53 insertions(+), 29 deletions(-) diff --git a/encompass-cs/Collections/ComponentDeltaStore.cs b/encompass-cs/Collections/ComponentDeltaStore.cs index d59d97a..a0b022c 100644 --- a/encompass-cs/Collections/ComponentDeltaStore.cs +++ b/encompass-cs/Collections/ComponentDeltaStore.cs @@ -25,7 +25,7 @@ namespace Encompass } } - public void Set(int entityID, TComponent component) where TComponent : struct + public void Set(int entityID, in TComponent component) where TComponent : struct { _store.Set(entityID, component); RegisterComponentType(); diff --git a/encompass-cs/Collections/ComponentStore.cs b/encompass-cs/Collections/ComponentStore.cs index a0fbcb0..b4f541e 100644 --- a/encompass-cs/Collections/ComponentStore.cs +++ b/encompass-cs/Collections/ComponentStore.cs @@ -48,18 +48,18 @@ namespace Encompass return ComponentBitSet.EntityBitArray(entityID); } - public ref readonly TComponent Get(int entityID) where TComponent : struct + public ref TComponent Get(int entityID) where TComponent : struct { return ref Lookup().Get(entityID); } - public void Set(int entityID, TComponent component) where TComponent : struct + public void Set(int entityID, in TComponent component) where TComponent : struct { Lookup().Set(entityID, component); ComponentBitSet.Set(entityID); } - public bool Set(int entityID, TComponent component, int priority) where TComponent : struct + public bool Set(int entityID, in TComponent component, int priority) where TComponent : struct { if (Lookup().Set(entityID, component, priority)) { diff --git a/encompass-cs/Collections/TypedComponentStore.cs b/encompass-cs/Collections/TypedComponentStore.cs index cc77e07..727859d 100644 --- a/encompass-cs/Collections/TypedComponentStore.cs +++ b/encompass-cs/Collections/TypedComponentStore.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -14,7 +13,7 @@ namespace Encompass public abstract void ClearPriorities(); } - internal unsafe class TypedComponentStore : TypedComponentStore where TComponent : struct + internal class TypedComponentStore : TypedComponentStore where TComponent : struct { private readonly Dictionary _indices = new Dictionary(512); private readonly Dictionary _priorities = new Dictionary(512); @@ -23,18 +22,18 @@ namespace Encompass public override int Count { get => _indices.Count; } - public unsafe ref readonly TComponent Get(int entityID) + public ref TComponent Get(int entityID) { if (!_indices.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), entityID); } return ref _components[_indices[entityID]]; } - public unsafe void Set(int entityID, TComponent component) + public void Set(int entityID, in TComponent component) { InternalSet(entityID, component); } - public unsafe bool Set(int entityID, TComponent component, int priority) + public bool Set(int entityID, in TComponent component, int priority) { if (!_priorities.ContainsKey(entityID) || priority < _priorities[entityID]) { @@ -46,7 +45,7 @@ namespace Encompass return false; } - private unsafe void InternalSet(int entityID, TComponent component) + private unsafe void InternalSet(int entityID, in TComponent component) { if (!_indices.ContainsKey(entityID)) { @@ -70,9 +69,12 @@ namespace Encompass public override void ForceRemove(int entityID) { - _indices.Remove(entityID); - _priorities.Remove(entityID); - _idManager.Free(entityID); + if (_indices.ContainsKey(entityID)) + { + _idManager.Free(_indices[entityID]); + _indices.Remove(entityID); + _priorities.Remove(entityID); + } } public override bool Has(int entityID) @@ -82,9 +84,9 @@ namespace Encompass public override void Clear() { - foreach (var entityID in _indices.Keys) + foreach (var mappedID in _indices.Values) { - _idManager.Free(entityID); + _idManager.Free(mappedID); } _indices.Clear(); _priorities.Clear(); diff --git a/encompass-cs/ComponentManager.cs b/encompass-cs/ComponentManager.cs index aacdc6a..fe98902 100644 --- a/encompass-cs/ComponentManager.cs +++ b/encompass-cs/ComponentManager.cs @@ -61,7 +61,7 @@ namespace Encompass _replayStore.ClearAll(); } - internal bool AddImmediateComponent(int entityID, TComponent component, int priority) where TComponent : struct + internal bool AddImmediateComponent(int entityID, in TComponent component, int priority) where TComponent : struct { if (_immediateComponentStore.Set(entityID, component, priority)) { @@ -73,14 +73,14 @@ namespace Encompass return false; } - internal void AddImmediateComponent(int entityID, TComponent component) where TComponent : struct + internal void AddImmediateComponent(int entityID, in TComponent component) where TComponent : struct { _immediateComponentStore.Set(entityID, component); _replayStore.Set(entityID, component); _upToDateComponentStore.Set(entityID, component); } - internal bool UpdateComponent(int entityID, TComponent component, int priority) where TComponent : struct + internal bool UpdateComponent(int entityID, in TComponent component, int priority) where TComponent : struct { var result = _upToDateComponentStore.Set(entityID, component, priority); if (result) @@ -90,7 +90,7 @@ namespace Encompass return result; } - internal void AddComponent(int entityID, TComponent component) where TComponent : struct + internal void AddComponent(int entityID, in TComponent component) where TComponent : struct { _upToDateComponentStore.Set(entityID, component); _replayStore.Set(entityID, component); @@ -153,17 +153,17 @@ namespace Encompass // component getters - internal ref readonly TComponent ReadImmediateOrExistingComponentByEntityAndType(int entityID) where TComponent : struct + internal ref TComponent ReadImmediateOrExistingComponentByEntityAndType(int entityID) where TComponent : struct { return ref _upToDateComponentStore.Get(entityID); } - internal ref readonly TComponent ReadExistingComponentByEntityAndType(int entityID) where TComponent : struct + internal ref TComponent ReadExistingComponentByEntityAndType(int entityID) where TComponent : struct { return ref _existingComponentStore.Get(entityID); } - internal ref readonly TComponent ReadImmediateComponentByEntityAndType(int entityID) where TComponent : struct + internal ref TComponent ReadImmediateComponentByEntityAndType(int entityID) where TComponent : struct { return ref _immediateComponentStore.Get(entityID); } diff --git a/encompass-cs/DrawLayerManager.cs b/encompass-cs/DrawLayerManager.cs index 571ac20..e500371 100644 --- a/encompass-cs/DrawLayerManager.cs +++ b/encompass-cs/DrawLayerManager.cs @@ -97,9 +97,16 @@ namespace Encompass { foreach (var store in _layerIndexToTypeToID.Values) { - foreach (var set in store.Values) + foreach (var typeToSet in store) { - set.Remove(entityID); + var type = typeToSet.Key; + var set = typeToSet.Value; + + if (set.Contains(entityID)) + { + _typeToEntityToLayer[type].Remove(entityID); + set.Remove(entityID); + } } } } diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index 1116c0c..b5e6779 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -344,7 +344,7 @@ namespace Encompass } } - private ref readonly TComponent GetComponentHelper(int entityID) where TComponent : struct + private ref TComponent GetComponentHelper(int entityID) where TComponent : struct { var immediateRead = ReadImmediateTypes.Contains(typeof(TComponent)); var existingRead = ReadTypes.Contains(typeof(TComponent)); @@ -380,6 +380,20 @@ namespace Encompass return ref GetComponentHelper(entity.ID); } + /// + /// Returns a Component by reference with the specified Type that exists on the Entity. + /// + /// + /// Thrown when the Entity does not have a Component of the specified Type + /// + /// + /// Thrown when the Engine does not declare that it reads the given Component Type. + /// + protected ref TComponent GetComponentMutable(Entity entity) where TComponent : struct + { + return ref GetComponentHelper(entity.ID); + } + /// /// Returns true if the Entity has a Component of the given Type. /// @@ -444,7 +458,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Writes the given Component Type. /// - protected void SetComponent(Entity entity, TComponent component) where TComponent : struct + protected void SetComponent(Entity entity, in TComponent component) where TComponent : struct { var priority = WritePriorities.ContainsKey(typeof(TComponent)) ? WritePriorities[typeof(TComponent)] : DefaultWritePriority; @@ -484,7 +498,7 @@ namespace Encompass /// /// Thrown when the Engine does not declare that it Writes the given Component Type. /// - protected void AddComponent(Entity entity, TComponent component) where TComponent : struct + protected void AddComponent(Entity entity, in TComponent component) where TComponent : struct { if (!EntityCreatedThisFrame(entity.ID)) { diff --git a/encompass-cs/Renderers/OrderedRenderer.cs b/encompass-cs/Renderers/OrderedRenderer.cs index da480df..56935f2 100644 --- a/encompass-cs/Renderers/OrderedRenderer.cs +++ b/encompass-cs/Renderers/OrderedRenderer.cs @@ -11,7 +11,8 @@ namespace Encompass internal void InternalRender(Entity entity) { - Render(entity, GetComponent(entity)); + ref readonly var component = ref GetComponent(entity); + Render(entity, component); } } } diff --git a/encompass-cs/WorldBuilder.cs b/encompass-cs/WorldBuilder.cs index 17eb320..68cb330 100644 --- a/encompass-cs/WorldBuilder.cs +++ b/encompass-cs/WorldBuilder.cs @@ -84,7 +84,7 @@ namespace Encompass /// /// Sets Component data for the specified Component Type on the specified Entity. /// - public void SetComponent(Entity entity, TComponent component) where TComponent : struct + public void SetComponent(Entity entity, in TComponent component) where TComponent : struct { RegisterComponentType(); _startingExistingComponentStore.Set(entity.ID, component);