update pool init/AllowedInWorldsAttribute

This commit is contained in:
DCFApixels 2025-05-19 14:41:05 +08:00
parent d181fd3729
commit e8bdb01e37
8 changed files with 68 additions and 53 deletions

View File

@ -35,7 +35,7 @@ namespace DCFApixels.DragonECS
void IEcsWorldComponent<AspectCache<T>>.Init(ref AspectCache<T> component, EcsWorld world) void IEcsWorldComponent<AspectCache<T>>.Init(ref AspectCache<T> component, EcsWorld world)
{ {
#if DEBUG #if DEBUG
AllowedInWorldsAttribute.CheckAllows<T>(world); AllowedInWorldsAttribute.CheckAllows(world, typeof(T));
#endif #endif
var result = EcsAspect.Builder.New<T>(world); var result = EcsAspect.Builder.New<T>(world);
component = new AspectCache<T>(result.aspect, result.mask); component = new AspectCache<T>(result.aspect, result.mask);

View File

@ -31,9 +31,13 @@ namespace DCFApixels.DragonECS
[DataMember] public int PoolsCapacity; [DataMember] public int PoolsCapacity;
[DataMember] public int PoolComponentsCapacity; [DataMember] public int PoolComponentsCapacity;
[DataMember] public int PoolRecycledComponentsCapacity; [DataMember] public int PoolRecycledComponentsCapacity;
public EcsWorldConfig() : this(512) { } public EcsWorldConfig(int entitiesCapacity = 512, int groupCapacity = 512, int poolsCapacity = 512, int poolComponentsCapacity = 512, int poolRecycledComponentsCapacity = -1)
public EcsWorldConfig(int entitiesCapacity = 512, int groupCapacity = 512, int poolsCapacity = 512, int poolComponentsCapacity = 512, int poolRecycledComponentsCapacity = 512 / 2)
{ {
if (poolRecycledComponentsCapacity < 0)
{
poolComponentsCapacity = poolComponentsCapacity / 4;
}
EntitiesCapacity = entitiesCapacity; EntitiesCapacity = entitiesCapacity;
GroupCapacity = groupCapacity; GroupCapacity = groupCapacity;
PoolsCapacity = poolsCapacity; PoolsCapacity = poolsCapacity;

View File

@ -161,14 +161,14 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region FindOrAutoCreatePool/InitPool #region FindOrAutoCreatePool/InitPool
public void InitPool(IEcsPoolImplementation poolImplementation) public void InitPoolInstance(IEcsPoolImplementation poolImplementation)
{ {
#if DEBUG #if DEBUG
if (Count > 0) { Throw.World_MethodCalledAfterEntityCreation(nameof(InitEntitySlot)); } if (Count > 0) { Throw.World_MethodCalledAfterEntityCreation(nameof(InitEntitySlot)); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
if (Count > 0) { return; } if (Count > 0) { return; }
#endif #endif
InitPool_Internal(poolImplementation); InitPoolInstance_Internal(poolImplementation);
} }
private TPool FindOrAutoCreatePool<TPool>() where TPool : IEcsPoolImplementation, new() private TPool FindOrAutoCreatePool<TPool>() where TPool : IEcsPoolImplementation, new()
{ {
@ -184,14 +184,17 @@ namespace DCFApixels.DragonECS
return (TPool)pool; return (TPool)pool;
} }
TPool newPool = new TPool(); TPool newPool = new TPool();
InitPool_Internal(newPool); InitPoolInstance_Internal(newPool);
return newPool; return newPool;
} }
} }
private void InitPool_Internal(IEcsPoolImplementation newPool) private void InitPoolInstance_Internal(IEcsPoolImplementation newPool)
{ {
lock (_worldLock) lock (_worldLock)
{ {
#if DEBUG
AllowedInWorldsAttribute.CheckAllows(this, newPool.ComponentType);
#endif
int poolTypeCode = (int)EcsTypeCodeManager.Get(newPool.GetType()); int poolTypeCode = (int)EcsTypeCodeManager.Get(newPool.GetType());
if (_poolTypeCode_2_CmpTypeIDs.Contains(poolTypeCode)) if (_poolTypeCode_2_CmpTypeIDs.Contains(poolTypeCode))
{ {

View File

@ -207,7 +207,7 @@ namespace DCFApixels.DragonECS
} }
#if DEBUG #if DEBUG
AllowedInWorldsAttribute.CheckAllows<T>(_worlds[worldID]); AllowedInWorldsAttribute.CheckAllows(_worlds[worldID], typeof(T));
#endif #endif
_interface.Init(ref _items[itemIndex], _worlds[worldID]); _interface.Init(ref _items[itemIndex], _worlds[worldID]);

View File

@ -90,6 +90,39 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region Constructors/Init/Destroy
public EcsPool() { }
public EcsPool(int capacity, int recycledCapacity = -1)
{
capacity = ArrayUtility.NextPow2(capacity);
if (recycledCapacity < 0)
{
recycledCapacity = capacity / 2;
}
_items = new T[capacity];
_recycledItems = new int[recycledCapacity];
}
void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
{
_source = world;
_mediator = mediator;
_componentTypeID = componentTypeID;
_maskBit = EcsMaskChunck.FromID(componentTypeID);
_mapping = new int[world.Capacity];
var worldConfig = world.Configs.GetWorldConfigOrDefault();
if (_items == null)
{
_items = new T[ArrayUtility.NextPow2(worldConfig.PoolComponentsCapacity)];
}
if (_recycledItems == null)
{
_recycledItems = new int[worldConfig.PoolRecycledComponentsCapacity];
}
}
void IEcsPoolImplementation.OnWorldDestroy() { }
#endregion
#region Methods #region Methods
public ref T Add(int entityID) public ref T Add(int entityID)
{ {
@ -261,26 +294,11 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Callbacks #region Callbacks
void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
{
#if DEBUG
AllowedInWorldsAttribute.CheckAllows<T>(world);
#endif
_source = world;
_mediator = mediator;
_componentTypeID = componentTypeID;
_maskBit = EcsMaskChunck.FromID(componentTypeID);
_mapping = new int[world.Capacity];
_items = new T[ArrayUtility.NextPow2(world.Configs.GetWorldConfigOrDefault().PoolComponentsCapacity)];
_recycledItems = new int[world.Configs.GetWorldConfigOrDefault().PoolRecycledComponentsCapacity];
}
void IEcsPoolImplementation.OnWorldResize(int newSize) void IEcsPoolImplementation.OnWorldResize(int newSize)
{ {
Array.Resize(ref _mapping, newSize); Array.Resize(ref _mapping, newSize);
} }
void IEcsPoolImplementation.OnWorldDestroy() { }
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
{ {
if (_itemsCount <= 0) if (_itemsCount <= 0)

View File

@ -26,13 +26,6 @@ namespace DCFApixels.DragonECS.PoolsCore
/// <typeparam name="T"> Component type. </typeparam> /// <typeparam name="T"> Component type. </typeparam>
public interface IEcsPoolImplementation<T> : IEcsPoolImplementation { } public interface IEcsPoolImplementation<T> : IEcsPoolImplementation { }
//TODO
//public interface IEcsReadonlyPoolImplementation<TPool> : IEcsReadonlyPool
// where TPool : IEcsReadonlyPoolImplementation<TPool>
//{
// void Init(ref TPool pool);
//}
#region EcsPoolThrowHelper #region EcsPoolThrowHelper
public static class EcsPoolThrowHelper public static class EcsPoolThrowHelper
{ {

View File

@ -60,13 +60,6 @@ namespace DCFApixels.DragonECS
_isInvalidType = typeof(T).GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Length > 0; _isInvalidType = typeof(T).GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic).Length > 0;
#pragma warning restore IL2090 #pragma warning restore IL2090
} }
public EcsTagPool()
{
if (_isInvalidType)
{
throw new Exception($"{typeof(T).Name} type must not contain any data.");
}
}
#endif #endif
#endregion #endregion
@ -100,6 +93,25 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region Constructors/Init/Destroy
public EcsTagPool()
{
#if DEBUG
if (_isInvalidType) { Throw.Exception($"{typeof(T).Name} type must not contain any data."); }
#endif
}
void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
{
_source = world;
_mediator = mediator;
_componentTypeID = componentTypeID;
_maskBit = EcsMaskChunck.FromID(componentTypeID);
_mapping = new bool[world.Capacity];
}
void IEcsPoolImplementation.OnWorldDestroy() { }
#endregion
#region Method #region Method
public void Add(int entityID) public void Add(int entityID)
{ {
@ -218,24 +230,11 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Callbacks #region Callbacks
void IEcsPoolImplementation.OnInit(EcsWorld world, EcsWorld.PoolsMediator mediator, int componentTypeID)
{
#if DEBUG
AllowedInWorldsAttribute.CheckAllows<T>(world);
#endif
_source = world;
_mediator = mediator;
_componentTypeID = componentTypeID;
_maskBit = EcsMaskChunck.FromID(componentTypeID);
_mapping = new bool[world.Capacity];
}
void IEcsPoolImplementation.OnWorldResize(int newSize) void IEcsPoolImplementation.OnWorldResize(int newSize)
{ {
Array.Resize(ref _mapping, newSize); Array.Resize(ref _mapping, newSize);
} }
void IEcsPoolImplementation.OnWorldDestroy() { }
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
{ {

View File

@ -15,10 +15,8 @@ namespace DCFApixels.DragonECS
AllowedWorlds = allowedWorlds; AllowedWorlds = allowedWorlds;
} }
public static void CheckAllows(EcsWorld world, Type componentType)
public static void CheckAllows<T>(EcsWorld world)
{ {
Type componentType = typeof(T);
Type worldType = world.GetType(); Type worldType = world.GetType();
if (componentType.TryGetAttribute(out AllowedInWorldsAttribute attribute)) if (componentType.TryGetAttribute(out AllowedInWorldsAttribute attribute))
{ {