// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
// This code can only be used under the standard Unity Asset Store End User License Agreement
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
namespace Doozy.Runtime.Common.Utils
{
/// Utility class with optimized methods for reflection inside the Doozy assembly
public static class ReflectionUtils
{
private static Assembly[] s_domainAssemblies;
/// Current Domain assemblies (cached on first call)
public static IEnumerable domainAssemblies =>
s_domainAssemblies ??= AppDomain.CurrentDomain.GetAssemblies();
private static Assembly s_doozyEditorAssembly;
/// Doozy.Editor assembly (only for editor use) (cached on first call)
public static Assembly doozyEditorAssembly
{
get
{
if (s_doozyEditorAssembly != null) return s_doozyEditorAssembly;
foreach (Assembly assembly in domainAssemblies)
{
if (!assembly.DefinedTypes.Any(typeInfo => typeInfo.Namespace != null && typeInfo.Namespace.Contains("Doozy.Editor.")))
continue;
s_doozyEditorAssembly = assembly;
return s_doozyEditorAssembly;
}
return s_doozyEditorAssembly;
}
}
private static Assembly s_doozyRuntimeAssembly;
/// Doozy.Runtime assembly (for runtime use) (cached on first call)
public static Assembly doozyRuntimeAssembly =>
s_doozyRuntimeAssembly ??= Assembly.GetAssembly(typeof(ReflectionUtils));
private static IEnumerable s_doozyRuntimeTypes;
/// Enumeration of all the runtime types inside the Doozy.Runtime assembly (cached on first call)
public static IEnumerable doozyRuntimeTypes =>
s_doozyRuntimeTypes ??= doozyRuntimeAssembly.GetTypes();
///
/// Get all derived types for the givenBase type from the types collection
///
/// Collection of types
/// Base Type
public static IEnumerable GetDerivedTypes(IEnumerable types, Type baseType)
{
var list = new List();
foreach (Type typeInAssembly in types)
{
if (typeInAssembly.BaseType != baseType)
continue;
if (typeInAssembly.IsAbstract)
continue;
list.Add(typeInAssembly);
}
return list;
}
///
/// Get all types that implement the given interface
///
/// Type of Interface
public static IEnumerable GetTypesThatImplementInterface(Assembly fromAssembly) =>
fromAssembly
.GetTypes()
.Where(p => typeof(T).IsAssignableFrom(p) && !p.IsInterface);
///
/// Get all types that implement the given interface
///
/// Type of Interface
public static IEnumerable GetTypesThatImplementInterface() =>
domainAssemblies
.SelectMany(s => s.GetTypes())
.Where(p => typeof(T).IsAssignableFrom(p) && !p.IsInterface);
///
/// Get all de derived types for the given baseType and search in the given assembly
///
/// Assembly to search for derived types
/// Base Type
public static IEnumerable GetDerivedTypes(Assembly assembly, Type baseType) =>
GetDerivedTypes(assembly.GetTypes(), baseType);
///
/// Get all the derived types for the given type and search in the same assembly as the Base Type
///
/// Base Type
public static IEnumerable GetDerivedTypes(Type baseType) =>
GetDerivedTypes(Assembly.GetAssembly(baseType), baseType);
public static IEnumerable GetAttributeReferences(IEnumerable types) where T : Attribute
{
var list = new List();
foreach (Type type in types)
{
MemberInfo[] members = type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
foreach (MemberInfo member in members)
{
T attribute = member.GetCustomAttribute();
if (attribute == null) continue;
list.Add(attribute);
}
}
return list;
}
private static bool GetAttribute(IEnumerable