Move all liblo stuff to the same file, add crude auto-deploy mode
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
31c108c9ae
commit
e29243af60
7 changed files with 347 additions and 175 deletions
|
@ -37,17 +37,12 @@
|
||||||
#include <string.hpp>
|
#include <string.hpp>
|
||||||
#include <system.hpp>
|
#include <system.hpp>
|
||||||
#include <app/Scene.hpp>
|
#include <app/Scene.hpp>
|
||||||
#include <engine/Engine.hpp>
|
|
||||||
#include <window/Window.hpp>
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
# undef DEBUG
|
# undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
|
||||||
# include <lo/lo.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for finding home dir
|
// for finding home dir
|
||||||
#ifndef ARCH_WIN
|
#ifndef ARCH_WIN
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
|
@ -215,27 +210,6 @@ void saveAsDialog()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void deployToMOD()
|
|
||||||
{
|
|
||||||
#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 async_dialog_filebrowser(const bool saving,
|
void async_dialog_filebrowser(const bool saving,
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
# define REMOTE_HOST_PORT "2228"
|
# define REMOTE_HOST_PORT "2228"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace rack
|
namespace rack {
|
||||||
{
|
|
||||||
|
|
||||||
namespace settings {
|
namespace settings {
|
||||||
extern int rateLimit;
|
extern int rateLimit;
|
||||||
|
@ -36,10 +35,9 @@ namespace ui {
|
||||||
struct Menu;
|
struct Menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace rack
|
||||||
|
|
||||||
namespace patchUtils
|
namespace patchUtils {
|
||||||
{
|
|
||||||
|
|
||||||
void loadDialog();
|
void loadDialog();
|
||||||
void loadPathDialog(const std::string& path);
|
void loadPathDialog(const std::string& path);
|
||||||
|
@ -49,6 +47,11 @@ void revertDialog();
|
||||||
void saveDialog(const std::string& path);
|
void saveDialog(const std::string& path);
|
||||||
void saveAsDialog();
|
void saveAsDialog();
|
||||||
void appendSelectionContextMenu(rack::ui::Menu* menu);
|
void appendSelectionContextMenu(rack::ui::Menu* menu);
|
||||||
void deployToMOD();
|
|
||||||
|
|
||||||
}
|
bool connectToRemote();
|
||||||
|
bool isRemoteConnected();
|
||||||
|
bool isRemoteAutoDeployed();
|
||||||
|
void setRemoteAutoDeploy(bool autoDeploy);
|
||||||
|
void deployToRemote();
|
||||||
|
|
||||||
|
} // namespace patchUtils
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
cd $(dirname ${0})
|
||||||
|
|
||||||
diff -U3 ../Rack/dep/oui-blendish/blendish.c blendish.c > diffs/blendish.c.diff
|
diff -U3 ../Rack/dep/oui-blendish/blendish.c blendish.c > diffs/blendish.c.diff
|
||||||
diff -U3 ../Rack/src/common.cpp common.cpp > diffs/common.cpp.diff
|
diff -U3 ../Rack/src/common.cpp common.cpp > diffs/common.cpp.diff
|
||||||
|
|
|
@ -86,27 +86,6 @@ struct MenuButton : ui::Button {
|
||||||
struct FileButton : MenuButton {
|
struct FileButton : MenuButton {
|
||||||
const bool isStandalone;
|
const bool isStandalone;
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
|
||||||
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<FileButton*>(self)->oscConnected = true;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~FileButton() {
|
|
||||||
lo_server_free(oscServer);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
FileButton(const bool standalone)
|
FileButton(const bool standalone)
|
||||||
: MenuButton(), isStandalone(standalone) {}
|
: MenuButton(), isStandalone(standalone) {}
|
||||||
|
|
||||||
|
@ -133,21 +112,19 @@ struct FileButton : MenuButton {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
#ifdef HAVE_LIBLO
|
||||||
if (oscServer == nullptr || !oscConnected) {
|
if (patchUtils::isRemoteConnected()) {
|
||||||
menu->addChild(createMenuItem("Connect to MOD", "", [this]() {
|
|
||||||
if (oscServer == nullptr) {
|
|
||||||
oscServer = lo_server_new_with_proto(nullptr, LO_UDP, nullptr);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,);
|
|
||||||
lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, this);
|
|
||||||
}
|
|
||||||
const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,);
|
|
||||||
lo_send(addr, "/hello", "");
|
|
||||||
lo_address_free(addr);
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
|
menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
|
||||||
patchUtils::deployToMOD();
|
patchUtils::deployToRemote();
|
||||||
|
}));
|
||||||
|
|
||||||
|
const bool autoDeploy = patchUtils::isRemoteAutoDeployed();
|
||||||
|
menu->addChild(createCheckMenuItem("Auto deploy to MOD", "",
|
||||||
|
[=]() {return autoDeploy;},
|
||||||
|
[=]() {patchUtils::setRemoteAutoDeploy(!autoDeploy);}
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
menu->addChild(createMenuItem("Connect to MOD", "", [this]() {
|
||||||
|
patchUtils::connectToRemote();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -171,15 +148,6 @@ struct FileButton : MenuButton {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
|
||||||
void step() override {
|
|
||||||
MenuButton::step();
|
|
||||||
if (oscServer != nullptr) {
|
|
||||||
while (lo_server_recv_noblock(oscServer, 0) != 0) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <app/TipWindow.hpp>
|
#include <app/TipWindow.hpp>
|
||||||
#include <app/MenuBar.hpp>
|
#include <app/MenuBar.hpp>
|
||||||
#include <context.hpp>
|
#include <context.hpp>
|
||||||
|
#include <engine/Engine.hpp>
|
||||||
#include <system.hpp>
|
#include <system.hpp>
|
||||||
#include <network.hpp>
|
#include <network.hpp>
|
||||||
#include <history.hpp>
|
#include <history.hpp>
|
||||||
|
@ -41,7 +42,16 @@
|
||||||
#include <patch.hpp>
|
#include <patch.hpp>
|
||||||
#include <asset.hpp>
|
#include <asset.hpp>
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
# undef DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBLO
|
||||||
|
# include <lo/lo.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../CardinalCommon.hpp"
|
#include "../CardinalCommon.hpp"
|
||||||
|
#include "DistrhoUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
|
@ -92,14 +102,34 @@ struct Scene::Internal {
|
||||||
ResizeHandle* resizeHandle;
|
ResizeHandle* resizeHandle;
|
||||||
|
|
||||||
bool heldArrowKeys[4] = {};
|
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<Internal*>(self)->oscConnected = true;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Internal() {
|
||||||
|
lo_server_free(oscServer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void hideResizeHandle(Scene* scene) {
|
|
||||||
scene->internal->resizeHandle->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Scene::Scene() {
|
Scene::Scene() {
|
||||||
internal = new Internal;
|
internal = new Internal;
|
||||||
|
|
||||||
|
@ -121,6 +151,11 @@ Scene::Scene() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void hideResizeHandle(Scene* scene) {
|
||||||
|
scene->internal->resizeHandle->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
delete internal;
|
delete internal;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +202,22 @@ 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 (internal->oscAutoDeploy) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Widget::step();
|
Widget::step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +309,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::deployToMOD();
|
patchUtils::deployToRemote();
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,3 +435,73 @@ void Scene::onPathDrop(const PathDropEvent& e) {
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace rack
|
} // namespace rack
|
||||||
|
|
||||||
|
|
||||||
|
namespace patchUtils {
|
||||||
|
|
||||||
|
|
||||||
|
bool connectToRemote() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace patchUtils
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--- ../Rack/src/app/MenuBar.cpp 2022-01-15 14:44:46.391280963 +0000
|
--- ../Rack/src/app/MenuBar.cpp 2022-01-15 14:44:46.391280963 +0000
|
||||||
+++ MenuBar.cpp 2022-01-23 17:13:16.500279828 +0000
|
+++ MenuBar.cpp 2022-01-24 11:25:15.507061204 +0000
|
||||||
@@ -1,8 +1,33 @@
|
@@ -1,8 +1,33 @@
|
||||||
+/*
|
+/*
|
||||||
+ * DISTRHO Cardinal Plugin
|
+ * DISTRHO Cardinal Plugin
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -48,80 +78,108 @@
|
@@ -48,79 +78,75 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,27 +73,6 @@
|
||||||
struct FileButton : MenuButton {
|
struct FileButton : MenuButton {
|
||||||
+ const bool isStandalone;
|
+ const bool isStandalone;
|
||||||
+
|
+
|
||||||
+#ifdef HAVE_LIBLO
|
|
||||||
+ 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<FileButton*>(self)->oscConnected = true;
|
|
||||||
+ }
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ~FileButton() {
|
|
||||||
+ lo_server_free(oscServer);
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+ FileButton(const bool standalone)
|
+ FileButton(const bool standalone)
|
||||||
+ : MenuButton(), isStandalone(standalone) {}
|
+ : MenuButton(), isStandalone(standalone) {}
|
||||||
+
|
+
|
||||||
|
@ -124,10 +103,6 @@
|
||||||
-
|
-
|
||||||
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
|
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
|
||||||
- APP->patch->saveDialog();
|
- APP->patch->saveDialog();
|
||||||
- }));
|
|
||||||
-
|
|
||||||
- menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() {
|
|
||||||
- APP->patch->saveAsDialog();
|
|
||||||
+ // NOTE: will do nothing if path is empty, intentionally
|
+ // NOTE: will do nothing if path is empty, intentionally
|
||||||
+ patchUtils::saveDialog(APP->patch->path);
|
+ patchUtils::saveDialog(APP->patch->path);
|
||||||
+ }, APP->patch->path.empty()));
|
+ }, APP->patch->path.empty()));
|
||||||
|
@ -136,25 +111,26 @@
|
||||||
+ patchUtils::saveAsDialog();
|
+ patchUtils::saveAsDialog();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
- menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() {
|
||||||
|
- APP->patch->saveAsDialog();
|
||||||
|
- }));
|
||||||
|
+#ifdef HAVE_LIBLO
|
||||||
|
+ if (patchUtils::isRemoteConnected()) {
|
||||||
|
+ menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
|
||||||
|
+ patchUtils::deployToRemote();
|
||||||
|
+ }));
|
||||||
|
|
||||||
- menu->addChild(createMenuItem("Save a copy", "", []() {
|
- menu->addChild(createMenuItem("Save a copy", "", []() {
|
||||||
- APP->patch->saveAsDialog(false);
|
- APP->patch->saveAsDialog(false);
|
||||||
- }));
|
- }));
|
||||||
+#ifdef HAVE_LIBLO
|
+ const bool autoDeploy = patchUtils::isRemoteAutoDeployed();
|
||||||
+ if (oscServer == nullptr || !oscConnected) {
|
+ menu->addChild(createCheckMenuItem("Auto deploy to MOD", "",
|
||||||
+ menu->addChild(createMenuItem("Connect to MOD", "", [this]() {
|
+ [=]() {return autoDeploy;},
|
||||||
+ if (oscServer == nullptr) {
|
+ [=]() {patchUtils::setRemoteAutoDeploy(!autoDeploy);}
|
||||||
+ oscServer = lo_server_new_with_proto(nullptr, LO_UDP, nullptr);
|
+ ));
|
||||||
+ DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,);
|
|
||||||
+ lo_server_add_method(oscServer, "/resp", nullptr, osc_handler, this);
|
|
||||||
+ }
|
|
||||||
+ const lo_address addr = lo_address_new_with_proto(LO_UDP, REMOTE_HOST, REMOTE_HOST_PORT);
|
|
||||||
+ DISTRHO_SAFE_ASSERT_RETURN(addr != nullptr,);
|
|
||||||
+ lo_send(addr, "/hello", "");
|
|
||||||
+ lo_address_free(addr);
|
|
||||||
+ }));
|
|
||||||
+ } else {
|
+ } else {
|
||||||
+ menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
|
+ menu->addChild(createMenuItem("Connect to MOD", "", [this]() {
|
||||||
+ patchUtils::deployToMOD();
|
+ patchUtils::connectToRemote();
|
||||||
+ }));
|
+ }));
|
||||||
+ }
|
+ }
|
||||||
+#endif
|
+#endif
|
||||||
|
@ -189,19 +165,9 @@
|
||||||
+ }));
|
+ }));
|
||||||
+ };
|
+ };
|
||||||
}
|
}
|
||||||
+
|
|
||||||
+#ifdef HAVE_LIBLO
|
|
||||||
+ void step() override {
|
|
||||||
+ MenuButton::step();
|
|
||||||
+ if (oscServer != nullptr) {
|
|
||||||
+ while (lo_server_recv_noblock(oscServer, 0) != 0) {}
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -166,7 +192,7 @@
|
||||||
@@ -166,7 +224,7 @@
|
|
||||||
|
|
||||||
menu->addChild(new ui::MenuSeparator);
|
menu->addChild(new ui::MenuSeparator);
|
||||||
|
|
||||||
|
@ -210,7 +176,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -256,7 +314,7 @@
|
@@ -256,7 +282,7 @@
|
||||||
return settings::cableTension;
|
return settings::cableTension;
|
||||||
}
|
}
|
||||||
float getDefaultValue() override {
|
float getDefaultValue() override {
|
||||||
|
@ -219,7 +185,7 @@
|
||||||
}
|
}
|
||||||
float getDisplayValue() override {
|
float getDisplayValue() override {
|
||||||
return getValue() * 100;
|
return getValue() * 100;
|
||||||
@@ -421,28 +479,9 @@
|
@@ -421,28 +447,9 @@
|
||||||
haloBrightnessSlider->box.size.x = 250.0;
|
haloBrightnessSlider->box.size.x = 250.0;
|
||||||
menu->addChild(haloBrightnessSlider);
|
menu->addChild(haloBrightnessSlider);
|
||||||
|
|
||||||
|
@ -249,7 +215,7 @@
|
||||||
|
|
||||||
static const std::vector<std::string> knobModeLabels = {
|
static const std::vector<std::string> knobModeLabels = {
|
||||||
"Linear",
|
"Linear",
|
||||||
@@ -467,6 +506,21 @@
|
@@ -467,6 +474,21 @@
|
||||||
menu->addChild(knobScrollSensitivitySlider);
|
menu->addChild(knobScrollSensitivitySlider);
|
||||||
|
|
||||||
menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules));
|
menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules));
|
||||||
|
@ -271,7 +237,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -476,47 +530,6 @@
|
@@ -476,47 +498,6 @@
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,7 +285,7 @@
|
||||||
struct EngineButton : MenuButton {
|
struct EngineButton : MenuButton {
|
||||||
void onAction(const ActionEvent& e) override {
|
void onAction(const ActionEvent& e) override {
|
||||||
ui::Menu* menu = createMenu();
|
ui::Menu* menu = createMenu();
|
||||||
@@ -529,269 +542,6 @@
|
@@ -529,269 +510,6 @@
|
||||||
menu->addChild(createMenuItem("Performance meters", cpuMeterText, [=]() {
|
menu->addChild(createMenuItem("Performance meters", cpuMeterText, [=]() {
|
||||||
settings::cpuMeter ^= true;
|
settings::cpuMeter ^= true;
|
||||||
}));
|
}));
|
||||||
|
@ -589,7 +555,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -802,63 +552,24 @@
|
@@ -802,63 +520,24 @@
|
||||||
|
|
||||||
|
|
||||||
struct HelpButton : MenuButton {
|
struct HelpButton : MenuButton {
|
||||||
|
@ -616,14 +582,14 @@
|
||||||
|
|
||||||
- menu->addChild(createMenuItem("VCVRack.com", "", [=]() {
|
- menu->addChild(createMenuItem("VCVRack.com", "", [=]() {
|
||||||
- system::openBrowser("https://vcvrack.com/");
|
- system::openBrowser("https://vcvrack.com/");
|
||||||
- }));
|
|
||||||
-
|
|
||||||
- menu->addChild(createMenuItem("Open user folder", "", [=]() {
|
|
||||||
- system::openDirectory(asset::user(""));
|
|
||||||
+ menu->addChild(createMenuItem("Cardinal Project page", "", [=]() {
|
+ menu->addChild(createMenuItem("Cardinal Project page", "", [=]() {
|
||||||
+ system::openBrowser("https://github.com/DISTRHO/Cardinal/");
|
+ system::openBrowser("https://github.com/DISTRHO/Cardinal/");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
- menu->addChild(createMenuItem("Open user folder", "", [=]() {
|
||||||
|
- system::openDirectory(asset::user(""));
|
||||||
|
- }));
|
||||||
|
-
|
||||||
- if (library::isAppUpdateAvailable()) {
|
- if (library::isAppUpdateAvailable()) {
|
||||||
- menu->addChild(new ui::MenuSeparator);
|
- menu->addChild(new ui::MenuSeparator);
|
||||||
-
|
-
|
||||||
|
@ -658,7 +624,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -908,7 +619,9 @@
|
@@ -908,7 +587,9 @@
|
||||||
struct MenuBar : widget::OpaqueWidget {
|
struct MenuBar : widget::OpaqueWidget {
|
||||||
MeterLabel* meterLabel;
|
MeterLabel* meterLabel;
|
||||||
|
|
||||||
|
@ -669,7 +635,7 @@
|
||||||
const float margin = 5;
|
const float margin = 5;
|
||||||
box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
|
box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
|
||||||
|
|
||||||
@@ -917,7 +630,7 @@
|
@@ -917,7 +598,7 @@
|
||||||
layout->spacing = math::Vec(0, 0);
|
layout->spacing = math::Vec(0, 0);
|
||||||
addChild(layout);
|
addChild(layout);
|
||||||
|
|
||||||
|
@ -678,7 +644,7 @@
|
||||||
fileButton->text = "File";
|
fileButton->text = "File";
|
||||||
layout->addChild(fileButton);
|
layout->addChild(fileButton);
|
||||||
|
|
||||||
@@ -933,10 +646,6 @@
|
@@ -933,10 +614,6 @@
|
||||||
engineButton->text = "Engine";
|
engineButton->text = "Engine";
|
||||||
layout->addChild(engineButton);
|
layout->addChild(engineButton);
|
||||||
|
|
||||||
|
@ -689,7 +655,7 @@
|
||||||
HelpButton* helpButton = new HelpButton;
|
HelpButton* helpButton = new HelpButton;
|
||||||
helpButton->text = "Help";
|
helpButton->text = "Help";
|
||||||
layout->addChild(helpButton);
|
layout->addChild(helpButton);
|
||||||
@@ -971,7 +680,11 @@
|
@@ -971,7 +648,11 @@
|
||||||
|
|
||||||
|
|
||||||
widget::Widget* createMenuBar() {
|
widget::Widget* createMenuBar() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--- ../Rack/src/app/Scene.cpp 2021-12-14 21:35:44.414568198 +0000
|
--- ../Rack/src/app/Scene.cpp 2021-12-14 21:35:44.414568198 +0000
|
||||||
+++ Scene.cpp 2022-01-23 17:13:24.715889665 +0000
|
+++ Scene.cpp 2022-01-24 11:12:33.268767988 +0000
|
||||||
@@ -1,3 +1,30 @@
|
@@ -1,3 +1,30 @@
|
||||||
+/*
|
+/*
|
||||||
+ * DISTRHO Cardinal Plugin
|
+ * DISTRHO Cardinal Plugin
|
||||||
|
@ -31,11 +31,28 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <osdialog.h>
|
#include <osdialog.h>
|
||||||
@@ -14,31 +41,49 @@
|
@@ -7,6 +34,7 @@
|
||||||
|
#include <app/TipWindow.hpp>
|
||||||
|
#include <app/MenuBar.hpp>
|
||||||
|
#include <context.hpp>
|
||||||
|
+#include <engine/Engine.hpp>
|
||||||
|
#include <system.hpp>
|
||||||
|
#include <network.hpp>
|
||||||
|
#include <history.hpp>
|
||||||
|
@@ -14,31 +42,58 @@
|
||||||
#include <patch.hpp>
|
#include <patch.hpp>
|
||||||
#include <asset.hpp>
|
#include <asset.hpp>
|
||||||
|
|
||||||
|
+#ifdef NDEBUG
|
||||||
|
+# undef DEBUG
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_LIBLO
|
||||||
|
+# include <lo/lo.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
+#include "../CardinalCommon.hpp"
|
+#include "../CardinalCommon.hpp"
|
||||||
|
+#include "DistrhoUtils.hpp"
|
||||||
+
|
+
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
|
@ -74,16 +91,16 @@
|
||||||
+ nvgStroke(args.vg);
|
+ nvgStroke(args.vg);
|
||||||
+
|
+
|
||||||
+ nvgStrokeColor(args.vg, nvgRGBf(0, 0, 0));
|
+ nvgStrokeColor(args.vg, nvgRGBf(0, 0, 0));
|
||||||
+
|
|
||||||
+ nvgBeginPath(args.vg);
|
|
||||||
+ nvgMoveTo(args.vg, box.size.x+1, 0);
|
|
||||||
+ nvgLineTo(args.vg, 0, box.size.y+1);
|
|
||||||
+ nvgStroke(args.vg);
|
|
||||||
|
|
||||||
- void onDragMove(const DragMoveEvent& e) override {
|
- void onDragMove(const DragMoveEvent& e) override {
|
||||||
- size = size.plus(e.mouseDelta);
|
- size = size.plus(e.mouseDelta);
|
||||||
- APP->window->setSize(size.round());
|
- APP->window->setSize(size.round());
|
||||||
+ nvgBeginPath(args.vg);
|
+ nvgBeginPath(args.vg);
|
||||||
|
+ nvgMoveTo(args.vg, box.size.x+1, 0);
|
||||||
|
+ nvgLineTo(args.vg, 0, box.size.y+1);
|
||||||
|
+ nvgStroke(args.vg);
|
||||||
|
+
|
||||||
|
+ nvgBeginPath(args.vg);
|
||||||
+ nvgMoveTo(args.vg, box.size.x + 6, 0);
|
+ nvgMoveTo(args.vg, box.size.x + 6, 0);
|
||||||
+ nvgLineTo(args.vg, 0, box.size.y + 6);
|
+ nvgLineTo(args.vg, 0, box.size.y + 6);
|
||||||
+ nvgStroke(args.vg);
|
+ nvgStroke(args.vg);
|
||||||
|
@ -95,25 +112,42 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,12 +91,15 @@
|
@@ -46,9 +101,32 @@
|
||||||
struct Scene::Internal {
|
struct Scene::Internal {
|
||||||
ResizeHandle* resizeHandle;
|
ResizeHandle* resizeHandle;
|
||||||
|
|
||||||
- double lastAutosaveTime = 0.0;
|
- double lastAutosaveTime = 0.0;
|
||||||
-
|
-
|
||||||
bool heldArrowKeys[4] = {};
|
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<Internal*>(self)->oscConnected = true;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ~Internal() {
|
||||||
|
+ lo_server_free(oscServer);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
+void hideResizeHandle(Scene* scene) {
|
@@ -67,17 +145,17 @@
|
||||||
+ scene->internal->resizeHandle->hide();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
Scene::Scene() {
|
|
||||||
internal = new Internal;
|
|
||||||
|
|
||||||
@@ -67,13 +115,8 @@
|
|
||||||
browser->hide();
|
browser->hide();
|
||||||
addChild(browser);
|
addChild(browser);
|
||||||
|
|
||||||
|
@ -128,7 +162,16 @@
|
||||||
addChild(internal->resizeHandle);
|
addChild(internal->resizeHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,32 +132,13 @@
|
|
||||||
|
+void hideResizeHandle(Scene* scene) {
|
||||||
|
+ scene->internal->resizeHandle->hide();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
Scene::~Scene() {
|
||||||
|
delete internal;
|
||||||
|
}
|
||||||
|
@@ -89,32 +167,13 @@
|
||||||
|
|
||||||
|
|
||||||
void Scene::step() {
|
void Scene::step() {
|
||||||
|
@ -162,7 +205,30 @@
|
||||||
// Scroll RackScrollWidget with arrow keys
|
// Scroll RackScrollWidget with arrow keys
|
||||||
math::Vec arrowDelta;
|
math::Vec arrowDelta;
|
||||||
if (internal->heldArrowKeys[0]) {
|
if (internal->heldArrowKeys[0]) {
|
||||||
@@ -172,7 +196,7 @@
|
@@ -143,6 +202,22 @@
|
||||||
|
rackScroll->offset += arrowDelta * arrowSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef HAVE_LIBLO
|
||||||
|
+ if (internal->oscServer != nullptr) {
|
||||||
|
+ while (lo_server_recv_noblock(internal->oscServer, 0) != 0) {}
|
||||||
|
+
|
||||||
|
+ if (internal->oscAutoDeploy) {
|
||||||
|
+ 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();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
Widget::step();
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -172,7 +247,7 @@
|
||||||
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
|
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
|
||||||
// DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str());
|
// DEBUG("key '%d '%c' scancode %d '%c' keyName '%s'", e.key, e.key, e.scancode, e.scancode, e.keyName.c_str());
|
||||||
if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
if (e.keyName == "n" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
||||||
|
@ -171,7 +237,7 @@
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
if (e.keyName == "q" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
||||||
@@ -180,19 +204,20 @@
|
@@ -180,19 +255,20 @@
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
if (e.keyName == "o" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
if (e.keyName == "o" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
||||||
|
@ -196,7 +262,7 @@
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
if (e.keyName == "z" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
if (e.keyName == "z" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
||||||
@@ -232,10 +257,8 @@
|
@@ -232,10 +308,8 @@
|
||||||
settings::cpuMeter ^= true;
|
settings::cpuMeter ^= true;
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
|
@ -205,11 +271,11 @@
|
||||||
- // The MenuBar will be hidden when the mouse moves over the RackScrollWidget.
|
- // The MenuBar will be hidden when the mouse moves over the RackScrollWidget.
|
||||||
- // menuBar->hide();
|
- // menuBar->hide();
|
||||||
+ 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::deployToMOD();
|
+ patchUtils::deployToRemote();
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,13 +349,6 @@
|
@@ -326,13 +400,6 @@
|
||||||
|
|
||||||
// Key commands that can be overridden by children
|
// Key commands that can be overridden by children
|
||||||
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
|
if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) {
|
||||||
|
@ -223,7 +289,7 @@
|
||||||
if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
if (e.keyName == "v" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
|
||||||
rack->pasteClipboardAction();
|
rack->pasteClipboardAction();
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
@@ -351,7 +367,7 @@
|
@@ -351,7 +418,7 @@
|
||||||
std::string extension = system::getExtension(path);
|
std::string extension = system::getExtension(path);
|
||||||
|
|
||||||
if (extension == ".vcv") {
|
if (extension == ".vcv") {
|
||||||
|
@ -232,3 +298,77 @@
|
||||||
e.consume(this);
|
e.consume(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -368,3 +435,73 @@
|
||||||
|
|
||||||
|
} // namespace app
|
||||||
|
} // namespace rack
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+namespace patchUtils {
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+bool connectToRemote() {
|
||||||
|
+ 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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+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
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+} // namespace patchUtils
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue