initial template system

filter_relations
cosmonaut 2022-12-05 17:46:18 -08:00
parent 7c6410275f
commit f045335881
8 changed files with 82 additions and 31 deletions

View File

@ -15,7 +15,7 @@ namespace MoonTools.ECS
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Register<TComponent>(int index) where TComponent : unmanaged internal void Register<TComponent>(int index) where TComponent : unmanaged
{ {
if (index >= storages.Length) if (index >= storages.Length)
{ {
@ -47,12 +47,11 @@ namespace MoonTools.ECS
return ref Lookup<TComponent>().Get(entityID); return ref Lookup<TComponent>().Get(entityID);
} }
#if DEBUG // used for debugging and template instantiation
public object Debug_Get(int entityID, int componentTypeIndex) internal object UntypedGet(int entityID, int componentTypeIndex)
{ {
return storages[componentTypeIndex].Debug_Get(entityID); return storages[componentTypeIndex].UntypedGet(entityID);
} }
#endif
public ref readonly TComponent GetFirst<TComponent>() where TComponent : unmanaged public ref readonly TComponent GetFirst<TComponent>() where TComponent : unmanaged
{ {
@ -64,6 +63,11 @@ namespace MoonTools.ECS
Lookup<TComponent>().Set(entityID, component); Lookup<TComponent>().Set(entityID, component);
} }
internal void Set(int entityID, int componentTypeIndex, object component)
{
storages[componentTypeIndex].Set(entityID, component);
}
public Entity GetSingletonEntity<TComponent>() where TComponent : unmanaged public Entity GetSingletonEntity<TComponent>() where TComponent : unmanaged
{ {
return Lookup<TComponent>().FirstEntity(); return Lookup<TComponent>().FirstEntity();

View File

@ -6,14 +6,14 @@ namespace MoonTools.ECS
{ {
internal abstract class ComponentStorage internal abstract class ComponentStorage
{ {
internal abstract void Set(int entityID, object component);
public abstract bool Remove(int entityID); public abstract bool Remove(int entityID);
public abstract ComponentStorageState CreateState(); public abstract ComponentStorageState CreateState();
public abstract void Save(ComponentStorageState state); public abstract void Save(ComponentStorageState state);
public abstract void Load(ComponentStorageState state); public abstract void Load(ComponentStorageState state);
#if DEBUG // used for debugging and template instantiation
public abstract object Debug_Get(int entityID); internal abstract object UntypedGet(int entityID);
#endif
} }
internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged
@ -33,6 +33,11 @@ namespace MoonTools.ECS
return ref components[entityIDToStorageIndex[entityID]]; return ref components[entityIDToStorageIndex[entityID]];
} }
internal override object UntypedGet(int entityID)
{
return components[entityIDToStorageIndex[entityID]];
}
public ref readonly TComponent GetFirst() public ref readonly TComponent GetFirst()
{ {
#if DEBUG #if DEBUG
@ -64,6 +69,11 @@ namespace MoonTools.ECS
components[entityIDToStorageIndex[entityID]] = component; components[entityIDToStorageIndex[entityID]] = component;
} }
internal override void Set(int entityID, object component)
{
Set(entityID, (TComponent) component);
}
// Returns true if the entity had this component. // Returns true if the entity had this component.
public override bool Remove(int entityID) public override bool Remove(int entityID)
{ {
@ -151,12 +161,5 @@ namespace MoonTools.ECS
nextID = state.Count; nextID = state.Count;
} }
#if DEBUG
public override object Debug_Get(int entityID)
{
return components[entityIDToStorageIndex[entityID]];
}
#endif
} }
} }

View File

