diff --git a/src/Collections/EcsGraph.cs b/src/Collections/EcsGraph.cs deleted file mode 100644 index 7795537..0000000 --- a/src/Collections/EcsGraph.cs +++ /dev/null @@ -1,450 +0,0 @@ -using DCFApixels.DragonECS.Relations.Internal; -using System; -using System.ComponentModel; -using System.Runtime.CompilerServices; -using static DCFApixels.DragonECS.EcsGraph; - -namespace DCFApixels.DragonECS -{ - public readonly ref struct EcsReadonlyGraph - { - private readonly EcsGraph _source; - - #region Properties - public bool IsNull => _source == null; - public EcsArc Arc - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.Arc; } - } - public EcsWorld StartWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.StartWorld; } - } - public EcsWorld EndWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.EndWorld; } - } - public EcsArcWorld ArcWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.ArcWorld; } - } - public int ArcWorldID - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.ArcWorldID; } - } - public bool IsLoopArc - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.IsLoopArc; } - } - public EnumerableRelEnd this[int startEntityID] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source[startEntityID]; } - } - #endregion - - #region Constructors - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsReadonlyGraph(EcsGraph source) { _source = source; } - #endregion - - #region Methods - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int relEntityID) { return _source.Has(relEntityID); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool HasStart(int startEntityID) { return _source.HasStart(startEntityID); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool HasEnd(int endEntityID) { return _source.HasEnd(endEntityID); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EnumerableRelEnd GetRelEnds(int startEntityID) { return _source.GetRelEnds(startEntityID); } - #endregion - - #region Internal - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EcsGraph GetSource_Internal() => _source; - #endregion - - #region Other - public override string ToString() - { - return _source != null ? _source.ToString() : "NULL"; - } -#pragma warning disable CS0809 // Устаревший член переопределяет неустаревший член - [Obsolete("Equals() on EcsGroup will always throw an exception. Use the equality operator instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) => throw new NotSupportedException(); - [Obsolete("GetHashCode() on EcsGroup will always throw an exception.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override int GetHashCode() => throw new NotSupportedException(); -#pragma warning restore CS0809 // Устаревший член переопределяет неустаревший член - #endregion - } - //[DebuggerTypeProxy(typeof(DebuggerProxy))] - public class EcsGraph - { - private readonly EcsArc _source; - private readonly bool _isLoop; - - private readonly BasketList _startBaskets; - private readonly BasketList _endBaskets; - private RelNodesInfo[] _relNodesMapping; - - #region Properties - public EcsReadonlyGraph Readonly - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return new EcsReadonlyGraph(this); } - } - public EcsArc Arc - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source; } - } - public EcsWorld StartWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.StartWorld; } - } - public EcsWorld EndWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.EndWorld; } - } - public EcsArcWorld ArcWorld - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.ArcWorld; } - } - public int ArcWorldID - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _source.ArcWorldID; } - } - public bool IsLoopArc - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _isLoop; } - } - - public EnumerableRelEnd this[int startEntityID] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return GetRelEnds(startEntityID); } - } - #endregion - - #region Constructors - public EcsGraph(EcsArc arc) - { - _source = arc; - _isLoop = arc.IsLoop; - - _startBaskets = new BasketList(); - _endBaskets = new BasketList(); - - _relNodesMapping = new RelNodesInfo[arc.ArcWorld.Capacity]; - } - #endregion - - #region Add/Del - public void Add(int startEntityID, int endEntityID, int relEntityID) - { - _relNodesMapping[relEntityID] = new RelNodesInfo( - _startBaskets.AddToBasket(startEntityID, relEntityID), - _endBaskets.AddToBasket(endEntityID, relEntityID)); - } - public void Add(int relEntityID) - { - var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID); - _relNodesMapping[relEntityID] = new RelNodesInfo( - _startBaskets.AddToBasket(startEntityID, relEntityID), - _endBaskets.AddToBasket(endEntityID, relEntityID)); - } - public void Del(int relEntityID) - { - var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID); - ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID]; - _startBaskets.RemoveFromBasket(startEntityID, relInfo.startNodeIndex); - _endBaskets.RemoveFromBasket(endEntityID, relInfo.endNodeIndex); - } - public void DelStart(int startEntityID) - { - foreach (var relEntityID in _startBaskets.GetBasketIterator(startEntityID)) - { - var endEntityID = _source.GetRelEnd(relEntityID); - ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID]; - _endBaskets.RemoveFromBasket(endEntityID, relInfo.startNodeIndex); - } - _startBaskets.RemoveBasket(startEntityID); - } - public void DelEnd(int endEntityID) - { - foreach (var relEntityID in _endBaskets.GetBasketIterator(endEntityID)) - { - var startEntityID = _source.GetRelStart(relEntityID); - ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID]; - _startBaskets.RemoveFromBasket(startEntityID, relInfo.endNodeIndex); - } - _endBaskets.RemoveBasket(endEntityID); - } - - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void DelStartAndDelRelEntities(int startEntityID, EcsArc arc) - { - - foreach (var relEntityID in _startBaskets.GetBasketIterator(startEntityID)) - { - arc.ArcWorld.TryDelEntity(relEntityID); - } - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void DelEndAndDelRelEntities(int endEntityID, EcsArc arc) - { - foreach (var relEntityID in _endBaskets.GetBasketIterator(endEntityID)) - { - arc.ArcWorld.TryDelEntity(relEntityID); - } - } - public struct FriendEcsArc - { - private EcsGraph _join; - public FriendEcsArc(EcsArc arc, EcsGraph join) - { - if (arc.IsInit_Internal != false) - { - Throw.UndefinedException(); - } - _join = join; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void DelStartAndDelRelEntities(int startEntityID, EcsArc arc) - { - _join.DelStartAndDelRelEntities(startEntityID, arc); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void DelEndAndDelRelEntities(int endEntityID, EcsArc arc) - { - _join.DelEndAndDelRelEntities(endEntityID, arc); - } - } - #endregion - - #region Has - public bool Has(int relEntityID) - { - return _relNodesMapping[relEntityID] != RelNodesInfo.Empty; - } - public bool HasStart(int startEntityID) - { - return _startBaskets.GetBasketNodesCount(startEntityID) > 0; - } - public bool HasEnd(int endEntityID) - { - return _endBaskets.GetBasketNodesCount(endEntityID) > 0; - } - #endregion - - #region Clear - public void Clear() - { - _startBaskets.Clear(); - if (!_isLoop) - { - _endBaskets.Clear(); - } - } - #endregion - - #region GetRelEnds - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EnumerableRelEnd GetRelEnds(int startEntityID) - { - return new EnumerableRelEnd(_source, _startBaskets.GetBasketIterator(startEntityID).GetEnumerator()); - } - #endregion - - #region EnumerableArcEnd - public readonly ref struct EnumerableRelEnd //: IEnumerable - { - private readonly EcsArc _arc; - private readonly BasketList.BasketIterator.Enumerator _iterator; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EnumerableRelEnd(EcsArc arc, BasketList.BasketIterator.Enumerator iterator) - { - _arc = arc; - _iterator = iterator; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() { return new Enumerator(_arc, _iterator); } - //IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - //IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - public ref struct Enumerator //: IEnumerator - { - private readonly EcsArc _arc; - private BasketList.BasketIterator.Enumerator _iterator; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Enumerator(EcsArc arc, BasketList.BasketIterator.Enumerator iterator) - { - _arc = arc; - _iterator = iterator; - } - public RelEnd Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - int currentArc = _iterator.Current; - return new RelEnd(currentArc, _arc.GetRelEnd(currentArc)); - } - } - //object IEnumerator.Current => Current; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() { return _iterator.MoveNext(); } - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - //public void Reset() { } - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - //public void Dispose() { } - } - } - #endregion - - #region ArcInfo - private struct RelNodesInfo : IEquatable - { - public readonly static RelNodesInfo Empty = default; - public int startNodeIndex; - public int endNodeIndex; - public RelNodesInfo(int startNodeIndex, int endNodeIndex) - { - this.startNodeIndex = startNodeIndex; - this.endNodeIndex = endNodeIndex; - } - #region Object - public override bool Equals(object obj) - { - return obj is RelNodesInfo && Equals((RelNodesInfo)obj); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Equals(RelNodesInfo other) - { - return startNodeIndex == other.startNodeIndex && - endNodeIndex == other.endNodeIndex; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetHashCode() - { - return ~startNodeIndex ^ endNodeIndex; - } - #endregion - - #region operators - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(RelNodesInfo a, RelNodesInfo b) => a.startNodeIndex == b.startNodeIndex && a.endNodeIndex == b.endNodeIndex; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(RelNodesInfo a, RelNodesInfo b) => a.startNodeIndex != b.startNodeIndex || a.endNodeIndex != b.endNodeIndex; - #endregion - } - #endregion - - #region Operators - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static implicit operator EcsReadonlyGraph(EcsGraph a) => a.Readonly; - #endregion - - #region UpSize - public void UpArcSize(int minSize) - { - Array.Resize(ref _relNodesMapping, minSize); - } - public void UpStartSize(int minSize) - { - _startBaskets.UpBasketsSize(minSize); - } - public void UpEndSize(int minSize) - { - _endBaskets.UpBasketsSize(minSize); - } - #endregion - - #region DebuggerProxy - //internal class DebuggerProxy - //{ - // private EcsJoinGroup _basket; - // - // public SpanDebugInfo[] HeadSpans => GetSpans(_basket._startList, _basket._startMapping); - // public SpanDebugInfo[] ValueSpans => GetSpans(_basket._endList, _basket._endMapping); - // - // private SpanDebugInfo[] GetSpans(IdsLinkedList list, SpanInfo[] mapping) - // { - // SpanDebugInfo[] result = new SpanDebugInfo[mapping.Length]; - // for (int i = 0; i < mapping.Length; i++) - // result[i] = new SpanDebugInfo(list, mapping[i].nodeIndex, mapping[i].count); - // return result; - // } - // public DebuggerProxy(EcsJoinGroup basket) - // { - // _basket = basket; - // } - // public struct SpanDebugInfo - // { - // private IdsLinkedList _list; - // public int index; - // public int count; - // public NodeDebugInfo[] Nodes - // { - // get - // { - // var result = new NodeDebugInfo[this.count]; - // var nodes = _list.Nodes; - // int index; - // int count = this.count; - // int next = this.index; - // int i = 0; - // while (true) - // { - // index = next; - // next = nodes[next].next; - // if (!(index > 0 && count-- > 0)) - // break; - // var node = nodes[index]; - // result[i] = new NodeDebugInfo(index, node.prev, node.next, node.value); - // i++; - // } - // return result; - // } - // } - // public SpanDebugInfo(IdsLinkedList list, int index, int count) - // { - // _list = list; - // this.index = index; - // this.count = count; - // } - // public override string ToString() => $"[{index}] {count}"; - // } - // public struct NodeDebugInfo - // { - // public int index; - // public int prev; - // public int next; - // public int value; - // public NodeDebugInfo(int index, int prev, int next, int value) - // { - // this.index = index; - // this.prev = prev; - // this.next = next; - // this.value = value; - // } - // public override string ToString() => $"[{index}] {prev}_{next} - {value}"; - // } - //} - #endregion - } -} \ No newline at end of file diff --git a/src/EcsArc.cs b/src/EcsArc.cs index bfb6fe6..ad540ac 100644 --- a/src/EcsArc.cs +++ b/src/EcsArc.cs @@ -1,8 +1,6 @@ using DCFApixels.DragonECS.Relations.Internal; -using DCFApixels.DragonECS.Relations.Utils; using System; using System.Runtime.CompilerServices; -using System.Xml; namespace DCFApixels.DragonECS { @@ -21,11 +19,6 @@ namespace DCFApixels.DragonECS private readonly EndWorldHandler _endWorldHandler; private readonly LoopWorldHandler _loopWorldHandler; - //private readonly SparseArray64 _relationsMatrix = new SparseArray64(); - - private EcsGraph _entitiesGraph; - private EcsGraph.FriendEcsArc _entitiesGraphFriend; - private EcsGroup _relEntities; private RelEntityInfo[] _relEntityInfos; //N * (N - 1) / 2 @@ -63,11 +56,6 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _relEntities.Readonly; } } - public EcsReadonlyGraph EntitiesGraph - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get { return _entitiesGraph.Readonly; } - } public bool IsLoop { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -88,9 +76,6 @@ namespace DCFApixels.DragonECS _relEntities = EcsGroup.New(_arcWorld); - _entitiesGraph = new EcsGraph(this); - - _entitiesGraphFriend = new EcsGraph.FriendEcsArc(this, _entitiesGraph); _arcWorldHandler = new ArcWorldHandler(this); if (_isLoop) @@ -124,30 +109,11 @@ namespace DCFApixels.DragonECS #region New/Del public int NewRelation(int startEntityID, int endEntityID) { - //if (HasRelation(startEntityID, endEntityID)) - //{ - // Throw.RelationAlreadyExists(); - //} - int relEntity = _arcWorld.NewEntity(); - //_relationsMatrix.Add(startEntityID, endEntityID, relEntity); - _relEntityInfos[relEntity] = new RelEntityInfo(startEntityID, endEntityID); _relEntities.Add(relEntity); - _entitiesGraph.Add(startEntityID, endEntityID, relEntity); return relEntity; } - //public void DelRelation(int startEntityID, int endEntityID) - //{ - // if (_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntityID)) - // { - // _arcWorld.DelEntity(relEntityID); - // } - // else - // { - // Throw.UndefinedRelationException(); - // } - //} public void DelRelation(int relEntityID) { @@ -157,39 +123,8 @@ namespace DCFApixels.DragonECS public void ClearRelation_Internal(int relEntityID) { _relEntities.Remove(relEntityID); - _entitiesGraph.Del(relEntityID); _relEntityInfos[relEntityID] = RelEntityInfo.Empty; } - - //private void ClearRelation_Internal(int startEntityID, int endEntityID) - //{ - // if (_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntityID)) - // { - // _relEntities.Remove(relEntityID); - // _entitiesGraph.Del(relEntityID); - // _relationsMatrix.Remove(startEntityID, endEntityID); - // _relEntityInfos[relEntityID] = RelEntityInfo.Empty; - // } - //} - #endregion - - #region GetRelation/HasRelation - //public bool HasRelation(int startEntityID, int endEntityID) - //{ - // return _relationsMatrix.Contains(startEntityID, endEntityID); - //} - //public int GetRelation(int startEntityID, int endEntityID) - //{ - // if (!_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntityID)) - // { - // Throw.UndefinedRelationException(); - // } - // return relEntityID; - //} - //public bool TryGetRelation(int startEntityID, int endEntityID, out int relEntityID) - //{ - // return _relationsMatrix.TryGetValue(startEntityID, endEntityID, out relEntityID); - //} #endregion #region ArcEntityInfo @@ -221,19 +156,6 @@ namespace DCFApixels.DragonECS { return GetRelationInfo(relEntityID).end; } - - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - //public int GetInversedRelation(int relEntityID) - //{ - // var (startEntityID, endEntityID) = GetRelationInfo(relEntityID); - // return GetRelation(endEntityID, startEntityID); - //} - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - //public bool TryGetInversedRelation(int relEntityID, out int inversedRelEntityID) - //{ - // var (startEntityID, endEntityID) = GetRelationInfo(relEntityID); - // return TryGetRelation(endEntityID, startEntityID, out inversedRelEntityID); - //} #endregion #region Other @@ -275,7 +197,6 @@ namespace DCFApixels.DragonECS public void OnWorldResize(int arcWorldNewSize) { Array.Resize(ref _arc._relEntityInfos, arcWorldNewSize); - _arc._entitiesGraph.UpArcSize(arcWorldNewSize); } #endregion } @@ -295,17 +216,10 @@ namespace DCFApixels.DragonECS #region Callbacks public void OnReleaseDelEntityBuffer(ReadOnlySpan startEntityBuffer) { - foreach (var startEntityID in startEntityBuffer) - { - _arc._entitiesGraphFriend.DelStartAndDelRelEntities(startEntityID, _arc); - } _arc._arcWorld.ReleaseDelEntityBufferAll(); } public void OnWorldDestroy() { } - public void OnWorldResize(int startWorldNewSize) - { - _arc._entitiesGraph.UpStartSize(startWorldNewSize); - } + public void OnWorldResize(int startWorldNewSize) { } #endregion } private class EndWorldHandler : IEcsWorldEventListener @@ -324,17 +238,10 @@ namespace DCFApixels.DragonECS #region Callbacks public void OnReleaseDelEntityBuffer(ReadOnlySpan endEntityBuffer) { - foreach (var endEntityID in endEntityBuffer) - { - _arc._entitiesGraphFriend.DelEndAndDelRelEntities(endEntityID, _arc); - } _arc._arcWorld.ReleaseDelEntityBufferAll(); } public void OnWorldDestroy() { } - public void OnWorldResize(int endWorldNewSize) - { - _arc._entitiesGraph.UpEndSize(endWorldNewSize); - } + public void OnWorldResize(int endWorldNewSize) { } #endregion } private class LoopWorldHandler : IEcsWorldEventListener @@ -353,19 +260,10 @@ namespace DCFApixels.DragonECS #region Callbacks public void OnReleaseDelEntityBuffer(ReadOnlySpan startEntityBuffer) { - foreach (var startEntityID in startEntityBuffer) - { - _arc._entitiesGraphFriend.DelStartAndDelRelEntities(startEntityID, _arc); - _arc._entitiesGraphFriend.DelEndAndDelRelEntities(startEntityID, _arc); - } _arc._arcWorld.ReleaseDelEntityBufferAll(); } public void OnWorldDestroy() { } - public void OnWorldResize(int startWorldNewSize) - { - _arc._entitiesGraph.UpStartSize(startWorldNewSize); - _arc._entitiesGraph.UpEndSize(startWorldNewSize); - } + public void OnWorldResize(int startWorldNewSize) { } #endregion } #endregion diff --git a/src/EcsWorldConfig.cs b/src/EcsWorldConfig.cs index 4b29540..d77b0e0 100644 --- a/src/EcsWorldConfig.cs +++ b/src/EcsWorldConfig.cs @@ -1,10 +1,7 @@ -using System; -using System.Collections.Generic; - -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS { public static class EcsWorldConfigRelationsExtensions { - + } } diff --git a/src/Utils/BasketList.cs b/src/Utils/BasketList.cs deleted file mode 100644 index cbdd39e..0000000 --- a/src/Utils/BasketList.cs +++ /dev/null @@ -1,438 +0,0 @@ -using DCFApixels.DragonECS.Relations.Internal; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace DCFApixels.DragonECS -{ - [DebuggerTypeProxy(typeof(DebuggerProxy))] - internal class BasketList - { - public const int NULL = 0; - - private UnsafeArray _baskets = new UnsafeArray(64, true); - private UnsafeArray _nodes; - private int _recycledListHead = NULL; - - #region Constructors/Destroy - public BasketList() : this(16) { } - public BasketList(int minCapacity) - { - Initialize(ArrayUtility.NormalizeSizeToPowerOfTwo(minCapacity)); - } - //Dispose //GC.SuppressFinalize - ~BasketList() - { - _baskets.Dispose(); - _nodes.Dispose(); - } - #endregion - - #region Clear - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Clear() - { - for (int i = 0; i < _nodes.Length; i++) - { - _nodes[i].next = 0; - } - for (int i = 0; i < _baskets.Length; i++) - { - _baskets[i] = default; - } - } - #endregion - - #region Other - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetBasketNodesCount(int basketIndex) - { - return _baskets[basketIndex].count; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Set(int nodeIndex, int value) - { - _nodes[nodeIndex].value = value; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Get(int nodeIndex) - { - return _nodes[nodeIndex].value; - } - private Node GetNode(int nodeIndex) - { - return _nodes[nodeIndex]; - } - #endregion - - #region AddToBasket/TakeRecycledNode - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int TakeRecycledNode() - { - if (_recycledListHead == NULL) - { - ResizeNodes(_nodes.Length << 1); - } - int node = _recycledListHead; - _recycledListHead = _nodes[node].next; - return node; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int AddToBasket(int basketIndex, int value) - { - ref BasketInfo basketInfo = ref _baskets[basketIndex]; - int newNodeIndex = TakeRecycledNode(); - if (basketInfo.count == 0) - { - _nodes[newNodeIndex].SetValue_Prev(value, 0); - } - else - { - int nodeIndex = basketInfo.nodeIndex; - ref int nextNode_Prev = ref _nodes[nodeIndex].prev; - - _nodes[newNodeIndex].Set(value, nextNode_Prev, nodeIndex); - nextNode_Prev = newNodeIndex; - } - basketInfo.nodeIndex = newNodeIndex; - basketInfo.count++; - return newNodeIndex; - } - #endregion - - #region RemoveFromBasket/RemoveBasket - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void RemoveFromBasket(int basketIndex, int nodeIndex) - {//нужно добавить ограничение на удаление повторяющейся ноды, иначе recycled ноды зацикливаются -#if DEBUG - if (nodeIndex <= 0) - { - //Throw.ArgumentOutOfRange(); - return; - } -#endif - ref BasketInfo basketInfo = ref _baskets[basketIndex]; - - ref var node = ref _nodes[nodeIndex]; - int nextNode = node.next; - - Link(node.prev, nextNode); - LinkToRecycled(nodeIndex, nodeIndex); - if (basketInfo.nodeIndex == nodeIndex) - { - basketInfo.nodeIndex = nextNode; - } - basketInfo.count--; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void RemoveBasket(int basketIndex) - { - ref BasketInfo basket = ref _baskets[basketIndex]; - - int startNodeIndex = basket.nodeIndex; - int endNodeIndex = startNodeIndex; - ref Node startNode = ref _nodes[startNodeIndex]; - for (int i = 0, n = basket.count; i < n; i++) - { - endNodeIndex = _nodes[endNodeIndex].next; - } - ref Node endNode = ref _nodes[endNodeIndex]; - - LinkToRecycled(startNodeIndex, endNodeIndex); - Link(startNode.prev, endNode.next); - - basket.count = 0; - } - #endregion - - #region Links - //[MethodImpl(MethodImplOptions.AggressiveInlining)] - //private void Separate(int leftNodeIndex, int rightNodeIndex) - //{ - // _nodes[rightNodeIndex].prev = 0; - // _nodes[leftNodeIndex].next = 0; - //} - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Link(int leftNodeIndex, int rightNodeIndex) - { - _nodes[rightNodeIndex].prev = leftNodeIndex; - _nodes[leftNodeIndex].next = rightNodeIndex; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void LinkToRecycled(int startNodeIndex, int endNodeIndex) - { - if (_recycledListHead <= NULL) - { - _nodes[endNodeIndex].next = NULL; - } - else - { - Link(startNodeIndex, _recycledListHead); - } - _recycledListHead = startNodeIndex; - } - #endregion - - #region UpSize/Resize/Initialize - [MethodImpl(MethodImplOptions.NoInlining)] - private void ResizeNodes(int newSize) - { - int oldSize = _nodes.Length; - UnsafeArray.Resize(ref _nodes, newSize); - InitNewNodes(oldSize, newSize); - } - [MethodImpl(MethodImplOptions.NoInlining)] - private void Initialize(int newSize) - { - _nodes = new UnsafeArray(newSize); - _nodes[0] = Node.Empty; - InitNewNodes(1, newSize); - } - [MethodImpl(MethodImplOptions.NoInlining)] - private void InitNewNodes(int oldSize, int newSize) - { - int leftNode = NULL; - for (int i = oldSize; i < newSize; i++) - { - Link(leftNode, i); - leftNode = i; - } - LinkToRecycled(oldSize, newSize - 1); - } - - public void UpNodesSize(int minSize) - { - if (minSize > _nodes.Length) - { - int newSize = ArrayUtility.NormalizeSizeToPowerOfTwo(minSize); - ResizeNodes(newSize); - } - } - public void UpBasketsSize(int minSize) - { - if (minSize > _baskets.Length) - { - int newSize = ArrayUtility.NormalizeSizeToPowerOfTwo(minSize); - UnsafeArray.ResizeAndInit(ref _baskets, newSize); - } - } - #endregion - - #region Node - [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)] - public struct Node - { - public static readonly Node Empty = new Node() { value = 0, next = NULL }; - public int value; - /// next node index - public int next; - /// prev node index - public int prev; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Set(int value, int prev, int next) - { - this.value = value; - this.next = next; - this.prev = prev; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetValue_Prev(int value, int prev) - { - this.value = value; - this.prev = prev; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void SetPrev_Next(int prev, int next) - { - this.next = next; - this.prev = prev; - } - public override string ToString() => $"node({prev}<>{next} v:{value})"; - } - #endregion - - #region BasketInfo - private struct BasketInfo - { - public static readonly BasketInfo Empty = new BasketInfo() { nodeIndex = 0, count = 0, }; - public int nodeIndex; - public int count; - public override string ToString() => $"basket_info(i:{nodeIndex} c:{count})"; - } - #endregion - - #region Basket - public BasketIterator this[int basketIndex] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetBasketIterator(basketIndex); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public BasketIterator GetBasketIterator(int basketIndex) - { - return new BasketIterator(this, basketIndex); - } - public readonly struct BasketIterator : IEnumerable - { - private readonly BasketList _basketList; - private readonly int _basketIndex; - public int Count - { - get { return _basketList._baskets[_basketIndex].count; } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public BasketIterator(BasketList basketList, int basketIndex) - { - _basketList = basketList; - _basketIndex = basketIndex; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() => new Enumerator(this); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public struct Enumerator : IEnumerator - { - private readonly UnsafeArray _nodes; - private int _nodeIndex; - private int _nextNodeIndex; - private int _count; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator(BasketIterator iterator) - { - ref BasketInfo basketInfo = ref iterator._basketList._baskets[iterator._basketIndex]; - _nodes = iterator._basketList._nodes; - _nodeIndex = -1; - _nextNodeIndex = basketInfo.nodeIndex; - _count = basketInfo.count; - } - public int Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _nodes[_nodeIndex].value; - } - object IEnumerator.Current => Current; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() - { - _nodeIndex = _nextNodeIndex; - _nextNodeIndex = _nodes[_nextNodeIndex].next; - return _nodeIndex > 0 && _count-- > 0; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Reset() { } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() { } - } - } - #endregion - - #region DebuggerProxy - private class DebuggerProxy - { - private BasketList _basketList; - public IEnumerable Baskets - { - get - { - List result = new List(); - for (int i = 0; i < _basketList._baskets.Length; i++) - { - if (_basketList._baskets[i].count > 0) - { - result.Add(new BasketIteratorDebbugerProxy(_basketList[i])); - } - } - return result; - } - } - public IEnumerable Recycled - { - get - { - List result = new List(); - Node curNode = new Node(); - curNode.index = _basketList._recycledListHead; - - for (int i = 0; i < _basketList._nodes.Length; i++) - { - if (curNode.index == NULL) - { - break; - } - BasketList.Node x = _basketList.GetNode(curNode.index); - curNode.prev = x.prev; - curNode.next = x.next; - - result.Add(curNode); - - curNode.index = curNode.next; - } - return result; - } - } - public IEnumerable AllNodes - { - get - { - List result = new List(); - - for (int i = 0; i < _basketList._nodes.Length; i++) - { - result.Add(new Node(_basketList._nodes[i].prev, i, _basketList._nodes[i].next)); - } - return result; - } - } - public DebuggerProxy(BasketList basketList) - { - _basketList = basketList; - } - public struct Node - { - public int prev; - public int index; - public int next; - public Node(int prev, int index, int next) - { - this.prev = prev; - this.index = index; - this.next = next; - } - public override string ToString() => $"node({prev}< {index} >{next})"; - } - public struct BasketIteratorDebbugerProxy - { - private BasketIterator _iterrator; - public int Count => _iterrator.Count; - public IEnumerable RelEntities - { - get - { - List result = new List(); - foreach (var e in _iterrator) - { - result.Add(e); - } - return result; - } - } - public BasketIteratorDebbugerProxy(BasketIterator iterrator) - { - _iterrator = iterrator; - } - public override string ToString() - { - return $"count: {_iterrator.Count}"; - } - } - } - #endregion - } -} diff --git a/src/Utils/Exceptions.cs b/src/Utils/Exceptions.cs index ace14c7..989aa5b 100644 --- a/src/Utils/Exceptions.cs +++ b/src/Utils/Exceptions.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.CompilerServices; -using System.Runtime.Serialization; namespace DCFApixels.DragonECS.Relations.Internal { @@ -42,6 +41,5 @@ namespace DCFApixels.DragonECS public EcsRelationException() { } public EcsRelationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { } public EcsRelationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { } - protected EcsRelationException(SerializationInfo info, StreamingContext context) : base(info, context) { } } }