encompass-cs/encompass-cs/Collections/ComponentStore.cs

155 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace Encompass
{
internal class ComponentStore
{
interface IComponentStore
{
T All<T>() where T : 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<TComponent> : TypedComponentStore where TComponent : struct, IComponent
{
private readonly Dictionary<Entity, TComponent> store = new Dictionary<Entity, TComponent>();
private readonly Dictionary<Entity, int> priorities = new Dictionary<Entity, int>();
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<T> All<T>()
// {
// return store.Values.Cast<T>();
// }
public override bool Remove(Entity entity)
{
throw new NotImplementedException();
}
}
private readonly Dictionary<Type, TypedComponentStore> Stores = new Dictionary<Type, TypedComponentStore>();
public void RegisterComponentType<TComponent>() where TComponent : struct, IComponent
{
if (!Stores.ContainsKey(typeof(TComponent)))
{
var store = new TypedComponentStore<TComponent>();
Stores.Add(typeof(TComponent), store);
}
}
private TypedComponentStore<TComponent> Lookup<TComponent>() where TComponent : struct, IComponent
{
return Stores[typeof(TComponent)] as TypedComponentStore<TComponent>;
}
public bool Has<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return Lookup<TComponent>().Has(entity);
}
public bool Has(Type type, Entity entity)
{
return Stores[type].Has(entity);
}
public TComponent Get<TComponent>(Entity entity) where TComponent : struct, IComponent
{
return Lookup<TComponent>().Get(entity);
}
public void Set<TComponent>(Entity entity, TComponent component) where TComponent : struct, IComponent
{
Lookup<TComponent>().Set(entity, component);
}
public void Set<TComponent>(Entity entity, TComponent component, int priority) where TComponent : struct, IComponent
{
Lookup<TComponent>().Set(entity, component, priority);
}
public void Remove<TComponent>(Entity entity) where TComponent : struct, IComponent
{
Lookup<TComponent>().Remove(entity);
}
public void Remove(Entity entity)
{
foreach (var entry in Stores.Values)
{
entry.Remove(entity);
}
}
public bool Any<TComponent>() where TComponent : struct, IComponent
{
return Lookup<TComponent>().Count > 0;
}
// public IEnumerable<TComponent> All<TComponent>() where TComponent : struct, IComponent
// {
// return Lookup<TComponent>().All<TComponent>();
// }
public IEnumerable<(Entity, TComponent)> All<TComponent>() where TComponent : struct, IComponent
{
return Lookup<TComponent>().All();
}
public void Clear<TComponent>() where TComponent : struct, IComponent
{
Lookup<TComponent>().Clear();
}
public void ClearAll()
{
foreach (var store in Stores.Values)
{
store.Clear();
}
}
}
}