109 lines
3.4 KiB
C#
109 lines
3.4 KiB
C#
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace Encompass
|
|
{
|
|
internal abstract class TypedComponentStore
|
|
{
|
|
public abstract int Count { get; }
|
|
public abstract bool Has(int entity);
|
|
public abstract bool Remove(int entity, int priority);
|
|
public abstract void ForceRemove(int entity);
|
|
public abstract void Clear();
|
|
public abstract void ClearPriorities();
|
|
}
|
|
|
|
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : struct
|
|
{
|
|
private readonly Dictionary<int, int> _indices = new Dictionary<int, int>(512);
|
|
private readonly Dictionary<int, int> _priorities = new Dictionary<int, int>(512);
|
|
private readonly TComponent[] _components = new TComponent[512]; // TODO: allow specify size
|
|
private readonly IDManager _idManager = new IDManager();
|
|
|
|
public override int Count { get => _indices.Count; }
|
|
|
|
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 void Set(int entityID, in TComponent component)
|
|
{
|
|
InternalSet(entityID, component);
|
|
}
|
|
|
|
public bool Set(int entityID, in TComponent component, int priority)
|
|
{
|
|
if (!_priorities.ContainsKey(entityID) || priority <= _priorities[entityID]) // if priorities are equal that means it's the same engine
|
|
{
|
|
InternalSet(entityID, component);
|
|
_priorities[entityID] = priority;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void InternalSet(int entityID, in TComponent component)
|
|
{
|
|
if (!_indices.ContainsKey(entityID))
|
|
{
|
|
_indices[entityID] = _idManager.NextID();
|
|
}
|
|
|
|
_components[_indices[entityID]] = component;
|
|
}
|
|
|
|
public override bool Remove(int entityID, int priority)
|
|
{
|
|
if (!_priorities.ContainsKey(entityID) || priority <= _priorities[entityID]) // if priorities are equal that means it's the same engine
|
|
{
|
|
_priorities[entityID] = priority;
|
|
ForceRemove(entityID);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override void ForceRemove(int entityID)
|
|
{
|
|
if (_indices.ContainsKey(entityID))
|
|
{
|
|
_idManager.Free(_indices[entityID]);
|
|
_indices.Remove(entityID);
|
|
_priorities.Remove(entityID);
|
|
}
|
|
}
|
|
|
|
public override bool Has(int entityID)
|
|
{
|
|
return _indices.ContainsKey(entityID);
|
|
}
|
|
|
|
public override void Clear()
|
|
{
|
|
foreach (var mappedID in _indices.Values)
|
|
{
|
|
_idManager.Free(mappedID);
|
|
}
|
|
_indices.Clear();
|
|
_priorities.Clear();
|
|
}
|
|
|
|
public override void ClearPriorities()
|
|
{
|
|
_priorities.Clear();
|
|
}
|
|
|
|
public IEnumerable<(TComponent, int)> All()
|
|
{
|
|
foreach (var kvp in _indices)
|
|
{
|
|
yield return (_components[kvp.Value], kvp.Key);
|
|
}
|
|
}
|
|
}
|
|
}
|