add compatibility structures
parent
3d2261f739
commit
c7f7d8c362
|
@ -0,0 +1,29 @@
|
|||
namespace MoonTools.ECS.Rev2.Compatibility;
|
||||
|
||||
public abstract class EntityComponentReader
|
||||
{
|
||||
protected World World;
|
||||
|
||||
protected EntityComponentReader(World world)
|
||||
{
|
||||
World = world;
|
||||
}
|
||||
|
||||
protected bool Has<T>(in Id entityId) where T : unmanaged => World.Has<T>(entityId);
|
||||
protected bool Some<T>() where T : unmanaged => World.Some<T>();
|
||||
protected ref T Get<T>(in Id entityId) where T : unmanaged => ref World.Get<T>(entityId);
|
||||
protected ref T GetSingleton<T>() where T : unmanaged => ref World.GetSingleton<T>();
|
||||
protected Id GetSingletonEntity<T>() where T : unmanaged => World.GetSingletonEntity<T>();
|
||||
|
||||
protected ReverseSpanEnumerator<(Id, Id)> Relations<T>() where T : unmanaged => World.Relations<T>();
|
||||
protected bool Related<T>(in Id entityA, in Id entityB) where T : unmanaged => World.Related<T>(entityA, entityB);
|
||||
protected T GetRelationData<T>(in Id entityA, in Id entityB) where T : unmanaged => World.GetRelationData<T>(entityA, entityB);
|
||||
|
||||
protected ReverseSpanEnumerator<Id> OutRelations<T>(in Id entity) where T : unmanaged => World.OutRelations<T>(entity);
|
||||
protected Id OutRelationSingleton<T>(in Id entity) where T : unmanaged => World.OutRelationSingleton<T>(entity);
|
||||
protected bool HasOutRelation<T>(in Id entity) where T : unmanaged => World.HasOutRelation<T>(entity);
|
||||
|
||||
protected ReverseSpanEnumerator<Id> InRelations<T>(in Id entity) where T : unmanaged => World.InRelations<T>(entity);
|
||||
protected Id InRelationSingleton<T>(in Id entity) where T : unmanaged => World.InRelationSingleton<T>(entity);
|
||||
protected bool HasInRelation<T>(in Id entity) where T : unmanaged => World.HasInRelation<T>(entity);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace MoonTools.ECS.Rev2.Compatibility;
|
||||
|
||||
public class Manipulator : EntityComponentReader
|
||||
{
|
||||
public Manipulator(World world) : base(world) { }
|
||||
|
||||
protected void Set<TComponent>(in Id entity, in TComponent component) where TComponent : unmanaged => World.Set<TComponent>(entity, component);
|
||||
protected void Remove<TComponent>(in Id entity) where TComponent : unmanaged => World.Remove<TComponent>(entity);
|
||||
|
||||
protected void Unrelate<TRelationKind>(in Id entityA, in Id entityB) where TRelationKind : unmanaged => World.Unrelate<TRelationKind>(entityA, entityB);
|
||||
protected void UnrelateAll<TRelationKind>(in Id entity) where TRelationKind : unmanaged => World.UnrelateAll<TRelationKind>(entity);
|
||||
protected void Destroy(in Id entity) => World.Destroy(entity);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
namespace MoonTools.ECS.Rev2.Compatibility;
|
||||
|
||||
public class Renderer : EntityComponentReader
|
||||
{
|
||||
public Renderer(World world) : base(world) { }
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace MoonTools.ECS.Rev2.Compatibility;
|
||||
|
||||
public class System : Manipulator
|
||||
{
|
||||
public System(World world) : base(world) { }
|
||||
|
||||
protected ReadOnlySpan<T> ReadMessages<T>() where T : unmanaged => World.ReadMessages<T>();
|
||||
protected T ReadMessage<T>() where T : unmanaged => World.ReadMessage<T>();
|
||||
protected bool SomeMessage<T>() where T : unmanaged => World.SomeMessage<T>();
|
||||
protected void Send<T>(T message) where T : unmanaged => World.Send(message);
|
||||
}
|
|
@ -24,15 +24,13 @@ public ref struct FilterBuilder
|
|||
|
||||
public FilterBuilder Include<T>() where T : unmanaged
|
||||
{
|
||||
World.GetTypeId<T>();
|
||||
Included.Add(World.TypeToId[typeof(T)]);
|
||||
Included.Add(World.GetTypeId<T>());
|
||||
return new FilterBuilder(World, Included, Excluded);
|
||||
}
|
||||
|
||||
public FilterBuilder Exclude<T>() where T : unmanaged
|
||||
{
|
||||
World.GetTypeId<T>();
|
||||
Excluded.Add(World.TypeToId[typeof(T)]);
|
||||
Excluded.Add(World.GetTypeId<T>());
|
||||
return new FilterBuilder(World, Included, Excluded);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ internal class RelationStorage
|
|||
return (aEmpty, bEmpty);
|
||||
}
|
||||
|
||||
public void RemoveEntity(Id entity)
|
||||
public void RemoveEntity(in Id entity)
|
||||
{
|
||||
if (outRelations.TryGetValue(entity, out var entityOutRelations))
|
||||
{
|
||||
|
|
|
@ -18,9 +18,6 @@ public class World : IDisposable
|
|||
// Going from EntityId to Archetype and storage row
|
||||
internal Dictionary<Id, Record> EntityIndex = new Dictionary<Id, Record>();
|
||||
|
||||
// Going from ComponentId to Archetype list
|
||||
Dictionary<Id, List<Archetype>> ComponentIndex = new Dictionary<Id, List<Archetype>>();
|
||||
|
||||
// Relation Storages
|
||||
internal Dictionary<Id, RelationStorage> RelationIndex =
|
||||
new Dictionary<Id, RelationStorage>();
|
||||
|
@ -33,6 +30,9 @@ public class World : IDisposable
|
|||
private Dictionary<Id, MessageStorage> MessageIndex =
|
||||
new Dictionary<Id, MessageStorage>();
|
||||
|
||||
// Filters with a single Include type for Singleton/Some implementation
|
||||
private Dictionary<Id, Filter> SingleTypeFilters = new Dictionary<Id, Filter>();
|
||||
|
||||
// ID Management
|
||||
// FIXME: Entity and Type Ids should be separated
|
||||
internal IdAssigner IdAssigner = new IdAssigner();
|
||||
|
@ -60,7 +60,6 @@ public class World : IDisposable
|
|||
for (int i = 0; i < signature.Count; i += 1)
|
||||
{
|
||||
var componentId = signature[i];
|
||||
ComponentIndex[componentId].Add(archetype);
|
||||
archetype.ComponentToColumnIndex.Add(componentId, i);
|
||||
archetype.ComponentColumns[i] = new NativeArray(ElementSizes[componentId]);
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ public class World : IDisposable
|
|||
return archetype;
|
||||
}
|
||||
|
||||
public Id CreateEntity()
|
||||
public Id CreateEntity(string tag = "")
|
||||
{
|
||||
var entityId = IdAssigner.Assign();
|
||||
EntityIndex.Add(entityId, new Record(EmptyArchetype, EmptyArchetype.Count));
|
||||
|
@ -98,9 +97,9 @@ public class World : IDisposable
|
|||
private void TryRegisterComponentId<T>() where T : unmanaged
|
||||
{
|
||||
var typeId = GetTypeId<T>();
|
||||
if (!ComponentIndex.ContainsKey(typeId))
|
||||
if (!SingleTypeFilters.ContainsKey(typeId))
|
||||
{
|
||||
ComponentIndex.Add(typeId, new List<Archetype>());
|
||||
SingleTypeFilters.Add(typeId, FilterBuilder.Include<T>().Build());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +183,12 @@ public class World : IDisposable
|
|||
return record.Archetype.ComponentToColumnIndex.ContainsKey(componentId);
|
||||
}
|
||||
|
||||
public bool Some<T>() where T : unmanaged
|
||||
{
|
||||
var componentTypeId = GetComponentId<T>();
|
||||
return SingleTypeFilters[componentTypeId].Count > 0;
|
||||
}
|
||||
|
||||
// will throw if non-existent
|
||||
public unsafe ref T Get<T>(Id entityId) where T : unmanaged
|
||||
{
|
||||
|
@ -196,6 +201,37 @@ public class World : IDisposable
|
|||
return ref ((T*) column.Elements)[record.Row];
|
||||
}
|
||||
|
||||
public ref T GetSingleton<T>() where T : unmanaged
|
||||
{
|
||||
var componentId = GetComponentId<T>();
|
||||
|
||||
foreach (var archetype in SingleTypeFilters[componentId].Archetypes)
|
||||
{
|
||||
if (archetype.Count > 0)
|
||||
{
|
||||
var columnIndex = archetype.ComponentToColumnIndex[componentId];
|
||||
return ref archetype.ComponentColumns[columnIndex].Get<T>(0);
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("No component of this type exists!");
|
||||
}
|
||||
|
||||
public Id GetSingletonEntity<T>() where T : unmanaged
|
||||
{
|
||||
var componentId = GetComponentId<T>();
|
||||
|
||||
foreach (var archetype in SingleTypeFilters[componentId].Archetypes)
|
||||
{
|
||||
if (archetype.Count > 0)
|
||||
{
|
||||
return archetype.RowToEntity[0];
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException("No entity with this component type exists!");
|
||||
}
|
||||
|
||||
public unsafe void Set<T>(in Id entityId, in T component) where T : unmanaged
|
||||
{
|
||||
TryRegisterComponentId<T>();
|
||||
|
@ -301,6 +337,12 @@ public class World : IDisposable
|
|||
relationStorage.Remove(entityA, entityB);
|
||||
}
|
||||
|
||||
public void UnrelateAll<T>(in Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
relationStorage.RemoveEntity(entity);
|
||||
}
|
||||
|
||||
public bool Related<T>(in Id entityA, in Id entityB) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
|
@ -325,12 +367,36 @@ public class World : IDisposable
|
|||
return relationStorage.OutRelations(entity);
|
||||
}
|
||||
|
||||
public Id OutRelationSingleton<T>(in Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
return relationStorage.OutFirst(entity);
|
||||
}
|
||||
|
||||
public bool HasOutRelation<T>(in Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
return relationStorage.HasOutRelation(entity);
|
||||
}
|
||||
|
||||
public ReverseSpanEnumerator<Id> InRelations<T>(Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
return relationStorage.InRelations(entity);
|
||||
}
|
||||
|
||||
public Id InRelationSingleton<T>(in Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
return relationStorage.InFirst(entity);
|
||||
}
|
||||
|
||||
public bool HasInRelation<T>(in Id entity) where T : unmanaged
|
||||
{
|
||||
var relationStorage = GetRelationStorage<T>();
|
||||
return relationStorage.HasInRelation(entity);
|
||||
}
|
||||
|
||||
private bool Has(Id entityId, Id typeId)
|
||||
{
|
||||
var record = EntityIndex[entityId];
|
||||
|
|
Loading…
Reference in New Issue