com.alicizax.unity.framework/Runtime/UI/Constant/UIMetaRegistry.cs
2025-11-13 11:16:31 +08:00

107 lines
3.8 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace AlicizaX.UI.Runtime
{
public static class UIMetaRegistry
{
public readonly struct UIMetaInfo
{
public readonly RuntimeTypeHandle RuntimeTypeHandle;
public readonly RuntimeTypeHandle HolderRuntimeTypeHandle;
public readonly int UILayer;
public readonly bool FullScreen;
public readonly int CacheTime;
public UIMetaInfo(RuntimeTypeHandle runtimeTypeHandle, RuntimeTypeHandle holderRuntimeTypeHandle, UILayer windowLayer, bool fullScreen, int cacheTime)
{
RuntimeTypeHandle = runtimeTypeHandle;
HolderRuntimeTypeHandle = holderRuntimeTypeHandle;
UILayer = (int)windowLayer;
FullScreen = fullScreen;
CacheTime = cacheTime;
}
}
private static readonly Dictionary<RuntimeTypeHandle, UIMetaInfo> _typeHandleMap = new();
private static readonly Dictionary<string, RuntimeTypeHandle> _stringHandleMap = new();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Register(Type uiType, Type holderType, UILayer layer = UILayer.UI, bool fullScreen = false, int cacheTime = 0)
{
var holderHandle = holderType.TypeHandle;
var uiHandle = uiType.TypeHandle;
_typeHandleMap[uiHandle] = new UIMetaInfo(uiHandle, holderHandle, layer, fullScreen, cacheTime);
_stringHandleMap[uiType.Name] = uiHandle;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGet(RuntimeTypeHandle handle, out UIMetaInfo info)
{
if (_typeHandleMap.TryGetValue(handle, out info))
return true;
var t = Type.GetTypeFromHandle(handle);
if (TryReflectAndRegister(t, out info))
return true;
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool TryGet(string typeName, out UIMetaInfo info)
{
if (_stringHandleMap.TryGetValue(typeName, out var handle))
return TryGet(handle, out info);
var type = AlicizaX.Utility.Assembly.GetType(typeName);
if (type != null && TryReflectAndRegister(type, out info))
return true;
info = default;
return false;
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool TryReflectAndRegister(Type uiType, out UIMetaInfo info)
{
Log.Warning($"[UI] UI未注册[{uiType.FullName}] 反射进行缓存");
Type baseType = uiType;
Type? holderType = baseType.GetGenericArguments()[0];
UILayer layer = UILayer.UI;
bool fullScreen = false;
int cacheTime = 0;
var cad = CustomAttributeData.GetCustomAttributes(uiType)
.FirstOrDefault(a => a.AttributeType.Name == nameof(WindowAttribute));
if (cad != null)
{
var args = cad.ConstructorArguments;
if (args.Count > 0) layer = (UILayer)(args[0].Value ?? UILayer.UI);
if (args.Count > 1) fullScreen = (bool)(args[1].Value ?? false);
if (args.Count > 2) cacheTime = (int)(args[2].Value ?? 0);
}
if (holderType != null)
{
Register(uiType, holderType, layer, fullScreen, cacheTime);
info = _typeHandleMap[uiType.TypeHandle];
return true;
}
info = default;
return false;
}
}
}