add optimization with IEntityStorage to EcsMaskIterator

This commit is contained in:
DCFApixels 2025-03-11 14:30:33 +08:00
parent 21833bd532
commit 55ef119aff
8 changed files with 83 additions and 46 deletions

View File

@ -24,7 +24,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _worldID == 0; }
}
public int WorldID
public short WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _worldID; }
@ -43,6 +43,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return new EcsLongsSpan(this); }
}
public bool IsSourceEntities
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return this == EcsWorld.GetWorld(_worldID).GetCurrentEntities_Internal(); }
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.ArrayBoundsChecks, true)]
#endif
@ -180,7 +185,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.IsNull; }
}
public int WorldID
public short WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.WorldID; }
@ -194,6 +199,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.Count; }
}
public bool IsSourceEntities
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.IsSourceEntities; }
}
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.ArrayBoundsChecks, true)]
#endif

View File

@ -498,7 +498,10 @@ namespace DCFApixels.DragonECS
/// <summary> slised _sortIncChunckBuffer </summary>
private readonly UnsafeArray<EcsMaskChunck> _sortExcChunckBuffer;
private readonly bool _isSingleIncPoolWithEntityStorage;
private readonly bool _isHasAnyEntityStorage;
private readonly MaskType _maskType;
private enum MaskType : byte
{
Empty,
@ -512,11 +515,6 @@ namespace DCFApixels.DragonECS
World = source;
Mask = mask;
//_sortIncBuffer = UnsafeArray<int>.FromArray(mask._incs);
//_sortExcBuffer = UnsafeArray<int>.FromArray(mask._excs);
//_sortIncChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._incChunckMasks);
//_sortExcChunckBuffer = UnsafeArray<EcsMaskChunck>.FromArray(mask._excChunckMasks);
var sortBuffer = new UnsafeArray<int>(mask._incs.Length + mask._excs.Length);
var sortChunckBuffer = new UnsafeArray<EcsMaskChunck>(mask._incChunckMasks.Length + mask._excChunckMasks.Length);
@ -530,6 +528,16 @@ namespace DCFApixels.DragonECS
_sortExcChunckBuffer = sortChunckBuffer.Slice(mask._incChunckMasks.Length, mask._excChunckMasks.Length);
_sortExcChunckBuffer.CopyFromArray_Unchecked(mask._excChunckMasks);
_isHasAnyEntityStorage = false;
var pools = source.AllPools;
for (int i = 0; i < _sortIncBuffer.Length; i++)
{
var pool = pools[_sortIncBuffer.ptr[i]];
_isHasAnyEntityStorage |= pool is IEntityStorage;
if (_isHasAnyEntityStorage) { break; }
}
_isSingleIncPoolWithEntityStorage = Mask.Excs.Length <= 0 && Mask.Incs.Length == 1;
if (_sortExcBuffer.Length <= 0)
{
_maskType = mask.IsEmpty ? MaskType.Empty : MaskType.OnlyInc;
@ -594,9 +602,26 @@ namespace DCFApixels.DragonECS
// Выражение мало IncCount < (AllEntitesCount - ExcCount) вероятно будет истинным.
// ExcCount = максимальное количество ентитей с исключеющим ограничением и IncCount = минимальоне количество ентитей с включающим ограничением
// Поэтому исключающее ограничение игнорируется для maxEntites.
return maxEntites;
}
private unsafe bool TryGetEntityStorage(out IEntityStorage storage)
{
if (_isHasAnyEntityStorage)
{
var pools = World.AllPools;
for (int i = 0; i < _sortIncBuffer.Length; i++)
{
var pool = pools[_sortIncBuffer.ptr[i]];
storage = pool as IEntityStorage;
if (storage != null)
{
return true;
}
}
}
storage = null;
return false;
}
#endregion
#region IterateTo
@ -694,7 +719,6 @@ namespace DCFApixels.DragonECS
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator()
{
if (_iterator.Mask.IsBroken)
@ -706,7 +730,14 @@ namespace DCFApixels.DragonECS
{
return new Enumerator(_span.Slice(0, 0), _iterator);
}
return new Enumerator(_span, _iterator);
if (_iterator.TryGetEntityStorage(out IEntityStorage storage))
{
return new Enumerator(storage.ToSpan(), _iterator);
}
else
{
return new Enumerator(_span, _iterator);
}
}
#if ENABLE_IL2CPP
@ -827,7 +858,6 @@ namespace DCFApixels.DragonECS
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator()
{
if (_iterator.Mask.IsBroken)
@ -839,7 +869,14 @@ namespace DCFApixels.DragonECS
{
return new Enumerator(_span.Slice(0, 0), _iterator);
}
return new Enumerator(_span, _iterator);
if (_iterator.TryGetEntityStorage(out IEntityStorage storage))
{
return new Enumerator(storage.ToSpan(), _iterator);
}
else
{
return new Enumerator(_span, _iterator);
}
}
#if ENABLE_IL2CPP

View File

@ -130,7 +130,7 @@ namespace DCFApixels.DragonECS
get
{
ReleaseDelEntityBufferAll();
return _entityDispenser.UsedToEcsSpan(ID);
return GetCurrentEntities_Internal();
}
}
public int PoolsCount
@ -1167,6 +1167,14 @@ namespace DCFApixels.DragonECS
}
}
#endregion
#region Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsSpan GetCurrentEntities_Internal()
{
return _entityDispenser.UsedToEcsSpan(ID);
}
#endregion
}
#region Callbacks Interface

