PriorityMuxer.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #pragma once
  2. // STL includes
  3. #include <vector>
  4. #include <cstdint>
  5. // QT includes
  6. #include <QMap>
  7. #include <QObject>
  8. #include <QMap>
  9. #include <QVector>
  10. // Utils includes
  11. #include <utils/ColorRgb.h>
  12. #include <utils/Image.h>
  13. #include <utils/Components.h>
  14. // global defines
  15. #define SMOOTHING_MODE_DEFAULT 0
  16. #define SMOOTHING_MODE_PAUSE 1
  17. class QTimer;
  18. class Logger;
  19. ///
  20. /// The PriorityMuxer handles the priority channels. Led values input/ images are written to the priority map
  21. /// and the muxer keeps track of all active priorities. The current priority can be queried and per
  22. /// priority the led colors. Handles also manual/auto selection mode, provides a lot of signals to hook into priority related events
  23. ///
  24. class PriorityMuxer : public QObject
  25. {
  26. Q_OBJECT
  27. public:
  28. ///
  29. /// The information structure for a single priority channel
  30. ///
  31. struct InputInfo
  32. {
  33. /// The priority of this channel
  34. int priority;
  35. /// The absolute timeout of the channel
  36. int64_t timeoutTime_ms;
  37. /// The colors for each led of the channel
  38. std::vector<ColorRgb> ledColors;
  39. /// The raw Image (size should be preprocessed!)
  40. Image<ColorRgb> image;
  41. /// The component
  42. hyperion::Components componentId;
  43. /// Who set it
  44. QString origin;
  45. /// id of smoothing config
  46. unsigned smooth_cfg;
  47. /// specific owner description
  48. QString owner;
  49. };
  50. typedef QMap<int, InputInfo> InputsMap;
  51. //Foreground and Background priorities
  52. const static int FG_PRIORITY;
  53. const static int BG_PRIORITY;
  54. const static int MANUAL_SELECTED_PRIORITY;
  55. /// The lowest possible priority, which is used when no priority channels are active
  56. const static int LOWEST_PRIORITY;
  57. /// Timeout used to identify a non active priority
  58. const static int TIMEOUT_NOT_ACTIVE_PRIO;
  59. const static int REMOVE_CLEARED_PRIO;
  60. const static int ENDLESS;
  61. ///
  62. /// Constructs the PriorityMuxer for the given number of LEDs (used to switch to black when
  63. /// there are no priority channels
  64. ///
  65. /// @param ledCount The number of LEDs
  66. ///
  67. PriorityMuxer(int ledCount, QObject * parent);
  68. ///
  69. /// Destructor
  70. ///
  71. ~PriorityMuxer() override;
  72. ///
  73. /// @brief Start/Stop the PriorityMuxer update timer; On disabled no priority and timeout updates will be performend
  74. /// @param enable The new state
  75. ///
  76. void setEnable(bool enable);
  77. /// @brief Enable or disable auto source selection
  78. /// @param enable True if it should be enabled else false
  79. /// @param update True to update _currentPriority - INTERNAL usage.
  80. /// @return True if changed has been applied, false if the state is unchanged
  81. ///
  82. bool setSourceAutoSelectEnabled(bool enable, bool update = true);
  83. ///
  84. /// @brief Get the state of source auto selection
  85. /// @return True if enabled, else false
  86. ///
  87. bool isSourceAutoSelectEnabled() const { return _sourceAutoSelectEnabled; }
  88. ///
  89. /// @brief Overwrite current lowest priority with manual selection; On success disables auto selection
  90. /// @param priority The
  91. /// @return True on success, false if priority not found
  92. ///
  93. bool setPriority(int priority);
  94. ///
  95. /// @brief Update all LED-Colors with min length of >= 1 to fit the new led length
  96. /// @param[in] ledCount The count of LEDs
  97. ///
  98. void updateLedColorsLength(int ledCount);
  99. ///
  100. /// Returns the current priority
  101. ///
  102. /// @return The current priority
  103. ///
  104. int getCurrentPriority() const { return _currentPriority; }
  105. ///
  106. /// Returns the previous priority before current priority
  107. ///
  108. /// @return The previous priority
  109. ///
  110. int getPreviousPriority() const { return _previousPriority; }
  111. ///
  112. /// Returns the state (enabled/disabled) of a specific priority channel
  113. /// @param priority The priority channel
  114. /// @return True if the priority channel exists else false
  115. ///
  116. bool hasPriority(int priority) const;
  117. ///
  118. /// Returns the number of active priorities
  119. ///
  120. /// @return The list with active priorities
  121. ///
  122. QList<int> getPriorities() const;
  123. ///
  124. /// Returns the information of a specified priority channel.
  125. /// If a priority is no longer available the _lowestPriorityInfo (255) is returned
  126. ///
  127. /// @param priority The priority channel
  128. ///
  129. /// @return The information for the specified priority channel
  130. ///
  131. InputInfo getInputInfo(int priority) const;
  132. ///
  133. /// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
  134. /// A repeated call to update the base data of a known priority won't overwrite their current timeout
  135. /// @param[in] priority The priority of the channel
  136. /// @param[in] component The component of the channel
  137. /// @param[in] origin Who set the channel (CustomString@IP)
  138. /// @param[in] owner Specific owner string, might be empty
  139. /// @param[in] smooth_cfg The smooth id to use
  140. ///
  141. void registerInput(int priority, hyperion::Components component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = SMOOTHING_MODE_DEFAULT);
  142. ///
  143. /// @brief Update the current color of a priority (previous registered with registerInput())
  144. /// @param priority The priority to update
  145. /// @param ledColors The colors
  146. /// @param timeout_ms The new timeout (defaults to -1 endless)
  147. /// @return True on success, false when priority is not found
  148. ///
  149. bool setInput(int priority, const std::vector<ColorRgb>& ledColors, int64_t timeout_ms = ENDLESS);
  150. ///
  151. /// @brief Update the current image of a priority (prev registered with registerInput())
  152. /// @param priority The priority to update
  153. /// @param image The new image
  154. /// @param timeout_ms The new timeout (defaults to -1 endless)
  155. /// @return True on success, false when priority is not found
  156. ///
  157. bool setInputImage(int priority, const Image<ColorRgb>& image, int64_t timeout_ms = ENDLESS);
  158. ///
  159. /// @brief Set the given priority to inactive
  160. /// @param priority The priority
  161. /// @return True on success false if not found
  162. ///
  163. bool setInputInactive(int priority);
  164. ///
  165. /// Clears the specified priority channel and update _currentPriority on success
  166. ///
  167. /// @param[in] priority The priority of the channel to clear
  168. /// @return True if priority has been cleared else false (not found)
  169. ///
  170. bool clearInput(int priority);
  171. ///
  172. /// Clears all priority channels
  173. ///
  174. void clearAll(bool forceClearAll=false);
  175. signals:
  176. ///
  177. /// @brief Emits whenever the visible priority has changed
  178. /// @param priority The new visible priority
  179. ///
  180. void visiblePriorityChanged(int priority);
  181. ///
  182. /// @brief Emits whenever the current visible component changed
  183. /// @param comp The new component
  184. ///
  185. void visibleComponentChanged(hyperion::Components comp);
  186. ///
  187. /// @brief Emits whenever something changes which influences the priorities listing
  188. /// Emits also in 1s interval when a COLOR or EFFECT is running with a timeout > -1
  189. /// @param currentPriority The current priority at time of emit
  190. /// @param activeInputs The current active input map at time of emit
  191. ///
  192. void prioritiesChanged(int currentPriority, InputsMap activeInputs);
  193. ///
  194. /// internal used signal to resolve treading issues with timer
  195. ///
  196. void signalTimeTrigger();
  197. private slots:
  198. ///
  199. /// Slot which is called to adapt to 1s interval for signal prioritiesChanged()
  200. ///
  201. void timeTrigger();
  202. ///
  203. /// Updates the current priorities. Channels with a configured time out will be checked and cleared if
  204. /// required. Cleared priorities will be removed.
  205. ///
  206. void updatePriorities();
  207. private:
  208. ///
  209. /// @brief Get the component of the given priority
  210. /// @return The component
  211. ///
  212. hyperion::Components getComponentOfPriority(int priority) const;
  213. /// Logger instance
  214. Logger* _log;
  215. /// The current priority (lowest value in _activeInputs)
  216. int _currentPriority;
  217. /// The previous priority before current priority
  218. int _previousPriority;
  219. /// The manual select priority set with setPriority
  220. int _manualSelectedPriority;
  221. // The last visible component
  222. hyperion::Components _prevVisComp = hyperion::COMP_INVALID;
  223. /// The mapping from priority channel to led-information
  224. InputsMap _activeInputs;
  225. /// The information of the lowest priority channel
  226. InputInfo _lowestPriorityInfo;
  227. // Reflect the state of auto select
  228. bool _sourceAutoSelectEnabled;
  229. // Timer to update Muxer times independent
  230. QTimer* _updateTimer;
  231. QTimer* _timer;
  232. QTimer* _blockTimer;
  233. };