Merge branch 'dev' into new_system_layers

This commit is contained in:
DCFApixels 2025-04-04 14:51:03 +08:00
commit de751acaa5
6 changed files with 42 additions and 18 deletions

View File

@ -962,29 +962,30 @@ namespace DCFApixels.DragonECS.Internal
internal const int STACK_BUFFER_THRESHOLD = 100; internal const int STACK_BUFFER_THRESHOLD = 100;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ConvertToChuncks(EcsMaskChunck* ptr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output) internal static void ConvertToChuncks(EcsMaskChunck* bufferPtr, UnsafeArray<int> input, UnsafeArray<EcsMaskChunck> output)
{ {
for (int i = 0; i < input.Length; i++) for (int i = 0; i < input.Length; i++)
{ {
ptr[i] = EcsMaskChunck.FromID(input.ptr[i]); bufferPtr[i] = EcsMaskChunck.FromID(input.ptr[i]);
} }
for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, ptr++) for (int inputI = 0, outputI = 0; outputI < output.Length; inputI++, bufferPtr++)
{ {
int maskX = ptr->mask; int stackingMask = bufferPtr->mask;
if (maskX == 0) { continue; } if (stackingMask == 0) { continue; }
int chunkIndexX = ptr->chunkIndex; int stackingChunkIndex = bufferPtr->chunkIndex;
EcsMaskChunck* subptr = ptr; EcsMaskChunck* bufferSpanPtr = bufferPtr + 1;
for (int j = 1; j < input.Length - inputI; j++, subptr++) for (int j = 1; j < input.Length - inputI; j++, bufferSpanPtr++)
{ {
if (subptr->chunkIndex == chunkIndexX) if (bufferSpanPtr->chunkIndex == stackingChunkIndex)
{ {
maskX |= subptr->mask; stackingMask |= bufferSpanPtr->mask;
*subptr = default; *bufferSpanPtr = default;
} }
} }
output.ptr[outputI] = new EcsMaskChunck(chunkIndexX, maskX);
output.ptr[outputI] = new EcsMaskChunck(stackingChunkIndex, stackingMask);
outputI++; outputI++;
} }
} }

View File

@ -365,6 +365,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int NewEntity(int entityID) public int NewEntity(int entityID)
{ {
_entityDispenser.Upsize(entityID + 1);
#if DEBUG #if DEBUG
if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); } if (IsUsed(entityID)) { Throw.World_EntityIsAlreadyСontained(entityID); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
@ -1257,9 +1258,12 @@ namespace DCFApixels.DragonECS
{ {
EntitySlotInfo[] result = new EntitySlotInfo[_world.Count]; EntitySlotInfo[] result = new EntitySlotInfo[_world.Count];
int i = 0; int i = 0;
foreach (var e in _world.ToSpan()) using (_world.DisableAutoReleaseDelEntBuffer())
{ {
result[i++] = _world.GetEntitySlotInfoDebug(e); foreach (var e in _world.ToSpan())
{
result[i++] = _world.GetEntitySlotInfoDebug(e);
}
} }
return result; return result;
} }

View File

@ -91,10 +91,22 @@ namespace DCFApixels.DragonECS.Internal
Execute_Iternal(); Execute_Iternal();
#if DEBUG || DRAGONECS_DEEP_DEBUG #if DEBUG || DRAGONECS_DEEP_DEBUG
var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount); var newSpan = new EcsSpan(World.ID, _filteredAllEntities, _filteredAllEntitiesCount);
foreach (var e in newSpan) using (EcsGroup group = EcsGroup.New(World))
{ {
if (World.IsMatchesMask(Mask, e) == false) foreach (var e in World.Entities)
{ {
if (World.IsMatchesMask(Mask, e))
{
group.Add(e);
}
}
if (group.SetEquals(newSpan) == false)
{
int[] array = new int[_filteredAllEntities.Length];
var count = _iterator.IterateTo(World.Entities, ref array);
EcsDebug.PrintError(newSpan.ToString() + "\r\n" + group.ToSpan().ToString());
Throw.DeepDebugException(); Throw.DeepDebugException();
} }
} }

View File

@ -95,11 +95,12 @@ namespace DCFApixels.DragonECS
{ {
ref int itemIndex = ref _mapping[entityID]; ref int itemIndex = ref _mapping[entityID];
#if DEBUG #if DEBUG
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); } if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
if (itemIndex > 0) { return ref Get(entityID); } if (itemIndex > 0) { return ref Get(entityID); }
if (_isLocked) { return ref _items[0]; } if (_isLocked | _source.IsUsed(entityID) == false) { return ref _items[0]; }
#endif #endif
if (_recycledItemsCount > 0) if (_recycledItemsCount > 0)
{ {

View File

@ -104,10 +104,11 @@ namespace DCFApixels.DragonECS
public void Add(int entityID) public void Add(int entityID)
{ {
#if DEBUG #if DEBUG
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); } if (Has(entityID)) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); } if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
#elif DRAGONECS_STABILITY_MODE #elif DRAGONECS_STABILITY_MODE
if (Has(entityID) || _isLocked) { return; } if (Has(entityID) | _source.IsUsed(entityID) == false | _isLocked) { return; }
#endif #endif
_count++; _count++;
_mapping[entityID] = true; _mapping[entityID] = true;

View File

@ -118,6 +118,11 @@ namespace DCFApixels.DragonECS.Internal
throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world."); throw new InvalidOperationException($"The method {methodName} can only be executed before creating entities in the world.");
} }
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void Ent_ThrowIsNotAlive(EcsWorld world, int entityID)
{
Ent_ThrowIsNotAlive((world, entityID));
}
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void Ent_ThrowIsNotAlive(entlong entity) internal static void Ent_ThrowIsNotAlive(entlong entity)
{ {