Update entity lifecycle/collcetions

update auto release DelEntBuffer
replace ReadnolySpan<int> to EcsSpan
This commit is contained in:
Mikhail 2023-12-31 13:07:53 +08:00
parent 82c5dbc939
commit 1ecad4de1d
9 changed files with 221 additions and 118 deletions

View File

@ -121,20 +121,20 @@
var combined = self.GetAspect<CombinedAspect<A0, A1>>(); var combined = self.GetAspect<CombinedAspect<A0, A1>>();
a0 = combined.a0; a0 = combined.a0;
a1 = combined.a1; a1 = combined.a1;
return self.WhereFor<CombinedAspect<A0, A1>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1>>(sourceGroup);
} }
public static EcsReadonlyGroup Where<A0, A1>(this EcsWorld self) public static EcsReadonlyGroup Where<A0, A1>(this EcsWorld self)
where A0 : EcsAspect where A0 : EcsAspect
where A1 : EcsAspect where A1 : EcsAspect
{ {
return self.Where<CombinedAspect<A0, A1>>(); return self.WhereToGroup<CombinedAspect<A0, A1>>();
} }
public static EcsReadonlyGroup WhereFor<A0, A1>(this EcsWorld self, EcsReadonlyGroup sourceGroup) public static EcsReadonlyGroup WhereFor<A0, A1>(this EcsWorld self, EcsReadonlyGroup sourceGroup)
where A0 : EcsAspect where A0 : EcsAspect
where A1 : EcsAspect where A1 : EcsAspect
{ {
return self.WhereFor<CombinedAspect<A0, A1>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1>>(sourceGroup);
} }
#endregion #endregion
@ -155,7 +155,7 @@
a0 = combined.a0; a0 = combined.a0;
a1 = combined.a1; a1 = combined.a1;
a2 = combined.a2; a2 = combined.a2;
return self.WhereFor<CombinedAspect<A0, A1, A2>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2>>(sourceGroup);
} }
public static EcsReadonlyGroup Where<A0, A1, A2>(this EcsWorld self) public static EcsReadonlyGroup Where<A0, A1, A2>(this EcsWorld self)
@ -163,14 +163,14 @@
where A1 : EcsAspect where A1 : EcsAspect
where A2 : EcsAspect where A2 : EcsAspect
{ {
return self.Where<CombinedAspect<A0, A1, A2>>(); return self.WhereToGroup<CombinedAspect<A0, A1, A2>>();
} }
public static EcsReadonlyGroup WhereFor<A0, A1, A2>(this EcsWorld self, EcsReadonlyGroup sourceGroup) public static EcsReadonlyGroup WhereFor<A0, A1, A2>(this EcsWorld self, EcsReadonlyGroup sourceGroup)
where A0 : EcsAspect where A0 : EcsAspect
where A1 : EcsAspect where A1 : EcsAspect
where A2 : EcsAspect where A2 : EcsAspect
{ {
return self.WhereFor<CombinedAspect<A0, A1, A2>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2>>(sourceGroup);
} }
#endregion #endregion
@ -194,7 +194,7 @@
a1 = combined.a1; a1 = combined.a1;
a2 = combined.a2; a2 = combined.a2;
a3 = combined.a3; a3 = combined.a3;
return self.WhereFor<CombinedAspect<A0, A1, A2, A3>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3>>(sourceGroup);
} }
public static EcsReadonlyGroup Where<A0, A1, A2, A3>(this EcsWorld self) public static EcsReadonlyGroup Where<A0, A1, A2, A3>(this EcsWorld self)
@ -203,7 +203,7 @@
where A2 : EcsAspect where A2 : EcsAspect
where A3 : EcsAspect where A3 : EcsAspect
{ {
return self.Where<CombinedAspect<A0, A1, A2, A3>>(); return self.WhereToGroup<CombinedAspect<A0, A1, A2, A3>>();
} }
public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3>(this EcsWorld self, EcsReadonlyGroup sourceGroup) public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3>(this EcsWorld self, EcsReadonlyGroup sourceGroup)
where A0 : EcsAspect where A0 : EcsAspect
@ -211,7 +211,7 @@
where A2 : EcsAspect where A2 : EcsAspect
where A3 : EcsAspect where A3 : EcsAspect
{ {
return self.WhereFor<CombinedAspect<A0, A1, A2, A3>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3>>(sourceGroup);
} }
#endregion #endregion
@ -238,7 +238,7 @@
a2 = combined.a2; a2 = combined.a2;
a3 = combined.a3; a3 = combined.a3;
a4 = combined.a4; a4 = combined.a4;
return self.WhereFor<CombinedAspect<A0, A1, A2, A3, A4>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3, A4>>(sourceGroup);
} }
@ -249,7 +249,7 @@
where A3 : EcsAspect where A3 : EcsAspect
where A4 : EcsAspect where A4 : EcsAspect
{ {
return self.Where<CombinedAspect<A0, A1, A2, A3, A4>>(); return self.WhereToGroup<CombinedAspect<A0, A1, A2, A3, A4>>();
} }
public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3, A4>(this EcsWorld self, EcsReadonlyGroup sourceGroup) public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3, A4>(this EcsWorld self, EcsReadonlyGroup sourceGroup)
where A0 : EcsAspect where A0 : EcsAspect
@ -258,7 +258,7 @@
where A3 : EcsAspect where A3 : EcsAspect
where A4 : EcsAspect where A4 : EcsAspect
{ {
return self.WhereFor<CombinedAspect<A0, A1, A2, A3, A4>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3, A4>>(sourceGroup);
} }
#endregion #endregion
@ -288,7 +288,7 @@
a3 = combined.a3; a3 = combined.a3;
a4 = combined.a4; a4 = combined.a4;
a5 = combined.a5; a5 = combined.a5;
return self.WhereFor<CombinedAspect<A0, A1, A2, A3, A4, A5>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3, A4, A5>>(sourceGroup);
} }
@ -300,7 +300,7 @@
where A4 : EcsAspect where A4 : EcsAspect
where A5 : EcsAspect where A5 : EcsAspect
{ {
return self.Where<CombinedAspect<A0, A1, A2, A3, A4, A5>>(); return self.WhereToGroup<CombinedAspect<A0, A1, A2, A3, A4, A5>>();
} }
public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3, A4, A5>(this EcsWorld self, EcsReadonlyGroup sourceGroup) public static EcsReadonlyGroup WhereFor<A0, A1, A2, A3, A4, A5>(this EcsWorld self, EcsReadonlyGroup sourceGroup)
where A0 : EcsAspect where A0 : EcsAspect
@ -310,7 +310,7 @@
where A4 : EcsAspect where A4 : EcsAspect
where A5 : EcsAspect where A5 : EcsAspect
{ {
return self.WhereFor<CombinedAspect<A0, A1, A2, A3, A4, A5>>(sourceGroup); return self.WhereToGroupFor<CombinedAspect<A0, A1, A2, A3, A4, A5>>(sourceGroup);
} }
#endregion #endregion
} }

