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.

107 lines
3.7KB

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