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.

211 lines
9.0KB

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