using System; using System.Collections.Generic; using AlicizaX.Runtime; namespace AlicizaX.UI.Runtime { public static class MetaTypeCache where T : UIBase { public static readonly UIMetadata Metadata; static MetaTypeCache() { var type = typeof(T); Metadata = type.IsSubclassOf(typeof(UIWidget)) ? UIMetadataFactory.GetWidgetInfo(type.TypeHandle) : UIMetadataFactory.GetWindowInfo(type.TypeHandle); } } internal static class UIMetadataFactory { private static readonly Dictionary UIWindowMetadata = new(); private static readonly Dictionary UIWidgetMetadata = new(); internal static UIMetadata GetWindowInfo(RuntimeTypeHandle handle) { if (!UIWindowMetadata.TryGetValue(handle, out var meta)) { meta = GetWindowAttributeInfo(Type.GetTypeFromHandle(handle)); UIWindowMetadata[handle] = meta; } return meta; } internal static UIMetadata GetWidgetInfo(RuntimeTypeHandle handle) { if (!UIWidgetMetadata.TryGetValue(handle, out var meta)) { meta = CreateWidgetMetadata(Type.GetTypeFromHandle(handle)); UIWidgetMetadata[handle] = meta; } return meta; } private static UIMetadata CreateWidgetMetadata(Type type) { if (!type.IsSubclassOf(typeof(UIWidget))) throw new InvalidOperationException($"Invalid type: {type.Name}"); return new UIMetadata(type); } private static UIMetadata GetWindowAttributeInfo(Type uiType) { if (!uiType.IsSubclassOf(typeof(UIWindow))) throw new InvalidOperationException($" {uiType.FullName} not SubClass Of UIWindow"); WindowAttribute windowAttribute = Attribute.GetCustomAttribute(uiType, typeof(WindowAttribute)) as WindowAttribute; if (windowAttribute == null) throw new GameFrameworkException($"Window {uiType.FullName} WindowAttribute can be null."); return new UIMetadata(uiType, windowAttribute.WindowLayer, windowAttribute.FullScreen, windowAttribute.CacheTime); } } }