using System; using System.Collections.Generic; using System.Reflection; using UnityEngine; namespace BaseGames.AI { /// /// 反射收集所有 [AiDefinition] 的 AiScript 子类,按 id 提供共享 AiGraph(flyweight)。 /// 同一 id 全实例共享同一 AiScript 实例 → 同一张不可变 AiGraph。 /// public static class AiDefinitionRegistry { static Dictionary _byId; // 项目已关闭 Domain Reload:静态缓存需在进入播放时重置,保证按最新类型重建。 [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void ResetOnPlay() => _byId = null; static void EnsureBuilt() { if (_byId != null) return; _byId = new Dictionary(); foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { Type[] types; try { types = asm.GetTypes(); } catch (ReflectionTypeLoadException e) { types = e.Types; } if (types == null) continue; for (int i = 0; i < types.Length; i++) { var t = types[i]; if (t == null || t.IsAbstract || !typeof(AiScript).IsAssignableFrom(t)) continue; var attr = t.GetCustomAttribute(); if (attr == null) continue; if (_byId.ContainsKey(attr.Id)) throw new InvalidOperationException( $"AiDefinitionRegistry: 重复的 AI 定义 id '{attr.Id}'({t.FullName})。"); _byId[attr.Id] = (AiScript)Activator.CreateInstance(t); } } } public static bool Has(string id) { EnsureBuilt(); return _byId.ContainsKey(id); } /// 取 id 对应的共享 AiGraph;不存在则显式抛错(根因暴露,不做兜底)。 public static AiGraph GetGraph(string id) => GetDefinition(id).GetOrBuildGraph(); /// 取 id 对应的定义;不存在则显式抛错(根因暴露,不做兜底)。 public static IAiDefinition GetDefinition(string id) { EnsureBuilt(); if (!_byId.TryGetValue(id, out var script)) throw new InvalidOperationException( $"AiDefinitionRegistry: 未找到 AI 定义 id '{id}'。请确认存在 [AiDefinition(\"{id}\")] 的 AiScript 子类。"); return script; } public static IEnumerable Ids { get { EnsureBuilt(); return _byId.Keys; } } } }