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.Models; namespace TeamAAS.Motion { 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(); public List Devices { get; } = new List(); public List Configs { get; private set; } = new List(); 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(); } else { Configs = new List(); } } catch { Configs = new List(); } foreach (var cfg in Configs) { var dev = CreateDevice(cfg); if (dev != null) Devices.Add(dev); } } } 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 IMotionCard GetMotion(string name) => Devices.OfType() .FirstOrDefault(d => string.Equals(d.Name, name, StringComparison.OrdinalIgnoreCase)); public IIOCard GetIO(string name) => Devices.OfType() .FirstOrDefault(d => string.Equals(d.Name, name, StringComparison.OrdinalIgnoreCase)); public void CloseAll() { lock (_sync) { CloseAllUnsafe(); } } private void CloseAllUnsafe() { foreach (var d in Devices) { try { if (d is IMotionCard motion) motion.Close(); else (d as IConnectableDevice)?.Close(); } catch { } } Devices.Clear(); } public object CreateDevice(MotionDeviceConfig cfg) { if (cfg == null) return null; var factory = DevicePluginManager.GetFactory(cfg); if (factory == null) { AppLogger.Info($"未找到运动适配器: {cfg.AdapterKey}"); return null; } return factory.Create(cfg); } public bool AddDevice(MotionDeviceConfig cfg) { if (cfg == null || string.IsNullOrWhiteSpace(cfg.Name)) return false; lock (_sync) { if (Configs.Any(c => string.Equals(c.Name, cfg.Name, StringComparison.OrdinalIgnoreCase))) return false; var dev = CreateDevice(cfg); if (dev == null) return false; Configs.Add(cfg); Devices.Add(dev); return SaveConfig(); } } public bool RemoveDevice(MotionDeviceConfig cfg) { if (cfg == null) return false; lock (_sync) { var motion = GetMotion(cfg.Name); try { motion?.Close(); } catch { } if (motion != null) Devices.Remove(motion); Configs.RemoveAll(c => string.Equals(c.Name, cfg.Name, StringComparison.OrdinalIgnoreCase)); return SaveConfig(); } } } }