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.

149 lines
5.1KB

  1. using System.Runtime.CompilerServices;
  2. using Svelto.DataStructures.Native;
  3. using Svelto.ECS.Internal;
  4. using Svelto.ECS.Native;
  5. namespace Svelto.ECS
  6. {
  7. public struct NativeEntityFilterCollection<T> where T : unmanaged, _IInternalEntityComponent
  8. {
  9. internal NativeEntityFilterCollection(NativeEGIDMultiMapper<T> mmap)
  10. {
  11. _mmap = mmap;
  12. _filtersPerGroup = new SharedSveltoDictionaryNative<ExclusiveGroupStruct, GroupFilters>();
  13. }
  14. public NativeEntityFilterIterator<T> iterator => new NativeEntityFilterIterator<T>(this);
  15. public void AddEntity(EGID egid)
  16. {
  17. AddEntity(egid, _mmap.GetIndex(egid));
  18. }
  19. public void RemoveEntity(EGID egid)
  20. {
  21. _filtersPerGroup[egid.groupID].Remove(egid.entityID);
  22. }
  23. public void Clear()
  24. {
  25. var filterSets = _filtersPerGroup.GetValues(out var count);
  26. for (var i = 0; i < count; i++)
  27. {
  28. filterSets[i].Clear();
  29. }
  30. }
  31. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  32. void AddEntity(EGID egid, uint toIndex)
  33. {
  34. if (_filtersPerGroup.TryGetValue(egid.groupID, out var groupFilter) == false)
  35. {
  36. groupFilter = new GroupFilters(32, egid.groupID);
  37. _filtersPerGroup[egid.groupID] = groupFilter;
  38. }
  39. groupFilter.Add(egid.entityID, toIndex);
  40. }
  41. internal int groupCount => _filtersPerGroup.count;
  42. internal GroupFilters GetGroup(int indexGroup)
  43. {
  44. DBC.ECS.Check.Require(indexGroup < _filtersPerGroup.count);
  45. return _filtersPerGroup.GetValues(out _)[indexGroup];
  46. }
  47. internal void Dispose()
  48. {
  49. var filterSets = _filtersPerGroup.GetValues(out var count);
  50. for (var i = 0; i < count; i++)
  51. {
  52. filterSets[i].Dispose();
  53. }
  54. }
  55. readonly NativeEGIDMultiMapper<T> _mmap;
  56. //double check if this needs to be shared
  57. SharedSveltoDictionaryNative<ExclusiveGroupStruct, GroupFilters> _filtersPerGroup;
  58. internal struct GroupFilters
  59. {
  60. internal GroupFilters(uint size, ExclusiveGroupStruct group)
  61. {
  62. _entityIDToDenseIndex = new SharedSveltoDictionaryNative<uint, uint>(size);
  63. _indexToEntityId = new SharedSveltoDictionaryNative<uint, uint>(size);
  64. _group = group;
  65. }
  66. internal void Add(uint entityId, uint entityIndex)
  67. {
  68. _entityIDToDenseIndex.Add(entityId, entityIndex);
  69. _indexToEntityId.Add(entityIndex, entityId);
  70. }
  71. internal void Remove(uint entityId)
  72. {
  73. _indexToEntityId.Remove(_entityIDToDenseIndex[entityId]);
  74. _entityIDToDenseIndex.Remove(entityId);
  75. }
  76. internal void RemoveWithSwapBack(uint entityId, uint entityIndex, uint lastIndex)
  77. {
  78. // Check if the last index is part of the filter as an entity, in that case
  79. //we need to update the filter
  80. if (entityIndex != lastIndex && _indexToEntityId.ContainsKey(lastIndex))
  81. {
  82. uint lastEntityID = _indexToEntityId[lastIndex];
  83. _entityIDToDenseIndex[lastEntityID] = entityIndex;
  84. _indexToEntityId[entityIndex] = lastEntityID;
  85. _indexToEntityId.Remove(lastIndex);
  86. }
  87. else
  88. {
  89. // We don't need to check if the entityIndex is a part of the dictionary.
  90. // The Remove function will check for us.
  91. _indexToEntityId.Remove(entityIndex);
  92. }
  93. // We don't need to check if the entityID is part of the dictionary.
  94. // The Remove function will check for us.
  95. _entityIDToDenseIndex.Remove(entityId);
  96. }
  97. internal void Clear()
  98. {
  99. _indexToEntityId.Clear();
  100. _entityIDToDenseIndex.Clear();
  101. }
  102. internal bool HasEntity(uint entityId) => _entityIDToDenseIndex.ContainsKey(entityId);
  103. internal void Dispose()
  104. {
  105. _entityIDToDenseIndex.Dispose();
  106. _indexToEntityId.Dispose();
  107. }
  108. internal EntityFilterIndices indices
  109. {
  110. get
  111. {
  112. var values = _entityIDToDenseIndex.GetValues(out var count);
  113. return new EntityFilterIndices(values, count);
  114. }
  115. }
  116. internal uint count => (uint)_entityIDToDenseIndex.count;
  117. internal ExclusiveGroupStruct group => _group;
  118. //double check if these need to be shared
  119. SharedSveltoDictionaryNative<uint, uint> _indexToEntityId;
  120. SharedSveltoDictionaryNative<uint, uint> _entityIDToDenseIndex;
  121. readonly ExclusiveGroupStruct _group;
  122. }
  123. }
  124. }