add Manipulator, remove Spawner, remove Template

pull/4/head
cosmonaut 2023-05-24 12:46:27 -07:00
parent cc158e460b
commit f7d4fcdee7
7 changed files with 56 additions and 143 deletions

View File

@ -13,7 +13,6 @@ 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)

17
src/Manipulator.cs Normal file
View File

@ -0,0 +1,17 @@
namespace MoonTools.ECS
{
public abstract class Manipulator : EntityComponentReader
{
public Manipulator(World world) : base(world)
{
}
protected Entity CreateEntity() => World.CreateEntity();
protected void Set<TComponent>(in Entity entity, in TComponent component) where TComponent : unmanaged => World.Set<TComponent>(entity, component);
protected void Remove<TComponent>(in Entity entity) where TComponent : unmanaged => World.Remove<TComponent>(entity);
protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged => World.Relate(entityA, entityB, relationData);
protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged => World.Unrelate<TRelationKind>(entityA, entityB);
protected void UnrelateAll<TRelationKind>(in Entity entity) where TRelationKind : unmanaged => World.UnrelateAll<TRelationKind>(entity);
protected void Destroy(in Entity entity) => World.Destroy(entity);
}
}

View File

@ -1,13 +0,0 @@
namespace MoonTools.ECS
{
public abstract class Spawner : EntityComponentReader
{
public Spawner(World world) : base(world)
{
}
protected Entity CreateEntity() => World.CreateEntity();
protected void Set<TComponent>(in Entity entity, in TComponent component) where TComponent : unmanaged => World.Set<TComponent>(entity, component);
protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged => World.Relate(entityA, entityB, relationData);
}
}

View File

@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
namespace MoonTools.ECS
{
public abstract class System : EntityComponentReader
public abstract class System : Manipulator
{
internal MessageDepot MessageDepot => World.MessageDepot;
@ -11,25 +10,6 @@ namespace MoonTools.ECS
public abstract void Update(TimeSpan delta);
protected Entity CreateEntity() => World.CreateEntity();
protected void Set<TComponent>(in Entity entity, in TComponent component) where TComponent : unmanaged => World.Set<TComponent>(entity, component);
protected void Remove<TComponent>(in Entity entity) where TComponent : unmanaged
{
if (EntityStorage.RemoveComponent(entity.ID, ComponentTypeIndices.GetIndex<TComponent>()))
{
// Run filter storage update first so that the entity state is still valid in the remove callback.
FilterStorage.Check<TComponent>(entity.ID);
ComponentDepot.Remove<TComponent>(entity.ID);
}
}
protected void Set<TComponent>(in Template template, in TComponent component) where TComponent : unmanaged => World.Set<TComponent>(template, component);
// This feature is EXPERIMENTAL. USe at your own risk!!
protected Entity Instantiate(in Template template) => World.Instantiate(template);
protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : unmanaged
{
return MessageDepot.All<TMessage>();
@ -60,39 +40,8 @@ namespace MoonTools.ECS
return MessageDepot.SomeWithEntity<TMessage>(entity.ID);
}
protected void Send<TMessage>(in TMessage message) where TMessage : unmanaged
{
MessageDepot.Add(message);
}
protected void Send<TMessage>(in TMessage message) where TMessage : unmanaged => World.Send(message);
protected void Send<TMessage>(in Entity entity, in TMessage message) where TMessage : unmanaged
{
MessageDepot.Add(entity.ID, message);
}
protected void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged => World.Relate(entityA, entityB, relationData);
protected void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
{
var (aEmpty, bEmpty) = RelationDepot.Remove<TRelationKind>(entityA, entityB);
if (aEmpty)
{
EntityStorage.RemoveRelation(entityA.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
if (bEmpty)
{
EntityStorage.RemoveRelation(entityB.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
}
protected void UnrelateAll<TRelationKind>(in Entity entity) where TRelationKind : unmanaged
{
RelationDepot.UnrelateAll<TRelationKind>(entity.ID);
EntityStorage.RemoveRelation(entity.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
protected void Destroy(in Entity entity) => World.Destroy(entity);
protected void Send<TMessage>(in Entity entity, in TMessage message) where TMessage : unmanaged => World.Send(entity, message);
}
}

View File

@ -1,13 +0,0 @@
namespace MoonTools.ECS
{
// This feature is EXPERIMENTAL. Use at your own risk!!
public struct Template
{
public int ID { get; }
internal Template(int id)
{
ID = id;
}
}
}

View File

@ -1,34 +0,0 @@
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 HashSet<int> ComponentTypeIndices(int templateID)
{
return TemplateToComponentTypeIndices[templateID];
}
private int NextID()
{
var id = nextID;
nextID += 1;
return id;
}
}
}

View File

@ -13,7 +13,6 @@ namespace MoonTools.ECS
internal readonly FilterStorage FilterStorage;
public FilterBuilder FilterBuilder => new FilterBuilder(FilterStorage, ComponentTypeIndices);
internal readonly TemplateStorage TemplateStorage = new TemplateStorage();
internal readonly ComponentDepot TemplateComponentDepot;
public World()
@ -46,36 +45,14 @@ namespace MoonTools.ECS
}
}
public Template CreateTemplate()
public void Remove<TComponent>(in Entity entity) where TComponent : unmanaged
{
return TemplateStorage.Create();
}
public 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);
}
public unsafe Entity Instantiate(in Template template)
{
var entity = EntityStorage.Create();
foreach (var componentTypeIndex in TemplateStorage.ComponentTypeIndices(template.ID))
if (EntityStorage.RemoveComponent(entity.ID, ComponentTypeIndices.GetIndex<TComponent>()))
{
EntityStorage.SetComponent(entity.ID, componentTypeIndex);
FilterStorage.Check(entity.ID, componentTypeIndex);
ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex));
// Run filter storage update first so that the entity state is still valid in the remove callback.
FilterStorage.Check<TComponent>(entity.ID);
ComponentDepot.Remove<TComponent>(entity.ID);
}
return entity;
}
public void Send<TMessage>(in TMessage message) where TMessage : unmanaged
{
MessageDepot.Add(message);
}
public void Relate<TRelationKind>(in Entity entityA, in Entity entityB, TRelationKind relationData) where TRelationKind : unmanaged
@ -86,6 +63,37 @@ namespace MoonTools.ECS
EntityStorage.AddRelationKind(entityB.ID, relationTypeIndex);
}
public void Unrelate<TRelationKind>(in Entity entityA, in Entity entityB) where TRelationKind : unmanaged
{
var (aEmpty, bEmpty) = RelationDepot.Remove<TRelationKind>(entityA, entityB);
if (aEmpty)
{
EntityStorage.RemoveRelation(entityA.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
if (bEmpty)
{
EntityStorage.RemoveRelation(entityB.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
}
public void UnrelateAll<TRelationKind>(in Entity entity) where TRelationKind : unmanaged
{
RelationDepot.UnrelateAll<TRelationKind>(entity.ID);
EntityStorage.RemoveRelation(entity.ID, RelationTypeIndices.GetIndex<TRelationKind>());
}
public void Send<TMessage>(in TMessage message) where TMessage : unmanaged
{
MessageDepot.Add(message);
}
public void Send<TMessage>(in Entity entity, in TMessage message) where TMessage : unmanaged
{
MessageDepot.Add(entity.ID, message);
}
public void Destroy(in Entity entity)
{
foreach (var componentTypeIndex in EntityStorage.ComponentTypeIndices(entity.ID))