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