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;
}
}
}