View File

@ -23,7 +23,7 @@ namespace DCFApixels.DragonECS
foreach (var world in _worlds) foreach (var world in _worlds)
{ {
world.DeleteEmptyEntites(); world.DeleteEmptyEntites();
world.ReleaseDelEntityBuffer(); world.ReleaseDelEntityBufferAll();
} }
} }
} }
@ -47,7 +47,7 @@ namespace DCFApixels.DragonECS
EcsWorld world = _worlds[i]; EcsWorld world = _worlds[i];
if (world.IsComponentTypeDeclared<TComponent>()) if (world.IsComponentTypeDeclared<TComponent>())
{ {
foreach (var e in world.Where(out Aspect a)) foreach (var e in world.WhereToGroup(out Aspect a))
a.pool.Del(e); a.pool.Del(e);
} }
} }

View File

@ -77,9 +77,9 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Bake(List<int> entities) => _source.Bake(entities); public void Bake(List<int> entities) => _source.Bake(entities);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<int> ToSpan() => _source.ToSpan(); public EcsSpan ToSpan() => _source.ToSpan();
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ReadOnlySpan<int> ToSpan(int start, int length) => _source.ToSpan(start, length); public EcsSpan ToSpan(int start, int length) => _source.ToSpan(start, length);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsGroup.LongsIterator GetLongs() => _source.GetLongs(); public EcsGroup.LongsIterator GetLongs() => _source.GetLongs();
@ -121,12 +121,9 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Convertions #region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<int>(EcsReadonlyGroup a) => a.ToSpan(); public static implicit operator EcsSpan(EcsReadonlyGroup a) => a.ToSpan();
#endregion
#region DebuggerProxy
internal class DebuggerProxy : EcsGroup.DebuggerProxy internal class DebuggerProxy : EcsGroup.DebuggerProxy
{ {
public DebuggerProxy(EcsReadonlyGroup group) : base(group._source) { } public DebuggerProxy(EcsReadonlyGroup group) : base(group._source) { }
@ -321,13 +318,16 @@ namespace DCFApixels.DragonECS
foreach (var e in this) foreach (var e in this)
entities.Add(e); entities.Add(e);
} }
public ReadOnlySpan<int> ToSpan() => new ReadOnlySpan<int>(_dense, 0, _count); public EcsSpan ToSpan()
public ReadOnlySpan<int> ToSpan(int start, int length) {
return new EcsSpan(WorldID, _dense);
}
public EcsSpan ToSpan(int start, int length)
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
if (start + length > _count) Throw.ArgumentOutOfRange(); if (start + length > _count) Throw.ArgumentOutOfRange();
#endif #endif
return new ReadOnlySpan<int>(_dense, start, length); return new EcsSpan(WorldID, _dense, start, length);
} }
#endregion #endregion
@ -637,28 +637,18 @@ namespace DCFApixels.DragonECS
#region Enumerator #region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() => new Enumerator(this); public Enumerator GetEnumerator() => new Enumerator(this);
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
{ IEnumerator<int> IEnumerable<int>.GetEnumerator() => GetEnumerator();
for (int i = 0; i < _count; i++)
yield return _dense[i];
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
for (int i = 0; i < _count; i++)
yield return _dense[i];
}
public LongsIterator GetLongs() => new LongsIterator(this); public LongsIterator GetLongs() => new LongsIterator(this);
public struct Enumerator : IEnumerator<int> public struct Enumerator : IEnumerator<int>
{ {
private readonly int[] _dense; private readonly int[] _dense;
private readonly int _count; private uint _index;
private int _index;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator(EcsGroup group) public Enumerator(EcsGroup group)
{ {
_dense = group._dense; _dense = group._dense;
_count = group._count > _dense.Length ? _dense.Length : group._count; _index = (uint)(group._count > _dense.Length ? _dense.Length : group._count);
_index = 0;
} }
public int Current public int Current
{ {
@ -667,7 +657,7 @@ namespace DCFApixels.DragonECS
} }
object IEnumerator.Current => Current; object IEnumerator.Current => Current;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() => ++_index <= _count; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны public bool MoveNext() => --_index > 0; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose() { } public void Dispose() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -689,38 +679,34 @@ namespace DCFApixels.DragonECS
for (int i = 0; i < _group._count; i++) for (int i = 0; i < _group._count; i++)
yield return _group.World.GetEntityLong(_group._dense[i]); yield return _group.World.GetEntityLong(_group._dense[i]);
} }
public ref struct Enumerator public struct Enumerator : IEnumerator<entlong>
{ {
private readonly EcsWorld world; private readonly EcsWorld world;
private readonly int[] _dense; private readonly int[] _dense;
private readonly int _count; private uint _index;
private int _index;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator(EcsGroup group) public Enumerator(EcsGroup group)
{ {
world = group.World; world = group.World;
_dense = group._dense; _dense = group._dense;
_count = group._count > _dense.Length ? _dense.Length : group._count; _index = (uint)(group._count > _dense.Length ? _dense.Length : group._count);
_index = 0;
} }
public entlong Current public entlong Current
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => world.GetEntityLong(_dense[_index]); get => world.GetEntityLong(_dense[_index]);
} }
object IEnumerator.Current => Current;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() => ++_index <= _count; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны public bool MoveNext() => ++_index > 0; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Reset() { }
} }
} }
#endregion #endregion
#region Convertions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator EcsReadonlyGroup(EcsGroup a) => a.Readonly;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ReadOnlySpan<int>(EcsGroup a) => a.ToSpan();
#endregion
#region Other #region Other
public override string ToString() public override string ToString()
{ {
@ -741,6 +727,10 @@ namespace DCFApixels.DragonECS
{ {
Array.Resize(ref _sparse, newSize); Array.Resize(ref _sparse, newSize);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator EcsReadonlyGroup(EcsGroup a) => a.Readonly;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator EcsSpan(EcsGroup a) => a.ToSpan();
internal class DebuggerProxy internal class DebuggerProxy
{ {
private EcsGroup _group; private EcsGroup _group;

View File

@ -10,14 +10,29 @@ namespace DCFApixels.DragonECS
private readonly ReadOnlySpan<int> _values; private readonly ReadOnlySpan<int> _values;
#region Properties #region Properties
public int WorldID => _worldID; public int WorldID
public EcsWorld World => EcsWorld.GetWorld(_worldID); {
public int Length => _values.Length; [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsEmpty => _values.IsEmpty; get => _worldID;
}
public EcsWorld World
{
get => EcsWorld.GetWorld(_worldID);
}
public int Length
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _values.Length;
}
public readonly int this[int index] public readonly int this[int index]
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _values[index]; get => _values[index];
}
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _values.IsEmpty;
} }
#endregion #endregion

View File

@ -188,9 +188,9 @@ namespace DCFApixels.DragonECS
{ {
return new EcsAspectIterator(this, source.Entities); return new EcsAspectIterator(this, source.Entities);
} }
public EcsAspectIterator GetIteratorFor(EcsReadonlyGroup sourceGroup) public EcsAspectIterator GetIteratorFor(EcsSpan span)
{ {
return new EcsAspectIterator(this, sourceGroup); return new EcsAspectIterator(this, span);
} }
#endregion #endregion
@ -336,14 +336,14 @@ namespace DCFApixels.DragonECS
{ {
public readonly int worldID; public readonly int worldID;
public readonly EcsMask mask; public readonly EcsMask mask;
private EcsReadonlyGroup _sourceGroup; private EcsSpan _span;
private Enumerator _enumerator; private Enumerator _enumerator;
public EcsAspectIterator(EcsAspect aspect, EcsReadonlyGroup sourceGroup) public EcsAspectIterator(EcsAspect aspect, EcsSpan span)
{ {
worldID = aspect.World.id; worldID = aspect.World.id;
mask = aspect.mask; mask = aspect.mask;
_sourceGroup = sourceGroup; _span = span;
_enumerator = default; _enumerator = default;
} }
@ -403,33 +403,33 @@ namespace DCFApixels.DragonECS
#region Enumerator #region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() => new Enumerator(_sourceGroup, mask); public Enumerator GetEnumerator() => new Enumerator(_span, mask);
public ref struct Enumerator public ref struct Enumerator
{ {
private EcsGroup.Enumerator _sourceGroup; private ReadOnlySpan<int>.Enumerator _span;
private readonly EcsMaskBit[] _inc; private readonly EcsMaskBit[] _inc;
private readonly EcsMaskBit[] _exc; private readonly EcsMaskBit[] _exc;
private readonly int[][] _entitiesComponentMasks; private readonly int[][] _entitiesComponentMasks;
public Enumerator(EcsReadonlyGroup sourceGroup, EcsMask mask) public Enumerator(EcsSpan span, EcsMask mask)
{ {
_sourceGroup = sourceGroup.GetEnumerator(); _span = span.GetEnumerator();
_inc = mask.incChunckMasks; _inc = mask.incChunckMasks;
_exc = mask.excChunckMasks; _exc = mask.excChunckMasks;
_entitiesComponentMasks = sourceGroup.World._entitiesComponentMasks; _entitiesComponentMasks = span.World._entitiesComponentMasks;
} }
public int Current public int Current
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _sourceGroup.Current; get => _span.Current;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() public bool MoveNext()
{ {
while (_sourceGroup.MoveNext()) while (_span.MoveNext())
{ {
int e = _sourceGroup.Current; int e = _span.Current;
EcsMaskBit bit; EcsMaskBit bit;
for (int i = 0, iMax = _inc.Length; i < iMax; i++) for (int i = 0, iMax = _inc.Length; i < iMax; i++)
{ {

View File

@ -23,6 +23,7 @@ namespace DCFApixels.DragonECS
private int _delEntBufferCount; private int _delEntBufferCount;
private int _delEntBufferMinCount; private int _delEntBufferMinCount;
private int _freeSpace; private int _freeSpace;
//private bool _isEnableReleaseDelEntBuffer = true;
private List<WeakReference<EcsGroup>> _groups = new List<WeakReference<EcsGroup>>(); private List<WeakReference<EcsGroup>> _groups = new List<WeakReference<EcsGroup>>();
private Stack<EcsGroup> _groupsPool = new Stack<EcsGroup>(64); private Stack<EcsGroup> _groupsPool = new Stack<EcsGroup>(64);
@ -111,38 +112,75 @@ namespace DCFApixels.DragonECS
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Get<T>() where T : struct => ref WorldComponentPool<T>.GetForWorld(id); public ref T Get<T>() where T : struct
{
return ref WorldComponentPool<T>.GetForWorld(id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T UncheckedGet<T>() where T : struct => ref WorldComponentPool<T>.UncheckedGetForWorld(id); public ref T GetUnchecked<T>() where T : struct
{
return ref WorldComponentPool<T>.GetForWorldUnchecked(id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Get<T>(int worldID) where T : struct => ref WorldComponentPool<T>.GetForWorld(worldID); public static ref T Get<T>(int worldID) where T : struct
{
return ref WorldComponentPool<T>.GetForWorld(worldID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T UncheckedGet<T>(int worldID) where T : struct => ref WorldComponentPool<T>.UncheckedGetForWorld(worldID); public static ref T GetUnchecked<T>(int worldID) where T : struct
{
return ref WorldComponentPool<T>.GetForWorldUnchecked(worldID);
}
#endregion #endregion
#region Where Query #region Where Query
public EcsReadonlyGroup WhereFor<TAspect>(EcsReadonlyGroup sourceGroup, out TAspect aspect) where TAspect : EcsAspect public EcsReadonlyGroup WhereToGroupFor<TAspect>(EcsSpan span, out TAspect aspect) where TAspect : EcsAspect
{ {
ReleaseDelEntityBufferAll();
var executor = GetExecutor<EcsWhereExecutor<TAspect>>(); var executor = GetExecutor<EcsWhereExecutor<TAspect>>();
aspect = executor.Aspect; aspect = executor.Aspect;
return executor.ExecuteFor(sourceGroup); return executor.ExecuteFor(span);
} }
public EcsReadonlyGroup WhereFor<TAspect>(EcsReadonlyGroup sourceGroup) where TAspect : EcsAspect public EcsReadonlyGroup WhereToGroupFor<TAspect>(EcsSpan span) where TAspect : EcsAspect
{ {
return GetExecutor<EcsWhereExecutor<TAspect>>().ExecuteFor(sourceGroup); ReleaseDelEntityBufferAll();
return GetExecutor<EcsWhereExecutor<TAspect>>().ExecuteFor(span);
} }
public EcsReadonlyGroup Where<TAspect>(out TAspect aspect) where TAspect : EcsAspect public EcsReadonlyGroup WhereToGroup<TAspect>(out TAspect aspect) where TAspect : EcsAspect
{ {
ReleaseDelEntityBufferAll();
var executor = GetExecutor<EcsWhereExecutor<TAspect>>(); var executor = GetExecutor<EcsWhereExecutor<TAspect>>();
aspect = executor.Aspect; aspect = executor.Aspect;
return executor.Execute(); return executor.Execute();
} }
public EcsReadonlyGroup Where<TAspect>() where TAspect : EcsAspect public EcsReadonlyGroup WhereToGroup<TAspect>() where TAspect : EcsAspect
{ {
ReleaseDelEntityBufferAll();
return GetExecutor<EcsWhereExecutor<TAspect>>().Execute(); return GetExecutor<EcsWhereExecutor<TAspect>>().Execute();
} }
public EcsSpan WhereSpan<TAspect>() where TAspect : EcsAspect
public EcsSpan WhereFor<TAspect>(EcsSpan span, out TAspect aspect) where TAspect : EcsAspect
{ {
ReleaseDelEntityBufferAll();
var executor = GetExecutor<EcsWhereSpanExecutor<TAspect>>();
aspect = executor.Aspect;
return executor.ExecuteFor(span);
}
public EcsSpan WhereFor<TAspect>(EcsSpan span) where TAspect : EcsAspect
{
ReleaseDelEntityBufferAll();
return GetExecutor<EcsWhereSpanExecutor<TAspect>>().ExecuteFor(span);
}
public EcsSpan Where<TAspect>(out TAspect aspect) where TAspect : EcsAspect
{
ReleaseDelEntityBufferAll();
var executor = GetExecutor<EcsWhereSpanExecutor<TAspect>>();
aspect = executor.Aspect;
return executor.Execute();
}
public EcsSpan Where<TAspect>() where TAspect : EcsAspect
{
ReleaseDelEntityBufferAll();
return GetExecutor<EcsWhereSpanExecutor<TAspect>>().Execute(); return GetExecutor<EcsWhereSpanExecutor<TAspect>>().Execute();
} }
#endregion #endregion
@ -150,8 +188,8 @@ namespace DCFApixels.DragonECS
#region Entity #region Entity
public int NewEntity() public int NewEntity()
{ {
if (_freeSpace <= 1 && _delEntBufferCount > _delEntBufferMinCount) //if (_isEnableReleaseDelEntBuffer && _freeSpace <= 1 && _delEntBufferCount > _delEntBufferMinCount)
ReleaseDelEntityBuffer(); // ReleaseDelEntityBufferAll();
int entityID = _entityDispenser.GetFree(); int entityID = _entityDispenser.GetFree();
_freeSpace--; _freeSpace--;
@ -177,9 +215,8 @@ namespace DCFApixels.DragonECS
_gens[entityID] |= DEATH_GEN_BIT; _gens[entityID] |= DEATH_GEN_BIT;
_entitiesCount--; _entitiesCount--;
_entityListeners.InvokeOnDelEntity(entityID); _entityListeners.InvokeOnDelEntity(entityID);
//if (_delEntBufferCount >= _delEntBuffer.Length)
if (_delEntBufferCount >= _delEntBuffer.Length) // ReleaseDelEntityBufferAll();
ReleaseDelEntityBuffer();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe entlong GetEntityLong(int entityID) public unsafe entlong GetEntityLong(int entityID)
@ -214,24 +251,15 @@ namespace DCFApixels.DragonECS
} }
return true; return true;
} }
public void ReleaseDelEntityBuffer()
{
if (_delEntBufferCount <= 0)
return;
ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, 0, _delEntBufferCount);
foreach (var pool in _pools)
pool.OnReleaseDelEntityBuffer(buffser);
_listeners.InvokeOnReleaseDelEntityBuffer(buffser);
for (int i = 0; i < _delEntBufferCount; i++)
_entityDispenser.Release(_delEntBuffer[i]);
_freeSpace = _entitesCapacity - _entitiesCount;
_delEntBufferCount = 0;
}
public void DeleteEmptyEntites() public void DeleteEmptyEntites()
{ {
foreach (var e in _allEntites) foreach (var e in _allEntites)
{ {
if (_componentCounts[e] <= 0) DelEntity(e); if (_componentCounts[e] <= 0)
{
DelEntity(e);
}
} }
} }
@ -304,8 +332,64 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region DelEntBuffer
//public AutoReleaseDelEntBufferLonkUnloker DisableAutoReleaseDelEntBuffer()
//{
// _isEnableReleaseDelEntBuffer = false;
// return new AutoReleaseDelEntBufferLonkUnloker(this);
//}
//public void EnableAutoReleaseDelEntBuffer()
//{
// _isEnableReleaseDelEntBuffer = true;
//}
//public readonly struct AutoReleaseDelEntBufferLonkUnloker : IDisposable
//{
// private readonly EcsWorld _source;
// public AutoReleaseDelEntBufferLonkUnloker(EcsWorld source)
// {
// _source = source;
// }
// public void Dispose()
// {
// _source.EnableAutoReleaseDelEntBuffer();
// }
//}
public void ReleaseDelEntityBufferAll()
{
ReleaseDelEntityBuffer(-1);
}
public void ReleaseDelEntityBuffer(int count)
{
if (_delEntBufferCount <= 0)
{
return;
}
if (count < 0)
{
count = _delEntBufferCount;
}
else if (count > _delEntBufferCount)
{
count = _delEntBufferCount;
}
_delEntBufferCount -= count;
ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, _delEntBufferCount, count);
for (int i = 0; i < _poolsCount; i++)
{
_pools[i].OnReleaseDelEntityBuffer(buffser);
}
_listeners.InvokeOnReleaseDelEntityBuffer(buffser);
for (int i = 0; i < buffser.Length; i++)
{
_entityDispenser.Release(buffser[i]);
}
_freeSpace += count;// _entitesCapacity - _entitiesCount;
}
#endregion
#region Upsize #region Upsize
//[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
private void Upsize() private void Upsize()
{ {
Array.Resize(ref _gens, _gens.Length << 1); Array.Resize(ref _gens, _gens.Length << 1);
@ -394,6 +478,7 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region PoolsMediator
public readonly struct PoolsMediator public readonly struct PoolsMediator
{ {
private readonly EcsWorld _world; private readonly EcsWorld _world;
@ -409,7 +494,6 @@ namespace DCFApixels.DragonECS
} }
_world = world; _world = world;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RegisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit) public void RegisterComponent(int entityID, int componentTypeID, EcsMaskBit maskBit)
{ {
@ -426,6 +510,7 @@ namespace DCFApixels.DragonECS
return _world.HasEntityComponent(entityID, maskBit); return _world.HasEntityComponent(entityID, maskBit);
} }
} }
#endregion
} }
#region Callbacks Interface #region Callbacks Interface

View File

@ -38,7 +38,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPool GetPoolUnchecked<TPool>() where TPool : IEcsPoolImplementation, new() public TPool GetPoolUnchecked<TPool>() where TPool : IEcsPoolImplementation, new()
{ {
return UncheckedGet<PoolCache<TPool>>().instance; return GetUnchecked<PoolCache<TPool>>().instance;
} }
#if UNITY_2020_3_OR_NEWER #if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
@ -54,7 +54,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TPool UncheckedGetPool<TPool>(int worldID) where TPool : IEcsPoolImplementation, new() public static TPool UncheckedGetPool<TPool>(int worldID) where TPool : IEcsPoolImplementation, new()
{ {
return UncheckedGet<PoolCache<TPool>>(worldID).instance; return GetUnchecked<PoolCache<TPool>>(worldID).instance;
} }
#endregion #endregion

View File

@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T GetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorld(worldID); public static ref T GetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorld(worldID);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T UncheckedGetData<T>(int worldID) => ref WorldComponentPool<T>.UncheckedGetForWorld(worldID); public static ref T UncheckedGetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorldUnchecked(worldID);
private abstract class DataReleaser private abstract class DataReleaser
{ {
@ -57,11 +57,24 @@ namespace DCFApixels.DragonECS
private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance; private static IEcsWorldComponent<T> _interface = EcsWorldComponentHandler<T>.instance;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Get(int itemIndex) => ref _items[itemIndex]; public static ref T Get(int itemIndex)
{
return ref _items[itemIndex];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T GetForWorld(int worldID) => ref _items[GetItemIndex(worldID)]; public static ref T GetForWorld(int worldID)
{
return ref _items[GetItemIndex(worldID)];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T UncheckedGetForWorld(int worldID) => ref _items[_mapping[worldID]]; public static ref T GetForWorldUnchecked(int worldID)
{
#if (DEBUG && !DISABLE_DEBUG)
if (_mapping[worldID] <= 0)
throw new Exception();
#endif
return ref _items[_mapping[worldID]];
}
public static int GetItemIndex(int worldID) public static int GetItemIndex(int worldID)
{ {
if (_mapping.Length < Worlds.Length) if (_mapping.Length < Worlds.Length)

View File

@ -42,15 +42,15 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup Execute() => ExecuteFor(_aspect.World.Entities); public EcsReadonlyGroup Execute() => ExecuteFor(_aspect.World.Entities);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup ExecuteFor(EcsReadonlyGroup sourceGroup) public EcsReadonlyGroup ExecuteFor(EcsSpan span)
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.Begin(); _executeMarker.Begin();
if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. if (span.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения.
if (sourceGroup.WorldID != WorldID) throw new System.ArgumentException();//TODO составить текст исключения. if (span.WorldID != WorldID) throw new System.ArgumentException();//TODO составить текст исключения.
#endif #endif
unchecked { _version++; } unchecked { _version++; }
_aspect.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); _aspect.GetIteratorFor(span).CopyTo(_filteredGroup);
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.End(); _executeMarker.End();
#endif #endif
@ -99,15 +99,15 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Execute() => ExecuteFor(_aspect.World.Entities); public EcsSpan Execute() => ExecuteFor(_aspect.World.Entities);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ExecuteFor(EcsReadonlyGroup sourceGroup) public EcsSpan ExecuteFor(EcsSpan span)
{ {
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.Begin(); _executeMarker.Begin();
if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. if (span.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения.
if (sourceGroup.WorldID != WorldID) throw new System.ArgumentException();//TODO составить текст исключения. if (span.WorldID != WorldID) throw new System.ArgumentException();//TODO составить текст исключения.
#endif #endif
unchecked { _version++; } unchecked { _version++; }
EcsSpan result = _aspect.GetIteratorFor(sourceGroup).CopyToSpan(ref _filteredEntities); EcsSpan result = _aspect.GetIteratorFor(span).CopyToSpan(ref _filteredEntities);
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
_executeMarker.End(); _executeMarker.End();
#endif #endif