I have some valueTrees in a plug-in, to represent things like GUI size, colour schemes, etc. Things that wouldn’t normally get saved as a part of a preset. Just extra user settings.
During the call to getStateInformation(), I add any extra trees along with the one from apvts to a new parent tree, and write that to memory.
In setStateInformation(), I get this master tree back. For apvts, I call replaceState() on it and pass it the appropriate child tree from the parent tree. All good.
What would be the correct way to handle the other trees, though? Without the lock that apvts uses in replaceState(), is changing values in a ValueTree from setStateInformation() going to cause a data race when the plug-in is loaded, if those values are used in the editors constructor?
Keep all you non-audio subtrees/properties in apvts.state, so when you call replaceState() you don’t have to deal with child trees.
If some object need to use this non-audio data, make sure it inherits from ValueTree::Listener and Value::Listener.
Assuming this object has a reference to apvts, add to its constuctor apvts.state.addListener(this);
And assuming you keep you colour in a propery called “main colour” in apvts.state, make a local Value object called myColour and call myColour.addListener(this) also in the constructor.
To prevent to data race you override ValueTree::Listener::valueTreeRedirected with this:
and then you need to override Value::Listener::valueChanged with whatever you want to do when myColour is changed/loaded.
In this way, you copy the data from apvts.state properties to your local variables so there is no data race. You listen to apvts.state and get an alert when the plugin loads its last known state or when you switch presets so your local variables will be updated whenever needed through valueTreeRedirected.
Only thing left is to manually update your getStateInformation with the data from your local variables back to apvts.state in a way that would match setStateInformation.
Edit: offloading the data from apvts.state property into a Value object may not be needed if you are not using it as a value in the first place, so you can skip all the Value::Listener part and just update whatever you need inside ValueTree::Listener::valueTreeRedirected. Still, you will need to buffer this data away from apvts.state to prevent the data race.