I have a simple button class that calls ofRegisterTouchEvents(this) in setup. It works great when I create a single instance. When I create multiple instances in a loop and store them in a vector it no longer works. If I use a shared pointer in the vector they work as expected.
This works coolButton button;
These don’t receive touch events vector<coolButton> buttons;
But these do vector<shared_ptr<coolButton>> betterButtons;
In the mm file
for (int i = 0; i < NUM_BUTTONS; i++) {
// don't receive touch events
coolButton button;
buttons.push_back(button);
buttons[i].setup(i);
// these work as expected
betterButtons.push_back(shared_ptr<ixWordButton>(new ixWordButton()));
betterButtons[i]->setup(i);
}
This is a problem with callbacs to objects in c++. vectors move memory around when you push_back to them so when you set up the object, ofEvent stores a pointer to it but when that object is moved by the vector to a different location the ofEvent pointer becomes invalid and your application should even crash. There’s no easy way to solve this except for having some kind of event where objects can poll from instead of receive callbacks.
A possible solution is also to preallocate the vector so it doesn’t reallocate the objects and then call setup on them like:
that way buttons never move from their original location and the addresses are always valid. another solution if you need to dynamically allocate new buttons (or remove them) after the app has started is to use a list instead of a vector which never moves the objects from their original locations