diff --git a/DragonECS-Relations.asmdef b/DragonECS-Relations.asmdef index 18b13f7..78b12c1 100644 --- a/DragonECS-Relations.asmdef +++ b/DragonECS-Relations.asmdef @@ -1,12 +1,12 @@ { - "name": "DCFApixels.DragonECS.Relations", + "name": "DCFApixels.DragonECS.Graphs", "rootNamespace": "DCFApixels", "references": [ "GUID:abb125fa67fff1e45914d0825236f608" ], "includePlatforms": [], "excludePlatforms": [], - "allowUnsafeCode": false, + "allowUnsafeCode": true, "overrideReferences": false, "precompiledReferences": [], "autoReferenced": true, diff --git a/src/Builtin/EcsEdgeWorld.cs.meta b/src/Builtin/EcsArcWorld.cs.meta similarity index 83% rename from src/Builtin/EcsEdgeWorld.cs.meta rename to src/Builtin/EcsArcWorld.cs.meta index f213f03..9185047 100644 --- a/src/Builtin/EcsEdgeWorld.cs.meta +++ b/src/Builtin/EcsArcWorld.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 245c8b2a0b1b736438bc5016f536df7b +guid: 72248d53a53519847b5b360dd02c37c5 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EcsArc.cs b/src/EcsArc.cs index 0d5e70d..05629f2 100644 --- a/src/EcsArc.cs +++ b/src/EcsArc.cs @@ -19,7 +19,7 @@ namespace DCFApixels.DragonECS private readonly EndWorldHandler _endWorldHandler; private readonly LoopWorldHandler _loopWorldHandler; - private RelEntityInfo[] _relEntityInfos; //N * (N - 1) / 2 + private RelationInfo[] _relEntityInfos; //N * (N - 1) / 2 private readonly SparseMatrix _matrix; private bool _isLoop; @@ -67,7 +67,7 @@ namespace DCFApixels.DragonECS _isLoop = startWorld == endWorld; - _relEntityInfos = new RelEntityInfo[arcWorld.Capacity]; + _relEntityInfos = new RelationInfo[arcWorld.Capacity]; _matrix = new SparseMatrix(arcWorld.Capacity); _arcWorldHandler = new ArcWorldHandler(this); @@ -119,7 +119,7 @@ namespace DCFApixels.DragonECS { int relEntityID = _arcWorld.NewEntity(); _matrix.Add(startEntityID, endEntityID, relEntityID); - _relEntityInfos[relEntityID] = new RelEntityInfo(startEntityID, endEntityID); + _relEntityInfos[relEntityID] = new RelationInfo(startEntityID, endEntityID); return relEntityID; } #endregion @@ -156,9 +156,9 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ClearRelation_Internal(int relEntityID) { - ref RelEntityInfo info = ref _relEntityInfos[relEntityID]; + ref RelationInfo info = ref _relEntityInfos[relEntityID]; _matrix.TryDel(info.start, info.end); - info = RelEntityInfo.Empty; + info = RelationInfo.Empty; } #endregion @@ -170,16 +170,16 @@ namespace DCFApixels.DragonECS { return false; } - return !_relEntityInfos[relEntityID].IsEmpty; + return !_relEntityInfos[relEntityID].IsNull; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public RelEntityInfo GetRelationInfo(int relEntityID) + public StartEnd GetRelationInfo(int relEntityID) { if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length) { Throw.UndefinedException(); } - return _relEntityInfos[relEntityID]; + return new StartEnd(_relEntityInfos[relEntityID]); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetRelStart(int relEntityID) diff --git a/src/EcsEdge.cs.meta b/src/EcsArc.cs.meta similarity index 83% rename from src/EcsEdge.cs.meta rename to src/EcsArc.cs.meta index 146d807..fa6cc7d 100644 --- a/src/EcsEdge.cs.meta +++ b/src/EcsArc.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 15bd591d98596324aaf149538dfbb174 +guid: 8bbdbeffc4dbc37478284bfc4d2c8d59 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/EcsWorldGraph.cs b/src/EcsWorldGraph.cs index e75ba09..5d274aa 100644 --- a/src/EcsWorldGraph.cs +++ b/src/EcsWorldGraph.cs @@ -1,5 +1,4 @@ using DCFApixels.DragonECS.Graphs.Internal; -using DCFApixels.DragonECS.Graphs.Utils; using System; namespace DCFApixels.DragonECS diff --git a/src/WorldGraph.cs.meta b/src/EcsWorldGraph.cs.meta similarity index 83% rename from src/WorldGraph.cs.meta rename to src/EcsWorldGraph.cs.meta index 71dfeff..77cd4d3 100644 --- a/src/WorldGraph.cs.meta +++ b/src/EcsWorldGraph.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 56fd7412f01e8be4485580a7860b1331 +guid: 1ebb7cb8c3ca3e74dbcec878a032442e MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/src/Executors.meta b/src/Executors.meta new file mode 100644 index 0000000..c4a2b32 --- /dev/null +++ b/src/Executors.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3e96147ad8229048bfd07d82236327c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Executors/EcsJoinExecutor.cs.meta b/src/Executors/EcsJoinExecutor.cs.meta new file mode 100644 index 0000000..8f7c531 --- /dev/null +++ b/src/Executors/EcsJoinExecutor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 37a368fc468a4f845ba8f0426d44ac46 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal.meta b/src/Internal.meta new file mode 100644 index 0000000..d18ee52 --- /dev/null +++ b/src/Internal.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 73c4fcc6529a39342a22a06cd2eef4f9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/ArrayUtility.cs.meta b/src/Internal/ArrayUtility.cs.meta new file mode 100644 index 0000000..93a6ea0 --- /dev/null +++ b/src/Internal/ArrayUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e18d76e777aacc74d87b74a4160f4dd4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/BitsUtility.cs.meta b/src/Internal/BitsUtility.cs.meta new file mode 100644 index 0000000..0fc14f3 --- /dev/null +++ b/src/Internal/BitsUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20978cdfe73c32d49952cb225e32a5b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/RelEntityInfo.cs b/src/Internal/RelationInfo.cs similarity index 52% rename from src/Internal/RelEntityInfo.cs rename to src/Internal/RelationInfo.cs index d8ed03d..05d5160 100644 --- a/src/Internal/RelEntityInfo.cs +++ b/src/Internal/RelationInfo.cs @@ -6,9 +6,9 @@ namespace DCFApixels.DragonECS.Graphs.Internal { [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)] [Serializable] - internal readonly struct RelEntityInfo : IEquatable + internal readonly struct RelationInfo : IEquatable { - public static readonly RelEntityInfo Empty = new RelEntityInfo(); + public static readonly RelationInfo Empty = new RelationInfo(); /// Start vertex entity ID. public readonly int start; @@ -16,15 +16,21 @@ namespace DCFApixels.DragonECS.Graphs.Internal public readonly int end; #region Properties - public bool IsEmpty + public bool IsNull { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => start == 0 && end == 0; + get { return start == 0 && end == 0; } + } + public bool IsLoop + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return start == end; } } #endregion + #region Constructor/Deconstruct [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal RelEntityInfo(int startEntity, int endEntity) + internal RelationInfo(int startEntity, int endEntity) { start = startEntity; end = endEntity; @@ -35,21 +41,22 @@ namespace DCFApixels.DragonECS.Graphs.Internal start = this.start; end = this.end; } + #endregion #region operators [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(RelEntityInfo a, RelEntityInfo b) => a.start == b.start && a.end == b.end; + public static bool operator ==(RelationInfo a, RelationInfo b) { return a.start == b.start && a.end == b.end; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(RelEntityInfo a, RelEntityInfo b) => a.start != b.start || a.end != b.end; + public static bool operator !=(RelationInfo a, RelationInfo b) { return a.start != b.start || a.end != b.end; } #endregion #region Other - public override bool Equals(object obj) => obj is RelEntityInfo targets && targets == this; + public override bool Equals(object obj) { return obj is RelationInfo targets && targets == this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(RelEntityInfo other) => this == other; + public bool Equals(RelationInfo other) { return this == other; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() => ~start ^ end; - public override string ToString() => $"arc({start} -> {end})"; + public override int GetHashCode() { return start ^ BitsUtility.NextXorShiftState(end); } + public override string ToString() { return $"arc({start} -> {end})"; } #endregion } -} \ No newline at end of file +} diff --git a/src/Internal/RelationInfo.cs.meta b/src/Internal/RelationInfo.cs.meta new file mode 100644 index 0000000..b26d33d --- /dev/null +++ b/src/Internal/RelationInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dbff41f77f58de74e8a869e63278a16c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/SparseArray.cs.meta b/src/Internal/SparseArray.cs.meta new file mode 100644 index 0000000..d8ea5e1 --- /dev/null +++ b/src/Internal/SparseArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c3dd2571d8641a142a77b4dc93c8a33b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/SparseMatrix.cs b/src/Internal/SparseMatrix.cs index 647c656..872e2d4 100644 --- a/src/Internal/SparseMatrix.cs +++ b/src/Internal/SparseMatrix.cs @@ -121,7 +121,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal } #if DEBUG - if(_freeCount < 0) { Throw.UndefinedException(); } + if (_freeCount < 0) { Throw.UndefinedException(); } #endif ref Basket basket = ref _buckets[targetBucket]; @@ -179,7 +179,7 @@ namespace DCFApixels.DragonECS.Graphs.Internal { int index = FindEntry(x, y); #if DEBUG - if(index < 0) { Throw.KeyNotFound(); } + if (index < 0) { Throw.KeyNotFound(); } #endif return _entries[index].value; } diff --git a/src/Internal/SparseMatrix.cs.meta b/src/Internal/SparseMatrix.cs.meta new file mode 100644 index 0000000..f923b98 --- /dev/null +++ b/src/Internal/SparseMatrix.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33f08dac2af94224394c92df946092b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Internal/UnsafeArray.cs.meta b/src/Internal/UnsafeArray.cs.meta new file mode 100644 index 0000000..574a179 --- /dev/null +++ b/src/Internal/UnsafeArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a40924dd997ba8443b5dbe58940f3d0d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Utils/Rel.cs b/src/Utils/Rel.cs deleted file mode 100644 index 92b97ca..0000000 --- a/src/Utils/Rel.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace DCFApixels.DragonECS -{ - public readonly ref struct StartRelEnd - { - /// Start vertex entity ID. - public readonly int start; - /// Relation entity ID. - public readonly int rel; - /// End vertex entity ID. - public readonly int end; - [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; - } - } - public readonly ref struct RelEnd - { - /// Relation entity ID. - public readonly int rel; - /// End vertex entity ID. - public readonly int end; - [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; - } - } -} diff --git a/src/Utils/Rels.cs b/src/Utils/Rels.cs new file mode 100644 index 0000000..8d9c4ff --- /dev/null +++ b/src/Utils/Rels.cs @@ -0,0 +1,166 @@ +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 + { + /// Start vertex entity ID. + public readonly int start; + /// End vertex entity ID. + 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 + } + public readonly ref struct StartRelEnd + { + /// Start vertex entity ID. + public readonly int start; + /// Relation entity ID. + public readonly int rel; + /// End vertex entity ID. + 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 + } + public readonly ref struct RelEnd + { + /// Relation entity ID. + public readonly int rel; + /// End vertex entity ID. + 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 + } +} diff --git a/src/Utils/Rels.cs.meta b/src/Utils/Rels.cs.meta new file mode 100644 index 0000000..4b37ae3 --- /dev/null +++ b/src/Utils/Rels.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f15f529231efb91419dc996fc78319cf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: