using System; using System.Collections.Generic; using System.IO; using System.Linq; using Newtonsoft.Json; using TeamAAS.Global.Devices; using TeamAAS.Motion.AdapterFactorys; using TeamAAS.Motion.Interfaces; using TeamAAS.Motion.Models; using TeamAAS.Motion.Motions; namespace TeamAAS.Motion { /// /// 运动控制设备管理器(懒汉单例)。 /// 职责:加载/保存 Config\MotionDevices.json;按配置实例化品牌适配器(仿真/雷赛/固高/IMC60G/GR20T); /// 对上层(主程序状态栏、流程节点、调试页)提供统一的 IMotionCard/IIOCard 访问。 /// 与 CameraManager/RobotManager 同构:App 启动时 LoadConfig,退出时 CloseAll。 /// public class MotionManager { private static MotionManager _instance; public static MotionManager Instance => _instance ?? (_instance = new MotionManager()); private DevicePluginManager _DevicePluginManager=new DevicePluginManager(); public DevicePluginManager DevicePluginManager { get => _DevicePluginManager; set => _DevicePluginManager = value; } private readonly object _sync = new object(); /// 全部运动/IO 设备实例(含运动卡与 IO 卡)。 public List Devices { get; } = new List(); /// 设备配置列表(与 Devices 一一对应)。 public List Configs { get; private set; } = new List(); /// /// 配置文件路径(Config\MotionDevices.json)。 /// 由系统配置文件的目录派生(SystemConfigurationFile 在 Config\ 下),不引入新的 PathHelper 成员。 /// public static string ConfigPath { get { var sysCfg = TeamAAS.PathHelper.SystemConfigurationFile; var dir = string.IsNullOrEmpty(sysCfg) ? AppDomain.CurrentDomain.BaseDirectory : Path.GetDirectoryName(sysCfg); return Path.Combine(dir ?? "", "MotionDevices.json"); } } /// /// 从配置实例化全部设备(已存在实例时先释放)。仅创建,不自动连接。 /// public void LoadConfig() { lock (_sync) { CloseAllUnsafe(); try { if (File.Exists(ConfigPath)) { var json = File.ReadAllText(ConfigPath); Configs = JsonConvert.DeserializeObject>(json) ?? new List(); } } catch { Configs = new List(); } foreach (var cfg in Configs) { var dev = CreateDevice(cfg); if (dev != null) Devices.Add(dev); } } } /// 保存配置到 Config\MotionDevices.json。 public bool SaveConfig() { lock (_sync) { try { var dir = Path.GetDirectoryName(ConfigPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) Directory.CreateDirectory(dir); File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(Configs, Formatting.Indented)); return true; } catch (Exception ex) { AppLogger.Error("运动设备配置保存失败", ex, nameof(MotionManager)); } return false; } } /// 按名称取运动卡。 public IMotionControl GetMotion(string name) => Devices.OfType().FirstOrDefault(d => string.Equals(d.CardName, name, StringComparison.OrdinalIgnoreCase)); /// 按名称取 IO 卡。 public IIOCard GetIO(string name) => Devices.OfType().FirstOrDefault(d => string.Equals(d.Name, name, StringComparison.OrdinalIgnoreCase)); /// 断开并清空全部设备(App 退出时调用)。 public void CloseAll() { lock (_sync) { CloseAllUnsafe(); } } private void CloseAllUnsafe() { foreach (var d in Devices) { try { (d as IConnectableDevice)?.Close(); } catch { } } Devices.Clear(); } /// /// 按配置创建设备实例(品牌适配器工厂)。 /// 新品牌接入:实现 IMotionCard/IIOCard → 在此 switch 增加分支即可。 /// public object CreateDevice(MotionDeviceConfig cfg) { IDeviceAdapterFactory Devicefactory= Instance.DevicePluginManager.GetFactory(cfg); if ( Devicefactory != null ) { IMotionControl motion= Devicefactory.Create(cfg); if ( motion != null ) { Devices.Add(motion); return motion; } } AppLogger.Info("该品牌还未适配"); return null; } public void RemoveDevice(MotionDeviceConfig cfg) { GetMotion(cfg.Name).Disconnect(); Devices.Remove(cfg); } } }