Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
4.0KB

  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Svelto.Common;
  4. namespace Svelto.ECS.DataStructures
  5. {
  6. struct UnsafeArray
  7. {
  8. internal unsafe byte* ptr => _ptr;
  9. //expressed in bytes
  10. internal int capacity => (int) _capacity;
  11. //expressed in bytes
  12. internal int count => (int) _writeIndex;
  13. //expressed in bytes
  14. internal int space => capacity - count;
  15. #if DEBUG && !PROFILE_SVELTO
  16. #pragma warning disable 649
  17. internal uint id;
  18. #pragma warning restore 649
  19. #endif
  20. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  21. public ref T Get<T>(uint index) where T : struct
  22. {
  23. unsafe
  24. {
  25. #if DEBUG && !PROFILE_SVELTO
  26. uint sizeOf = (uint) MemoryUtilities.SizeOf<T>();
  27. if (index + sizeOf > _writeIndex)
  28. throw new Exception("no reading authorized");
  29. #endif
  30. return ref Unsafe.AsRef<T>(Unsafe.Add<T>(ptr, (int) index));
  31. }
  32. }
  33. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  34. public void Set<T>(uint index, in T value) where T : struct
  35. {
  36. unsafe
  37. {
  38. uint sizeOf = (uint) MemoryUtilities.SizeOf<T>();
  39. uint writeIndex = (uint) (index * sizeOf);
  40. #if DEBUG && !PROFILE_SVELTO
  41. if (_capacity < writeIndex + sizeOf)
  42. throw new Exception("no writing authorized");
  43. #endif
  44. Unsafe.AsRef<T>(Unsafe.Add<T>(_ptr, (int) index)) = value;
  45. if (_writeIndex < writeIndex + sizeOf)
  46. _writeIndex = (uint) (writeIndex + sizeOf);
  47. }
  48. }
  49. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  50. public void Add<T>(in T value) where T : struct
  51. {
  52. unsafe
  53. {
  54. var structSize = MemoryUtilities.SizeOf<T>();
  55. #if DEBUG && !PROFILE_SVELTO
  56. if (space - structSize < 0)
  57. throw new Exception("no writing authorized");
  58. #endif
  59. Unsafe.Write(ptr + _writeIndex, value);
  60. _writeIndex += (uint)structSize;
  61. }
  62. }
  63. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  64. public ref T Pop<T>() where T : struct
  65. {
  66. unsafe
  67. {
  68. var structSize = MemoryUtilities.SizeOf<T>();
  69. _writeIndex -= (uint)structSize;
  70. return ref Unsafe.AsRef<T>(ptr + _writeIndex);
  71. }
  72. }
  73. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  74. internal void Realloc(uint newCapacity, Allocator allocator)
  75. {
  76. unsafe
  77. {
  78. if (_ptr == null)
  79. _ptr = (byte*) MemoryUtilities.Alloc(newCapacity, allocator);
  80. else
  81. _ptr = (byte*) MemoryUtilities.Realloc((IntPtr) _ptr, (uint) count, newCapacity, allocator);
  82. _capacity = newCapacity;
  83. }
  84. }
  85. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  86. public void Dispose(Allocator allocator)
  87. {
  88. unsafe
  89. {
  90. if (ptr != null)
  91. MemoryUtilities.Free((IntPtr) ptr, allocator);
  92. _ptr = null;
  93. _writeIndex = 0;
  94. _capacity = 0;
  95. }
  96. }
  97. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  98. public void Clear()
  99. {
  100. _writeIndex = 0;
  101. }
  102. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  103. public void SetCountTo(uint count)
  104. {
  105. _writeIndex = count;
  106. }
  107. #if UNITY_NATIVE
  108. [global::Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction]
  109. #endif
  110. unsafe byte* _ptr;
  111. uint _writeIndex;
  112. uint _capacity;
  113. }
  114. }