This commit is contained in:
Mikhail 2024-03-17 13:43:15 +08:00
parent 492f7f41f7
commit f16e5e353c
5 changed files with 110 additions and 63 deletions

View File

@ -1,4 +1,5 @@
using DCFApixels.DragonECS.Graphs.Internal; using DCFApixels.DragonECS.Graphs.Internal;
using DCFApixels.DragonECS.UncheckedCore;
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -25,6 +26,8 @@ namespace DCFApixels.DragonECS
private bool _isLoop; private bool _isLoop;
private bool _isInit = false; private bool _isInit = false;
private int _count;
#region Properties #region Properties
internal bool IsInit_Internal internal bool IsInit_Internal
{ {
@ -46,7 +49,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld; } get { return _arcWorld; }
} }
public int ArcWorldID public short ArcWorldID
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld.id; } get { return _arcWorld.id; }
@ -56,6 +59,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _isLoop; } get { return _isLoop; }
} }
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _count; }
}
#endregion #endregion
#region Constructors/Destroy #region Constructors/Destroy
@ -120,6 +128,7 @@ namespace DCFApixels.DragonECS
int relEntityID = _arcWorld.NewEntity(); int relEntityID = _arcWorld.NewEntity();
_matrix.Add(startEntityID, endEntityID, relEntityID); _matrix.Add(startEntityID, endEntityID, relEntityID);
_relEntityInfos[relEntityID] = new RelationInfo(startEntityID, endEntityID); _relEntityInfos[relEntityID] = new RelationInfo(startEntityID, endEntityID);
_count++;
return relEntityID; return relEntityID;
} }
#endregion #endregion
@ -149,17 +158,20 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DelRelation(int relEntityID) public void DelRelation(int relEntityID)
{ {
_arcWorld.DelEntity(relEntityID); _arcWorld.TryDelEntity(relEntityID);
ClearRelation_Internal(relEntityID); //ClearRelation_Internal(relEntityID);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ClearRelation_Internal(int relEntityID) public void ClearRelation_Internal(int relEntityID)
{ {
ref RelationInfo info = ref _relEntityInfos[relEntityID]; ref RelationInfo info = ref _relEntityInfos[relEntityID];
_matrix.TryDel(info.start, info.end); if (_matrix.TryDel(info.start, info.end))
{
_count--;
info = RelationInfo.Empty; info = RelationInfo.Empty;
} }
}
#endregion #endregion
#region ArcEntityInfo #region ArcEntityInfo
@ -241,6 +253,42 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
} }
#region Loop
private class LoopWorldHandler : IEcsWorldEventListener
{
private readonly EcsArc _arc;
public LoopWorldHandler(EcsArc arc)
{
_arc = arc;
_arc.StartWorld.AddListener(this);
//OnWorldResize(_arc.StartWorld.Capacity);
}
public void Destroy()
{
_arc.StartWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
{
var graph = _arc.ArcWorld.GetExecutor<EcsJoinToGraphExecutor<EmptyAspect>>().Execute();
foreach (var e in startEntityBuffer)
{
var span = graph.GetNodes(e);
foreach (var relE in span)
{
_arc.DelRelation(relE);
}
}
_arc._arcWorld.ReleaseDelEntityBufferAll();
}
public void OnWorldDestroy() { }
public void OnWorldResize(int startWorldNewSize) { }
#endregion
}
#endregion
#region StartEnd
private class StartWorldHandler : IEcsWorldEventListener private class StartWorldHandler : IEcsWorldEventListener
{ {
private readonly EcsArc _arc; private readonly EcsArc _arc;
@ -285,28 +333,8 @@ namespace DCFApixels.DragonECS
public void OnWorldResize(int endWorldNewSize) { } public void OnWorldResize(int endWorldNewSize) { }
#endregion #endregion
} }
private class LoopWorldHandler : IEcsWorldEventListener
{
private readonly EcsArc _arc;
public LoopWorldHandler(EcsArc arc)
{
_arc = arc;
_arc.StartWorld.AddListener(this);
//OnWorldResize(_arc.StartWorld.Capacity);
}
public void Destroy()
{
_arc.StartWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
{
_arc._arcWorld.ReleaseDelEntityBufferAll();
}
public void OnWorldDestroy() { }
public void OnWorldResize(int startWorldNewSize) { }
#endregion #endregion
}
#endregion #endregion
} }
} }

