fix filter results being out of order on world transfer
parent
a2a81bf477
commit
3cba3e047c
|
@ -20,6 +20,35 @@ namespace MoonTools.ECS
|
||||||
ComponentTypeIndices = componentTypeIndices;
|
ComponentTypeIndices = componentTypeIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CopyTypeCache(Dictionary<int, List<FilterSignature>> typeCache)
|
||||||
|
{
|
||||||
|
foreach (var type in typeCache.Keys)
|
||||||
|
{
|
||||||
|
if (!typeToFilterSignatures.ContainsKey(type))
|
||||||
|
{
|
||||||
|
typeToFilterSignatures.Add(type, new List<FilterSignature>());
|
||||||
|
|
||||||
|
foreach (var signature in typeCache[type])
|
||||||
|
{
|
||||||
|
typeToFilterSignatures[type].Add(signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateMissingStorages(FilterStorage other)
|
||||||
|
{
|
||||||
|
foreach (var filterSignature in other.filterSignatureToEntityIDs.Keys)
|
||||||
|
{
|
||||||
|
if (!filterSignatureToEntityIDs.ContainsKey(filterSignature))
|
||||||
|
{
|
||||||
|
filterSignatureToEntityIDs.Add(filterSignature, new IndexableSet<Entity>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyTypeCache(other.typeToFilterSignatures);
|
||||||
|
}
|
||||||
|
|
||||||
public Filter CreateFilter(IndexableSet<int> included, IndexableSet<int> excluded)
|
public Filter CreateFilter(IndexableSet<int> included, IndexableSet<int> excluded)
|
||||||
{
|
{
|
||||||
var filterSignature = new FilterSignature(included, excluded);
|
var filterSignature = new FilterSignature(included, excluded);
|
||||||
|
@ -174,6 +203,32 @@ namespace MoonTools.ECS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used by TransferEntity
|
||||||
|
public void AddEntity(FilterSignature signature, int entityID)
|
||||||
|
{
|
||||||
|
filterSignatureToEntityIDs[signature].Add(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TransferStorage(Dictionary<int, int> worldToTransferID, FilterStorage other)
|
||||||
|
{
|
||||||
|
foreach (var (filterSignature, entityIDs) in filterSignatureToEntityIDs)
|
||||||
|
{
|
||||||
|
foreach (var entity in entityIDs)
|
||||||
|
{
|
||||||
|
if (worldToTransferID.ContainsKey(entity))
|
||||||
|
{
|
||||||
|
var otherEntityID = worldToTransferID[entity];
|
||||||
|
other.AddEntity(filterSignature, otherEntityID);
|
||||||
|
|
||||||
|
if (other.addCallbacks.TryGetValue(filterSignature, out var addCallback))
|
||||||
|
{
|
||||||
|
addCallback(otherEntityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// used by World.Clear, ignores callbacks
|
// used by World.Clear, ignores callbacks
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
|
|
14
src/World.cs
14
src/World.cs
|
@ -54,14 +54,11 @@ namespace MoonTools.ECS
|
||||||
}
|
}
|
||||||
|
|
||||||
// untyped version for Transfer
|
// untyped version for Transfer
|
||||||
|
// no filter check because filter state is copied directly
|
||||||
internal unsafe void Set(Entity entity, int componentTypeIndex, void* component)
|
internal unsafe void Set(Entity entity, int componentTypeIndex, void* component)
|
||||||
{
|
{
|
||||||
ComponentDepot.Set(entity.ID, componentTypeIndex, component);
|
ComponentDepot.Set(entity.ID, componentTypeIndex, component);
|
||||||
|
EntityStorage.SetComponent(entity.ID, componentTypeIndex);
|
||||||
if (EntityStorage.SetComponent(entity.ID, componentTypeIndex))
|
|
||||||
{
|
|
||||||
FilterStorage.Check(entity.ID, componentTypeIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Remove<TComponent>(in Entity entity) where TComponent : unmanaged
|
public void Remove<TComponent>(in Entity entity) where TComponent : unmanaged
|
||||||
|
@ -163,6 +160,10 @@ namespace MoonTools.ECS
|
||||||
other.ComponentDepot.CreateMissingStorages(ComponentDepot);
|
other.ComponentDepot.CreateMissingStorages(ComponentDepot);
|
||||||
other.RelationDepot.CreateMissingStorages(RelationDepot);
|
other.RelationDepot.CreateMissingStorages(RelationDepot);
|
||||||
|
|
||||||
|
// FIXME: we could just do this once on startup
|
||||||
|
// Could have a PrepareTransfer method or something
|
||||||
|
other.FilterStorage.CreateMissingStorages(FilterStorage);
|
||||||
|
|
||||||
// destroy all entities matching the filter
|
// destroy all entities matching the filter
|
||||||
foreach (var entity in otherFilter.Entities)
|
foreach (var entity in otherFilter.Entities)
|
||||||
{
|
{
|
||||||
|
@ -176,6 +177,7 @@ namespace MoonTools.ECS
|
||||||
WorldToTransferID.Add(entity.ID, otherWorldEntity.ID);
|
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
|
// set relations before components so filters don't freak out
|
||||||
foreach (var entity in filter.Entities)
|
foreach (var entity in filter.Entities)
|
||||||
{
|
{
|
||||||
|
@ -211,6 +213,8 @@ namespace MoonTools.ECS
|
||||||
other.Set(otherWorldEntity, componentTypeIndex, ComponentDepot.UntypedGet(entity.ID, componentTypeIndex));
|
other.Set(otherWorldEntity, componentTypeIndex, ComponentDepot.UntypedGet(entity.ID, componentTypeIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilterStorage.TransferStorage(WorldToTransferID, other.FilterStorage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue