Skip to content
This repository has been archived by the owner on Aug 11, 2024. It is now read-only.

Commit

Permalink
optimized perf when looking up types by guid (#632)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenHodgson authored Jun 2, 2020
1 parent 04eb196 commit 749ac66
Showing 1 changed file with 31 additions and 24 deletions.
55 changes: 31 additions & 24 deletions Runtime/Extensions/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UnityEngine;
using Debug = UnityEngine.Debug;

namespace XRTK.Extensions
{
Expand All @@ -14,13 +14,21 @@ namespace XRTK.Extensions
/// </summary>
public static class TypeExtensions
{
private static readonly Dictionary<Guid, Type> TypeCache = new Dictionary<Guid, Type>();

private static IEnumerable<Type> allTypes = null;
private static void BuildTypeCache()
{
foreach (var (type, guid) in
from type in AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsClass && !type.IsAbstract)
let guid = type.GUID
where !TypeCache.ContainsKey(guid)
select (type, guid))
{
TypeCache.Add(guid, type);
}
}

private static IEnumerable<Type> AllTypes => allTypes ?? (allTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => type.IsClass && !type.IsAbstract));
private static readonly Dictionary<Guid, Type> TypeCache = new Dictionary<Guid, Type>();

/// <summary>
/// Attempts to resolve the type using the class <see cref="Guid"/>.
Expand All @@ -32,14 +40,15 @@ public static bool TryResolveType(Guid guid, out Type resolvedType)
{
resolvedType = null;

if (guid == Guid.Empty)
if (TypeCache.Count == 0)
{
return false;
BuildTypeCache();
}

if (!TypeCache.TryGetValue(guid, out resolvedType))
if (guid == Guid.Empty ||
!TypeCache.TryGetValue(guid, out resolvedType))
{
resolvedType = AllTypes.FirstOrDefault(type => type.GUID == guid);
return false;
}

if (resolvedType != null && !resolvedType.IsAbstract)
Expand Down Expand Up @@ -71,22 +80,20 @@ public static bool TryResolveType(string typeRef, out Type resolvedType)
{
return TryResolveType(guid, out resolvedType);
}
else

resolvedType = Type.GetType(typeRef);

if (resolvedType != null)
{
resolvedType = Type.GetType(typeRef);
if (resolvedType.GUID != Guid.Empty)
{
return TryResolveType(guid, out resolvedType);
}

if (resolvedType != null)
if (!resolvedType.IsAbstract)
{
if (resolvedType.GUID != Guid.Empty)
{
return TryResolveType(guid, out resolvedType);
}

if (!resolvedType.IsAbstract)
{
Debug.LogWarning($"{resolvedType.Name} is missing a {nameof(GuidAttribute)}. This extension has been upgraded to use System.Type.GUID instead of System.Type.AssemblyQualifiedName");
return true;
}
Debug.LogWarning($"{resolvedType.Name} is missing a {nameof(GuidAttribute)}. This extension has been upgraded to use System.Type.GUID instead of System.Type.AssemblyQualifiedName");
return true;
}
}

Expand Down

0 comments on commit 749ac66

Please sign in to comment.