using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; namespace XericUI.ReflectionUIGenerator { /// /// 元数据集 /// 包含从对象反射提取的完整元数据,以及用于生成 MVVM 绑定的 BuildMDVM() 方法 /// public class AvrgMemberMetaDataSet { private List _metaDataList = new List(); /// /// 只读访问元数据列表 /// public IReadOnlyList MetaDataList => _metaDataList; /// /// 添加元数据 /// public void Add(AvrgMemberMetaData metaData) { _metaDataList.Add(metaData); } /// /// 处理编组合并 — 将 GroupPath 相同的元数据合并 /// 非编组元数据保持为独立 Entry /// internal void MergeGroupEntries() { // 提取编组和非编组 var grouped = _metaDataList .Where(m => !string.IsNullOrEmpty(m.GroupPath)) .GroupBy(m => m.GroupPath) .ToList(); var nonGrouped = _metaDataList .Where(m => string.IsNullOrEmpty(m.GroupPath)) .ToList(); var merged = new List(); foreach (var gEntry in grouped) { // 编组内第一个成员作为主元数据 var first = gEntry.First(); first.SubMetaDataList ??= new List(); foreach (var member in gEntry) { if (member == first) continue; // 成员自身的 Split 子属性合并到父级 if (member.SubMetaDataList?.Count > 0) first.SubMetaDataList.AddRange(member.SubMetaDataList); // Merge: 成员自身作为子属性加入,保留独立 MemberInfo/TargetInstance first.SubMetaDataList.Add(member); } merged.Add(first); } // 非编组直接追加 merged.AddRange(nonGrouped); _metaDataList = merged; } /// /// 按 FieldOrder 排序 /// internal void SortByFieldOrder() { _metaDataList.Sort((a, b) => { int orderCompare = a.FieldOrder.CompareTo(b.FieldOrder); if (orderCompare != 0) return orderCompare; return string.Compare(a.MemberName, b.MemberName, StringComparison.Ordinal); }); } /// /// 为元数据生成对应的 MVVM 值绑定模板 /// /// 可选的业务目标对象(如果元数据中没有绑定目标,则在此传入) /// 可选的冲突解决配置 /// 绑定集合 public AvrgMvvmBindingCollection BuildMDVM( object businessTarget = null, AvrgMvvmResolverConfig resolverConfig = null) { var bindingCollection = new AvrgMvvmBindingCollection(); var scheduler = new AvrgMvvmScheduler(resolverConfig); foreach (var metaData in _metaDataList) { // 确定目标实例 var target = metaData.TargetInstance ?? businessTarget; if (target == null) continue; // 创建主绑定 var binding = new AvrgMvvmBinding { MetaData = metaData, ReadFunc = () => metaData.GetValue(), }; var capturedBinding = binding; binding.WriteAction = (val) => { metaData.SetValue(val); scheduler.MarkDataDirty(capturedBinding); }; // 如果元数据有拆分子属性,创建子绑定 if (metaData.SubMetaDataList?.Count > 0) { binding.SubBindings = new List(); foreach (var subMetaData in metaData.SubMetaDataList) { var subBinding = new AvrgMvvmBinding { MetaData = subMetaData, }; // Merge 路径:子字段有自己的 MemberInfo/TargetInstance(来自编组成员) if (subMetaData.MemberInfo != null && subMetaData.TargetInstance != null) { var capturedSub = subMetaData; subBinding.ReadFunc = () => capturedSub.GetValue(); subBinding.WriteAction = (val) => { capturedSub.SetValue(val); scheduler.MarkDataDirty(capturedBinding); }; } // Split 路径:通过 PropertyPath 从父值访问(来自 XuiavrgSplit) else if (!string.IsNullOrEmpty(subMetaData.PropertyPath)) { string subPath = subMetaData.PropertyPath; subBinding.ReadFunc = () => ReadSubProperty(metaData.GetValue(), subPath); subBinding.WriteAction = (val) => { var parentVal = metaData.GetValue(); var modifiedParent = WriteSubProperty(parentVal, subPath, val); metaData.SetValue(modifiedParent); scheduler.MarkDataDirty(capturedBinding); }; } else { continue; // 无法创建绑定,跳过 } binding.SubBindings.Add(subBinding); } } // 注册到调度器 scheduler.Register(binding); bindingCollection.Add(binding); } bindingCollection.AttachScheduler(scheduler); return bindingCollection; } // ============ 子属性访问辅助方法 ============ /// /// 从父值中读取子属性(支持单层路径如 "x"、"y") /// 例如:ReadSubProperty(Vector2(1,2), "x") → 1f /// private static object ReadSubProperty(object parentValue, string propertyPath) { if (parentValue == null || string.IsNullOrEmpty(propertyPath)) return null; // 仅支持单层路径 if (propertyPath.Contains('/')) { Debug.LogWarning($"[Xuiavrg] 暂不支持多层嵌套路径 '{propertyPath}'"); return null; } var type = parentValue.GetType(); var field = type.GetRuntimeField(propertyPath); if (field != null) return field.GetValue(parentValue); var prop = type.GetRuntimeProperty(propertyPath); if (prop != null) return prop.GetValue(parentValue); Debug.LogWarning($"[Xuiavrg] 在类型 '{type.Name}' 上找不到子属性 '{propertyPath}'"); return null; } /// /// 修改父值中的子属性并返回修改后的父值 /// 适用于值类型(struct)和引用类型 /// private static object WriteSubProperty(object parentValue, string propertyPath, object value) { if (parentValue == null || string.IsNullOrEmpty(propertyPath)) return parentValue; if (propertyPath.Contains('/')) { Debug.LogWarning($"[Xuiavrg] 暂不支持多层嵌套路径 '{propertyPath}'"); return parentValue; } var type = parentValue.GetType(); var field = type.GetRuntimeField(propertyPath); if (field != null) { field.SetValue(parentValue, value); return parentValue; } var prop = type.GetRuntimeProperty(propertyPath); if (prop != null && prop.CanWrite) { prop.SetValue(parentValue, value); return parentValue; } Debug.LogWarning($"[Xuiavrg] 在类型 '{type.Name}' 上找不到可写的子属性 '{propertyPath}'"); return parentValue; } // ============ 验证方法 ============ /// /// 对当前元数据集执行属性检查验证 /// /// 值范围配置(可选,不传入则不执行范围检查) /// 验证结果集合 public AvrgValidationResultSet Validate(AvrgValueRangeConfig valueRangeConfig = null) { var resultSet = new AvrgValidationResultSet(); foreach (var metaData in _metaDataList) { if (metaData.Hide) continue; // 只有标记了 PropertyCheck 的才验证 if (!metaData.Required && !metaData.ValidateReasonable && !metaData.ValidateWarning && !metaData.ValidateInvalid) { resultSet.Results.Add(new AvrgMemberValidationResult { MetaData = metaData, Result = AvrgMemberCheckResult.Skipped, CurrentValueString = metaData.GetValue()?.ToString(), Message = "未标记属性检查", }); continue; } var value = metaData.GetValue(); var checkResult = CheckSingleMember(metaData, value, valueRangeConfig); resultSet.Results.Add(checkResult); } return resultSet; } /// /// 验证单个成员 /// private AvrgMemberValidationResult CheckSingleMember( AvrgMemberMetaData metaData, object value, AvrgValueRangeConfig rangeConfig) { var result = new AvrgMemberValidationResult { MetaData = metaData, CurrentValueString = value?.ToString() ?? "(null)", }; // 根据 CheckKey 查找值范围规则 AvrgValueRangeEntry rangeEntry = null; string checkKey = !string.IsNullOrEmpty(metaData.PropertyCheckKey) ? metaData.PropertyCheckKey : metaData.ValueType?.FullName; if (rangeConfig != null && !string.IsNullOrEmpty(checkKey)) { rangeEntry = rangeConfig.FindEntry(checkKey); } // ——— 优先级 1: 空值检查 (Required) ——— if (metaData.Required) { bool isEmpty = false; // 引用类型 null if (value == null) { isEmpty = true; } // 字符串 null/空 else if (value is string str) { isEmpty = string.IsNullOrEmpty(str); } // 使用 ValueRangeEntry 的 IsEmpty 判断 else if (rangeEntry != null && !rangeEntry.skipEmptyCheck) { isEmpty = rangeEntry.IsEmpty(value); } if (isEmpty) { result.Result = AvrgMemberCheckResult.Empty; result.Message = $"必填字段 '{metaData.MemberName}' 为空"; return result; } } // 如果没有范围配置,无法继续检查 if (rangeEntry == null) { result.Result = AvrgMemberCheckResult.Valid; result.Message = "通过(无范围配置)"; return result; } // ——— 优先级 2: 合理值检查(最高优先级,命中即通过) ——— if (metaData.ValidateReasonable && rangeEntry.IsReasonable(value)) { result.Result = AvrgMemberCheckResult.Valid; result.Message = "值在合理范围内"; return result; } // ——— 优先级 3: 无效值检查 ——— if (metaData.ValidateInvalid && rangeEntry.IsInvalid(value)) { result.Result = AvrgMemberCheckResult.Invalid; result.Message = $"值 {value} 在无效范围内"; return result; } // ——— 优先级 4: 警告值检查 ——— if (metaData.ValidateWarning && rangeEntry.IsWarning(value)) { result.Result = AvrgMemberCheckResult.Warning; result.Message = $"值 {value} 在警告范围内"; return result; } // ——— 最终: 通过 ——— result.Result = AvrgMemberCheckResult.Valid; result.Message = "通过"; return result; } } }