View File

@ -1,9 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {

View File

@ -41,6 +41,7 @@ namespace DCFApixels.DragonECS
_baskets = new Basket[World.Capacity]; _baskets = new Basket[World.Capacity];
World.AddListener(this); World.AddListener(this);
_arcWorld = (EcsArcWorld)World; _arcWorld = (EcsArcWorld)World;
_aspect = AspectRaw;
} }
protected override void OnDestroy() protected override void OnDestroy()
{ {
@ -80,26 +81,24 @@ namespace DCFApixels.DragonECS
EcsArc arc = _arcWorld.GetRegisteredArc(); EcsArc arc = _arcWorld.GetRegisteredArc();
if (_aspect.Mask.IsEmpty)
{
foreach (var relationEntityID in span)
{
int startEntityID = arc.GetRelationStart(relationEntityID);
if (startEntityID == 0) { continue; }
Add(startEntityID, relationEntityID);
}
}
else
{
var iterator = _aspect.GetIteratorFor(span); var iterator = _aspect.GetIteratorFor(span);
foreach (var relationEntityID in iterator) foreach (var relationEntityID in iterator)
{ {
int startEntityID = arc.GetRelationStart(relationEntityID); int startEntityID = arc.GetRelationStart(relationEntityID);
if(startEntityID == 0) if (startEntityID == 0) { continue; }
{ Add(startEntityID, relationEntityID);
continue;
} }
_startEntities[_startEntitiesCount++] = startEntityID;
ref var basket = ref _baskets[startEntityID];
if (basket.index <= 0)
{
basket.index = _linkedList.Add(relationEntityID);
}
else
{
_linkedList.InsertAfter(basket.index, relationEntityID);
}
basket.count++;
} }
_lastWorldVersion = World.Version; _lastWorldVersion = World.Version;
@ -112,6 +111,21 @@ namespace DCFApixels.DragonECS
_executeMarker.End(); _executeMarker.End();
return new EcsGraph(this, UncheckedCoreUtility.CreateSpan(WorldID, _startEntities, _startEntitiesCount)); return new EcsGraph(this, UncheckedCoreUtility.CreateSpan(WorldID, _startEntities, _startEntitiesCount));
} }
private void Add(int startEntityID, int relationEntityID)
{
_startEntities[_startEntitiesCount++] = startEntityID;
ref var basket = ref _baskets[startEntityID];
if (basket.index <= 0)
{
basket.index = _linkedList.Add(relationEntityID);
}
else
{
_linkedList.InsertAfter(basket.index, relationEntityID);
}
basket.count++;
}
#endregion #endregion
#region Internal result methods #region Internal result methods
@ -156,7 +170,7 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
} }
public sealed class EcsJoinExecutor<TAspect> : EcsJoinToGraphExecutor public sealed class EcsJoinToGraphExecutor<TAspect> : EcsJoinToGraphExecutor
where TAspect : EcsAspect where TAspect : EcsAspect
{ {
private TAspect _aspect; private TAspect _aspect;
@ -169,7 +183,14 @@ namespace DCFApixels.DragonECS
} }
protected override EcsAspect AspectRaw protected override EcsAspect AspectRaw
{ {
get { return _aspect; } get
{
if (_aspect == null)
{
_aspect = World.GetAspect<TAspect>();
}
return _aspect;
}
} }
#endregion #endregion
} }

View File

