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
Assuming this object has a reference to apvts, add to its constuctor
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");
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
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.