Editor/AssetBrowserAddon/LocationRegistration.Hammer.cs
using System;
using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Editor;
using Sandbox;
namespace Sandbox.AssetBrowserAddon;
internal static partial class LocationRegistration
{
private static bool _hammerTypeChecked;
private static Type _hammerType;
private static Func<LocalAssetBrowser> _hammerInstanceGetter;
/// <summary>
/// Explicitly watch for the Hammer asset browser and attach our header once it exists.
/// </summary>
[EditorEvent.Frame]
private static void TryInstallHammer()
{
if (_hammerAttached)
return;
if (_hammerType is null && !_hammerTypeChecked)
{
_hammerType = AppDomain.CurrentDomain
.GetAssemblies()
.SelectManySafe(a => a.GetTypesSafe())
.FirstOrDefault(t =>
t.FullName is not null &&
t.FullName.Contains("HammerAssetBrowser", StringComparison.Ordinal) &&
typeof(LocalAssetBrowser).IsAssignableFrom(t));
_hammerTypeChecked = true;
if (_hammerType is not null)
{
_hammerInstanceGetter = CreateHammerGetter(_hammerType);
}
}
if (_hammerType is null || _hammerInstanceGetter is null)
return;
var inst = _hammerInstanceGetter();
if (inst is not LocalAssetBrowser hammer)
return;
if (RegisterBrowser(hammer))
{
_hammerAttached = true;
RebuildAll();
}
}
private static Func<LocalAssetBrowser> CreateHammerGetter(Type hammerType)
{
var prop = hammerType.GetProperty("Instance", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (prop != null)
{
return () => prop.GetValue(null) as LocalAssetBrowser;
}
var field = hammerType.GetField("Instance", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (field != null)
{
return () => field.GetValue(null) as LocalAssetBrowser;
}
return null;
}
private static IEnumerable<Type> GetTypesSafe(this Assembly assembly)
{
try
{
return assembly.GetTypes();
}
catch
{
return Array.Empty<Type>();
}
}
/// <summary>
/// Safe helper to flatten types across assemblies.
/// </summary>
private static IEnumerable<Type> SelectManySafe(this Assembly[] assemblies, Func<Assembly, IEnumerable<Type>> selector)
{
foreach (var asm in assemblies)
{
foreach (var type in selector(asm))
{
yield return type;
}
}
}
}