mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54: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)]
|
[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
|
||||||
|
@ -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)]
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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++;
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user