266 lines
10 KiB
C#
266 lines
10 KiB
C#
namespace MfGames.Gallium;
|
|
|
|
/// <summary>
|
|
/// Extension methods for IEnumerable<Entity> that split the entity into two
|
|
/// sequences, one that contains the
|
|
/// various components and the other list which does not.
|
|
/// </summary>
|
|
public static class SplitEntityExtensions
|
|
{
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given generic components
|
|
/// and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <typeparam name="T1">
|
|
/// A component to require to be in included in the first
|
|
/// list.
|
|
/// </typeparam>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity<T1>(
|
|
this IEnumerable<Entity> entities,
|
|
Func<Entity, T1, bool>? test = null
|
|
)
|
|
{
|
|
test ??= (e, v1) => true;
|
|
|
|
return entities.SplitEntity(typeof(T1), (e, v1) => test(e, (T1)v1));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given generic components
|
|
/// and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <typeparam name="T1">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T2">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity<T1, T2>(
|
|
this IEnumerable<Entity> entities,
|
|
Func<Entity, T1, T2, bool>? test = null
|
|
)
|
|
{
|
|
test ??= (e, v1, v2) => true;
|
|
|
|
return entities.SplitEntity(typeof(T1), typeof(T2), (e, v1, v2) => test(e, (T1)v1, (T2)v2));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given generic components
|
|
/// and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <typeparam name="T1">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T2">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T3">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity<T1, T2, T3>(
|
|
this IEnumerable<Entity> entities,
|
|
Func<Entity, T1, T2, T3, bool>? test = null
|
|
)
|
|
{
|
|
test ??= (e, v1, v2, v3) => true;
|
|
|
|
return entities.SplitEntity(
|
|
typeof(T1),
|
|
typeof(T2),
|
|
typeof(T3),
|
|
(e, v1, v2, v3) => test(e, (T1)v1, (T2)v2, (T3)v3)
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given generic components
|
|
/// and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <typeparam name="T1">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T2">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T3">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <typeparam name="T4">
|
|
/// A component to require to be in included in the first list.
|
|
/// </typeparam>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity<T1, T2, T3, T4>(
|
|
this IEnumerable<Entity> entities,
|
|
Func<Entity, T1, T2, T3, T4, bool>? test = null
|
|
)
|
|
{
|
|
test ??= (e, v1, v2, v3, v4) => true;
|
|
|
|
return entities.SplitEntity(
|
|
typeof(T1),
|
|
typeof(T2),
|
|
typeof(T3),
|
|
typeof(T4),
|
|
(e, v1, v2, v3, v4) => test(e, (T1)v1, (T2)v2, (T3)v3, (T4)v4)
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given component types and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="t1">The type of a required component.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity(
|
|
this IEnumerable<Entity> entities,
|
|
Type t1,
|
|
Func<Entity, object, bool> test
|
|
)
|
|
{
|
|
return SplitEntity(entities, a => a.Has(t1) && test(a, a.Get<object>(t1)));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given component types and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="t1">The type of a required component.</param>
|
|
/// <param name="t2">The type of a required component.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity(
|
|
this IEnumerable<Entity> entities,
|
|
Type t1,
|
|
Type t2,
|
|
Func<Entity, object, object, bool> test
|
|
)
|
|
{
|
|
return SplitEntity(entities, a => a.HasAll(t1, t2));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given component types and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="t1">The type of a required component.</param>
|
|
/// <param name="t2">The type of a required component.</param>
|
|
/// <param name="t3">The type of a required component.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity(
|
|
this IEnumerable<Entity> entities,
|
|
Type t1,
|
|
Type t2,
|
|
Type t3,
|
|
Func<Entity, object, object, object, bool> test
|
|
)
|
|
{
|
|
return SplitEntity(entities, a => a.HasAll(t1, t2, t3));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Splits the enumeration of entities into two separate enumerations, ones that
|
|
/// have the given component types and those which do not.
|
|
/// </summary>
|
|
/// <param name="entities">The entities to split into two lists.</param>
|
|
/// <param name="t1">The type of a required component.</param>
|
|
/// <param name="t2">The type of a required component.</param>
|
|
/// <param name="t3">The type of a required component.</param>
|
|
/// <param name="t4">The type of a required component.</param>
|
|
/// <param name="test">
|
|
/// An additional test function to determine if the entity is
|
|
/// included in the has list. If null, then entities with all the components will
|
|
/// be included.
|
|
/// </param>
|
|
/// <returns>A pair of enumerations, ones with the components and ones without.</returns>
|
|
public static SplitEntityEnumerations SplitEntity(
|
|
this IEnumerable<Entity> entities,
|
|
Type t1,
|
|
Type t2,
|
|
Type t3,
|
|
Type t4,
|
|
Func<Entity, object, object, object, object, bool> test
|
|
)
|
|
{
|
|
return SplitEntity(
|
|
entities,
|
|
a =>
|
|
a.HasAll(t1, t2, t3, t4)
|
|
&& test(
|
|
a,
|
|
a.Get<object>(t1),
|
|
a.Get<object>(t2),
|
|
a.Get<object>(t3),
|
|
a.Get<object>(t4)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static SplitEntityEnumerations SplitEntity(
|
|
IEnumerable<Entity> entities,
|
|
Func<Entity, bool> keySelector
|
|
)
|
|
{
|
|
if (entities == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(entities));
|
|
}
|
|
|
|
IEnumerable<IGrouping<bool, Entity>> group = entities.GroupBy(keySelector, a => a).ToList();
|
|
|
|
IEnumerable<Entity>? has = group.Where(a => a.Key).SelectMany(a => a);
|
|
|
|
IEnumerable<Entity>? hasNot = group.Where(a => !a.Key).SelectMany(a => a);
|
|
|
|
return new SplitEntityEnumerations(has, hasNot);
|
|
}
|
|
}
|