using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; using UnityEngine.UIElements; namespace BITKit.UX { [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class UXBindPathAttribute : Attribute { public string Path; public bool CanBeNull; public UXBindPathAttribute() { } public UXBindPathAttribute(string path) { Path = path; } public UXBindPathAttribute(string path, bool canBeNull) { Path = path; CanBeNull = canBeNull; } } public class UXUtils { public static void Inject(object self,VisualElement root=null) { UIDocument document = null; var field = self.GetType().GetField("document", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var rootVisualElementFieldInfo = self.GetType().GetField("RootVisualElement", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var rootVisualElementPropertyInfo = self.GetType().GetProperty("RootVisualElement", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); var rootVisualElement = (rootVisualElementFieldInfo, rootVisualElementPropertyInfo) switch { { } when rootVisualElementPropertyInfo?.GetValue(self) is VisualElement ve => ve, { } when rootVisualElementFieldInfo?.GetValue(self) is VisualElement ve => ve, _ => root, }; if (rootVisualElement is not null) { } else { switch (field) { case null when self is MonoBehaviour monoBehaviour && monoBehaviour.TryGetComponent(out document): break; case not null when field.GetValue(self) is UIDocument _document: document = _document; break; default: BIT4Log.Warning($"document 未赋值或未找到@{self.GetType().Name}"); return; } } foreach (var fieldInfo in self.GetType() .GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly) .Where(x => x.GetCustomAttribute() is not null) ) { var bindPathAtt = fieldInfo.GetCustomAttribute(); VisualElement ve = (document, rootVisualElement) switch { (_, not null) => rootVisualElement, (not null, _) => document.rootVisualElement, _ => throw new NotImplementedException(), }; foreach (var path in bindPathAtt.Path.Split(".")) { ve = ve.Q(path); } //ve = document.rootVisualElement.Q(bindPathAtt.Path); if (bindPathAtt.CanBeNull is false && ve is null) BIT4Log.LogException(new NullReferenceException($"{self.GetType().Name},{rootVisualElement.name}上未找到{bindPathAtt.Path}")); try { fieldInfo.SetValue(self, ve); } catch (Exception e) { BIT4Log.Warning(fieldInfo!.Name); } } } } }