Line data Source code
1 : #pragma once 2 : 3 : #include "MIDIInputElement.hpp" 4 : #include <AH/Containers/LinkedList.hpp> 5 : 6 : #if defined(ESP32) 7 : #include <mutex> 8 : #define GUARD_LIST_LOCK std::lock_guard<std::mutex> guard_(mutex) 9 : #else 10 : #define GUARD_LIST_LOCK 11 : #endif 12 : 13 : BEGIN_CS_NAMESPACE 14 : 15 : /** 16 : * @brief Class for objects that listen for incoming MIDI Channel Pressure 17 : * events. 18 : * 19 : * @ingroup MIDIInputElements 20 : */ 21 : class MIDIInputElementChannelPressure 22 : : public MIDIInputElement, 23 : public DoublyLinkable<MIDIInputElementChannelPressure> { 24 : public: 25 : /** 26 : * @brief Constructor. 27 : * @todo Documentation. 28 : */ 29 12 : MIDIInputElementChannelPressure(const MIDIAddress &address) 30 24 : : MIDIInputElement(address) { 31 : GUARD_LIST_LOCK; 32 12 : elements.append(this); 33 12 : } 34 : 35 : /** 36 : * @brief Destructor. 37 : * @todo Documentation. 38 : */ 39 12 : virtual ~MIDIInputElementChannelPressure() { 40 : GUARD_LIST_LOCK; 41 12 : elements.remove(this); 42 12 : } 43 : 44 1 : static void beginAll() { 45 : GUARD_LIST_LOCK; 46 2 : for (MIDIInputElementChannelPressure &el : elements) 47 1 : el.begin(); 48 1 : } 49 : 50 : /** 51 : * @brief Reset all MIDIInputElementChannelPressure elements to their 52 : * initial state. 53 : * 54 : * @see MIDIInputElementChannelPressure#reset 55 : */ 56 0 : static void resetAll() { 57 : GUARD_LIST_LOCK; 58 0 : for (MIDIInputElementChannelPressure &el : elements) 59 0 : el.reset(); 60 0 : } 61 : 62 : /** 63 : * @brief Update all MIDIInputElementChannelPressure elements. 64 : */ 65 1 : static void updateAll() { 66 : GUARD_LIST_LOCK; 67 2 : for (MIDIInputElementChannelPressure &el : elements) 68 1 : el.update(); 69 1 : } 70 : 71 : /** 72 : * @brief Update all MIDIInputElementChannelPressure elements with a new 73 : * MIDI message. 74 : * 75 : * @see MIDIInputElementChannelPressure#updateWith 76 : */ 77 19 : static void updateAllWith(const ChannelMessageMatcher &midimsg) { 78 38 : for (MIDIInputElementChannelPressure &e : elements) 79 19 : if (e.updateWith(midimsg)) { 80 19 : e.moveDown(); 81 19 : return; 82 19 : } 83 : // No mutex required: 84 : // e.moveDown may alter the list, but if it does, it always returns, 85 : // and we stop iterating, so it doesn't matter. 86 19 : } 87 : 88 : private: 89 : /// Channel Pressure doesn't have an address, so the target consists of just 90 : /// the channel and the cable number. 91 0 : MIDIAddress getTarget(const ChannelMessageMatcher &midimsg) const override { 92 0 : return { 93 : 0, 94 0 : Channel(midimsg.channel), 95 0 : Cable(midimsg.CN), 96 : }; 97 : } 98 : 99 : /** 100 : * @brief Move down this element in the linked list of elements. 101 : * 102 : * This means that the element will be checked earlier on the next 103 : * iteration. 104 : */ 105 19 : void moveDown() { 106 : GUARD_LIST_LOCK; 107 19 : elements.moveDown(this); 108 19 : } 109 : 110 : static DoublyLinkedList<MIDIInputElementChannelPressure> elements; 111 : #ifdef ESP32 112 : static std::mutex mutex; 113 : #endif 114 : }; 115 : 116 : #undef GUARD_LIST_LOCK 117 : 118 : END_CS_NAMESPACE