using System; using System.Collections.Generic; using System.Reflection; using Data; using EventWorkClass; using Utils; using UnityEngine; namespace Managers { /// /// 事件管理器,负责事件的加载、注册和执行。 /// 遵循单例模式,并在启动流程中扮演一个管理器角色。 /// class EventManager : Singleton, ILaunchManager { /// /// 存储所有已加载的事件定义,键为事件名称,值为对应的事件工作类实例。 /// public Dictionary EventDefs { get; private set; } = null; /// /// 获取当前加载步骤的描述,用于启动流程的进度显示。 /// public string StepDescription => "正在载入事件"; /// /// 初始化事件管理器,从定义管理器中加载所有事件定义并实例化其工作类。 /// public void Init() { // 如果事件定义已经加载,则直接返回,避免重复初始化。 if (EventDefs != null) return; var defs = DefineManager.Instance.QueryDefinesByType(); EventDefs = new Dictionary(); foreach (var def in defs) { if (EventDefs.ContainsKey(def.defName)) { Debug.LogWarning($"警告:事件名称重复,已跳过加载名称为 {def.defName} 的事件定义。"); continue; } var eventWorker = GetAndInstantiateEventWorker(def.workClass); if (eventWorker == null) { Debug.LogWarning($"警告:未能找到或实例化名称为 '{def.workClass}' 的事件工作类,已跳过加载名称为 '{def.defName}' 的事件定义。"); continue; } eventWorker.Init(def.value); EventDefs.Add(def.defName, eventWorker); } Debug.Log($"事件管理器初始化完成,共载入 {EventDefs.Count} 个事件。"); } /// /// 清理事件管理器,释放所有已加载的事件定义。 /// public void Clear() { EventDefs = null; Debug.Log("事件管理器已清理。"); } /// /// 执行指定名称的事件。 /// /// 要执行的事件的名称。 /// 事件执行的维度ID,如果为null,将使用当前焦点的维度ID。 public void Action(string eventName, string dimensionID = null) { if (EventDefs == null) { Debug.LogError($"错误:事件管理器尚未初始化或已被清理。无法执行事件 '{eventName}'。"); return; } if (!EventDefs.ContainsKey(eventName)) { Debug.LogWarning($"警告:未能找到名称为 '{eventName}' 的事件定义,已跳过执行该事件。"); return; } // 假设 Program.Instance 和 FocusedDimensionId 存在且可访问。 // 如果 dimensionID 为 null,则使用当前焦点维度ID。 dimensionID ??= Program.Instance.FocusedDimensionId; EventDefs[eventName].Run(dimensionID); } /// /// 根据类名从指定命名空间和程序集下获取并实例化一个 的子类。 /// /// 要实例化的类的短名称(不包含命名空间)。 /// 目标类所在的完整命名空间。 /// 要搜索的程序集。如果为 null,将搜索 所在的程序集。 /// 实例化后的 对象,如果找不到或不符合条件则返回 null。 public static EventWorkClassBase GetAndInstantiateEventWorker( string className, string targetNamespace = "EventWorkClass", // 默认命名空间 Assembly assemblyToSearch = null) // 默认程序集 { // 1. 确定要搜索的程序集。 if (assemblyToSearch == null) { // 默认从 EventWorkClassBase 所在的程序集查找,通常其实现类也会在这个程序集。 assemblyToSearch = typeof(EventWorkClassBase).Assembly; } // 2. 构造完整的类型名称。 string fullTypeName = $"{targetNamespace}.{className}"; Type targetType = null; // 3. 尝试直接从程序集获取类型。 targetType = assemblyToSearch.GetType(fullTypeName); // 4. 进行类型检查。 if (targetType == null) { Debug.LogError($"错误:在程序集 '{assemblyToSearch.FullName}' 的命名空间 '{targetNamespace}' 中未找到类 '{className}'。"); return null; } // 检查是否是 EventWorkClassBase 的子类。 if (!typeof(EventWorkClassBase).IsAssignableFrom(targetType)) { Debug.LogError($"错误:类 '{fullTypeName}' 不是 '{typeof(EventWorkClassBase).FullName}' 的子类。"); return null; } // 检查是否可以实例化(非抽象类,非接口)。 if (targetType.IsAbstract || targetType.IsInterface) { Debug.LogError($"错误:类 '{fullTypeName}' 是抽象类或接口,不能直接实例化。"); return null; } // 5. 实例化对象。 try { // 使用 Activator.CreateInstance 实例化对象。它默认调用无参公共构造函数。 object instance = Activator.CreateInstance(targetType); return instance as EventWorkClassBase; } catch (MissingMethodException ex) { Debug.LogError($"错误:类 '{fullTypeName}' 没有公共的无参构造函数。详情: {ex.Message}"); return null; } catch (Exception ex) { Debug.LogError($"实例化类 '{fullTypeName}' 时发生未知错误。详情: {ex.Message}"); return null; } } } }