mirror of
https://github.com/DCFApixels/DragonECS-Graphs.git
synced 2025-09-18 11:54:35 +08:00
fixes
нормально работает на небольших мирах, до 250 ентитей, разница с желаемым результатом в 10 раз. но в мирах на 1000 разница с желаемым результатом аж 100
This commit is contained in:
parent
2473c5dc78
commit
f865989c2d
@ -153,23 +153,25 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Add/Del
|
#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)
|
public void Add(int relEntityID)
|
||||||
{
|
{
|
||||||
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
||||||
ref RelNodesInfo arcInfo = ref _relNodesMapping[relEntityID];
|
_relNodesMapping[relEntityID] = new RelNodesInfo(
|
||||||
|
_startBaskets.AddToBasket(startEntityID, relEntityID),
|
||||||
arcInfo.startNodeIndex = _startBaskets.AddToBasket(startEntityID, relEntityID);
|
_endBaskets.AddToBasket(endEntityID, relEntityID));
|
||||||
arcInfo.endNodeIndex = _endBaskets.AddToBasket(endEntityID, relEntityID);
|
|
||||||
}
|
}
|
||||||
public void Del(int relEntityID)
|
public void Del(int relEntityID)
|
||||||
{
|
{
|
||||||
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
||||||
ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID];
|
ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID];
|
||||||
_startBaskets.RemoveFromBasket(startEntityID, relInfo.startNodeIndex);
|
_startBaskets.RemoveFromBasket(startEntityID, relInfo.startNodeIndex);
|
||||||
if (!_isLoop)
|
_endBaskets.RemoveFromBasket(endEntityID, relInfo.endNodeIndex);
|
||||||
{
|
|
||||||
//_startBaskets.RemoveFromBasket(endEntityID, relInfo.endNodeIndex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public void DelStart(int startEntityID)
|
public void DelStart(int startEntityID)
|
||||||
{
|
{
|
||||||
@ -320,7 +322,11 @@ namespace DCFApixels.DragonECS
|
|||||||
public readonly static RelNodesInfo Empty = default;
|
public readonly static RelNodesInfo Empty = default;
|
||||||
public int startNodeIndex;
|
public int startNodeIndex;
|
||||||
public int endNodeIndex;
|
public int endNodeIndex;
|
||||||
|
public RelNodesInfo(int startNodeIndex, int endNodeIndex)
|
||||||
|
{
|
||||||
|
this.startNodeIndex = startNodeIndex;
|
||||||
|
this.endNodeIndex = endNodeIndex;
|
||||||
|
}
|
||||||
#region Object
|
#region Object
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
|
@ -134,7 +134,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
_relEntityInfos[relEntity] = new RelEntityInfo(startEntityID, endEntityID);
|
_relEntityInfos[relEntity] = new RelEntityInfo(startEntityID, endEntityID);
|
||||||
_relEntities.Add(relEntity);
|
_relEntities.Add(relEntity);
|
||||||
_entitiesGraph.Add(relEntity);
|
_entitiesGraph.Add(startEntityID, endEntityID, relEntity);
|
||||||
return relEntity;
|
return relEntity;
|
||||||
}
|
}
|
||||||
//public void DelRelation(int startEntityID, int endEntityID)
|
//public void DelRelation(int startEntityID, int endEntityID)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System;
|
using DCFApixels.DragonECS.Relations.Internal;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -10,21 +10,27 @@ namespace DCFApixels.DragonECS
|
|||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||||
internal class BasketList
|
internal class BasketList
|
||||||
{
|
{
|
||||||
public const int RECYCLE = -1;
|
public const int NULL = 0;
|
||||||
public const int HEAD = 0;
|
|
||||||
|
|
||||||
private BasketInfo[] _baskets = new BasketInfo[64];
|
private UnsafeArray<BasketInfo> _baskets = new UnsafeArray<BasketInfo>(64, true);
|
||||||
private Node[] _nodes;
|
private UnsafeArray<Node> _nodes;
|
||||||
private int _recycledListLast = -1;
|
private int _recycledListHead = NULL;
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors/Destroy
|
||||||
public BasketList() : this(16) { }
|
public BasketList() : this(16) { }
|
||||||
public BasketList(int capacity)
|
public BasketList(int minCapacity)
|
||||||
{
|
{
|
||||||
Initialize(capacity);
|
Initialize(ArrayUtility.NormalizeSizeToPowerOfTwo(minCapacity));
|
||||||
|
}
|
||||||
|
//Dispose //GC.SuppressFinalize
|
||||||
|
~BasketList()
|
||||||
|
{
|
||||||
|
_baskets.Dispose();
|
||||||
|
_nodes.Dispose();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Clear
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
@ -37,40 +43,14 @@ namespace DCFApixels.DragonECS
|
|||||||
_baskets[i] = default;
|
_baskets[i] = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
#region Other
|
||||||
private void Resize(int newSize)
|
|
||||||
{
|
|
||||||
int oldSize = _nodes.Length;
|
|
||||||
Array.Resize(ref _nodes, newSize);
|
|
||||||
int leftNode = newSize - 1;
|
|
||||||
for (int i = oldSize; i < newSize; i++)
|
|
||||||
{
|
|
||||||
Link(i, leftNode);
|
|
||||||
leftNode = i;
|
|
||||||
}
|
|
||||||
LinkToRecycled(newSize - 1, oldSize);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
|
||||||
private void Initialize(int newSize)
|
|
||||||
{
|
|
||||||
_nodes = new Node[newSize];
|
|
||||||
int leftNode = newSize - 1;
|
|
||||||
for (int i = 1; i < newSize; i++)
|
|
||||||
{
|
|
||||||
Link(i, leftNode);
|
|
||||||
leftNode = i;
|
|
||||||
}
|
|
||||||
LinkToRecycled(newSize - 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int GetBasketNodesCount(int basketIndex)
|
public int GetBasketNodesCount(int basketIndex)
|
||||||
{
|
{
|
||||||
return _baskets[basketIndex].count;
|
return _baskets[basketIndex].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Set(int nodeIndex, int value)
|
public void Set(int nodeIndex, int value)
|
||||||
{
|
{
|
||||||
@ -81,16 +61,52 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return _nodes[nodeIndex].value;
|
return _nodes[nodeIndex].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node GetNode(int nodeIndex)
|
private Node GetNode(int nodeIndex)
|
||||||
{
|
{
|
||||||
return _nodes[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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveFromBasket(int basketIndex, int nodeIndex)
|
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 DEBUG
|
||||||
if (nodeIndex <= 0)
|
if (nodeIndex <= 0)
|
||||||
{
|
{
|
||||||
@ -112,68 +128,6 @@ namespace DCFApixels.DragonECS
|
|||||||
basketInfo.count--;
|
basketInfo.count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public int AddToBasket(int basketIndex, int value)
|
|
||||||
{
|
|
||||||
ref BasketInfo basketInfo = ref _baskets[basketIndex];
|
|
||||||
int newNodeIndex = TakeRecycledNode();
|
|
||||||
if (basketInfo.count == 0)
|
|
||||||
{
|
|
||||||
basketInfo.nodeIndex = newNodeIndex;
|
|
||||||
_nodes[newNodeIndex].Set(value, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int nodeIndex = basketInfo.nodeIndex;
|
|
||||||
ref Node nextNode = ref _nodes[nodeIndex];
|
|
||||||
|
|
||||||
_nodes[newNodeIndex].Set(value, nextNode.prev, nodeIndex);
|
|
||||||
basketInfo.nodeIndex = newNodeIndex;
|
|
||||||
nextNode.prev = newNodeIndex;
|
|
||||||
}
|
|
||||||
basketInfo.count++;
|
|
||||||
return newNodeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private int TakeRecycledNode()
|
|
||||||
{
|
|
||||||
if (_recycledListLast == -1)
|
|
||||||
{
|
|
||||||
Resize(_nodes.Length << 1);
|
|
||||||
}
|
|
||||||
int node = _recycledListLast;
|
|
||||||
_recycledListLast = _nodes[node].prev;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
//[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 (_recycledListLast <= -1)
|
|
||||||
{
|
|
||||||
_nodes[startNodeIndex].prev = RECYCLE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Link(_recycledListLast, startNodeIndex);
|
|
||||||
}
|
|
||||||
_recycledListLast = endNodeIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void RemoveBasket(int basketIndex)
|
public void RemoveBasket(int basketIndex)
|
||||||
{
|
{
|
||||||
@ -193,55 +147,86 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
basket.count = 0;
|
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)]
|
[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<Node>(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)
|
public void UpBasketsSize(int minSize)
|
||||||
{
|
{
|
||||||
if (minSize > _baskets.Length)
|
if (minSize > _baskets.Length)
|
||||||
{
|
{
|
||||||
int newSize = 1 << (GetHighBitNumber((uint)minSize - 1) + 1);
|
int newSize = ArrayUtility.NormalizeSizeToPowerOfTwo(minSize);
|
||||||
Array.Resize(ref _baskets, newSize);
|
UnsafeArray.ResizeAndInit(ref _baskets, newSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static int GetHighBitNumber(uint bits)
|
#endregion
|
||||||
{
|
|
||||||
if (bits == 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int bit = 0;
|
|
||||||
if ((bits & 0xFFFF0000) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 16;
|
|
||||||
bit |= 16;
|
|
||||||
}
|
|
||||||
if ((bits & 0xFF00) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 8;
|
|
||||||
bit |= 8;
|
|
||||||
}
|
|
||||||
if ((bits & 0xF0) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 4;
|
|
||||||
bit |= 4;
|
|
||||||
}
|
|
||||||
if ((bits & 0xC) != 0)
|
|
||||||
{
|
|
||||||
bits >>= 2;
|
|
||||||
bit |= 2;
|
|
||||||
}
|
|
||||||
if ((bits & 0x2) != 0)
|
|
||||||
{
|
|
||||||
bit |= 1;
|
|
||||||
}
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Node
|
#region Node
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
||||||
public struct Node
|
public struct Node
|
||||||
{
|
{
|
||||||
public static readonly Node Empty = new Node() { value = 0, next = -1 };
|
public static readonly Node Empty = new Node() { value = 0, next = NULL };
|
||||||
public int value;
|
public int value;
|
||||||
/// <summary>next node index</summary>
|
/// <summary>next node index</summary>
|
||||||
public int next;
|
public int next;
|
||||||
@ -254,6 +239,18 @@ namespace DCFApixels.DragonECS
|
|||||||
this.next = next;
|
this.next = next;
|
||||||
this.prev = prev;
|
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})";
|
public override string ToString() => $"node({prev}<>{next} v:{value})";
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -301,7 +298,7 @@ namespace DCFApixels.DragonECS
|
|||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
public struct Enumerator : IEnumerator<int>
|
public struct Enumerator : IEnumerator<int>
|
||||||
{
|
{
|
||||||
private readonly Node[] _nodes;
|
private readonly UnsafeArray<Node> _nodes;
|
||||||
private int _nodeIndex;
|
private int _nodeIndex;
|
||||||
private int _nextNodeIndex;
|
private int _nextNodeIndex;
|
||||||
private int _count;
|
private int _count;
|
||||||
@ -361,17 +358,21 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
List<Node> result = new List<Node>();
|
List<Node> result = new List<Node>();
|
||||||
Node curNode = new Node();
|
Node curNode = new Node();
|
||||||
curNode.index = _basketList._recycledListLast;
|
curNode.index = _basketList._recycledListHead;
|
||||||
|
|
||||||
while (curNode.index != -1)
|
for (int i = 0; i < _basketList._nodes.Length; i++)
|
||||||
{
|
{
|
||||||
|
if (curNode.index == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
BasketList.Node x = _basketList.GetNode(curNode.index);
|
BasketList.Node x = _basketList.GetNode(curNode.index);
|
||||||
curNode.prev = x.prev;
|
curNode.prev = x.prev;
|
||||||
curNode.next = x.next;
|
curNode.next = x.next;
|
||||||
|
|
||||||
result.Add(curNode);
|
result.Add(curNode);
|
||||||
curNode = new Node();
|
|
||||||
curNode.index = curNode.prev;
|
curNode.index = curNode.next;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using DCFApixels.DragonECS.Utils;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@ -32,19 +31,27 @@ namespace DCFApixels.DragonECS.Relations.Internal
|
|||||||
|
|
||||||
public ref T this[int index]
|
public ref T this[int index]
|
||||||
{
|
{
|
||||||
get { return ref ptr[index]; }
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (index < 0 || index >= Length)
|
||||||
|
Throw.ArgumentOutOfRange();
|
||||||
|
#endif
|
||||||
|
return ref ptr[index];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray(int length)
|
public UnsafeArray(int length)
|
||||||
{
|
{
|
||||||
UnmanagedArrayUtility.New(out ptr, length);
|
ptr = UnmanagedArrayUtility.New<T>(length);
|
||||||
Length = length;
|
Length = length;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UnsafeArray(int length, bool isInit)
|
public UnsafeArray(int length, bool isInit)
|
||||||
{
|
{
|
||||||
UnmanagedArrayUtility.NewAndInit(out ptr, length);
|
ptr = UnmanagedArrayUtility.NewAndInit<T>(length);
|
||||||
Length = length;
|
Length = length;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -67,8 +74,7 @@ namespace DCFApixels.DragonECS.Relations.Internal
|
|||||||
}
|
}
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
T* ptr = this.ptr;
|
return $"ua({Length}) ({string.Join(", ", this.ToArray())})";
|
||||||
return CollectionUtility.AutoToString(EnumerableInt.Range(0, Length).Select(i => ptr[i]), "ua");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Resize(ref UnsafeArray<T> array, int newSize)
|
public static void Resize(ref UnsafeArray<T> array, int newSize)
|
||||||
@ -113,12 +119,18 @@ namespace DCFApixels.DragonECS.Relations.Internal
|
|||||||
|
|
||||||
internal class DebuggerProxy
|
internal class DebuggerProxy
|
||||||
{
|
{
|
||||||
|
public void* ptr;
|
||||||
public T[] elements;
|
public T[] elements;
|
||||||
public int length;
|
public int length;
|
||||||
public DebuggerProxy(UnsafeArray<T> instance)
|
public DebuggerProxy(UnsafeArray<T> instance)
|
||||||
{
|
{
|
||||||
elements = EnumerableInt.Range(0, instance.Length).Select(i => instance.ptr[i]).ToArray();
|
ptr = instance.ptr;
|
||||||
length = instance.Length;
|
length = instance.Length;
|
||||||
|
elements = new T[length];
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
elements[i] = instance[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user