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.

213 lines
8.9KB

  1. using System;
  2. using Svelto.DataStructures;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// This feature must be eventually tied to the new ExclusiveGroup that won't allow the use of custom EntitiesID
  7. /// The filters could be updated when entities buffer changes during the submission, while now this process
  8. /// is completely manual.
  9. /// Making this working properly is not in my priorities right now, as I will need to add the new group type
  10. /// AND optimize the submission process to be able to add more overhead
  11. /// </summary>
  12. public partial class EntitiesDB
  13. {
  14. public readonly struct Filters
  15. {
  16. public Filters
  17. (FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, GroupFilters>> filters)
  18. {
  19. _filters = filters;
  20. }
  21. public ref FilterGroup CreateOrGetFilterForGroup<T>(int filterID, ExclusiveGroupStruct groupID)
  22. where T : struct, IEntityComponent
  23. {
  24. var refWrapper = TypeRefWrapper<T>.wrapper;
  25. return ref CreateOrGetFilterForGroup(filterID, groupID, refWrapper);
  26. }
  27. ref FilterGroup CreateOrGetFilterForGroup(int filterID, ExclusiveGroupStruct groupID, RefWrapperType refWrapper)
  28. {
  29. var fasterDictionary =
  30. _filters.GetOrCreate(refWrapper, () => new FasterDictionary<ExclusiveGroupStruct, GroupFilters>());
  31. GroupFilters filters =
  32. fasterDictionary.GetOrCreate(
  33. groupID, () => new GroupFilters(new SharedSveltoDictionaryNative<int, FilterGroup>(0), groupID));
  34. return ref filters.CreateOrGetFilter(filterID);
  35. }
  36. public bool HasFiltersForGroup<T>(ExclusiveGroupStruct groupID) where T : struct, IEntityComponent
  37. {
  38. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
  39. return false;
  40. return fasterDictionary.ContainsKey(groupID);
  41. }
  42. public bool HasFilterForGroup<T>(int filterID, ExclusiveGroupStruct groupID)
  43. where T : struct, IEntityComponent
  44. {
  45. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
  46. return false;
  47. if (fasterDictionary.TryGetValue(groupID, out var result))
  48. return result.HasFilter(filterID);
  49. return false;
  50. }
  51. public ref GroupFilters CreateOrGetFiltersForGroup<T>(ExclusiveGroupStruct groupID)
  52. where T : struct, IEntityComponent
  53. {
  54. var fasterDictionary =
  55. _filters.GetOrCreate(TypeRefWrapper<T>.wrapper, () => new FasterDictionary<ExclusiveGroupStruct, GroupFilters>());
  56. return ref
  57. fasterDictionary.GetOrCreate(
  58. groupID, () => new GroupFilters(new SharedSveltoDictionaryNative<int, FilterGroup>(0), groupID));
  59. }
  60. public ref GroupFilters GetFiltersForGroup<T>(ExclusiveGroupStruct groupID)
  61. where T : struct, IEntityComponent
  62. {
  63. #if DEBUG && !PROFILE_SVELTO
  64. if (_filters.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
  65. throw new ECSException(
  66. $"trying to fetch not existing filters, type {typeof(T)}");
  67. if (_filters[TypeRefWrapper<T>.wrapper].ContainsKey(groupID) == false)
  68. throw new ECSException(
  69. $"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}");
  70. #endif
  71. return ref _filters[TypeRefWrapper<T>.wrapper].GetValueByRef(groupID);
  72. }
  73. public ref FilterGroup GetFilterForGroup<T>(int filterId, ExclusiveGroupStruct groupID)
  74. where T : struct, IEntityComponent
  75. {
  76. #if DEBUG && !PROFILE_SVELTO
  77. if (_filters.ContainsKey(TypeRefWrapper<T>.wrapper) == false)
  78. throw new ECSException(
  79. $"trying to fetch not existing filters, type {typeof(T)}");
  80. if (_filters[TypeRefWrapper<T>.wrapper].ContainsKey(groupID) == false)
  81. throw new ECSException(
  82. $"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}");
  83. #endif
  84. return ref _filters[TypeRefWrapper<T>.wrapper][groupID].GetFilter(filterId);
  85. }
  86. public bool TryGetFilterForGroup<T>(int filterId, ExclusiveGroupStruct groupID, out FilterGroup groupFilter)
  87. where T : struct, IEntityComponent
  88. {
  89. groupFilter = default;
  90. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
  91. return false;
  92. if (fasterDictionary.TryGetValue(groupID, out var groupFilters) == false)
  93. return false;
  94. if (groupFilters.TryGetFilter(filterId, out groupFilter) == false)
  95. return false;
  96. return true;
  97. }
  98. public bool TryGetFiltersForGroup<T>(ExclusiveGroupStruct groupID, out GroupFilters groupFilters)
  99. where T : struct, IEntityComponent
  100. {
  101. groupFilters = default;
  102. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == false)
  103. return false;
  104. return fasterDictionary.TryGetValue(groupID, out groupFilters);
  105. }
  106. public void ClearFilter<T>(int filterID, ExclusiveGroupStruct exclusiveGroupStruct)
  107. {
  108. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == true)
  109. {
  110. DBC.ECS.Check.Require(fasterDictionary.ContainsKey(exclusiveGroupStruct), $"trying to clear filter not present in group {exclusiveGroupStruct}");
  111. fasterDictionary[exclusiveGroupStruct].ClearFilter(filterID);
  112. }
  113. }
  114. public void ClearFilters<T>(int filterID)
  115. {
  116. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == true)
  117. {
  118. foreach (var filtersPerGroup in fasterDictionary)
  119. filtersPerGroup.Value.ClearFilter(filterID);
  120. }
  121. }
  122. public void DisposeFilters<T>(ExclusiveGroupStruct exclusiveGroupStruct)
  123. {
  124. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == true)
  125. {
  126. fasterDictionary[exclusiveGroupStruct].DisposeFilters();
  127. fasterDictionary.Remove(exclusiveGroupStruct);
  128. }
  129. }
  130. public void DisposeFilters<T>()
  131. {
  132. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == true)
  133. {
  134. foreach (var filtersPerGroup in fasterDictionary)
  135. filtersPerGroup.Value.DisposeFilters();
  136. }
  137. _filters.Remove(TypeRefWrapper<T>.wrapper);
  138. }
  139. public void DisposeFilterForGroup<T>(int resetFilterID, ExclusiveGroupStruct @group)
  140. {
  141. if (_filters.TryGetValue(TypeRefWrapper<T>.wrapper, out var fasterDictionary) == true)
  142. {
  143. fasterDictionary[group].DisposeFilter(resetFilterID);
  144. }
  145. }
  146. public bool TryRemoveEntityFromFilter<T>(int filtersID, EGID egid) where T : unmanaged, IEntityComponent
  147. {
  148. if (TryGetFilterForGroup<T>(filtersID, egid.groupID, out var filter))
  149. {
  150. return filter.TryRemove(egid.entityID);
  151. }
  152. return false;
  153. }
  154. public void RemoveEntityFromFilter<T>(int filtersID, EGID egid) where T : unmanaged, IEntityComponent
  155. {
  156. ref var filter = ref GetFilterForGroup<T>(filtersID, egid.groupID);
  157. filter.Remove(egid.entityID);
  158. }
  159. public void AddEntityToFilter<N>(int filtersID, EGID egid, N mapper) where N:IEGIDMapper
  160. {
  161. ref var filter = ref CreateOrGetFilterForGroup(filtersID, egid.groupID, new RefWrapperType(mapper.entityType));
  162. filter.Add(egid.entityID, mapper);
  163. }
  164. readonly FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, GroupFilters>> _filters;
  165. }
  166. public Filters GetFilters()
  167. {
  168. return new Filters(_filters);
  169. }
  170. FasterDictionary<RefWrapperType, FasterDictionary<ExclusiveGroupStruct, GroupFilters>> _filters
  171. => _enginesRoot._groupFilters;
  172. }
  173. }