Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include <AH/Debug/Debug.hpp> 6 : #include <AH/Error/Error.hpp> 7 : #include <AH/Containers/LinkedList.hpp> 8 : #include <Selectors/Selectable.hpp> 9 : 10 : BEGIN_CS_NAMESPACE 11 : 12 : template <setting_t N> 13 : class BankableMIDIInput; 14 : 15 : /** 16 : * @brief A class for changing the address of BankableMIDIOutput%s. 17 : */ 18 : class OutputBank { 19 : public: 20 : /** 21 : * @brief Create a new OutputBank object. 22 : * 23 : * @param tracksPerBank 24 : * The number of addresses/tracks to skip for each bank setting. 25 : * Must be strictly positive. 26 : * @param initialSelection 27 : * The initial bank setting. 28 : */ 29 38 : OutputBank(uint8_t tracksPerBank = 1, setting_t initialSelection = 0) 30 38 : : tracksPerBank(tracksPerBank), bankSetting(initialSelection) { 31 38 : if (tracksPerBank == 0) 32 1 : FATAL_ERROR(F("A Bank must have a non-zero number of tracks."), 33 : 0x4573); 34 38 : } 35 : 36 : /** 37 : * @brief Select the given bank setting. 38 : * 39 : * @param setting 40 : * The new setting to select. 41 : */ 42 61 : void select(setting_t setting) { bankSetting = setting; } 43 : 44 : /** 45 : * @brief Get the current bank setting. 46 : */ 47 203 : virtual setting_t getSelection() const { return bankSetting; } 48 : 49 : /** 50 : * @brief Get the number of tracks per bank. 51 : * This is the number of addresses/tracks to skip for each bank setting. 52 : */ 53 115 : uint8_t getTracksPerBank() const { return tracksPerBank; } 54 : 55 : /** 56 : * @brief Get the offset (number of banks times the index of the selected 57 : * bank) 58 : */ 59 : uint8_t getOffset() const { return getSelection() * getTracksPerBank(); } 60 : 61 : private: 62 : uint8_t tracksPerBank; 63 : setting_t bankSetting; 64 : }; 65 : 66 : /** 67 : * @brief A class that groups Bankable BankableMIDIOutput%s and 68 : * BankableMIDIInput%s, and allows the user to change the addresses 69 : * of these elements. 70 : * 71 : * @tparam N 72 : * The number of banks. 73 : */ 74 : template <setting_t N> 75 : class Bank : public Selectable<N>, public OutputBank { 76 : friend class BankableMIDIInput<N>; 77 : 78 : public: 79 : /** 80 : * @brief Construct a new Bank object. 81 : * 82 : * @param tracksPerBank 83 : * The number of addresses/tracks to skip for each bank setting. 84 : * Must be strictly positive. 85 : * @param initialSelection 86 : * The initial bank setting. 87 : */ 88 21 : Bank(uint8_t tracksPerBank = 1, setting_t initialSelection = 0) 89 21 : : Selectable<N>(initialSelection), 90 63 : OutputBank(tracksPerBank, initialSelection) {} 91 : 92 : /** 93 : * @brief Select the given bank setting. 94 : * 95 : * All BankableMIDIInput%s will be updated. 96 : * 97 : * @param bankSetting 98 : * The new setting to select. 99 : */ 100 : void select(setting_t bankSetting) override; 101 : 102 : /** 103 : * @brief Get the number of Banks. 104 : */ 105 : constexpr static uint8_t getNumberOfBanks() { return N; } 106 : 107 : private: 108 : /** 109 : * @brief Add a BankableMIDIInput to the bank. 110 : * 111 : * This method is called in the BankableMIDIInput constructor. 112 : * 113 : * @param bankable 114 : * The BankableMIDIInput to be added. 115 : */ 116 : void add(BankableMIDIInput<N> *bankable); 117 : 118 : /** 119 : * @brief Remove a BankableMIDIInput from the bank. 120 : * 121 : * This method is called in the BankableMIDIInput destructor. 122 : * 123 : * @param bankable 124 : * The BankableMIDIInput to be removed. 125 : */ 126 : void remove(BankableMIDIInput<N> *bankable); 127 : 128 : /** 129 : * @brief A linked list of all BankableMIDIInput elements that have been 130 : * added to this bank, and that should be updated when the bank 131 : * setting changes. 132 : * 133 : * The list is updated automatically when BankableMIDIInput elements are 134 : * created or destroyed. 135 : */ 136 : DoublyLinkedList<BankableMIDIInput<N>> inputBankables; 137 : }; 138 : 139 : END_CS_NAMESPACE 140 : 141 : // ---------------------------- Implementations ----------------------------- // 142 : 143 : #include <Banks/BankableMIDIInput.hpp> 144 : 145 : BEGIN_CS_NAMESPACE 146 : 147 : template <setting_t N> 148 16 : void Bank<N>::add(BankableMIDIInput<N> *bankable) { 149 16 : inputBankables.append(bankable); 150 16 : } 151 : 152 : template <setting_t N> 153 16 : void Bank<N>::remove(BankableMIDIInput<N> *bankable) { 154 16 : inputBankables.remove(bankable); 155 16 : } 156 : 157 : template <setting_t N> 158 51 : void Bank<N>::select(setting_t bankSetting) { 159 51 : bankSetting = this->validateSetting(bankSetting); 160 51 : OutputBank::select(bankSetting); 161 100 : for (BankableMIDIInput<N> &e : inputBankables) 162 49 : e.onBankSettingChange(); 163 50 : } 164 : 165 : END_CS_NAMESPACE