This commit is contained in:
Mikhail 2024-01-26 21:56:03 +08:00
parent 3b3f009fa6
commit 7c85a69ab0
4 changed files with 161 additions and 50 deletions

View File

@ -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

47
src/Utils/Arc.cs Normal file
View File

@ -0,0 +1,47 @@
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
public readonly struct StartArcEnd
{
/// <summary>Start vertex entity ID.</summary>
public readonly int start;
/// <summary>Arc entity ID.</summary>
public readonly int arc;
/// <summary>End vertex entity ID.</summary>
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
{
/// <summary>Arc entity ID.</summary>
public readonly int arc;
/// <summary>End vertex entity ID.</summary>
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;
}
}
}

View File

@ -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]

View File

@ -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<EcsArc> _matrix = new SparseArray64<EcsArc>(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
}
}
}