Mirror of Svelto.ECS because we're a fan of it
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

198 linhas
6.8KB

  1. using System.Runtime.CompilerServices;
  2. using Svelto.Common;
  3. using Svelto.DataStructures.Native;
  4. using Svelto.ECS.Native;
  5. namespace Svelto.ECS
  6. {
  7. public readonly struct EntityFilterCollection
  8. {
  9. internal EntityFilterCollection(CombinedFilterID combinedFilterId,
  10. Allocator allocatorStrategy = Allocator.Persistent)
  11. {
  12. _filtersPerGroup =
  13. SharedSveltoDictionaryNative<ExclusiveGroupStruct, GroupFilters>.Create(allocatorStrategy);
  14. combinedFilterID = combinedFilterId;
  15. }
  16. public CombinedFilterID combinedFilterID { get; }
  17. public EntityFilterIterator GetEnumerator() => new EntityFilterIterator(this);
  18. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  19. public bool Add<T>(EGID egid, NativeEGIDMapper<T> mmap) where T : unmanaged, IEntityComponent
  20. {
  21. DBC.ECS.Check.Require(mmap.groupID == egid.groupID, "not compatible NativeEgidMapper used");
  22. return Add(egid, mmap.GetIndex(egid.entityID));
  23. }
  24. public bool Add<T>(EGID egid, NativeEGIDMultiMapper<T> mmap) where T : unmanaged, IEntityComponent
  25. {
  26. return Add(egid, mmap.GetIndex(egid));
  27. }
  28. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  29. public bool Add(EGID egid, uint toIndex)
  30. {
  31. return GetGroupFilter(egid.groupID).Add(egid.entityID, toIndex);
  32. }
  33. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  34. public void Add(uint entityID, ExclusiveGroupStruct groupId, uint index)
  35. {
  36. Add(new EGID(entityID, groupId), index);
  37. }
  38. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  39. public void Remove(EGID egid)
  40. {
  41. _filtersPerGroup[egid.groupID].Remove(egid.entityID);
  42. }
  43. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  44. public bool Exists(EGID egid)
  45. {
  46. return GetGroupFilter(egid.groupID).Exists(egid.entityID);
  47. }
  48. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  49. public GroupFilters GetGroupFilter(ExclusiveGroupStruct group)
  50. {
  51. if (_filtersPerGroup.TryGetValue(group, out var groupFilter) == false)
  52. {
  53. groupFilter = new GroupFilters(group);
  54. _filtersPerGroup.Add(group, groupFilter);
  55. }
  56. return groupFilter;
  57. }
  58. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  59. public void Clear()
  60. {
  61. var filterSets = _filtersPerGroup.GetValues(out var count);
  62. for (var i = 0; i < count; i++)
  63. {
  64. filterSets[i].Clear();
  65. }
  66. }
  67. internal int groupCount => _filtersPerGroup.count;
  68. public void ComputeFinalCount(out int count)
  69. {
  70. count = 0;
  71. for (int i = 0; i < _filtersPerGroup.count; i++)
  72. {
  73. count += (int)GetGroup(i).count;
  74. }
  75. }
  76. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  77. internal GroupFilters GetGroup(int indexGroup)
  78. {
  79. DBC.ECS.Check.Require(indexGroup < _filtersPerGroup.count);
  80. return _filtersPerGroup.GetValues(out _)[indexGroup];
  81. }
  82. public void Dispose()
  83. {
  84. var filterSets = _filtersPerGroup.GetValues(out var count);
  85. for (var i = 0; i < count; i++)
  86. {
  87. filterSets[i].Dispose();
  88. }
  89. _filtersPerGroup.Dispose();
  90. }
  91. internal readonly SharedSveltoDictionaryNative<ExclusiveGroupStruct, GroupFilters> _filtersPerGroup;
  92. public struct GroupFilters
  93. {
  94. internal GroupFilters(ExclusiveGroupStruct group) : this()
  95. {
  96. _entityIDToDenseIndex = new SharedSveltoDictionaryNative<uint, uint>(1);
  97. _indexToEntityId = new SharedSveltoDictionaryNative<uint, uint>(1);
  98. _group = group;
  99. }
  100. public bool Add(uint entityId, uint entityIndex)
  101. {
  102. //TODO: when sentinels are finished, we need to add AsWriter here
  103. if (_entityIDToDenseIndex.TryAdd(entityId, entityIndex, out _))
  104. {
  105. _indexToEntityId[entityIndex] = entityId;
  106. return true;
  107. }
  108. return false;
  109. }
  110. public bool Exists(uint entityId) => _entityIDToDenseIndex.ContainsKey(entityId);
  111. public void Remove(uint entityId)
  112. {
  113. _indexToEntityId.Remove(_entityIDToDenseIndex[entityId]);
  114. _entityIDToDenseIndex.Remove(entityId);
  115. }
  116. public EntityFilterIndices indices
  117. {
  118. get
  119. {
  120. var values = _entityIDToDenseIndex.GetValues(out var count);
  121. return new EntityFilterIndices(values, count);
  122. }
  123. }
  124. public int count => _entityIDToDenseIndex.count;
  125. public bool isValid => _entityIDToDenseIndex.isValid;
  126. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  127. internal void RemoveWithSwapBack(uint entityId, uint entityIndex, uint lastIndex)
  128. {
  129. // Check if the last index is part of the filter as an entity, in that case
  130. //we need to update the filter
  131. if (entityIndex != lastIndex && _indexToEntityId.TryGetValue(lastIndex, out var lastEntityID))
  132. {
  133. _entityIDToDenseIndex[lastEntityID] = entityIndex;
  134. _indexToEntityId[entityIndex] = lastEntityID;
  135. _indexToEntityId.Remove(lastIndex);
  136. }
  137. else
  138. {
  139. // We don't need to check if the entityIndex is a part of the dictionary.
  140. // The Remove function will check for us.
  141. _indexToEntityId.Remove(entityIndex);
  142. }
  143. // We don't need to check if the entityID is part of the dictionary.
  144. // The Remove function will check for us.
  145. _entityIDToDenseIndex.Remove(entityId);
  146. }
  147. internal void Clear()
  148. {
  149. _indexToEntityId.FastClear();
  150. _entityIDToDenseIndex.FastClear();
  151. }
  152. internal void Dispose()
  153. {
  154. _entityIDToDenseIndex.Dispose();
  155. _indexToEntityId.Dispose();
  156. }
  157. internal ExclusiveGroupStruct group => _group;
  158. SharedSveltoDictionaryNative<uint, uint> _indexToEntityId;
  159. internal SharedSveltoDictionaryNative<uint, uint> _entityIDToDenseIndex;
  160. readonly ExclusiveGroupStruct _group;
  161. }
  162. }
  163. }