LightControllerBase.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using TeamAAS_VP.Models.Lights;
  7. namespace TeamAAS_VP.Core.Lights
  8. {
  9. /// <summary>
  10. /// 光源控制器基类。
  11. /// 提供通用的光源控制和通道管理能力,具体控制器应从此类继承并实现硬件相关逻辑。
  12. /// </summary>
  13. public abstract class LightControllerBase : ILightController
  14. {
  15. /// <summary>
  16. /// 控制器唯一标识(只读)。
  17. /// </summary>
  18. public int Id { get; }
  19. /// <summary>
  20. /// 控制器名称,可用于显示或日志记录。
  21. /// </summary>
  22. public string Name { get; set; }
  23. /// <summary>
  24. /// 光源模型信息(只读),用于指示此控制器对应的光源类型或型号。
  25. /// </summary>
  26. public LightModel Model { get; }
  27. /// <summary>
  28. /// 控制器支持的通道数量(只读)。
  29. /// </summary>
  30. public int ChannelCount { get; }
  31. /// <summary>
  32. /// 控制器配置(只读)。
  33. /// </summary>
  34. public LightControllerConfig Config { get; }
  35. /// <summary>
  36. /// 指示控制器当前是否与设备连接。派生类应在连接/断开时维护此状态。
  37. /// </summary>
  38. public bool IsConnected { get; protected set; }
  39. /// <summary>
  40. /// 内部维护的通道列表(可变)。派生类或内部实现可通过此集合管理通道。
  41. /// </summary>
  42. protected List<ILightChannel> ChannelsInternal { get; }
  43. /// <summary>
  44. /// 对外只读的通道集合,外部调用者只能读取,不可修改通道集合本身。
  45. /// </summary>
  46. public IReadOnlyList<ILightChannel> Channels => ChannelsInternal;
  47. /// <summary>
  48. /// 构造函数:根据指定的 id 和通道数量初始化控制器实例并创建通道集合。
  49. /// </summary>
  50. /// <param name="id">控制器标识符。</param>
  51. /// <param name="channelCount">通道数量,必须为非负整数。</param>
  52. /// <param name="config">控制器配置。</param>
  53. protected LightControllerBase(int id,int channelCount, LightControllerConfig config)
  54. {
  55. Id = id;
  56. ChannelCount = channelCount;
  57. ChannelsInternal = new List<ILightChannel>();
  58. Config = config;
  59. InitializeChannels();
  60. }
  61. /// <summary>
  62. /// 初始化通道集合,根据 <see cref="ChannelCount"/> 调用 <see cref="CreateChannel(int)"/> 创建每个通道。
  63. /// 私有方法,在构造期间调用以确保通道列表已准备就绪。
  64. /// </summary>
  65. private void InitializeChannels()
  66. {
  67. for (int i = 0; i < ChannelCount; i++)
  68. {
  69. ChannelsInternal.Add(CreateChannel(i, Config.ChannelConfigs[i].Name));
  70. }
  71. }
  72. /// <summary>
  73. /// 创建指定索引处的通道实例。
  74. /// 派生类必须实现此方法以返回实际的 <see cref="ILightChannel"/> 对象。
  75. /// </summary>
  76. /// <param name="index">通道索引(从 0 开始)。</param>
  77. /// <param name="channelName">通道名称。</param>
  78. /// <returns>新创建的 <see cref="ILightChannel"/> 实例。</returns>
  79. protected abstract ILightChannel CreateChannel(int index,string channelName);
  80. /// <summary>
  81. /// 异步连接到控制器对应的硬件或服务。
  82. /// 在成功连接后,派生类应将 <see cref="IsConnected"/> 设置为 true。
  83. /// </summary>
  84. /// <returns>表示连接是否成功的任务(true 表示成功)。</returns>
  85. public abstract Task<bool> ConnectAsync();
  86. /// <summary>
  87. /// 异步断开与硬件或服务的连接。
  88. /// 在断开后,派生类应将 <see cref="IsConnected"/> 设置为 false。
  89. /// </summary>
  90. /// <returns>表示断开操作完成的任务。</returns>
  91. public abstract Task DisconnectAsync();
  92. /// <summary>
  93. /// 异步初始化控制器(例如加载配置、检测硬件状态等)。
  94. /// 在调用任何控制或通道相关操作前应先调用此方法。
  95. /// </summary>
  96. /// <returns>表示初始化是否成功的任务(true 表示成功)。</returns>
  97. public abstract Task<bool> InitializeAsync();
  98. /// <summary>
  99. /// 异步打开所有通道的光源。
  100. /// 实现应保证在并发场景下的线程安全或在文档中说明限制。
  101. /// </summary>
  102. /// <returns>表示操作是否成功的任务(true 表示成功)。</returns>
  103. public abstract Task<bool> TurnOnAllAsync();
  104. /// <summary>
  105. /// 异步关闭所有通道的光源。
  106. /// </summary>
  107. /// <returns>表示操作是否成功的任务(true 表示成功)。</returns>
  108. public abstract Task<bool> TurnOffAllAsync();
  109. /// <summary>
  110. /// 释放托管资源的虚拟方法实现。
  111. /// 派生类在覆盖时应调用 base.Dispose(disposing) 以确保基类资源被正确释放。
  112. /// </summary>
  113. /// <param name="disposing">若为 true,则同时释放托管资源;若为 false,仅释放非托管资源。</param>
  114. protected virtual void Dispose(bool disposing)
  115. {
  116. if (disposing)
  117. {
  118. foreach (var channel in ChannelsInternal)
  119. {
  120. (channel as IDisposable)?.Dispose();
  121. }
  122. ChannelsInternal.Clear();
  123. }
  124. }
  125. /// <summary>
  126. /// 释放当前实例占用的资源并通知垃圾回收器不再调用终结器。
  127. /// 建议在不再使用控制器时显式调用此方法以尽早释放资源。
  128. /// </summary>
  129. public void Dispose()
  130. {
  131. Dispose(true);
  132. GC.SuppressFinalize(this);
  133. }
  134. }
  135. }