initial template system
parent
7c6410275f
commit
f045335881
|
@ -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();
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
21
src/World.cs
21
src/World.cs
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue