diff --git a/src/Builtin/Subjects.cs b/src/Builtin/Subjects.cs index 03b6d25..9c221c1 100644 --- a/src/Builtin/Subjects.cs +++ b/src/Builtin/Subjects.cs @@ -16,8 +16,8 @@ public readonly S1 s1; public CombinedSubject(Builder b) { - s0 = b.Combine(); - s1 = b.Combine(); + s0 = b.CombineInclude(); + s1 = b.CombineInclude(); } } @@ -31,9 +31,9 @@ public readonly S2 s2; public CombinedSubject(Builder b) { - s0 = b.Combine(); - s1 = b.Combine(); - s2 = b.Combine(); + s0 = b.CombineInclude(); + s1 = b.CombineInclude(); + s2 = b.CombineInclude(); } } @@ -49,10 +49,10 @@ public readonly S3 s3; public CombinedSubject(Builder b) { - s0 = b.Combine(); - s1 = b.Combine(); - s2 = b.Combine(); - s3 = b.Combine(); + s0 = b.CombineInclude(); + s1 = b.CombineInclude(); + s2 = b.CombineInclude(); + s3 = b.CombineInclude(); } } @@ -70,11 +70,11 @@ public readonly S4 s4; public CombinedSubject(Builder b) { - s0 = b.Combine(); - s1 = b.Combine(); - s2 = b.Combine(); - s3 = b.Combine(); - s4 = b.Combine(); + s0 = b.CombineInclude(); + s1 = b.CombineInclude(); + s2 = b.CombineInclude(); + s3 = b.CombineInclude(); + s4 = b.CombineInclude(); } } @@ -94,12 +94,12 @@ public readonly S5 s5; public CombinedSubject(Builder b) { - s0 = b.Combine(); - s1 = b.Combine(); - s2 = b.Combine(); - s3 = b.Combine(); - s4 = b.Combine(); - s5 = b.Combine(); + s0 = b.CombineInclude(); + s1 = b.CombineInclude(); + s2 = b.CombineInclude(); + s3 = b.CombineInclude(); + s4 = b.CombineInclude(); + s5 = b.CombineInclude(); } } diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index 99fa224..60d1a02 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -71,8 +71,8 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Bake(List entities) => _source.Bake(entities); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Span ToSpan() => _source.ToSpan(); - public Span ToSpan(int start, int length) => _source.ToSpan(start, length); + public ReadOnlySpan ToSpan() => _source.ToSpan(); + public ReadOnlySpan ToSpan(int start, int length) => _source.ToSpan(start, length); [MethodImpl(MethodImplOptions.AggressiveInlining)] public int First() => _source.First(); @@ -163,7 +163,6 @@ namespace DCFApixels.DragonECS { return world.GetFreeGroup(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] internal EcsGroup(EcsWorld world, int denseCapacity = 64) { _source = world; @@ -282,13 +281,13 @@ namespace DCFApixels.DragonECS foreach (var e in this) entities.Add(e); } - public Span ToSpan() => new Span(_dense, 0, _count); - public Span ToSpan(int start, int length) + public ReadOnlySpan ToSpan() => new ReadOnlySpan(_dense, 0, _count); + public ReadOnlySpan ToSpan(int start, int length) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (start + length > _count) ThrowArgumentOutOfRangeException(); #endif - return new Span(_dense, start, length); + return new ReadOnlySpan(_dense, start, length); } #endregion @@ -323,9 +322,9 @@ namespace DCFApixels.DragonECS /// as Intersect sets [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AndWith(EcsReadonlyGroup group) => AndWith(group.GetGroupInternal()); + public void IntersectWith(EcsReadonlyGroup group) => IntersectWith(group.GetGroupInternal()); /// as Intersect sets - public void AndWith(EcsGroup group) + public void IntersectWith(EcsGroup group) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (World != group.World) ThrowArgumentDifferentWorldsException(); @@ -337,9 +336,9 @@ namespace DCFApixels.DragonECS /// as Symmetric Except sets [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void XorWith(EcsReadonlyGroup group) => XorWith(group.GetGroupInternal()); + public void SymmetricExceptWith(EcsReadonlyGroup group) => SymmetricExceptWith(group.GetGroupInternal()); /// as Symmetric Except sets - public void XorWith(EcsGroup group) + public void SymmetricExceptWith(EcsGroup group) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (_source != group.World) ThrowArgumentDifferentWorldsException(); @@ -390,7 +389,7 @@ namespace DCFApixels.DragonECS } /// as Intersect sets /// new group from pool - public static EcsGroup And(EcsGroup a, EcsGroup b) + public static EcsGroup Intersect(EcsGroup a, EcsGroup b) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (a._source != b._source) ThrowArgumentDifferentWorldsException(); @@ -404,7 +403,7 @@ namespace DCFApixels.DragonECS /// as Symmetric Except sets /// new group from pool - public static EcsGroup Xor(EcsGroup a, EcsGroup b) + public static EcsGroup SymmetricExcept(EcsGroup a, EcsGroup b) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS if (a._source != b._source) ThrowArgumentDifferentWorldsException(); diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index 6a7d91b..30a5a41 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -100,8 +100,8 @@ namespace DCFApixels.DragonECS } #endregion - #region Combine - public TOtherSubject Combine() where TOtherSubject : EcsSubject + #region Combine Include/Exclude/Optional + public TOtherSubject CombineInclude() where TOtherSubject : EcsSubject { var result = _world.GetSubject(); _inc.ExceptWith(result.mask._exc);//удаляю конфликтующие ограничения @@ -111,6 +111,20 @@ namespace DCFApixels.DragonECS _exc.UnionWith(result.mask._exc); return result; } + public TOtherSubject CombineExclude() where TOtherSubject : EcsSubject + { + var result = _world.GetSubject(); + _inc.ExceptWith(result.mask._exc);//удаляю конфликтующие ограничения + _exc.ExceptWith(result.mask._inc);//удаляю конфликтующие ограничения + + _inc.UnionWith(result.mask._inc); + _exc.UnionWith(result.mask._exc); + return result; + } + public TOtherSubject CombineOptional() where TOtherSubject : EcsSubject + { + return _world.GetSubject(); + } #endregion private void End(out EcsMask mask) @@ -120,7 +134,7 @@ namespace DCFApixels.DragonECS var exc = _exc.ToArray(); Array.Sort(exc); - mask = new EcsMask(_world.Archetype, inc, exc); + mask = new EcsMask(_world.Archetype, inc, exc, _inc.Overlaps(exc)); _world = null; _inc = null; _exc = null; @@ -170,24 +184,16 @@ namespace DCFApixels.DragonECS internal readonly Type _worldType; internal readonly int[] _inc; internal readonly int[] _exc; - public EcsMask(Type worldType, int[] inc, int[] exc) + internal readonly bool _isConflicting; + + public EcsMask(Type worldType, int[] inc, int[] exc, bool isConflicting) { _worldType = worldType; _inc = inc; _exc = exc; + _isConflicting = isConflicting; } - public static EcsMask Union(EcsMask a, EcsMask b) - { - if(a._worldType != b._worldType) ThrowHelper.ThrowArgumentDifferentWorldsException(); - - HashSet incset = new HashSet(a._inc); - HashSet excset = new HashSet(a._exc); - incset.UnionWith(b._inc); - excset.UnionWith(b._exc); - return new EcsMask(a._worldType, incset.ToArray(), excset.ToArray()); - } - #region Object public override string ToString() => CreateLogString(_worldType, _inc, _exc); #endregion diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index c01d4cd..adb0dfd 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -42,6 +42,8 @@ namespace DCFApixels.DragonECS private object[] _components; + private EcsGroup _emptyGroup; + #region Properties public abstract Type Archetype { get; } public int UniqueID => uniqueID; @@ -84,6 +86,7 @@ namespace DCFApixels.DragonECS _groups = new List>(); _allEntites = GetFreeGroup(); + _emptyGroup = GetFreeGroup(); _subjects = new EcsSubject[128]; _executors = new EcsQueryExecutor[128]; @@ -354,6 +357,7 @@ namespace DCFApixels.DragonECS group.Clear(); _groupsPool.Push(group); } + internal EcsGroup GetEmptyGroup() => _emptyGroup; #endregion #region Debug