mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
add CombinedSubject
This commit is contained in:
parent
39ca9d7d74
commit
80ac00e887
228
src/Builtin/Subjects.cs
Normal file
228
src/Builtin/Subjects.cs
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class SingleSubject<TComponent, TPool> : EcsSubject where TPool : IEcsPoolImplementation<TComponent>, new()
|
||||||
|
{
|
||||||
|
public readonly TPool pool;
|
||||||
|
public SingleSubject(Builder b)
|
||||||
|
{
|
||||||
|
pool = b.Include<TComponent, TPool>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class CombinedSubject<S0, S1> : EcsSubject
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
{
|
||||||
|
public readonly S0 s0;
|
||||||
|
public readonly S1 s1;
|
||||||
|
public CombinedSubject(Builder b)
|
||||||
|
{
|
||||||
|
s0 = b.Combine<S0>();
|
||||||
|
s1 = b.Combine<S1>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CombinedSubject<S0, S1, S2> : EcsSubject
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
{
|
||||||
|
public readonly S0 s0;
|
||||||
|
public readonly S1 s1;
|
||||||
|
public readonly S2 s2;
|
||||||
|
public CombinedSubject(Builder b)
|
||||||
|
{
|
||||||
|
s0 = b.Combine<S0>();
|
||||||
|
s1 = b.Combine<S1>();
|
||||||
|
s2 = b.Combine<S2>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CombinedSubject<S0, S1, S2, S3> : EcsSubject
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
{
|
||||||
|
public readonly S0 s0;
|
||||||
|
public readonly S1 s1;
|
||||||
|
public readonly S2 s2;
|
||||||
|
public readonly S3 s3;
|
||||||
|
public CombinedSubject(Builder b)
|
||||||
|
{
|
||||||
|
s0 = b.Combine<S0>();
|
||||||
|
s1 = b.Combine<S1>();
|
||||||
|
s2 = b.Combine<S2>();
|
||||||
|
s3 = b.Combine<S3>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CombinedSubject<S0, S1, S2, S3, S4> : EcsSubject
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
{
|
||||||
|
public readonly S0 s0;
|
||||||
|
public readonly S1 s1;
|
||||||
|
public readonly S2 s2;
|
||||||
|
public readonly S3 s3;
|
||||||
|
public readonly S4 s4;
|
||||||
|
public CombinedSubject(Builder b)
|
||||||
|
{
|
||||||
|
s0 = b.Combine<S0>();
|
||||||
|
s1 = b.Combine<S1>();
|
||||||
|
s2 = b.Combine<S2>();
|
||||||
|
s3 = b.Combine<S3>();
|
||||||
|
s4 = b.Combine<S4>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CombinedSubject<S0, S1, S2, S3, S4, S5> : EcsSubject
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
where S5 : EcsSubject
|
||||||
|
{
|
||||||
|
public readonly S0 s0;
|
||||||
|
public readonly S1 s1;
|
||||||
|
public readonly S2 s2;
|
||||||
|
public readonly S3 s3;
|
||||||
|
public readonly S4 s4;
|
||||||
|
public readonly S5 s5;
|
||||||
|
public CombinedSubject(Builder b)
|
||||||
|
{
|
||||||
|
s0 = b.Combine<S0>();
|
||||||
|
s1 = b.Combine<S1>();
|
||||||
|
s2 = b.Combine<S2>();
|
||||||
|
s3 = b.Combine<S3>();
|
||||||
|
s4 = b.Combine<S4>();
|
||||||
|
s5 = b.Combine<S5>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CombinedSubjectExtensions
|
||||||
|
{
|
||||||
|
#region 2
|
||||||
|
public static EcsReadonlyGroup Where<S0, S1>(this EcsWorld self, out S0 s0, out S1 s1)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
{
|
||||||
|
return self.WhereFor(self.Entities, out s0, out s1);
|
||||||
|
}
|
||||||
|
public static EcsReadonlyGroup WhereFor<S0, S1>(this EcsWorld self, EcsReadonlyGroup sourceGroup, out S0 s0, out S1 s1)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
{
|
||||||
|
var combined = self.GetSubject<CombinedSubject<S0, S1>>();
|
||||||
|
s0 = combined.s0;
|
||||||
|
s1 = combined.s1;
|
||||||
|
return self.WhereFor<CombinedSubject<S0, S1>>(sourceGroup);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 3
|
||||||
|
public static EcsReadonlyGroup Where<S0, S1, S2>(this EcsWorld self, out S0 s0, out S1 s1, out S2 s2)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
{
|
||||||
|
return self.WhereFor(self.Entities, out s0, out s1, out s2);
|
||||||
|
}
|
||||||
|
public static EcsReadonlyGroup WhereFor<S0, S1, S2>(this EcsWorld self, EcsReadonlyGroup sourceGroup, out S0 s0, out S1 s1, out S2 s2)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
{
|
||||||
|
var combined = self.GetSubject<CombinedSubject<S0, S1, S2>>();
|
||||||
|
s0 = combined.s0;
|
||||||
|
s1 = combined.s1;
|
||||||
|
s2 = combined.s2;
|
||||||
|
return self.WhereFor<CombinedSubject<S0, S1, S2>>(sourceGroup);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 4
|
||||||
|
public static EcsReadonlyGroup Where<S0, S1, S2, S3>(this EcsWorld self, out S0 s0, out S1 s1, out S2 s2, out S3 s3)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
{
|
||||||
|
return self.WhereFor(self.Entities, out s0, out s1, out s2, out s3);
|
||||||
|
}
|
||||||
|
public static EcsReadonlyGroup WhereFor<S0, S1, S2, S3>(this EcsWorld self, EcsReadonlyGroup sourceGroup, out S0 s0, out S1 s1, out S2 s2, out S3 s3)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
{
|
||||||
|
var combined = self.GetSubject<CombinedSubject<S0, S1, S2, S3>>();
|
||||||
|
s0 = combined.s0;
|
||||||
|
s1 = combined.s1;
|
||||||
|
s2 = combined.s2;
|
||||||
|
s3 = combined.s3;
|
||||||
|
return self.WhereFor<CombinedSubject<S0, S1, S2, S3>>(sourceGroup);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 5
|
||||||
|
public static EcsReadonlyGroup Where<S0, S1, S2, S3, S4>(this EcsWorld self, out S0 s0, out S1 s1, out S2 s2, out S3 s3, out S4 s4)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
{
|
||||||
|
return self.WhereFor(self.Entities, out s0, out s1, out s2, out s3, out s4);
|
||||||
|
}
|
||||||
|
public static EcsReadonlyGroup WhereFor<S0, S1, S2, S3, S4>(this EcsWorld self, EcsReadonlyGroup sourceGroup, out S0 s0, out S1 s1, out S2 s2, out S3 s3, out S4 s4)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
{
|
||||||
|
var combined = self.GetSubject<CombinedSubject<S0, S1, S2, S3, S4>>();
|
||||||
|
s0 = combined.s0;
|
||||||
|
s1 = combined.s1;
|
||||||
|
s2 = combined.s2;
|
||||||
|
s3 = combined.s3;
|
||||||
|
s4 = combined.s4;
|
||||||
|
return self.WhereFor<CombinedSubject<S0, S1, S2, S3, S4>>(sourceGroup);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region 6
|
||||||
|
public static EcsReadonlyGroup Where<S0, S1, S2, S3, S4, S5>(this EcsWorld self, out S0 s0, out S1 s1, out S2 s2, out S3 s3, out S4 s4, out S5 s5)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
where S5 : EcsSubject
|
||||||
|
{
|
||||||
|
return self.WhereFor(self.Entities, out s0, out s1, out s2, out s3, out s4, out s5);
|
||||||
|
}
|
||||||
|
public static EcsReadonlyGroup WhereFor<S0, S1, S2, S3, S4, S5>(this EcsWorld self, EcsReadonlyGroup sourceGroup, out S0 s0, out S1 s1, out S2 s2, out S3 s3, out S4 s4, out S5 s5)
|
||||||
|
where S0 : EcsSubject
|
||||||
|
where S1 : EcsSubject
|
||||||
|
where S2 : EcsSubject
|
||||||
|
where S3 : EcsSubject
|
||||||
|
where S4 : EcsSubject
|
||||||
|
where S5 : EcsSubject
|
||||||
|
{
|
||||||
|
var combined = self.GetSubject<CombinedSubject<S0, S1, S2, S3, S4, S5>>();
|
||||||
|
s0 = combined.s0;
|
||||||
|
s1 = combined.s1;
|
||||||
|
s2 = combined.s2;
|
||||||
|
s3 = combined.s3;
|
||||||
|
s4 = combined.s4;
|
||||||
|
s5 = combined.s5;
|
||||||
|
return self.WhereFor<CombinedSubject<S0, S1, S2, S3, S4, S5>>(sourceGroup);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@ -35,22 +35,22 @@ namespace DCFApixels.DragonECS
|
|||||||
public sealed class Builder : EcsSubjectBuilderBase
|
public sealed class Builder : EcsSubjectBuilderBase
|
||||||
{
|
{
|
||||||
private EcsWorld _world;
|
private EcsWorld _world;
|
||||||
private List<int> _inc;
|
private HashSet<int> _inc;
|
||||||
private List<int> _exc;
|
private HashSet<int> _exc;
|
||||||
|
|
||||||
public EcsWorld World => _world;
|
public EcsWorld World => _world;
|
||||||
|
|
||||||
private Builder(EcsWorld world)
|
private Builder(EcsWorld world)
|
||||||
{
|
{
|
||||||
_world = world;
|
_world = world;
|
||||||
_inc = new List<int>(8);
|
_inc = new HashSet<int>(8);
|
||||||
_exc = new List<int>(4);
|
_exc = new HashSet<int>(4);
|
||||||
}
|
}
|
||||||
internal static TSubject Build<TSubject>(EcsWorld world) where TSubject : EcsSubject
|
internal static TSubject Build<TSubject>(EcsWorld world) where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
Builder builder = new Builder(world);
|
Builder builder = new Builder(world);
|
||||||
Type queryType = typeof(TSubject);
|
Type subjectType = typeof(TSubject);
|
||||||
ConstructorInfo constructorInfo = queryType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Builder) }, null);
|
ConstructorInfo constructorInfo = subjectType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Builder) }, null);
|
||||||
EcsSubject newSubject;
|
EcsSubject newSubject;
|
||||||
if (constructorInfo != null)
|
if (constructorInfo != null)
|
||||||
{
|
{
|
||||||
@ -100,11 +100,24 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Combine
|
||||||
|
public TOtherSubject Combine<TOtherSubject>() where TOtherSubject : EcsSubject
|
||||||
|
{
|
||||||
|
var result = _world.GetSubject<TOtherSubject>();
|
||||||
|
_inc.UnionWith(result.mask._inc);
|
||||||
|
_exc.UnionWith(result.mask._exc);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
private void End(out EcsMask mask)
|
private void End(out EcsMask mask)
|
||||||
{
|
{
|
||||||
_inc.Sort();
|
var inc = _inc.ToArray();
|
||||||
_exc.Sort();
|
Array.Sort(inc);
|
||||||
mask = new EcsMask(_world.Archetype, _inc.ToArray(), _exc.ToArray());
|
var exc = _exc.ToArray();
|
||||||
|
Array.Sort(exc);
|
||||||
|
|
||||||
|
mask = new EcsMask(_world.Archetype, inc, exc);
|
||||||
_world = null;
|
_world = null;
|
||||||
_inc = null;
|
_inc = null;
|
||||||
_exc = null;
|
_exc = null;
|
||||||
@ -161,12 +174,25 @@ namespace DCFApixels.DragonECS
|
|||||||
_exc = exc;
|
_exc = exc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EcsMask Union(EcsMask a, EcsMask b)
|
||||||
|
{
|
||||||
|
if(a._worldType != b._worldType) ThrowHelper.ThrowArgumentDifferentWorldsException();
|
||||||
|
|
||||||
|
HashSet<int> incset = new HashSet<int>(a._inc);
|
||||||
|
HashSet<int> excset = new HashSet<int>(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);
|
public override string ToString() => CreateLogString(_worldType, _inc, _exc);
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Debug utils
|
#region Debug utils
|
||||||
private static string CreateLogString(Type worldType, int[] inc, int[] exc)
|
private static string CreateLogString(Type worldType, int[] inc, int[] exc)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if (DEBUG && !DISABLE_DEBUG)
|
||||||
int worldID = WorldMetaStorage.GetWorldID(worldType);
|
int worldID = WorldMetaStorage.GetWorldID(worldType);
|
||||||
string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldID, o), 1);
|
string converter(int o) => EcsDebugUtility.GetGenericTypeName(WorldMetaStorage.GetComponentType(worldID, o), 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))})";
|
||||||
@ -194,6 +220,14 @@ namespace DCFApixels.DragonECS
|
|||||||
public override string ToString() => CreateLogString(worldType, inc, exc);
|
public override string ToString() => CreateLogString(worldType, inc, exc);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ThrowHelper
|
||||||
|
internal static class ThrowHelper
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||||
|
public static void ThrowArgumentDifferentWorldsException() => throw new ArgumentException("The groups belong to different worlds.");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user