How to save/restore plugin state during UndoManager Undo/Redo operations?

How to ensure that UndoManager works correctly when deleting and recreating VST/AU plugins during Undo/Redo operations?

I have MyClass which listens to ValueTree changes.

Every time a plugin ValueTree node is added, it creates instance of that plugin for itself.

Every time a plugin ValueTree node is removed, it deletes that instance of the plugin from itself.

But where to store the plugins state when it’s deleted, so it can be properly restored if/when UndoManager calls valueTreeChildAdded()?

If I store it into that deleted plugins ValueTree, that messes up UndoManager history. So what to do?

Here’s in a nutshell what my code is doing and what the problem is:

void MyClass::valueTreeChildAdded(...)
{
    // We end up here because of one of two reasons:
    // 1. User added new plugin node: create new plugin instance.
    // 2. UndoManager added back a previously deleted plugin node: restore that plugin instance with its saved plugin state. (WHERE TO GET THIS DATA?)
}


void MyClass::valueTreeChildRemoved(...)
{
    // We end up here because of one of two reasons:
    // 1. User deleted the plugin node: save the plugin state and delete plugin instance. (WHERE TO STORE THIS DATA?)
    // 2. UndoManager removed the plugin node: save the plugin state and delete plugin instance. (WHERE TO STORE THIS DATA?)
}

How to overcome this issue?

What would happen if I just saved the plugin data as a property inside the removed ValueTree node the following way inside valueTreeChildRemoved():

node_thats_removed.setProperty(plugin_state_id, plugin_state_data_block, nullptr);     // NULLPTR for UndoManager pointer!

That way the addition of property would probably not touch UndoManager history, because of NULLPTR given for UndoManager pointer. That would still change the actual ValueTree node so that the property is hopefully still there when UndoManager gives that ValueTree node back to valueTreeChildAdded() when user Undos the deletion of the plugin. Is that a viable and functional option? Would that cause trouble and will that even work at all?

I’m going to answer my own question:

When the plugin is first constructed by the user or by loading the project file, add the plugin instances smart pointer to its own ValueTree as a property. Now when the ValueTree gets removed from its parent, the smart pointer keeps the whole plugin, and its state, alive as long as it’s available in the UndoManager.

When user uses Undo/Redo, the plugin will not need to be reconstructed, but you just get its smart pointer from ValueTree property.

Depending on your code structure, you could also write your own UndoableAction for “delete plugin”, that itself keeps the plugin data alive.