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)
{
#if DEBUG
AllowedInWorldsAttribute.CheckAllows<T>(world);
AllowedInWorldsAttribute.CheckAllows(world, typeof(T));
#endif
var result = EcsAspect.Builder.New<T>(world);
component = new AspectCache<T>(result.aspect, result.mask);

View File

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

View File

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

View File

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

View File

@ -90,6 +90,39 @@ namespace DCFApixels.DragonECS
}
#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
public ref T Add(int entityID)
{
@ -261,26 +294,11 @@ namespace DCFApixels.DragonECS
#endregion
#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)
{
Array.Resize(ref _mapping, newSize);
}
void IEcsPoolImplementation.OnWorldDestroy() { }
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
{
if (_itemsCount <= 0)

View File

@ -26,13 +26,6 @@ namespace DCFApixels.DragonECS.PoolsCore
/// <typeparam name="T"> Component type. </typeparam>
public interface IEcsPoolImplementation<T> : IEcsPoolImplementation { }
//TODO
//public interface IEcsReadonlyPoolImplementation<TPool> : IEcsReadonlyPool
// where TPool : IEcsReadonlyPoolImplementation<TPool>
//{
// void Init(ref TPool pool);
//}
#region 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;
#pragma warning restore IL2090
}
public EcsTagPool()
{
if (_isInvalidType)
{
throw new Exception($"{typeof(T).Name} type must not contain any data.");
}
}
#endif
#endregion
@ -100,6 +93,25 @@ namespace DCFApixels.DragonECS
}
#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
public void Add(int entityID)
{
@ -218,24 +230,11 @@ namespace DCFApixels.DragonECS
#endregion
#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)
{
Array.Resize(ref _mapping, newSize);
}
void IEcsPoolImplementation.OnWorldDestroy() { }
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
{

View File

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