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