more untyped storage granularity
parent
9bc6822f38
commit
8d1274cba0
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace MoonTools.ECS
|
namespace MoonTools.ECS
|
||||||
|
@ -57,8 +58,6 @@ namespace MoonTools.ECS
|
||||||
Lookup<TComponent>().Set(entityID, component);
|
Lookup<TComponent>().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();
|
||||||
|
@ -92,14 +91,12 @@ namespace MoonTools.ECS
|
||||||
|
|
||||||
// these methods used to implement snapshots, templates, and debugging
|
// these methods used to implement snapshots, templates, and debugging
|
||||||
|
|
||||||
// FIXME: use unsafe pointers instead of object
|
internal unsafe void* UntypedGet(int entityID, int componentTypeIndex)
|
||||||
internal object UntypedGet(int entityID, int componentTypeIndex)
|
|
||||||
{
|
{
|
||||||
return storages[componentTypeIndex].UntypedGet(entityID);
|
return storages[componentTypeIndex].UntypedGet(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: use unsafe pointers instead of object
|
internal unsafe void Set(int entityID, int componentTypeIndex, void* component)
|
||||||
internal void Set(int entityID, int componentTypeIndex, object component)
|
|
||||||
{
|
{
|
||||||
storages[componentTypeIndex].Set(entityID, component);
|
storages[componentTypeIndex].Set(entityID, component);
|
||||||
}
|
}
|
||||||
|
@ -114,5 +111,19 @@ namespace MoonTools.ECS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this method is used to iterate components of an entity, only for use with a debug inspector
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
public object Debug_Get(int entityID, int componentTypeIndex)
|
||||||
|
{
|
||||||
|
return storages[componentTypeIndex].Debug_Get(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<int> Debug_GetEntityIDs(int componentTypeIndex)
|
||||||
|
{
|
||||||
|
return storages[componentTypeIndex].Debug_GetEntityIDs();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace MoonTools.ECS
|
namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
internal abstract class ComponentStorage
|
internal abstract class ComponentStorage
|
||||||
{
|
{
|
||||||
internal abstract void Set(int entityID, object component);
|
internal abstract unsafe void Set(int entityID, void* component);
|
||||||
public abstract bool Remove(int entityID);
|
public abstract bool Remove(int entityID);
|
||||||
public abstract void Clear();
|
public abstract void Clear();
|
||||||
|
|
||||||
// used for debugging and template instantiation
|
// used for debugging and template instantiation
|
||||||
internal abstract object UntypedGet(int entityID);
|
internal abstract unsafe void* UntypedGet(int entityID);
|
||||||
// used to create correctly typed storage on snapshot
|
// used to create correctly typed storage on snapshot
|
||||||
public abstract ComponentStorage CreateStorage();
|
public abstract ComponentStorage CreateStorage();
|
||||||
|
#if DEBUG
|
||||||
|
internal abstract object Debug_Get(int entityID);
|
||||||
|
internal abstract IEnumerable<int> Debug_GetEntityIDs();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged
|
internal class ComponentStorage<TComponent> : ComponentStorage where TComponent : unmanaged
|
||||||
|
@ -33,9 +36,12 @@ namespace MoonTools.ECS
|
||||||
return ref components[entityIDToStorageIndex[entityID]];
|
return ref components[entityIDToStorageIndex[entityID]];
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override object UntypedGet(int entityID)
|
internal override unsafe void* UntypedGet(int entityID)
|
||||||
{
|
{
|
||||||
return components[entityIDToStorageIndex[entityID]];
|
fixed (void* p = &components[entityIDToStorageIndex[entityID]])
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref readonly TComponent GetFirst()
|
public ref readonly TComponent GetFirst()
|
||||||
|
@ -69,9 +75,9 @@ namespace MoonTools.ECS
|
||||||
components[entityIDToStorageIndex[entityID]] = component;
|
components[entityIDToStorageIndex[entityID]] = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void Set(int entityID, object component)
|
internal override unsafe void Set(int entityID, void* component)
|
||||||
{
|
{
|
||||||
Set(entityID, (TComponent) component);
|
Set(entityID, *((TComponent*) component));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the entity had this component.
|
// Returns true if the entity had this component.
|
||||||
|
@ -127,5 +133,17 @@ namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
return new ComponentStorage<TComponent>();
|
return new ComponentStorage<TComponent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
internal override object Debug_Get(int entityID)
|
||||||
|
{
|
||||||
|
return components[entityIDToStorageIndex[entityID]];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override IEnumerable<int> Debug_GetEntityIDs()
|
||||||
|
{
|
||||||
|
return entityIDToStorageIndex.Keys;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,24 @@ namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
public abstract class DebugSystem : System
|
public abstract class DebugSystem : System
|
||||||
{
|
{
|
||||||
private Dictionary<Type, Filter> singleComponentFilters = new Dictionary<Type, Filter>();
|
|
||||||
|
|
||||||
protected DebugSystem(World world) : base(world)
|
protected DebugSystem(World world) : base(world)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<object> Debug_GetAllComponents(Entity entity)
|
protected IEnumerable<dynamic> Debug_GetAllComponents(Entity entity)
|
||||||
{
|
{
|
||||||
foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID))
|
foreach (var typeIndex in EntityStorage.ComponentTypeIndices(entity.ID))
|
||||||
{
|
{
|
||||||
yield return ComponentDepot.UntypedGet(entity.ID, typeIndex);
|
yield return ComponentDepot.Debug_Get(entity.ID, typeIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<Entity> Debug_GetEntities(Type componentType)
|
protected IEnumerable<Entity> Debug_GetEntities(Type componentType)
|
||||||
{
|
{
|
||||||
if (!singleComponentFilters.ContainsKey(componentType))
|
foreach (var entityID in ComponentDepot.Debug_GetEntityIDs(ComponentTypeIndices.GetIndex(componentType)))
|
||||||
{
|
{
|
||||||
singleComponentFilters.Add(componentType, new Filter(FilterStorage, new HashSet<int>(ComponentTypeIndices.GetIndex(componentType)), new HashSet<int>()));
|
yield return new Entity(entityID);
|
||||||
}
|
}
|
||||||
return singleComponentFilters[componentType].Entities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<Type> Debug_SearchComponentType(string typeString)
|
protected IEnumerable<Type> Debug_SearchComponentType(string typeString)
|
||||||
|
|
|
@ -103,24 +103,24 @@ namespace MoonTools.ECS
|
||||||
|
|
||||||
// untyped methods used for destroying and snapshots
|
// untyped methods used for destroying and snapshots
|
||||||
|
|
||||||
public void Set(int entityA, int entityB, int relationTypeIndex, object relationData)
|
public unsafe void Set(int entityA, int entityB, int relationTypeIndex, void* relationData)
|
||||||
{
|
{
|
||||||
storages[relationTypeIndex].Set(entityA, entityB, relationData);
|
storages[relationTypeIndex].Set(entityA, entityB, relationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe void* Get(int relationTypeIndex, int relationStorageIndex)
|
||||||
|
{
|
||||||
|
return storages[relationTypeIndex].Get(relationStorageIndex);
|
||||||
|
}
|
||||||
|
|
||||||
public void UnrelateAll(int entityID, int relationTypeIndex)
|
public void UnrelateAll(int entityID, int relationTypeIndex)
|
||||||
{
|
{
|
||||||
storages[relationTypeIndex].UnrelateAll(entityID);
|
storages[relationTypeIndex].UnrelateAll(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<(int, object)> InRelations(int entityID, int relationTypeIndex)
|
public IEnumerable<(int, int)> OutRelationIndices(int entityID, int relationTypeIndex)
|
||||||
{
|
{
|
||||||
return storages[relationTypeIndex].UntypedInRelations(entityID);
|
return storages[relationTypeIndex].OutRelationIndices(entityID);
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<(int, object)> OutRelations(int entityID, int relationTypeIndex)
|
|
||||||
{
|
|
||||||
return storages[relationTypeIndex].UntypedOutRelations(entityID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
|
|
@ -5,11 +5,10 @@ namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
internal abstract class RelationStorage
|
internal abstract class RelationStorage
|
||||||
{
|
{
|
||||||
public abstract void Set(int entityA, int entityB, object relationData);
|
public abstract unsafe void Set(int entityA, int entityB, void* relationData);
|
||||||
|
public abstract unsafe void* Get(int relationStorageIndex);
|
||||||
public abstract void UnrelateAll(int entityID);
|
public abstract void UnrelateAll(int entityID);
|
||||||
public abstract IEnumerable<(int, object)> UntypedInRelations(int entityID);
|
public abstract IEnumerable<(int, int)> OutRelationIndices(int entityID);
|
||||||
public abstract IEnumerable<(int, object)> UntypedOutRelations(int entityID);
|
|
||||||
// used to create correctly typed storage on snapshot
|
|
||||||
public abstract RelationStorage CreateStorage();
|
public abstract RelationStorage CreateStorage();
|
||||||
public abstract void Clear();
|
public abstract void Clear();
|
||||||
}
|
}
|
||||||
|
@ -208,9 +207,17 @@ namespace MoonTools.ECS
|
||||||
|
|
||||||
// untyped methods used for internal implementation
|
// untyped methods used for internal implementation
|
||||||
|
|
||||||
public override void Set(int entityA, int entityB, object relationData)
|
public override unsafe void Set(int entityA, int entityB, void* relationData)
|
||||||
{
|
{
|
||||||
Set(new Relation(entityA, entityB), (TRelation) relationData);
|
Set(new Relation(entityA, entityB), *((TRelation*) relationData));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override unsafe void* Get(int relationStorageIndex)
|
||||||
|
{
|
||||||
|
fixed (void* p = &relations[relationStorageIndex])
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UnrelateAll(int entityID)
|
public override void UnrelateAll(int entityID)
|
||||||
|
@ -238,20 +245,16 @@ namespace MoonTools.ECS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<(int, object)> UntypedInRelations(int entityID)
|
public override IEnumerable<(int, int)> OutRelationIndices(int entityID)
|
||||||
{
|
{
|
||||||
foreach (var (entity, relationData) in InRelations(entityID))
|
if (outRelations.ContainsKey(entityID))
|
||||||
{
|
{
|
||||||
yield return (entity.ID, relationData);
|
foreach (var id in outRelations[entityID])
|
||||||
|
{
|
||||||
|
var relation = new Relation(entityID, id);
|
||||||
|
yield return (id, indices[relation]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<(int, object)> UntypedOutRelations(int entityID)
|
|
||||||
{
|
|
||||||
foreach (var (entity, relationData) in OutRelations(entityID))
|
|
||||||
{
|
|
||||||
yield return (entity.ID, relationData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override RelationStorage<TRelation> CreateStorage()
|
public override RelationStorage<TRelation> CreateStorage()
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace MoonTools.ECS
|
||||||
SnapshotRelationDepot = new RelationDepot(World.RelationTypeIndices);
|
SnapshotRelationDepot = new RelationDepot(World.RelationTypeIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Take(Filter filter)
|
public unsafe void Take(Filter filter)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
|
@ -50,7 +50,7 @@ namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
SnapshotEntityStorage.AddRelationKind(snapshotEntityID, relationTypeIndex);
|
SnapshotEntityStorage.AddRelationKind(snapshotEntityID, relationTypeIndex);
|
||||||
|
|
||||||
foreach (var (otherEntityID, relationData) in World.RelationDepot.OutRelations(worldEntity.ID, relationTypeIndex))
|
foreach (var (otherEntityID, relationStorageIndex) in World.RelationDepot.OutRelationIndices(worldEntity.ID, relationTypeIndex))
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (!World.FilterStorage.CheckSatisfied(otherEntityID, Filter.Signature))
|
if (!World.FilterStorage.CheckSatisfied(otherEntityID, Filter.Signature))
|
||||||
|
@ -60,13 +60,13 @@ namespace MoonTools.ECS
|
||||||
#endif
|
#endif
|
||||||
var otherSnapshotID = WorldToSnapshotID[otherEntityID];
|
var otherSnapshotID = WorldToSnapshotID[otherEntityID];
|
||||||
SnapshotEntityStorage.AddRelationKind(otherSnapshotID, relationTypeIndex);
|
SnapshotEntityStorage.AddRelationKind(otherSnapshotID, relationTypeIndex);
|
||||||
SnapshotRelationDepot.Set(snapshotEntityID, otherSnapshotID, relationTypeIndex, relationData);
|
SnapshotRelationDepot.Set(snapshotEntityID, otherSnapshotID, relationTypeIndex, World.RelationDepot.Get(relationTypeIndex, relationStorageIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Restore()
|
public unsafe void Restore()
|
||||||
{
|
{
|
||||||
if (Filter == null)
|
if (Filter == null)
|
||||||
{
|
{
|
||||||
|
@ -99,10 +99,10 @@ namespace MoonTools.ECS
|
||||||
{
|
{
|
||||||
World.EntityStorage.AddRelationKind(worldID, relationTypeIndex);
|
World.EntityStorage.AddRelationKind(worldID, relationTypeIndex);
|
||||||
|
|
||||||
foreach (var (otherEntityID, relationData) in SnapshotRelationDepot.OutRelations(i, relationTypeIndex))
|
foreach (var (otherEntityID, relationStorageIndex) in SnapshotRelationDepot.OutRelationIndices(i, relationTypeIndex))
|
||||||
{
|
{
|
||||||
var otherEntityWorldID = SnapshotToWorldID[otherEntityID];
|
var otherEntityWorldID = SnapshotToWorldID[otherEntityID];
|
||||||
World.RelationDepot.Set(worldID, otherEntityWorldID, relationTypeIndex, relationData);
|
World.RelationDepot.Set(worldID, otherEntityWorldID, relationTypeIndex, SnapshotRelationDepot.Get(relationTypeIndex, relationStorageIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace MoonTools.ECS
|
||||||
ComponentDepot.Register<TComponent>(componentTypeIndex);
|
ComponentDepot.Register<TComponent>(componentTypeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity Instantiate(in Template template)
|
public unsafe Entity Instantiate(in Template template)
|
||||||
{
|
{
|
||||||
var entity = EntityStorage.Create();
|
var entity = EntityStorage.Create();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue