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.UncheckedCore;
using System;
using System.Runtime.CompilerServices;
@ -25,6 +26,8 @@ namespace DCFApixels.DragonECS
private bool _isLoop;
private bool _isInit = false;
private int _count;
#region Properties
internal bool IsInit_Internal
{
@ -46,7 +49,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld; }
}
public int ArcWorldID
public short ArcWorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld.id; }
@ -56,6 +59,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _isLoop; }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _count; }
}
#endregion
#region Constructors/Destroy
@ -120,6 +128,7 @@ namespace DCFApixels.DragonECS
int relEntityID = _arcWorld.NewEntity();
_matrix.Add(startEntityID, endEntityID, relEntityID);
_relEntityInfos[relEntityID] = new RelationInfo(startEntityID, endEntityID);
_count++;
return relEntityID;
}
#endregion
@ -149,16 +158,19 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void DelRelation(int relEntityID)
{
_arcWorld.DelEntity(relEntityID);
ClearRelation_Internal(relEntityID);
_arcWorld.TryDelEntity(relEntityID);
//ClearRelation_Internal(relEntityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ClearRelation_Internal(int relEntityID)
{
ref RelationInfo info = ref _relEntityInfos[relEntityID];
_matrix.TryDel(info.start, info.end);
info = RelationInfo.Empty;
if (_matrix.TryDel(info.start, info.end))
{
_count--;
info = RelationInfo.Empty;
}
}
#endregion
@ -241,6 +253,42 @@ namespace DCFApixels.DragonECS
}
#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 readonly EcsArc _arc;
@ -285,28 +333,8 @@ namespace DCFApixels.DragonECS
public void OnWorldResize(int endWorldNewSize) { }
#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
}
}

View File

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

View File

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

View File

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

View File

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