using System; using System.Collections.Generic; using System.Linq; using System.Threading; namespace TeamAAS.Vision { /// /// 视觉引擎管理器(懒汉单例,Lazy 线程安全)。 /// /// 职责: /// 1. 引擎探测(Discover):通过通用模块扫描器(AssemblyScanner)收集 /// IVisualEngine 实现——插件 DLL 由 PluginLoader 在启动时加载进 AppDomain /// (Runtime\Plugins 目录),无需硬编码已知引擎程序集列表; /// 2. 引擎切换(SetCurrent):按配置的 EngineName 一键切换; /// 3. 引擎取用(GetOrLoad):按名称取引擎,找不到回退第一个。 /// /// 引擎实现位于各引擎插件类库(如 Plugins.Vpp),本管理器只依赖抽象接口, /// 引擎 SDK 的加载与解析由插件体系完成 —— 引擎可整体替换,宿主零改动。 /// public sealed class VisualEngineManager { /// 懒汉单例:首次访问 Instance 时才创建(Lazy 默认 ExecutionAndPublication 线程安全) private static readonly Lazy _lazy = new Lazy(() => new VisualEngineManager(), LazyThreadSafetyMode.ExecutionAndPublication); /// 全局单例入口 public static VisualEngineManager Instance => _lazy.Value; private readonly List _engines = new List(); private bool _discovered; private VisualEngineManager() { } /// /// 反射创建 AppDomain 内全部 IVisualEngine 实现实例(无参构造;构造失败跳过)。 /// 自包含实现,不依赖外部扫描器(原 Global 的 AssemblyScanner)——引擎插件 DLL /// 由 PluginLoader 在启动时先行加载进 AppDomain,故此处直接扫描已加载程序集即可。 /// private static IEnumerable CreateEngineInstances() { foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { Type[] types; try { types = asm.GetTypes(); } catch (System.Reflection.ReflectionTypeLoadException ex) { types = ex.Types?.Where(t => t != null).ToArray() ?? Type.EmptyTypes; } catch { continue; } foreach (var t in types) { if (t == null || t.IsAbstract || t.IsInterface || t.IsGenericTypeDefinition) continue; if (!typeof(IVisualEngine).IsAssignableFrom(t)) continue; IVisualEngine inst; try { inst = Activator.CreateInstance(t) as IVisualEngine; } catch (Exception ex) { // 引擎 SDK 运行库缺失等 → 跳过该实现;Debug 输出便于诊断“引擎没起来/主页画面空白” System.Diagnostics.Debug.WriteLine($"[VisualEngine] 引擎 {t.FullName} 实例化失败,已跳过: {ex.Message}"); continue; } if (inst != null) yield return inst; } } } /// 探测到的全部可用引擎 public IReadOnlyList Engines => _engines; /// 当前生效引擎(配置里的 EngineName;未配置/未找到时为第一个) public IVisualEngine Current { get; private set; } /// 引擎是否已探测完成(避免宿主过早取用) public bool Discovered => _discovered; /// 引擎清单变化通知 public event Action EnginesChanged; /// 执行探测(幂等,可重复调用) public void Discover() { if (_discovered) return; _discovered = true; // 通用模块扫描:收集全部 IVisualEngine 实现(EngineName 去重由本管理器负责) foreach (var engine in CreateEngineInstances()) { if (_engines.Any(e => e.EngineName == engine.EngineName)) continue; _engines.Add(engine); } EnginesChanged?.Invoke(); } /// 按名称取引擎;找不到时回退第一个,完全没有引擎返回 null。 public IVisualEngine GetOrLoad(string engineName) { if (_engines.Count == 0) return null; var match = _engines.FirstOrDefault(e => string.Equals(e.EngineName, engineName, StringComparison.OrdinalIgnoreCase)); return match ?? _engines[0]; } /// 切换当前引擎(一键切换);名称不存在返回 false。 public bool SetCurrent(string engineName) { var engine = _engines.FirstOrDefault(e => string.Equals(e.EngineName, engineName, StringComparison.OrdinalIgnoreCase)); if (engine == null) return false; Current = engine; return true; } } }