The VST3 version of Voxengo TEOTE would deadlock in Ardour when Ardour
calls `IEditController::setState()`, the plugin calls
`IUnitHandler::notifyProgramListChange()` in response, and then when
Ardour calls `IUnitInfo::getProgramName()` while handling that callback.
All of these functions have to be called from the same thread in Voxengo
plugins.
Those DAWs would immediately call `IEditController::performEdit()` with
the same parameter change the plugin has just announced, which would
result in a deadlock. Hopefully this helps with #100.
This reverts commit a495f1a67f.
This ended up not being an issue. What we _do_ have to do, sadly, is to
have a mutual recursion context stack per plugin. Otherwise multiple
plugin instances can deadlock eachother.
FabFilter plugins will exchange messages that have to be handled from
the GUI thread, or they'll get stuck waiting on a synchronisation
object. This probably hurts GUI performance significantly but luckily it
only affects Ardour.
Instead of serializing the actual `YaMessage`, for the reasons mentioned
in the comments. This was needed to stop iZotope VocalSynth 2 in Ardour
from segfaulting when editing parameters, because that plugin is
apparently being very naughty.
I copied this from the SDK implementation and they don't do any pointer
casts there because it's not strictly necessary, but they're relying on
implementation details that may not always hold true.
It's not necessary, since all of these objects are simple data objects
that will be passed as arguments to other functions. When we have to
pass through one of those functions we can just serialize the objects at
that point.
iZotope plugins will already send messages when connect() is called on
the first object, so this flag has to be set on both host contexts at
the same time.
This has much fewer moving parts, and it's probably more understandable.
There was also a race condition in the previous implementation, so
there's that.
This requires a super hacky workaround because the UI thread can be
currently blocked by the plugin calling `IPlugFrame::resizeView()` from
the Win32 message loop.
As it turns out there are only two or three functions where we can do
this. It also breaks logging, and this function will probably only be
called once anyways. More consistency is always better.
This is quite a huge refactor, but note everything is consistent (and
we're going to need one or two more of these `Vst3*Proxy` objects).
Right now nothing extends `IHostApplication`, but this way it will be
trivial to add support for more host context interfaces.