@ -9,9 +9,7 @@ namespace MoonTools.ECS
{ {
public abstract class DebugSystem : System public abstract class DebugSystem : System
{ {
#if DEBUG
private Dictionary<Type, Filter> singleComponentFilters = new Dictionary<Type, Filter>(); private Dictionary<Type, Filter> singleComponentFilters = new Dictionary<Type, Filter>();
#endif
protected DebugSystem(World world) : base(world) protected DebugSystem(World world) : base(world)
{ {
@ -21,7 +19,7 @@ namespace MoonTools.ECS
{ {
foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID)) foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID))
{ {
yield return ComponentDepot.Debug_Get(entity.ID, typeIndex); yield return ComponentDepot.UntypedGet(entity.ID, typeIndex);
} }
} }

View File

@ -13,6 +13,8 @@ namespace MoonTools.ECS
internal FilterStorage FilterStorage => World.FilterStorage; internal FilterStorage FilterStorage => World.FilterStorage;
internal TypeIndices ComponentTypeIndices => World.ComponentTypeIndices; internal TypeIndices ComponentTypeIndices => World.ComponentTypeIndices;
internal TypeIndices RelationTypeIndices => World.RelationTypeIndices; internal TypeIndices RelationTypeIndices => World.RelationTypeIndices;
internal TemplateStorage TemplateStorage => World.TemplateStorage;
internal ComponentDepot TemplateComponentDepot => World.TemplateComponentDepot;
public EntityComponentReader(World world) public EntityComponentReader(World world)
{ {

View File

@ -33,20 +33,20 @@ namespace MoonTools.ECS
} }
// Returns true if the component is new. // Returns true if the component is new.
public bool SetComponent(int entityID, int storageIndex) public bool SetComponent(int entityID, int componentTypeIndex)
{ {
return EntityToComponentTypeIndices[entityID].Add(storageIndex); return EntityToComponentTypeIndices[entityID].Add(componentTypeIndex);
} }
public bool HasComponent(int entityID, int storageIndex) public bool HasComponent(int entityID, int componentTypeIndex)
{ {
return EntityToComponentTypeIndices[entityID].Contains(storageIndex); return EntityToComponentTypeIndices[entityID].Contains(componentTypeIndex);
} }
// Returns true if the component existed. // Returns true if the component existed.
public bool RemoveComponent(int entityID, int storageIndex) public bool RemoveComponent(int entityID, int componentTypeIndex)
{ {
return EntityToComponentTypeIndices[entityID].Remove(storageIndex); return EntityToComponentTypeIndices[entityID].Remove(componentTypeIndex);
} }
public void AddRelation(int entityID, int relationIndex) public void AddRelation(int entityID, int relationIndex)

View File

@ -42,6 +42,28 @@ namespace MoonTools.ECS
} }
} }
protected void Set<TComponent>(in Template template, in TComponent component) where TComponent : unmanaged
{
var componentTypeIndex = ComponentTypeIndices.GetIndex<TComponent>();
TemplateStorage.SetComponent(template.ID, componentTypeIndex);
TemplateComponentDepot.Set(template.ID, component);
ComponentDepot.Register<TComponent>(componentTypeIndex);
}
protected Entity Instantiate(in Template template)
{
var entity = EntityStorage.Create();
foreach (var componentTypeIndex in TemplateStorage.ComponentTypeIndices(template.ID))
{
EntityStorage.SetComponent(entity.ID, componentTypeIndex);
FilterStorage.Check(entity.ID, componentTypeIndex);
ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex));
}
return entity;
}
protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : unmanaged protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : unmanaged
{ {
return MessageDepot.All<TMessage>(); return MessageDepot.All<TMessage>();

View File

@ -1,14 +1,29 @@
using System.Collections.Generic;
namespace MoonTools.ECS namespace MoonTools.ECS
{ {
public class TemplateStorage public class TemplateStorage
{ {
private int nextID = 0; private int nextID = 0;
private Dictionary<int, HashSet<int>> TemplateToComponentTypeIndices = new Dictionary<int, HashSet<int>>();
public Template Create() public Template Create()
{ {
TemplateToComponentTypeIndices.Add(nextID, new HashSet<int>());
return new Template(NextID()); return new Template(NextID());
} }
public bool SetComponent(int templateID, int componentTypeIndex)
{
return TemplateToComponentTypeIndices[templateID].Add(componentTypeIndex);
}
public IEnumerable<int> ComponentTypeIndices(int templateID)
{
return TemplateToComponentTypeIndices[templateID];
}
private int NextID() private int NextID()
{ {
var id = nextID; var id = nextID;

View File

@ -10,16 +10,16 @@
internal readonly RelationDepot RelationDepot; internal readonly RelationDepot RelationDepot;
internal readonly FilterStorage FilterStorage; internal readonly FilterStorage FilterStorage;
/*
internal readonly TemplateStorage TemplateStorage = new TemplateStorage(); internal readonly TemplateStorage TemplateStorage = new TemplateStorage();
internal readonly ComponentDepot TemplateComponentDepot = new ComponentDepot(); internal readonly ComponentDepot TemplateComponentDepot;
*/
public World() public World()
{ {
ComponentDepot = new ComponentDepot(ComponentTypeIndices); ComponentDepot = new ComponentDepot(ComponentTypeIndices);
RelationDepot = new RelationDepot(RelationTypeIndices); RelationDepot = new RelationDepot(RelationTypeIndices);
FilterStorage = new FilterStorage(EntityStorage, ComponentTypeIndices); FilterStorage = new FilterStorage(EntityStorage, ComponentTypeIndices);
TemplateComponentDepot = new ComponentDepot(ComponentTypeIndices);
} }
public Entity CreateEntity() public Entity CreateEntity()
@ -37,22 +37,29 @@
ComponentDepot.Set<TComponent>(entity.ID, component); ComponentDepot.Set<TComponent>(entity.ID, component);
} }
/*
public Template CreateTemplate() public Template CreateTemplate()
{ {
return TemplateStorage.Create(); return TemplateStorage.Create();
} }
public void Set<TComponent>(Template template, in TComponent component) where TComponent : unmanaged public void Set<TComponent>(in Template template, in TComponent component) where TComponent : unmanaged
{ {
TemplateStorage.SetComponent(template.ID, ComponentTypeIndices.GetIndex<TComponent>());
TemplateComponentDepot.Set(template.ID, component); TemplateComponentDepot.Set(template.ID, component);
} }
*/
public Entity Instantiate(Template template) // TODO: TEST ME!!!
public Entity Instantiate(in Template template)
{ {
var entity = EntityStorage.Create(); var entity = EntityStorage.Create();
foreach (var componentTypeIndex in TemplateStorage.ComponentTypeIndices(template.ID))
{
EntityStorage.SetComponent(entity.ID, componentTypeIndex);
FilterStorage.Check(entity.ID, componentTypeIndex);
ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex));
}
return entity; return entity;
} }