This is entirely implemented on the Wine side. I'll assume most Windows
plugins will use their own timers instead, but this could be useful for
plugins that try to use the same interface on all platforms.
We had to add an even hackier hack now to get Boost.Process to
interoperate with Asio's IO contexts. This will be replaced later when
we replace Boost.Process.
I'm not a fan of Hungarian notation, but C++ kind of needs it with its
implicit `this`. And of all the common options for this, I find
suffixing members with an underscore the least offensive one.
Since this was never stopped, the `watchdog_handler` thread would also
keep running. Since after e3f0926aef
everything is supposed to exit cleanly, this would cause group host
processes to hang and never exit. Tying the watchdog timer to
`MainContext::run()` is cleaner anyways.
On the Wine side. Instead of always having it enabled and disabling it
when it could potentially hurt (i.e. when handling GUI related things),
we'll now only enable it when it's potentially beneficial. This way we
don't have to constantly switch scheduling policies on the GUI thread.
This also changes the refresh rate for most plugins. You can now lower
this setting if your computer is struggling to keep up with rendering a
certain heavy plugin.
Although it hasn't shown up, this will get rid of the possibility of
off-thread effEditIdle calls causing issues. And since we need some way
to run call this function while the event loop is running anyways, doing
it entirely from a timer similar to how hosts on Windows would do it
seems like the best solution.
std::function does not allow non-movable lambdas, so capturing by move
doesn't work there. And the old solution of course has issues with
dangling pointers (but because this is C++ the compiler still thinks
it's A-Ok).
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.
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.