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 Note events. 17 : * 18 : * @ingroup MIDIInputElements 19 : */ 20 : class MIDIInputElementNote : public MIDIInputElement, 21 : public DoublyLinkable<MIDIInputElementNote> { 22 : protected: 23 : /** 24 : * @brief Constructor. 25 : * @todo Documentation. 26 : */ 27 11 : MIDIInputElementNote(const MIDICNChannelAddress &address) 28 22 : : MIDIInputElement{address} { 29 : GUARD_LIST_LOCK; 30 11 : elements.append(this); 31 11 : } 32 : 33 : public: 34 : /** 35 : * @brief Destructor. 36 : * @todo Documentation. 37 : */ 38 11 : virtual ~MIDIInputElementNote() { 39 : GUARD_LIST_LOCK; 40 11 : elements.remove(this); 41 11 : } 42 : 43 : /** 44 : * @brief Initialize all MIDIInputElementNote elements. 45 : * 46 : * @see MIDIInputElementNote#begin 47 : */ 48 1 : static void beginAll() { 49 : GUARD_LIST_LOCK; 50 2 : for (MIDIInputElementNote &e : elements) 51 1 : e.begin(); 52 1 : } 53 : 54 : /** 55 : * @brief Update all MIDIInputElementNote elements. 56 : * 57 : * @see MIDIInputElementNote#update 58 : */ 59 0 : static void updateAll() { 60 : GUARD_LIST_LOCK; 61 0 : for (MIDIInputElementNote &e : elements) 62 0 : e.update(); 63 0 : } 64 : 65 : /** 66 : * @brief Reset all MIDIInputElementNote elements to their initial state. 67 : * 68 : * @see MIDIInputElementNote#reset 69 : */ 70 1 : static void resetAll() { 71 : GUARD_LIST_LOCK; 72 2 : for (MIDIInputElementNote &e : elements) 73 1 : e.reset(); 74 1 : } 75 : 76 : /** 77 : * @brief Update all MIDIInputElementNote elements with a new MIDI 78 : * message. 79 : * 80 : * @see MIDIInputElementNote#updateWith 81 : */ 82 13 : static void updateAllWith(const ChannelMessageMatcher &midimsg) { 83 13 : for (MIDIInputElementNote &e : elements) 84 13 : if (e.updateWith(midimsg)) { 85 13 : e.moveDown(); 86 13 : return; 87 : } 88 : // No mutex required: 89 : // e.moveDown may alter the list, but if it does, it always returns, 90 : // and we stop iterating, so it doesn't matter. 91 13 : } 92 : 93 : private: 94 : /** 95 : * @brief Move down this element in the linked list of elements. 96 : * 97 : * This means that the element will be checked earlier on the next 98 : * iteration. 99 : */ 100 13 : void moveDown() { 101 : GUARD_LIST_LOCK; 102 13 : elements.moveDown(this); 103 13 : } 104 : 105 : static DoublyLinkedList<MIDIInputElementNote> elements; 106 : #ifdef ESP32 107 : static std::mutex mutex; 108 : #endif 109 : }; 110 : 111 : #undef GUARD_LIST_LOCK 112 : 113 : END_CS_NAMESPACE