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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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