mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
add optimization with IEntityStorage to EcsMaskIterator
This commit is contained in:
parent
21833bd532
commit
55ef119aff
@ -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
|
||||
|
@ -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,8 +730,15 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
[Il2CppSetOption(Option.NullChecks, false)]
|
||||
@ -827,7 +858,6 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Enumerator
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
if (_iterator.Mask.IsBroken)
|
||||
@ -839,8 +869,15 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
[Il2CppSetOption(Option.NullChecks, false)]
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user