I have found weird behavior in JUCE VST plugin which tries to create an editor two times (creates/removes/creates) and deletes all child components. I mean it should remove MainWindow and all child components will be destroyed due to std::unique_ptr but instead JUCE trying to destroy all child in deleteEditor->editorBeingDeleted->deleteAllChildren:
Ok, Let’s go forward with simple steps:
juce_VST_Wrapper.cpp, handleGetEditorBounds - first one editor created here
juce_VST_Wrapper.cpp, handleOpenEditor - second one here, and before create a new one it removing deleteEditor(true)
Some hosts may be open and close (create/delete) the editor multiple times in succession. That is just a thing you will have to be prepared for. Don’t do anything too expensive in the editor constructor.
Child UI components of MainWindow using juce::ChangeListener for event subscription and when MainWindow deletes earlier than the component itself I have a dangling pointer.
deleteAllChildren code removes child components without respect to parent (MainWindow) class. So, Instead of removing all childrens first and then remove MainWindow it removes all components in some free order.
Ok, I have moved ChangeBroadcaster out from the MainWindow into the AudioProcessor class and now it works normally and GUI components could normally add a listener in the constructor and remove it in the destructor. But in my opinion right place for ChangeBroadcaster should be in MainWindow because of user actions.
that sounds like the wrong design decision, making your AudioProcessor a change broadcaster.
Your editor should poll the atomic values that live in your processor with a Timer. ChangeBroadcaster uses AsyncUpdater internally to broadcast the message.
so, there ya go. Calling triggerAsyncUpdate() from the audio thread locks and makes system calls.
and that is what happens when you call sendChangeMessage() from the audio thread:
void ChangeBroadcaster::sendChangeMessage()
{
if (anyListeners)
broadcastCallback.triggerAsyncUpdate();
}
I’m not blocking the main audio thread, instead, I have another thread that listens to DSP changes and if occurs asks ChangeBroadcaster to send messages for all.
Also, the editor could ask ChangeBroadcaster to signal all others components using atomic events.