using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using TeamAAS.Communication.Interfaces; using TeamAAS.Communication.LightSources; namespace TeamAAS.Communication { /// /// 光源管理器。懒汉单例:LightSourceManager.Instance。 /// 提供两种使用模式: /// 1) 直接调用:传入 serialDeviceName + LightModel,内部 new 临时 controller 执行完即释放; /// 2) 长期持有:通过 Register/Get/Remove 管理命名 controller,适合 UI 长期绑定场景。 /// 同时保留静态工具方法(GetChannelCount/GetProtocolName)供反射或下拉框使用。 /// public class LightSourceManager { #region 单例 private static readonly Lazy _instance = new Lazy(() => new LightSourceManager(), isThreadSafe: true); /// /// 懒汉单例入口。首次访问时初始化,线程安全。 /// public static LightSourceManager Instance => _instance.Value; #endregion #region 长期持有的控制器池 private readonly object _poolLock = new object(); private readonly Dictionary _pool = new Dictionary(); /// /// 注册一个长期持有的光源控制器(按 name 索引)。 /// 已存在同名 controller 会先 Dispose 旧的再替换。 /// public LightSourceController Register(string name, LightModel model, ICommunication comm) { if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("name 不能为空", nameof(name)); if (comm == null) throw new ArgumentNullException(nameof(comm)); var controller = new LightSourceController(model, GetChannelCount(model)) { Name = name }; controller.AttachCommunication(comm); LightSourceController old = null; lock (_poolLock) { if (_pool.TryGetValue(name, out old)) _pool[name] = controller; else _pool.Add(name, controller); } if (old != null && !ReferenceEquals(old, controller)) { try { old.Disconnect(); } catch { } try { old.Dispose(); } catch { } } return controller; } /// /// 获取已注册的光源控制器(按 name)。不存在返回 null。 /// public LightSourceController Get(string name) { if (string.IsNullOrWhiteSpace(name)) return null; lock (_poolLock) { return _pool.TryGetValue(name, out var c) ? c : null; } } /// /// 移除并释放已注册的光源控制器。 /// public bool Remove(string name) { if (string.IsNullOrWhiteSpace(name)) return false; LightSourceController controller; lock (_poolLock) { if (!_pool.TryGetValue(name, out controller)) return false; _pool.Remove(name); } if (controller != null) { try { controller.Disconnect(); } catch { } try { controller.Dispose(); } catch { } } return true; } /// /// 获取所有已注册控制器的快照。 /// public IReadOnlyList GetAll() { lock (_poolLock) { return _pool.Values.ToList().AsReadOnly(); } } /// /// 清空并释放所有已注册控制器。 /// public void Clear() { List snapshot; lock (_poolLock) { snapshot = _pool.Values.ToList(); _pool.Clear(); } foreach (var c in snapshot) { try { c.Disconnect(); } catch { } try { c.Dispose(); } catch { } } } #endregion #region 直接操作模式(按需 new 临时 controller) /// /// 直接设置亮度(不长期持有 controller)。 /// public async Task SetBrightnessAsync(string serialDeviceName, LightModel model, int channel, int brightness, int timeoutMs = 1000) { var comm = ResolveCommunication(serialDeviceName); if (comm == null) return false; int channelCount = GetChannelCount(model); var controller = new LightSourceController(model, channelCount); try { controller.AttachCommunication(comm); return await controller.SetBrightnessAsync(channel, brightness, timeoutMs); } finally { controller.Dispose(); } } /// /// 直接全开(不长期持有 controller)。 /// public async Task TurnOnAllAsync(string serialDeviceName, LightModel model, int timeoutMs = 1000) { var comm = ResolveCommunication(serialDeviceName); if (comm == null) return false; int channelCount = GetChannelCount(model); var controller = new LightSourceController(model, channelCount); try { controller.AttachCommunication(comm); return await controller.TurnOnAllAsync(timeoutMs); } finally { controller.Dispose(); } } /// /// 直接全关(不长期持有 controller)。 /// public async Task TurnOffAllAsync(string serialDeviceName, LightModel model, int timeoutMs = 1000) { var comm = ResolveCommunication(serialDeviceName); if (comm == null) return false; int channelCount = GetChannelCount(model); var controller = new LightSourceController(model, channelCount); try { controller.AttachCommunication(comm); return await controller.TurnOffAllAsync(timeoutMs); } finally { controller.Dispose(); } } /// /// 直接读取某通道亮度(不长期持有 controller)。 /// public async Task ReadBrightnessAsync(string serialDeviceName, LightModel model, int channel, int timeoutMs = 1000) { var comm = ResolveCommunication(serialDeviceName); if (comm == null) return 0; int channelCount = GetChannelCount(model); var controller = new LightSourceController(model, channelCount); try { controller.AttachCommunication(comm); return await controller.ReadBrightnessAsync(channel, timeoutMs); } finally { controller.Dispose(); } } private ICommunication ResolveCommunication(string serialDeviceName) { if (string.IsNullOrWhiteSpace(serialDeviceName)) return null; var comm = CommunicationManager.Instance.GetByName(serialDeviceName); return comm?.IsConnected == true ? comm : null; } #endregion #region 静态工具方法 /// /// 根据型号获取通道数量 /// public static int GetChannelCount(LightModel model) { switch (model) { case LightModel.KCS_KDC_12V60W_4T: return 4; case LightModel.KCS_KDC3_24V300W_8T: return 8; case LightModel.TSD_DPA12024V_4T_3_0: return 4; default: return 4; } } /// /// 根据型号获取协议名称 /// public static string GetProtocolName(LightModel model) { switch (model) { case LightModel.KCS_KDC_12V60W_4T: case LightModel.KCS_KDC3_24V300W_8T: return "KCS"; case LightModel.TSD_DPA12024V_4T_3_0: return "TSD"; default: return "Unknown"; } } #endregion } }