We do this by using this new `MessageReference<T>` type to avoid copying
our `YaAudioProcessor::Process` struct and the contained `YaProcessData`
object. This is only part of the work, but this redesign lets us keep
the these objects alive on both the plugin and the host side. On the
plugin side, we'll simply serialize the data from the referred to object
without copying it. On the Wine side, we'll write the data to a
persistent thread local object, and then reassign the
`MessageReference<T>` to point to that object. This lets us serialize
'references', thus avoiding potentially expensive allocations. With
these last few changes alone VST3 plugins are already at the same
performance level as our optimized VST2 plugin groups.
This means that, we're now receiving into an existing `YaProcessData`
object, which should reduce the number of allocations on the Wine side
considerably. Next we should also reuse the `YaProcessDataResponse`
object.
We would close the socket, but the `receive_multi()` call would finish
after the object had already been deallocated using `erase()`. Somehow
this never caused any issues though.
If `yabridge-host.exe` were somehow to be run with a socket base
directory that's not inside of `$XDG_RUNTIME_DIR`/`/tmp`, then we'll now
warn instead of removing that directory. This should not be necessary,
but in case someone wants to write a wrapper around
`yabridge-host.exe.so` us using a custom `$WINELOADER` then this could
save a lot of headaches.
It turns out we can't safely disable this, because in some situations we
still have these mutually recursive function calls. We could optimize
this a bit to have those calls be handled by the general sockets, but
this is much more manageable.
This reverts commit 415c1b5683.
This way every relevant object instance will get its own thread for
handling these calls. The alternative would be creating a full fat
Vst3MessageHandler pair for all object instances, but that would be a
huge waste.
We'll need this for handling `IAudioProcessor` method calls in VST3. We
basically want a `Vst3MessageHandler` per `IAudioProcessor` instance,
but without the additional socket spawning or extra thread.
This now takes a regular overloaded function and the visiting is done in
`receive_messages()` itself. This way we can use templates to ensure
that the return type is correct. Otherwise auto will cause issues in the
future when we want to return multiple concrete types from a function
that takes a single variant. The alternative would be both receiving a
variant as a parameter and then returning another variant as a result,
but that is much less type safe.
- Now allows direct deserialization into existing objects. This will be
necessary for our VST3 implementations since the interface instances
we'll deserialize into will not be trivially constructable because
they have to be able to do callbacks.
- `ControlResponse` and `CallbackResponse` were dropped. These response
enums are not necessary because of the `T::Response` associated type
and returning the types directly makes the direct deserialization
possible.
We're going to need this for VST3 because we're going to have to
explicitly instantiate our interface implementations since they need to
be able to perform complicated callbacks.