View File

@ -73,7 +73,7 @@ namespace DCFApixels.DragonECS
var world = _worlds[i];
if (world == null) { continue; }
if(world.IsDestroyed == false)
if (world.IsDestroyed == false)
{
world.Destroy();
}

View File

@ -91,6 +91,10 @@ namespace DCFApixels.DragonECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span)
{
if (span.IsSourceEntities)
{
return Execute();
}
ExecuteFor_Iternal(span);
return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);
}
@ -105,6 +109,10 @@ namespace DCFApixels.DragonECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsSpan span, Comparison<int> comparison)
{
if (span.IsSourceEntities)
{
return Execute(comparison);
}
ExecuteFor_Iternal(span);
ArraySortHalperX<int>.Sort(_filteredEntities, comparison, _filteredEntitiesCount);
return new EcsSpan(World.ID, _filteredEntities, _filteredEntitiesCount);

View File

@ -90,6 +90,10 @@ namespace DCFApixels.DragonECS.Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup ExecuteFor(EcsSpan span)
{
if (span.IsSourceEntities)
{
return Execute();
}
ExecuteFor_Iternal(span);
return _filteredGroup;
}

View File

@ -120,7 +120,7 @@ namespace DCFApixels.DragonECS.Core
_world = mask.World;
_maskInc = mask._incs;
_maskExc = mask._excs;
_versions = UnmanagedArrayUtility.New<long>(1 + mask._incs.Length + mask._excs.Length);
_versions = UnmanagedArrayUtility.NewAndInit<long>(1 + mask._incs.Length + mask._excs.Length);
}
public bool Check()
{
@ -176,7 +176,7 @@ namespace DCFApixels.DragonECS.Core
long* ptr = _versions;
var slots = _world._poolSlots;
bool result = true;
bool result = _maskInc.Length > 0 || _maskExc.Length > 0;
foreach (var slotIndex in _maskInc)
{
ptr++;

View File

@ -16,11 +16,6 @@ namespace DCFApixels.DragonECS
where TAspect : new()
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
entities.World.GetQueryCache(out EcsWhereExecutor executor, out aspect);
return executor.Execute();
}
return entities.ToSpan().Where(out aspect);
}
public static EcsSpan Where<TAspect>(this EcsReadonlyGroup group, out TAspect aspect)
@ -38,11 +33,6 @@ namespace DCFApixels.DragonECS
public static EcsSpan Where<TCollection>(this TCollection entities, IComponentMask mask)
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
var executor = entities.World.GetExecutorForMask<EcsWhereExecutor>(mask);
return executor.Execute();
}
return entities.ToSpan().Where(mask);
}
public static EcsSpan Where(this EcsReadonlyGroup group, IComponentMask mask)
@ -61,11 +51,6 @@ namespace DCFApixels.DragonECS
where TAspect : new()
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
entities.World.GetQueryCache(out EcsWhereExecutor executor, out aspect);
return executor.Execute(comparison);
}
return entities.ToSpan().Where(out aspect, comparison);
}
public static EcsSpan Where<TAspect>(this EcsReadonlyGroup group, out TAspect aspect, Comparison<int> comparison)
@ -83,11 +68,6 @@ namespace DCFApixels.DragonECS
public static EcsSpan Where<TCollection>(this TCollection entities, IComponentMask mask, Comparison<int> comparison)
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
EcsWhereExecutor executor = entities.World.GetExecutorForMask<EcsWhereExecutor>(mask);
return executor.Execute(comparison);
}
return entities.ToSpan().Where(mask, comparison);
}
public static EcsSpan Where(this EcsReadonlyGroup group, IComponentMask mask, Comparison<int> comparison)
@ -106,11 +86,6 @@ namespace DCFApixels.DragonECS
where TAspect : new()
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
entities.World.GetQueryCache(out EcsWhereToGroupExecutor executor, out aspect);
return executor.Execute();
}
return entities.ToSpan().WhereToGroup(out aspect);
}
public static EcsReadonlyGroup WhereToGroup<TAspect>(this EcsReadonlyGroup group, out TAspect aspect)
@ -128,11 +103,6 @@ namespace DCFApixels.DragonECS
public static EcsReadonlyGroup WhereToGroup<TCollection>(this TCollection entities, IComponentMask mask)
where TCollection : IEntityStorage
{
if (ReferenceEquals(entities, entities.World))
{
EcsWhereToGroupExecutor executor = entities.World.GetExecutorForMask<EcsWhereToGroupExecutor>(mask);
return executor.Execute();
}
return entities.ToSpan().WhereToGroup(mask);
}
public static EcsReadonlyGroup WhereToGroup(this EcsReadonlyGroup group, IComponentMask mask)