From 7c85a69ab0cea021396c3f2a21717bf8e8a6613b Mon Sep 17 00:00:00 2001
From: Mikhail <99481254+DCFApixels@users.noreply.github.com>
Date: Fri, 26 Jan 2024 21:56:03 +0800
Subject: [PATCH] update
---
src/EcsArc.cs | 4 +-
src/Utils/Arc.cs | 47 +++++++++++++
src/Utils/Exceptions.cs | 13 ++++
src/WorldGraph.cs | 147 +++++++++++++++++++++++++++-------------
4 files changed, 161 insertions(+), 50 deletions(-)
create mode 100644 src/Utils/Arc.cs
diff --git a/src/EcsArc.cs b/src/EcsArc.cs
index 996b3bc..e6e96fa 100644
--- a/src/EcsArc.cs
+++ b/src/EcsArc.cs
@@ -120,11 +120,11 @@ namespace DCFApixels.DragonECS
#region Other
public EcsArc GetInversetArc()
{
- return _endWorld.GetArcWith(_startWorld);
+ return _endWorld.GetArc(_startWorld);
}
public bool TryGetInversetArc(out EcsArc arc)
{
- return _endWorld.TryGetArcWith(_startWorld, out arc);
+ return _endWorld.TryGetArc(_startWorld, out arc);
}
#endregion
diff --git a/src/Utils/Arc.cs b/src/Utils/Arc.cs
new file mode 100644
index 0000000..321d04b
--- /dev/null
+++ b/src/Utils/Arc.cs
@@ -0,0 +1,47 @@
+using System.Runtime.CompilerServices;
+
+namespace DCFApixels.DragonECS
+{
+ public readonly struct StartArcEnd
+ {
+ /// Start vertex entity ID.
+ public readonly int start;
+ /// Arc entity ID.
+ public readonly int arc;
+ /// End vertex entity ID.
+ public readonly int end;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public StartArcEnd(int start, int arc, int end)
+ {
+ this.start = start;
+ this.arc = arc;
+ this.end = end;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Deconstruct(out int start, out int arc, out int end)
+ {
+ start = this.start;
+ arc = this.arc;
+ end = this.end;
+ }
+ }
+ public readonly struct ArcEnd
+ {
+ /// Arc entity ID.
+ public readonly int arc;
+ /// End vertex entity ID.
+ public readonly int end;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public ArcEnd(int arc, int end)
+ {
+ this.arc = arc;
+ this.end = end;
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Deconstruct(out int arc, out int end)
+ {
+ arc = this.arc;
+ end = this.end;
+ }
+ }
+}
diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs
index ff38ead..9012c46 100644
--- a/src/Utils/Exceptions.cs
+++ b/src/Utils/Exceptions.cs
@@ -1,6 +1,19 @@
using System;
+using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+namespace DCFApixels.DragonECS.Relations.Internal
+{
+ internal static class Throw
+ {
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ internal static void ArgumentNull()
+ {
+ throw new ArgumentNullException();
+ }
+ }
+}
+
namespace DCFApixels.DragonECS
{
[Serializable]
diff --git a/src/WorldGraph.cs b/src/WorldGraph.cs
index 0172f1b..2867a3b 100644
--- a/src/WorldGraph.cs
+++ b/src/WorldGraph.cs
@@ -2,97 +2,148 @@
using DCFApixels.DragonECS.Relations.Utils;
using System;
-namespace DCFApixels.DragonECS.Relations.Internal
+namespace DCFApixels.DragonECS
{
- internal static class WorldGraph
+ public static class WorldGraph
{
private static readonly SparseArray64 _matrix = new SparseArray64(4);
+ private static EcsArc[] _arcsMapping = new EcsArc[4];
- internal static EcsArc Register(EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld edgeWorld)
+ private static EcsArc Register(EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld arcWorld)
{
int startWorldID = startWorld.id;
int endWorldID = endWorld.id;
+ int arcWorldID = arcWorld.id;
+
+ if(_arcsMapping.Length <= arcWorldID)
+ {
+ Array.Resize(ref _arcsMapping, arcWorldID + 4);
+ }
+
#if DEBUG
if (_matrix.Contains(startWorldID, endWorldID))
+ {
throw new EcsFrameworkException();
+ }
#endif
- EcsArc edge = new EcsArc(startWorld, endWorld, edgeWorld);
- _matrix[startWorldID, endWorldID] = edge;
- return edge;
+ EcsArc arc = new EcsArc(startWorld, endWorld, arcWorld);
+ _matrix[startWorldID, endWorldID] = arc;
+ _arcsMapping[arcWorldID] = arc;
+ return arc;
}
- internal static void Unregister(EcsWorld startWorld, EcsWorld endWorld)
+ private static void Unregister(EcsWorld startWorld, EcsWorld endWorld)
{
int startWorldID = startWorld.id;
int endWorldID = endWorld.id;
+ EcsArc arc = _matrix[startWorldID, endWorldID];
+ _arcsMapping[arc.ArcWorld.id] = null;
_matrix.Remove(startWorldID, endWorldID);
}
- internal static EcsArc Get(EcsWorld startWorld, EcsWorld otherWorld)
+ private static EcsArc Get(EcsWorld startWorld, EcsWorld otherWorld)
{
#if DEBUG
if (!_matrix.Contains(startWorld.id, otherWorld.id))
+ {
throw new EcsFrameworkException();
+ }
#endif
return _matrix[startWorld.id, otherWorld.id];
}
- internal static bool HasArc(EcsWorld startWorld, EcsWorld endWorld) => HasArc(startWorld.id, endWorld.id);
- internal static bool HasArc(int startWorldID, int endWorldID) => _matrix.Contains(startWorldID, endWorldID);
- }
-}
+ private static bool Has(EcsWorld startWorld, EcsWorld endWorld) => Has(startWorld.id, endWorld.id);
+ private static bool Has(int startWorldID, int endWorldID) => _matrix.Contains(startWorldID, endWorldID);
-namespace DCFApixels.DragonECS
-{
- public static class WorldGraphExtensions
- {
- public static EcsArc SetLoopArc(this EcsWorld self) => SetArcWith(self, self);
- public static EcsArc SetArcWith(this EcsWorld self, EcsWorld endWorld)
+
+
+
+ #region Extension
+ public static bool IsRegistered(this EcsArcWorld self)
{
- if (self == null || endWorld == null)
- throw new ArgumentNullException();
- return WorldGraph.Register(self, endWorld, new EcsArcWorld());
+ if (self == null)
+ {
+ Throw.ArgumentNull();
+ }
+ int id = self.id;
+ return id < _arcsMapping.Length && _arcsMapping[self.id] != null;
+ }
+ public static EcsArc GetRegisteredArc(this EcsArcWorld self)
+ {
+ if (self == null)
+ {
+ Throw.ArgumentNull();
+ }
+ int id = self.id;
+ if(id < _arcsMapping.Length && _arcsMapping[self.id] == null)
+ {
+ throw new Exception();
+ }
+ return _arcsMapping[self.id];
}
- public static EcsArc SetLoopArc(this EcsWorld self, EcsArcWorld edgeWorld) => SetEdgeWith(self, self, edgeWorld);
- public static EcsArc SetEdgeWith(this EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld edgeWorld)
+
+
+ public static EcsArc SetLoopArc(this EcsWorld self) => SetArc(self, self);
+ public static EcsArc SetArc(this EcsWorld start, EcsWorld end)
{
- if (startWorld == null || endWorld == null || edgeWorld == null)
- throw new ArgumentNullException();
- return WorldGraph.Register(startWorld, endWorld, edgeWorld);
+ if (start == null || end == null)
+ {
+ Throw.ArgumentNull();
+ }
+ return Register(start, end, new EcsArcWorld());
}
- public static bool HasLoopArc(this EcsWorld self) => HasArcWith(self, self);
- public static bool HasArcWith(this EcsWorld startWorld, EcsWorld endWorld)
+ public static EcsArc SetLoopArc(this EcsWorld self, EcsArcWorld arc) => SetArc(self, self, arc);
+ public static EcsArc SetArc(this EcsWorld start, EcsWorld end, EcsArcWorld arc)
{
- if (startWorld == null || endWorld == null)
- throw new ArgumentNullException();
- return WorldGraph.HasArc(startWorld, endWorld);
+ if (start == null || end == null || arc == null)
+ {
+ Throw.ArgumentNull();
+ }
+ return Register(start, end, arc);
}
- public static EcsArc GetLoopArc(this EcsWorld self) => GetArcWith(self, self);
- public static EcsArc GetArcWith(this EcsWorld startWorld, EcsWorld endWorld)
+ public static bool HasLoopArc(this EcsWorld self) => HasArc(self, self);
+ public static bool HasArc(this EcsWorld start, EcsWorld end)
{
- if (startWorld == null || endWorld == null)
- throw new ArgumentNullException();
- return WorldGraph.Get(startWorld, endWorld);
+ if (start == null || end == null)
+ {
+ Throw.ArgumentNull();
+ }
+ return Has(start, end);
}
- public static bool TryGetLoopArc(this EcsWorld self, out EcsArc arc) => TryGetArcWith(self, self, out arc);
- public static bool TryGetArcWith(this EcsWorld startWorld, EcsWorld endWorld, out EcsArc arc)
+ public static EcsArc GetLoopArc(this EcsWorld self) => GetArc(self, self);
+ public static EcsArc GetArc(this EcsWorld start, EcsWorld end)
{
- if (startWorld == null || endWorld == null)
- throw new ArgumentNullException();
- bool result = WorldGraph.HasArc(startWorld, endWorld);
- arc = result ? WorldGraph.Get(startWorld, endWorld) : null;
+ if (start == null || end == null)
+ {
+ Throw.ArgumentNull();
+ }
+ return Get(start, end);
+ }
+
+ public static bool TryGetLoopArc(this EcsWorld self, out EcsArc arc) => TryGetArc(self, self, out arc);
+ public static bool TryGetArc(this EcsWorld start, EcsWorld end, out EcsArc arc)
+ {
+ if (start == null || end == null)
+ {
+ Throw.ArgumentNull();
+ }
+ bool result = Has(start, end);
+ arc = result ? Get(start, end) : null;
return result;
}
public static void DestroyLoopArc(this EcsWorld self) => DestroyArcWith(self, self);
- public static void DestroyArcWith(this EcsWorld startWorld, EcsWorld endWorld)
+ public static void DestroyArcWith(this EcsWorld start, EcsWorld end)
{
- if (startWorld == null || endWorld == null)
- throw new ArgumentNullException();
- WorldGraph.Get(startWorld, endWorld).ArcWorld.Destroy();
- WorldGraph.Unregister(startWorld, endWorld);
+ if (start == null || end == null)
+ {
+ Throw.ArgumentNull();
+ }
+ Get(start, end).ArcWorld.Destroy();
+ Unregister(start, end);
}
+ #endregion
}
-}
+}
\ No newline at end of file