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.

218 linhas
7.4KB

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