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:
falkTX 2022-01-24 11:28:23 +00:00
parent 31c108c9ae
commit e29243af60
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
7 changed files with 347 additions and 175 deletions

View file

@ -34,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>
@ -41,7 +42,16 @@
#include <patch.hpp>
#include <asset.hpp>
#ifdef NDEBUG
# undef DEBUG
#endif
#ifdef HAVE_LIBLO
# include <lo/lo.h>
#endif
#include "../CardinalCommon.hpp"
#include "DistrhoUtils.hpp"
namespace rack {
@ -92,14 +102,34 @@ struct Scene::Internal {
ResizeHandle* resizeHandle;
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() {
internal = new Internal;
@ -121,6 +151,11 @@ Scene::Scene() {
}
void hideResizeHandle(Scene* scene) {
scene->internal->resizeHandle->hide();
}
Scene::~Scene() {
delete internal;
}
@ -167,6 +202,22 @@ void Scene::step() {
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();
}
@ -258,7 +309,7 @@ void Scene::onHoverKey(const HoverKeyEvent& e) {
e.consume(this);
}
if (e.key == GLFW_KEY_F7 && (e.mods & RACK_MOD_MASK) == 0) {
patchUtils::deployToMOD();
patchUtils::deployToRemote();
e.consume(this);
}
@ -384,3 +435,73 @@ void Scene::onPathDrop(const PathDropEvent& e) {
} // 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