refactor: cleaning up code to newer C# standards
This commit is contained in:
parent
6b9c9cf5e3
commit
e4c9e82b99
18 changed files with 1180 additions and 1153 deletions
|
@ -3,471 +3,470 @@ using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A low-overhead entity with identification.
|
||||||
|
/// </summary>
|
||||||
|
public record Entity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// A low-overhead entity with identification.
|
public virtual bool Equals(Entity? other)
|
||||||
/// </summary>
|
|
||||||
public record Entity
|
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
if (ReferenceEquals(null, other))
|
||||||
public virtual bool Equals(Entity? other)
|
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(null, other))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ReferenceEquals(this, other))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Id == other.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
return this.Id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ImmutableDictionary<Type, object> Components { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The internal ID to ensure the entities are unique. Since we are not
|
|
||||||
/// worried about serialization or using the identifiers from one call
|
|
||||||
/// to another, we can use a simple interlocked identifier instead of
|
|
||||||
/// a factory or provider method.
|
|
||||||
/// </summary>
|
|
||||||
private static int nextId;
|
|
||||||
|
|
||||||
public Entity()
|
|
||||||
: this(Interlocked.Increment(ref nextId))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private Entity(int id)
|
|
||||||
{
|
|
||||||
this.Id = id;
|
|
||||||
this.Components = ImmutableDictionary.Create<Type, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has a specific type of
|
|
||||||
/// component registered.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T1">The component type.</typeparam>
|
|
||||||
/// <returns>True if the type exists, otherwise false.</returns>
|
|
||||||
public bool Has<T1>()
|
|
||||||
{
|
|
||||||
return this.Has(typeof(T1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components of the given types
|
|
||||||
/// registered.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
|
||||||
/// <returns>
|
|
||||||
/// True if there are components of the given type exists, otherwise
|
|
||||||
/// false.
|
|
||||||
/// </returns>
|
|
||||||
public bool HasAll<T1, T2>()
|
|
||||||
{
|
|
||||||
return this.HasAll(typeof(T1), typeof(T2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components of the given types
|
|
||||||
/// registered.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
|
||||||
/// <typeparam name="T3">The third component type.</typeparam>
|
|
||||||
/// <returns>
|
|
||||||
/// True if there are components of the given type exists, otherwise
|
|
||||||
/// false.
|
|
||||||
/// </returns>
|
|
||||||
public bool HasAll<T1, T2, T3>()
|
|
||||||
{
|
|
||||||
return this.HasAll(typeof(T1), typeof(T2), typeof(T3));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components of the given types
|
|
||||||
/// registered.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
|
||||||
/// <typeparam name="T3">The third component type.</typeparam>
|
|
||||||
/// <typeparam name="T4">The third component type.</typeparam>
|
|
||||||
/// <returns>
|
|
||||||
/// True if there are components of the given type exists, otherwise
|
|
||||||
/// false.
|
|
||||||
/// </returns>
|
|
||||||
public bool HasAll<T1, T2, T3, T4>()
|
|
||||||
{
|
|
||||||
return this.HasAll(typeof(T1), typeof(T2), typeof(T3), typeof(T4));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has a specific type of
|
|
||||||
/// component registered.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The component type.</param>
|
|
||||||
/// <returns>True if the type exists, otherwise false.</returns>
|
|
||||||
public bool Has(Type type)
|
|
||||||
{
|
|
||||||
return this.Components.ContainsKey(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components for all the given
|
|
||||||
/// types.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="t1">The component type.</param>
|
|
||||||
/// <param name="t2">The component type.</param>
|
|
||||||
/// <returns>True if the type exists, otherwise false.</returns>
|
|
||||||
public bool HasAll(
|
|
||||||
Type t1,
|
|
||||||
Type t2)
|
|
||||||
{
|
|
||||||
return this.Has(t1) && this.Components.ContainsKey(t2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components for all the given
|
|
||||||
/// types.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="t1">The component type.</param>
|
|
||||||
/// <param name="t2">The component type.</param>
|
|
||||||
/// <param name="t3">The component type.</param>
|
|
||||||
/// <returns>True if the type exists, otherwise false.</returns>
|
|
||||||
public bool HasAll(
|
|
||||||
Type t1,
|
|
||||||
Type t2,
|
|
||||||
Type t3)
|
|
||||||
{
|
|
||||||
return this.HasAll(t1, t2) && this.Components.ContainsKey(t3);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value indicating whether the entity has components for all the given
|
|
||||||
/// types.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="t1">The component type.</param>
|
|
||||||
/// <param name="t2">The component type.</param>
|
|
||||||
/// <param name="t3">The component type.</param>
|
|
||||||
/// <param name="t4">The component type.</param>
|
|
||||||
/// <returns>True if the type exists, otherwise false.</returns>
|
|
||||||
public bool HasAll(
|
|
||||||
Type t1,
|
|
||||||
Type t2,
|
|
||||||
Type t3,
|
|
||||||
Type t4)
|
|
||||||
{
|
|
||||||
return this.HasAll(t1, t2, t3) && this.Components.ContainsKey(t4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves a registered component of the given type.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TType">The component type.</typeparam>
|
|
||||||
/// <returns>The registered object.</returns>
|
|
||||||
public TType Get<TType>()
|
|
||||||
{
|
|
||||||
return (TType)this.Components[typeof(TType)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves a registered component of the given type and casts it to
|
|
||||||
/// TType.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The component key.</param>
|
|
||||||
/// <typeparam name="TType">The component type.</typeparam>
|
|
||||||
/// <returns>The registered object.</returns>
|
|
||||||
public TType Get<TType>(Type type)
|
|
||||||
{
|
|
||||||
return (TType)this.Components[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of components registered in the entity.
|
|
||||||
/// </summary>
|
|
||||||
public int Count => this.Components.Count;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the given component type if inside the entity, otherwise the
|
|
||||||
/// default value.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TType">The component type.</typeparam>
|
|
||||||
/// <returns>The found component or default (typically null).</returns>
|
|
||||||
public TType? GetOptional<TType>()
|
|
||||||
{
|
|
||||||
return this.Has<TType>() ? this.Get<TType>() : default;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to get the value, if present. If not, this returns false
|
|
||||||
/// and the value is undefined. Otherwise, this method returns true
|
|
||||||
/// and the actual value inside that variable.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The value if contained in the entity.</param>
|
|
||||||
/// <typeparam name="T1">The component type.</typeparam>
|
|
||||||
/// <returns>True if found, otherwise false.</returns>
|
|
||||||
public bool TryGet<T1>(out T1 value)
|
|
||||||
{
|
|
||||||
if (this.Has<T1>())
|
|
||||||
{
|
|
||||||
value = this.Get<T1>();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = default!;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
if (ReferenceEquals(this, other))
|
||||||
/// Attempts to get the values, if present. If not, this returns false
|
|
||||||
/// and the value is undefined. Otherwise, this method returns true
|
|
||||||
/// and the actual value inside that variable.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value1">The value if contained in the entity.</param>
|
|
||||||
/// <param name="value2">The value if contained in the entity.</param>
|
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
|
||||||
/// <returns>True if found, otherwise false.</returns>
|
|
||||||
public bool TryGet<T1, T2>(
|
|
||||||
out T1 value1,
|
|
||||||
out T2 value2)
|
|
||||||
{
|
{
|
||||||
if (this.HasAll<T1, T2>())
|
return true;
|
||||||
{
|
|
||||||
value1 = this.Get<T1>();
|
|
||||||
value2 = this.Get<T2>();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value1 = default!;
|
|
||||||
value2 = default!;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return this.Id == other.Id;
|
||||||
/// Attempts to get the values, if present. If not, this returns false
|
}
|
||||||
/// and the value is undefined. Otherwise, this method returns true
|
|
||||||
/// and the actual value inside that variable.
|
/// <inheritdoc />
|
||||||
/// </summary>
|
public override int GetHashCode()
|
||||||
/// <param name="value1">The value if contained in the entity.</param>
|
{
|
||||||
/// <param name="value2">The value if contained in the entity.</param>
|
return this.Id;
|
||||||
/// <param name="value3">The value if contained in the entity.</param>
|
}
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
private ImmutableDictionary<Type, object> Components { get; set; }
|
||||||
/// <typeparam name="T3">The third component type.</typeparam>
|
|
||||||
/// <returns>True if found, otherwise false.</returns>
|
/// <summary>
|
||||||
public bool TryGet<T1, T2, T3>(
|
/// The internal ID to ensure the entities are unique. Since we are not
|
||||||
out T1 value1,
|
/// worried about serialization or using the identifiers from one call
|
||||||
out T2 value2,
|
/// to another, we can use a simple interlocked identifier instead of
|
||||||
out T3 value3)
|
/// a factory or provider method.
|
||||||
|
/// </summary>
|
||||||
|
private static int nextId;
|
||||||
|
|
||||||
|
public Entity()
|
||||||
|
: this(Interlocked.Increment(ref nextId))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entity(int id)
|
||||||
|
{
|
||||||
|
this.Id = id;
|
||||||
|
this.Components = ImmutableDictionary.Create<Type, object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has a specific type of
|
||||||
|
/// component registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T1">The component type.</typeparam>
|
||||||
|
/// <returns>True if the type exists, otherwise false.</returns>
|
||||||
|
public bool Has<T1>()
|
||||||
|
{
|
||||||
|
return this.Has(typeof(T1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components of the given types
|
||||||
|
/// registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// True if there are components of the given type exists, otherwise
|
||||||
|
/// false.
|
||||||
|
/// </returns>
|
||||||
|
public bool HasAll<T1, T2>()
|
||||||
|
{
|
||||||
|
return this.HasAll(typeof(T1), typeof(T2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components of the given types
|
||||||
|
/// registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
|
/// <typeparam name="T3">The third component type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// True if there are components of the given type exists, otherwise
|
||||||
|
/// false.
|
||||||
|
/// </returns>
|
||||||
|
public bool HasAll<T1, T2, T3>()
|
||||||
|
{
|
||||||
|
return this.HasAll(typeof(T1), typeof(T2), typeof(T3));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components of the given types
|
||||||
|
/// registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
|
/// <typeparam name="T3">The third component type.</typeparam>
|
||||||
|
/// <typeparam name="T4">The third component type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// True if there are components of the given type exists, otherwise
|
||||||
|
/// false.
|
||||||
|
/// </returns>
|
||||||
|
public bool HasAll<T1, T2, T3, T4>()
|
||||||
|
{
|
||||||
|
return this.HasAll(typeof(T1), typeof(T2), typeof(T3), typeof(T4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has a specific type of
|
||||||
|
/// component registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The component type.</param>
|
||||||
|
/// <returns>True if the type exists, otherwise false.</returns>
|
||||||
|
public bool Has(Type type)
|
||||||
|
{
|
||||||
|
return this.Components.ContainsKey(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components for all the given
|
||||||
|
/// types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t1">The component type.</param>
|
||||||
|
/// <param name="t2">The component type.</param>
|
||||||
|
/// <returns>True if the type exists, otherwise false.</returns>
|
||||||
|
public bool HasAll(
|
||||||
|
Type t1,
|
||||||
|
Type t2)
|
||||||
|
{
|
||||||
|
return this.Has(t1) && this.Components.ContainsKey(t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components for all the given
|
||||||
|
/// types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t1">The component type.</param>
|
||||||
|
/// <param name="t2">The component type.</param>
|
||||||
|
/// <param name="t3">The component type.</param>
|
||||||
|
/// <returns>True if the type exists, otherwise false.</returns>
|
||||||
|
public bool HasAll(
|
||||||
|
Type t1,
|
||||||
|
Type t2,
|
||||||
|
Type t3)
|
||||||
|
{
|
||||||
|
return this.HasAll(t1, t2) && this.Components.ContainsKey(t3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the entity has components for all the given
|
||||||
|
/// types.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="t1">The component type.</param>
|
||||||
|
/// <param name="t2">The component type.</param>
|
||||||
|
/// <param name="t3">The component type.</param>
|
||||||
|
/// <param name="t4">The component type.</param>
|
||||||
|
/// <returns>True if the type exists, otherwise false.</returns>
|
||||||
|
public bool HasAll(
|
||||||
|
Type t1,
|
||||||
|
Type t2,
|
||||||
|
Type t3,
|
||||||
|
Type t4)
|
||||||
|
{
|
||||||
|
return this.HasAll(t1, t2, t3) && this.Components.ContainsKey(t4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a registered component of the given type.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TType">The component type.</typeparam>
|
||||||
|
/// <returns>The registered object.</returns>
|
||||||
|
public TType Get<TType>()
|
||||||
|
{
|
||||||
|
return (TType)this.Components[typeof(TType)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a registered component of the given type and casts it to
|
||||||
|
/// TType.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The component key.</param>
|
||||||
|
/// <typeparam name="TType">The component type.</typeparam>
|
||||||
|
/// <returns>The registered object.</returns>
|
||||||
|
public TType Get<TType>(Type type)
|
||||||
|
{
|
||||||
|
return (TType)this.Components[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of components registered in the entity.
|
||||||
|
/// </summary>
|
||||||
|
public int Count => this.Components.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the given component type if inside the entity, otherwise the
|
||||||
|
/// default value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TType">The component type.</typeparam>
|
||||||
|
/// <returns>The found component or default (typically null).</returns>
|
||||||
|
public TType? GetOptional<TType>()
|
||||||
|
{
|
||||||
|
return this.Has<TType>() ? this.Get<TType>() : default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to get the value, if present. If not, this returns false
|
||||||
|
/// and the value is undefined. Otherwise, this method returns true
|
||||||
|
/// and the actual value inside that variable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value if contained in the entity.</param>
|
||||||
|
/// <typeparam name="T1">The component type.</typeparam>
|
||||||
|
/// <returns>True if found, otherwise false.</returns>
|
||||||
|
public bool TryGet<T1>(out T1 value)
|
||||||
|
{
|
||||||
|
if (this.Has<T1>())
|
||||||
{
|
{
|
||||||
if (this.HasAll<T1, T2, T3>())
|
value = this.Get<T1>();
|
||||||
{
|
|
||||||
value1 = this.Get<T1>();
|
|
||||||
value2 = this.Get<T2>();
|
|
||||||
value3 = this.Get<T3>();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
value1 = default!;
|
|
||||||
value2 = default!;
|
|
||||||
value3 = default!;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
value = default!;
|
||||||
/// Attempts to get the values, if present. If not, this returns false
|
|
||||||
/// and the value is undefined. Otherwise, this method returns true
|
return false;
|
||||||
/// and the actual value inside that variable.
|
}
|
||||||
/// </summary>
|
|
||||||
/// <param name="value1">The value if contained in the entity.</param>
|
/// <summary>
|
||||||
/// <param name="value2">The value if contained in the entity.</param>
|
/// Attempts to get the values, if present. If not, this returns false
|
||||||
/// <param name="value3">The value if contained in the entity.</param>
|
/// and the value is undefined. Otherwise, this method returns true
|
||||||
/// <param name="value4">The value if contained in the entity.</param>
|
/// and the actual value inside that variable.
|
||||||
/// <typeparam name="T1">The first component type.</typeparam>
|
/// </summary>
|
||||||
/// <typeparam name="T2">The second component type.</typeparam>
|
/// <param name="value1">The value if contained in the entity.</param>
|
||||||
/// <typeparam name="T3">The third component type.</typeparam>
|
/// <param name="value2">The value if contained in the entity.</param>
|
||||||
/// <typeparam name="T4">The fourth component type.</typeparam>
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
/// <returns>True if found, otherwise false.</returns>
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
public bool TryGet<T1, T2, T3, T4>(
|
/// <returns>True if found, otherwise false.</returns>
|
||||||
out T1 value1,
|
public bool TryGet<T1, T2>(
|
||||||
out T2 value2,
|
out T1 value1,
|
||||||
out T3 value3,
|
out T2 value2)
|
||||||
out T4 value4)
|
{
|
||||||
|
if (this.HasAll<T1, T2>())
|
||||||
{
|
{
|
||||||
if (this.HasAll<T1, T2, T3, T4>())
|
value1 = this.Get<T1>();
|
||||||
{
|
value2 = this.Get<T2>();
|
||||||
value1 = this.Get<T1>();
|
|
||||||
value2 = this.Get<T2>();
|
|
||||||
value3 = this.Get<T3>();
|
|
||||||
value4 = this.Get<T4>();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
value1 = default!;
|
|
||||||
value2 = default!;
|
|
||||||
value3 = default!;
|
|
||||||
value4 = default!;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
value1 = default!;
|
||||||
/// Sets the component in the entity, regardless if there was a
|
value2 = default!;
|
||||||
/// component already registered.
|
|
||||||
/// </summary>
|
return false;
|
||||||
/// <param name="component">The component to register.</param>
|
}
|
||||||
/// <typeparam name="T1">The component type.</typeparam>
|
|
||||||
/// <returns>The entity for chaining.</returns>
|
/// <summary>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// Attempts to get the values, if present. If not, this returns false
|
||||||
public Entity Set<T1>(T1 component)
|
/// and the value is undefined. Otherwise, this method returns true
|
||||||
|
/// and the actual value inside that variable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value1">The value if contained in the entity.</param>
|
||||||
|
/// <param name="value2">The value if contained in the entity.</param>
|
||||||
|
/// <param name="value3">The value if contained in the entity.</param>
|
||||||
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
|
/// <typeparam name="T3">The third component type.</typeparam>
|
||||||
|
/// <returns>True if found, otherwise false.</returns>
|
||||||
|
public bool TryGet<T1, T2, T3>(
|
||||||
|
out T1 value1,
|
||||||
|
out T2 value2,
|
||||||
|
out T3 value3)
|
||||||
|
{
|
||||||
|
if (this.HasAll<T1, T2, T3>())
|
||||||
{
|
{
|
||||||
if (component == null)
|
value1 = this.Get<T1>();
|
||||||
{
|
value2 = this.Get<T2>();
|
||||||
throw new ArgumentNullException(nameof(component));
|
value3 = this.Get<T3>();
|
||||||
}
|
|
||||||
|
|
||||||
if (this.Components.TryGetValue(typeof(T1), out object? value)
|
return true;
|
||||||
&& value is T1
|
|
||||||
&& value.Equals(component))
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this with
|
|
||||||
{
|
|
||||||
Components = this.Components.SetItem(typeof(T1), component),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
value1 = default!;
|
||||||
/// Adds a component to the entity.
|
value2 = default!;
|
||||||
/// </summary>
|
value3 = default!;
|
||||||
/// <param name="component">The component to register.</param>
|
|
||||||
/// <typeparam name="T1">The component type.</typeparam>
|
return false;
|
||||||
/// <returns>
|
}
|
||||||
/// The same entity if the component is already registered, otherwise a
|
|
||||||
/// cloned entity with the new component.
|
/// <summary>
|
||||||
/// </returns>
|
/// Attempts to get the values, if present. If not, this returns false
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// and the value is undefined. Otherwise, this method returns true
|
||||||
public Entity Add<T1>(T1 component)
|
/// and the actual value inside that variable.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value1">The value if contained in the entity.</param>
|
||||||
|
/// <param name="value2">The value if contained in the entity.</param>
|
||||||
|
/// <param name="value3">The value if contained in the entity.</param>
|
||||||
|
/// <param name="value4">The value if contained in the entity.</param>
|
||||||
|
/// <typeparam name="T1">The first component type.</typeparam>
|
||||||
|
/// <typeparam name="T2">The second component type.</typeparam>
|
||||||
|
/// <typeparam name="T3">The third component type.</typeparam>
|
||||||
|
/// <typeparam name="T4">The fourth component type.</typeparam>
|
||||||
|
/// <returns>True if found, otherwise false.</returns>
|
||||||
|
public bool TryGet<T1, T2, T3, T4>(
|
||||||
|
out T1 value1,
|
||||||
|
out T2 value2,
|
||||||
|
out T3 value3,
|
||||||
|
out T4 value4)
|
||||||
|
{
|
||||||
|
if (this.HasAll<T1, T2, T3, T4>())
|
||||||
{
|
{
|
||||||
if (component == null)
|
value1 = this.Get<T1>();
|
||||||
{
|
value2 = this.Get<T2>();
|
||||||
throw new ArgumentNullException(nameof(component));
|
value3 = this.Get<T3>();
|
||||||
}
|
value4 = this.Get<T4>();
|
||||||
|
|
||||||
if (this.Has<T1>())
|
return true;
|
||||||
{
|
|
||||||
throw new ArgumentException(
|
|
||||||
"An element with the same type ("
|
|
||||||
+ typeof(T1).FullName
|
|
||||||
+ ") already exists.",
|
|
||||||
nameof(component));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.Components.TryGetValue(typeof(T1), out object? value)
|
|
||||||
&& value is T1
|
|
||||||
&& value.Equals(component))
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this with
|
|
||||||
{
|
|
||||||
Components = this.Components.Add(typeof(T1), component),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
value1 = default!;
|
||||||
/// Removes a component to the entity.
|
value2 = default!;
|
||||||
/// </summary>
|
value3 = default!;
|
||||||
/// <typeparam name="TType">The component type.</typeparam>
|
value4 = default!;
|
||||||
/// <returns>
|
|
||||||
/// The same entity if the component is already removed, otherwise a
|
return false;
|
||||||
/// cloned entity without the new component.
|
}
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <summary>
|
||||||
public Entity Remove<TType>()
|
/// Sets the component in the entity, regardless if there was a
|
||||||
|
/// component already registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to register.</param>
|
||||||
|
/// <typeparam name="T1">The component type.</typeparam>
|
||||||
|
/// <returns>The entity for chaining.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
public Entity Set<T1>(T1 component)
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
{
|
{
|
||||||
return this.Remove(typeof(TType));
|
throw new ArgumentNullException(nameof(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
if (this.Components.TryGetValue(typeof(T1), out object? value)
|
||||||
/// Removes a component to the entity.
|
&& value is T1
|
||||||
/// </summary>
|
&& value.Equals(component))
|
||||||
/// <returns>
|
|
||||||
/// The same entity if the component is already removed, otherwise a
|
|
||||||
/// cloned entity without the new component.
|
|
||||||
/// </returns>
|
|
||||||
/// <param name="type">The component type to remove.</param>
|
|
||||||
public Entity Remove(Type type)
|
|
||||||
{
|
{
|
||||||
if (!this.Has(type))
|
return this;
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this with
|
|
||||||
{
|
|
||||||
Components = this.Components.Remove(type),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
return this with
|
||||||
/// Gets the identifier of the entity. This should be treated as an
|
|
||||||
/// opaque field.
|
|
||||||
/// </summary>
|
|
||||||
public int Id { get; private init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a copy of the entity, including copying the identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public Entity ExactCopy()
|
|
||||||
{
|
{
|
||||||
return this with { };
|
Components = this.Components.SetItem(typeof(T1), component)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a component to the entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component">The component to register.</param>
|
||||||
|
/// <typeparam name="T1">The component type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// The same entity if the component is already registered, otherwise a
|
||||||
|
/// cloned entity with the new component.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
public Entity Add<T1>(T1 component)
|
||||||
|
{
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
if (this.Has<T1>())
|
||||||
/// Creates a copy of the entity, including components, but with a new
|
|
||||||
/// identifier.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public Entity Copy()
|
|
||||||
{
|
{
|
||||||
return this with
|
throw new ArgumentException(
|
||||||
{
|
"An element with the same type ("
|
||||||
Id = Interlocked.Increment(ref nextId),
|
+ typeof(T1).FullName
|
||||||
};
|
+ ") already exists.",
|
||||||
|
nameof(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
if (this.Components.TryGetValue(typeof(T1), out object? value)
|
||||||
/// Retrieves a list of the component types currently registered in the
|
&& value is T1
|
||||||
/// Entity.
|
&& value.Equals(component))
|
||||||
/// </summary>
|
|
||||||
/// <returns>An enumerable of the various component keys.</returns>
|
|
||||||
public IEnumerable<Type> GetComponentTypes()
|
|
||||||
{
|
{
|
||||||
return this.Components.Keys;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this with
|
||||||
|
{
|
||||||
|
Components = this.Components.Add(typeof(T1), component)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a component to the entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TType">The component type.</typeparam>
|
||||||
|
/// <returns>
|
||||||
|
/// The same entity if the component is already removed, otherwise a
|
||||||
|
/// cloned entity without the new component.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
|
public Entity Remove<TType>()
|
||||||
|
{
|
||||||
|
return this.Remove(typeof(TType));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a component to the entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// The same entity if the component is already removed, otherwise a
|
||||||
|
/// cloned entity without the new component.
|
||||||
|
/// </returns>
|
||||||
|
/// <param name="type">The component type to remove.</param>
|
||||||
|
public Entity Remove(Type type)
|
||||||
|
{
|
||||||
|
if (!this.Has(type))
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this with
|
||||||
|
{
|
||||||
|
Components = this.Components.Remove(type)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the identifier of the entity. This should be treated as an
|
||||||
|
/// opaque field.
|
||||||
|
/// </summary>
|
||||||
|
public int Id { get; private init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a copy of the entity, including copying the identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Entity ExactCopy()
|
||||||
|
{
|
||||||
|
return this with { };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a copy of the entity, including components, but with a new
|
||||||
|
/// identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Entity Copy()
|
||||||
|
{
|
||||||
|
return this with
|
||||||
|
{
|
||||||
|
Id = Interlocked.Increment(ref nextId)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a list of the component types currently registered in the
|
||||||
|
/// Entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>An enumerable of the various component keys.</returns>
|
||||||
|
public IEnumerable<Type> GetComponentTypes()
|
||||||
|
{
|
||||||
|
return this.Components.Keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,27 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
public static class JoinEntityExtensions
|
||||||
{
|
{
|
||||||
public static class JoinEntityExtensions
|
/// <summary>
|
||||||
|
/// Merges two sets of entities using the identifier to determine which
|
||||||
|
/// entities are the same. The `merge` function takes both of the
|
||||||
|
/// entities with the Entity from the `input` first and the one from
|
||||||
|
/// `other` second. The returning entity is put into the collection. If
|
||||||
|
/// an entity from the input is not found in other, then it is just
|
||||||
|
/// passed on.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input">The enumerable of entities to merge to.</param>
|
||||||
|
/// <param name="other">The collection of entities to merge from.</param>
|
||||||
|
/// <param name="merge">The callback to merge the two.</param>
|
||||||
|
/// <returns>An sequence of entities, merged and unmerged.</returns>
|
||||||
|
public static IEnumerable<Entity> JoinEntity(
|
||||||
|
this IEnumerable<Entity> input,
|
||||||
|
ICollection<Entity> other,
|
||||||
|
Func<Entity, Entity, Entity> merge)
|
||||||
{
|
{
|
||||||
/// <summary>
|
return input.Join(other, a => a.Id, a => a.Id, merge);
|
||||||
/// Merges two sets of entities using the identifier to determine which
|
|
||||||
/// entities are the same. The `merge` function takes both of the
|
|
||||||
/// entities with the Entity from the `input` first and the one from
|
|
||||||
/// `other` second. The returning entity is put into the collection. If
|
|
||||||
/// an entity from the input is not found in other, then it is just
|
|
||||||
/// passed on.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input">The enumerable of entities to merge to.</param>
|
|
||||||
/// <param name="other">The collection of entities to merge from.</param>
|
|
||||||
/// <param name="merge">The callback to merge the two.</param>
|
|
||||||
/// <returns>An sequence of entities, merged and unmerged.</returns>
|
|
||||||
public static IEnumerable<Entity> JoinEntity(
|
|
||||||
this IEnumerable<Entity> input,
|
|
||||||
ICollection<Entity> other,
|
|
||||||
Func<Entity, Entity, Entity> merge)
|
|
||||||
{
|
|
||||||
return input.Join(other, a => a.Id, a => a.Id, merge);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ public static class SelectComponentExtensions
|
||||||
/// <param name="entities">The entities to process.</param>
|
/// <param name="entities">The entities to process.</param>
|
||||||
/// <typeparam name="T1">The component type being searched.</typeparam>
|
/// <typeparam name="T1">The component type being searched.</typeparam>
|
||||||
/// <returns>A sequence of T1.</returns>
|
/// <returns>A sequence of T1.</returns>
|
||||||
public static IEnumerable<T1> SelectComponent<T1>(this IEnumerable<Entity> entities)
|
public static IEnumerable<T1> SelectComponent<T1>(
|
||||||
|
this IEnumerable<Entity> entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,8 @@ public static class SelectComponentOrDefaultExtensions
|
||||||
/// <param name="entities">The entities to process.</param>
|
/// <param name="entities">The entities to process.</param>
|
||||||
/// <typeparam name="T1">The component type being searched.</typeparam>
|
/// <typeparam name="T1">The component type being searched.</typeparam>
|
||||||
/// <returns>A sequence of T1.</returns>
|
/// <returns>A sequence of T1.</returns>
|
||||||
public static IEnumerable<T1?> SelectComponentOrDefault<T1>(this IEnumerable<Entity> entities)
|
public static IEnumerable<T1?> SelectComponentOrDefault<T1>(
|
||||||
|
this IEnumerable<Entity> entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,260 +1,279 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
public static class SelectEntityExtensions
|
||||||
{
|
{
|
||||||
public static class SelectEntityExtensions
|
/// <summary>
|
||||||
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
|
/// the given components.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entities">The entities to parse.</param>
|
||||||
|
/// <param name="selectWithComponents">
|
||||||
|
/// The transformation function for the entity and selected components. If this
|
||||||
|
/// returns null, then the entity
|
||||||
|
/// will be filtered out.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="includeEntitiesWithoutComponents">
|
||||||
|
/// If true, then entities without all the components are included. Otherwise, they
|
||||||
|
/// are excluded.
|
||||||
|
/// </param>
|
||||||
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
|
public static IEnumerable<Entity> SelectEntity<T1>(
|
||||||
|
this IEnumerable<Entity> entities,
|
||||||
|
Func<Entity, T1, Entity?> selectWithComponents,
|
||||||
|
bool includeEntitiesWithoutComponents = true)
|
||||||
{
|
{
|
||||||
/// <summary>
|
return entities.SelectEntity(
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
selectWithComponents,
|
||||||
/// the given components.
|
includeEntitiesWithoutComponents ? a => a : a => null);
|
||||||
/// </summary>
|
}
|
||||||
/// <param name="entities">The entities to parse.</param>
|
|
||||||
/// <param name="selectWithComponents">
|
|
||||||
/// The transformation function for the entity and selected components. If this
|
|
||||||
/// returns null, then the entity
|
|
||||||
/// will be filtered out.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="includeEntitiesWithoutComponents">
|
|
||||||
/// If true, then entities without all the components are included. Otherwise, they
|
|
||||||
/// are excluded.
|
|
||||||
/// </param>
|
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
|
||||||
public static IEnumerable<Entity> SelectEntity<T1>(
|
|
||||||
this IEnumerable<Entity> entities,
|
|
||||||
Func<Entity, T1, Entity?> selectWithComponents,
|
|
||||||
bool includeEntitiesWithoutComponents = true)
|
|
||||||
{
|
|
||||||
return entities.SelectEntity(selectWithComponents, includeEntitiesWithoutComponents ? a => a : a => null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="includeEntitiesWithoutComponents">
|
/// <param name="includeEntitiesWithoutComponents">
|
||||||
/// If true, then entities without all the components are included. Otherwise, they
|
/// If true, then entities without all the components are included. Otherwise, they
|
||||||
/// are excluded.
|
/// are excluded.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, Entity?> selectWithComponents,
|
||||||
bool includeEntitiesWithoutComponents = true)
|
bool includeEntitiesWithoutComponents = true)
|
||||||
{
|
{
|
||||||
return entities.SelectEntity(selectWithComponents, includeEntitiesWithoutComponents ? a => a : a => null);
|
return entities.SelectEntity(
|
||||||
}
|
selectWithComponents,
|
||||||
|
includeEntitiesWithoutComponents ? a => a : a => null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="includeEntitiesWithoutComponents">
|
/// <param name="includeEntitiesWithoutComponents">
|
||||||
/// If true, then entities without all the components are included. Otherwise, they
|
/// If true, then entities without all the components are included. Otherwise, they
|
||||||
/// are excluded.
|
/// are excluded.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <typeparam name="T3">The type of the third component.</typeparam>
|
/// <typeparam name="T3">The type of the third component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2, T3>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2, T3>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, T3, Entity?> selectWithComponents,
|
||||||
bool includeEntitiesWithoutComponents = true)
|
bool includeEntitiesWithoutComponents = true)
|
||||||
{
|
{
|
||||||
return entities.SelectEntity(selectWithComponents, includeEntitiesWithoutComponents ? a => a : a => null);
|
return entities.SelectEntity(
|
||||||
}
|
selectWithComponents,
|
||||||
|
includeEntitiesWithoutComponents ? a => a : a => null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="includeEntitiesWithoutComponents">
|
/// <param name="includeEntitiesWithoutComponents">
|
||||||
/// If true, then entities without all the components are included. Otherwise, they
|
/// If true, then entities without all the components are included. Otherwise, they
|
||||||
/// are excluded.
|
/// are excluded.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <typeparam name="T3">The type of the third component.</typeparam>
|
/// <typeparam name="T3">The type of the third component.</typeparam>
|
||||||
/// <typeparam name="T4">The type of the fourth component.</typeparam>
|
/// <typeparam name="T4">The type of the fourth component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2, T3, T4>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2, T3, T4>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, T4, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, T3, T4, Entity?> selectWithComponents,
|
||||||
bool includeEntitiesWithoutComponents = true)
|
bool includeEntitiesWithoutComponents = true)
|
||||||
{
|
{
|
||||||
return entities.SelectEntity(selectWithComponents, includeEntitiesWithoutComponents ? a => a : a => null);
|
return entities.SelectEntity(
|
||||||
}
|
selectWithComponents,
|
||||||
|
includeEntitiesWithoutComponents ? a => a : a => null);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="selectWithoutComponents">
|
/// <param name="selectWithoutComponents">
|
||||||
/// The optional transformation function for entities that do not have all the
|
/// The optional transformation function for entities that do not have all the
|
||||||
/// components. If returns null,
|
/// components. If returns null,
|
||||||
/// then the entity will not be included.
|
/// then the entity will not be included.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1>(
|
public static IEnumerable<Entity> SelectEntity<T1>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, Entity?> selectWithComponents,
|
Func<Entity, T1, Entity?> selectWithComponents,
|
||||||
Func<Entity, Entity?> selectWithoutComponents)
|
Func<Entity, Entity?> selectWithoutComponents)
|
||||||
|
{
|
||||||
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
Entity? result = entity.TryGet(out T1 value1)
|
||||||
|
? selectWithComponents?.Invoke(entity, value1)
|
||||||
|
: selectWithoutComponents?.Invoke(entity);
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
{
|
{
|
||||||
Entity? result = entity.TryGet(out T1 value1)
|
yield return result;
|
||||||
? selectWithComponents?.Invoke(entity, value1)
|
|
||||||
: selectWithoutComponents?.Invoke(entity);
|
|
||||||
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
yield return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="selectWithoutComponents">
|
/// <param name="selectWithoutComponents">
|
||||||
/// The optional transformation function for entities that do not have all the
|
/// The optional transformation function for entities that do not have all the
|
||||||
/// components. If returns null,
|
/// components. If returns null,
|
||||||
/// then the entity will not be included.
|
/// then the entity will not be included.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, Entity?> selectWithComponents,
|
||||||
Func<Entity, Entity?> selectWithoutComponents)
|
Func<Entity, Entity?> selectWithoutComponents)
|
||||||
|
{
|
||||||
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
Entity? result = entity.TryGet(out T1 value1)
|
||||||
{
|
&& entity.TryGet(out T2 value2)
|
||||||
Entity? result = entity.TryGet(out T1 value1) && entity.TryGet(out T2 value2)
|
|
||||||
? selectWithComponents?.Invoke(entity, value1, value2)
|
? selectWithComponents?.Invoke(entity, value1, value2)
|
||||||
: selectWithoutComponents?.Invoke(entity);
|
: selectWithoutComponents?.Invoke(entity);
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
yield return result;
|
yield return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="selectWithoutComponents">
|
/// <param name="selectWithoutComponents">
|
||||||
/// The optional transformation function for entities that do not have all the
|
/// The optional transformation function for entities that do not have all the
|
||||||
/// components. If returns null,
|
/// components. If returns null,
|
||||||
/// then the entity will not be included.
|
/// then the entity will not be included.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <typeparam name="T3">The type of the third component.</typeparam>
|
/// <typeparam name="T3">The type of the third component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2, T3>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2, T3>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, T3, Entity?> selectWithComponents,
|
||||||
Func<Entity, Entity?> selectWithoutComponents)
|
Func<Entity, Entity?> selectWithoutComponents)
|
||||||
|
{
|
||||||
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
Entity? result =
|
||||||
{
|
entity.TryGet(out T1 value1)
|
||||||
Entity? result =
|
&& entity.TryGet(out T2 value2)
|
||||||
entity.TryGet(out T1 value1) && entity.TryGet(out T2 value2) && entity.TryGet(out T3 value3)
|
&& entity.TryGet(out T3 value3)
|
||||||
? selectWithComponents?.Invoke(entity, value1, value2, value3)
|
? selectWithComponents?.Invoke(
|
||||||
: selectWithoutComponents?.Invoke(entity);
|
entity,
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
value3)
|
||||||
|
: selectWithoutComponents?.Invoke(entity);
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
yield return result;
|
yield return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Selects an entity from the given list, filtering on entities with
|
/// Selects an entity from the given list, filtering on entities with
|
||||||
/// the given components.
|
/// the given components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entities">The entities to parse.</param>
|
/// <param name="entities">The entities to parse.</param>
|
||||||
/// <param name="selectWithComponents">
|
/// <param name="selectWithComponents">
|
||||||
/// The transformation function for the entity and selected components. If this
|
/// The transformation function for the entity and selected components. If this
|
||||||
/// returns null, then the entity
|
/// returns null, then the entity
|
||||||
/// will be filtered out.
|
/// will be filtered out.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="selectWithoutComponents">
|
/// <param name="selectWithoutComponents">
|
||||||
/// The optional transformation function for entities that do not have all the
|
/// The optional transformation function for entities that do not have all the
|
||||||
/// components. If returns null,
|
/// components. If returns null,
|
||||||
/// then the entity will not be included.
|
/// then the entity will not be included.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <typeparam name="T1">The type of the first component.</typeparam>
|
/// <typeparam name="T1">The type of the first component.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the second component.</typeparam>
|
/// <typeparam name="T2">The type of the second component.</typeparam>
|
||||||
/// <typeparam name="T3">The type of the third component.</typeparam>
|
/// <typeparam name="T3">The type of the third component.</typeparam>
|
||||||
/// <typeparam name="T4">The type of the third component.</typeparam>
|
/// <typeparam name="T4">The type of the third component.</typeparam>
|
||||||
/// <returns>An enumeration of transformed entities.</returns>
|
/// <returns>An enumeration of transformed entities.</returns>
|
||||||
public static IEnumerable<Entity> SelectEntity<T1, T2, T3, T4>(
|
public static IEnumerable<Entity> SelectEntity<T1, T2, T3, T4>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, T4, Entity?> selectWithComponents,
|
Func<Entity, T1, T2, T3, T4, Entity?> selectWithComponents,
|
||||||
Func<Entity, Entity?> selectWithoutComponents)
|
Func<Entity, Entity?> selectWithoutComponents)
|
||||||
|
{
|
||||||
|
foreach (Entity entity in entities)
|
||||||
{
|
{
|
||||||
foreach (Entity entity in entities)
|
Entity? result =
|
||||||
{
|
entity.TryGet(out T1 value1)
|
||||||
Entity? result =
|
&& entity.TryGet(out T2 value2)
|
||||||
entity.TryGet(out T1 value1)
|
&& entity.TryGet(out T3 value3)
|
||||||
&& entity.TryGet(out T2 value2)
|
&& entity.TryGet(out T4 value4)
|
||||||
&& entity.TryGet(out T3 value3)
|
? selectWithComponents?.Invoke(
|
||||||
&& entity.TryGet(out T4 value4)
|
entity,
|
||||||
? selectWithComponents?.Invoke(entity, value1, value2, value3, value4)
|
value1,
|
||||||
: selectWithoutComponents?.Invoke(entity);
|
value2,
|
||||||
|
value3,
|
||||||
|
value4)
|
||||||
|
: selectWithoutComponents?.Invoke(entity);
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
yield return result;
|
yield return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,9 @@ public static class SplitEntityExtensions
|
||||||
Type t1,
|
Type t1,
|
||||||
Func<Entity, object, bool> test)
|
Func<Entity, object, bool> test)
|
||||||
{
|
{
|
||||||
return SplitEntity(entities, a => a.Has(t1) && test(a, a.Get<object>(t1)));
|
return SplitEntity(
|
||||||
|
entities,
|
||||||
|
a => a.Has(t1) && test(a, a.Get<object>(t1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -2,47 +2,46 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
public static class WhereEntityExtensions
|
||||||
{
|
{
|
||||||
public static class WhereEntityExtensions
|
public static IEnumerable<Entity> WhereEntity<T1>(
|
||||||
|
this IEnumerable<Entity> entities,
|
||||||
|
Func<Entity, T1, bool> include)
|
||||||
{
|
{
|
||||||
public static IEnumerable<Entity> WhereEntity<T1>(
|
return entities.Where(x => x.Has<T1>() && include(x, x.Get<T1>()));
|
||||||
this IEnumerable<Entity> entities,
|
}
|
||||||
Func<Entity, T1, bool> include)
|
|
||||||
{
|
|
||||||
return entities.Where(x => x.Has<T1>() && include(x, x.Get<T1>()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntity<T1, T2>(
|
public static IEnumerable<Entity> WhereEntity<T1, T2>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, bool> include)
|
Func<Entity, T1, T2, bool> include)
|
||||||
{
|
{
|
||||||
return entities.Where(
|
return entities.Where(
|
||||||
x => x.HasAll<T1, T2>()
|
x => x.HasAll<T1, T2>()
|
||||||
&& include(x, x.Get<T1>(), x.Get<T2>()));
|
&& include(x, x.Get<T1>(), x.Get<T2>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntity<T1, T2, T3>(
|
public static IEnumerable<Entity> WhereEntity<T1, T2, T3>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, bool> include)
|
Func<Entity, T1, T2, T3, bool> include)
|
||||||
{
|
{
|
||||||
return entities.Where(
|
return entities.Where(
|
||||||
x => x.HasAll<T1, T2, T3>()
|
x => x.HasAll<T1, T2, T3>()
|
||||||
&& include(x, x.Get<T1>(), x.Get<T2>(), x.Get<T3>()));
|
&& include(x, x.Get<T1>(), x.Get<T2>(), x.Get<T3>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntity<T1, T2, T3, T4>(
|
public static IEnumerable<Entity> WhereEntity<T1, T2, T3, T4>(
|
||||||
this IEnumerable<Entity> entities,
|
this IEnumerable<Entity> entities,
|
||||||
Func<Entity, T1, T2, T3, T4, bool> include)
|
Func<Entity, T1, T2, T3, T4, bool> include)
|
||||||
{
|
{
|
||||||
return entities.Where(
|
return entities.Where(
|
||||||
x => x.HasAll<T1, T2, T3, T4>()
|
x => x.HasAll<T1, T2, T3, T4>()
|
||||||
&& include(
|
&& include(
|
||||||
x,
|
x,
|
||||||
x.Get<T1>(),
|
x.Get<T1>(),
|
||||||
x.Get<T2>(),
|
x.Get<T2>(),
|
||||||
x.Get<T3>(),
|
x.Get<T3>(),
|
||||||
x.Get<T4>()));
|
x.Get<T4>()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,31 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
public static class WhereEntityHasExtensions
|
||||||
{
|
{
|
||||||
public static class WhereEntityHasExtensions
|
public static IEnumerable<Entity> WhereEntityHas<T1>(
|
||||||
|
this IEnumerable<Entity> entities)
|
||||||
{
|
{
|
||||||
public static IEnumerable<Entity> WhereEntityHas<T1>(this IEnumerable<Entity> entities)
|
return entities.Where(x => x.Has<T1>());
|
||||||
{
|
}
|
||||||
return entities.Where(x => x.Has<T1>());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityHasAll
|
||||||
{
|
<T1, T2>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => x.HasAll<T1, T2>());
|
{
|
||||||
}
|
return entities.Where(x => x.HasAll<T1, T2>());
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2, T3>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityHasAll
|
||||||
{
|
<T1, T2, T3>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => x.HasAll<T1, T2, T3>());
|
{
|
||||||
}
|
return entities.Where(x => x.HasAll<T1, T2, T3>());
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityHasAll<T1, T2, T3, T4>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityHasAll
|
||||||
{
|
<T1, T2, T3, T4>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => x.HasAll<T1, T2, T3, T4>());
|
{
|
||||||
}
|
return entities.Where(x => x.HasAll<T1, T2, T3, T4>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,31 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace MfGames.Gallium
|
namespace MfGames.Gallium;
|
||||||
|
|
||||||
|
public static class WhereEntityNotHasExtensions
|
||||||
{
|
{
|
||||||
public static class WhereEntityNotHasExtensions
|
public static IEnumerable<Entity> WhereEntityNotHas<T1>(
|
||||||
|
this IEnumerable<Entity> entities)
|
||||||
{
|
{
|
||||||
public static IEnumerable<Entity> WhereEntityNotHas<T1>(this IEnumerable<Entity> entities)
|
return entities.Where(x => !x.Has<T1>());
|
||||||
{
|
}
|
||||||
return entities.Where(x => !x.Has<T1>());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityNotHasAll
|
||||||
{
|
<T1, T2>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => !x.HasAll<T1, T2>());
|
{
|
||||||
}
|
return entities.Where(x => !x.HasAll<T1, T2>());
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2, T3>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityNotHasAll
|
||||||
{
|
<T1, T2, T3>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => !x.HasAll<T1, T2, T3>());
|
{
|
||||||
}
|
return entities.Where(x => !x.HasAll<T1, T2, T3>());
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<Entity> WhereEntityNotHasAll<T1, T2, T3, T4>(this IEnumerable<Entity> entities)
|
public static IEnumerable<Entity> WhereEntityNotHasAll
|
||||||
{
|
<T1, T2, T3, T4>(this IEnumerable<Entity> entities)
|
||||||
return entities.Where(x => !x.HasAll<T1, T2, T3, T4>());
|
{
|
||||||
}
|
return entities.Where(x => !x.HasAll<T1, T2, T3, T4>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,216 +1,217 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using MfGames.Gallium;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class EntityTests : GalliumTestsBase
|
||||||
{
|
{
|
||||||
public class EntityTests : GalliumTestsBase
|
public EntityTests(ITestOutputHelper output)
|
||||||
|
: base(output)
|
||||||
{
|
{
|
||||||
public EntityTests(ITestOutputHelper output)
|
}
|
||||||
: base(output)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddingComponentOnceWorks()
|
public void AddingComponentOnceWorks()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.True(entity1.Has<TestComponent1>());
|
Assert.True(entity1.Has<TestComponent1>());
|
||||||
Assert.Equal(component1, entity1.Get<TestComponent1>());
|
Assert.Equal(component1, entity1.Get<TestComponent1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddingComponentViaInterfaceWork()
|
public void AddingComponentViaInterfaceWork()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent3a();
|
var component1 = new TestComponent3a();
|
||||||
Entity entity1 = new Entity().Add<ITestComponent3>(component1);
|
Entity entity1 = new Entity().Add<ITestComponent3>(component1);
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.False(entity1.Has<TestComponent3a>());
|
Assert.False(entity1.Has<TestComponent3a>());
|
||||||
Assert.True(entity1.Has<ITestComponent3>());
|
Assert.True(entity1.Has<ITestComponent3>());
|
||||||
Assert.Equal(component1, entity1.Get<ITestComponent3>());
|
Assert.Equal(component1, entity1.Get<ITestComponent3>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void AddingTwiceThrowsException()
|
public void AddingTwiceThrowsException()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
|
|
||||||
Exception exception = Assert.Throws<ArgumentException>(
|
Exception exception = Assert.Throws<ArgumentException>(
|
||||||
() => new Entity()
|
() => new Entity()
|
||||||
.Add(component1)
|
.Add(component1)
|
||||||
.Add(component1));
|
.Add(component1));
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
"An element with the same type "
|
"An element with the same type "
|
||||||
+ "(MfGames.Gallium.Tests.TestComponent1)"
|
+ "(MfGames.Gallium.Tests.TestComponent1)"
|
||||||
+ " already exists. (Parameter 'component')",
|
+ " already exists. (Parameter 'component')",
|
||||||
exception.Message);
|
exception.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CopyEntityAlsoCopiesComponents()
|
public void CopyEntityAlsoCopiesComponents()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
Entity entity2 = entity1.Copy();
|
Entity entity2 = entity1.Copy();
|
||||||
|
|
||||||
Assert.Equal(1, entity2.Count);
|
Assert.Equal(1, entity2.Count);
|
||||||
Assert.True(entity2.Has<TestComponent1>());
|
Assert.True(entity2.Has<TestComponent1>());
|
||||||
Assert.Equal(component1, entity2.Get<TestComponent1>());
|
Assert.Equal(component1, entity2.Get<TestComponent1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ExactCopyEntityAlsoCopiesComponents()
|
public void ExactCopyEntityAlsoCopiesComponents()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
Entity entity2 = entity1.ExactCopy();
|
Entity entity2 = entity1.ExactCopy();
|
||||||
|
|
||||||
Assert.Equal(1, entity2.Count);
|
Assert.Equal(1, entity2.Count);
|
||||||
Assert.True(entity2.Has<TestComponent1>());
|
Assert.True(entity2.Has<TestComponent1>());
|
||||||
Assert.Equal(component1, entity2.Get<TestComponent1>());
|
Assert.Equal(component1, entity2.Get<TestComponent1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetOptionalWorks()
|
public void GetOptionalWorks()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
|
|
||||||
Assert.Equal(component1, entity1.GetOptional<TestComponent1>());
|
Assert.Equal(component1, entity1.GetOptional<TestComponent1>());
|
||||||
Assert.Null(entity1.GetOptional<TestComponent2>());
|
Assert.Null(entity1.GetOptional<TestComponent2>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasReturnsFalseIfNotRegistered()
|
public void HasReturnsFalseIfNotRegistered()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
|
|
||||||
Assert.False(entity1.Has<TestComponent1>());
|
Assert.False(entity1.Has<TestComponent1>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NewEntityHasNoComponents()
|
public void NewEntityHasNoComponents()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
|
|
||||||
Assert.Equal(0, entity1.Count);
|
Assert.Equal(0, entity1.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RemoveAlreadyMissingComponentWorks()
|
public void RemoveAlreadyMissingComponentWorks()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
|
|
||||||
Assert.Equal(0, entity1.Count);
|
Assert.Equal(0, entity1.Count);
|
||||||
|
|
||||||
Entity entity2 = entity1.Remove<TestComponent1>();
|
Entity entity2 = entity1.Remove<TestComponent1>();
|
||||||
|
|
||||||
Assert.Equal(0, entity1.Count);
|
Assert.Equal(0, entity1.Count);
|
||||||
Assert.Equal(0, entity2.Count);
|
Assert.Equal(0, entity2.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RemoveComponentDoesNotRemoveFromCopies()
|
public void RemoveComponentDoesNotRemoveFromCopies()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
Entity entity2 = entity1.ExactCopy();
|
Entity entity2 = entity1.ExactCopy();
|
||||||
Entity entity3 = entity1.Copy();
|
Entity entity3 = entity1.Copy();
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.Equal(1, entity2.Count);
|
Assert.Equal(1, entity2.Count);
|
||||||
Assert.Equal(1, entity3.Count);
|
Assert.Equal(1, entity3.Count);
|
||||||
|
|
||||||
Entity entity1A = entity1.Remove<TestComponent1>();
|
Entity entity1A = entity1.Remove<TestComponent1>();
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.Equal(0, entity1A.Count);
|
Assert.Equal(0, entity1A.Count);
|
||||||
Assert.Equal(1, entity2.Count);
|
Assert.Equal(1, entity2.Count);
|
||||||
Assert.Equal(1, entity3.Count);
|
Assert.Equal(1, entity3.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RemoveComponentWorks()
|
public void RemoveComponentWorks()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
|
|
||||||
Entity entity2 = entity1.Remove<TestComponent1>();
|
Entity entity2 = entity1.Remove<TestComponent1>();
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.Equal(0, entity2.Count);
|
Assert.Equal(0, entity2.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SettingComponentsWorks()
|
public void SettingComponentsWorks()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent3a();
|
var component1 = new TestComponent3a();
|
||||||
var component2 = new TestComponent3b();
|
var component2 = new TestComponent3b();
|
||||||
|
|
||||||
Entity entity1 = new Entity()
|
Entity entity1 = new Entity()
|
||||||
.Set<ITestComponent3>(component1)
|
.Set<ITestComponent3>(component1)
|
||||||
.Set<ITestComponent3>(component1)
|
.Set<ITestComponent3>(component1)
|
||||||
.Set<ITestComponent3>(component2);
|
.Set<ITestComponent3>(component2);
|
||||||
|
|
||||||
Assert.Equal(1, entity1.Count);
|
Assert.Equal(1, entity1.Count);
|
||||||
Assert.Equal(component2, entity1.Get<ITestComponent3>());
|
Assert.Equal(component2, entity1.Get<ITestComponent3>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TryGetWorks()
|
public void TryGetWorks()
|
||||||
{
|
{
|
||||||
var component1 = new TestComponent1();
|
var component1 = new TestComponent1();
|
||||||
Entity entity1 = new Entity().Add(component1);
|
Entity entity1 = new Entity().Add(component1);
|
||||||
|
|
||||||
bool result1 = entity1.TryGet(out TestComponent1 value1);
|
bool result1 = entity1.TryGet(out TestComponent1 value1);
|
||||||
|
|
||||||
Assert.True(result1);
|
Assert.True(result1);
|
||||||
Assert.Equal(component1, value1);
|
Assert.Equal(component1, value1);
|
||||||
|
|
||||||
bool result2 = entity1.TryGet(out TestComponent2 _);
|
bool result2 = entity1.TryGet(out TestComponent2 _);
|
||||||
|
|
||||||
Assert.False(result2);
|
Assert.False(result2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TwoCopiesHaveDifferentIds()
|
public void TwoCopiesHaveDifferentIds()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
Entity entity2 = entity1.Copy();
|
Entity entity2 = entity1.Copy();
|
||||||
|
|
||||||
Assert.NotEqual(entity1.Id, entity2.Id);
|
Assert.NotEqual(entity1.Id, entity2.Id);
|
||||||
Assert.NotEqual(entity1, entity2);
|
Assert.NotEqual(entity1, entity2);
|
||||||
Assert.False(entity1 == entity2);
|
Assert.False(entity1 == entity2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TwoEntitiesHaveDifferentIds()
|
public void TwoEntitiesHaveDifferentIds()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
var entity2 = new Entity();
|
var entity2 = new Entity();
|
||||||
|
|
||||||
Assert.NotEqual(entity1.Id, entity2.Id);
|
Assert.NotEqual(entity1.Id, entity2.Id);
|
||||||
Assert.NotEqual(entity1, entity2);
|
Assert.NotEqual(entity1, entity2);
|
||||||
Assert.False(entity1 == entity2);
|
Assert.False(entity1 == entity2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TwoExactCopiesHaveDifferentIds()
|
public void TwoExactCopiesHaveDifferentIds()
|
||||||
{
|
{
|
||||||
var entity1 = new Entity();
|
var entity1 = new Entity();
|
||||||
Entity entity2 = entity1.ExactCopy();
|
Entity entity2 = entity1.ExactCopy();
|
||||||
|
|
||||||
Assert.Equal(entity1.Id, entity2.Id);
|
Assert.Equal(entity1.Id, entity2.Id);
|
||||||
Assert.Equal(entity1, entity2);
|
Assert.Equal(entity1, entity2);
|
||||||
Assert.True(entity1 == entity2);
|
Assert.True(entity1 == entity2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,215 +1,221 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
|
using MfGames.Gallium;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class EnumerableEntityTests
|
||||||
{
|
{
|
||||||
public class EnumerableEntityTests
|
[Fact]
|
||||||
|
public void ForComponentsC1()
|
||||||
{
|
{
|
||||||
[Fact]
|
Entity[] entities =
|
||||||
public void ForComponentsC1()
|
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2()),
|
||||||
new Entity().Add("2")
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent2()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add(new TestComponent1()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1!", "2", "3!" },
|
new[] { "1!", "2", "3!" },
|
||||||
entities.SelectEntity<TestComponent1>(
|
entities.SelectEntity<TestComponent1>(
|
||||||
(
|
(
|
||||||
e,
|
e,
|
||||||
_) => e.Set(e.Get<string>() + "!"))
|
_) => e.Set(e.Get<string>() + "!"))
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ForComponentsC2()
|
public void ForComponentsC2()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2()),
|
||||||
new Entity().Add("2")
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent2()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("3")
|
.Add(new TestComponent2())
|
||||||
.Add(new TestComponent1())
|
};
|
||||||
.Add(new TestComponent2()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1", "2", "3!" },
|
new[] { "1", "2", "3!" },
|
||||||
entities.SelectEntity<TestComponent1, TestComponent2>(
|
entities.SelectEntity<TestComponent1, TestComponent2>(
|
||||||
(
|
(
|
||||||
e,
|
e,
|
||||||
_,
|
_,
|
||||||
_) => e.Set(e.Get<string>() + "!"))
|
_) => e.Set(e.Get<string>() + "!"))
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ForComponentsC3()
|
public void ForComponentsC3()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2())
|
||||||
new Entity().Add("2")
|
.Add<ITestComponent3>(new TestComponent3b()),
|
||||||
.Add(new TestComponent2())
|
new Entity().Add("3")
|
||||||
.Add<ITestComponent3>(new TestComponent3b()),
|
.Add<ITestComponent3>(new TestComponent3a())
|
||||||
new Entity().Add("3")
|
.Add(new TestComponent1())
|
||||||
.Add<ITestComponent3>(new TestComponent3a())
|
.Add(new TestComponent2())
|
||||||
.Add(new TestComponent1())
|
};
|
||||||
.Add(new TestComponent2()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1", "2", "3-TestComponent3a" },
|
new[] { "1", "2", "3-TestComponent3a" },
|
||||||
entities.SelectEntity<TestComponent1, TestComponent2, ITestComponent3>(
|
entities
|
||||||
(
|
.SelectEntity<TestComponent1, TestComponent2, ITestComponent3>(
|
||||||
e,
|
(
|
||||||
_,
|
e,
|
||||||
_,
|
_,
|
||||||
t) => e.Set(
|
_,
|
||||||
e.Get<string>()
|
t) => e.Set(
|
||||||
+ "-"
|
e.Get<string>()
|
||||||
+ t.GetType()
|
+ "-"
|
||||||
.Name))
|
+ t.GetType()
|
||||||
.Select(x => x.Get<string>())
|
.Name))
|
||||||
.ToArray());
|
.Select(x => x.Get<string>())
|
||||||
}
|
.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasComponentsC1()
|
public void HasComponentsC1()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2()),
|
||||||
new Entity().Add("2")
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent2()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add(new TestComponent1()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1", "3" },
|
new[] { "1", "3" },
|
||||||
entities.WhereEntityHas<TestComponent1>()
|
entities.WhereEntityHas<TestComponent1>()
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasComponentsC2()
|
public void HasComponentsC2()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2())
|
||||||
new Entity().Add("2")
|
.Add(new TestComponent1()),
|
||||||
.Add(new TestComponent2())
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add(new TestComponent1()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "2" },
|
new[] { "2" },
|
||||||
entities.WhereEntityHasAll<TestComponent1, TestComponent2>()
|
entities.WhereEntityHasAll<TestComponent1, TestComponent2>()
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void HasComponentsC3()
|
public void HasComponentsC3()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("1")
|
.Add<ITestComponent3>(new TestComponent3b())
|
||||||
.Add(new TestComponent1())
|
.Add(new TestComponent2()),
|
||||||
.Add<ITestComponent3>(new TestComponent3b())
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent2()),
|
.Add(new TestComponent2())
|
||||||
new Entity().Add("2")
|
.Add(new TestComponent1()),
|
||||||
.Add(new TestComponent2())
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent1()),
|
.Add<ITestComponent3>(new TestComponent3a())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add<ITestComponent3>(new TestComponent3a()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1" },
|
new[] { "1" },
|
||||||
entities.WhereEntityHasAll<TestComponent1, TestComponent2, ITestComponent3>()
|
entities
|
||||||
.Select(x => x.Get<string>())
|
.WhereEntityHasAll<TestComponent1, TestComponent2,
|
||||||
.ToArray());
|
ITestComponent3>()
|
||||||
}
|
.Select(x => x.Get<string>())
|
||||||
|
.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotComponentsC1()
|
public void NotComponentsC1()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2()),
|
||||||
new Entity().Add("2")
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent2()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add(new TestComponent1()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "2" },
|
new[] { "2" },
|
||||||
entities.WhereEntityNotHas<TestComponent1>()
|
entities.WhereEntityNotHas<TestComponent1>()
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotComponentsC2()
|
public void NotComponentsC2()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent2())
|
||||||
new Entity().Add("2")
|
.Add(new TestComponent1()),
|
||||||
.Add(new TestComponent2())
|
new Entity().Add("3")
|
||||||
.Add(new TestComponent1()),
|
};
|
||||||
new Entity().Add("3"),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new[] { "1", "3" },
|
new[] { "1", "3" },
|
||||||
entities.WhereEntityNotHasAll<TestComponent1, TestComponent2>()
|
entities.WhereEntityNotHasAll<TestComponent1, TestComponent2>()
|
||||||
.Select(x => x.Get<string>())
|
.Select(x => x.Get<string>())
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotComponentsC3()
|
public void NotComponentsC3()
|
||||||
|
{
|
||||||
|
Entity[] entities =
|
||||||
{
|
{
|
||||||
Entity[] entities =
|
new Entity().Add("1")
|
||||||
{
|
.Add(new TestComponent1()),
|
||||||
new Entity().Add("1")
|
new Entity().Add("2")
|
||||||
.Add(new TestComponent1()),
|
.Add(new TestComponent1())
|
||||||
new Entity().Add("2")
|
.Add(new TestComponent2())
|
||||||
.Add(new TestComponent1())
|
.Add<ITestComponent3>(new TestComponent3b()),
|
||||||
.Add(new TestComponent2())
|
new Entity().Add("3")
|
||||||
.Add<ITestComponent3>(new TestComponent3b()),
|
.Add<ITestComponent3>(new TestComponent3a())
|
||||||
new Entity().Add("3")
|
};
|
||||||
.Add<ITestComponent3>(new TestComponent3a()),
|
|
||||||
};
|
|
||||||
|
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
new string[] { "1", "3" },
|
new[] { "1", "3" },
|
||||||
entities.WhereEntityNotHasAll<TestComponent1, TestComponent2, ITestComponent3>()
|
entities
|
||||||
.Select(x => x.Get<string>())
|
.WhereEntityNotHasAll<TestComponent1, TestComponent2,
|
||||||
.ToArray());
|
ITestComponent3>()
|
||||||
}
|
.Select(x => x.Get<string>())
|
||||||
|
.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,39 +3,38 @@ using Serilog.Core;
|
||||||
|
|
||||||
using Xunit.Abstractions;
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Common initialization logic for Gallium-based tests including setting
|
||||||
|
/// up containers, logging, and Serilog.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class GalliumTestsBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
protected GalliumTestsBase(ITestOutputHelper output)
|
||||||
/// Common initialization logic for Gallium-based tests including setting
|
|
||||||
/// up containers, logging, and Serilog.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class GalliumTestsBase
|
|
||||||
{
|
{
|
||||||
protected GalliumTestsBase(ITestOutputHelper output)
|
this.Output = output;
|
||||||
{
|
|
||||||
this.Output = output;
|
|
||||||
|
|
||||||
// Set up logging.
|
// Set up logging.
|
||||||
const string Template =
|
const string Template =
|
||||||
"[{Level:u3}] "
|
"[{Level:u3}] "
|
||||||
+ "({SourceContext}) {Message}"
|
+ "({SourceContext}) {Message}"
|
||||||
+ "{NewLine}{Exception}";
|
+ "{NewLine}{Exception}";
|
||||||
|
|
||||||
this.Logger = new LoggerConfiguration()
|
this.Logger = new LoggerConfiguration()
|
||||||
.WriteTo.TestOutput(
|
.WriteTo.TestOutput(
|
||||||
output,
|
output,
|
||||||
outputTemplate: Template)
|
outputTemplate: Template)
|
||||||
.CreateLogger();
|
.CreateLogger();
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the output for the tests.
|
|
||||||
/// </summary>
|
|
||||||
public ITestOutputHelper Output { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the logger used to report messages about the test.
|
|
||||||
/// </summary>
|
|
||||||
protected Logger Logger { get; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the output for the tests.
|
||||||
|
/// </summary>
|
||||||
|
public ITestOutputHelper Output { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the logger used to report messages about the test.
|
||||||
|
/// </summary>
|
||||||
|
protected Logger Logger { get; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public interface ITestComponent3
|
||||||
{
|
{
|
||||||
public interface ITestComponent3
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
<Version>1.4.0</Version>
|
<Version>1.4.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1"/>
|
||||||
<PackageReference Include="Serilog.Sinks.XUnit" Version="3.0.3" />
|
<PackageReference Include="Serilog.Sinks.XUnit" Version="3.0.3"/>
|
||||||
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114" />
|
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114"/>
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="xunit" Version="2.4.2"/>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
@ -24,6 +24,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\MfGames.Gallium\MfGames.Gallium.csproj" />
|
<ProjectReference Include="..\..\src\MfGames.Gallium\MfGames.Gallium.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class TestComponent1
|
||||||
{
|
{
|
||||||
public class TestComponent1
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class TestComponent2
|
||||||
{
|
{
|
||||||
public class TestComponent2
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class TestComponent3a : ITestComponent3
|
||||||
{
|
{
|
||||||
public class TestComponent3a : ITestComponent3
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
namespace MfGames.Gallium.Tests
|
namespace Gallium.Tests;
|
||||||
|
|
||||||
|
public class TestComponent3b : ITestComponent3
|
||||||
{
|
{
|
||||||
public class TestComponent3b : ITestComponent3
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue