contiguous component storage
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
e4d4df9fdd
commit
61845d752a
|
@ -15,17 +15,18 @@ namespace Encompass
|
||||||
|
|
||||||
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct
|
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct
|
||||||
{
|
{
|
||||||
private readonly Dictionary<int, int> _indices = new Dictionary<int, int>(512);
|
private int _nextID = 0;
|
||||||
private readonly Dictionary<int, int> _priorities = new Dictionary<int, int>(512);
|
private readonly Dictionary<int, int> _entityIDToStorageIndex = new Dictionary<int, int>(128);
|
||||||
private readonly TComponent[] _components = new TComponent[512]; // TODO: allow specify size
|
private readonly Dictionary<int, int> _storageIndexToEntityID = new Dictionary<int, int>(128);
|
||||||
private readonly IDManager _idManager = new IDManager();
|
private readonly Dictionary<int, int> _priorities = new Dictionary<int, int>(128);
|
||||||
|
private TComponent[] _components = new TComponent[128];
|
||||||
|
|
||||||
public override int Count { get => _indices.Count; }
|
public override int Count { get => _entityIDToStorageIndex.Count; }
|
||||||
|
|
||||||
public ref 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); }
|
if (!_entityIDToStorageIndex.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]];
|
return ref _components[_entityIDToStorageIndex[entityID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(int entityID, in TComponent component)
|
public void Set(int entityID, in TComponent component)
|
||||||
|
@ -47,12 +48,18 @@ namespace Encompass
|
||||||
|
|
||||||
private void InternalSet(int entityID, in TComponent component)
|
private void InternalSet(int entityID, in TComponent component)
|
||||||
{
|
{
|
||||||
if (!_indices.ContainsKey(entityID))
|
if (!_entityIDToStorageIndex.ContainsKey(entityID))
|
||||||
{
|
{
|
||||||
_indices[entityID] = _idManager.NextID();
|
var index = _nextID++;
|
||||||
|
if (index >= _components.Length)
|
||||||
|
{
|
||||||
|
System.Array.Resize(ref _components, _components.Length * 2);
|
||||||
|
}
|
||||||
|
_entityIDToStorageIndex[entityID] = index;
|
||||||
|
_storageIndexToEntityID[index] = entityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
_components[_indices[entityID]] = component;
|
_components[_entityIDToStorageIndex[entityID]] = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Remove(int entityID, int priority)
|
public override bool Remove(int entityID, int priority)
|
||||||
|
@ -69,26 +76,40 @@ namespace Encompass
|
||||||
|
|
||||||
public override void ForceRemove(int entityID)
|
public override void ForceRemove(int entityID)
|
||||||
{
|
{
|
||||||
if (_indices.ContainsKey(entityID))
|
if (_entityIDToStorageIndex.ContainsKey(entityID))
|
||||||
{
|
{
|
||||||
_idManager.Free(_indices[entityID]);
|
var storageIndex = _entityIDToStorageIndex[entityID];
|
||||||
_indices.Remove(entityID);
|
_entityIDToStorageIndex.Remove(entityID);
|
||||||
|
_storageIndexToEntityID.Remove(storageIndex);
|
||||||
_priorities.Remove(entityID);
|
_priorities.Remove(entityID);
|
||||||
|
|
||||||
|
// move a component into the hole to maintain contiguous memory
|
||||||
|
if (_nextID > 1 && storageIndex != _nextID - 1)
|
||||||
|
{
|
||||||
|
var lastStorageIndex = _nextID - 1;
|
||||||
|
var lastEntityID = _storageIndexToEntityID[lastStorageIndex];
|
||||||
|
_storageIndexToEntityID.Remove(lastStorageIndex);
|
||||||
|
|
||||||
|
_entityIDToStorageIndex[lastEntityID] = storageIndex;
|
||||||
|
_storageIndexToEntityID[storageIndex] = lastEntityID;
|
||||||
|
_components[storageIndex] = _components[lastStorageIndex];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_nextID--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Has(int entityID)
|
public override bool Has(int entityID)
|
||||||
{
|
{
|
||||||
return _indices.ContainsKey(entityID);
|
return _entityIDToStorageIndex.ContainsKey(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Clear()
|
public override void Clear()
|
||||||
{
|
{
|
||||||
foreach (var mappedID in _indices.Values)
|
_nextID = 0;
|
||||||
{
|
_entityIDToStorageIndex.Clear();
|
||||||
_idManager.Free(mappedID);
|
_storageIndexToEntityID.Clear();
|
||||||
}
|
|
||||||
_indices.Clear();
|
|
||||||
_priorities.Clear();
|
_priorities.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +120,7 @@ namespace Encompass
|
||||||
|
|
||||||
public IEnumerable<(TComponent, int)> All()
|
public IEnumerable<(TComponent, int)> All()
|
||||||
{
|
{
|
||||||
foreach (var kvp in _indices)
|
foreach (var kvp in _entityIDToStorageIndex)
|
||||||
{
|
{
|
||||||
yield return (_components[kvp.Value], kvp.Key);
|
yield return (_components[kvp.Value], kvp.Key);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue