299 lines
10 KiB
C#
299 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
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);
|
|
}
|
|
}
|