Syntriax.Engine/Engine.Core/Extensions/BehaviourControllerExtensio...

97 lines
5.4 KiB
C#

using System.Diagnostics.CodeAnalysis;
using Syntriax.Engine.Core.Abstract;
namespace Syntriax.Engine.Core;
public static class BehaviourControllerExtensions
{
/// <summary>
/// Tries to get a <see cref="IBehaviour"/> of the specified type.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to search in.</param>
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found; otherwise, <see cref="false"/>.</returns>
public static bool TryGetBehaviour<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour)
{
behaviour = behaviourController.GetBehaviour<T>();
return behaviour is not null;
}
/// <summary>
/// Gets an existing <see cref="IBehaviour"/> of the specified type, or adds and returns a new one if it doesn't exist.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get or add.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to search in.</param>
/// <param name="args">Optional arguments to pass to the constructor of the <see cref="IBehaviour"/> if a new one is added.</param>
/// <returns>The existing or newly added <see cref="IBehaviour"/> of the specified type.</returns>
public static T GetOrAddBehaviour<T>(this IBehaviourController behaviourController, params object?[]? args) where T : class, IBehaviour
=> behaviourController.GetBehaviour<T>() ?? behaviourController.AddBehaviour<T>(args);
/// <summary>
/// Tries to get a <see cref="IBehaviour"/> of the specified type in the parent hierarchy.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the parent hierarchy; otherwise, <see cref="false"/>.</returns>
public static bool TryGetBehaviourInParent<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{
behaviour = GetBehaviourInParent<T>(behaviourController);
return behaviour is not null;
}
/// <summary>
/// Gets a <see cref="IBehaviour"/> of the specified type in the parent hierarchy.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, null.</returns>
public static T? GetBehaviourInParent<T>(this IBehaviourController behaviourController) where T : class
{
IBehaviourController? controller = behaviourController;
while (controller is not null)
{
if (behaviourController.GetBehaviour<T>() is T behaviour)
return behaviour;
controller = controller.GameObject.Transform.Parent?.GameObject.BehaviourController;
}
return default;
}
/// <summary>
/// Tries to get a <see cref="IBehaviour"/> of the specified type in the child hierarchy.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <param name="behaviour">When this method returns, contains the <see cref="IBehaviour"/> of the specified type, if found; otherwise, null.</param>
/// <returns><see cref="true"/> if a <see cref="IBehaviour"/> of the specified type was found in the child hierarchy; otherwise, <see cref="false"/>.</returns>
public static bool TryGetBehaviourInChildren<T>(this IBehaviourController behaviourController, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class
{
behaviour = GetBehaviourInChildren<T>(behaviourController);
return behaviour is not null;
}
/// <summary>
/// Gets a <see cref="IBehaviour"/> of the specified type in the child hierarchy.
/// </summary>
/// <typeparam name="T">The type of <see cref="IBehaviour"/> to get.</typeparam>
/// <param name="behaviourController">The <see cref="IBehaviourController"/> to start searching from.</param>
/// <returns>The <see cref="IBehaviour"/> of the specified type if found; otherwise, null.</returns>
public static T? GetBehaviourInChildren<T>(this IBehaviourController behaviourController) where T : class
{
if (behaviourController.GetBehaviour<T>() is T localBehaviour)
return localBehaviour;
foreach (ITransform transform in behaviourController.GameObject.Transform)
if (GetBehaviourInChildren<T>(transform.GameObject.BehaviourController) is T behaviour)
return behaviour;
return default;
}
}