Value Tree Properties not Reloading when Saved Project Reopened

I have some properties of my plugin that I want saved and reloaded, but not automatable, so I’m putting them in a value tree that is a child of the audio processor value tree state’s value tree. When I close the plugin interface and re-open it, all of these properties are restored just fine. However, when I save, close, and reopen the DAW project, these properties are not restored.

My audio processor value tree state is restoring most parameters when the project is reopened, but its child with the non-automatable properties is not being restored. I’ve been debugging this for days, and have confirmed that the child tree does have the changed parameters intact when it is saved, but then when it is reloaded, it does not. There are no spots where saved properties are being overwritten, unless it appears in the code below. This happens without the editor being opened, so the problem must be in the processor somewhere.

I’ve been stuck on this for days and have tried everything I could find from tutorials and videos, but nothing has changed. Here is the relevant code:

In the header file, my apvts and the child value tree are initialized as follows:

AudioProcessorValueTreeState valueTree;
ValueTree moduleSettings{ "SETTINGS" };
Value moduleActivatedValue;
Identifier moduleActivatedValueID{ "VISIBLE0" };

In the creation argument of the processor, the property is added to the moduleSettings tree and that tree is added as a child to apvts as follows:

if (!moduleSettings.hasProperty(moduleActivatedValueID))
    moduleSettings.setProperty(moduleActivatedValueID, false, nullptr);
moduleActivatedValue.referTo(moduleSettings.getPropertyAsValue(moduleActivatedValueID, nullptr));
if (!moduleSettings.isAChildOf(valueTree.state))
    valueTree.state.appendChild(moduleSettings, nullptr);
valueTree.state = ValueTree("valueTreeState");

In getStateInformation() I have the following code. I have also tried the writeToStream methods and other ways of re-ordering this code, but all have the same result:

if (unique_ptr<XmlElement> xml = valueTree.state.createXml())
        copyXmlToBinary(*xml, destData);

In setStateInformation(), I have the following code:

if (unique_ptr<XmlElement> xml = getXmlFromBinary(data, sizeInBytes))
        valueTree.state = ValueTree::fromXml(*xml);

So does anyone know why my apvts parameters are reloading when a saved project is reopened, but the child tree’s properties are not reloaded? Any help or insight would be greatly appreciated.

Doesn’t that last line replace valueTree.state, whether you have just appended moduleSettings to it in the line above or not?

I had also tried it with that line before appending the child and it had the same results. That line is just assigning a tag name to valueTree.state. The api says to do it after parameters are added. Removing that line has the same results too anyway.

The header file has this function:

/** Creates an empty ValueTree with the given type name.

    Like an XmlElement, each ValueTree has a type, which you can access with
    getType() and hasType().
explicit ValueTree (const Identifier& type);

which means that that line is creating a new, empty ValueTree object with that name. It does not change the rest of your valueTree object, but it does create a new, empty ValueTree with that name, and assign it to your valueTree.state member.

I don’t see what you’re doing before this, other than adding parameters, but your code is asking about the contents of valueTree.state, not just valueTree, which implies you have (or may have) already added something to the valueTree.state member. If that is the case, then whatever you added is gone once you make that assignment. Anything that you want to be in valueTree.state has to be added after you have assigned it to valueTree.state, or else you have to create a ValueTree object with that name, add your stuff to that ValueTree instance, and then assign it to valueTree.state.

We do have a line like that after adding our parameters, but we don’t mess with the valueTree.state information at all, let alone before that line is called.

The only things before the code is adding parameters to the apvts. I’ve tried it without adding the tag name to the apvts tree, I’ve tried it with adding the tag name before I do anything with my child tree and/or before I attach the child tree to the apvts, I’ve tried it with adding the child tree as a child before adding properties to the child tree, and no matter what order I put that code in, the exact same thing happens every time and the problem remains.

After two weeks of staring at this one problem I finally found the solution:

In setStateInformation I needed the child tree object to copy properties from the child of apvts’s xml-written tree.

moduleSettings.copyPropertiesFrom(valueTree.state.getChildWithName("SETTINGS"), nullptr);