@ -13,8 +13,8 @@ namespace DCFApixels.DragonECS.Graphs.Internal
private const int MAX_CHAIN_LENGTH = 5; private const int MAX_CHAIN_LENGTH = 5;
private Basket* _buckets; private UnsafeArray<Basket> _buckets;
private Entry* _entries; private UnsafeArray<Entry> _entries;
private int _capacity; private int _capacity;
private int _count; private int _count;
@ -42,12 +42,12 @@ namespace DCFApixels.DragonECS.Graphs.Internal
public SparseMatrix(int minCapacity = MIN_CAPACITY) public SparseMatrix(int minCapacity = MIN_CAPACITY)
{ {
minCapacity = NormalizeCapacity(minCapacity); minCapacity = NormalizeCapacity(minCapacity);
_buckets = UnmanagedArrayUtility.New<Basket>(minCapacity); _buckets = new UnsafeArray<Basket>(minCapacity);
for (int i = 0; i < minCapacity; i++) for (int i = 0; i < minCapacity; i++)
{ {
_buckets[i] = Basket.Empty; _buckets[i] = Basket.Empty;
} }
_entries = UnmanagedArrayUtility.NewAndInit<Entry>(minCapacity); _entries = new UnsafeArray<Entry>(minCapacity, true);
_modBitMask = (minCapacity - 1) & 0x7FFFFFFF; _modBitMask = (minCapacity - 1) & 0x7FFFFFFF;
_count = 0; _count = 0;
@ -256,26 +256,29 @@ namespace DCFApixels.DragonECS.Graphs.Internal
int newSize = _capacity << 1; int newSize = _capacity << 1;
_modBitMask = (newSize - 1) & 0x7FFFFFFF; _modBitMask = (newSize - 1) & 0x7FFFFFFF;
//newBuckets create and ini
Basket* newBuckets = UnmanagedArrayUtility.New<Basket>(newSize); Basket* newBuckets = UnmanagedArrayUtility.New<Basket>(newSize);
for (int i = 0; i < _capacity; i++) for (int i = 0; i < newSize; i++)
{ {
newBuckets[i] = Basket.Empty; newBuckets[i] = Basket.Empty;
} }
//END newBuckets create and ini
Entry* newEntries = UnmanagedArrayUtility.ResizeAndInit<Entry>(_entries, _capacity, newSize); Entry* newEntries = UnmanagedArrayUtility.ResizeAndInit<Entry>(_entries.ptr, _capacity, newSize);
for (int i = 0; i < _count; i++) for (int i = 0; i < _count; i++)
{ {
if (newEntries[i].key.yHash >= 0) if (newEntries[i].key.yHash >= 0)
{ {
int targetBusket = newEntries[i].key.yHash % newSize; int targetBusket = newEntries[i].key.yHash % _capacity;
ref Basket basket = ref _buckets[targetBusket]; ref Basket basket = ref _buckets[targetBusket];
newEntries[i].next = basket.index; newEntries[i].next = basket.index;
basket.index = i; basket.index = i;
basket.count++; basket.count++;
} }
} }
_buckets = newBuckets;
_entries = newEntries; _buckets = new UnsafeArray<Basket>(newBuckets, newSize);
_entries = new UnsafeArray<Entry>(newEntries, newSize);
_capacity = newSize; _capacity = newSize;
} }

View File

@ -47,8 +47,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
get get
{ {
#if DEBUG #if DEBUG
if (index < 0 || index >= Length) if (index < 0 || index >= Length) { Throw.ArgumentOutOfRange(); }
Throw.ArgumentOutOfRange();
#endif #endif
return ref ptr[index]; return ref ptr[index];
} }
@ -67,7 +66,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
Length = length; Length = length;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private UnsafeArray(T* ptr, int length) public UnsafeArray(T* ptr, int length)
{ {
this.ptr = ptr; this.ptr = ptr;
Length = length; Length = length;