My C/C++ skills are a bit rusty, and I've mostly been working in Java for the past few years. Now I just started playing around with Arduino, and made a simple button class. I want to add an event listener, so I did something like this:
class MyButton{
public:
MyButton(byte pin);
bool isPressed();
bool wasToggled();
bool wasPressed();
void eventLoop();
inline void setListener(MyButtonListener* listener) { _listener = listener; }
private:
byte _pin;
boolean _lastToggledState = false;
MyButtonListener* _listener;
};
class MyButtonListener{
public:
virtual void onPressed() = 0;
private:
};
The eventLoop()
method (which is intended to be called from the Arduino loop()
function ), invokes the onPressed()
method in the listener class:
void MyButton::eventLoop(){
if( wasPressed() && _listener ){
_listener->onPressed();
}
}
So far, things are okay. But I can't figure out how to actually assign and use the listener in the main Arduino file. Coming from Java, I'm used to just doing something like
myBtn.setListener( new MyButtonListener(){
void onPressed(){
Serial.println("Pressed");
toggleLed(); // toggleLed() is a method in the main Arduino file
}
});
I got it to work in a very convoluted way, by declaring a new class which takes the toggleLed()
method as an argument (because it can't be accessed from within the new class otherwise):
class BtnListener : public MyButtonListener{
public:
BtnListener(void* toggleFunction) : _toggleFunction(toggleFunction){ };
private:
void (*_toggleFunction)();
void onPressed(){
Serial.println("Pressed");
_toggleFunction();
};
};
myBtn.setListener( new BtnListener(toggleLed) );
Surely there must be a more convenient way of doing something like this in C++? It's doable (but ugly) with one listener - I can't even imagine the horror of having 10 buttons which all need different listener implementations...