How should one load a ValueTree?

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?

Thanks for reading!

My suggestion:

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:

myColour = apvts.state.getProperty("main colour");
valueChanged(myColour );

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.

1 Like

Be careful what you want to save by host / project. You might want to save certain things globally for all instances of your plugin no matter which host or project :wink:

2 Likes

I’m guessing this would need to be done via a config file on disk? I like the idea, for certain things such as whether or not to use OpenGL.

Thank you for that detailed reply. That all makes sense to me. I’ll give it a try later today.

Yes, a config file would work :wink: