/// <summary> /// Updates all filters for changed component mask. /// </summary> /// <param name="entity">Entity.</param> /// <param name="component">Component.</param> /// <param name="oldMask">Old component state.</param> /// <param name="newMask">New component state.</param> void UpdateFilters(int entity, int component, EcsComponentMask oldMask, EcsComponentMask newMask) { for (var i = _filters.Count - 1; i >= 0; i--) { var filter = _filters[i]; var isNewMaskCompatible = newMask.IsCompatible(filter.IncludeMask, filter.ExcludeMask); if (oldMask.IsCompatible(filter.IncludeMask, filter.ExcludeMask)) { if (!isNewMaskCompatible) { #if DEBUG && !ECS_PERF_TEST if (filter.Entities.IndexOf(entity) == -1) { throw new Exception( string.Format("Something wrong - entity {0} should be in filter {1}, but not exits.", entity, filter)); } #endif filter.Entities.Remove(entity); filter.RaiseOnEntityRemoved(entity, component); } } else { if (isNewMaskCompatible) { filter.Entities.Add(entity); filter.RaiseOnEntityAdded(entity, component); } } } }
/// <summary> /// Gets filter for specific components. /// </summary> /// <param name="include">Component mask for required components.</param> /// <param name="include">Component mask for denied components.</param> internal EcsFilter GetFilter(EcsComponentMask include, EcsComponentMask exclude) { #if DEBUG && !ECS_PERF_TEST if (include == null) { throw new ArgumentNullException("include"); } if (exclude == null) { throw new ArgumentNullException("exclude"); } #endif var i = _filters.Count - 1; for (; i >= 0; i--) { if (this._filters[i].IncludeMask.IsEquals(include) && _filters[i].ExcludeMask.IsEquals(exclude)) { break; } } if (i == -1) { i = _filters.Count; _filters.Add(new EcsFilter(include, exclude)); } return(_filters[i]); }
/// <summary> /// Gets filter for specific components. /// </summary> public EcsFilter GetFilter <A, B> () where A : class, IEcsComponent where B : class, IEcsComponent { var mask = new EcsComponentMask(); mask.SetBit(GetComponentIndex <A> (), true); mask.SetBit(GetComponentIndex <B> (), true); return(GetFilter(mask)); }
/// <summary> /// Gets filter for specific components. /// </summary> /// <param name="include">Component mask for required components.</param> /// <param name="include">Component mask for denied components.</param> /// <param name="shouldBeFilled">New filter should be filled with compatible entities on creation.</param> internal EcsFilter GetFilter(EcsComponentMask include, EcsComponentMask exclude, bool shouldBeFilled) { #if DEBUG if (include == null) { throw new ArgumentNullException("include"); } if (exclude == null) { throw new ArgumentNullException("exclude"); } #endif var i = _filtersCount - 1; for (; i >= 0; i--) { if (this._filters[i].IncludeMask.IsEquals(include) && _filters[i].ExcludeMask.IsEquals(exclude)) { break; } } if (i == -1) { i = _filtersCount; var filter = new EcsFilter(include, exclude); if (shouldBeFilled) { FillFilter(filter); } if (_filtersCount == _filters.Length) { Array.Resize(ref _filters, _filtersCount << 1); } _filters[_filtersCount++] = filter; for (var bit = 0; bit < include.BitsCount; bit++) { var typeId = include.Bits[bit]; if (typeId >= _componentPoolFilters.Length) { Array.Resize(ref _componentPoolFilters, EcsHelpers.GetPowerOfTwoSize(typeId + 1)); } var filterList = _componentPoolFilters[typeId]; if (filterList == null) { filterList = new EcsFilterList(); _componentPoolFilters[typeId] = filterList; } if (filterList.Count == filterList.Filters.Length) { Array.Resize(ref filterList.Filters, filterList.Count << 1); } filterList.Filters[filterList.Count++] = filter; } } return(_filters[i]); }
/// <summary> /// Gets filter for specific components. /// </summary> /// <param name="mask">Component selection.</param> public EcsFilter GetFilter(EcsComponentMask mask) { var i = _filters.Count - 1; for (; i >= 0; i--) { if (_filters[i].Mask.IsEquals(mask)) { break; } } if (i == -1) { i = _filters.Count; _filters.Add(new EcsFilter(mask)); } return(_filters[i]); }
/// <summary> /// Updates all filters for changed component mask. /// </summary> /// <param name="entity">Entity.</param> /// <param name="oldMask">Old component state.</param> /// <param name="newMask">New component state.</param> void UpdateFilters(int entity, EcsComponentMask oldMask, EcsComponentMask newMask) { for (var i = _filters.Count - 1; i >= 0; i--) { var isNewMaskCompatible = newMask.IsCompatible(_filters[i].Mask); if (oldMask.IsCompatible(_filters[i].Mask)) { if (!isNewMaskCompatible) { _filters[i].Entities.Remove(entity); } } else { if (isNewMaskCompatible) { _filters[i].Entities.Add(entity); } } } }
void UpdateFilters(int entity, object component, EcsComponentMask oldMask, EcsComponentMask newMask) { for (var i = _filtersCount - 1; i >= 0; i--) { var filter = _filters[i]; var isNewMaskCompatible = newMask.IsCompatible(filter); if (oldMask.IsCompatible(filter)) { if (!isNewMaskCompatible) { #if DEBUG var ii = filter.EntitiesCount - 1; for (; ii >= 0; ii--) { if (filter.Entities[ii] == entity) { break; } } if (ii == -1) { throw new Exception( string.Format("Something wrong - entity {0} should be in filter {1}, but not exits.", entity, filter)); } #endif filter.RaiseOnRemoveEvent(entity, component); } } else { if (isNewMaskCompatible) { filter.RaiseOnAddEvent(entity, component); } } } }
internal EcsFilter(EcsComponentMask include, EcsComponentMask exclude) { IncludeMask = include; ExcludeMask = exclude; }
/// <summary> /// Processes delayed updates. Use carefully! /// </summary> public void ProcessDelayedUpdates() { var iMax = _delayedUpdates.Count; for (var i = 0; i < iMax; i++) { var op = _delayedUpdates[i]; var entityData = _entities[op.Entity]; var oldMask = entityData.Mask; switch (op.Type) { case DelayedUpdate.Op.RemoveEntity: if (!entityData.IsReserved) { var componentId = 0; var empty = new EcsComponentMask(); while (!entityData.Mask.IsEmpty()) { if (entityData.Mask.GetBit(componentId)) { entityData.Mask.SetBit(componentId, false); DetachComponent(op.Entity, entityData, componentId); } componentId++; } UpdateFilters(op.Entity, oldMask, empty); entityData.IsReserved = true; _reservedEntityIds.Add(op.Entity); } break; case DelayedUpdate.Op.AddComponent: if (!entityData.Mask.GetBit(op.Component)) { entityData.Mask.SetBit(op.Component, true); OnComponentAttach(op.Entity, entityData.Components[op.Component]); UpdateFilters(op.Entity, oldMask, entityData.Mask); } break; case DelayedUpdate.Op.RemoveComponent: if (entityData.Mask.GetBit(op.Component)) { entityData.Mask.SetBit(op.Component, false); DetachComponent(op.Entity, entityData, op.Component); UpdateFilters(op.Entity, oldMask, entityData.Mask); } break; } } if (iMax > 0) { if (_delayedUpdates.Count == iMax) { _delayedUpdates.Clear(); } else { _delayedUpdates.RemoveRange(0, iMax); ProcessDelayedUpdates(); } } }
/// <summary> /// Gets filter for specific component. /// </summary> public EcsFilter GetFilter <A> () where A : class, IEcsComponent { var mask = new EcsComponentMask(GetComponentIndex <A> ()); return(GetFilter(mask)); }
public EcsFilter(EcsComponentMask mask) { Mask = mask; }