transfer relations in order
parent
3cba3e047c
commit
2aa8fc87e7
|
@ -6,11 +6,13 @@ namespace MoonTools.ECS
|
|||
{
|
||||
internal class RelationDepot
|
||||
{
|
||||
private EntityStorage EntityStorage;
|
||||
private TypeIndices RelationTypeIndices;
|
||||
private RelationStorage[] storages = new RelationStorage[256];
|
||||
|
||||
public RelationDepot(TypeIndices relationTypeIndices)
|
||||
public RelationDepot(EntityStorage entityStorage, TypeIndices relationTypeIndices)
|
||||
{
|
||||
EntityStorage = entityStorage;
|
||||
RelationTypeIndices = relationTypeIndices;
|
||||
}
|
||||
|
||||
|
@ -123,26 +125,11 @@ namespace MoonTools.ECS
|
|||
storages[relationTypeIndex].Set(entityA, entityB, relationData);
|
||||
}
|
||||
|
||||
public int GetStorageIndex(int relationTypeIndex, int entityA, int entityB)
|
||||
{
|
||||
return storages[relationTypeIndex].GetStorageIndex(entityA, entityB);
|
||||
}
|
||||
|
||||
public unsafe void* Get(int relationTypeIndex, int relationStorageIndex)
|
||||
{
|
||||
return storages[relationTypeIndex].Get(relationStorageIndex);
|
||||
}
|
||||
|
||||
public void UnrelateAll(int entityID, int relationTypeIndex)
|
||||
{
|
||||
storages[relationTypeIndex].UnrelateAll(entityID);
|
||||
}
|
||||
|
||||
public ReverseSpanEnumerator<Entity> OutRelations(int entityID, int relationTypeIndex)
|
||||
{
|
||||
return storages[relationTypeIndex].OutRelations(entityID);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (var i = 0; i < storages.Length; i += 1)
|
||||
|
@ -174,5 +161,33 @@ namespace MoonTools.ECS
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void TransferStorage(Dictionary<int, int> worldToTransferID, RelationDepot other)
|
||||
{
|
||||
for (var i = 0; i < storages.Length; i += 1)
|
||||
{
|
||||
if (storages[i] != null)
|
||||
{
|
||||
foreach (var (a, b) in storages[i].All())
|
||||
{
|
||||
if (worldToTransferID.TryGetValue(a, out var otherA))
|
||||
{
|
||||
if (worldToTransferID.TryGetValue(b, out var otherB))
|
||||
{
|
||||
var storageIndex = storages[i].GetStorageIndex(a, b);
|
||||
var relationData = storages[i].Get(storageIndex);
|
||||
other.Set(otherA, otherB, i, relationData);
|
||||
other.EntityStorage.AddRelationKind(otherA, i);
|
||||
other.EntityStorage.AddRelationKind(otherB, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Missing transfer entity! {EntityStorage.Tag(a.ID)} related to {EntityStorage.Tag(b.ID)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace MoonTools.ECS
|
|||
public abstract int GetStorageIndex(int entityA, int entityB);
|
||||
public abstract unsafe void* Get(int relationStorageIndex);
|
||||
public abstract void UnrelateAll(int entityID);
|
||||
public abstract ReverseSpanEnumerator<Entity> OutRelations(int entityID);
|
||||
public abstract ReverseSpanEnumerator<(Entity, Entity)> All();
|
||||
public abstract RelationStorage CreateStorage();
|
||||
public abstract void Clear();
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ namespace MoonTools.ECS
|
|||
relationDatas = (TRelation*) NativeMemory.Alloc((nuint) (capacity * Unsafe.SizeOf<TRelation>()));
|
||||
}
|
||||
|
||||
public ReverseSpanEnumerator<(Entity, Entity)> All()
|
||||
public override ReverseSpanEnumerator<(Entity, Entity)> All()
|
||||
{
|
||||
return new ReverseSpanEnumerator<(Entity, Entity)>(new Span<(Entity, Entity)>(relations, count));
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ namespace MoonTools.ECS
|
|||
return indices.ContainsKey(relation);
|
||||
}
|
||||
|
||||
public override ReverseSpanEnumerator<Entity> OutRelations(int entityID)
|
||||
public ReverseSpanEnumerator<Entity> OutRelations(int entityID)
|
||||
{
|
||||
if (outRelations.TryGetValue(entityID, out var entityOutRelations))
|
||||
{
|
||||
|
|
38
src/World.cs
38
src/World.cs
|
@ -17,7 +17,7 @@ namespace MoonTools.ECS
|
|||
public World()
|
||||
{
|
||||
ComponentDepot = new ComponentDepot(ComponentTypeIndices);
|
||||
RelationDepot = new RelationDepot(RelationTypeIndices);
|
||||
RelationDepot = new RelationDepot(EntityStorage, RelationTypeIndices);
|
||||
FilterStorage = new FilterStorage(EntityStorage, ComponentTypeIndices);
|
||||
}
|
||||
|
||||
|
@ -79,14 +79,6 @@ namespace MoonTools.ECS
|
|||
EntityStorage.AddRelationKind(entityB.ID, relationTypeIndex);
|
||||
}
|
||||
|
||||
// untyped version for Transfer
|
||||
internal unsafe void Relate(Entity entityA, Entity entityB, int relationTypeIndex, void* relationData)
|
||||
{
|
||||
RelationDepot.Set(entityA, entityB, relationTypeIndex, relationData);
|
||||
EntityStorage.AddRelationKind(entityA.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);
|
||||
|
@ -177,31 +169,8 @@ namespace MoonTools.ECS
|
|||
WorldToTransferID.Add(entity.ID, otherWorldEntity.ID);
|
||||
}
|
||||
|
||||
// FIXME: make sure this preserves relation order, should probably do something similar to filter storage
|
||||
// set relations before components so filters don't freak out
|
||||
foreach (var entity in filter.Entities)
|
||||
{
|
||||
var otherWorldEntityA = WorldToTransferID[entity.ID];
|
||||
|
||||
foreach (var relationTypeIndex in EntityStorage.RelationTypeIndices(entity.ID))
|
||||
{
|
||||
foreach (var entityB in RelationDepot.OutRelations(entity.ID, relationTypeIndex))
|
||||
{
|
||||
var storageIndex = RelationDepot.GetStorageIndex(relationTypeIndex, entity.ID, entityB);
|
||||
|
||||
int otherWorldEntityB;
|
||||
if (WorldToTransferID.TryGetValue(entityB, out otherWorldEntityB))
|
||||
{
|
||||
other.Relate(otherWorldEntityA, otherWorldEntityB, relationTypeIndex, RelationDepot.Get(relationTypeIndex, storageIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
// related entity is not in the filter
|
||||
throw new Exception($"Missing transfer entity! {EntityStorage.Tag(entity.ID)} related to {EntityStorage.Tag(entityB.ID)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// transfer relations
|
||||
RelationDepot.TransferStorage(WorldToTransferID, other.RelationDepot);
|
||||
|
||||
// set components
|
||||
foreach (var entity in filter.Entities)
|
||||
|
@ -214,6 +183,7 @@ namespace MoonTools.ECS
|
|||
}
|
||||
}
|
||||
|
||||
// transfer filters last so callbacks trigger correctly
|
||||
FilterStorage.TransferStorage(WorldToTransferID, other.FilterStorage);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue