DragonECS-Graphs/src/EcsWorldGraph.cs

200 lines
7.0 KiB
C#
Raw Normal View History

2024-03-16 13:54:50 +08:00
using DCFApixels.DragonECS.Graphs.Internal;
2023-06-29 14:25:51 +08:00
using System;
2024-01-26 21:56:03 +08:00
namespace DCFApixels.DragonECS
2023-06-29 14:25:51 +08:00
{
2024-01-29 17:40:38 +08:00
public static class EcsWorldGraph
2023-06-29 14:25:51 +08:00
{
2024-02-03 21:37:11 +08:00
private static readonly SparseArray<EcsArc> _matrix = new SparseArray<EcsArc>(4);
2024-01-26 21:56:03 +08:00
private static EcsArc[] _arcsMapping = new EcsArc[4];
2023-06-29 14:25:51 +08:00
2024-01-29 17:40:38 +08:00
#region Register/Unregister
2024-01-26 21:56:03 +08:00
private static EcsArc Register(EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld arcWorld)
2023-06-29 14:25:51 +08:00
{
2023-12-25 08:59:00 +08:00
int startWorldID = startWorld.id;
int endWorldID = endWorld.id;
2024-01-26 21:56:03 +08:00
int arcWorldID = arcWorld.id;
2024-01-31 04:25:48 +08:00
if (_arcsMapping.Length <= arcWorldID)
2024-01-26 21:56:03 +08:00
{
Array.Resize(ref _arcsMapping, arcWorldID + 4);
}
2023-06-29 14:25:51 +08:00
#if DEBUG
2023-12-25 08:59:00 +08:00
if (_matrix.Contains(startWorldID, endWorldID))
2024-01-26 21:56:03 +08:00
{
2023-06-29 14:25:51 +08:00
throw new EcsFrameworkException();
2024-01-26 21:56:03 +08:00
}
2023-06-29 14:25:51 +08:00
#endif
2024-01-26 21:56:03 +08:00
EcsArc arc = new EcsArc(startWorld, endWorld, arcWorld);
_matrix[startWorldID, endWorldID] = arc;
_arcsMapping[arcWorldID] = arc;
return arc;
2023-06-29 14:25:51 +08:00
}
2024-01-31 04:25:48 +08:00
public static bool IsRegistered(EcsArc arc)
{
return Has(arc.StartWorld.id, arc.EndWorld.id);
}
2024-01-26 21:56:03 +08:00
private static void Unregister(EcsWorld startWorld, EcsWorld endWorld)
2023-06-29 14:25:51 +08:00
{
2023-12-25 08:59:00 +08:00
int startWorldID = startWorld.id;
int endWorldID = endWorld.id;
2024-01-26 21:56:03 +08:00
EcsArc arc = _matrix[startWorldID, endWorldID];
_arcsMapping[arc.ArcWorld.id] = null;
2023-12-25 08:59:00 +08:00
_matrix.Remove(startWorldID, endWorldID);
2024-01-31 04:25:48 +08:00
arc.Destroy();
2023-06-29 14:25:51 +08:00
}
2024-01-29 17:40:38 +08:00
#endregion
2023-06-29 14:25:51 +08:00
2024-01-29 17:40:38 +08:00
#region Get/Has
2024-01-31 04:25:48 +08:00
// private static EcsArc GetOrRigister(EcsWorld startWorld, EcsWorld otherWorld)
// {
//#if DEBUG
// if (!_matrix.Contains(startWorld.id, otherWorld.id))
// {
// return Register();
// }
//#endif
// return _matrix[startWorld.id, otherWorld.id];
// }
2024-01-26 21:56:03 +08:00
private static EcsArc Get(EcsWorld startWorld, EcsWorld otherWorld)
2023-06-29 14:25:51 +08:00
{
#if DEBUG
2023-12-25 08:59:00 +08:00
if (!_matrix.Contains(startWorld.id, otherWorld.id))
2024-01-26 21:56:03 +08:00
{
2023-06-29 14:25:51 +08:00
throw new EcsFrameworkException();
2024-01-26 21:56:03 +08:00
}
2023-06-29 14:25:51 +08:00
#endif
2023-12-25 08:59:00 +08:00
return _matrix[startWorld.id, otherWorld.id];
2023-06-29 14:25:51 +08:00
}
2024-01-31 04:25:48 +08:00
private static bool Has(EcsWorld startWorld, EcsWorld endWorld)
{
return Has(startWorld.id, endWorld.id);
}
private static bool Has(int startWorldID, int endWorldID)
{
return _matrix.Contains(startWorldID, endWorldID);
}
2024-01-29 17:40:38 +08:00
#endregion
2024-01-26 21:56:03 +08:00
#region Extension
public static bool IsRegistered(this EcsArcWorld self)
{
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;
2024-01-31 04:25:48 +08:00
if (id < _arcsMapping.Length && _arcsMapping[self.id] == null)
2024-01-26 21:56:03 +08:00
{
throw new Exception();
}
return _arcsMapping[self.id];
}
2024-03-13 17:42:58 +08:00
public static EcsArc SetLoopArcAuto<TWorld>(this TWorld self, out EcsLoopArcWorld<TWorld> arcWorld, IConfigContainer config = null)
2024-01-31 04:25:48 +08:00
where TWorld : EcsWorld
{
if (self == null)
{
Throw.ArgumentNull();
}
if (typeof(TWorld) != self.GetType())
{
EcsDebug.PrintWarning($"{nameof(TWorld)} is not {self.GetType().Name}");
}
2024-02-03 21:37:11 +08:00
arcWorld = new EcsLoopArcWorld<TWorld>(config);
2024-01-31 04:25:48 +08:00
return Register(self, self, arcWorld);
}
2024-03-13 17:42:58 +08:00
public static EcsArc SetArcAuto<TStartWorld, TEndWorld>(this TStartWorld start, TEndWorld end, out EcsArcWorld<TStartWorld, TEndWorld> arcWorld, IConfigContainer config = null)
2024-01-31 04:25:48 +08:00
where TStartWorld : EcsWorld
where TEndWorld : EcsWorld
2023-06-29 14:25:51 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null)
{
Throw.ArgumentNull();
}
2024-01-31 04:25:48 +08:00
if (typeof(TStartWorld) == typeof(EcsWorld) && typeof(TEndWorld) == typeof(EcsWorld))
{
EcsDebug.PrintWarning($"{nameof(TStartWorld)} is not {start.GetType().Name} or {nameof(TEndWorld)} is not {end.GetType().Name}");
}
2024-02-03 21:37:11 +08:00
arcWorld = new EcsArcWorld<TStartWorld, TEndWorld>(config);
2024-01-31 04:25:48 +08:00
return Register(start, end, arcWorld);
}
2024-03-13 17:42:58 +08:00
public static EcsArc SetLoopArcAuto<TWorld>(this TWorld self, IConfigContainer config = null)
2024-01-31 04:25:48 +08:00
where TWorld : EcsWorld
{
2024-02-03 21:37:11 +08:00
return SetLoopArcAuto(self, out _, config);
2024-01-31 04:25:48 +08:00
}
2024-03-13 17:42:58 +08:00
public static EcsArc SetArcAuto<TStartWorld, TEndWorld>(this TStartWorld start, TEndWorld end, IConfigContainer config = null)
2024-01-31 04:25:48 +08:00
where TStartWorld : EcsWorld
where TEndWorld : EcsWorld
{
2024-02-03 21:37:11 +08:00
return SetArcAuto(start, end, out _, config);
2023-06-29 14:25:51 +08:00
}
2023-12-25 08:59:00 +08:00
2024-01-26 21:56:03 +08:00
public static EcsArc SetLoopArc(this EcsWorld self, EcsArcWorld arc) => SetArc(self, self, arc);
public static EcsArc SetArc(this EcsWorld start, EcsWorld end, EcsArcWorld arc)
2023-12-25 08:59:00 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null || arc == null)
{
Throw.ArgumentNull();
}
return Register(start, end, arc);
2023-12-25 08:59:00 +08:00
}
2024-01-26 21:56:03 +08:00
public static bool HasLoopArc(this EcsWorld self) => HasArc(self, self);
public static bool HasArc(this EcsWorld start, EcsWorld end)
2023-06-29 14:25:51 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null)
{
Throw.ArgumentNull();
}
return Has(start, end);
2023-06-29 14:25:51 +08:00
}
2024-01-26 21:56:03 +08:00
public static EcsArc GetLoopArc(this EcsWorld self) => GetArc(self, self);
public static EcsArc GetArc(this EcsWorld start, EcsWorld end)
2023-06-29 14:25:51 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null)
{
Throw.ArgumentNull();
}
return Get(start, end);
2023-06-29 14:25:51 +08:00
}
2024-01-26 21:56:03 +08:00
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)
2023-06-29 14:25:51 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null)
{
Throw.ArgumentNull();
}
bool result = Has(start, end);
arc = result ? Get(start, end) : null;
2023-12-25 08:59:00 +08:00
return result;
2023-06-29 14:25:51 +08:00
}
2023-12-25 08:59:00 +08:00
public static void DestroyLoopArc(this EcsWorld self) => DestroyArcWith(self, self);
2024-01-26 21:56:03 +08:00
public static void DestroyArcWith(this EcsWorld start, EcsWorld end)
2023-06-29 14:25:51 +08:00
{
2024-01-26 21:56:03 +08:00
if (start == null || end == null)
{
Throw.ArgumentNull();
}
Get(start, end).ArcWorld.Destroy();
Unregister(start, end);
2023-06-29 14:25:51 +08:00
}
2024-01-26 21:56:03 +08:00
#endregion
2023-06-29 14:25:51 +08:00
}
2024-01-26 21:56:03 +08:00
}