Listeners can be called in the middle of update functions?

The cout messages on the left are being called (and destroying a pointer) while the update function on the right is still being executed. I didn’t even know this was possible and it never happened when I used listeners for ofParameters on the ofxGui. Is this a problem with ofxMidi in particular or something I’m not understanding about c++?

Anyway, to fix it, I just put the listener messages into a deque and then, in the Update(), I cycle through the deque and push_front() after calling the setImageFromMidi() function.

this isn’t guaranted for all platforms, but afaik the update/draw/key**/mouse**/touch** - events belong together and never interupt each other. typically all those are called from the main thread.

most other types of events (midi, audio, network, etc.) are completely asynchronerous and you will need to use mutexes or lock-free datastructures to share data with the main thread.

so for your deque solution: use a mutex too, deque itself isn’t thread safe.

the standard c++ solution to this are lock_guards, which take care of calling lock() and unlock() for you. here is a brief example:

// header ... 
class ofApp : ofBaseApp{

	// .....


	std::mutex midi_mutex;
	std::deque<ofxMidiMessage> midi_messages;
}




// implementation

void ofApp::newMidiMessage(ofxMidiMessage & msg){
	std::lock_guard<std::mutex> lock{midi_mutex};
	midi_messages.push_back(msg);
}


void ofApp::update(){

	// make sure to do the work inside a block-scope (the curly {})
	// so that the lock_guard can release the lock as early as possible. 
	// without those braces the lock is held until the end of update()

	{
		std::lock_guard<std::mutex> lock{midi_mutex};
		int max_pop = 50;
		while(!midi_messages.empty() && max_pop>0){
			ofxMidiMessage msg = midi_messages.front();
			midi_messages.pop_front();
		
			do_something(msg);
		
			max_pop --; 
		}
	} // lock is released automatically when leaving this block
}

i just typed this in, so it might not compile 100% :slight_smile: also note that this solution is improvable, but it should be good enough for most situations.

2 Likes

Thanks! I’ll give it a shot.