refactoring

This commit is contained in:
Mikhail 2023-05-26 00:24:38 +08:00
parent 0e793f70ec
commit 6fd85813c3
5 changed files with 94 additions and 224 deletions

View File

@ -9,7 +9,6 @@
public const string DEBUG_WARNING_TAG = "WARNING"; public const string DEBUG_WARNING_TAG = "WARNING";
public const string DEBUG_ERROR_TAG = "ERROR"; public const string DEBUG_ERROR_TAG = "ERROR";
public const string PRE_BEGIN_LAYER = nameof(PRE_BEGIN_LAYER); public const string PRE_BEGIN_LAYER = nameof(PRE_BEGIN_LAYER);
public const string BEGIN_LAYER = nameof(BEGIN_LAYER); public const string BEGIN_LAYER = nameof(BEGIN_LAYER);
public const string BASIC_LAYER = nameof(BASIC_LAYER); public const string BASIC_LAYER = nameof(BASIC_LAYER);

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Unity.Profiling;
using delayedOp = System.Int32;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -45,7 +43,7 @@ namespace DCFApixels.DragonECS
public bool IsReleazed public bool IsReleazed
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source.IsReleazed; get => _source.IsReleased;
} }
public int this[int index] public int this[int index]
{ {
@ -93,26 +91,13 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
// индексация начинается с 1
// _delayedOps это int[] для отложенных операций, хранятся отложенные операции в виде int значения, если старший бит = 0 то это опреация добавленияб если = 1 то это операция вычитания
public unsafe class EcsGroup : IDisposable, IEquatable<EcsGroup> public unsafe class EcsGroup : IDisposable, IEquatable<EcsGroup>
{ {
private const int DEALAYED_ADD = 0;
private const int DEALAYED_REMOVE = int.MinValue;
private EcsWorld _source; private EcsWorld _source;
private int[] _dense; private int[] _dense;
private int[] _sparse; private int[] _sparse;
private int _count; private int _count;
private bool _isReleased = true;
private delayedOp[] _delayedOps;
private int _delayedOpsCount;
private int _lockCount;
private bool _isReleazed = true;
#region Properties #region Properties
public EcsWorld World => _source; public EcsWorld World => _source;
@ -136,10 +121,10 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new EcsReadonlyGroup(this); get => new EcsReadonlyGroup(this);
} }
public bool IsReleazed public bool IsReleased
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _isReleazed; get => _isReleased;
} }
public int this[int index] public int this[int index]
{ {
@ -161,27 +146,15 @@ namespace DCFApixels.DragonECS
return world.GetGroupFromPool(); return world.GetGroupFromPool();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsGroup(EcsWorld world, int denseCapacity = 64, int delayedOpsCapacity = 128) internal EcsGroup(EcsWorld world, int denseCapacity = 64)
{ {
_source = world; _source = world;
_source.RegisterGroup(this); _source.RegisterGroup(this);
_dense = new int[denseCapacity]; _dense = new int[denseCapacity];
_sparse = new int[world.Capacity]; _sparse = new int[world.Capacity];
_delayedOps = new delayedOp[delayedOpsCapacity];
_lockCount = 0;
_delayedOpsCount = 0;
_count = 0; _count = 0;
} }
//защита от криворукости
//перед сборкой мусора снова создает сильную ссылку и возвращает в пул
//TODO переделат или удалить, так как сборщик мусора просыпается только после 12к и более экземпляров, только тогда и вызывается финализатор, слишком жирно
~EcsGroup()
{
Release();
}
#endregion #endregion
#region Has #region Has
@ -211,16 +184,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void AddInternal(int entityID) internal void AddInternal(int entityID)
{ {
//if (_lockCount > 0)
//{
// AddDelayedOp(entityID, DEALAYED_ADD);
// return;
//}
AggressiveAdd(entityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void AggressiveAdd(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (Has(entityID)) ThrowAlreadyContains(entityID); if (Has(entityID)) ThrowAlreadyContains(entityID);
#endif #endif
@ -239,16 +202,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void RemoveInternal(int entityID) internal void RemoveInternal(int entityID)
{ {
//if (_lockCount > 0)
//{
// AddDelayedOp(entityID, DEALAYED_REMOVE);
// return;
//}
AggressiveRemove(entityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void AggressiveRemove(int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (!Has(entityID)) ThrowDoesNotContain(entityID); if (!Has(entityID)) ThrowDoesNotContain(entityID);
#endif #endif
@ -257,22 +210,12 @@ namespace DCFApixels.DragonECS
_sparse[entityID] = 0; _sparse[entityID] = 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void AddDelayedOp(int entityID, int isAddBitFlag)
{
if (_delayedOpsCount >= _delayedOps.Length)
{
Array.Resize(ref _delayedOps, _delayedOps.Length << 1);
}
_delayedOps[_delayedOpsCount++] = entityID | isAddBitFlag; // delayedOp = entityID add isAddBitFlag
}
public void RemoveUnusedEntityIDs() public void RemoveUnusedEntityIDs()
{ {
foreach (var e in this) foreach (var e in this)
{ {
if (!_source.IsUsed(e)) if (!_source.IsUsed(e))
AggressiveRemove(e); RemoveInternal(e);
} }
} }
#endregion #endregion
@ -299,7 +242,7 @@ namespace DCFApixels.DragonECS
if(_count > 0) if(_count > 0)
Clear(); Clear();
foreach (var item in group) foreach (var item in group)
AggressiveAdd(item); AddInternal(item);
} }
public EcsGroup Clone() public EcsGroup Clone()
{ {
@ -321,7 +264,7 @@ namespace DCFApixels.DragonECS
#endif #endif
foreach (var item in group) foreach (var item in group)
if (!Has(item)) if (!Has(item))
AggressiveAdd(item); AddInternal(item);
} }
/// <summary>as Except sets</summary> /// <summary>as Except sets</summary>
@ -335,7 +278,7 @@ namespace DCFApixels.DragonECS
#endif #endif
foreach (var item in this) foreach (var item in this)
if (group.Has(item)) if (group.Has(item))
AggressiveRemove(item); RemoveInternal(item);
} }
/// <summary>as Intersect sets</summary> /// <summary>as Intersect sets</summary>
@ -349,7 +292,7 @@ namespace DCFApixels.DragonECS
#endif #endif
foreach (var item in this) foreach (var item in this)
if (!group.Has(item)) if (!group.Has(item))
AggressiveRemove(item); RemoveInternal(item);
} }
/// <summary>as Symmetric Except sets</summary> /// <summary>as Symmetric Except sets</summary>
@ -363,9 +306,9 @@ namespace DCFApixels.DragonECS
#endif #endif
foreach (var item in group) foreach (var item in group)
if (Has(item)) if (Has(item))
AggressiveRemove(item); RemoveInternal(item);
else else
AggressiveAdd(item); AddInternal(item);
} }
#endregion #endregion
@ -380,7 +323,7 @@ namespace DCFApixels.DragonECS
EcsGroup result = a._source.GetGroupFromPool(); EcsGroup result = a._source.GetGroupFromPool();
foreach (var item in a) foreach (var item in a)
if (!b.Has(item)) if (!b.Has(item))
result.AggressiveAdd(item); result.AddInternal(item);
a._source.ReleaseGroup(a); a._source.ReleaseGroup(a);
return result; return result;
} }
@ -394,7 +337,7 @@ namespace DCFApixels.DragonECS
EcsGroup result = a._source.GetGroupFromPool(); EcsGroup result = a._source.GetGroupFromPool();
foreach (var item in a) foreach (var item in a)
if (b.Has(item)) if (b.Has(item))
result.AggressiveAdd(item); result.AddInternal(item);
a._source.ReleaseGroup(a); a._source.ReleaseGroup(a);
return result; return result;
} }
@ -407,7 +350,7 @@ namespace DCFApixels.DragonECS
#endif #endif
EcsGroup result = a._source.GetGroupFromPool(); EcsGroup result = a._source.GetGroupFromPool();
foreach (var item in a) foreach (var item in a)
result.AggressiveAdd(item); result.AddInternal(item);
foreach (var item in a) foreach (var item in a)
result.Add(item); result.Add(item);
return result; return result;
@ -415,34 +358,9 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetEnumerator #region GetEnumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Unlock()
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (_lockCount <= 0)
{
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsGroup)}.");
}
#endif
if (--_lockCount <= 0)
{
for (int i = 0; i < _delayedOpsCount; i++)
{
delayedOp op = _delayedOps[i];
if (op >= 0) //delayedOp.IsAdded
AggressiveAdd(op & int.MaxValue); //delayedOp.EcsEntity
else
AggressiveRemove(op & int.MaxValue); //delayedOp.EcsEntity
}
}
}
private ProfilerMarker _getEnumeratorReturn = new ProfilerMarker("EcsGroup.GetEnumerator");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() public Enumerator GetEnumerator()
{ {
// _lockCount++;
return new Enumerator(this); return new Enumerator(this);
} }
#endregion #endregion
@ -538,7 +456,7 @@ namespace DCFApixels.DragonECS
} }
public void Release() public void Release()
{ {
_isReleazed = true; _isReleased = true;
_source.ReleaseGroup(this); _source.ReleaseGroup(this);
} }
#endregion #endregion
@ -558,6 +476,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
#region Extensions
public static class EcsGroupExtensions public static class EcsGroupExtensions
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -571,4 +490,5 @@ namespace DCFApixels.DragonECS
if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense); if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense);
} }
} }
#endregion
} }

View File

@ -10,21 +10,6 @@ namespace DCFApixels.DragonECS
{ {
public sealed class EcsPipeline public sealed class EcsPipeline
{ {
private static EcsPipeline _empty;
public static EcsPipeline Empty
{
get
{
if(_empty == null)
{
_empty = new EcsPipeline(Array.Empty<IEcsSystem>());
_empty.Init();
_empty._isEmptyDummy = true;
}
return _empty;
}
}
private IEcsSystem[] _allSystems; private IEcsSystem[] _allSystems;
private Dictionary<Type, IEcsRunner> _runners; private Dictionary<Type, IEcsRunner> _runners;
private IEcsRunProcess _runRunnerCache; private IEcsRunProcess _runRunnerCache;
@ -350,30 +335,21 @@ namespace DCFApixels.DragonECS
public interface IEcsModule public interface IEcsModule
{ {
public void ImportSystems(EcsPipeline.Builder b); void ImportSystems(EcsPipeline.Builder b);
} }
#region Extensions #region Extensions
public static class EcsPipelineExtensions public static class EcsPipelineExtensions
{ {
public static bool IsNullOrDestroyed(this EcsPipeline self) public static bool IsNullOrDestroyed(this EcsPipeline self) => self == null || self.IsDestoryed;
{
return self == null || self.IsDestoryed;
}
public static EcsPipeline.Builder Add(this EcsPipeline.Builder self, IEnumerable<IEcsSystem> range, string layerName = null) public static EcsPipeline.Builder Add(this EcsPipeline.Builder self, IEnumerable<IEcsSystem> range, string layerName = null)
{ {
foreach (var item in range) foreach (var item in range) self.Add(item, layerName);
{
self.Add(item, layerName);
}
return self; return self;
} }
public static EcsPipeline.Builder AddUnique(this EcsPipeline.Builder self, IEnumerable<IEcsSystem> range, string layerName = null) public static EcsPipeline.Builder AddUnique(this EcsPipeline.Builder self, IEnumerable<IEcsSystem> range, string layerName = null)
{ {
foreach (var item in range) foreach (var item in range) self.AddUnique(item, layerName);
{
self.AddUnique(item, layerName);
}
return self; return self;
} }
public static EcsPipeline BuildAndInit(this EcsPipeline.Builder self) public static EcsPipeline BuildAndInit(this EcsPipeline.Builder self)
@ -382,7 +358,6 @@ namespace DCFApixels.DragonECS
result.Init(); result.Init();
return result; return result;
} }
} }
#endregion #endregion
} }

