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)]
private void Register<TComponent>(int index) where TComponent : unmanaged
internal void Register<TComponent>(int index) where TComponent : unmanaged
{
if (index >= storages.Length)
{
@ -47,12 +47,11 @@ namespace MoonTools.ECS
return ref Lookup<TComponent>().Get(entityID);
}
#if DEBUG
public object Debug_Get(int entityID, int componentTypeIndex)
// used for debugging and template instantiation
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
{
@ -64,6 +63,11 @@ namespace MoonTools.ECS
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
{
return Lookup<TComponent>().FirstEntity();

View File

@ -6,14 +6,14 @@ namespace MoonTools.ECS
{
internal abstract class ComponentStorage
{
internal abstract void Set(int entityID, object component);
public abstract bool Remove(int entityID);
public abstract ComponentStorageState CreateState();
public abstract void Save(ComponentStorageState state);
public abstract void Load(ComponentStorageState state);
#if DEBUG
public abstract object Debug_Get(int entityID);
#endif
// used for debugging and template instantiation
internal abstract object UntypedGet(int entityID);
}
internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged
@ -33,6 +33,11 @@ namespace MoonTools.ECS
return ref components[entityIDToStorageIndex[entityID]];
}
internal override object UntypedGet(int entityID)
{
return components[entityIDToStorageIndex[entityID]];
}
public ref readonly TComponent GetFirst()
{
#if DEBUG
@ -64,6 +69,11 @@ namespace MoonTools.ECS
components[entityIDToStorageIndex[entityID]] = component;
}
internal override void Set(int entityID, object component)
{
Set(entityID, (TComponent) component);
}
// Returns true if the entity had this component.
public override bool Remove(int entityID)
{
@ -151,12 +161,5 @@ namespace MoonTools.ECS
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
{
#if DEBUG
private Dictionary<Type, Filter> singleComponentFilters = new Dictionary<Type, Filter>();
#endif
protected DebugSystem(World world) : base(world)
{
@ -21,7 +19,7 @@ namespace MoonTools.ECS
{
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 TypeIndices ComponentTypeIndices => World.ComponentTypeIndices;
internal TypeIndices RelationTypeIndices => World.RelationTypeIndices;
internal TemplateStorage TemplateStorage => World.TemplateStorage;
internal ComponentDepot TemplateComponentDepot => World.TemplateComponentDepot;
public EntityComponentReader(World world)
{

View File

@ -33,20 +33,20 @@ namespace MoonTools.ECS
}
// 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.
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)

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
{
return MessageDepot.All<TMessage>();

View File

@ -1,14 +1,29 @@
using System.Collections.Generic;
namespace MoonTools.ECS
{
public class TemplateStorage
{
private int nextID = 0;
private Dictionary<int, HashSet<int>> TemplateToComponentTypeIndices = new Dictionary<int, HashSet<int>>();
public Template Create()
{
TemplateToComponentTypeIndices.Add(nextID, new HashSet<int>());
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()
{
var id = nextID;

View File

@ -10,16 +10,16 @@
internal readonly RelationDepot RelationDepot;
internal readonly FilterStorage FilterStorage;
/*
internal readonly TemplateStorage TemplateStorage = new TemplateStorage();
internal readonly ComponentDepot TemplateComponentDepot = new ComponentDepot();
*/
internal readonly ComponentDepot TemplateComponentDepot;
public World()
{
ComponentDepot = new ComponentDepot(ComponentTypeIndices);
RelationDepot = new RelationDepot(RelationTypeIndices);
FilterStorage = new FilterStorage(EntityStorage, ComponentTypeIndices);
TemplateComponentDepot = new ComponentDepot(ComponentTypeIndices);
}
public Entity CreateEntity()
@ -37,22 +37,29 @@
ComponentDepot.Set<TComponent>(entity.ID, component);
}
/*
public Template CreateTemplate()
{
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);
}
*/
public Entity Instantiate(Template template)
// TODO: TEST ME!!!
public 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;
}