|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using Object = UnityEngine.Object;
|
|
|
|
|
|
|
|
|
|
public static class ComponentExtensions
|
|
|
|
|
{
|
|
|
|
|
private static class ComponentsCache<TComponent> where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
public static readonly Dictionary<GameObject, TComponent> components = new Dictionary<GameObject, TComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// We need to cleanup each generic cache when domain reload is disabled.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private static readonly Dictionary<Type, bool> typesToCleanup = new Dictionary<Type, bool>();
|
|
|
|
|
private static int reloadCounter;
|
|
|
|
|
|
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
|
|
|
private static void Init()
|
|
|
|
|
{
|
|
|
|
|
reloadCounter++;
|
|
|
|
|
typesToCleanup.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void CheckCacheCleanup<TComponent>() where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
if (reloadCounter > 0)
|
|
|
|
|
{
|
|
|
|
|
var componentType = typeof(TComponent);
|
|
|
|
|
if (!typesToCleanup.TryGetValue(componentType, out var needsCleanup))
|
|
|
|
|
{
|
|
|
|
|
typesToCleanup.Add(componentType, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (needsCleanup)
|
|
|
|
|
{
|
|
|
|
|
ComponentsCache<TComponent>.components.Clear();
|
|
|
|
|
typesToCleanup[componentType] = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public static bool TryGetComponentCached<TComponent>(this Component instance, out TComponent component)
|
|
|
|
|
where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
return TryGetComponentCached(instance.gameObject, out component);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool TryGetComponentCached<TComponent>(this GameObject gameObject, out TComponent component)
|
|
|
|
|
where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
CheckCacheCleanup<TComponent>();
|
|
|
|
|
#endif
|
|
|
|
|
if (ComponentsCache<TComponent>.components.TryGetValue(gameObject, out component))
|
|
|
|
|
return component;
|
|
|
|
|
|
|
|
|
|
if (gameObject.TryGetComponent(out component))
|
|
|
|
|
ComponentsCache<TComponent>.components.Add(gameObject, component);
|
|
|
|
|
|
|
|
|
|
return component;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static TComponent GetComponentCached<TComponent>(this Component instance)
|
|
|
|
|
where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
return GetComponentCached<TComponent>(instance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static TComponent GetComponentCached<TComponent>(this GameObject gameObject)
|
|
|
|
|
where TComponent : Component
|
|
|
|
|
{
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
CheckCacheCleanup<TComponent>();
|
|
|
|
|
#endif
|
|
|
|
|
if (ComponentsCache<TComponent>.components.TryGetValue(gameObject, out var component))
|
|
|
|
|
return component;
|
|
|
|
|
|
|
|
|
|
if (gameObject.TryGetComponent(out component))
|
|
|
|
|
ComponentsCache<TComponent>.components.Add(gameObject, component);
|
|
|
|
|
|
|
|
|
|
return component;
|
|
|
|
|
}
|
|
|
|
|
}
|