It seems that going to/from XML in the setting and getting of plugin state info has some good benefits. Mainly that a human readable representation of the ValueTree is readily at hand.
I’m at the point where I’d like to store more complex data structures (beyond string/value pairs)
I hit this assertion after adding a value that was a var() referenceCountedObject:
void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const
{
for (auto& i : values)
....
{
// These types can't be stored as XML!
jassert (! i.value.isObject());
From what I can see ahead, I will need to write and maintain a fair amountof code for saving and restoring of data structures.
Is there a smart way of doing this that I would want to learn about? (I’m all for learning!)
Yes, you will need to write the serialisation and deserialisation of your object yourself.
The easiest way is, since you know which objects are to be expected, to add the reading manually in getStateInformation() to the tree, like
(btw; does this look like it would actually work?)
The assertion I posted before happens in
void myAudioProcessor::getStateInformation(MemoryBlock& destData)
{ //parameters->data block (i.e save to project)
auto state = parameters.copyState();
std::unique_ptr<XmlElement> xml(state.createXml()); //assertion happens here
So the object I added couldn’t be turned into XML, I assume.
You indicate the custom serialise method is called in vt.setProperty().
Roughly speaking what would this method look like for a simple struct like I show above.
I’m assuming it would render the data as values that are compatible with the createXml() (and fromXml() to deserialise) ?
Yes, I would not put the object into the tree, but rather it’s state.
I was thinking, if there is something it tries to call when serialising the ValueTree, but I don’t think so. You cannot avoid this assert with an object in the state.
So I add a node to the valuetree that represents an object with maybe the nodetype to indicate the object type, and a list of property/value pairs to represent the state of items within the object?
I suppose this implies that var(&referenceCountedObject) is not useful in the case of APVTS though it may be in the general ValueTree case?
Thanks for your input.
Just to confirm: a serialise and deserialise method is written for each object type as required, and when it’s done this way the XML translation will yield a human readable version of the plugin tree state. The “readability” of the text values in the XML will of course be dependent on the serialisation technique in my code.
and a ValueTree::Listener reacts to propertyChanged applying it to setState (treeWhosePropertyHasChanged);
And a parent could create a new object, when a valueTreeAdded() is called etc. That way you can easily react to an undo manager.
Constructor creates a node that represents the object’s state. Adds the node to the VT state. This is done in the processor constructor after the plugin parameters have been made.
setState() updates/loads the object’s state from the VT
getState() transfers the object’s state into property/value pairs in a node then returns the node.
It follows that setState() would be called from setStateInformation() (load from host) and getState() would be called from getStateInformation()(save to host)?