mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
add EcsMask.Builder.Except
This commit is contained in:
parent
02fcd5f821
commit
f2238cd33a
@ -168,7 +168,7 @@ namespace DCFApixels.DragonECS
|
|||||||
return (TAspect)newAspect;
|
return (TAspect)newAspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Include/Exclude/Optional/Combine
|
#region Include/Exclude/Optional/Combine/Except
|
||||||
public TPool IncludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
public TPool IncludePool<TPool>() where TPool : IEcsPoolImplementation, new()
|
||||||
{
|
{
|
||||||
var pool = _world.GetPoolInstance<TPool>();
|
var pool = _world.GetPoolInstance<TPool>();
|
||||||
@ -199,6 +199,12 @@ namespace DCFApixels.DragonECS
|
|||||||
_maskBuilder.Combine(result.Mask);
|
_maskBuilder.Combine(result.Mask);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
public TOtherAspect Except<TOtherAspect>(int order = 0) where TOtherAspect : EcsAspect
|
||||||
|
{
|
||||||
|
var result = _world.GetAspect<TOtherAspect>();
|
||||||
|
_maskBuilder.Except(result.Mask);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void Build(out EcsMask mask)
|
private void Build(out EcsMask mask)
|
||||||
@ -364,9 +370,14 @@ namespace DCFApixels.DragonECS
|
|||||||
_sortIncChunckBuffer = aspect._sortIncChunckBuffer;
|
_sortIncChunckBuffer = aspect._sortIncChunckBuffer;
|
||||||
_sortExcChunckBuffer = aspect._sortExcChunckBuffer;
|
_sortExcChunckBuffer = aspect._sortExcChunckBuffer;
|
||||||
|
|
||||||
//_entityComponentMaskBitShift = BitsUtility.GetHighBitNumber(aspect.World._entityComponentMaskLength);
|
|
||||||
_entityComponentMaskLengthBitShift = aspect.World._entityComponentMaskLengthBitShift;
|
_entityComponentMaskLengthBitShift = aspect.World._entityComponentMaskLengthBitShift;
|
||||||
|
|
||||||
|
if (aspect.Mask.IsBroken)
|
||||||
|
{
|
||||||
|
_span = span.Slice(0, 0).GetEnumerator();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#region Sort
|
#region Sort
|
||||||
UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
|
UnsafeArray<int> _sortIncBuffer = aspect._sortIncBuffer;
|
||||||
UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
|
UnsafeArray<int> _sortExcBuffer = aspect._sortExcBuffer;
|
||||||
@ -388,9 +399,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
|
for (int i = 0, ii = 0; ii < _sortIncChunckBuffer.Length; ii++)
|
||||||
{
|
{
|
||||||
EcsMaskChunck bas = _preSortedIncBuffer[i];
|
EcsMaskChunck chunkX = _preSortedIncBuffer[i];
|
||||||
int chankIndexX = bas.chankIndex;
|
int chankIndexX = chunkX.chankIndex;
|
||||||
int maskX = bas.mask;
|
int maskX = chunkX.mask;
|
||||||
|
|
||||||
for (int j = i + 1; j < _sortIncBuffer.Length; j++)
|
for (int j = i + 1; j < _sortIncBuffer.Length; j++)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,10 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
get { return inc.Length == 0 && exc.Length == 0; }
|
get { return inc.Length == 0 && exc.Length == 0; }
|
||||||
}
|
}
|
||||||
|
public bool IsBroken
|
||||||
|
{
|
||||||
|
get { return (inc.Length & exc.Length) == 1 && inc[0] == exc[0]; }
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
@ -51,11 +55,24 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return new Builder(world);
|
return new Builder(world);
|
||||||
}
|
}
|
||||||
internal EcsMask(int id, short worldID, int[] inc, int[] exc)
|
|
||||||
|
internal static EcsMask New(int id, short worldID, int[] inc, int[] exc)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CheckConstraints(inc, exc);
|
CheckConstraints(inc, exc);
|
||||||
#endif
|
#endif
|
||||||
|
return new EcsMask(id, worldID, inc, exc);
|
||||||
|
}
|
||||||
|
internal static EcsMask NewEmpty(int id, short worldID)
|
||||||
|
{
|
||||||
|
return new EcsMask(id, worldID, new int[0], new int[0]);
|
||||||
|
}
|
||||||
|
internal static EcsMask NewBroken(int id, short worldID)
|
||||||
|
{
|
||||||
|
return new EcsMask(id, worldID, new int[1] { 1 }, new int[1] { 1 });
|
||||||
|
}
|
||||||
|
private EcsMask(int id, short worldID, int[] inc, int[] exc)
|
||||||
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.inc = inc;
|
this.inc = inc;
|
||||||
this.exc = exc;
|
this.exc = exc;
|
||||||
@ -198,7 +215,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Debug utils
|
#region Debug utils
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private static HashSet<int> _dummyHashSet = new HashSet<int>();
|
private static HashSet<int> _dummyHashSet = new HashSet<int>();
|
||||||
private void CheckConstraints(int[] inc, int[] exc)
|
private static void CheckConstraints(int[] inc, int[] exc)
|
||||||
{
|
{
|
||||||
lock (_dummyHashSet)
|
lock (_dummyHashSet)
|
||||||
{
|
{
|
||||||
@ -209,7 +226,7 @@ namespace DCFApixels.DragonECS
|
|||||||
if (_dummyHashSet.Overlaps(exc)) { throw new EcsFrameworkException("Conflicting Include and Exclude constraints."); }
|
if (_dummyHashSet.Overlaps(exc)) { throw new EcsFrameworkException("Conflicting Include and Exclude constraints."); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private bool CheckRepeats(int[] array)
|
private static bool CheckRepeats(int[] array)
|
||||||
{
|
{
|
||||||
_dummyHashSet.Clear();
|
_dummyHashSet.Clear();
|
||||||
foreach (var item in array)
|
foreach (var item in array)
|
||||||
@ -235,6 +252,8 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
internal class DebuggerProxy
|
internal class DebuggerProxy
|
||||||
{
|
{
|
||||||
|
private EcsMask _source;
|
||||||
|
|
||||||
public readonly int ID;
|
public readonly int ID;
|
||||||
public readonly EcsWorld world;
|
public readonly EcsWorld world;
|
||||||
private readonly short _worldID;
|
private readonly short _worldID;
|
||||||
@ -245,8 +264,13 @@ namespace DCFApixels.DragonECS
|
|||||||
public readonly Type[] includedTypes;
|
public readonly Type[] includedTypes;
|
||||||
public readonly Type[] excludedTypes;
|
public readonly Type[] excludedTypes;
|
||||||
|
|
||||||
|
public bool IsEmpty { get { return _source.IsEmpty; } }
|
||||||
|
public bool IsBroken { get { return _source.IsBroken; } }
|
||||||
|
|
||||||
public DebuggerProxy(EcsMask mask)
|
public DebuggerProxy(EcsMask mask)
|
||||||
{
|
{
|
||||||
|
_source = mask;
|
||||||
|
|
||||||
ID = mask.id;
|
ID = mask.id;
|
||||||
world = EcsWorld.GetWorld(mask.worldID);
|
world = EcsWorld.GetWorld(mask.worldID);
|
||||||
_worldID = mask.worldID;
|
_worldID = mask.worldID;
|
||||||
@ -308,16 +332,26 @@ namespace DCFApixels.DragonECS
|
|||||||
private readonly Dictionary<Key, EcsMask> _masks;
|
private readonly Dictionary<Key, EcsMask> _masks;
|
||||||
private readonly Dictionary<OpMaskKey, EcsMask> _opMasks;
|
private readonly Dictionary<OpMaskKey, EcsMask> _opMasks;
|
||||||
|
|
||||||
|
public readonly EcsMask EmptyMask;
|
||||||
|
public readonly EcsMask BrokenMask;
|
||||||
|
|
||||||
#region Constructor/Destructor
|
#region Constructor/Destructor
|
||||||
public WorldMaskComponent(EcsWorld world, Dictionary<Key, EcsMask> masks, Dictionary<OpMaskKey, EcsMask> opMasks)
|
public WorldMaskComponent(EcsWorld world, Dictionary<Key, EcsMask> masks, Dictionary<OpMaskKey, EcsMask> opMasks, EcsMask emptyMask, EcsMask brokenMask)
|
||||||
{
|
{
|
||||||
_world = world;
|
_world = world;
|
||||||
_masks = masks;
|
_masks = masks;
|
||||||
_opMasks = opMasks;
|
_opMasks = opMasks;
|
||||||
|
EmptyMask = emptyMask;
|
||||||
|
BrokenMask = brokenMask;
|
||||||
}
|
}
|
||||||
public void Init(ref WorldMaskComponent component, EcsWorld world)
|
public void Init(ref WorldMaskComponent component, EcsWorld world)
|
||||||
{
|
{
|
||||||
component = new WorldMaskComponent(world, new Dictionary<Key, EcsMask>(256), new Dictionary<OpMaskKey, EcsMask>(256));
|
var masks = new Dictionary<Key, EcsMask>(256);
|
||||||
|
EcsMask emptyMask = NewEmpty(0, world.id);
|
||||||
|
EcsMask brokenMask = NewBroken(1, world.id);
|
||||||
|
masks.Add(new Key(emptyMask.inc, emptyMask.exc), emptyMask);
|
||||||
|
masks.Add(new Key(brokenMask.inc, brokenMask.exc), brokenMask);
|
||||||
|
component = new WorldMaskComponent(world, masks, new Dictionary<OpMaskKey, EcsMask>(256), emptyMask, brokenMask);
|
||||||
}
|
}
|
||||||
public void OnDestroy(ref WorldMaskComponent component, EcsWorld world)
|
public void OnDestroy(ref WorldMaskComponent component, EcsWorld world)
|
||||||
{
|
{
|
||||||
@ -336,7 +370,7 @@ namespace DCFApixels.DragonECS
|
|||||||
var builder = New(a.World);
|
var builder = New(a.World);
|
||||||
if (a.IsConflictWith(b))
|
if (a.IsConflictWith(b))
|
||||||
{
|
{
|
||||||
return a.World.GetAspect<EmptyAspect>().Mask;
|
return a.World.Get<WorldMaskComponent>().BrokenMask;
|
||||||
}
|
}
|
||||||
ExceptMaskConstraint(builder, a.inc, b.inc, true);
|
ExceptMaskConstraint(builder, a.inc, b.inc, true);
|
||||||
ExceptMaskConstraint(builder, a.exc, b.exc, false);
|
ExceptMaskConstraint(builder, a.exc, b.exc, false);
|
||||||
@ -376,7 +410,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
||||||
{
|
{
|
||||||
result = new EcsMask(_masks.Count, _world.id, maskKey.inc, maskKey.exc);
|
result = EcsMask.New(_masks.Count, _world.id, maskKey.inc, maskKey.exc);
|
||||||
_masks.Add(maskKey, result);
|
_masks.Add(maskKey, result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -447,7 +481,8 @@ namespace DCFApixels.DragonECS
|
|||||||
private readonly EcsWorld _world;
|
private readonly EcsWorld _world;
|
||||||
private readonly HashSet<int> _inc = new HashSet<int>();
|
private readonly HashSet<int> _inc = new HashSet<int>();
|
||||||
private readonly HashSet<int> _exc = new HashSet<int>();
|
private readonly HashSet<int> _exc = new HashSet<int>();
|
||||||
private readonly List<Combined> _combined = new List<Combined>();
|
private readonly List<Combined> _combineds = new List<Combined>();
|
||||||
|
private readonly List<Excepted> _excepteds = new List<Excepted>();
|
||||||
|
|
||||||
#region Constrcutors
|
#region Constrcutors
|
||||||
internal Builder(EcsWorld world)
|
internal Builder(EcsWorld world)
|
||||||
@ -493,7 +528,13 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public Builder Combine(EcsMask mask, int order = 0)
|
public Builder Combine(EcsMask mask, int order = 0)
|
||||||
{
|
{
|
||||||
_combined.Add(new Combined(mask, order));
|
_combineds.Add(new Combined(mask, order));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder Except(EcsMask mask, int order = 0)
|
||||||
|
{
|
||||||
|
_excepteds.Add(new Excepted(mask, order));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -503,12 +544,12 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
HashSet<int> combinedInc;
|
HashSet<int> combinedInc;
|
||||||
HashSet<int> combinedExc;
|
HashSet<int> combinedExc;
|
||||||
if (_combined.Count > 0)
|
if (_combineds.Count > 0)
|
||||||
{
|
{
|
||||||
combinedInc = new HashSet<int>();
|
combinedInc = new HashSet<int>();
|
||||||
combinedExc = new HashSet<int>();
|
combinedExc = new HashSet<int>();
|
||||||
_combined.Sort((a, b) => a.order - b.order);
|
_combineds.Sort((a, b) => a.order - b.order);
|
||||||
foreach (var item in _combined)
|
foreach (var item in _combineds)
|
||||||
{
|
{
|
||||||
EcsMask submask = item.mask;
|
EcsMask submask = item.mask;
|
||||||
combinedInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения
|
combinedInc.ExceptWith(submask.exc);//удаляю конфликтующие ограничения
|
||||||
@ -526,15 +567,28 @@ namespace DCFApixels.DragonECS
|
|||||||
combinedInc = _inc;
|
combinedInc = _inc;
|
||||||
combinedExc = _exc;
|
combinedExc = _exc;
|
||||||
}
|
}
|
||||||
|
if (_excepteds.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var item in _excepteds)
|
||||||
|
{
|
||||||
|
if(combinedInc.Overlaps(item.mask.exc) || combinedExc.Overlaps(item.mask.inc))
|
||||||
|
{
|
||||||
|
_combineds.Clear();
|
||||||
|
_excepteds.Clear();
|
||||||
|
return _world.Get<WorldMaskComponent>().BrokenMask;
|
||||||
|
}
|
||||||
|
combinedInc.ExceptWith(item.mask.inc);
|
||||||
|
combinedExc.ExceptWith(item.mask.exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var inc = combinedInc.ToArray();
|
var inc = combinedInc.ToArray();
|
||||||
Array.Sort(inc);
|
Array.Sort(inc);
|
||||||
_inc.Clear();
|
|
||||||
var exc = combinedExc.ToArray();
|
var exc = combinedExc.ToArray();
|
||||||
Array.Sort(exc);
|
Array.Sort(exc);
|
||||||
_exc.Clear();
|
|
||||||
|
|
||||||
_combined.Clear();
|
_combineds.Clear();
|
||||||
|
_excepteds.Clear();
|
||||||
|
|
||||||
return _world.Get<WorldMaskComponent>().GetMask(new Key(inc, exc));
|
return _world.Get<WorldMaskComponent>().GetMask(new Key(inc, exc));
|
||||||
}
|
}
|
||||||
@ -551,6 +605,16 @@ namespace DCFApixels.DragonECS
|
|||||||
this.order = order;
|
this.order = order;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private readonly struct Excepted
|
||||||
|
{
|
||||||
|
public readonly EcsMask mask;
|
||||||
|
public readonly int order;
|
||||||
|
public Excepted(EcsMask mask, int order)
|
||||||
|
{
|
||||||
|
this.mask = mask;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user