Processor / Editor Update Weirdness... best approach?

Hello all,

So here is something that has been bugging me. I have a little program that will show the midi notes that you have pressed down, but it is a little sticky (the notes of chords stay listed if they are released) if I press and release keys quickly. I am wondering what the best approach to solving this problem would be.

So in the processor, I have a vector of bools that stores all the key states - allKeyStates. This is updated correctly when I press and release keys / midi notes. Then I have a bool called ‘needsGuiUpdate’, that will be set to true if any midi messages are received.

Then in the editor code I am checking that ‘needsGuiUpdate’ bool in a timerCallback to well… check if it needs updating and after that is taken care of, the editor sets ‘needsGuiUpdate’ back to false.

Now what I suspect is happening, is that sometimes the Editor is still updating while the key states change and then it sets the ‘needsGuiUpdate’ back to false when in fact, the Processor has just set that it needs to do an update moments before.

I have experimented with adding a CriticalSection, and using a ScopedLock in the private methods for setting / getting the value of the ‘needsGuiUpdate’ bool. However, the more I thought about this I realised that this doesn’t actually help since the editor can still call the ‘set_needs_gui_update(false)’ method when the lock is not in effect. I essentially have the same problem.

What would be the best approach for this?

EDIT: I mean… I have also experimented with putting the call to ‘set_needs_gui_update(false)’ at the top of the update code in the editor. This solves the problem, but what if in some case it needed to go at the end? How would you solve that? I am still not convinced that simply doing that is the best approach.

That’s how it works. Say needsGuiUpdate is an atomic_bool. You make all your changes on the writing thread and, at the end, you say (true, std::memory_order_release). Then on the reading thread, if ( (false, std::memory_order_acquire)) then you update the GUI. You can omit the memory order args and leave the default (sequentially consistent), I wrote them to remark that you release after writing and acquire before reading. Of course, if you’re reading and writing many pieces of data, you may read an inconsistent set: you’re guaranteed to read everything updated until the last release, but you may get some changes after it. To avoid that, you need some way of synchronizing the whole thing, like some kind of FIFO, or a single structure that’s atomically swapped at release and acquire.

Ah interesting. Thanks I will take a look into this more on the morrow with a fresh head.