167 lines
7.7 KiB
C#
167 lines
7.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
using Syntriax.Engine.Core.Exceptions;
|
|
|
|
namespace Syntriax.Engine.Core;
|
|
|
|
public static class UniverseObjectExtensions
|
|
{
|
|
public static T SetUniverseObject<T>(this T universeObject, string? name = "", IUniverseObject? parent = null) where T : IUniverseObject
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(name))
|
|
universeObject.Name = name;
|
|
if (parent is not null)
|
|
universeObject.SetParent(parent);
|
|
return universeObject;
|
|
}
|
|
|
|
#region Universe Object Search
|
|
|
|
public static T? GetUniverseObject<T>(this IEnumerable<IUniverseObject> universeObjects) where T : class
|
|
{
|
|
foreach (IUniverseObject universeObject in universeObjects)
|
|
if (universeObject is T @object)
|
|
return @object;
|
|
|
|
return default;
|
|
}
|
|
|
|
public static bool TryGetUniverseObject<T>(this IEnumerable<IUniverseObject> universeObjects, [NotNullWhen(returnValue: true)] out T? universeObject) where T : class
|
|
{
|
|
universeObject = GetUniverseObject<T>(universeObjects);
|
|
return universeObject is not null;
|
|
}
|
|
|
|
public static void GetUniverseObjects<T>(this IEnumerable<IUniverseObject> universeObjects, IList<T> foundUniverseObjects) where T : class
|
|
{
|
|
foundUniverseObjects.Clear();
|
|
|
|
foreach (IUniverseObject universeObject in universeObjects)
|
|
if (universeObject is T @object)
|
|
foundUniverseObjects.Add(@object);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Universe Object Search In Parent
|
|
|
|
/// <summary>
|
|
/// Tries to get a <see cref="IUniverseObject"/> of the specified type in it's parents recursively.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="behaviour">When this method returns, contains the <see cref="IUniverseObject"/> of the specified type, if found; otherwise, null.</param>
|
|
/// <returns><see cref="true"/> if a <see cref="IUniverseObject"/> of the specified type was found in the parent universe objects; otherwise, <see cref="false"/>.</returns>
|
|
public static bool TryGetUniverseObjectInParent<T>(this IUniverseObject universeObject, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
{
|
|
behaviour = GetUniverseObjectInParent<T>(universeObject);
|
|
return behaviour is not null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="IUniverseObject"/> of the specified type in it's parents recursively.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="universeObject">The <see cref="IUniverseObject"/> to start searching from.</param>
|
|
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns>
|
|
public static T? GetUniverseObjectInParent<T>(this IUniverseObject universeObject) where T : class
|
|
{
|
|
if (universeObject.GetUniverseObject<T>() is T localUniverseObject)
|
|
return localUniverseObject;
|
|
|
|
IUniverseObject? parent = universeObject;
|
|
|
|
while (parent is not null)
|
|
{
|
|
if (parent is T behaviour)
|
|
return behaviour;
|
|
|
|
parent = universeObject.Parent;
|
|
}
|
|
|
|
return default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="IUniverseObject"/> of the specified type in the parents recursively. Throws an error if not found.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="universeObject">The <see cref="IUniverseObject"/> to start searching from.</param>
|
|
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, throws <see cref="UniverseObjectNotFoundException"/>.</returns>
|
|
public static T GetRequiredUniverseObjectInParent<T>(this IUniverseObject universeObject) where T : class
|
|
=> universeObject.GetUniverseObjectInParent<T>() ?? throw new UniverseObjectNotFoundException($"{universeObject.Name}'s {nameof(IUniverseObject)} does not contain any {typeof(T).FullName} on any parent ");
|
|
|
|
#endregion
|
|
|
|
#region Universe Object Search In Children
|
|
/// <summary>
|
|
/// Tries to get a <see cref="IUniverseObject"/> of the specified type in it's children recursively.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="behaviour">When this method returns, contains the <see cref="IUniverseObject"/> of the specified type, if found; otherwise, null.</param>
|
|
/// <returns><see cref="true"/> if a <see cref="IUniverseObject"/> of the specified type was found in the child universe objects; otherwise, <see cref="false"/>.</returns>
|
|
public static bool TryGetUniverseObjectInChildren<T>(this IUniverseObject universeObject, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
{
|
|
behaviour = GetUniverseObjectInChildren<T>(universeObject);
|
|
return behaviour is not null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="IUniverseObject"/> of the specified type in it's children recursively.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="universeObject">The <see cref="IUniverseObject"/> to start searching from.</param>
|
|
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, null.</returns>
|
|
public static T? GetUniverseObjectInChildren<T>(this IUniverseObject universeObject) where T : class
|
|
{
|
|
if (universeObject.GetUniverseObject<T>() is T localUniverseObject)
|
|
return localUniverseObject;
|
|
|
|
foreach (IUniverseObject child in universeObject)
|
|
if (GetUniverseObjectInChildren<T>(child) is T behaviour)
|
|
return behaviour;
|
|
|
|
return default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a <see cref="IUniverseObject"/> of the specified type in the children recursively. Throws an error if not found.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of <see cref="IUniverseObject"/> to get.</typeparam>
|
|
/// <param name="universeObject">The <see cref="IUniverseObject"/> to start searching from.</param>
|
|
/// <returns>The <see cref="IUniverseObject"/> of the specified type if found; otherwise, throws <see cref="UniverseObjectNotFoundException"/>.</returns>
|
|
public static T GetRequiredUniverseObjectInChildren<T>(this IUniverseObject universeObject) where T : class
|
|
=> universeObject.GetUniverseObjectInChildren<T>() ?? throw new UniverseObjectNotFoundException($"{universeObject.Name}'s {nameof(IUniverseObject)} does not contain any {typeof(T).FullName} on any children ");
|
|
#endregion
|
|
|
|
#region Behaviour Search
|
|
public static T? FindBehaviour<T>(this IEnumerable<IUniverseObject> universeObjects) where T : class
|
|
{
|
|
foreach (IUniverseObject universeObject in universeObjects)
|
|
if (universeObject.BehaviourController.GetBehaviour<T>() is T behaviour)
|
|
return behaviour;
|
|
|
|
return default;
|
|
}
|
|
|
|
public static bool TryFindBehaviour<T>(this IEnumerable<IUniverseObject> universeObjects, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
|
|
{
|
|
behaviour = FindBehaviour<T>(universeObjects);
|
|
return behaviour is not null;
|
|
}
|
|
|
|
public static void FindBehaviours<T>(this IEnumerable<IUniverseObject> universeObjects, IList<T> behaviours) where T : class
|
|
{
|
|
behaviours.Clear();
|
|
List<T> cache = [];
|
|
|
|
foreach (IUniverseObject universeObject in universeObjects)
|
|
{
|
|
universeObject.BehaviourController.GetBehaviours(cache);
|
|
foreach (T behaviour in cache)
|
|
behaviours.Add(behaviour);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|