How is thread-safety managed here? The internal-value tree is updated by the message-thread from time to time. What if the host uses another thread to access the current state?
Second problem, what if the internal-parameter value has just been changed, can be guaranteed the next state includes the change?
Another critical problem i see
If the parameter uses an interval, the quantized (stepped) values are stored internally. I think this is problematic, from a hosts perspective, it sets a certain float value, and gets a quantized value back.
if the listeners are implemented asynchron, from the message-thread.
My conclusion is not to use it, because it has lots of potential flaws.
One way to “fix” the concurrency if the host access the State, would be to implement a MM-Lock, but this highly dangerous, because of deadlocks.
I would remove any message-thread dependency, and secure access to the ValueTree by a additional Critical-Sections.
I guess whether this is a problem depends on what the message thread actually does to the ValueTree? The main concern would be anything that adds or removes nodes from it, e.g. loading or saving new preset? Should the ValueTree be exposed as a public member at all here … seems to be the start of trouble?
What I’m thinking is that it could take the state information, pop it in a queue for the message thread to deal with and block until that action has completed. If it doesn’t block it’ll screw up the timing and there’s a danger of the host getting the wrong settings when working offline (cheers Doug…)
It’d need to check it wasn’t being called on the message thread though - otherwise this approach is going nowhere.
And I guess it could easily deadlock if the host had locked the message thread waiting for this job to complete.
At the very least, as it’s designed to be used in a multi-thread environment the documentation could mention the word ‘thread’, probably more than once
These are all fair points (along with other AudioProcessorValueTreeState issues pointed out on the forum). We’ve been a bit silent on this as we have yet to decide exactly how we want to address these problems.
The goal is to have a “best-practice” sample code on how to deal with parameters and ensure that this approach is thread-safe and interacts well with other JUCE code such as the UndoManager. We are planning to push this out with a point release - either 5.2 or 5.3.
I never realised the benefit to save the exact same information doubled, inside the AudioProcessorParameter and inside a separate ValueTree. I find it better when one information is always stored at one place, so you never have any synchronisation issues. When i need a ValueTree (to save the state) i just created it from there.
PS: Otherwise a ValueTree could be helpful, if JUCE has some kind of high-level ValueTree tools, like thread safe-lock free synchronisation / read-only-shadow-copies which can be read from the audio-thread etc… then yes, a valuetree could be helpful, otherwise no
Great to hear that you are working on improvements to the AudioProcessorValueTreeState.
Have you considered allowing the creation of customized parameter attachments? I have requested that earlier here: Please make AudioProcessorValueTreeState::Parameter public!
After all it basically only requires to move the Parameter and AttachedControlBase class definitions over to the header file. As far as I can see that wouldn’t even break any of the existing code.
Even small adjustments to the existing attachments are impossible to make due to the present access restrictions. (like the one discussed here: AudioProcessorValueTreeState::SliderAttachment and RightButtonDown)