Since it does something way more involved than
`SocketHandler::{send,receive_multi}`, and that makes it a bit confusing
if you don't already know about that (and even if you do).
This will require more testing of course, but I think it should be safe.
This would increase the potential maximal throughput in group hosts
significantly.
When the message loop is active and we get an incoming dispatch() event,
we'll just handle it directly. In practice this would only be needed
when the event is a response to an `audioMaster()` call made during the
event loop, but we can't know that. This allows the `getProgram()`
during `audioMasterUpdateDisplay()` in REAPER and Renoise to work
correctly. Hopefully this doesn't cause random rare breakage.
On the Wine side we want to handle most events on the main UI thread.
We'll assume any events coming in from a secondary socket are safe and
can be handled directly.
This is a pretty huge change that will be important for being able to
handle nested or mutually recursive `dispatch()` and `audioMaster()`
calls. This sadly all had to be done in a single commit, so here's a
summary:
- `src/common/sockets.h:Sockets` contains all sockets on both the plugin
and the Wine host side, and is used to both listen on and connect to
the sockets.
- Sockets and other temporary files respect `$XDG_RUNTIME_DIR` instead
of being dumped in `/tmp`.
- All sockets now have a unique endpoint in
`/run/user/<uid>/yabridge-<plugin_name>-<random_id>/`. This is
important for when we want to have multiple socket connections for
handling `dispatch()` and `audioMaster()`.
- Because of the above, we no longer clean up the socket endpoint files
after the connection gets established during initialization. Instead
we'll remove the socket base directory when shutting down.
This is not ideal since it requires the user to know about this option
and to create a config file, but I think it's the best we can do without
compromising on yabridge's transparency and 'zero hacks' philosophy.
See #29 and #32.
This works around Waves plugins causing an infinite message loop. Since
we run the loop 30 times per second anyways splitting the loop up into
chunks of 20 shouldn't be an issue.
This sounds like it would the simplest way to work around the issue of
E27 calculating its own coordinates based on the parent window's
coordinates. I have not noticed any weird issues with having this
enabled all the time, but less moving parts is always better so it's
still behind an option.
It's a bit clearer this way. I would prefer using jthreads here, but we
would still need this try-catch block since there's no way to cancel
synchronous Boost.Asio socket operations other than closing the socket.
I did not know that `std::optional::value()` did checked access. And I
still prefer a more explicit .has_value() over boolean conversion, but
this seems to be the accepted way to do this.
This reverts commit 0c047f9a66.
This workaround was needed because of the weird threading behavior with
the Win32 APIs, std::thread and winelib. Now that the actual
`active_plugins.erase()` call is done from within the plugin
context/main thread, this hack is no longer needed.
This makes the individual plugin host slightly more complex, but now
both individually hosted plugins and plugin groups handle both
dispatcher events and GUI events in the exact same way.
Should not matter that much, but a potential situation where you would
want to have handled the X11 events first is when the editor enters a
blocking message loop while it is waiting on a GUI component just as the
window gets moved by an external program or window manager.
At a 30 fps rate with a limit on the number of window messages per
frame. This is somehow needed for Melda plugins, as they otherwise
dispatch tiemr messages indefinitely after opening a second editor with
seemingly no way around it.
With this and some refactoring #15 should be almost done.
This is a bit more restrictive than the old approach that only skipped
when `effEditOpen()` got called after `effEditGetRect()`. Not sure why
the Melda plugins block indefinitely on the message loop without this
now.