using Svelto.DataStructures; namespace Svelto.ECS { /// /// This feature must be eventually tied to the new ExclusiveGroup that won't allow the use of custom EntitiesID /// The filters could be updated when entities buffer changes during the submission, while now this process /// is completely manual. /// Making this working properly is not in my priorities right now, as I will need to add the new group type /// AND optimize the submission process to be able to add more overhead /// public partial class EntitiesDB { public readonly struct Filters { public Filters (FasterDictionary> filters) { _filters = filters; } public ref FilterGroup CreateOrGetFilterForGroup(int filterID, ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { var refWrapper = TypeRefWrapper.wrapper; return ref CreateOrGetFilterForGroup(filterID, groupID, refWrapper); } internal ref FilterGroup CreateOrGetFilterForGroup (int filterID, ExclusiveGroupStruct groupID, RefWrapperType refWrapper) { var fasterDictionary = _filters.GetOrCreate(refWrapper, () => new FasterDictionary()); GroupFilters filters = fasterDictionary.GetOrCreate( groupID, () => new GroupFilters(new SharedSveltoDictionaryNative(0), groupID)); return ref filters.CreateOrGetFilter(filterID); } public bool HasFiltersForGroup(ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == false) return false; return fasterDictionary.ContainsKey(groupID); } public bool HasFilterForGroup(int filterID, ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == false) return false; if (fasterDictionary.TryGetValue(groupID, out var result)) return result.HasFilter(filterID); return false; } public ref GroupFilters CreateOrGetFiltersForGroup(ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { var fasterDictionary = _filters.GetOrCreate(TypeRefWrapper.wrapper , () => new FasterDictionary()); return ref fasterDictionary.GetOrCreate( groupID, () => new GroupFilters(new SharedSveltoDictionaryNative(0), groupID)); } public ref GroupFilters GetFiltersForGroup(ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { #if DEBUG && !PROFILE_SVELTO if (_filters.ContainsKey(TypeRefWrapper.wrapper) == false) throw new ECSException($"trying to fetch not existing filters, type {typeof(T)}"); if (_filters[TypeRefWrapper.wrapper].ContainsKey(groupID) == false) throw new ECSException( $"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}"); #endif return ref _filters[TypeRefWrapper.wrapper].GetValueByRef(groupID); } public ref FilterGroup GetFilterForGroup(int filterId, ExclusiveGroupStruct groupID) where T : struct, IEntityComponent { #if DEBUG && !PROFILE_SVELTO if (_filters.ContainsKey(TypeRefWrapper.wrapper) == false) throw new ECSException($"trying to fetch not existing filters, type {typeof(T)}"); if (_filters[TypeRefWrapper.wrapper].ContainsKey(groupID) == false) throw new ECSException( $"trying to fetch not existing filters, type {typeof(T)} group {groupID.ToName()}"); #endif return ref _filters[TypeRefWrapper.wrapper][groupID].GetFilter(filterId); } public bool TryGetFilterForGroup(int filterId, ExclusiveGroupStruct groupID, out FilterGroup groupFilter) where T : struct, IEntityComponent { groupFilter = default; if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == false) return false; if (fasterDictionary.TryGetValue(groupID, out var groupFilters) == false) return false; if (groupFilters.TryGetFilter(filterId, out groupFilter) == false) return false; return true; } public bool TryGetFiltersForGroup(ExclusiveGroupStruct groupID, out GroupFilters groupFilters) where T : struct, IEntityComponent { groupFilters = default; if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == false) return false; return fasterDictionary.TryGetValue(groupID, out groupFilters); } public void ClearFilter(int filterID, ExclusiveGroupStruct exclusiveGroupStruct) { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == true) { DBC.ECS.Check.Require(fasterDictionary.ContainsKey(exclusiveGroupStruct) , $"trying to clear filter not present in group {exclusiveGroupStruct}"); fasterDictionary[exclusiveGroupStruct].ClearFilter(filterID); } } public void ClearFilters(int filterID) { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == true) { foreach (var filtersPerGroup in fasterDictionary) filtersPerGroup.Value.ClearFilter(filterID); } } public void DisposeFilters(ExclusiveGroupStruct exclusiveGroupStruct) { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == true) { fasterDictionary[exclusiveGroupStruct].DisposeFilters(); fasterDictionary.Remove(exclusiveGroupStruct); } } public void DisposeFilters() { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == true) { foreach (var filtersPerGroup in fasterDictionary) filtersPerGroup.Value.DisposeFilters(); } _filters.Remove(TypeRefWrapper.wrapper); } public void DisposeFilterForGroup(int resetFilterID, ExclusiveGroupStruct @group) { if (_filters.TryGetValue(TypeRefWrapper.wrapper, out var fasterDictionary) == true) { fasterDictionary[group].DisposeFilter(resetFilterID); } } public bool TryRemoveEntityFromFilter(int filtersID, EGID egid) where T : struct, IEntityComponent { if (TryGetFilterForGroup(filtersID, egid.groupID, out var filter)) { return filter.TryRemove(egid.entityID); } return false; } public void RemoveEntityFromFilter(int filtersID, EGID egid) where T : struct, IEntityComponent { ref var filter = ref GetFilterForGroup(filtersID, egid.groupID); filter.Remove(egid.entityID); } public bool AddEntityToFilter(int filtersID, EGID egid, N mapper) where N : IEGIDMapper { ref var filter = ref CreateOrGetFilterForGroup(filtersID, egid.groupID, new RefWrapperType(mapper.entityType)); return filter.Add(egid.entityID, mapper); } readonly FasterDictionary> _filters; } public Filters GetFilters() { return new Filters(_filters); } FasterDictionary> _filters => _enginesRoot._groupFilters; } }