View File

@ -13,7 +13,6 @@ namespace DCFApixels.DragonECS
internal EcsWorld source; internal EcsWorld source;
[EditorBrowsable(EditorBrowsableState.Always)] [EditorBrowsable(EditorBrowsableState.Always)]
internal EcsMask mask; internal EcsMask mask;
private bool _isInit; private bool _isInit;
#region Properties #region Properties
@ -26,7 +25,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Methods #region Methods
public bool IsMatches(int entityID) => source.IsMaskCompatible(mask, entityID); public bool IsMatches(int entityID) => source.IsMatchesMask(mask, entityID);
#endregion #endregion
#region Builder #region Builder
@ -111,6 +110,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
#region Extensions
public static class EcsSubjectExtensions public static class EcsSubjectExtensions
{ {
public static EcsSubjectIterator<TSubject> GetIterator<TSubject>(this TSubject self) where TSubject : EcsSubject public static EcsSubjectIterator<TSubject> GetIterator<TSubject>(this TSubject self) where TSubject : EcsSubject
@ -122,6 +122,7 @@ namespace DCFApixels.DragonECS
return new EcsSubjectIterator<TSubject>(self, sourceGroup); return new EcsSubjectIterator<TSubject>(self, sourceGroup);
} }
} }
#endregion
#region BuilderBase #region BuilderBase
public abstract class EcsSubjectBuilderBase public abstract class EcsSubjectBuilderBase
@ -135,20 +136,18 @@ namespace DCFApixels.DragonECS
#region Mask #region Mask
public sealed class EcsMask public sealed class EcsMask
{ {
internal readonly Type WorldType; internal readonly Type _worldType;
internal readonly int[] Inc; internal readonly int[] _inc;
internal readonly int[] Exc; internal readonly int[] _exc;
public EcsMask(Type worldType, int[] inc, int[] exc) public EcsMask(Type worldType, int[] inc, int[] exc)
{ {
WorldType = worldType; _worldType = worldType;
Inc = inc; _inc = inc;
Exc = exc; _exc = exc;
} }
public override string ToString() public override string ToString()
{ {
return $"Inc({string.Join(", ", Inc)}) Exc({string.Join(", ", Exc)})"; return $"Inc({string.Join(", ", _inc)}) Exc({string.Join(", ", _exc)})";
} }
} }
#endregion #endregion
@ -181,7 +180,7 @@ namespace DCFApixels.DragonECS
group.Clear(); group.Clear();
var enumerator = GetEnumerator(); var enumerator = GetEnumerator();
while (enumerator.MoveNext()) while (enumerator.MoveNext())
group.AggressiveAdd(enumerator.Current); group.AddInternal(enumerator.Current);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() => new Enumerator(sourceGroup, s); public Enumerator GetEnumerator() => new Enumerator(sourceGroup, s);
@ -207,9 +206,9 @@ namespace DCFApixels.DragonECS
public Enumerator(EcsReadonlyGroup sourceGroup, EcsSubject subject) public Enumerator(EcsReadonlyGroup sourceGroup, EcsSubject subject)
{ {
_sourceGroup = sourceGroup.GetEnumerator(); _sourceGroup = sourceGroup.GetEnumerator();
_inc = subject.mask.Inc; _inc = subject.mask._inc;
_exc = subject.mask.Exc; _exc = subject.mask._exc;
_pools = subject.World.pools; _pools = subject.World._pools;
} }
public int Current public int Current
{ {

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -27,17 +26,17 @@ namespace DCFApixels.DragonECS
private IntDispenser _entityDispenser; private IntDispenser _entityDispenser;
private int _entitiesCount; private int _entitiesCount;
private int _entitesCapacity; private int _entitesCapacity;
private short[] _gens; //старший бит указывает на то жива ли сущьность. private short[] _gens; //старший бит указывает на то жива ли сущность
private short[] _componentCounts; private short[] _componentCounts;
private EcsGroup _allEntites; private EcsGroup _allEntites;
//буфер удаления откладывает освобождение андишников сущьностей. //буфер удаления откладывает освобождение андишников сущностей.
//Нужен для того чтобы запускать некоторые процесыы связанные с удалением сущьности не по одному при каждом удалении, а пачкой //Нужен для того чтобы запускать некоторые процесыы связанные с удалением сущности не по одному при каждом удалении, а пачкой
//В теории такой подход частично улучшает ситуацию с переполнением поколений //В теории такой подход частично улучшает ситуацию с переполнением поколений
private int[] _delEntBuffer; private int[] _delEntBuffer;
private int _delEntBufferCount; private int _delEntBufferCount;
internal IEcsPoolImplementation[] pools; internal IEcsPoolImplementation[] _pools;
private EcsNullPool _nullPool; private EcsNullPool _nullPool;
private int _poolsCount = 0; private int _poolsCount = 0;
@ -55,7 +54,7 @@ namespace DCFApixels.DragonECS
public int Count => _entitiesCount; public int Count => _entitiesCount;
public int Capacity => _entitesCapacity; //_denseEntities.Length; public int Capacity => _entitesCapacity; //_denseEntities.Length;
public EcsReadonlyGroup Entities => _allEntites.Readonly; public EcsReadonlyGroup Entities => _allEntites.Readonly;
public ReadOnlySpan<IEcsPoolImplementation> AllPools => pools;// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount); public ReadOnlySpan<IEcsPoolImplementation> AllPools => _pools;// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount);
public int PoolsCount => _poolsCount; public int PoolsCount => _poolsCount;
#endregion #endregion
@ -84,8 +83,8 @@ namespace DCFApixels.DragonECS
_entityDispenser = new IntDispenser(0); _entityDispenser = new IntDispenser(0);
_nullPool = EcsNullPool.instance; _nullPool = EcsNullPool.instance;
pools = new IEcsPoolImplementation[512]; _pools = new IEcsPoolImplementation[512];
ArrayUtility.Fill(pools, _nullPool); ArrayUtility.Fill(_pools, _nullPool);
_gens = new short[_entitesCapacity]; _gens = new short[_entitesCapacity];
_componentCounts = new short[_entitesCapacity]; _componentCounts = new short[_entitesCapacity];
@ -106,7 +105,7 @@ namespace DCFApixels.DragonECS
_entityDispenser = null; _entityDispenser = null;
//_denseEntities = null; //_denseEntities = null;
_gens = null; _gens = null;
pools = null; _pools = null;
_nullPool = null; _nullPool = null;
_subjects = null; _subjects = null;
_executors = null; _executors = null;
@ -130,23 +129,23 @@ namespace DCFApixels.DragonECS
{ {
int uniqueID = WorldMetaStorage.GetComponentId<TComponent>(_worldTypeID); int uniqueID = WorldMetaStorage.GetComponentId<TComponent>(_worldTypeID);
if (uniqueID >= pools.Length) if (uniqueID >= _pools.Length)
{ {
int oldCapacity = pools.Length; int oldCapacity = _pools.Length;
Array.Resize(ref pools, pools.Length << 1); Array.Resize(ref _pools, _pools.Length << 1);
ArrayUtility.Fill(pools, _nullPool, oldCapacity, oldCapacity - pools.Length); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
} }
if (pools[uniqueID] == _nullPool) if (_pools[uniqueID] == _nullPool)
{ {
var pool = new TPool(); var pool = new TPool();
pools[uniqueID] = pool; _pools[uniqueID] = pool;
pool.OnInit(this, uniqueID); pool.OnInit(this, uniqueID);
_poolsCount++; _poolsCount++;
//EcsDebug.Print(pool.GetType().FullName); //EcsDebug.Print(pool.GetType().FullName);
} }
return (TPool)pools[uniqueID]; return (TPool)_pools[uniqueID];
} }
#endregion #endregion
@ -258,21 +257,21 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region IsMaskCompatible #region IsMatchesMask
public bool IsMaskCompatible(EcsMask mask, int entityID) public bool IsMatchesMask(EcsMask mask, int entityID)
{ {
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (mask.WorldType != Archetype) if (mask._worldType != Archetype)
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TTableArhetype)"); throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TTableArhetype)");
#endif #endif
for (int i = 0, iMax = mask.Inc.Length; i < iMax; i++) for (int i = 0, iMax = mask._inc.Length; i < iMax; i++)
{ {
if (!pools[mask.Inc[i]].Has(entityID)) if (!_pools[mask._inc[i]].Has(entityID))
return false; return false;
} }
for (int i = 0, iMax = mask.Exc.Length; i < iMax; i++) for (int i = 0, iMax = mask._exc.Length; i < iMax; i++)
{ {
if (pools[mask.Exc[i]].Has(entityID)) if (_pools[mask._exc[i]].Has(entityID))
return false; return false;
} }
return true; return true;
@ -305,7 +304,7 @@ namespace DCFApixels.DragonECS
_groups.RemoveAt(last); _groups.RemoveAt(last);
} }
} }
foreach (var item in pools) foreach (var item in _pools)
item.OnWorldResize(_gens.Length); item.OnWorldResize(_gens.Length);
_listeners.InvokeOnWorldResize(_gens.Length); _listeners.InvokeOnWorldResize(_gens.Length);
@ -341,30 +340,30 @@ namespace DCFApixels.DragonECS
public void ReleaseDelEntityBuffer() public void ReleaseDelEntityBuffer()
{ {
ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, 0, _delEntBufferCount); ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, 0, _delEntBufferCount);
foreach (var pool in pools) foreach (var pool in _pools)
pool.OnReleaseDelEntityBuffer(buffser); pool.OnReleaseDelEntityBuffer(buffser);
_listeners.InvokeOnReleaseDelEntityBuffer(buffser); _listeners.InvokeOnReleaseDelEntityBuffer(buffser);
for (int i = 0; i < _delEntBufferCount; i++) for (int i = 0; i < _delEntBufferCount; i++)
_entityDispenser.Release(_delEntBuffer[i]); _entityDispenser.Release(_delEntBuffer[i]);
_delEntBufferCount = 0; _delEntBufferCount = 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetGen(int entityID) => _gens[entityID]; public short GetGen(int entityID) => _gens[entityID];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetComponentsCount(int entityID) => _componentCounts[entityID]; public short GetComponentsCount(int entityID) => _componentCounts[entityID];
public void DeleteEmptyEntites() public void DeleteEmptyEntites()
{ {
foreach (var e in _allEntites) foreach (var e in _allEntites)
{ {
if (_componentCounts[e] <= 0) if (_componentCounts[e] <= 0) DelEntity(e);
DelEntity(e);
} }
} }
public void CopyEntity(int fromEntityID, int toEntityID) public void CopyEntity(int fromEntityID, int toEntityID)
{ {
foreach (var pool in pools) foreach (var pool in _pools)
{ {
if(pool.Has(fromEntityID)) if(pool.Has(fromEntityID)) pool.Copy(fromEntityID, toEntityID);
pool.Copy(fromEntityID, toEntityID);
} }
} }
public int CloneEntity(int fromEntityID) public int CloneEntity(int fromEntityID)
@ -376,7 +375,7 @@ namespace DCFApixels.DragonECS
public void CloneEntity(int fromEntityID, int toEntityID) public void CloneEntity(int fromEntityID, int toEntityID)
{ {
CopyEntity(fromEntityID, toEntityID); CopyEntity(fromEntityID, toEntityID);
foreach (var pool in pools) foreach (var pool in _pools)
{ {
if (!pool.Has(fromEntityID)&& pool.Has(toEntityID)) if (!pool.Has(fromEntityID)&& pool.Has(toEntityID))
pool.Del(toEntityID); pool.Del(toEntityID);
@ -384,19 +383,14 @@ namespace DCFApixels.DragonECS
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void IncrementEntityComponentCount(int entityID) internal void IncrementEntityComponentCount(int entityID) => _componentCounts[entityID]++;
{
_componentCounts[entityID]++;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void DecrementEntityComponentCount(int entityID) internal void DecrementEntityComponentCount(int entityID)
{ {
var count = --_componentCounts[entityID]; var count = --_componentCounts[entityID];
if(count == 0 && _allEntites.Has(entityID)) if(count == 0 && _allEntites.Has(entityID)) DelEntity(entityID);
DelEntity(entityID);
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (count < 0) throw new EcsFrameworkException("нарушен баланс инкремента.декремента компонентов"); if (count < 0) throw new EcsFrameworkException("нарушен баланс инкремента/декремента компонентов");
#endif #endif
} }
#endregion #endregion
@ -408,8 +402,7 @@ namespace DCFApixels.DragonECS
} }
internal EcsGroup GetGroupFromPool() internal EcsGroup GetGroupFromPool()
{ {
if (_groupsPool.Count <= 0) if (_groupsPool.Count <= 0) return new EcsGroup(this);
return new EcsGroup(this);
return _groupsPool.Pop(); return _groupsPool.Pop();
} }
internal void ReleaseGroup(EcsGroup group) internal void ReleaseGroup(EcsGroup group)
@ -431,10 +424,10 @@ namespace DCFApixels.DragonECS
if (itemsCount == 0) if (itemsCount == 0)
return; return;
for (var i = 0; i < pools.Length; i++) for (var i = 0; i < _pools.Length; i++)
{ {
if (pools[i].Has(entityID)) if (_pools[i].Has(entityID))
list.Add(pools[i].GetRaw(entityID)); list.Add(_pools[i].GetRaw(entityID));
if (list.Count >= itemsCount) if (list.Count >= itemsCount)
break; break;
} }
@ -485,41 +478,25 @@ namespace DCFApixels.DragonECS
} }
#region Utils #region Utils
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 24)]
internal readonly struct PoolRunners
{
public readonly IEcsComponentAdd add;
public readonly IEcsComponentWrite write;
public readonly IEcsComponentDel del;
public PoolRunners(EcsPipeline pipeline)
{
add = pipeline.GetRunner<IEcsComponentAdd>();
write = pipeline.GetRunner<IEcsComponentWrite>();
del = pipeline.GetRunner<IEcsComponentDel>();
}
}
public static class WorldMetaStorage public static class WorldMetaStorage
{ {
private static List<Resizer> resizer = new List<Resizer>(); private static List<Resizer> _resizer = new List<Resizer>();
private static int tokenCount = 0; private static int _tokenCount = 0;
private static int[] componentCounts = new int[0]; private static int[] _componentCounts = new int[0];
private static int[] queryCounts = new int[0]; private static int[] _subjectsCounts = new int[0];
private static Dictionary<Type, int> _worldIds = new Dictionary<Type, int>(); private static Dictionary<Type, int> _worldIds = new Dictionary<Type, int>();
private static class WorldIndex<TWorldArchetype> private static class WorldIndex<TWorldArchetype>
{ {
public static int id = GetWorldId(typeof(TWorldArchetype)); public static int id = GetWorldId(typeof(TWorldArchetype));
} }
private static int GetToken() private static int GetToken()
{ {
tokenCount++; _tokenCount++;
Array.Resize(ref componentCounts, tokenCount); Array.Resize(ref _componentCounts, _tokenCount);
Array.Resize(ref queryCounts, tokenCount); Array.Resize(ref _subjectsCounts, _tokenCount);
foreach (var item in resizer) foreach (var item in _resizer)
item.Resize(tokenCount); item.Resize(_tokenCount);
return tokenCount - 1; return _tokenCount - 1;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetWorldId(Type archetype) public static int GetWorldId(Type archetype)
@ -557,17 +534,17 @@ namespace DCFApixels.DragonECS
public static int[] ids; public static int[] ids;
static Component() static Component()
{ {
ids = new int[tokenCount]; ids = new int[_tokenCount];
for (int i = 0; i < ids.Length; i++) for (int i = 0; i < ids.Length; i++)
ids[i] = -1; ids[i] = -1;
resizer.Add(new Resizer<T>()); _resizer.Add(new Resizer<T>());
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Get(int token) public static int Get(int token)
{ {
ref int id = ref ids[token]; ref int id = ref ids[token];
if (id < 0) if (id < 0)
id = componentCounts[token]++; id = _componentCounts[token]++;
return id; return id;
} }
} }
@ -576,17 +553,17 @@ namespace DCFApixels.DragonECS
public static int[] ids; public static int[] ids;
static Subject() static Subject()
{ {
ids = new int[tokenCount]; ids = new int[_tokenCount];
for (int i = 0; i < ids.Length; i++) for (int i = 0; i < ids.Length; i++)
ids[i] = -1; ids[i] = -1;
resizer.Add(new Resizer<T>()); _resizer.Add(new Resizer<T>());
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Get(int token) public static int Get(int token)
{ {
ref int id = ref ids[token]; ref int id = ref ids[token];
if (id < 0) if (id < 0)
id = queryCounts[token]++; id = _subjectsCounts[token]++;
return id; return id;
} }
} }
@ -595,24 +572,24 @@ namespace DCFApixels.DragonECS
public static int[] ids; public static int[] ids;
static Executor() static Executor()
{ {
ids = new int[tokenCount]; ids = new int[_tokenCount];
for (int i = 0; i < ids.Length; i++) for (int i = 0; i < ids.Length; i++)
ids[i] = -1; ids[i] = -1;
resizer.Add(new Resizer<T>()); _resizer.Add(new Resizer<T>());
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Get(int token) public static int Get(int token)
{ {
ref int id = ref ids[token]; ref int id = ref ids[token];
if (id < 0) if (id < 0)
id = queryCounts[token]++; id = _subjectsCounts[token]++;
return id; return id;
} }
} }
} }
#endregion #endregion
#region Callbacks Interface //TODO #region Callbacks Interface
public interface IEcsWorldEventListener public interface IEcsWorldEventListener
{ {
void OnWorldResize(int newSize); void OnWorldResize(int newSize);
@ -624,7 +601,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Extensions #region Extensions
public static class WorldEventListExtensions internal static class WorldEventListExtensions
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void InvokeOnWorldResize(this List<IEcsWorldEventListener> self, int newSize) public static void InvokeOnWorldResize(this List<IEcsWorldEventListener> self, int newSize)