add Manipulator, remove Spawner, remove Template
parent
cc158e460b
commit
f7d4fcdee7
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
64
src/World.cs
64
src/World.cs
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue