Handles for things like timers should be unique on a per-thread basis in
the Win32 API, but apparently window classes have to be unique for the
entire application.
This allows for a significant speedup in plugin scanning time for plugin
groups, since starting Wine processes takes up pretty much the entirety
of the time spent scanning plugins.
This was not a problem with individually hosted plugins because the
entire process got terminated at once, but here we all threads to shut
down gracefully when a plugin's sockets get closed. I wish this wouldn't
need all these try-catches, but we're not writing Haskell here.
The only issue remaining is that for some reason only the first
instance's editor works, at least for Serum. This might be because of
the message loop.
To prevent a race condition when an exiting plugin wants to terminate
the process when it think there are no plugins left just as another
yabridge instance is connecting to the group socket.
Some plugins would either crash or freeze on the next Win32 message loop
when `effEditGetRect` gets called before `effEditOpen` and we run the
message loop between these two event calls.
Fixes the issue with Superior Drummer 3 in Bitwig mentioned in #12 and a
similar issue with the Roland Cloud synths.
I had swapped these names around once before but I think going with
PluginBridge for the plugin and WineBridge for the Wine VST host is the
least ambiguous it can get.
This keeps compatibility with some weirdly designed plugins (such as
Kontakt) while avoiding some unnecessary data transformations. Before
this we'd convert from a `DynamicVstEvents` object to a `VstEvents`
object, back to a `DynamicVstEvents` and then finally back into another
`VstEvents` object. With this change we can skip the second half of the
conversions.
Also remove any special `effEditIdle` handling.
Apparently plugins rely on the message loop for their internal tasks,
even for things that have nothing to do with GUIs, such as deferring
initialization.
This should not make any difference, but if this event ever gets called
at the same time as the processing then this at least won't cause any
issues with plugins that are not thread safe themselves.