From bcce427376fe5fab756c3a853edef3a896eb768f Mon Sep 17 00:00:00 2001 From: Syntriax Date: Sun, 25 May 2025 12:20:37 +0300 Subject: [PATCH] feat: added GetUniverseObject/InChildren/InParent to UniverseObjectExtensions --- .../Extensions/UniverseObjectExtensions.cs | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/Engine.Core/Extensions/UniverseObjectExtensions.cs b/Engine.Core/Extensions/UniverseObjectExtensions.cs index f2603b3..a47f4eb 100644 --- a/Engine.Core/Extensions/UniverseObjectExtensions.cs +++ b/Engine.Core/Extensions/UniverseObjectExtensions.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using Syntriax.Engine.Core.Exceptions; + namespace Syntriax.Engine.Core; public static class UniverseObjectExtensions @@ -15,6 +17,7 @@ public static class UniverseObjectExtensions } #region Universe Object Search + public static T? GetUniverseObject(this IEnumerable universeObjects) where T : class { foreach (IUniverseObject universeObject in universeObjects) @@ -38,6 +41,97 @@ public static class UniverseObjectExtensions if (universeObject is T @object) foundUniverseObjects.Add(@object); } + + #endregion + + #region Universe Object Search In Parent + + /// + /// Tries to get a of the specified type in it's parents recursively. + /// + /// The type of to get. + /// When this method returns, contains the of the specified type, if found; otherwise, null. + /// if a of the specified type was found in the parent universe objects; otherwise, . + public static bool TryGetUniverseObjectInParent(this IUniverseObject universeObject, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class + { + behaviour = GetUniverseObjectInParent(universeObject); + return behaviour is not null; + } + + /// + /// Gets a of the specified type in it's parents recursively. + /// + /// The type of to get. + /// The to start searching from. + /// The of the specified type if found; otherwise, null. + public static T? GetUniverseObjectInParent(this IUniverseObject universeObject) where T : class + { + if (universeObject.GetUniverseObject() 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; + } + + /// + /// Gets a of the specified type in the parents recursively. Throws an error if not found. + /// + /// The type of to get. + /// The to start searching from. + /// The of the specified type if found; otherwise, throws . + public static T GetRequiredUniverseObjectInParent(this IUniverseObject universeObject) where T : class + => universeObject.GetUniverseObjectInParent() ?? 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 + /// + /// Tries to get a of the specified type in it's children recursively. + /// + /// The type of to get. + /// When this method returns, contains the of the specified type, if found; otherwise, null. + /// if a of the specified type was found in the child universe objects; otherwise, . + public static bool TryGetUniverseObjectInChildren(this IUniverseObject universeObject, [NotNullWhen(returnValue: true)] out T? behaviour) where T : class + { + behaviour = GetUniverseObjectInChildren(universeObject); + return behaviour is not null; + } + + /// + /// Gets a of the specified type in it's children recursively. + /// + /// The type of to get. + /// The to start searching from. + /// The of the specified type if found; otherwise, null. + public static T? GetUniverseObjectInChildren(this IUniverseObject universeObject) where T : class + { + if (universeObject.GetUniverseObject() is T localUniverseObject) + return localUniverseObject; + + foreach (IUniverseObject child in universeObject) + if (GetUniverseObjectInChildren(child) is T behaviour) + return behaviour; + + return default; + } + + /// + /// Gets a of the specified type in the children recursively. Throws an error if not found. + /// + /// The type of to get. + /// The to start searching from. + /// The of the specified type if found; otherwise, throws . + public static T GetRequiredUniverseObjectInChildren(this IUniverseObject universeObject) where T : class + => universeObject.GetUniverseObjectInChildren() ?? throw new UniverseObjectNotFoundException($"{universeObject.Name}'s {nameof(IUniverseObject)} does not contain any {typeof(T).FullName} on any children "); #endregion #region Behaviour Search