mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
GetPool optimisation
GetPool almost 2x faster.
This commit is contained in:
parent
35d71245bc
commit
51b409d5d6
@ -123,10 +123,10 @@ namespace DCFApixels.DragonECS
|
|||||||
foreach (var item in _combined)
|
foreach (var item in _combined)
|
||||||
{
|
{
|
||||||
EcsMask submask = item.aspect.mask;
|
EcsMask submask = item.aspect.mask;
|
||||||
maskInc.ExceptWith(submask._exc);//удаляю конфликтующие ограничения
|
maskInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения
|
||||||
maskExc.ExceptWith(submask._inc);//удаляю конфликтующие ограничения
|
maskExc.ExceptWith(submask.inc);//удаляю конфликтующие ограничения
|
||||||
maskInc.UnionWith(submask._inc);
|
maskInc.UnionWith(submask.inc);
|
||||||
maskExc.UnionWith(submask._exc);
|
maskExc.UnionWith(submask.exc);
|
||||||
}
|
}
|
||||||
maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения
|
maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения
|
||||||
maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения
|
maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения
|
||||||
@ -144,7 +144,7 @@ namespace DCFApixels.DragonECS
|
|||||||
var exc = maskExc.ToArray();
|
var exc = maskExc.ToArray();
|
||||||
Array.Sort(exc);
|
Array.Sort(exc);
|
||||||
|
|
||||||
mask = new EcsMask(_world.WorldTypeID, inc, exc);
|
mask = new EcsMask(_world.id, inc, exc);
|
||||||
_world = null;
|
_world = null;
|
||||||
_inc = null;
|
_inc = null;
|
||||||
_exc = null;
|
_exc = null;
|
||||||
@ -202,24 +202,23 @@ namespace DCFApixels.DragonECS
|
|||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
public sealed class EcsMask
|
public sealed class EcsMask
|
||||||
{
|
{
|
||||||
internal readonly int _worldTypeID;
|
internal readonly int worldID;
|
||||||
/// <summary>Including constraints</summary>
|
/// <summary>Including constraints</summary>
|
||||||
internal readonly int[] _inc;
|
internal readonly int[] inc;
|
||||||
/// <summary>Excluding constraints</summary>
|
/// <summary>Excluding constraints</summary>
|
||||||
internal readonly int[] _exc;
|
internal readonly int[] exc;
|
||||||
internal EcsMask(int worldTypeID, int[] inc, int[] exc)
|
internal EcsMask(int worldID, int[] inc, int[] exc)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (worldTypeID == 0) throw new ArgumentException();
|
|
||||||
CheckConstraints(inc, exc);
|
CheckConstraints(inc, exc);
|
||||||
#endif
|
#endif
|
||||||
_worldTypeID = worldTypeID;
|
this.worldID = worldID;
|
||||||
_inc = inc;
|
this.inc = inc;
|
||||||
_exc = exc;
|
this.exc = exc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Object
|
#region Object
|
||||||
public override string ToString() => CreateLogString(_worldTypeID, _inc, _exc);
|
public override string ToString() => CreateLogString(worldID, inc, exc);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Debug utils
|
#region Debug utils
|
||||||
@ -247,10 +246,10 @@ namespace DCFApixels.DragonECS
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
private static string CreateLogString(int worldTypeID, int[] inc, int[] exc)
|
private static string CreateLogString(int worldID, int[] inc, int[] exc)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG)
|
#if (DEBUG && !DISABLE_DEBUG)
|
||||||
string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldTypeID, o), 1);
|
string converter(int o) => EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1);
|
||||||
return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})";
|
return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})";
|
||||||
#else
|
#else
|
||||||
return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization
|
return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization
|
||||||
@ -259,22 +258,22 @@ namespace DCFApixels.DragonECS
|
|||||||
internal class DebuggerProxy
|
internal class DebuggerProxy
|
||||||
{
|
{
|
||||||
public readonly Type worldType;
|
public readonly Type worldType;
|
||||||
public readonly int worldTypeID;
|
public readonly int worldID;
|
||||||
public readonly int[] included;
|
public readonly int[] included;
|
||||||
public readonly int[] excluded;
|
public readonly int[] excluded;
|
||||||
public readonly Type[] includedTypes;
|
public readonly Type[] includedTypes;
|
||||||
public readonly Type[] excludedTypes;
|
public readonly Type[] excludedTypes;
|
||||||
public DebuggerProxy(EcsMask mask)
|
public DebuggerProxy(EcsMask mask)
|
||||||
{
|
{
|
||||||
worldType = WorldMetaStorage.GetWorldType(mask._worldTypeID);
|
worldType = WorldMetaStorage.GetWorldType(mask.worldID);
|
||||||
worldTypeID = mask._worldTypeID;
|
worldID = mask.worldID;
|
||||||
included = mask._inc;
|
included = mask.inc;
|
||||||
excluded = mask._exc;
|
excluded = mask.exc;
|
||||||
Type converter(int o) => WorldMetaStorage.GetComponentType(worldTypeID, o);
|
Type converter(int o) => WorldMetaStorage.GetComponentType(worldID, o);
|
||||||
includedTypes = included.Select(converter).ToArray();
|
includedTypes = included.Select(converter).ToArray();
|
||||||
excludedTypes = excluded.Select(converter).ToArray();
|
excludedTypes = excluded.Select(converter).ToArray();
|
||||||
}
|
}
|
||||||
public override string ToString() => CreateLogString(worldTypeID, included, excluded);
|
public override string ToString() => CreateLogString(worldID, included, excluded);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -338,8 +337,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public Enumerator(EcsReadonlyGroup sourceGroup, EcsMask mask)
|
public Enumerator(EcsReadonlyGroup sourceGroup, EcsMask mask)
|
||||||
{
|
{
|
||||||
_sourceGroup = sourceGroup.GetEnumerator();
|
_sourceGroup = sourceGroup.GetEnumerator();
|
||||||
_inc = mask._inc;
|
_inc = mask.inc;
|
||||||
_exc = mask._exc;
|
_exc = mask.exc;
|
||||||
_pools = sourceGroup.World._pools;
|
_pools = sourceGroup.World._pools;
|
||||||
}
|
}
|
||||||
public int Current
|
public int Current
|
||||||
|
40
src/EcsWorld.cache.cs
Normal file
40
src/EcsWorld.cache.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using DCFApixels.DragonECS.Utils;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public partial class EcsWorld
|
||||||
|
{
|
||||||
|
internal readonly struct PoolCache<TPool> : IEcsWorldComponent<PoolCache<TPool>>
|
||||||
|
where TPool : IEcsPoolImplementation, new()
|
||||||
|
{
|
||||||
|
public readonly TPool instance;
|
||||||
|
public PoolCache(TPool instance) => this.instance = instance;
|
||||||
|
void IEcsWorldComponent<PoolCache<TPool>>.Init(ref PoolCache<TPool> component, EcsWorld world)
|
||||||
|
{
|
||||||
|
component = new PoolCache<TPool>(world.CreatePool<TPool>());
|
||||||
|
}
|
||||||
|
void IEcsWorldComponent<PoolCache<TPool>>.OnDestroy(ref PoolCache<TPool> component, EcsWorld world)
|
||||||
|
{
|
||||||
|
component = default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private TPool CreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
|
{
|
||||||
|
int index = WorldMetaStorage.GetPoolID<TPool>(_worldTypeID);
|
||||||
|
if (index >= _pools.Length)
|
||||||
|
{
|
||||||
|
int oldCapacity = _pools.Length;
|
||||||
|
Array.Resize(ref _pools, _pools.Length << 1);
|
||||||
|
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
||||||
|
}
|
||||||
|
if (_pools[index] == _nullPool)
|
||||||
|
{
|
||||||
|
var pool = new TPool();
|
||||||
|
_pools[index] = pool;
|
||||||
|
pool.OnInit(this, index);
|
||||||
|
}
|
||||||
|
return (TPool)_pools[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ using DCFApixels.DragonECS.Utils;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using typecode = System.Int32;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
@ -102,22 +103,10 @@ namespace DCFApixels.DragonECS
|
|||||||
#if UNITY_2020_3_OR_NEWER
|
#if UNITY_2020_3_OR_NEWER
|
||||||
[UnityEngine.Scripting.Preserve]
|
[UnityEngine.Scripting.Preserve]
|
||||||
#endif
|
#endif
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public TPool GetPool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public TPool GetPool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
int index = WorldMetaStorage.GetPoolID<TPool>(_worldTypeID);
|
return Get<PoolCache<TPool>>().instance;
|
||||||
if (index >= _pools.Length)
|
|
||||||
{
|
|
||||||
int oldCapacity = _pools.Length;
|
|
||||||
Array.Resize(ref _pools, _pools.Length << 1);
|
|
||||||
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
|
||||||
}
|
|
||||||
if (_pools[index] == _nullPool)
|
|
||||||
{
|
|
||||||
var pool = new TPool();
|
|
||||||
_pools[index] = pool;
|
|
||||||
pool.OnInit(this, index);
|
|
||||||
}
|
|
||||||
return (TPool)_pools[index];
|
|
||||||
}
|
}
|
||||||
public TAspect GetAspect<TAspect>() where TAspect : EcsAspect
|
public TAspect GetAspect<TAspect>() where TAspect : EcsAspect
|
||||||
{
|
{
|
||||||
@ -236,17 +225,17 @@ namespace DCFApixels.DragonECS
|
|||||||
public bool IsMatchesMask(EcsMask mask, int entityID)
|
public bool IsMatchesMask(EcsMask mask, int entityID)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||||
if (mask._worldTypeID != _worldTypeID)
|
if (mask.worldID != id)
|
||||||
throw new EcsFrameworkException("The types of the target world of the mask and this world are different.");
|
throw new EcsFrameworkException("The types of the target world of the mask and this world are different.");
|
||||||
#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;
|
||||||
|
28
src/Utils/EcsTypeCodeCache.cs
Normal file
28
src/Utils/EcsTypeCodeCache.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
namespace Internal
|
||||||
|
{
|
||||||
|
internal static class EcsTypeCode
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Type, int> _codes = new Dictionary<Type, int>();
|
||||||
|
private static int _incremetn = 1;
|
||||||
|
public static int GetCode(Type type)
|
||||||
|
{
|
||||||
|
if (!_codes.TryGetValue(type, out int code))
|
||||||
|
{
|
||||||
|
code = _incremetn++;
|
||||||
|
_codes.Add(type, code);
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
public static int Count => _codes.Count;
|
||||||
|
}
|
||||||
|
internal static class EcsTypeCodeCache<T>
|
||||||
|
{
|
||||||
|
public static readonly int code = EcsTypeCode.GetCode(typeof(T));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user