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.

147 lines
4.4KB

  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<T>(uint newCapacity, Allocator allocator) where T : struct
  75. {
  76. unsafe
  77. {
  78. var structSize = (uint) MemoryUtilities.SizeOf<T>();
  79. uint newCapacityInBytes = structSize * newCapacity;
  80. if (_ptr == null)
  81. _ptr = (byte*) MemoryUtilities.Alloc(newCapacityInBytes, allocator);
  82. else
  83. _ptr = (byte*) MemoryUtilities.Realloc((IntPtr) _ptr, newCapacityInBytes, allocator, (uint) count);
  84. _capacity = newCapacityInBytes;
  85. }
  86. }
  87. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  88. public void Dispose(Allocator allocator)
  89. {
  90. unsafe
  91. {
  92. #if DEBUG && !PROFILE_SVELTO
  93. if (ptr == null)
  94. throw new Exception("UnsafeArray: try to dispose an already disposed array");
  95. #endif
  96. MemoryUtilities.Free((IntPtr) ptr, allocator);
  97. _ptr = null;
  98. _writeIndex = 0;
  99. _capacity = 0;
  100. }
  101. }
  102. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  103. public void Clear()
  104. {
  105. _writeIndex = 0;
  106. }
  107. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  108. public void SetCountTo(uint count)
  109. {
  110. _writeIndex = count;
  111. }
  112. #if UNITY_COLLECTIONS || UNITY_JOBS || UNITY_BURST
  113. #if UNITY_BURST
  114. [Unity.Burst.NoAlias]
  115. #endif
  116. [Unity.Collections.LowLevel.Unsafe.NativeDisableUnsafePtrRestriction]
  117. #endif
  118. unsafe byte* _ptr;
  119. uint _writeIndex;
  120. uint _capacity;
  121. }
  122. }