From 796a555cbc98b419516a6a5cefa5ef50738a6ddb Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 14 Feb 2023 03:26:34 +0800 Subject: [PATCH] Update WIP, add Mask/Filter --- ...FitersProcessor.cs => FiltersProcessor.cs} | 2 +- ...essor.cs.meta => FiltersProcessor.cs.meta} | 0 src/Builtin/InjectProcessor.cs | 4 +- src/Code.cs | 16 - src/Code.cs.meta | 11 - src/EcsFilter.cs | 565 +++++++++++++----- src/EcsGroup.cs | 34 +- src/EcsSession.cs | 12 +- src/EcsWorld.cs | 152 ++--- src/React/EcsProcessorsGMessenger.cs | 6 +- src/React/EcsProcessorsMessenger.cs | 4 +- src/React/EcsProcessorsRunner.cs | 6 +- 12 files changed, 533 insertions(+), 279 deletions(-) rename src/Builtin/{FitersProcessor.cs => FiltersProcessor.cs} (75%) rename src/Builtin/{FitersProcessor.cs.meta => FiltersProcessor.cs.meta} (100%) delete mode 100644 src/Code.cs delete mode 100644 src/Code.cs.meta diff --git a/src/Builtin/FitersProcessor.cs b/src/Builtin/FiltersProcessor.cs similarity index 75% rename from src/Builtin/FitersProcessor.cs rename to src/Builtin/FiltersProcessor.cs index ba9a271..1cb620a 100644 --- a/src/Builtin/FitersProcessor.cs +++ b/src/Builtin/FiltersProcessor.cs @@ -1,6 +1,6 @@ namespace DCFApixels.DragonECS { - public class FitersProcessor : IEcsGReceive<_OnComponentAdded>, IEcsGReceive<_OnComponentRemoved> + public class FiltersProcessor : IEcsGReceive<_OnComponentAdded>, IEcsGReceive<_OnComponentRemoved> { void IEcsGReceive<_OnComponentAdded>.Do(EcsSession session, in _OnComponentAdded message, in T obj) { diff --git a/src/Builtin/FitersProcessor.cs.meta b/src/Builtin/FiltersProcessor.cs.meta similarity index 100% rename from src/Builtin/FitersProcessor.cs.meta rename to src/Builtin/FiltersProcessor.cs.meta diff --git a/src/Builtin/InjectProcessor.cs b/src/Builtin/InjectProcessor.cs index 59ab2cb..24b3a0f 100644 --- a/src/Builtin/InjectProcessor.cs +++ b/src/Builtin/InjectProcessor.cs @@ -18,7 +18,9 @@ namespace DCFApixels.DragonECS void IDo<_PreInit>.Do(EcsSession session) { _OnInject m = new _OnInject(_injectedData); - session.GetMessenger<_OnInject>().Send(in m); + var messenger = session.GetMessenger<_OnInject>(); + messenger.Send(in m); + messenger.Destroy(); } } diff --git a/src/Code.cs b/src/Code.cs deleted file mode 100644 index 997d461..0000000 --- a/src/Code.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace DCFApixels.DragonECS -{ - public static class Code - { - public static readonly NilType nil = default; - } - - - public readonly struct NilType { } -} diff --git a/src/Code.cs.meta b/src/Code.cs.meta deleted file mode 100644 index 489187d..0000000 --- a/src/Code.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fdfd15ed79cb9e04caf3fb0275900c72 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/EcsFilter.cs b/src/EcsFilter.cs index f54df61..5be21c1 100644 --- a/src/EcsFilter.cs +++ b/src/EcsFilter.cs @@ -1,174 +1,465 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; namespace DCFApixels.DragonECS { + #region Incs/Excs base + public interface ICondition + { + public int[] GetComponentsIDs(); + } + #endregion + + #region Incs + public interface IInc : ICondition { } + + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Inc : IInc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + #endregion + + #region Excs + public interface IExc : ICondition { } + + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + public struct Exc : IExc + { + public int[] GetComponentsIDs() + { + return new int[] + { + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID, + ComponentType.uniqueID + }; + } + } + #endregion + + #region Masks + public abstract class Mask + { + protected internal static int _typeIDIncrement = 0; + + internal abstract int[] Include { get; } + internal abstract int[] Exclude { get; } + + public abstract int ID { get; } + + public int IncCount + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Include.Length; + } + public int ExcCount + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => Exclude.Length; + } + } + public sealed class Mask : Mask + where TInc : struct, IInc + { + internal static readonly int[] include = new TInc().GetComponentsIDs(); + internal static readonly int[] exclude = Array.Empty(); + public static readonly int id = _typeIDIncrement++; + private static Mask _instance = new Mask(); + + private Mask() { } + + public static Mask Instance + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _instance; + } + public override int ID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => id; + } + internal override int[] Include + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => include; + } + internal override int[] Exclude + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => exclude; + } + } + public sealed class Mask : Mask + where TInc : struct, IInc + where TExc : struct, IExc + { + internal static readonly int[] include = new TInc().GetComponentsIDs(); + internal static readonly int[] exclude = new TExc().GetComponentsIDs(); + public static readonly int id = _typeIDIncrement++; + private static Mask _instance = new Mask(); + + private Mask() { } + + public static Mask Instance + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _instance; + } + public override int ID + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => id; + } + internal override int[] Include + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => include; + } + internal override int[] Exclude + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => exclude; + } + } + #endregion + + #region Filter public interface IEcsFilter { public EcsWorld World { get; } + public Mask Mask { get; } + public IEcsReadonlyGroup Entities { get; } public int EntitiesCount { get; } } - - public abstract class MaskBase - { - protected internal static int _typeIDIncrement = 0; - } - public abstract class IncBase { } - public abstract class ExcBase { } - - public sealed class Inc : IncBase { } - public sealed class Inc : IncBase { } - public sealed class Exc : ExcBase { } - public sealed class Exc : ExcBase { } - public sealed class Mask : MaskBase - where TInc : IncBase - { - public static readonly int typeID = _typeIDIncrement++; - } - public sealed class Mask : MaskBase - where TInc : IncBase - where TExc : ExcBase - { - public static readonly int typeID = _typeIDIncrement++; - } - - public class EcsFilter : IEcsFilter { private readonly EcsWorld _source; - private readonly EcsWorld.Mask _mask; - private readonly SparseSet _entities; - - private DelayedOp[] _delayedOps; - private int _delayedOpsCount; - - private int _lockCount; + private readonly EcsGroup _entities; + private readonly Mask _mask; #region Properties - public EcsWorld World => _source; - public EcsWorld.Mask Mask => _mask; - public int EntitiesCount => _entities.Count; + public EcsWorld World + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _source; + } + public Mask Mask + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _mask; + } + public IEcsReadonlyGroup Entities + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _entities; + } + public int EntitiesCount + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _entities.Count; + } #endregion #region Constrcutors - internal EcsFilter(EcsWorld source, EcsWorld.Mask mask, int capasity) + internal EcsFilter(EcsWorld source, Mask mask, int capasity) { _source = source; _mask = mask; - _entities = new SparseSet(capasity); - _delayedOps = new DelayedOp[512]; - _lockCount = 0; + _entities = new EcsGroup(source, capasity); } #endregion - - internal void Change(int entityID, bool isAdd) - { - if (isAdd) - Add(entityID); - else - Remove(entityID); - } + #region EntityChangedReact + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Add(int entityID) { - if (_lockCount > 0) - AddDelayedOp(entityID, true); _entities.Add(entityID); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Remove(int entityID) { - if (_lockCount > 0) - AddDelayedOp(entityID, false); _entities.Remove(entityID); } - - private void AddDelayedOp(int entityID, bool isAdd) - { - if(_delayedOpsCount >= _delayedOps.Length) - { - Array.Resize(ref _delayedOps, _delayedOps.Length << 1); - } - ref DelayedOp delayedOd = ref _delayedOps[_delayedOpsCount]; - delayedOd.Entity = entityID; - delayedOd.Added = isAdd; - } - - #region GetEnumerator - private void Unlock() - { -#if DEBUG - if (_lockCount <= 0) - { - throw new Exception($"Invalid lock-unlock balance for {nameof(EcsFilter)}."); - } -#endif - if (--_lockCount <= 0) - { - for (int i = 0; i < _delayedOpsCount; i++) - { - ref DelayedOp op = ref _delayedOps[i]; - if (op.Added) - { - Add(op.Entity); - } - else - { - Remove(op.Entity); - } - } - } - } - public Enumerator GetEnumerator() - { - _lockCount++; - return new Enumerator(this); - } - #endregion - - #region Utils - public ref struct Enumerator - { - private readonly EcsFilter _source; - private readonly SparseSet _entities; - private int _index; - - public Enumerator(EcsFilter filter) - { - _source = filter; - _entities = filter._entities; - _index = -1; - } - - public int Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _entities[_index]; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() - { - return ++_index < _entities.Count; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() - { - _source.Unlock(); - } - } - - private struct DelayedOp - { - public bool Added; - public int Entity; - } #endregion } + #endregion } diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index c0d049b..51f48e7 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -3,7 +3,19 @@ using System.Runtime.CompilerServices; namespace DCFApixels.DragonECS { - public class EcsGroup + public interface IEcsReadonlyGroup + { + public EcsWorld World { get; } + public int Count { get; } + public EcsGroup.Enumerator GetEnumerator(); + } + public interface IEcsGroup : IEcsReadonlyGroup + { + public void Add(int entityID); + public void Remove(int entityID); + } + + public class EcsGroup : IEcsGroup { private EcsWorld _source; private SparseSet _entities; @@ -15,7 +27,7 @@ namespace DCFApixels.DragonECS #region Properties public EcsWorld World => _source; - public int EntitiesCount => _entities.Count; + public int Count => _entities.Count; #endregion #region Constrcutors @@ -55,6 +67,24 @@ namespace DCFApixels.DragonECS } #endregion + #region AddGroup/RemoveGroup + public void AddGroup(IEcsReadonlyGroup group) + { + foreach (var item in group) + { + _entities.TryAdd(item.id); + } + } + + public void RemoveGroup(IEcsReadonlyGroup group) + { + foreach (var item in group) + { + _entities.TryRemove(item.id); + } + } + #endregion + #region GetEnumerator private void Unlock() { diff --git a/src/EcsSession.cs b/src/EcsSession.cs index 7388619..89f6d3f 100644 --- a/src/EcsSession.cs +++ b/src/EcsSession.cs @@ -44,11 +44,7 @@ namespace DCFApixels.DragonECS internal void OnRunnerDetroyed(EcsProcessorsRunner target) where TDoTag : IEcsDoTag { - Type type = typeof(TDoTag); - if (_runners.ContainsKey(type)) - { - _runners.Remove(type); - } + _runners.Remove(typeof(TDoTag)); } public EcsProcessorsMessenger GetMessenger() @@ -78,11 +74,7 @@ namespace DCFApixels.DragonECS internal void OnMessengerDetroyed(IEcsProcessorsMessenger target) where TMessege : IEcsMessage { - Type type = typeof(TMessege); - if (_messengers.ContainsKey(type)) - { - _messengers.Remove(type); - } + _messengers.Remove(typeof(TMessege)); } #endregion diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 3c5fe65..f6456d1 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -25,6 +25,9 @@ namespace DCFApixels.DragonECS private List[] _filtersByIncludedComponents; private List[] _filtersByExcludedComponents; + private EcsFilter[] _filters; + private SparseSet _maskIDToFilterID; + #region Properties public int ID => _id; public bool IsAlive => _id != DEAD_WORLD_ID; @@ -37,6 +40,24 @@ namespace DCFApixels.DragonECS _pools = new IEcsPool[512]; _entities = new SparseSet(512); _componentIDToPoolID = new SparseSet(512); + _maskIDToFilterID = new SparseSet(512); + _filters = new EcsFilter[512]; + } + #endregion + + #region Filters + public EcsFilter GetFilter(TMask mask) where TMask : Mask + { + if (_maskIDToFilterID.TryAdd(mask.ID, ref _filters)) + { + EcsFilter filter = new EcsFilter(this, mask, 512); + _filters[_maskIDToFilterID.IndexOf(mask.ID)] = filter; + return filter; + } + else + { + return _filters[_maskIDToFilterID.IndexOf(mask.ID)]; + } } #endregion @@ -86,19 +107,20 @@ namespace DCFApixels.DragonECS } #endregion + #region IsMaskCompatible/IsMaskCompatibleWithout [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool IsMaskCompatible(Mask filterMask, int entity) + public bool IsMaskCompatible(Mask mask, int entity) { - for (int i = 0, iMax = filterMask.includeCount; i < iMax; i++) + for (int i = 0, iMax = mask.IncCount; i < iMax; i++) { - if (!_pools[filterMask.include[i]].Has(entity)) + if (!_pools[_componentIDToPoolID[mask.Include[i]]].Has(entity)) { return false; } } - for (int i = 0, iMax = filterMask.excludeCount; i < iMax; i++) + for (int i = 0, iMax = mask.ExcCount; i < iMax; i++) { - if (_pools[filterMask.exclude[i]].Has(entity)) + if (_pools[_componentIDToPoolID[mask.Exclude[i]]].Has(entity)) { return false; } @@ -107,27 +129,29 @@ namespace DCFApixels.DragonECS } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool IsMaskCompatibleWithout(Mask filterMask, int entity, int componentId) + public bool IsMaskCompatibleWithout(Mask mask, int entity, int otherPoolID) { - for (int i = 0, iMax = filterMask.includeCount; i < iMax; i++) + for (int i = 0, iMax = mask.IncCount; i < iMax; i++) { - var typeId = filterMask.include[i]; - if (typeId == componentId || !_pools[typeId].Has(entity)) + int poolID = _componentIDToPoolID[mask.Include[i]]; + if (poolID == otherPoolID || !_pools[poolID].Has(entity)) { return false; } } - for (int i = 0, iMax = filterMask.excludeCount; i < iMax; i++) + for (int i = 0, iMax = mask.ExcCount; i < iMax; i++) { - var typeId = filterMask.exclude[i]; - if (typeId != componentId && _pools[typeId].Has(entity)) + int poolID = _componentIDToPoolID[mask.Exclude[i]]; + if (poolID != otherPoolID && _pools[poolID].Has(entity)) { return false; } } return true; } + #endregion + #region EntityChangedReact internal void OnEntityComponentAdded(int entityID, int changedPoolID) { var includeList = _filtersByIncludedComponents[changedPoolID]; @@ -155,96 +179,32 @@ namespace DCFApixels.DragonECS } } - - internal void OnEntityComponentRemoved(int entityID, int changedPool) + internal void OnEntityComponentRemoved(int entityID, int changedPoolID) { + var includeList = _filtersByIncludedComponents[changedPoolID]; + var excludeList = _filtersByExcludedComponents[changedPoolID]; - } - - - public class Mask - { - private readonly EcsWorld _world; - internal int[] include; - internal int[] exclude; - internal int includeCount; - internal int excludeCount; - -#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS - bool _built; -#endif - - internal Mask(EcsWorld world) + if (includeList != null) { - _world = world; - include = new int[8]; - exclude = new int[2]; - Reset(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void Reset() - { - includeCount = 0; - excludeCount = 0; -#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS - _built = false; -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Mask Inc() where T : struct - { - var poolId = _world.GetPool().ID; -#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS - if (_built) { throw new Exception("Cant change built mask."); } - if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); } - if (Array.IndexOf(exclude, poolId, 0, excludeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); } -#endif - if (includeCount == include.Length) { Array.Resize(ref include, includeCount << 1); } - include[includeCount++] = poolId; - return this; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Mask Exc() where T : struct - { - var poolId = _world.GetPool().ID; -#if DEBUG && !DCFAECS_NO_SANITIZE_CHECKS - if (_built) { throw new Exception("Cant change built mask."); } - if (Array.IndexOf(include, poolId, 0, includeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); } - if (Array.IndexOf(exclude, poolId, 0, excludeCount) != -1) { throw new Exception($"{typeof(T).Name} already in constraints list."); } -#endif - if (excludeCount == exclude.Length) { Array.Resize(ref exclude, excludeCount << 1); } - exclude[excludeCount++] = poolId; - return this; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsFilter End(int capacity = 512) - { -#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS - if (_built) { throw new Exception("Cant change built mask."); } - _built = true; -#endif - Array.Sort(include, 0, includeCount); - Array.Sort(exclude, 0, excludeCount); - - var (filter, isNew) = _world.GetFilterInternal(this, capacity); - if (!isNew) { Recycle(); } - return filter; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - void Recycle() - { - Reset(); - if (_world._masksCount == _world._masks.Length) + foreach (var filter in includeList) { - Array.Resize(ref _world._masks, _world._masksCount << 1); + if (IsMaskCompatible(filter.Mask, entityID)) + { + filter.Remove(entityID); + } + } + } + if (excludeList != null) + { + foreach (var filter in excludeList) + { + if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID)) + { + filter.Add(entityID); + } } - _world._masks[_world._masksCount++] = this; } } + #endregion } } diff --git a/src/React/EcsProcessorsGMessenger.cs b/src/React/EcsProcessorsGMessenger.cs index b348313..0eb9c01 100644 --- a/src/React/EcsProcessorsGMessenger.cs +++ b/src/React/EcsProcessorsGMessenger.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace DCFApixels.DragonECS { - public class EcsProcessorsGMessenger : IEcsProcessorsMessenger + public class EcsProcessorsGMessenger : IEcsProcessorsMessenger, IDisposable where TMessage : IEcsMessage { private readonly EcsSession _source; @@ -35,5 +36,6 @@ namespace DCFApixels.DragonECS } public void Destroy() => _source.OnMessengerDetroyed(this); + void IDisposable.Dispose() => Destroy(); } } diff --git a/src/React/EcsProcessorsMessenger.cs b/src/React/EcsProcessorsMessenger.cs index 90fb5f9..53ebc38 100644 --- a/src/React/EcsProcessorsMessenger.cs +++ b/src/React/EcsProcessorsMessenger.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System; namespace DCFApixels.DragonECS { @@ -7,7 +8,7 @@ namespace DCFApixels.DragonECS public EcsSession Source { get; } } public interface IEcsProcessorsMessenger : IEcsProcessorsMessenger where TMessage : IEcsMessage { } - public class EcsProcessorsMessenger : IEcsProcessorsMessenger + public class EcsProcessorsMessenger : IEcsProcessorsMessenger, IDisposable where TMessage : IEcsMessage { private readonly EcsSession _source; @@ -40,5 +41,6 @@ namespace DCFApixels.DragonECS } public void Destroy() => _source.OnMessengerDetroyed(this); + void IDisposable.Dispose() => Destroy(); } } diff --git a/src/React/EcsProcessorsRunner.cs b/src/React/EcsProcessorsRunner.cs index 3165700..d5e9c1a 100644 --- a/src/React/EcsProcessorsRunner.cs +++ b/src/React/EcsProcessorsRunner.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; namespace DCFApixels.DragonECS { @@ -7,7 +8,7 @@ namespace DCFApixels.DragonECS public EcsSession Source { get; } public void Run(); } - public class EcsProcessorsRunner : IEcsProcessorsRunner + public class EcsProcessorsRunner : IEcsProcessorsRunner, IDisposable where TDoTag : IEcsDoTag { private readonly EcsSession _source; @@ -40,5 +41,6 @@ namespace DCFApixels.DragonECS } public void Destroy() => _source.OnRunnerDetroyed(this); + void IDisposable.Dispose() => Destroy(); } }