From b71acc9f22d70617739af6283bad589970d4e75d Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 29 Dec 2022 12:16:43 +0000 Subject: [PATCH] Move code related to push-to-remote into a central file Signed-off-by: falkTX --- src/Cardinal/CardinalRemote.cpp | 1 + src/CardinalCommon.cpp | 69 +++++------ src/CardinalCommon.hpp | 29 +---- src/CardinalFX/CardinalRemote.cpp | 1 + src/CardinalMini/CardinalRemote.cpp | 1 + src/CardinalNative/CardinalRemote.cpp | 1 + src/CardinalPlugin.cpp | 8 +- src/CardinalRemote.cpp | 162 ++++++++++++++++++++++++++ src/CardinalRemote.hpp | 45 +++++++ src/CardinalSynth/CardinalRemote.cpp | 1 + src/Makefile.cardinal.mk | 2 + src/PluginContext.hpp | 6 +- src/override/MenuBar.cpp | 16 +-- src/override/Scene.cpp | 140 +--------------------- src/override/Window.cpp | 7 +- 15 files changed, 278 insertions(+), 211 deletions(-) create mode 120000 src/Cardinal/CardinalRemote.cpp create mode 120000 src/CardinalFX/CardinalRemote.cpp create mode 120000 src/CardinalMini/CardinalRemote.cpp create mode 120000 src/CardinalNative/CardinalRemote.cpp create mode 100644 src/CardinalRemote.cpp create mode 100644 src/CardinalRemote.hpp create mode 120000 src/CardinalSynth/CardinalRemote.cpp diff --git a/src/Cardinal/CardinalRemote.cpp b/src/Cardinal/CardinalRemote.cpp new file mode 120000 index 0000000..2383823 --- /dev/null +++ b/src/Cardinal/CardinalRemote.cpp @@ -0,0 +1 @@ +../CardinalRemote.cpp \ No newline at end of file diff --git a/src/CardinalCommon.cpp b/src/CardinalCommon.cpp index 2e1ea73..c6efe8b 100644 --- a/src/CardinalCommon.cpp +++ b/src/CardinalCommon.cpp @@ -42,6 +42,14 @@ #include #include +#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +# error wrong build +#endif + +#if defined(STATIC_BUILD) || CARDINAL_VARIANT_MINI +# undef CARDINAL_INIT_OSC_THREAD +#endif + #ifdef NDEBUG # undef DEBUG #endif @@ -54,12 +62,12 @@ # include #endif -#ifdef DISTRHO_OS_WASM -# include +#ifdef CARDINAL_INIT_OSC_THREAD +# include #endif -#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS -# error wrong build +#ifdef DISTRHO_OS_WASM +# include #endif #if defined(CARDINAL_COMMON_DSP_ONLY) || defined(HEADLESS) @@ -230,7 +238,8 @@ static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_m { d_stdout("osc_hello_handler()"); const lo_address source = lo_message_get_source(m); - lo_send_from(source, static_cast(self)->oscServer, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); + const lo_server server = lo_server_thread_get_server(static_cast(self)->oscServerThread); + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok"); return 0; } @@ -248,7 +257,7 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a bool ok = false; - if (CardinalBasePlugin* const plugin = static_cast(self)->oscPlugin) + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) { CardinalPluginContext* const context = plugin->context; std::vector data(size); @@ -269,8 +278,8 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a } const lo_address source = lo_message_get_source(m); - lo_send_from(source, static_cast(self)->oscServer, - LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail"); + const lo_server server = lo_server_thread_get_server(static_cast(self)->oscServerThread); + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail"); return 0; } @@ -288,12 +297,12 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, bool ok = false; - if (CardinalBasePlugin* const plugin = static_cast(self)->oscPlugin) + if (CardinalBasePlugin* const plugin = static_cast(self)->remotePluginInstance) ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer()); const lo_address source = lo_message_get_source(m); - lo_send_from(source, static_cast(self)->oscServer, - LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail"); + const lo_server server = lo_server_thread_get_server(static_cast(self)->oscServerThread); + lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail"); return 0; } #endif @@ -432,15 +441,13 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB #ifdef CARDINAL_INIT_OSC_THREAD INFO("Initializing OSC Remote control"); - oscServer = lo_server_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler); - DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,); - - lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this); - lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this); - lo_server_add_method(oscServer, "/screenshot", "b", osc_screenshot_handler, this); - lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr); + oscServerThread = lo_server_thread_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler); + DISTRHO_SAFE_ASSERT_RETURN(oscServerThread != nullptr,); - startThread(); + lo_server_thread_add_method(oscServerThread, "/hello", "", osc_hello_handler, this); + lo_server_thread_add_method(oscServerThread, "/load", "b", osc_load_handler, this); + lo_server_thread_add_method(oscServerThread, "/screenshot", "b", osc_screenshot_handler, this); + lo_server_thread_add_method(oscServerThread, nullptr, nullptr, osc_fallback_handler, nullptr); #else INFO("OSC Remote control is not enabled in this build"); #endif @@ -451,12 +458,11 @@ Initializer::~Initializer() using namespace rack; #ifdef CARDINAL_INIT_OSC_THREAD - if (oscServer != nullptr) + if (oscServerThread != nullptr) { - stopThread(5000); - lo_server_del_method(oscServer, nullptr, nullptr); - lo_server_free(oscServer); - oscServer = nullptr; + lo_server_thread_del_method(oscServerThread, nullptr, nullptr); + lo_server_thread_free(oscServerThread); + oscServerThread = nullptr; } #endif @@ -478,21 +484,6 @@ Initializer::~Initializer() logger::destroy(); } -#ifdef CARDINAL_INIT_OSC_THREAD -void Initializer::run() -{ - INFO("OSC Thread Listening for remote commands"); - - while (! shouldThreadExit()) - { - d_msleep(200); - while (lo_server_recv_noblock(oscServer, 0) != 0) {} - } - - INFO("OSC Thread Closed"); -} -#endif - // -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO diff --git a/src/CardinalCommon.hpp b/src/CardinalCommon.hpp index 31a57d1..b411b81 100644 --- a/src/CardinalCommon.hpp +++ b/src/CardinalCommon.hpp @@ -21,13 +21,6 @@ #include -#ifdef HAVE_LIBLO -// # define REMOTE_HOST "localhost" -# define REMOTE_HOST "192.168.51.1" -# define REMOTE_HOST_PORT "2228" -# include "extra/Thread.hpp" -#endif - #ifdef DISTRHO_OS_WASM # ifdef STATIC_BUILD # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv" @@ -85,21 +78,17 @@ void saveAsDialogUncompressed(); void appendSelectionContextMenu(rack::ui::Menu* menu); void openBrowser(const std::string& url); -bool connectToRemote(); -bool isRemoteConnected(); -bool isRemoteAutoDeployed(); -void setRemoteAutoDeploy(bool autoDeploy); -void deployToRemote(); -void sendScreenshotToRemote(const char* screenshot); - } // namespace patchUtils // ----------------------------------------------------------------------------------------------------------- -#if defined(HAVE_LIBLO) && defined(HEADLESS) && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS +// && defined(HEADLESS) +#if defined(HAVE_LIBLO) # define CARDINAL_INIT_OSC_THREAD #endif +typedef void* lo_server_thread; + START_NAMESPACE_DISTRHO class CardinalBasePlugin; @@ -107,22 +96,16 @@ class CardinalBaseUI; struct CardinalPluginContext; struct Initializer -#ifdef CARDINAL_INIT_OSC_THREAD - : public Thread -#endif { #ifdef CARDINAL_INIT_OSC_THREAD - lo_server oscServer = nullptr; - CardinalBasePlugin* oscPlugin = nullptr; + lo_server_thread oscServerThread = nullptr; + CardinalBasePlugin* remotePluginInstance = nullptr; #endif std::string templatePath; std::string factoryTemplatePath; Initializer(const CardinalBasePlugin* plugin, const CardinalBaseUI* ui); ~Initializer(); -#ifdef CARDINAL_INIT_OSC_THREAD - void run() override; -#endif }; #ifndef HEADLESS diff --git a/src/CardinalFX/CardinalRemote.cpp b/src/CardinalFX/CardinalRemote.cpp new file mode 120000 index 0000000..2383823 --- /dev/null +++ b/src/CardinalFX/CardinalRemote.cpp @@ -0,0 +1 @@ +../CardinalRemote.cpp \ No newline at end of file diff --git a/src/CardinalMini/CardinalRemote.cpp b/src/CardinalMini/CardinalRemote.cpp new file mode 120000 index 0000000..2383823 --- /dev/null +++ b/src/CardinalMini/CardinalRemote.cpp @@ -0,0 +1 @@ +../CardinalRemote.cpp \ No newline at end of file diff --git a/src/CardinalNative/CardinalRemote.cpp b/src/CardinalNative/CardinalRemote.cpp new file mode 120000 index 0000000..2383823 --- /dev/null +++ b/src/CardinalNative/CardinalRemote.cpp @@ -0,0 +1 @@ +../CardinalRemote.cpp \ No newline at end of file diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 77917a4..7d26c11 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -274,14 +274,15 @@ public: } #ifdef CARDINAL_INIT_OSC_THREAD - fInitializer->oscPlugin = this; + fInitializer->remotePluginInstance = this; #endif } ~CardinalPlugin() override { #ifdef CARDINAL_INIT_OSC_THREAD - fInitializer->oscPlugin = nullptr; + if (fInitializer->remotePluginInstance == this) + fInitializer->remotePluginInstance = nullptr; #endif { @@ -844,9 +845,6 @@ protected: if (std::strcmp(key, "screenshot") == 0) { fState.screenshot = value; - #if defined(HAVE_LIBLO) && !defined(HEADLESS) - patchUtils::sendScreenshotToRemote(value); - #endif return; } diff --git a/src/CardinalRemote.cpp b/src/CardinalRemote.cpp new file mode 100644 index 0000000..5aabed0 --- /dev/null +++ b/src/CardinalRemote.cpp @@ -0,0 +1,162 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2022 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the LICENSE file. + */ + +#include +#include +#include + +#ifdef NDEBUG +# undef DEBUG +#endif + +#include "CardinalRemote.hpp" +#include "PluginContext.hpp" +#include "extra/Base64.hpp" + +#if defined(STATIC_BUILD) || CARDINAL_VARIANT_MINI +# undef HAVE_LIBLO +#endif + +#ifdef HAVE_LIBLO +# include +#endif + +// ----------------------------------------------------------------------------------------------------------- + +namespace remoteUtils { + +#ifdef HAVE_LIBLO +static int osc_handler(const char* const path, const char* const types, lo_arg** argv, const int argc, lo_message, void* const self) +{ + d_stdout("osc_handler(\"%s\", \"%s\", %p, %i)", path, types, argv, argc); + + if (std::strcmp(path, "/resp") == 0 && argc == 2 && types[0] == 's' && types[1] == 's') + { + d_stdout("osc_handler(\"%s\", ...) - got resp | '%s' '%s'", path, &argv[0]->s, &argv[1]->s); + + if (std::strcmp(&argv[0]->s, "hello") == 0 && std::strcmp(&argv[1]->s, "ok") == 0) + static_cast(self)->connected = true; + } + return 0; +} +#endif + +RemoteDetails* getRemote() +{ + CardinalPluginContext* const context = static_cast(APP); + DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, nullptr); + + CardinalBaseUI* const ui = static_cast(context->ui); + DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, nullptr); + + return ui->remoteDetails; +} + +bool connectToRemote() +{ + CardinalPluginContext* const context = static_cast(APP); + DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, false); + + CardinalBaseUI* const ui = static_cast(context->ui); + DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false); + + RemoteDetails* remoteDetails = ui->remoteDetails; + +#ifdef HAVE_LIBLO + if (remoteDetails == nullptr) + { + const lo_server oscServer = lo_server_new_with_proto(nullptr, LO_UDP, nullptr); + DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr, false); + + remoteDetails = new RemoteDetails; + remoteDetails->handle = oscServer; + remoteDetails->connected = false; + remoteDetails->autoDeploy = false; + + lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, remoteDetails); + } + + if (const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT)) + { + lo_send(addr, "/hello", ""); + lo_address_free(addr); + } +#endif + + return remoteDetails != nullptr; +} + +void disconnectFromRemote(RemoteDetails* const remote) +{ + if (remote != nullptr) + { + #ifdef HAVE_LIBLO + lo_server_free(static_cast(remote->handle)); + delete remote; + #endif + } +} + +void idleRemote(RemoteDetails* const remote) +{ +#ifdef HAVE_LIBLO + while (lo_server_recv_noblock(static_cast(remote->handle), 0) != 0) {} +#endif +} + +void deployToRemote(RemoteDetails* const remote) +{ +#ifdef HAVE_LIBLO + const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); + DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); + + APP->engine->prepareSave(); + APP->patch->saveAutosave(); + APP->patch->cleanAutosave(); + std::vector data(rack::system::archiveDirectory(APP->patch->autosavePath, 1)); + + if (const lo_blob blob = lo_blob_new(data.size(), data.data())) + { + lo_send(addr, "/load", "b", blob); + lo_blob_free(blob); + } + + lo_address_free(addr); +#endif +} + +void sendScreenshotToRemote(RemoteDetails* const remote, const char* const screenshot) +{ +#ifdef HAVE_LIBLO + const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); + DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); + + std::vector data(d_getChunkFromBase64String(screenshot)); + + if (const lo_blob blob = lo_blob_new(data.size(), data.data())) + { + lo_send(addr, "/screenshot", "b", blob); + lo_blob_free(blob); + } + + lo_address_free(addr); +#endif +} + +} + +// ----------------------------------------------------------------------------------------------------------- diff --git a/src/CardinalRemote.hpp b/src/CardinalRemote.hpp new file mode 100644 index 0000000..6467641 --- /dev/null +++ b/src/CardinalRemote.hpp @@ -0,0 +1,45 @@ +/* + * DISTRHO Cardinal Plugin + * Copyright (C) 2021-2022 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of + * the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the LICENSE file. + */ + +#pragma once + +#ifdef HAVE_LIBLO +// # define REMOTE_HOST "localhost" +# define REMOTE_HOST "192.168.51.1" +# define REMOTE_HOST_PORT "2228" +#endif + +// ----------------------------------------------------------------------------------------------------------- + +namespace remoteUtils { + +struct RemoteDetails { + void* handle; + bool connected; + bool autoDeploy; +}; + +RemoteDetails* getRemote(); +bool connectToRemote(); +void disconnectFromRemote(RemoteDetails* remote); +void idleRemote(RemoteDetails* remote); +void deployToRemote(RemoteDetails* remote); +void sendScreenshotToRemote(RemoteDetails* remote, const char* screenshot); + +} + +// ----------------------------------------------------------------------------------------------------------- diff --git a/src/CardinalSynth/CardinalRemote.cpp b/src/CardinalSynth/CardinalRemote.cpp new file mode 120000 index 0000000..2383823 --- /dev/null +++ b/src/CardinalSynth/CardinalRemote.cpp @@ -0,0 +1 @@ +../CardinalRemote.cpp \ No newline at end of file diff --git a/src/Makefile.cardinal.mk b/src/Makefile.cardinal.mk index 0dbf35d..2226e34 100644 --- a/src/Makefile.cardinal.mk +++ b/src/Makefile.cardinal.mk @@ -96,6 +96,7 @@ endif FILES_DSP = CardinalPlugin.cpp FILES_DSP += CardinalCommon.cpp +FILES_DSP += CardinalRemote.cpp FILES_DSP += common.cpp ifeq ($(CARDINAL_VARIANT),mini) @@ -251,6 +252,7 @@ ifeq ($(CARDINAL_VARIANT),mini) ifneq ($(HEADLESS),true) FILES_UI = CardinalUI.cpp FILES_UI += CardinalCommon-UI.cpp +FILES_UI += CardinalRemote.cpp FILES_UI += common.cpp FILES_UI += glfw.cpp FILES_UI += Window.cpp diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp index 629bda2..94d696f 100644 --- a/src/PluginContext.hpp +++ b/src/PluginContext.hpp @@ -25,8 +25,8 @@ # undef DEBUG #endif +#include "CardinalRemote.hpp" #include "DistrhoPlugin.hpp" -#include "extra/Mutex.hpp" #ifndef HEADLESS # include "DistrhoUI.hpp" @@ -148,6 +148,7 @@ struct WasmRemotePatchLoadingDialog; class CardinalBaseUI : public UI { public: CardinalPluginContext* const context; + remoteUtils::RemoteDetails* remoteDetails; bool saving; bool savingUncompressed; @@ -166,6 +167,7 @@ public: #else context(new CardinalPluginContext(nullptr)), #endif + remoteDetails(nullptr), saving(false), savingUncompressed(false), #ifdef DISTRHO_OS_WASM @@ -180,6 +182,8 @@ public: ~CardinalBaseUI() override { + disconnectFromRemote(remoteDetails); + if (filebrowserhandle != nullptr) fileBrowserClose(filebrowserhandle); diff --git a/src/override/MenuBar.cpp b/src/override/MenuBar.cpp index c848e05..d75d8cc 100644 --- a/src/override/MenuBar.cpp +++ b/src/override/MenuBar.cpp @@ -52,6 +52,7 @@ #include #include "../CardinalCommon.hpp" +#include "../CardinalRemote.hpp" #include "DistrhoStandaloneUtils.hpp" #ifdef HAVE_LIBLO @@ -169,19 +170,20 @@ struct FileButton : MenuButton { #ifdef HAVE_LIBLO menu->addChild(new ui::MenuSeparator); - if (patchUtils::isRemoteConnected()) { - menu->addChild(createMenuItem("Deploy to MOD", "F7", []() { - patchUtils::deployToRemote(); + remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote(); + + if (remoteDetails != nullptr && remoteDetails->connected) { + menu->addChild(createMenuItem("Deploy to MOD", "F7", [remoteDetails]() { + remoteUtils::deployToRemote(remoteDetails); })); - const bool autoDeploy = patchUtils::isRemoteAutoDeployed(); menu->addChild(createCheckMenuItem("Auto deploy to MOD", "", - [=]() {return autoDeploy;}, - [=]() {patchUtils::setRemoteAutoDeploy(!autoDeploy);} + [remoteDetails]() {return remoteDetails->autoDeploy;}, + [remoteDetails]() {remoteDetails->autoDeploy = !remoteDetails->autoDeploy;} )); } else { menu->addChild(createMenuItem("Connect to MOD", "", []() { - patchUtils::connectToRemote(); + remoteUtils::connectToRemote(); })); } #endif diff --git a/src/override/Scene.cpp b/src/override/Scene.cpp index 8f4a9e8..032d4c2 100644 --- a/src/override/Scene.cpp +++ b/src/override/Scene.cpp @@ -25,10 +25,6 @@ * the License, or (at your option) any later version. */ -#include - -#include - #include #include #include @@ -46,17 +42,8 @@ # undef DEBUG #endif -#ifdef STATIC_BUILD -# undef HAVE_LIBLO -#endif - -#ifdef HAVE_LIBLO -# include -#endif - #include "../CardinalCommon.hpp" -#include "extra/Base64.hpp" -#include "DistrhoUtils.hpp" +#include "../CardinalRemote.hpp" namespace rack { @@ -131,30 +118,8 @@ struct Scene::Internal { bool heldArrowKeys[4] = {}; -#ifdef HAVE_LIBLO double lastSceneChangeTime = 0.0; int historyActionIndex = -1; - - bool oscAutoDeploy = false; - bool oscConnected = false; - lo_server oscServer = nullptr; - - static int osc_handler(const char* const path, const char* const types, lo_arg** argv, const int argc, lo_message, void* const self) - { - d_stdout("osc_handler(\"%s\", \"%s\", %p, %i)", path, types, argv, argc); - - if (std::strcmp(path, "/resp") == 0 && argc == 2 && types[0] == 's' && types[1] == 's') { - d_stdout("osc_handler(\"%s\", ...) - got resp | '%s' '%s'", path, &argv[0]->s, &argv[1]->s); - if (std::strcmp(&argv[0]->s, "hello") == 0 && std::strcmp(&argv[1]->s, "ok") == 0) - static_cast(self)->oscConnected = true; - } - return 0; - } - - ~Internal() { - lo_server_free(oscServer); - } -#endif }; @@ -238,22 +203,20 @@ void Scene::step() { rackScroll->offset += arrowDelta * arrowSpeed; } -#ifdef HAVE_LIBLO - if (internal->oscServer != nullptr) { - while (lo_server_recv_noblock(internal->oscServer, 0) != 0) {} + if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) { + idleRemote(remoteDetails); - if (internal->oscAutoDeploy) { + if (remoteDetails->autoDeploy) { const int actionIndex = APP->history->actionIndex; const double time = system::getTime(); if (internal->historyActionIndex != actionIndex && time - internal->lastSceneChangeTime >= 5.0) { internal->historyActionIndex = actionIndex; internal->lastSceneChangeTime = time; - patchUtils::deployToRemote(); + remoteUtils::deployToRemote(remoteDetails); window::generateScreenshot(); } } } -#endif Widget::step(); } @@ -352,7 +315,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { e.consume(this); } if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) { - patchUtils::deployToRemote(); + remoteUtils::deployToRemote(remoteUtils::getRemote()); window::generateScreenshot(); e.consume(this); } @@ -489,94 +452,3 @@ void Scene::onPathDrop(const PathDropEvent& e) { } // namespace app } // namespace rack - - -namespace patchUtils { - - -bool connectToRemote() { -#ifdef HAVE_LIBLO - rack::app::Scene::Internal* const internal = APP->scene->internal; - - if (internal->oscServer == nullptr) { - const lo_server oscServer = lo_server_new_with_proto(nullptr, LO_UDP, nullptr); - DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr, false); - lo_server_add_method(oscServer, "/resp", nullptr, rack::app::Scene::Internal::osc_handler, internal); - internal->oscServer = oscServer; - } - - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); - DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr, false); - lo_send(addr, "/hello", ""); - lo_address_free(addr); - - return true; -#else - return false; -#endif -} - - -bool isRemoteConnected() { -#ifdef HAVE_LIBLO - return APP->scene->internal->oscConnected; -#else - return false; -#endif -} - - -bool isRemoteAutoDeployed() { -#ifdef HAVE_LIBLO - return APP->scene->internal->oscAutoDeploy; -#else - return false; -#endif -} - - -void setRemoteAutoDeploy(bool autoDeploy) { -#ifdef HAVE_LIBLO - APP->scene->internal->oscAutoDeploy = autoDeploy; -#endif -} - - -void deployToRemote() { -#ifdef HAVE_LIBLO - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); - DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); - - APP->engine->prepareSave(); - APP->patch->saveAutosave(); - APP->patch->cleanAutosave(); - std::vector data(rack::system::archiveDirectory(APP->patch->autosavePath, 1)); - - if (const lo_blob blob = lo_blob_new(data.size(), data.data())) { - lo_send(addr, "/load", "b", blob); - lo_blob_free(blob); - } - - lo_address_free(addr); -#endif -} - - -void sendScreenshotToRemote(const char* const screenshot) { -#ifdef HAVE_LIBLO - const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT); - DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,); - - std::vector data(d_getChunkFromBase64String(screenshot)); - - if (const lo_blob blob = lo_blob_new(data.size(), data.data())) { - lo_send(addr, "/screenshot", "b", blob); - lo_blob_free(blob); - } - - lo_address_free(addr); -#endif -} - - -} // namespace patchUtils diff --git a/src/override/Window.cpp b/src/override/Window.cpp index 12c52d9..7c32b0c 100644 --- a/src/override/Window.cpp +++ b/src/override/Window.cpp @@ -584,8 +584,11 @@ static void Window__downscaleBitmap(uint8_t* pixels, int& width, int& height) { static void Window__writeImagePNG(void* context, void* data, int size) { USE_NAMESPACE_DISTRHO - UI* const ui = static_cast(context); - ui->setState("screenshot", String::asBase64(data, size).buffer()); + CardinalBaseUI* const ui = static_cast(context); + if (const char* const screenshot = String::asBase64(data, size).buffer()) { + ui->setState("screenshot", screenshot); + remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); + } } #endif #endif