functional recovery

This commit is contained in:
Mikhail 2023-11-22 19:05:00 +08:00
parent f9db91eeb2
commit 6411abf869

View File

@ -30,8 +30,8 @@ namespace DCFApixels.DragonECS
public sealed class Builder : EcsAspectBuilderBase public sealed class Builder : EcsAspectBuilderBase
{ {
private EcsWorld _world; private EcsWorld _world;
private Dictionary<int, int> _inc; private HashSet<int> _inc;
private Dictionary<int, int> _exc; private HashSet<int> _exc;
private List<Combined> _combined; private List<Combined> _combined;
public EcsWorld World => _world; public EcsWorld World => _world;
@ -40,8 +40,8 @@ namespace DCFApixels.DragonECS
{ {
_world = world; _world = world;
_combined = new List<Combined>(); _combined = new List<Combined>();
_inc = new Dictionary<int, int>(); _inc = new HashSet<int>();
_exc = new Dictionary<int, int>(); _exc = new HashSet<int>();
} }
internal static TAspect Build<TAspect>(EcsWorld world) where TAspect : EcsAspect internal static TAspect Build<TAspect>(EcsWorld world) where TAspect : EcsAspect
{ {
@ -82,24 +82,18 @@ namespace DCFApixels.DragonECS
private void IncludeImplicit(Type type) private void IncludeImplicit(Type type)
{ {
int id = _world.GetComponentID(type); int id = _world.GetComponentID(type);
//#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
// if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
//#endif #endif
var bit = EcsMaskBit.FromPoolID(id); _inc.Add(id);
if (!_inc.ContainsKey(bit.chankIndex))
_inc.Add(bit.chankIndex, 0);
_inc[bit.chankIndex] = _inc[bit.chankIndex] | bit.mask;
} }
private void ExcludeImplicit(Type type) private void ExcludeImplicit(Type type)
{ {
int id = _world.GetComponentID(type); int id = _world.GetComponentID(type);
//#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
// if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type); if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
//#endif #endif
var bit = EcsMaskBit.FromPoolID(id); _exc.Add(id);
if (!_exc.ContainsKey(bit.chankIndex))
_exc.Add(bit.chankIndex, 0);
_exc[bit.chankIndex] = _exc[bit.chankIndex] | bit.mask;
} }
#endregion #endregion
@ -119,26 +113,25 @@ namespace DCFApixels.DragonECS
private void End(out EcsMask mask) private void End(out EcsMask mask)
{ {
Dictionary<int, int> maskInc; HashSet<int> maskInc;
Dictionary<int, int> maskExc; HashSet<int> maskExc;
if (_combined.Count > 0) if (_combined.Count > 0)
{ {
throw new NotImplementedException(); maskInc = new HashSet<int>();
// maskInc = new Dictionary<int, int>(); maskExc = new HashSet<int>();
// maskExc = new Dictionary<int, int>(); _combined.Sort((a, b) => a.order - b.order);
// _combined.Sort((a, b) => a.order - b.order); foreach (var item in _combined)
// foreach (var item in _combined) {
// { EcsMask submask = item.aspect.mask;
// EcsMask submask = item.aspect.mask; maskInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения
// maskInc.ExceptWith(submask.excChunckMasks);//удаляю конфликтующие ограничения maskExc.ExceptWith(submask.inc);//удаляю конфликтующие ограничения
// maskExc.ExceptWith(submask.incChunckMasks);//удаляю конфликтующие ограничения maskInc.UnionWith(submask.inc);
// maskInc.UnionWith(submask.incChunckMasks); maskExc.UnionWith(submask.exc);
// maskExc.UnionWith(submask.excChunckMasks); }
// } maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения
// maskInc.ExceptWith(_exc);//удаляю конфликтующие ограничения maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения
// maskExc.ExceptWith(_inc);//удаляю конфликтующие ограничения maskInc.UnionWith(_inc);
// maskInc.UnionWith(_inc); maskExc.UnionWith(_exc);
// maskExc.UnionWith(_exc);
} }
else else
{ {
@ -146,10 +139,29 @@ namespace DCFApixels.DragonECS
maskExc = _exc; maskExc = _exc;
} }
mask = new EcsMask( Dictionary<int, int> r = new Dictionary<int, int>();
_world.id, foreach (var id in maskInc)
maskInc.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray(), {
maskExc.Select(o => new EcsMaskBit(o.Key, o.Value)).ToArray()); 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; _world = null;
_inc = null; _inc = null;
_exc = null; _exc = null;
@ -210,23 +222,27 @@ namespace DCFApixels.DragonECS
internal readonly int worldID; internal readonly int worldID;
internal readonly EcsMaskBit[] incChunckMasks; internal readonly EcsMaskBit[] incChunckMasks;
internal readonly EcsMaskBit[] excChunckMasks; internal readonly EcsMaskBit[] excChunckMasks;
internal readonly int[] inc;
internal readonly int[] exc;
public int WorldID => worldID; public int WorldID => worldID;
/// <summary>Including constraints</summary> /// <summary>Including constraints</summary>
public ReadOnlySpan<EcsMaskBit> Inc => incChunckMasks; public ReadOnlySpan<int> Inc => inc;
/// <summary>Excluding constraints</summary> /// <summary>Excluding constraints</summary>
public ReadOnlySpan<EcsMaskBit> Exc => excChunckMasks; public ReadOnlySpan<int> Exc => exc;
internal EcsMask(int worldID, EcsMaskBit[] inc, EcsMaskBit[] exc) internal EcsMask(int worldID, int[] inc, int[] exc, EcsMaskBit[] incChunckMasks, EcsMaskBit[] excChunckMasks)
{ {
#if DEBUG #if DEBUG
//CheckConstraints(inc, exc); CheckConstraints(inc, exc);
#endif #endif
this.inc = inc;
this.exc = exc;
this.worldID = worldID; this.worldID = worldID;
this.incChunckMasks = inc; this.incChunckMasks = incChunckMasks;
this.excChunckMasks = exc; this.excChunckMasks = excChunckMasks;
} }
#region Object #region Object
public override string ToString() => CreateLogString(worldID, incChunckMasks, excChunckMasks); public override string ToString() => CreateLogString(worldID, inc, exc);
#endregion #endregion
#region Debug utils #region Debug utils
@ -254,12 +270,11 @@ namespace DCFApixels.DragonECS
return false; return false;
} }
#endif #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) #if (DEBUG && !DISABLE_DEBUG)
//string converter(int o) => EcsDebugUtility.GetGenericTypeName(EcsWorld.GetWorld(worldID).AllPools[o].ComponentType, 1); 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.Select(converter))}) Exc({string.Join(", ", exc.Select(converter))})";
return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization
#else #else
return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization return $"Inc({string.Join(", ", inc)}) Exc({string.Join(", ", exc)})"; // Release optimization
#endif #endif
@ -268,19 +283,24 @@ namespace DCFApixels.DragonECS
{ {
public readonly EcsWorld world; public readonly EcsWorld world;
public readonly int worldID; public readonly int worldID;
public readonly EcsMaskBit[] included; public readonly EcsMaskBit[] includedChunkMasks;
public readonly EcsMaskBit[] excluded; public readonly EcsMaskBit[] excludedChunkMasks;
//public readonly Type[] includedTypes; public readonly int[] included;
//public readonly Type[] excludedTypes; public readonly int[] excluded;
public readonly Type[] includedTypes;
public readonly Type[] excludedTypes;
public DebuggerProxy(EcsMask mask) public DebuggerProxy(EcsMask mask)
{ {
world = EcsWorld.GetWorld(mask.worldID); world = EcsWorld.GetWorld(mask.worldID);
worldID = mask.worldID; worldID = mask.worldID;
included = mask.incChunckMasks; includedChunkMasks = mask.incChunckMasks;
excluded = mask.excChunckMasks; excludedChunkMasks = mask.excChunckMasks;
//Type converter(int o) => world.GetComponentType(o); included = mask.inc;
//includedTypes = included.Select(converter).ToArray(); excluded = mask.exc;
//excludedTypes = excluded.Select(converter).ToArray(); 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); public override string ToString() => CreateLogString(worldID, included, excluded);
} }
@ -361,14 +381,15 @@ namespace DCFApixels.DragonECS
while (_sourceGroup.MoveNext()) while (_sourceGroup.MoveNext())
{ {
int e = _sourceGroup.Current; int e = _sourceGroup.Current;
EcsMaskBit bit;
for (int i = 0, iMax = _inc.Length; i < iMax; i++) 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; if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) == 0) goto skip;
} }
for (int i = 0, iMax = _exc.Length; i < iMax; i++) 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; if ((_entitiesComponentMasks[e][bit.chankIndex] & bit.mask) != 0) goto skip;
} }
return true; return true;