add Manipulator, remove Spawner, remove Template
parent
cc158e460b
commit
f7d4fcdee7
|
@ -13,7 +13,6 @@ 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;
|
internal ComponentDepot TemplateComponentDepot => World.TemplateComponentDepot;
|
||||||
|
|
||||||
public EntityComponentReader(World world)
|
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;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace MoonTools.ECS
|
namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
public abstract class System : EntityComponentReader
|
public abstract class System : Manipulator
|
||||||
{
|
{
|
||||||
internal MessageDepot MessageDepot => World.MessageDepot;
|
internal MessageDepot MessageDepot => World.MessageDepot;
|
||||||
|
|
||||||
|
@ -11,25 +10,6 @@ namespace MoonTools.ECS
|
||||||
|
|
||||||
public abstract void Update(TimeSpan delta);
|
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
|
protected ReadOnlySpan<TMessage> ReadMessages<TMessage>() where TMessage : unmanaged
|
||||||
{
|
{
|
||||||
return MessageDepot.All<TMessage>();
|
return MessageDepot.All<TMessage>();
|
||||||
|
@ -60,39 +40,8 @@ namespace MoonTools.ECS
|
||||||
return MessageDepot.SomeWithEntity<TMessage>(entity.ID);
|
return MessageDepot.SomeWithEntity<TMessage>(entity.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Send<TMessage>(in TMessage message) where TMessage : unmanaged
|
protected void Send<TMessage>(in TMessage message) where TMessage : unmanaged => World.Send(message);
|
||||||
{
|
|
||||||
MessageDepot.Add(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void Send<TMessage>(in Entity entity, in TMessage message) where TMessage : unmanaged
|
protected void Send<TMessage>(in Entity entity, in TMessage message) where TMessage : unmanaged => World.Send(entity, message);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
66
src/World.cs
66
src/World.cs
|
@ -13,7 +13,6 @@ namespace MoonTools.ECS
|
||||||
internal readonly FilterStorage FilterStorage;
|
internal readonly FilterStorage FilterStorage;
|
||||||
public FilterBuilder FilterBuilder => new FilterBuilder(FilterStorage, ComponentTypeIndices);
|
public FilterBuilder FilterBuilder => new FilterBuilder(FilterStorage, ComponentTypeIndices);
|
||||||
|
|
||||||
internal readonly TemplateStorage TemplateStorage = new TemplateStorage();
|
|
||||||
internal readonly ComponentDepot TemplateComponentDepot;
|
internal readonly ComponentDepot TemplateComponentDepot;
|
||||||
|
|
||||||
public World()
|
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();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
EntityStorage.SetComponent(entity.ID, componentTypeIndex);
|
|
||||||
FilterStorage.Check(entity.ID, componentTypeIndex);
|
|
||||||
ComponentDepot.Set(entity.ID, componentTypeIndex, TemplateComponentDepot.UntypedGet(template.ID, componentTypeIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
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);
|
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)
|
public void Destroy(in Entity entity)
|
||||||
{
|
{
|
||||||
foreach (var componentTypeIndex in EntityStorage.ComponentTypeIndices(entity.ID))
|
foreach (var componentTypeIndex in EntityStorage.ComponentTypeIndices(entity.ID))
|
||||||
|
|
Loading…
Reference in New Issue