// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik // using System; using System.Collections.Generic; using UnityEngine; namespace Animancer { /// An object which can be converted to another type. /// https://kybernetik.com.au/animancer/api/Animancer/IConvertable_1 public interface IConvertable { /************************************************************************************************************************/ /// Returns the equivalent of this object as . T Convert(); /************************************************************************************************************************/ } /// Utility methods for . /// https://kybernetik.com.au/animancer/api/Animancer/ConvertableUtilities public static partial class ConvertableUtilities { /************************************************************************************************************************/ /// /// Custom conversion functions used as a fallback /// for types that can't implement . /// public static readonly Dictionary> CustomConverters = new(); /************************************************************************************************************************/ /// Tries to convert the `original` to . /// /// /// If the `original` is already a then it's returned directly. /// Or if it's an then is used. /// Otherwise, this method throws an . /// /// public static T ConvertOrThrow(object original) { if (TryConvert(original, out var converted)) return converted; throw new ArgumentException( $"Unable to convert '{AnimancerUtilities.ToStringOrNull(original)}'" + $" to '{typeof(T).GetNameCS()}'."); } /************************************************************************************************************************/ /// Tries to convert the `original` to . /// /// /// If the `original` is already a then it's returned directly. /// Or if it's an then is used. /// Otherwise, this method returns the default(T). /// /// public static T ConvertOrDefault(object original) { TryConvert(original, out var converted); return converted; } /************************************************************************************************************************/ /// Tries to convert the `original` to . /// /// /// If the `original` is already a then it's returned directly. /// Or if it's an then is used. /// Otherwise, this method returns false. /// /// public static bool TryConvert(object original, out T converted) { if (original is null) { converted = default; return converted == null;// True for value type, false for reference type. } if (original is T t) { converted = t; return true; } if (original is IConvertable convertable) { converted = convertable.Convert(); return true; } if (CustomConverters.TryGetValue(original.GetType(), out var converter)) { converted = (T)converter(original, typeof(T)); return converted != null; } converted = default; return false; } /************************************************************************************************************************/ /// Initializes the inbuilt custom converters. static ConvertableUtilities() { CustomConverters.Add(typeof(GameObject), TryGetComponent); } /************************************************************************************************************************/ /// Tries to get a component if the `original` is a . private static object TryGetComponent(object original, Type type) { if (original is GameObject gameObject && gameObject.TryGetComponent(type, out var component)) return component; return null; } /************************************************************************************************************************/ } }