2#include <bugui/concepts/color.hpp>
3#include <bugui/concepts/protocol.hpp>
4#include <bugui/color/color_converter.hpp>
6#include <libremidi/libremidi.hpp>
14template <is_sysex_out_component Component>
17 static consteval auto prefix_size()
18 {
return Component::out_message_t::sysex_id().size() + 1; };
19 static consteval auto prefix_incremented()
20 {
return prefix_size() + 1; };
26template <
typename Component>
27struct base_midi_formater
31 virtual void set(uint8_t
id
33 <
typename Component::color_t>& converter)
38 bytes.push_back(Component::color_t::constant_id());
41 bytes.push_back(converter.get());
48 void add(uint8_t element) { bytes.push_back(element); }
56 bytes.erase(bytes.cbegin() +
57 sysex_formater<Component>::prefix_size()
60 bytes.erase(bytes.cbegin() + 1, bytes.cend());
69 sysex_formater<Component>::prefix_size();
71 return bytes.size() > 1;
75 const libremidi::midi_bytes&
get()
const {
return bytes; }
81 using namespace libremidi;
84 bytes.push_back(to_underlying(message_type::NOTE_ON));
87 bytes.push_back(to_underlying(message_type
92 bytes.push_back(to_underlying(message_type
96 : Component::out_message_t::sysex_id())
101 libremidi::midi_bytes bytes;
106template <
typename Component>
108 : base_midi_formater<Component>
115template <has_dual_blink Component>
116struct dual_blinker :
virtual base_midi_formater<Component>
124 return blink_bytes.size() >
125 sysex_formater<Component>::prefix_incremented();
127 return blink_bytes.size() > 1;
133 { blink_bytes.push_back(element); }
138 {
return blink_bytes; }
145 using namespace libremidi;
147 if constexpr(is_on_off_out_component<Component>)
148 blink_bytes.push_back(channel_events::make_command
149 (message_type::NOTE_ON
151 ::blinking_channel()));
153 if constexpr(is_cc_out_component<Component>)
154 blink_bytes.push_back(channel_events::make_command
155 (message_type::CONTROL_CHANGE
157 ::blinking_channel()));
159 if constexpr(is_sysex_out_component<Component>)
161 blink_bytes = this->bytes;
162 blink_bytes.push_back(Component::color_t::blinking_id());
169 this->blink_bytes.erase(this->blink_bytes.cbegin() +
171 ::prefix_incremented()
172 , this->blink_bytes.cend());
174 this->blink_bytes.erase(this->blink_bytes.cbegin() + 1
175 , this->blink_bytes.cend());
178 libremidi::midi_bytes blink_bytes;
185template <
typename Component>
186 requires (has_dual_blink<Component>
187 && !has_dual_pulse<Component>)
189 : dual_blinker<Component>
194 void set(uint8_t
id,
const color_cnvrtr& converter)
override
199 this->bytes.push_back(Component::color_t::constant_id());
201 this->bytes.push_back(
id);
205 this->blink_bytes.push_back(
id);
206 this->bytes.push_back(color_cnvrtr::clear_value);
207 this->blink_bytes.push_back(converter.
get());
210 this->bytes.push_back(converter.
get());
224template <has_dual_pulse Component>
225struct dual_pulser :
virtual base_midi_formater<Component>
233 return pulse_bytes.size() >
234 sysex_formater<Component>::prefix_incremented();
236 return pulse_bytes.size() > 1;
242 { pulse_bytes.push_back(element); }
247 {
return pulse_bytes; }
254 using namespace libremidi;
256 if constexpr(is_on_off_out_component<Component>)
257 pulse_bytes.push_back(channel_events::make_command
258 (message_type::NOTE_ON
260 ::pulsing_channel()));
262 if constexpr(is_cc_out_component<Component>)
263 pulse_bytes.push_back(channel_events::make_command
264 (message_type::CONTROL_CHANGE
266 ::pulsing_channel()));
268 if constexpr(is_sysex_out_component<Component>)
270 pulse_bytes = this->bytes;
271 pulse_bytes.push_back(Component::color_t::pulsing_id());
278 this->pulse_bytes.erase(this->pulse_bytes.cbegin() +
280 ::prefix_incremented()
281 , this->pulse_bytes.cend());
283 this->pulse_bytes.erase(this->pulse_bytes.cbegin() + 1
284 , this->pulse_bytes.cend());
287 libremidi::midi_bytes pulse_bytes;
294template <
typename Component>
295 requires (!has_dual_blink<Component>
296 && has_dual_pulse<Component>)
297struct midi_formater<Component>
final
298 : dual_pulser<Component>
301 color_converter<typename Component::color_t>;
303 void set(uint8_t
id,
const color_cnvrtr& converter)
override
305 if constexpr(is_sysex_out_component<Component>)
306 if (this->bytes.size() == sysex_formater<Component>
308 this->bytes.push_back(Component::color_t::constant_id());
310 this->bytes.push_back(
id);
314 this->bytes.push_back(color_cnvrtr::clear_value);
315 this->pulse_bytes.push_back(converter.get());
316 this->pulse_bytes.push_back(
id);
319 this->bytes.push_back(converter.get());
333template <
typename Component>
334 requires (has_dual_blink<Component>
335 && has_dual_pulse<Component>)
336struct midi_formater<Component>
final
337 : dual_blinker<Component>
338 , dual_pulser<Component>
341 color_converter<typename Component::color_t>;
343 void set(uint8_t
id,
const color_cnvrtr& converter)
override
345 if constexpr(is_sysex_out_component<Component>)
346 if (this->bytes.size() == sysex_formater<Component>
348 this->bytes.push_back(Component::color_t::constant_id());
350 this->bytes.push_back(
id);
352 switch (converter.get_state())
355 this->bytes.push_back(color_cnvrtr::clear_value);
356 this->blink_bytes.push_back(
id);
357 this->blink_bytes.push_back(converter.get());
360 this->bytes.push_back(color_cnvrtr::clear_value);
361 this->pulse_bytes.push_back(
id);
362 this->pulse_bytes.push_back(converter.get());
365 this->bytes.push_back(converter.get());
383template <
typename Component>
384 requires (has_blink_offset<Component>
385 || has_pulse_offset<Component>)
386struct midi_formater<Component>
final
387 : base_midi_formater<Component>
389 using cmpnnt_clr = Component::color_t;
391 virtual void set(uint8_t
id
394 this->bytes.push_back(
id);
395 uint8_t value = converter.
get();
401 value += cmpnnt_clr::blinking_offset();
403 value += cmpnnt_clr::pulsing_offset();
407 value += cmpnnt_clr::pulsing_offset();
409 value += cmpnnt_clr::blinking_offset();
415 this->bytes.push_back(value);
Definition midi_message.hpp:124
Definition midi_message.hpp:128
Definition midi_message.hpp:120
color::states get_state() const
Retrives the current state.
Definition color_converter.hpp:36
Value_t get() const
Retrives the main device specific colour value.
Definition color_converter.hpp:34
Povides convertion of color objects to device specific integer values.
Definition color_converter.hpp:57
@ blinking
Alternating between the colour and black.
Definition color.hpp:20
@ constant
Constant colour.
Definition color.hpp:19
@ pulsing
Smooth cycle between the colour and black.
Definition color.hpp:21
Enables the use of multiple buffers targetting diferent midi Channels. This method is used for device...
Definition midi_formater.hpp:117
const libremidi::midi_bytes & get_blink() const
Retrives the MIDI buffer dedicated to blinking LED's.
Definition midi_formater.hpp:137
void add_blink(uint8_t element)
Add a given value to a MIDI buffer dedicated to blinking LED's.
Definition midi_formater.hpp:132
void clear() override
Removes all stores values of the message except for it's message type or prefix (NOTE_ON,...
Definition midi_formater.hpp:166
bool has_blink_message() const
Checks if a message is stored in the buffer dedicated for bliking, and ready to be sent to the device...
Definition midi_formater.hpp:121
Enables the use of multiple buffers targetting diferent midi Channels. This method is used for device...
Definition midi_formater.hpp:226
void clear() override
Removes all stores values of the message except for it's message type or prefix (NOTE_ON,...
Definition midi_formater.hpp:275
const libremidi::midi_bytes & get_pulse() const
Retrives the MIDI buffer dedicated to pulsing LED's.
Definition midi_formater.hpp:246
bool has_pulse_message() const
Checks if a message is stored in the buffer dedicated for pulsing, and ready to be sent to the device...
Definition midi_formater.hpp:230
void add_pulse(uint8_t element)
Add a given value to a MIDI buffer dedicated to pulsing LED's.
Definition midi_formater.hpp:241