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.

78 lines
3.3KB

  1. using System;
  2. using Svelto.DataStructures;
  3. using Svelto.DataStructures.Native;
  4. using Svelto.ECS.DataStructures;
  5. namespace Svelto.ECS.Native
  6. {
  7. /// <summary>
  8. /// Note: this class should really be ref struct by design. It holds the reference of a dictionary that can become
  9. /// invalid. Unfortunately it can be a ref struct, because Jobs needs to hold if by paramater. So the deal is
  10. /// that a job can use it as long as nothing else is modifying the entities database and the NativeEGIDMultiMapper
  11. /// is disposed right after the use.
  12. ///
  13. ///WARNING: REMEMBER THIS MUST BE DISPOSED OF, AS IT USES NATIVE MEMORY. IT WILL LEAK MEMORY OTHERWISE
  14. ///
  15. /// </summary>
  16. public struct NativeEGIDMultiMapper<T> : IDisposable where T : unmanaged, IEntityComponent
  17. {
  18. public NativeEGIDMultiMapper(in SveltoDictionary<
  19. /*key */ExclusiveGroupStruct,
  20. /*value*/
  21. SharedNative<SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<T>,
  22. NativeStrategy<int>>>,
  23. /*strategy to store the key*/ NativeStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>,
  24. /*strategy to store the value*/
  25. NativeStrategy<SharedNative<SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>,
  26. NativeStrategy<T>, NativeStrategy<int>>>>, NativeStrategy<int>> dictionary)
  27. {
  28. _dic = dictionary;
  29. }
  30. public int count => (int)_dic.count;
  31. public void Dispose()
  32. {
  33. _dic.Dispose();
  34. }
  35. public ref T Entity(EGID entity)
  36. {
  37. #if DEBUG && !PROFILE_SVELTO
  38. if (Exists(entity) == false)
  39. throw new Exception($"NativeEGIDMultiMapper: Entity not found {entity}");
  40. #endif
  41. ref var sveltoDictionary = ref _dic.GetValueByRef(entity.groupID);
  42. return ref sveltoDictionary.value.GetValueByRef(entity.entityID);
  43. }
  44. public uint GetIndex(EGID entity)
  45. {
  46. #if DEBUG && !PROFILE_SVELTO
  47. if (Exists(entity) == false)
  48. throw new Exception($"NativeEGIDMultiMapper: Entity not found {entity}");
  49. #endif
  50. ref var sveltoDictionary = ref _dic.GetValueByRef(entity.groupID);
  51. return sveltoDictionary.value.GetIndex(entity.entityID);
  52. }
  53. public bool Exists(EGID entity)
  54. {
  55. return _dic.TryFindIndex(entity.groupID, out var index) &&
  56. _dic.GetDirectValueByRef(index).value.ContainsKey(entity.entityID);
  57. }
  58. public bool TryGetEntity(EGID entity, out T component)
  59. {
  60. component = default;
  61. return _dic.TryFindIndex(entity.groupID, out var index) &&
  62. _dic.GetDirectValueByRef(index).value.TryGetValue(entity.entityID, out component);
  63. }
  64. SveltoDictionary<ExclusiveGroupStruct,
  65. SharedNative<SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<T>,
  66. NativeStrategy<int>>>, NativeStrategy<SveltoDictionaryNode<ExclusiveGroupStruct>>, NativeStrategy<
  67. SharedNative<SveltoDictionary<uint, T, NativeStrategy<SveltoDictionaryNode<uint>>, NativeStrategy<T>,
  68. NativeStrategy<int>>>>, NativeStrategy<int>> _dic;
  69. }
  70. }