using System.Runtime.CompilerServices;
namespace OECS;
///
/// Registry of all component sparse sets, keyed by component type.
/// Provides typed generic accessors that delegate to the underlying
/// instances.
///
internal class ComponentStore
{
private readonly Dictionary _sets = new();
///
/// Gets or creates the sparse set for component type .
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private SparseSet GetSet() where T : struct
{
var type = typeof(T);
if (!_sets.TryGetValue(type, out var set))
{
var newSet = new SparseSet();
_sets[type] = newSet;
return newSet;
}
return (SparseSet)set;
}
///
/// Gets the sparse set for component type if it exists.
///
private SparseSet? GetSetIfExists() where T : struct
{
if (_sets.TryGetValue(typeof(T), out var set))
return (SparseSet)set;
return null;
}
///
/// Returns all registered component types.
///
public IEnumerable ComponentTypes => _sets.Keys;
public void Add(Entity entity, T component) where T : struct
{
GetSet().Add(entity, component);
}
public void Remove(Entity entity) where T : struct
{
GetSetIfExists()?.Remove(entity);
}
///
/// Removes the component of the given type from the entity.
/// No-op if the entity does not have the component or the type is not registered.
/// Used for cascading relationship removal during entity destruction.
///
public void Remove(Entity entity, Type componentType)
{
GetSet(componentType)?.Remove(entity);
}
public ref T Get(Entity entity) where T : struct
{
return ref GetSet().Get(entity);
}
public bool Has(Entity entity) where T : struct
{
return GetSetIfExists()?.Contains(entity) ?? false;
}
///
/// Tries to get the component value for the given entity.
/// Returns true if the component exists, with the value copied to .
///
public bool TryGet(Entity entity, out T value) where T : struct
{
var set = GetSetIfExists();
if (set != null && set.Contains(entity))
{
value = set.Get(entity);
return true;
}
value = default;
return false;
}
///
/// Removes all components for the given entity across all component types.
///
public void RemoveAll(Entity entity)
{
foreach (var set in _sets.Values)
{
set.Remove(entity);
}
}
///
/// Returns the sparse set for a given type, or null if not registered.
/// Used by query execution to probe sets by Type.
///
public ISparseSet? GetSet(Type componentType)
{
_sets.TryGetValue(componentType, out var set);
return set;
}
}