mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Remove unsafe code from GrowableStack
This commit is contained in:
@@ -870,7 +870,7 @@ namespace Robust.Shared.Physics
|
||||
|
||||
public void Query<TState>(ref TState state, QueryCallback<TState> callback, in Box2 aabb)
|
||||
{
|
||||
using var stack = new GrowableStack<Proxy>(stackalloc Proxy[256]);
|
||||
var stack = new GrowableStack<Proxy>(stackalloc Proxy[256]);
|
||||
stack.Push(_root);
|
||||
|
||||
ref var baseRef = ref _nodes[0];
|
||||
@@ -915,7 +915,7 @@ namespace Robust.Shared.Physics
|
||||
{
|
||||
// NOTE: This is not Box2D's normal ray cast function, since our rays have infinite length.
|
||||
|
||||
using var stack = new GrowableStack<Proxy>(stackalloc Proxy[256]);
|
||||
var stack = new GrowableStack<Proxy>(stackalloc Proxy[256]);
|
||||
|
||||
stack.Push(_root);
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Robust.Shared.Utility
|
||||
{
|
||||
@@ -10,62 +9,31 @@ namespace Robust.Shared.Utility
|
||||
/// If the stack size exceeds the initial capacity, the heap is used
|
||||
/// to increase the size of the stack.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// You MUST call <see cref="Dispose"/> when you are done with this stack or else you will have a memory leak.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of elements in the stack.</typeparam>
|
||||
internal unsafe ref struct GrowableStack<T> where T : unmanaged
|
||||
internal ref struct GrowableStack<T> where T : unmanaged
|
||||
{
|
||||
// TODO: Switch to managed arrays for the on-heap alloc when we have .NET 5.
|
||||
// Because with .NET 5 we can use the Pinned Object Heap.
|
||||
private T* _stack;
|
||||
private bool _wasReallocated;
|
||||
private Span<T> _stack;
|
||||
private int _count;
|
||||
private int _capacity;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the growable stack with the allocated space as stack space.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <paramref name="stackSpace"/> MUST BE A PIECE OF PINNED MEMORY,
|
||||
/// OR ELSE YOU HAVE A MASSIVE GC BUG ON YOUR HAND.
|
||||
/// </remarks>
|
||||
public GrowableStack(Span<T> stackSpace)
|
||||
{
|
||||
fixed (T* ap = stackSpace)
|
||||
{
|
||||
_stack = ap;
|
||||
}
|
||||
|
||||
_stack = stackSpace;
|
||||
_capacity = stackSpace.Length;
|
||||
_wasReallocated = false;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_wasReallocated)
|
||||
{
|
||||
Marshal.FreeHGlobal((IntPtr) _stack);
|
||||
_stack = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Push(in T element)
|
||||
{
|
||||
if (_count == _capacity)
|
||||
{
|
||||
var old = _stack;
|
||||
_capacity *= 2;
|
||||
var dstSize = _capacity * sizeof(T);
|
||||
_stack = (T*) Marshal.AllocHGlobal(dstSize);
|
||||
Buffer.MemoryCopy(old, _stack, dstSize, _count * sizeof(T));
|
||||
if (_wasReallocated)
|
||||
{
|
||||
Marshal.FreeHGlobal((IntPtr) old);
|
||||
}
|
||||
|
||||
_wasReallocated = true;
|
||||
var oldStack = _stack;
|
||||
_stack = GC.AllocateUninitializedArray<T>(_capacity);
|
||||
oldStack.CopyTo(_stack);
|
||||
}
|
||||
|
||||
_stack[_count] = element;
|
||||
@@ -74,7 +42,6 @@ namespace Robust.Shared.Utility
|
||||
|
||||
public T Pop()
|
||||
{
|
||||
DebugTools.Assert(_count > 0);
|
||||
--_count;
|
||||
return _stack[_count];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user