cs-midi/MIDI_Outputs/Abstract/MIDIChordButton.hpp

60 lines
1.7 KiB
C++

#pragma once
#include <AH/Hardware/Button.hpp>
#include <AH/STL/memory>
#include <Def/Def.hpp>
#include <MIDI_Constants/Chords/Chords.hpp>
#include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp>
BEGIN_CS_NAMESPACE
template <class Sender>
class MIDIChordButton : public MIDIOutputElement {
public:
template <uint8_t N>
MIDIChordButton(pin_t pin, MIDIAddress address, Chord<N> chord,
const Sender &sender)
: button(pin), address(address),
newChord(AH::make_unique<Chord<N>>(std::move(chord))),
sender(sender) {}
void begin() final override { button.begin(); }
void update() final override {
AH::Button::State state = button.update();
MIDIAddress sendAddress = address;
if (state == AH::Button::Falling) {
if (newChord)
chord = std::move(newChord);
sender.sendOn(sendAddress);
for (int8_t offset : *chord)
sender.sendOn(sendAddress + offset);
} else if (state == AH::Button::Rising) {
sender.sendOff(sendAddress);
for (int8_t offset : *chord)
sender.sendOff(sendAddress + offset);
}
}
void invert() { button.invert(); }
AH::Button::State getButtonState() const { return button.getState(); }
template <uint8_t N>
void setChord(Chord<N> chord) {
newChord = AH::make_unique<Chord<N>>(std::move(chord));
}
MIDIAddress getAddress() const { return this->address; }
void setAddressUnsafe(MIDIAddress address) { this->address = address; }
private:
AH::Button button;
MIDIAddress address;
std::unique_ptr<const IChord> chord;
std::unique_ptr<const IChord> newChord;
public:
Sender sender;
};
END_CS_NAMESPACE