From 6411abf86961b6b304ae44a164b1ea562fe3505b Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Wed, 22 Nov 2023 19:05:00 +0800 Subject: [PATCH] functional recovery --- src/EcsAspect.cs | 145 +++++++++++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 27394a6..cb3d621 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -30,8 +30,8 @@ namespace DCFApixels.DragonECS public sealed class Builder : EcsAspectBuilderBase { private EcsWorld _world; - private Dictionary _inc; - private Dictionary _exc; + private HashSet _inc; + private HashSet _exc; private List _combined; public EcsWorld World => _world; @@ -40,8 +40,8 @@ namespace DCFApixels.DragonECS { _world = world; _combined = new List(); - _inc = new Dictionary(); - _exc = new Dictionary(); + _inc = new HashSet(); + _exc = new HashSet(); } internal static TAspect Build(EcsWorld world) where TAspect : EcsAspect { @@ -82,24 +82,18 @@ namespace DCFApixels.DragonECS private void IncludeImplicit(Type type) { int id = _world.GetComponentID(type); -//#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS -// if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); -//#endif - var bit = EcsMaskBit.FromPoolID(id); - if (!_inc.ContainsKey(bit.chankIndex)) - _inc.Add(bit.chankIndex, 0); - _inc[bit.chankIndex] = _inc[bit.chankIndex] | bit.mask; +#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS + if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); +#endif + _inc.Add(id); } private void ExcludeImplicit(Type type) { int id = _world.GetComponentID(type); -//#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS -// if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); -//#endif - var bit = EcsMaskBit.FromPoolID(id); - if (!_exc.ContainsKey(bit.chankIndex)) - _exc.Add(bit.chankIndex, 0); - _exc[bit.chankIndex] = _exc[bit.chankIndex] | bit.mask; +#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS + if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); +#endif + _exc.Add(id); } #endregion @@ -119,26 +113,25 @@ namespace DCFApixels.DragonECS private void End(out EcsMask mask) { - Dictionary maskInc; - Dictionary maskExc; + HashSet maskInc; + HashSet maskExc; if (_combined.Count > 0) { - throw new NotImplementedException(); - // maskInc = new Dictionary(); - // maskExc = new Dictionary(); - // _combined.Sort((a, b) => a.order - b.order); - // foreach (var item in _combined) - // { - // EcsMask submask = item.aspect.mask; - // maskInc.ExceptWith(submask.excChunckMasks);//удаляю конфликтующие ограничения - // maskExc.ExceptWith(submask.incChunckMasks);//удаляю конфликтующие ограничения - // maskInc.UnionWith(submask.incChunckMasks); - // maskExc.UnionWith(submask.excChunckMasks); - // } - // maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения - // maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения - // maskInc.UnionWith(_inc); - // maskExc.UnionWith(_exc); + maskInc = new HashSet(); + maskExc = new HashSet(); + _combined.Sort((a, b) => a.order - b.order); + foreach (var item in _combined) + { + EcsMask submask = item.aspect.mask; + maskInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения + maskExc.ExceptWith(submask.inc);//удаляю конфликтующие ограничения + maskInc.UnionWith(submask.inc); + maskExc.UnionWith(submask.exc); + } + maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения + maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения + maskInc.UnionWith(_inc); + maskExc.UnionWith(_exc); } else { @@ -146,10 +139,29 @@ namespace DCFApixels.DragonECS maskExc = _exc; } - mask = new EcsMask( - _world.id, - maskInc.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray(), - maskExc.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray()); + Dictionary r = new Dictionary(); + foreach (var id in maskInc) + { + var bit = EcsMaskBit.FromPoolID(id); + if(!r.TryAdd(bit.chankIndex, bit.mask)) + r[bit.chankIndex] = r[bit.chankIndex] | bit.mask; + } + EcsMaskBit[] incMasks = r.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray(); + r.Clear(); + foreach (var id in maskExc) + { + var bit = EcsMaskBit.FromPoolID(id); + if (!r.TryAdd(bit.chankIndex, bit.mask)) + r[bit.chankIndex] = r[bit.chankIndex] | bit.mask; + } + EcsMaskBit[] excMasks = r.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray(); + + var inc = maskInc.ToArray(); + Array.Sort(inc); + var exc = maskExc.ToArray(); + Array.Sort(exc); + + mask = new EcsMask(_world.id, inc, exc, incMasks, excMasks); _world = null; _inc = null; _exc = null; @@ -210,23 +222,27 @@ namespace DCFApixels.DragonECS internal readonly int worldID; internal readonly EcsMaskBit[] incChunckMasks; internal readonly EcsMaskBit[] excChunckMasks; + internal readonly int[] inc; + internal readonly int[] exc; public int WorldID => worldID; /// Including constraints - public ReadOnlySpan Inc => incChunckMasks; + public ReadOnlySpan Inc => inc; /// Excluding constraints - public ReadOnlySpan Exc => excChunckMasks; - internal EcsMask(int worldID, EcsMaskBit[] inc, EcsMaskBit[] exc) + public ReadOnlySpan Exc => exc; + internal EcsMask(int worldID, int[] inc, int[] exc, EcsMaskBit[] incChunckMasks, EcsMaskBit[] excChunckMasks) { #if DEBUG - //CheckConstraints(inc, exc); + CheckConstraints(inc, exc); #endif + this.inc = inc; + this.exc = exc; this.worldID = worldID; - this.incChunckMasks = inc; - this.excChunckMasks = exc; + this.incChunckMasks = incChunckMasks; + this.excChunckMasks = excChunckMasks; } #region Object - public override string ToString() => CreateLogString(worldID, incChunckMasks, excChunckMasks); + public override string ToString() => CreateLogString(worldID, inc, exc); #endregion #region Debug utils @@ -254,12 +270,11 @@ namespace DCFApixels.DragonECS return false; } #endif - private static string CreateLogString(int worldID, EcsMaskBit[] inc, EcsMaskBit[] exc) + private static string CreateLogString(int worldID, int[] inc, int[] exc) { #if (DEBUG && !DISABLE_DEBUG) - //string converter(int o) => EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1); - //return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})"; - return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization + string converter(int o) => EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1); + return $"Inc({string.Join(", ", inc.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})"; #else return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization #endif @@ -268,19 +283,24 @@ namespace DCFApixels.DragonECS { public readonly EcsWorld world; public readonly int worldID; - public readonly EcsMaskBit[] included; - public readonly EcsMaskBit[] excluded; - //public readonly Type[] includedTypes; - //public readonly Type[] excludedTypes; + public readonly EcsMaskBit[] includedChunkMasks; + public readonly EcsMaskBit[] excludedChunkMasks; + public readonly int[] included; + public readonly int[] excluded; + public readonly Type[] includedTypes; + public readonly Type[] excludedTypes; + public DebuggerProxy(EcsMask mask) { world = EcsWorld.GetWorld(mask.worldID); worldID = mask.worldID; - included = mask.incChunckMasks; - excluded = mask.excChunckMasks; - //Type converter(int o) => world.GetComponentType(o); - //includedTypes = included.Select(converter).ToArray(); - //excludedTypes = excluded.Select(converter).ToArray(); + includedChunkMasks = mask.incChunckMasks; + excludedChunkMasks = mask.excChunckMasks; + included = mask.inc; + excluded = mask.exc; + Type converter(int o) => world.GetComponentType(o); + includedTypes = included.Select(converter).ToArray(); + excludedTypes = excluded.Select(converter).ToArray(); } public override string ToString() => CreateLogString(worldID, included, excluded); } @@ -361,14 +381,15 @@ namespace DCFApixels.DragonECS while (_sourceGroup.MoveNext()) { int e = _sourceGroup.Current; + EcsMaskBit bit; for (int i = 0, iMax = _inc.Length; i < iMax; i++) { - EcsMaskBit bit = _inc[i]; + bit = _inc[i]; if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) == 0) goto skip; } for (int i = 0, iMax = _exc.Length; i < iMax; i++) { - EcsMaskBit bit = _exc[i]; + bit = _exc[i]; if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != 0) goto skip; } return true;