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.

108 lines
3.7KB

  1. #if UNITY_NATIVE
  2. using System;
  3. using System.Runtime.CompilerServices;
  4. using Svelto.Common;
  5. using Svelto.DataStructures;
  6. using Svelto.DataStructures.Native;
  7. namespace Svelto.ECS.Native
  8. {
  9. /// <summary>
  10. /// Note: this class should really be ref struct by design. It holds the reference of a dictionary that can become
  11. /// invalid. Unfortunately it can be a ref struct, because Jobs needs to hold if by paramater. So the deal is
  12. /// that a job can use it as long as nothing else is modifying the entities database and the NativeEGIDMapper
  13. /// is disposed right after the use.
  14. /// </summary>
  15. public readonly struct NativeEGIDMapper<T> : IEGIDMapper where T : unmanaged, IEntityComponent
  16. {
  17. public NativeEGIDMapper
  18. (ExclusiveGroupStruct groupStructId
  19. , SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<T>, NativeStrategy<int>>
  20. toNative) : this()
  21. {
  22. groupID = groupStructId;
  23. _map = new SveltoDictionaryNative<uint, T>();
  24. _map.UnsafeCast(toNative);
  25. }
  26. public int count => _map.count;
  27. public Type entityType => TypeCache<T>.type;
  28. public ExclusiveGroupStruct groupID { get; }
  29. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  30. public ref T Entity(uint entityID)
  31. {
  32. #if DEBUG
  33. if (_map.TryFindIndex(entityID, out var findIndex) == false)
  34. throw new Exception("Entity not found in this group ".FastConcat(typeof(T).ToString()));
  35. #else
  36. _map.TryFindIndex(entityID, out var findIndex);
  37. #endif
  38. return ref _map.GetDirectValueByRef(findIndex);
  39. }
  40. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  41. public bool TryGetEntity(uint entityID, out T value)
  42. {
  43. if (_map.count > 0 && _map.TryFindIndex(entityID, out var index))
  44. unsafe
  45. {
  46. value = Unsafe.AsRef<T>(Unsafe.Add<T>((void*) _map.GetValues(out _).ToNativeArray(out _)
  47. , (int) index));
  48. return true;
  49. }
  50. value = default;
  51. return false;
  52. }
  53. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  54. public NB<T> GetArrayAndEntityIndex(uint entityID, out uint index)
  55. {
  56. if (_map.TryFindIndex(entityID, out index))
  57. return new NB<T>(_map.GetValues(out var count).ToNativeArray(out _), count);
  58. #if DEBUG
  59. throw new ECSException("Entity not found");
  60. #else
  61. return default;
  62. #endif
  63. }
  64. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  65. public bool TryGetArrayAndEntityIndex(uint entityID, out uint index, out NB<T> array)
  66. {
  67. index = 0;
  68. if (_map.count > 0 && _map.TryFindIndex(entityID, out index))
  69. {
  70. array = new NB<T>(_map.GetValues(out var count).ToNativeArray(out _), count);
  71. return true;
  72. }
  73. array = default;
  74. return false;
  75. }
  76. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  77. public bool Exists(uint idEntityId)
  78. {
  79. return _map.count > 0 && _map.TryFindIndex(idEntityId, out _);
  80. }
  81. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  82. public uint GetIndex(uint entityID)
  83. {
  84. return _map.GetIndex(entityID);
  85. }
  86. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  87. public bool FindIndex(uint valueKey, out uint index)
  88. {
  89. return _map.TryFindIndex(valueKey, out index);
  90. }
  91. readonly SveltoDictionaryNative<uint, T> _map;
  92. }
  93. }
  94. #endif