DragonECS-Graphs/src/EcsArc.cs

306 lines
9.9 KiB
C#
Raw Normal View History

2024-01-31 04:25:48 +08:00
using DCFApixels.DragonECS.Relations.Internal;
2023-12-25 08:59:00 +08:00
using System;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
2024-01-29 17:40:38 +08:00
//Arc
//Arc world
//Rel entity
//Component
2024-01-28 02:19:49 +08:00
public class EcsArc
2023-12-25 08:59:00 +08:00
{
private readonly EcsWorld _startWorld;
private readonly EcsWorld _endWorld;
private readonly EcsArcWorld _arcWorld;
2024-01-28 02:19:49 +08:00
private readonly StartWorldHandler _startWorldHandler;
private readonly ArcWorldHandler _arcWorldHandler;
private readonly EndWorldHandler _endWorldHandler;
2024-02-01 01:17:06 +08:00
private readonly LoopWorldHandler _loopWorldHandler;
2023-12-25 08:59:00 +08:00
2024-01-29 17:40:38 +08:00
private RelEntityInfo[] _relEntityInfos; //N * (N - 1) / 2
2024-03-16 12:40:37 +08:00
private readonly SparseMatrix _matrix;
2024-01-29 17:40:38 +08:00
private bool _isLoop;
2024-01-31 04:25:48 +08:00
private bool _isInit = false;
2023-12-25 08:59:00 +08:00
#region Properties
2024-01-31 04:25:48 +08:00
internal bool IsInit_Internal
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _isInit; }
}
2024-01-29 17:40:38 +08:00
public EcsWorld StartWorld
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _startWorld; }
}
public EcsWorld EndWorld
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _endWorld; }
}
public EcsArcWorld ArcWorld
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld; }
}
public int ArcWorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _arcWorld.id; }
}
public bool IsLoop
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _isLoop; }
}
2023-12-25 08:59:00 +08:00
#endregion
2024-01-31 04:25:48 +08:00
#region Constructors/Destroy
2024-01-07 23:19:03 +08:00
internal EcsArc(EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld arcWorld)
2023-12-25 08:59:00 +08:00
{
2024-01-07 23:19:03 +08:00
_startWorld = startWorld;
_endWorld = endWorld;
2023-12-25 08:59:00 +08:00
_arcWorld = arcWorld;
2024-01-29 17:40:38 +08:00
_isLoop = startWorld == endWorld;
_relEntityInfos = new RelEntityInfo[arcWorld.Capacity];
2024-03-16 12:40:37 +08:00
_matrix = new SparseMatrix(arcWorld.Capacity);
2024-02-03 21:37:11 +08:00
_arcWorldHandler = new ArcWorldHandler(this);
2024-02-01 01:17:06 +08:00
if (_isLoop)
{
_loopWorldHandler = new LoopWorldHandler(this);
}
else
2024-01-29 17:40:38 +08:00
{
2024-02-01 01:17:06 +08:00
_startWorldHandler = new StartWorldHandler(this);
2024-01-29 17:40:38 +08:00
_endWorldHandler = new EndWorldHandler(this);
}
2024-01-07 23:19:03 +08:00
2024-01-31 04:25:48 +08:00
_isInit = true;
}
public void Destroy()
{
2024-02-01 01:17:06 +08:00
_arcWorldHandler.Destroy();
if (_isLoop)
{
_loopWorldHandler.Destroy();
}
else
2024-01-31 04:40:27 +08:00
{
2024-02-01 01:17:06 +08:00
_startWorldHandler.Destroy();
_endWorldHandler.Destroy();
2024-01-31 04:40:27 +08:00
}
2024-02-03 21:37:11 +08:00
2023-12-25 08:59:00 +08:00
}
#endregion
2024-03-16 12:40:37 +08:00
#region New
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-29 17:40:38 +08:00
public int NewRelation(int startEntityID, int endEntityID)
2023-12-25 08:59:00 +08:00
{
2024-03-16 12:40:37 +08:00
return NewRelationInternal(startEntityID, endEntityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetOrNewRelation(int startEntityID, int endEntityID)
{
if (_matrix.TryGetValue(startEntityID, endEntityID, out int relEntityID))
{
return relEntityID;
}
return NewRelationInternal(startEntityID, endEntityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int NewRelationInternal(int startEntityID, int endEntityID)
{
int relEntityID = _arcWorld.NewEntity();
_matrix.Add(startEntityID, endEntityID, relEntityID);
_relEntityInfos[relEntityID] = new RelEntityInfo(startEntityID, endEntityID);
return relEntityID;
}
#endregion
#region Has
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool HasRelation(int startEntityID, int endEntityID)
{
return _matrix.HasKey(startEntityID, endEntityID);
2023-12-25 08:59:00 +08:00
}
2024-03-16 12:40:37 +08:00
#endregion
2024-02-03 21:45:36 +08:00
2024-03-16 12:40:37 +08:00
#region Get
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetRelation(int startEntityID, int endEntityID)
{
return _matrix.GetValue(startEntityID, endEntityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGetRelation(int startEntityID, int endEntityID, out int relEntityID)
{
return _matrix.TryGetValue(startEntityID, endEntityID, out relEntityID);
}
#endregion
#region Del
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-03 21:45:36 +08:00
public void DelRelation(int relEntityID)
2023-12-25 08:59:00 +08:00
{
2024-02-03 21:45:36 +08:00
_arcWorld.DelEntity(relEntityID);
2024-03-16 12:40:37 +08:00
ClearRelation_Internal(relEntityID);
2024-01-31 04:25:48 +08:00
}
2024-01-07 23:19:03 +08:00
2024-03-16 12:40:37 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-03 21:45:36 +08:00
public void ClearRelation_Internal(int relEntityID)
2024-01-31 04:25:48 +08:00
{
2024-03-16 12:40:37 +08:00
ref RelEntityInfo info = ref _relEntityInfos[relEntityID];
_matrix.TryDel(info.start, info.end);
info = RelEntityInfo.Empty;
2023-12-25 08:59:00 +08:00
}
#endregion
#region ArcEntityInfo
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-31 04:25:48 +08:00
public bool IsRelation(int relEntityID)
2023-12-25 08:59:00 +08:00
{
2024-01-31 04:25:48 +08:00
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
{
2023-12-25 08:59:00 +08:00
return false;
2024-01-31 04:25:48 +08:00
}
return !_relEntityInfos[relEntityID].IsEmpty;
2023-12-25 08:59:00 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-31 04:25:48 +08:00
public RelEntityInfo GetRelationInfo(int relEntityID)
2023-12-25 08:59:00 +08:00
{
2024-01-31 04:25:48 +08:00
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
{
Throw.UndefinedException();
}
return _relEntityInfos[relEntityID];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetRelStart(int relEntityID)
{
return GetRelationInfo(relEntityID).start;
2023-12-25 08:59:00 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-01-31 04:25:48 +08:00
public int GetRelEnd(int relEntityID)
{
return GetRelationInfo(relEntityID).end;
}
2023-12-25 08:59:00 +08:00
#endregion
#region Other
public EcsArc GetInversetArc()
{
2024-01-26 21:56:03 +08:00
return _endWorld.GetArc(_startWorld);
2023-12-25 08:59:00 +08:00
}
public bool TryGetInversetArc(out EcsArc arc)
{
2024-01-26 21:56:03 +08:00
return _endWorld.TryGetArc(_startWorld, out arc);
2023-12-25 08:59:00 +08:00
}
#endregion
2024-01-28 02:19:49 +08:00
#region VertexWorldHandler
2024-01-31 04:25:48 +08:00
private class ArcWorldHandler : IEcsWorldEventListener
2023-12-25 08:59:00 +08:00
{
2024-01-28 02:19:49 +08:00
private readonly EcsArc _arc;
public ArcWorldHandler(EcsArc arc)
{
_arc = arc;
2024-01-31 04:25:48 +08:00
_arc.ArcWorld.AddListener(this);
}
public void Destroy()
{
_arc.ArcWorld.RemoveListener(this);
2024-01-28 02:19:49 +08:00
}
#region Callbacks
2024-01-31 04:25:48 +08:00
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> relEntityBuffer)
2024-01-28 02:19:49 +08:00
{
2024-01-31 04:25:48 +08:00
foreach (var relEntityID in relEntityBuffer)
2024-01-28 02:19:49 +08:00
{
2024-02-03 21:45:36 +08:00
//var (startEntityID, endEntityID) = _arc._relEntityInfos[relEntityID];
//_arc.ClearRelation_Internal(startEntityID, endEntityID);
_arc.ClearRelation_Internal(relEntityID);
2024-01-28 02:19:49 +08:00
}
}
2024-01-29 17:40:38 +08:00
public void OnWorldDestroy() { }
2024-01-31 04:25:48 +08:00
public void OnWorldResize(int arcWorldNewSize)
2024-01-28 02:19:49 +08:00
{
2024-01-31 04:25:48 +08:00
Array.Resize(ref _arc._relEntityInfos, arcWorldNewSize);
2024-01-28 02:19:49 +08:00
}
#endregion
2023-12-25 08:59:00 +08:00
}
2024-01-31 04:25:48 +08:00
private class StartWorldHandler : IEcsWorldEventListener
2024-01-07 23:19:03 +08:00
{
2024-01-28 02:19:49 +08:00
private readonly EcsArc _arc;
2024-01-29 17:40:38 +08:00
public StartWorldHandler(EcsArc arc)
2024-01-28 02:19:49 +08:00
{
_arc = arc;
2024-01-31 04:25:48 +08:00
_arc.StartWorld.AddListener(this);
2024-02-03 21:37:11 +08:00
OnWorldResize(_arc.StartWorld.Capacity);
2024-01-31 04:25:48 +08:00
}
public void Destroy()
{
_arc.StartWorld.RemoveListener(this);
2024-01-28 02:19:49 +08:00
}
#region Callbacks
2024-01-31 04:25:48 +08:00
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
2024-01-28 02:19:49 +08:00
{
2024-02-03 21:37:11 +08:00
_arc._arcWorld.ReleaseDelEntityBufferAll();
2024-01-28 02:19:49 +08:00
}
2024-01-29 17:40:38 +08:00
public void OnWorldDestroy() { }
2024-02-22 17:12:28 +08:00
public void OnWorldResize(int startWorldNewSize) { }
2024-01-28 02:19:49 +08:00
#endregion
}
2024-01-31 04:25:48 +08:00
private class EndWorldHandler : IEcsWorldEventListener
2023-12-25 08:59:00 +08:00
{
2024-01-28 02:19:49 +08:00
private readonly EcsArc _arc;
2024-01-29 17:40:38 +08:00
public EndWorldHandler(EcsArc arc)
2023-12-25 08:59:00 +08:00
{
2024-01-28 02:19:49 +08:00
_arc = arc;
2024-01-31 04:25:48 +08:00
_arc.EndWorld.AddListener(this);
2024-02-03 21:37:11 +08:00
OnWorldResize(_arc.EndWorld.Capacity);
2024-01-31 04:25:48 +08:00
}
public void Destroy()
{
_arc.EndWorld.RemoveListener(this);
2023-12-25 08:59:00 +08:00
}
2024-01-07 23:19:03 +08:00
#region Callbacks
2024-01-31 04:25:48 +08:00
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> endEntityBuffer)
2024-01-07 23:19:03 +08:00
{
2024-02-03 21:37:11 +08:00
_arc._arcWorld.ReleaseDelEntityBufferAll();
2024-01-07 23:19:03 +08:00
}
2024-01-29 17:40:38 +08:00
public void OnWorldDestroy() { }
2024-02-22 17:12:28 +08:00
public void OnWorldResize(int endWorldNewSize) { }
2024-01-07 23:19:03 +08:00
#endregion
2023-12-25 08:59:00 +08:00
}
2024-02-01 01:17:06 +08:00
private class LoopWorldHandler : IEcsWorldEventListener
{
private readonly EcsArc _arc;
public LoopWorldHandler(EcsArc arc)
{
_arc = arc;
_arc.StartWorld.AddListener(this);
2024-02-03 21:37:11 +08:00
OnWorldResize(_arc.StartWorld.Capacity);
2024-02-01 01:17:06 +08:00
}
public void Destroy()
{
_arc.StartWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
{
2024-02-03 21:37:11 +08:00
_arc._arcWorld.ReleaseDelEntityBufferAll();
2024-02-01 01:17:06 +08:00
}
public void OnWorldDestroy() { }
2024-02-22 17:12:28 +08:00
public void OnWorldResize(int startWorldNewSize) { }
2024-02-01 01:17:06 +08:00
#endregion
}
2023-12-25 08:59:00 +08:00
#endregion
}
}