Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIDIAddressable and MIDIAddressableUnsafe abstract classes #971

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

gwilherm
Copy link

@gwilherm gwilherm commented Nov 3, 2023

Hello,
Here is a change I made for a need I have.
I have a project of control surface with a set of push buttons. I wanted to make them configurable (via SysEx)
The two properties I want to configure is the CC address and whether it a latch or simple push button.
For that I needed an interface to call setAddressUnsafe() either for latch or simple button indifferently.

Of course I could use an array of MIDIOutputElements and cast CCButton/CCButtonLatched but it looks dirty to me.
See an example

The modification I made:

  • New abstract class MIDIAddressable with address member + getter + setter
  • New abstract class MIDIAddressableUnsafe with address member + getter + setter
  • Every MIDIOutputElement with setAddress() inherits from MIDIAddressable
  • Every MIDIOutputElement with setAddressUnsafe() inherits from MIDIAddressableUnsafe

Feel free to close if you think it is irrelevant ;-)

@tttapa
Copy link
Owner

tttapa commented Nov 3, 2023

Thanks, I'll have a look.

As a side note, even without a common base class, you can always do something like this:

#include <Control_Surface.h>

struct Addressable {
  virtual ~Addressable() = default;
  virtual MIDIAddress getAddress() const = 0;
  virtual void setAddressUnsafe(MIDIAddress address) = 0;
};

template <class T, class... Args>
Addressable *make_addressable(Args &&... args) {
  struct AddressableT : Addressable, T {
    AddressableT(Args &&... args) : T(std::forward<Args>(args)...) {}
    MIDIAddress getAddress() const override { return T::getAddress(); }
    void setAddressUnsafe(MIDIAddress address) override { T::setAddressUnsafe(address); }
  };
  return new AddressableT(std::forward<Args>(args)...);
}

Addressable *buttons[2];

void setup() {
  buttons[0] = make_addressable<CCButton>(2, 0x00);
  buttons[1] = make_addressable<CCButtonLatched>(3, 0x01);
  buttons[0]->setAddressUnsafe(buttons[0]->getAddress() + 0x10);
  buttons[1]->setAddressUnsafe(buttons[1]->getAddress() + 0x10);
  Control_Surface.begin();
}

void loop() {
  Control_Surface.loop();
}

@gwilherm
Copy link
Author

gwilherm commented Nov 4, 2023

Thank you for that cleaner solution !
It's great to meet people as invested as you, you're awesome, don't change !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants