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.

148 lines
5.1KB

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