Browse Source

Move code related to push-to-remote into a central file

Signed-off-by: falkTX <falktx@falktx.com>
tags/23.02
falkTX 2 years ago
parent
commit
b71acc9f22
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
15 changed files with 278 additions and 211 deletions
  1. +1
    -0
      src/Cardinal/CardinalRemote.cpp
  2. +30
    -39
      src/CardinalCommon.cpp
  3. +6
    -23
      src/CardinalCommon.hpp
  4. +1
    -0
      src/CardinalFX/CardinalRemote.cpp
  5. +1
    -0
      src/CardinalMini/CardinalRemote.cpp
  6. +1
    -0
      src/CardinalNative/CardinalRemote.cpp
  7. +3
    -5
      src/CardinalPlugin.cpp
  8. +162
    -0
      src/CardinalRemote.cpp
  9. +45
    -0
      src/CardinalRemote.hpp
  10. +1
    -0
      src/CardinalSynth/CardinalRemote.cpp
  11. +2
    -0
      src/Makefile.cardinal.mk
  12. +5
    -1
      src/PluginContext.hpp
  13. +9
    -7
      src/override/MenuBar.cpp
  14. +6
    -134
      src/override/Scene.cpp
  15. +5
    -2
      src/override/Window.cpp

+ 1
- 0
src/Cardinal/CardinalRemote.cpp View File

@@ -0,0 +1 @@
../CardinalRemote.cpp

+ 30
- 39
src/CardinalCommon.cpp View File

@@ -42,6 +42,14 @@
#include <app/Scene.hpp> #include <app/Scene.hpp>
#include <window/Window.hpp> #include <window/Window.hpp>


#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 #ifdef NDEBUG
# undef DEBUG # undef DEBUG
#endif #endif
@@ -54,12 +62,12 @@
# include <unistd.h> # include <unistd.h>
#endif #endif


#ifdef DISTRHO_OS_WASM
# include <emscripten/emscripten.h>
#ifdef CARDINAL_INIT_OSC_THREAD
# include <lo/lo.h>
#endif #endif


#ifndef DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
# error wrong build
#ifdef DISTRHO_OS_WASM
# include <emscripten/emscripten.h>
#endif #endif


#if defined(CARDINAL_COMMON_DSP_ONLY) || defined(HEADLESS) #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()"); d_stdout("osc_hello_handler()");
const lo_address source = lo_message_get_source(m); const lo_address source = lo_message_get_source(m);
lo_send_from(source, static_cast<Initializer*>(self)->oscServer, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok");
const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread);
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok");
return 0; return 0;
} }


@@ -248,7 +257,7 @@ static int osc_load_handler(const char*, const char* types, lo_arg** argv, int a


bool ok = false; bool ok = false;


if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->remotePluginInstance)
{ {
CardinalPluginContext* const context = plugin->context; CardinalPluginContext* const context = plugin->context;
std::vector<uint8_t> data(size); std::vector<uint8_t> 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); const lo_address source = lo_message_get_source(m);
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail");
const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread);
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail");
return 0; return 0;
} }


@@ -288,12 +297,12 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv,


bool ok = false; bool ok = false;


if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->remotePluginInstance)
ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer()); ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer());


const lo_address source = lo_message_get_source(m); const lo_address source = lo_message_get_source(m);
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail");
const lo_server server = lo_server_thread_get_server(static_cast<Initializer*>(self)->oscServerThread);
lo_send_from(source, server, LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail");
return 0; return 0;
} }
#endif #endif
@@ -432,15 +441,13 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB


#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
INFO("Initializing OSC Remote control"); 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 #else
INFO("OSC Remote control is not enabled in this build"); INFO("OSC Remote control is not enabled in this build");
#endif #endif
@@ -451,12 +458,11 @@ Initializer::~Initializer()
using namespace rack; using namespace rack;


#ifdef CARDINAL_INIT_OSC_THREAD #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 #endif


@@ -478,21 +484,6 @@ Initializer::~Initializer()
logger::destroy(); 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 END_NAMESPACE_DISTRHO


