mirror of
https://github.com/DCFApixels/DragonECS-Graphs.git
synced 2025-11-12 18:15:55 +08:00
api polishing
This commit is contained in:
parent
c7919eaa5a
commit
fa05cf3097
@ -22,6 +22,7 @@ namespace DCFApixels.DragonECS
|
||||
private int _count;
|
||||
|
||||
private bool _isInit = false;
|
||||
private bool _isDestroyed = false;
|
||||
|
||||
#region Properties
|
||||
internal bool IsInit_Internal
|
||||
@ -77,12 +78,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region New/Convert
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int NewRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
return NewRelationInternal(startEntityID, endEntityID);
|
||||
}
|
||||
#region New
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetOrNewRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
@ -92,40 +88,24 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
return NewRelationInternal(startEntityID, endEntityID);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetOrNewInverseRelation(int relEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
var info = _relEntityInfos[relEntityID];
|
||||
return GetOrNewRelation(info.end, info.start);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private int NewRelationInternal(int startEntityID, int endEntityID)
|
||||
{
|
||||
int relEntityID = _graphWorld.NewEntity();
|
||||
ConvertToRelationInternal(relEntityID, startEntityID, endEntityID);
|
||||
return relEntityID;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ConvertToRelation(int entityID, int startEntityID, int endEntityID)
|
||||
{
|
||||
if (IsRelation(entityID))
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
ConvertToRelationInternal(entityID, startEntityID, endEntityID);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ConvertToRelationInternal(int relEntityID, int startEntityID, int endEntityID)
|
||||
{
|
||||
_matrix.Add(startEntityID, endEntityID, relEntityID);
|
||||
_relEntityInfos[relEntityID] = new RelationInfo(startEntityID, endEntityID);
|
||||
_count++;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Inverse
|
||||
public int GetInverseRelation(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
var x = _relEntityInfos[relEntityID];
|
||||
return GetOrNewRelation(x.end, x.start);
|
||||
return relEntityID;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -138,42 +118,27 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsRelation(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
return false;
|
||||
return relEntityID > 0 &&
|
||||
relEntityID < _relEntityInfos.Length &&
|
||||
_relEntityInfos[relEntityID].IsNull == false;
|
||||
}
|
||||
return !_relEntityInfos[relEntityID].IsNull;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MoveRelation
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
//private void MoveRelation(int relEntityID, int newStartEntityID, int newEndEntityID)
|
||||
//{
|
||||
// var startEnd = GetRelationStartEnd(relEntityID);
|
||||
//
|
||||
// //Тут будет не стабильное состояние если TryDel пройдет, а TryAdd - нет
|
||||
// if (_matrix.TryDel(startEnd.start, startEnd.end) == false ||
|
||||
// _matrix.TryAdd(newStartEntityID, newEndEntityID, relEntityID) == false)
|
||||
// {
|
||||
// Throw.UndefinedException();
|
||||
// }
|
||||
//
|
||||
// _relEntityInfos[relEntityID] = new RelationInfo(newStartEntityID, newEndEntityID);
|
||||
//}
|
||||
#endregion
|
||||
|
||||
#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);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryGetInverseRelation(int relEntityID, out int inverseRelEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
var info = _relEntityInfos[relEntityID];
|
||||
return _matrix.TryGetValue(info.end, info.start, out inverseRelEntityID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Del
|
||||
@ -196,42 +161,38 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
public static implicit operator EntityGraph(SingletonMarker marker) { return marker.Builder.World.GetGraph(); }
|
||||
#endregion
|
||||
|
||||
#region RelEntityInfo
|
||||
|
||||
#region GetRelInfo
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public StartEnd GetRelationStartEnd(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
return new StartEnd(_relEntityInfos[relEntityID]);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetRelationStart(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
return _relEntityInfos[relEntityID].start;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetRelationEnd(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); }
|
||||
#endif
|
||||
return _relEntityInfos[relEntityID].end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GraphWorldHandler
|
||||
#region Other
|
||||
public static implicit operator EntityGraph(SingletonMarker marker) { return marker.Builder.World.GetGraph(); }
|
||||
#endregion
|
||||
|
||||
#region WorldHandlers
|
||||
private class GraphWorldHandler : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EntityGraph _arc;
|
||||
@ -259,9 +220,6 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WorldHandler
|
||||
private class WorldHandler : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EntityGraph _graph;
|
||||
|
||||
@ -7,6 +7,10 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
private static EntityGraph[] _worldGraphs = new EntityGraph[4];
|
||||
|
||||
public static EntityGraph CreateGraph(this EcsWorld self)
|
||||
{
|
||||
return self.CreateGraph(self);
|
||||
}
|
||||
public static EntityGraph CreateGraph(this EcsWorld self, EcsWorld graphWorld)
|
||||
{
|
||||
int worldID = self.ID;
|
||||
@ -25,6 +29,10 @@ namespace DCFApixels.DragonECS
|
||||
return graph;
|
||||
}
|
||||
|
||||
public static EntityGraph CreateOrGetGraph(this EcsWorld self)
|
||||
{
|
||||
return self.CreateGraph(self);
|
||||
}
|
||||
public static EntityGraph CreateOrGetGraph(this EcsWorld self, EcsWorld graphWorld)
|
||||
{
|
||||
int worldID = self.ID;
|
||||
@ -73,14 +81,15 @@ namespace DCFApixels.DragonECS
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void TryDestroy(EntityGraph graph)
|
||||
#region Internal Destroy
|
||||
private static void TryDestroyGraph(EntityGraph graph)
|
||||
{
|
||||
int worldID = graph.WorldID;
|
||||
short worldID = graph.WorldID;
|
||||
if (_worldGraphs.Length <= worldID)
|
||||
{
|
||||
Array.Resize(ref _worldGraphs, worldID + 4);
|
||||
}
|
||||
int graphWorldID = graph.GraphWorldID;
|
||||
short graphWorldID = graph.GraphWorldID;
|
||||
if (_worldGraphs.Length <= graphWorldID)
|
||||
{
|
||||
Array.Resize(ref _worldGraphs, graphWorldID + 4);
|
||||
@ -100,9 +109,10 @@ namespace DCFApixels.DragonECS
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer) { }
|
||||
public void OnWorldDestroy()
|
||||
{
|
||||
TryDestroy(_graph);
|
||||
TryDestroyGraph(_graph);
|
||||
}
|
||||
public void OnWorldResize(int newSize) { }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -96,7 +96,6 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
||||
// обновляем под новое значение _modBitMask
|
||||
targetBucket = hash & _modBitMask;
|
||||
}
|
||||
//index = Interlocked.Increment(ref _count);
|
||||
index = _count++;
|
||||
}
|
||||
else
|
||||
@ -281,7 +280,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal
|
||||
public override string ToString() { return key == 0 ? "NULL" : $"{key} {value}"; }
|
||||
}
|
||||
|
||||
public static class KeyUtility
|
||||
private static class KeyUtility
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static long FromXY(int x, int y)
|
||||
|
||||
66
src/Utils/RelInfo.cs
Normal file
66
src/Utils/RelInfo.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using DCFApixels.DragonECS.Graphs.Internal;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
||||
public readonly ref struct StartEnd
|
||||
{
|
||||
/// <summary>Start vertex entity ID.</summary>
|
||||
public readonly int start;
|
||||
/// <summary>End vertex entity ID.</summary>
|
||||
public readonly int end;
|
||||
|
||||
#region Properties
|
||||
public bool IsNull
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return start == 0 && end == 0; }
|
||||
}
|
||||
public bool IsLoop
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return start == end; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor/Deconstruct
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal StartEnd(RelationInfo relInfo)
|
||||
{
|
||||
start = relInfo.start;
|
||||
end = relInfo.end;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal StartEnd(int startEntity, int endEntity)
|
||||
{
|
||||
start = startEntity;
|
||||
end = endEntity;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int start, out int end)
|
||||
{
|
||||
start = this.start;
|
||||
end = this.end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region operators
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(StartEnd a, StartEnd b) { return a.start == b.start && a.end == b.end; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(StartEnd a, StartEnd b) { return a.start != b.start || a.end != b.end; }
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
public override int GetHashCode() { throw new NotSupportedException(); }
|
||||
public override bool Equals(object obj) { throw new NotSupportedException(); }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(StartEnd other) { return this == other; }
|
||||
public override string ToString() { return $"arc({start} -> {end})"; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,170 +0,0 @@
|
||||
using DCFApixels.DragonECS.Graphs.Internal;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
||||
[Serializable]
|
||||
public readonly ref struct StartEnd
|
||||
{
|
||||
/// <summary>Start vertex entity ID.</summary>
|
||||
public readonly int start;
|
||||
/// <summary>End vertex entity ID.</summary>
|
||||
public readonly int end;
|
||||
|
||||
#region Properties
|
||||
public bool IsNull
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return start == 0 && end == 0; }
|
||||
}
|
||||
public bool IsLoop
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return start == end; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor/Deconstruct
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal StartEnd(RelationInfo relInfo)
|
||||
{
|
||||
start = relInfo.start;
|
||||
end = relInfo.end;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal StartEnd(int startEntity, int endEntity)
|
||||
{
|
||||
start = startEntity;
|
||||
end = endEntity;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int start, out int end)
|
||||
{
|
||||
start = this.start;
|
||||
end = this.end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region operators
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(StartEnd a, StartEnd b) { return a.start == b.start && a.end == b.end; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(StartEnd a, StartEnd b) { return a.start != b.start || a.end != b.end; }
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
public override bool Equals(object obj) { throw new NotImplementedException(); }
|
||||
public override int GetHashCode() { throw new NotImplementedException(); }
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(StartEnd other) { return this == other; }
|
||||
public override string ToString() { return $"arc({start} -> {end})"; }
|
||||
#endregion
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 12)]
|
||||
[Serializable]
|
||||
public readonly ref struct StartRelEnd
|
||||
{
|
||||
/// <summary>Start vertex entity ID.</summary>
|
||||
public readonly int start;
|
||||
/// <summary>Relation entity ID.</summary>
|
||||
public readonly int rel;
|
||||
/// <summary>End vertex entity ID.</summary>
|
||||
public readonly int end;
|
||||
|
||||
#region Properties
|
||||
public bool IsNull
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return rel == 0 || (start == 0 && end == 0); }
|
||||
}
|
||||
public bool IsLoop
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return start == end; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor/Deconstruct
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public StartRelEnd(int start, int rel, int end)
|
||||
{
|
||||
this.start = start;
|
||||
this.rel = rel;
|
||||
this.end = end;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int start, out int rel, out int end)
|
||||
{
|
||||
start = this.start;
|
||||
rel = this.rel;
|
||||
end = this.end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region operators
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(StartRelEnd a, StartRelEnd b) { return a.start == b.start && a.rel == b.rel && a.end == b.end; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(StartRelEnd a, StartRelEnd b) { return a.start != b.start || a.rel != b.rel || a.end != b.end; }
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
public override bool Equals(object obj) { throw new NotImplementedException(); }
|
||||
public override int GetHashCode() { throw new NotImplementedException(); }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(StartRelEnd other) { return this == other; }
|
||||
public override string ToString() { return $"arc({start} --({rel})-> {end})"; }
|
||||
#endregion
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
||||
[Serializable]
|
||||
public readonly ref struct RelEnd
|
||||
{
|
||||
/// <summary>Relation entity ID.</summary>
|
||||
public readonly int rel;
|
||||
/// <summary>End vertex entity ID.</summary>
|
||||
public readonly int end;
|
||||
|
||||
#region Properties
|
||||
public bool IsNull
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return rel == 0; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructor/Deconstruct
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public RelEnd(int rel, int end)
|
||||
{
|
||||
this.rel = rel;
|
||||
this.end = end;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int rel, out int end)
|
||||
{
|
||||
rel = this.rel;
|
||||
end = this.end;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region operators
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(RelEnd a, RelEnd b) { return a.rel == b.rel && a.end == b.end; }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(RelEnd a, RelEnd b) { return a.rel != b.rel || a.end != b.end; }
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
public override bool Equals(object obj) { throw new NotImplementedException(); }
|
||||
public override int GetHashCode() { throw new NotImplementedException(); }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(RelEnd other) { return this == other; }
|
||||
public override string ToString() { return $"arc(--({rel})-> {end})"; }
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user