+ 6
- 23
src/CardinalCommon.hpp View File

@@ -21,13 +21,6 @@


#include <string> #include <string>


#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 DISTRHO_OS_WASM
# ifdef STATIC_BUILD # ifdef STATIC_BUILD
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv" # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv"
@@ -85,21 +78,17 @@ void saveAsDialogUncompressed();
void appendSelectionContextMenu(rack::ui::Menu* menu); void appendSelectionContextMenu(rack::ui::Menu* menu);
void openBrowser(const std::string& url); 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 } // namespace patchUtils


// ----------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------


#if defined(HAVE_LIBLO) && defined(HEADLESS) && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
// && defined(HEADLESS)
#if defined(HAVE_LIBLO)
# define CARDINAL_INIT_OSC_THREAD # define CARDINAL_INIT_OSC_THREAD
#endif #endif


typedef void* lo_server_thread;

START_NAMESPACE_DISTRHO START_NAMESPACE_DISTRHO


class CardinalBasePlugin; class CardinalBasePlugin;
@@ -107,22 +96,16 @@ class CardinalBaseUI;
struct CardinalPluginContext; struct CardinalPluginContext;


struct Initializer struct Initializer
#ifdef CARDINAL_INIT_OSC_THREAD
: public Thread
#endif
{ {
#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
lo_server oscServer = nullptr;
CardinalBasePlugin* oscPlugin = nullptr;
lo_server_thread oscServerThread = nullptr;
CardinalBasePlugin* remotePluginInstance = nullptr;
#endif #endif
std::string templatePath; std::string templatePath;
std::string factoryTemplatePath; std::string factoryTemplatePath;


Initializer(const CardinalBasePlugin* plugin, const CardinalBaseUI* ui); Initializer(const CardinalBasePlugin* plugin, const CardinalBaseUI* ui);
~Initializer(); ~Initializer();
#ifdef CARDINAL_INIT_OSC_THREAD
void run() override;
#endif
}; };


#ifndef HEADLESS #ifndef HEADLESS


+ 1
- 0
src/CardinalFX/CardinalRemote.cpp View File

@@ -0,0 +1 @@
../CardinalRemote.cpp

+ 1
- 0
src/CardinalMini/CardinalRemote.cpp View File

@@ -0,0 +1 @@
../CardinalRemote.cpp

+ 1
- 0
src/CardinalNative/CardinalRemote.cpp View File

@@ -0,0 +1 @@
../CardinalRemote.cpp

+ 3
- 5
src/CardinalPlugin.cpp View File

@@ -274,14 +274,15 @@ public:
} }
#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
fInitializer->oscPlugin = this;
fInitializer->remotePluginInstance = this;
#endif #endif
} }
~CardinalPlugin() override ~CardinalPlugin() override
{ {
#ifdef CARDINAL_INIT_OSC_THREAD #ifdef CARDINAL_INIT_OSC_THREAD
fInitializer->oscPlugin = nullptr;
if (fInitializer->remotePluginInstance == this)
fInitializer->remotePluginInstance = nullptr;
#endif #endif
{ {
@@ -844,9 +845,6 @@ protected:
if (std::strcmp(key, "screenshot") == 0) if (std::strcmp(key, "screenshot") == 0)
{ {
fState.screenshot = value; fState.screenshot = value;
#if defined(HAVE_LIBLO) && !defined(HEADLESS)
patchUtils::sendScreenshotToRemote(value);
#endif
return; return;
} }


+ 162
- 0
src/CardinalRemote.cpp View File

@@ -0,0 +1,162 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
*
* 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 <engine/Engine.hpp>
#include <patch.hpp>
#include <system.hpp>

#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 <lo/lo.h>
#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<RemoteDetails*>(self)->connected = true;
}
return 0;
}
#endif

RemoteDetails* getRemote()
{
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP);
DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, nullptr);

CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context->ui);
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, nullptr);

return ui->remoteDetails;
}

bool connectToRemote()
{
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP);
DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, false);

CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(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<lo_server>(remote->handle));
delete remote;
#endif
}
}

void idleRemote(RemoteDetails* const remote)
{
#ifdef HAVE_LIBLO
while (lo_server_recv_noblock(static_cast<lo_server>(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<uint8_t> 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<uint8_t> 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
}

}

// -----------------------------------------------------------------------------------------------------------

+ 45
- 0
src/CardinalRemote.hpp View File

@@ -0,0 +1,45 @@
/*
* DISTRHO Cardinal Plugin
* Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
*
* 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);

}

// -----------------------------------------------------------------------------------------------------------

+ 1
- 0
src/CardinalSynth/CardinalRemote.cpp View File

@@ -0,0 +1 @@
../CardinalRemote.cpp

+ 2
- 0
src/Makefile.cardinal.mk View File

@@ -96,6 +96,7 @@ endif


FILES_DSP = CardinalPlugin.cpp FILES_DSP = CardinalPlugin.cpp
FILES_DSP += CardinalCommon.cpp FILES_DSP += CardinalCommon.cpp
FILES_DSP += CardinalRemote.cpp
FILES_DSP += common.cpp FILES_DSP += common.cpp


ifeq ($(CARDINAL_VARIANT),mini) ifeq ($(CARDINAL_VARIANT),mini)
@@ -251,6 +252,7 @@ ifeq ($(CARDINAL_VARIANT),mini)
ifneq ($(HEADLESS),true) ifneq ($(HEADLESS),true)
FILES_UI = CardinalUI.cpp FILES_UI = CardinalUI.cpp
FILES_UI += CardinalCommon-UI.cpp FILES_UI += CardinalCommon-UI.cpp
FILES_UI += CardinalRemote.cpp
FILES_UI += common.cpp FILES_UI += common.cpp
FILES_UI += glfw.cpp FILES_UI += glfw.cpp
FILES_UI += Window.cpp FILES_UI += Window.cpp


+ 5
- 1
src/PluginContext.hpp View File

@@ -25,8 +25,8 @@
# undef DEBUG # undef DEBUG
#endif #endif


#include "CardinalRemote.hpp"
#include "DistrhoPlugin.hpp" #include "DistrhoPlugin.hpp"
#include "extra/Mutex.hpp"


#ifndef HEADLESS #ifndef HEADLESS
# include "DistrhoUI.hpp" # include "DistrhoUI.hpp"
@@ -148,6 +148,7 @@ struct WasmRemotePatchLoadingDialog;
class CardinalBaseUI : public UI { class CardinalBaseUI : public UI {
public: public:
CardinalPluginContext* const context; CardinalPluginContext* const context;
remoteUtils::RemoteDetails* remoteDetails;
bool saving; bool saving;
bool savingUncompressed; bool savingUncompressed;


@@ -166,6 +167,7 @@ public:
#else #else
context(new CardinalPluginContext(nullptr)), context(new CardinalPluginContext(nullptr)),
#endif #endif
remoteDetails(nullptr),
saving(false), saving(false),
savingUncompressed(false), savingUncompressed(false),
#ifdef DISTRHO_OS_WASM #ifdef DISTRHO_OS_WASM
@@ -180,6 +182,8 @@ public:


~CardinalBaseUI() override ~CardinalBaseUI() override
{ {
disconnectFromRemote(remoteDetails);

if (filebrowserhandle != nullptr) if (filebrowserhandle != nullptr)
fileBrowserClose(filebrowserhandle); fileBrowserClose(filebrowserhandle);




+ 9
- 7
src/override/MenuBar.cpp View File

@@ -52,6 +52,7 @@
#include <library.hpp> #include <library.hpp>


#include "../CardinalCommon.hpp" #include "../CardinalCommon.hpp"
#include "../CardinalRemote.hpp"
#include "DistrhoStandaloneUtils.hpp" #include "DistrhoStandaloneUtils.hpp"


#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
@@ -169,19 +170,20 @@ struct FileButton : MenuButton {
#ifdef HAVE_LIBLO #ifdef HAVE_LIBLO
menu->addChild(new ui::MenuSeparator); 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", "", menu->addChild(createCheckMenuItem("Auto deploy to MOD", "",
[=]() {return autoDeploy;},
[=]() {patchUtils::setRemoteAutoDeploy(!autoDeploy);}
[remoteDetails]() {return remoteDetails->autoDeploy;},
[remoteDetails]() {remoteDetails->autoDeploy = !remoteDetails->autoDeploy;}
)); ));
} else { } else {
menu->addChild(createMenuItem("Connect to MOD", "", []() { menu->addChild(createMenuItem("Connect to MOD", "", []() {
patchUtils::connectToRemote();
remoteUtils::connectToRemote();
})); }));
} }
#endif #endif


+ 6
- 134
src/override/Scene.cpp View File

@@ -25,10 +25,6 @@
* the License, or (at your option) any later version. * the License, or (at your option) any later version.
*/ */


#include <thread>

#include <osdialog.h>

#include <app/Scene.hpp> #include <app/Scene.hpp>
#include <app/Browser.hpp> #include <app/Browser.hpp>
#include <app/TipWindow.hpp> #include <app/TipWindow.hpp>
@@ -46,17 +42,8 @@
# undef DEBUG # undef DEBUG
#endif #endif


#ifdef STATIC_BUILD
# undef HAVE_LIBLO
#endif

#ifdef HAVE_LIBLO
# include <lo/lo.h>
#endif

#include "../CardinalCommon.hpp" #include "../CardinalCommon.hpp"
#include "extra/Base64.hpp"
#include "DistrhoUtils.hpp"
#include "../CardinalRemote.hpp"




namespace rack { namespace rack {
@@ -131,30 +118,8 @@ struct Scene::Internal {


bool heldArrowKeys[4] = {}; bool heldArrowKeys[4] = {};


#ifdef HAVE_LIBLO
double lastSceneChangeTime = 0.0; double lastSceneChangeTime = 0.0;
int historyActionIndex = -1; 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<Internal*>(self)->oscConnected = true;
}
return 0;
}

~Internal() {
lo_server_free(oscServer);
}
#endif
}; };




@@ -238,22 +203,20 @@ void Scene::step() {
rackScroll->offset += arrowDelta * arrowSpeed; 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 int actionIndex = APP->history->actionIndex;
const double time = system::getTime(); const double time = system::getTime();
if (internal->historyActionIndex != actionIndex && time - internal->lastSceneChangeTime >= 5.0) { if (internal->historyActionIndex != actionIndex && time - internal->lastSceneChangeTime >= 5.0) {
internal->historyActionIndex = actionIndex; internal->historyActionIndex = actionIndex;
internal->lastSceneChangeTime = time; internal->lastSceneChangeTime = time;
patchUtils::deployToRemote();
remoteUtils::deployToRemote(remoteDetails);
window::generateScreenshot(); window::generateScreenshot();
} }
} }
} }
#endif


Widget::step(); Widget::step();
} }
@@ -352,7 +315,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this); e.consume(this);
} }
if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) { if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) {
patchUtils::deployToRemote();
remoteUtils::deployToRemote(remoteUtils::getRemote());
window::generateScreenshot(); window::generateScreenshot();
e.consume(this); e.consume(this);
} }
@@ -489,94 +452,3 @@ void Scene::onPathDrop(const PathDropEvent& e) {


} // namespace app } // namespace app
} // namespace rack } // 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<uint8_t> 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<uint8_t> 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

+ 5
- 2
src/override/Window.cpp View File

@@ -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) { static void Window__writeImagePNG(void* context, void* data, int size) {
USE_NAMESPACE_DISTRHO USE_NAMESPACE_DISTRHO
UI* const ui = static_cast<UI*>(context);
ui->setState("screenshot", String::asBase64(data, size).buffer());
CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context);
if (const char* const screenshot = String::asBase64(data, size).buffer()) {
ui->setState("screenshot", screenshot);
remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot);
}
} }
#endif #endif
#endif #endif


Loading…
Cancel
Save