Setup mini variant UI, move around more code to accomodate this
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
cf74324568
commit
a85679758c
12 changed files with 534 additions and 334 deletions
2
dpf
2
dpf
|
@ -1 +1 @@
|
|||
Subproject commit 564f6519b4bbf1c6cc8791a9adbb377f6cfd4984
|
||||
Subproject commit 79948069d581c64bd19bc454234550de88b459a2
|
|
@ -293,6 +293,10 @@ PLUGIN_FILES += Cardinal/src/ImGuiTextEditor.cpp
|
|||
PLUGIN_FILES += Cardinal/src/SassyScope.cpp
|
||||
PLUGIN_FILES += Cardinal/src/DearImGui.cpp
|
||||
PLUGIN_FILES += Cardinal/src/DearImGuiColorTextEditor.cpp
|
||||
MINIPLUGIN_FILES += Cardinal/src/ImGuiWidget.cpp
|
||||
MINIPLUGIN_FILES += Cardinal/src/ImGuiTextEditor.cpp
|
||||
MINIPLUGIN_FILES += Cardinal/src/DearImGui.cpp
|
||||
MINIPLUGIN_FILES += Cardinal/src/DearImGuiColorTextEditor.cpp
|
||||
endif
|
||||
|
||||
ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true)
|
||||
|
@ -1290,7 +1294,7 @@ endif
|
|||
ifeq ($(NOPLUGINS),true)
|
||||
TARGETS = noplugins$(TARGET_SUFFIX).a
|
||||
else
|
||||
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini-headless.a
|
||||
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini.a
|
||||
endif
|
||||
|
||||
all: $(TARGETS)
|
||||
|
|
|
@ -189,6 +189,7 @@ void destroyStaticPlugins()
|
|||
|
||||
void updateStaticPluginsDarkMode()
|
||||
{
|
||||
d_stdout("TODO");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <settings.hpp>
|
||||
#include <string.hpp>
|
||||
#include <system.hpp>
|
||||
#include <app/Browser.hpp>
|
||||
#include <app/Scene.hpp>
|
||||
#include <window/Window.hpp>
|
||||
|
||||
|
@ -65,6 +66,27 @@
|
|||
# define HEADLESS
|
||||
#endif
|
||||
|
||||
#if CARDINAL_VARIANT_FX
|
||||
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
|
||||
#elif CARDINAL_VARIANT_NATIVE
|
||||
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
|
||||
#elif CARDINAL_VARIANT_SYNTH
|
||||
# define CARDINAL_TEMPLATE_NAME "init/synth.vcv"
|
||||
#else
|
||||
# define CARDINAL_TEMPLATE_NAME "init/main.vcv"
|
||||
#endif
|
||||
|
||||
namespace rack {
|
||||
namespace asset {
|
||||
std::string patchesPath();
|
||||
void destroy();
|
||||
}
|
||||
namespace plugin {
|
||||
void initStaticPlugins();
|
||||
void destroyStaticPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
const std::string CARDINAL_VERSION = "22.12";
|
||||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
@ -172,6 +194,284 @@ void CardinalPluginContext::writeMidiMessage(const rack::midi::Message& message,
|
|||
plugin->writeMidiEvent(event);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
static void osc_error_handler(int num, const char* msg, const char* path)
|
||||
{
|
||||
d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path);
|
||||
}
|
||||
|
||||
static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*)
|
||||
{
|
||||
d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_hello_handler()");
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_load_handler()");
|
||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||
|
||||
const int32_t size = argv[0]->blob.size;
|
||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||
|
||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||
{
|
||||
CardinalPluginContext* const context = plugin->context;
|
||||
std::vector<uint8_t> data(size);
|
||||
std::memcpy(data.data(), blob, size);
|
||||
|
||||
rack::contextSet(context);
|
||||
rack::system::removeRecursively(context->patch->autosavePath);
|
||||
rack::system::createDirectories(context->patch->autosavePath);
|
||||
try {
|
||||
rack::system::unarchiveToDirectory(data, context->patch->autosavePath);
|
||||
context->patch->loadAutosave();
|
||||
ok = true;
|
||||
}
|
||||
catch (rack::Exception& e) {
|
||||
WARN("%s", e.what());
|
||||
}
|
||||
rack::contextSet(nullptr);
|
||||
}
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_screenshot_handler()");
|
||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||
|
||||
const int32_t size = argv[0]->blob.size;
|
||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||
|
||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||
ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer());
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalBaseUI* const ui)
|
||||
{
|
||||
using namespace rack;
|
||||
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
settings::allowCursorLock = true;
|
||||
#else
|
||||
settings::allowCursorLock = false;
|
||||
#endif
|
||||
settings::autoCheckUpdates = false;
|
||||
settings::autosaveInterval = 0;
|
||||
settings::devMode = true;
|
||||
settings::isPlugin = true;
|
||||
settings::skipLoadOnLaunch = true;
|
||||
settings::showTipsOnLaunch = false;
|
||||
settings::windowPos = math::Vec(0, 0);
|
||||
#ifdef HEADLESS
|
||||
settings::headless = true;
|
||||
#endif
|
||||
|
||||
// copied from https://community.vcvrack.com/t/16-colour-cable-palette/15951
|
||||
settings::cableColors = {
|
||||
color::fromHexString("#ff5252"),
|
||||
color::fromHexString("#ff9352"),
|
||||
color::fromHexString("#ffd452"),
|
||||
color::fromHexString("#e8ff52"),
|
||||
color::fromHexString("#a8ff52"),
|
||||
color::fromHexString("#67ff52"),
|
||||
color::fromHexString("#52ff7d"),
|
||||
color::fromHexString("#52ffbe"),
|
||||
color::fromHexString("#52ffff"),
|
||||
color::fromHexString("#52beff"),
|
||||
color::fromHexString("#527dff"),
|
||||
color::fromHexString("#6752ff"),
|
||||
color::fromHexString("#a852ff"),
|
||||
color::fromHexString("#e952ff"),
|
||||
color::fromHexString("#ff52d4"),
|
||||
color::fromHexString("#ff5293"),
|
||||
};
|
||||
|
||||
system::init();
|
||||
logger::init();
|
||||
random::init();
|
||||
ui::init();
|
||||
|
||||
if (asset::systemDir.empty())
|
||||
{
|
||||
if (const char* const bundlePath = (plugin != nullptr ? plugin->getBundlePath() :
|
||||
ui != nullptr ? ui->getBundlePath() : nullptr))
|
||||
{
|
||||
if (const char* const resourcePath = getResourcePath(bundlePath))
|
||||
{
|
||||
asset::systemDir = resourcePath;
|
||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||
}
|
||||
}
|
||||
|
||||
if (asset::systemDir.empty() || ! system::exists(asset::systemDir) || ! system::exists(asset::bundlePath))
|
||||
{
|
||||
#ifdef CARDINAL_PLUGIN_SOURCE_DIR
|
||||
// Make system dir point to source code location as fallback
|
||||
asset::systemDir = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "Rack";
|
||||
asset::bundlePath.clear();
|
||||
|
||||
// If source code dir does not exist use install target prefix as system dir
|
||||
if (!system::exists(system::join(asset::systemDir, "res")))
|
||||
#endif
|
||||
{
|
||||
#if defined(DISTRHO_OS_WASM)
|
||||
asset::systemDir = "/resources";
|
||||
#elif defined(ARCH_MAC)
|
||||
asset::systemDir = "/Library/Application Support/Cardinal";
|
||||
#elif defined(ARCH_WIN)
|
||||
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
|
||||
if (! commonprogfiles.empty())
|
||||
asset::systemDir = system::join(commonprogfiles, "Cardinal");
|
||||
#else
|
||||
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
||||
#endif
|
||||
|
||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||
}
|
||||
}
|
||||
|
||||
asset::userDir = asset::systemDir;
|
||||
}
|
||||
|
||||
const std::string patchesPath = asset::patchesPath();
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME);
|
||||
#else
|
||||
templatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||
#endif
|
||||
factoryTemplatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||
|
||||
// Log environment
|
||||
INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str());
|
||||
INFO("%s", system::getOperatingSystemInfo().c_str());
|
||||
INFO("Binary filename: %s", getBinaryFilename());
|
||||
if (plugin != nullptr) {
|
||||
INFO("Bundle path: %s", plugin->getBundlePath());
|
||||
} else if (ui != nullptr) {
|
||||
INFO("Bundle path: %s", ui->getBundlePath());
|
||||
}
|
||||
INFO("System directory: %s", asset::systemDir.c_str());
|
||||
INFO("User directory: %s", asset::userDir.c_str());
|
||||
INFO("Template patch: %s", templatePath.c_str());
|
||||
INFO("System template patch: %s", factoryTemplatePath.c_str());
|
||||
|
||||
// Report to user if something is wrong with the installation
|
||||
if (asset::systemDir.empty())
|
||||
{
|
||||
d_stderr2("Failed to locate Cardinal plugin bundle.\n"
|
||||
"Install Cardinal with its bundle folder intact and try again.");
|
||||
}
|
||||
else if (! system::exists(asset::systemDir))
|
||||
{
|
||||
d_stderr2("System directory \"%s\" does not exist.\n"
|
||||
"Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str());
|
||||
}
|
||||
|
||||
INFO("Initializing plugins");
|
||||
plugin::initStaticPlugins();
|
||||
|
||||
INFO("Initializing plugin browser DB");
|
||||
app::browserInit();
|
||||
|
||||
#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);
|
||||
|
||||
startThread();
|
||||
#else
|
||||
INFO("OSC Remote control is not enabled in this build");
|
||||
#endif
|
||||
}
|
||||
|
||||
Initializer::~Initializer()
|
||||
{
|
||||
using namespace rack;
|
||||
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
if (oscServer != nullptr)
|
||||
{
|
||||
stopThread(5000);
|
||||
lo_server_del_method(oscServer, nullptr, nullptr);
|
||||
lo_server_free(oscServer);
|
||||
oscServer = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
INFO("Clearing asset paths");
|
||||
asset::bundlePath.clear();
|
||||
asset::systemDir.clear();
|
||||
asset::userDir.clear();
|
||||
|
||||
INFO("Destroying plugins");
|
||||
plugin::destroyStaticPlugins();
|
||||
|
||||
INFO("Destroying colourized assets");
|
||||
asset::destroy();
|
||||
|
||||
INFO("Destroying settings");
|
||||
settings::destroy();
|
||||
|
||||
INFO("Destroying logger");
|
||||
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
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
* For a full copy of the GNU General Public License see the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "DistrhoUtils.hpp"
|
||||
|
||||
#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
|
||||
|
@ -35,6 +38,8 @@
|
|||
|
||||
extern const std::string CARDINAL_VERSION;
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace rack {
|
||||
|
||||
namespace ui {
|
||||
|
@ -65,6 +70,8 @@ extern char* patchStorageSlug;
|
|||
|
||||
} // namespace rack
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
namespace patchUtils {
|
||||
|
||||
void loadDialog();
|
||||
|
@ -86,3 +93,37 @@ void deployToRemote();
|
|||
void sendScreenshotToRemote(const char* screenshot);
|
||||
|
||||
} // namespace patchUtils
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS) && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
# define CARDINAL_INIT_OSC_THREAD
|
||||
#endif
|
||||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
||||
class CardinalBasePlugin;
|
||||
class CardinalBaseUI;
|
||||
|
||||
struct Initializer
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
: public Thread
|
||||
#endif
|
||||
{
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
lo_server oscServer = nullptr;
|
||||
CardinalBasePlugin* oscPlugin = 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
|
||||
};
|
||||
|
||||
END_NAMESPACE_DISTRHO
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#define DISTRHO_PLUGIN_URI "https://distrho.kx.studio/plugins/cardinal#mini"
|
||||
#define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.cardinal#mini"
|
||||
|
||||
#define DISTRHO_PLUGIN_NAME "Cardinal FX"
|
||||
#define DISTRHO_PLUGIN_LABEL "CardinalFX"
|
||||
#define DISTRHO_PLUGIN_NAME "Cardinal Mini"
|
||||
#define DISTRHO_PLUGIN_LABEL "CardinalMini"
|
||||
|
||||
#define DISTRHO_PLUGIN_HAS_UI 1
|
||||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
* For a full copy of the GNU General Public License see the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <asset.hpp>
|
||||
#include <library.hpp>
|
||||
#include <midi.hpp>
|
||||
#include <patch.hpp>
|
||||
|
@ -24,7 +23,6 @@
|
|||
#include <settings.hpp>
|
||||
#include <system.hpp>
|
||||
|
||||
#include <app/Browser.hpp>
|
||||
#include <app/Scene.hpp>
|
||||
#include <engine/Engine.hpp>
|
||||
#include <ui/common.hpp>
|
||||
|
@ -52,16 +50,6 @@
|
|||
# include "extra/SharedResourcePointer.hpp"
|
||||
#endif
|
||||
|
||||
#if CARDINAL_VARIANT_FX
|
||||
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
|
||||
#elif CARDINAL_VARIANT_NATIVE
|
||||
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
|
||||
#elif CARDINAL_VARIANT_SYNTH
|
||||
# define CARDINAL_TEMPLATE_NAME "init/synth.vcv"
|
||||
#else
|
||||
# define CARDINAL_TEMPLATE_NAME "init/main.vcv"
|
||||
#endif
|
||||
|
||||
static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment
|
||||
|
||||
#ifndef HEADLESS
|
||||
|
@ -76,17 +64,9 @@ static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount;
|
|||
extern const std::string CARDINAL_VERSION;
|
||||
|
||||
namespace rack {
|
||||
namespace asset {
|
||||
std::string patchesPath();
|
||||
void destroy();
|
||||
}
|
||||
namespace engine {
|
||||
void Engine_setAboutToClose(Engine*);
|
||||
}
|
||||
namespace plugin {
|
||||
void initStaticPlugins();
|
||||
void destroyStaticPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
@ -98,6 +78,10 @@ bool d_isDiffHigherThanLimit(const T& v1, const T& v2, const T& limit)
|
|||
return v1 != v2 ? (v1 > v2 ? v1 - v2 : v2 - v1) > limit : false;
|
||||
}
|
||||
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
const char* UI::getBundlePath() const noexcept { return nullptr; }
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
|
@ -143,288 +127,6 @@ static char* getPatchStorageSlug() {
|
|||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct Initializer
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
: public Thread
|
||||
#endif
|
||||
{
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
lo_server oscServer = nullptr;
|
||||
CardinalBasePlugin* oscPlugin = nullptr;
|
||||
#endif
|
||||
std::string templatePath;
|
||||
std::string factoryTemplatePath;
|
||||
|
||||
Initializer(const CardinalBasePlugin* const plugin)
|
||||
{
|
||||
using namespace rack;
|
||||
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
settings::allowCursorLock = true;
|
||||
#else
|
||||
settings::allowCursorLock = false;
|
||||
#endif
|
||||
settings::autoCheckUpdates = false;
|
||||
settings::autosaveInterval = 0;
|
||||
settings::devMode = true;
|
||||
settings::isPlugin = true;
|
||||
settings::skipLoadOnLaunch = true;
|
||||
settings::showTipsOnLaunch = false;
|
||||
settings::windowPos = math::Vec(0, 0);
|
||||
#ifdef HEADLESS
|
||||
settings::headless = true;
|
||||
#endif
|
||||
|
||||
// copied from https://community.vcvrack.com/t/16-colour-cable-palette/15951
|
||||
settings::cableColors = {
|
||||
color::fromHexString("#ff5252"),
|
||||
color::fromHexString("#ff9352"),
|
||||
color::fromHexString("#ffd452"),
|
||||
color::fromHexString("#e8ff52"),
|
||||
color::fromHexString("#a8ff52"),
|
||||
color::fromHexString("#67ff52"),
|
||||
color::fromHexString("#52ff7d"),
|
||||
color::fromHexString("#52ffbe"),
|
||||
color::fromHexString("#52ffff"),
|
||||
color::fromHexString("#52beff"),
|
||||
color::fromHexString("#527dff"),
|
||||
color::fromHexString("#6752ff"),
|
||||
color::fromHexString("#a852ff"),
|
||||
color::fromHexString("#e952ff"),
|
||||
color::fromHexString("#ff52d4"),
|
||||
color::fromHexString("#ff5293"),
|
||||
};
|
||||
|
||||
system::init();
|
||||
logger::init();
|
||||
random::init();
|
||||
ui::init();
|
||||
|
||||
if (asset::systemDir.empty())
|
||||
{
|
||||
if (const char* const bundlePath = plugin->getBundlePath())
|
||||
{
|
||||
if (const char* const resourcePath = getResourcePath(bundlePath))
|
||||
{
|
||||
asset::systemDir = resourcePath;
|
||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||
}
|
||||
}
|
||||
|
||||
if (asset::systemDir.empty() || ! system::exists(asset::systemDir) || ! system::exists(asset::bundlePath))
|
||||
{
|
||||
#ifdef CARDINAL_PLUGIN_SOURCE_DIR
|
||||
// Make system dir point to source code location as fallback
|
||||
asset::systemDir = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "Rack";
|
||||
asset::bundlePath.clear();
|
||||
|
||||
// If source code dir does not exist use install target prefix as system dir
|
||||
if (!system::exists(system::join(asset::systemDir, "res")))
|
||||
#endif
|
||||
{
|
||||
#if defined(DISTRHO_OS_WASM)
|
||||
asset::systemDir = "/resources";
|
||||
#elif defined(ARCH_MAC)
|
||||
asset::systemDir = "/Library/Application Support/Cardinal";
|
||||
#elif defined(ARCH_WIN)
|
||||
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
|
||||
if (! commonprogfiles.empty())
|
||||
asset::systemDir = system::join(commonprogfiles, "Cardinal");
|
||||
#else
|
||||
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
||||
#endif
|
||||
|
||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||
}
|
||||
}
|
||||
|
||||
asset::userDir = asset::systemDir;
|
||||
}
|
||||
|
||||
const std::string patchesPath = asset::patchesPath();
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME);
|
||||
#else
|
||||
templatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||
#endif
|
||||
factoryTemplatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||
|
||||
// Log environment
|
||||
INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str());
|
||||
INFO("%s", system::getOperatingSystemInfo().c_str());
|
||||
INFO("Binary filename: %s", getBinaryFilename());
|
||||
INFO("Bundle path: %s", plugin->getBundlePath());
|
||||
INFO("System directory: %s", asset::systemDir.c_str());
|
||||
INFO("User directory: %s", asset::userDir.c_str());
|
||||
INFO("Template patch: %s", templatePath.c_str());
|
||||
INFO("System template patch: %s", factoryTemplatePath.c_str());
|
||||
|
||||
// Report to user if something is wrong with the installation
|
||||
if (asset::systemDir.empty())
|
||||
{
|
||||
d_stderr2("Failed to locate Cardinal plugin bundle.\n"
|
||||
"Install Cardinal with its bundle folder intact and try again.");
|
||||
}
|
||||
else if (! system::exists(asset::systemDir))
|
||||
{
|
||||
d_stderr2("System directory \"%s\" does not exist.\n"
|
||||
"Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str());
|
||||
}
|
||||
|
||||
INFO("Initializing plugins");
|
||||
plugin::initStaticPlugins();
|
||||
|
||||
INFO("Initializing plugin browser DB");
|
||||
app::browserInit();
|
||||
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
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);
|
||||
|
||||
startThread();
|
||||
#elif defined(HEADLESS)
|
||||
INFO("OSC Remote control is not enabled in this build");
|
||||
#endif
|
||||
}
|
||||
|
||||
~Initializer()
|
||||
{
|
||||
using namespace rack;
|
||||
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
if (oscServer != nullptr)
|
||||
{
|
||||
stopThread(5000);
|
||||
lo_server_del_method(oscServer, nullptr, nullptr);
|
||||
lo_server_free(oscServer);
|
||||
oscServer = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
INFO("Clearing asset paths");
|
||||
asset::bundlePath.clear();
|
||||
asset::systemDir.clear();
|
||||
asset::userDir.clear();
|
||||
|
||||
INFO("Destroying plugins");
|
||||
plugin::destroyStaticPlugins();
|
||||
|
||||
INFO("Destroying colourized assets");
|
||||
asset::destroy();
|
||||
|
||||
INFO("Destroying settings");
|
||||
settings::destroy();
|
||||
|
||||
INFO("Destroying logger");
|
||||
logger::destroy();
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
void run() override
|
||||
{
|
||||
INFO("OSC Thread Listening for remote commands");
|
||||
|
||||
while (! shouldThreadExit())
|
||||
{
|
||||
d_msleep(200);
|
||||
while (lo_server_recv_noblock(oscServer, 0) != 0) {}
|
||||
}
|
||||
|
||||
INFO("OSC Thread Closed");
|
||||
}
|
||||
|
||||
static void osc_error_handler(int num, const char* msg, const char* path)
|
||||
{
|
||||
d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path);
|
||||
}
|
||||
|
||||
static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*)
|
||||
{
|
||||
d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_hello_handler()");
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_load_handler()");
|
||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||
|
||||
const int32_t size = argv[0]->blob.size;
|
||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||
|
||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||
{
|
||||
CardinalPluginContext* const context = plugin->context;
|
||||
std::vector<uint8_t> data(size);
|
||||
std::memcpy(data.data(), blob, size);
|
||||
|
||||
rack::contextSet(context);
|
||||
rack::system::removeRecursively(context->patch->autosavePath);
|
||||
rack::system::createDirectories(context->patch->autosavePath);
|
||||
try {
|
||||
rack::system::unarchiveToDirectory(data, context->patch->autosavePath);
|
||||
context->patch->loadAutosave();
|
||||
ok = true;
|
||||
}
|
||||
catch (rack::Exception& e) {
|
||||
WARN("%s", e.what());
|
||||
}
|
||||
rack::contextSet(nullptr);
|
||||
}
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||
{
|
||||
d_stdout("osc_screenshot_handler()");
|
||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||
|
||||
const int32_t size = argv[0]->blob.size;
|
||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||
|
||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||
|
||||
bool ok = false;
|
||||
|
||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||
ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer());
|
||||
|
||||
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");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
struct ScopedContext {
|
||||
ScopedContext(const CardinalBasePlugin* const plugin)
|
||||
{
|
||||
|
@ -479,9 +181,9 @@ public:
|
|||
CardinalPlugin()
|
||||
: CardinalBasePlugin(kModuleParameters + kWindowParameterCount + 1, 0, kCardinalStateCount),
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
fInitializer(new Initializer(this)),
|
||||
fInitializer(new Initializer(this, static_cast<const CardinalBaseUI*>(nullptr))),
|
||||
#else
|
||||
fInitializer(this),
|
||||
fInitializer(this, static_cast<const CardinalBaseUI*>(nullptr)),
|
||||
#endif
|
||||
#if DISTRHO_PLUGIN_NUM_INPUTS != 0
|
||||
fAudioBufferCopy(nullptr),
|
||||
|
@ -571,14 +273,14 @@ public:
|
|||
context->patch->templatePath = context->patch->factoryTemplatePath;
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
fInitializer->oscPlugin = this;
|
||||
#endif
|
||||
}
|
||||
|
||||
~CardinalPlugin() override
|
||||
{
|
||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||
fInitializer->oscPlugin = nullptr;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
# include <ui/Label.hpp>
|
||||
# include <ui/MenuOverlay.hpp>
|
||||
# include <ui/SequentialLayout.hpp>
|
||||
# include "CardinalCommon.hpp"
|
||||
# include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
|
@ -47,15 +46,27 @@
|
|||
# undef DEBUG
|
||||
#endif
|
||||
|
||||
#include <Application.hpp>
|
||||
#include "Application.hpp"
|
||||
#include "AsyncDialog.hpp"
|
||||
#include "CardinalCommon.hpp"
|
||||
#include "PluginContext.hpp"
|
||||
#include "WindowParameters.hpp"
|
||||
|
||||
#ifndef DISTRHO_OS_WASM
|
||||
# include "extra/SharedResourcePointer.hpp"
|
||||
#endif
|
||||
|
||||
#ifndef HEADLESS
|
||||
# include "extra/ScopedValueSetter.hpp"
|
||||
#endif
|
||||
|
||||
namespace rack {
|
||||
namespace app {
|
||||
widget::Widget* createMenuBar(bool isStandalone);
|
||||
}
|
||||
namespace engine {
|
||||
void Engine_setAboutToClose(Engine*);
|
||||
}
|
||||
namespace window {
|
||||
void WindowSetPluginUI(Window* window, DISTRHO_NAMESPACE::UI* ui);
|
||||
void WindowSetMods(Window* window, int mods);
|
||||
|
@ -65,7 +76,14 @@ namespace window {
|
|||
|
||||
START_NAMESPACE_DISTRHO
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
const char* Plugin::getBundlePath() const noexcept { return nullptr; }
|
||||
bool Plugin::writeMidiEvent(const MidiEvent&) noexcept { return false; }
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
struct WasmWelcomeDialog : rack::widget::OpaqueWidget
|
||||
|
@ -268,6 +286,15 @@ static void downloadRemotePatchSucceeded(const char* const filename)
|
|||
class CardinalUI : public CardinalBaseUI,
|
||||
public WindowParametersCallback
|
||||
{
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
ScopedPointer<Initializer> fInitializer;
|
||||
#else
|
||||
SharedResourcePointer<Initializer> fInitializer;
|
||||
#endif
|
||||
std::string fAutosavePath;
|
||||
#endif
|
||||
|
||||
rack::math::Vec lastMousePos;
|
||||
WindowParameters windowParameters;
|
||||
int rateLimitStep = 0;
|
||||
|
@ -305,8 +332,65 @@ class CardinalUI : public CardinalBaseUI,
|
|||
|
||||
public:
|
||||
CardinalUI()
|
||||
: CardinalBaseUI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT)
|
||||
: CardinalBaseUI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT),
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
#ifdef DISTRHO_OS_WASM
|
||||
fInitializer(new Initializer(static_cast<const CardinalBasePlugin*>(nullptr), this)),
|
||||
#else
|
||||
fInitializer(static_cast<const CardinalBasePlugin*>(nullptr), this),
|
||||
#endif
|
||||
#endif
|
||||
lastMousePos()
|
||||
{
|
||||
rack::contextSet(context);
|
||||
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
// create unique temporary path for this instance
|
||||
try {
|
||||
char uidBuf[24];
|
||||
const std::string tmp = rack::system::getTempDirectory();
|
||||
|
||||
for (int i=1;; ++i)
|
||||
{
|
||||
std::snprintf(uidBuf, sizeof(uidBuf), "Cardinal.%04d", i);
|
||||
const std::string trypath = rack::system::join(tmp, uidBuf);
|
||||
|
||||
if (! rack::system::exists(trypath))
|
||||
{
|
||||
if (rack::system::createDirectories(trypath))
|
||||
fAutosavePath = trypath;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} DISTRHO_SAFE_EXCEPTION("create unique temporary path");
|
||||
|
||||
const float sampleRate = getSampleRate();
|
||||
rack::settings::sampleRate = sampleRate;
|
||||
|
||||
context->bufferSize = 128;
|
||||
context->sampleRate = sampleRate;
|
||||
|
||||
context->engine = new rack::engine::Engine;
|
||||
context->engine->setSampleRate(sampleRate);
|
||||
|
||||
context->history = new rack::history::State;
|
||||
context->patch = new rack::patch::Manager;
|
||||
context->patch->autosavePath = fAutosavePath;
|
||||
context->patch->templatePath = fInitializer->templatePath;
|
||||
context->patch->factoryTemplatePath = fInitializer->factoryTemplatePath;
|
||||
|
||||
context->event = new rack::widget::EventState;
|
||||
context->scene = new rack::app::Scene;
|
||||
context->event->rootWidget = context->scene;
|
||||
|
||||
context->window = new rack::window::Window;
|
||||
|
||||
context->patch->loadTemplate();
|
||||
context->scene->rackScroll->reset();
|
||||
// swap to factory template after first load
|
||||
context->patch->templatePath = context->patch->factoryTemplatePath;
|
||||
#endif
|
||||
|
||||
Window& window(getWindow());
|
||||
|
||||
window.setIgnoringKeyRepeat(true);
|
||||
|
@ -319,8 +403,6 @@ public:
|
|||
if (scaleFactor != 1.0)
|
||||
setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
|
||||
|
||||
rack::contextSet(context);
|
||||
|
||||
rack::window::WindowSetPluginUI(context->window, this);
|
||||
|
||||
if (rack::widget::Widget* const menuBar = context->scene->menuBar)
|
||||
|
@ -408,6 +490,23 @@ public:
|
|||
|
||||
rack::window::WindowSetPluginUI(context->window, nullptr);
|
||||
|
||||
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
{
|
||||
const ScopedContext sc(this);
|
||||
context->patch->clear();
|
||||
|
||||
// do a little dance to prevent context scene deletion from saving to temp dir
|
||||
#ifndef HEADLESS
|
||||
const ScopedValueSetter<bool> svs(rack::settings::headless, true);
|
||||
#endif
|
||||
Engine_setAboutToClose(context->engine);
|
||||
delete context;
|
||||
}
|
||||
|
||||
if (! fAutosavePath.empty())
|
||||
rack::system::removeRecursively(fAutosavePath);
|
||||
#endif
|
||||
|
||||
rack::contextSet(nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -201,8 +201,10 @@ endif
|
|||
# --------------------------------------------------------------
|
||||
# Setup resources
|
||||
|
||||
CORE_RESOURCES = patches
|
||||
CORE_RESOURCES += $(subst ../Rack/res/,,$(wildcard ../Rack/res/ComponentLibrary/*.svg ../Rack/res/fonts/*.ttf))
|
||||
CORE_RESOURCES = $(subst ../Rack/res/,,$(wildcard ../Rack/res/ComponentLibrary/*.svg ../Rack/res/fonts/*.ttf))
|
||||
# ifneq ($(CARDINAL_VARIANT),mini)
|
||||
CORE_RESOURCES += patches
|
||||
# endif
|
||||
|
||||
LV2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).lv2/resources/%)
|
||||
VST3_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst3/Contents/Resources/%)
|
||||
|
@ -243,15 +245,19 @@ endif
|
|||
# --------------------------------------------------------------
|
||||
# mini variant UI
|
||||
|
||||
# ifeq ($(CARDINAL_VARIANT),mini)
|
||||
# ifneq ($(HEADLESS)$(MOD_BUILD),true)
|
||||
# FILES_UI = CardinalUI.cpp
|
||||
# FILES_UI += glfw.cpp
|
||||
# FILES_UI += Window.cpp
|
||||
# EXTRA_UI_DEPENDENCIES = $(subst -headless,,$(EXTRA_DSP_DEPENDENCIES))
|
||||
# EXTRA_UI_LIBS = $(subst -headless,,$(EXTRA_DSP_LIBS))
|
||||
# endif
|
||||
# endif
|
||||
ifeq ($(CARDINAL_VARIANT),mini)
|
||||
ifneq ($(HEADLESS)$(MOD_BUILD),true)
|
||||
FILES_UI = CardinalUI.cpp
|
||||
FILES_UI += CardinalCommon.cpp
|
||||
FILES_UI += common.cpp
|
||||
FILES_UI += glfw.cpp
|
||||
FILES_UI += Window.cpp
|
||||
EXTRA_UI_DEPENDENCIES = $(subst -headless,,$(EXTRA_DSP_DEPENDENCIES))
|
||||
EXTRA_UI_LIBS = -Wl,--start-group
|
||||
EXTRA_UI_LIBS += $(subst -headless,,$(EXTRA_DSP_LIBS))
|
||||
EXTRA_UI_LIBS += -Wl,--end-group
|
||||
endif
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# Do some magic
|
||||
|
@ -467,6 +473,7 @@ endif
|
|||
|
||||
all: $(TARGETS)
|
||||
lv2: $(LV2_RESOURCES)
|
||||
lv2_sep: $(LV2_RESOURCES)
|
||||
vst2: $(VST2_RESOURCES)
|
||||
vst3: $(VST3_RESOURCES)
|
||||
clap: $(CLAP_RESOURCES)
|
||||
|
|
|
@ -189,9 +189,6 @@ public:
|
|||
|
||||
context->tlw = nullptr;
|
||||
context->ui = nullptr;
|
||||
#if !DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
delete context;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -107,6 +107,13 @@ public:
|
|||
initialise_variant<T>(variant);
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
SharedResourcePointer(const T1* const v1, const T2* const v2)
|
||||
: sharedObject(nullptr)
|
||||
{
|
||||
initialise_variant2<T1, T2>(v1, v2);
|
||||
}
|
||||
|
||||
SharedResourcePointer (const SharedResourcePointer&)
|
||||
: sharedObject(nullptr)
|
||||
{
|
||||
|
@ -179,6 +186,18 @@ private:
|
|||
sharedObject = holder.sharedInstance;
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
void initialise_variant2(const T1* const v1, const T2* const v2)
|
||||
{
|
||||
SharedObjectHolder& holder = getSharedObjectHolder();
|
||||
const SpinLock::ScopedLockType sl (holder.lock);
|
||||
|
||||
if (++(holder.refCount) == 1)
|
||||
holder.sharedInstance = new SharedObjectType(v1, v2);
|
||||
|
||||
sharedObject = holder.sharedInstance;
|
||||
}
|
||||
|
||||
// There's no need to assign to a SharedResourcePointer because every
|
||||
// instance of the class is exactly the same!
|
||||
SharedResourcePointer& operator= (const SharedResourcePointer&) = delete;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "Application.hpp"
|
||||
#include "extra/String.hpp"
|
||||
#include "../CardinalCommon.hpp"
|
||||
#include "../PluginContext.hpp"
|
||||
#include "../WindowParameters.hpp"
|
||||
|
||||
#ifndef DGL_NO_SHARED_RESOURCES
|
||||
|
@ -148,12 +149,14 @@ struct Window::Internal {
|
|||
DGL_NAMESPACE::NanoTopLevelWidget* tlw = nullptr;
|
||||
DISTRHO_NAMESPACE::WindowParameters params;
|
||||
DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr;
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
DGL_NAMESPACE::Application hiddenApp;
|
||||
DGL_NAMESPACE::Window hiddenWindow;
|
||||
NVGcontext* r_vg = nullptr;
|
||||
NVGcontext* r_fbVg = nullptr;
|
||||
NVGcontext* o_vg = nullptr;
|
||||
NVGcontext* o_fbVg = nullptr;
|
||||
#endif
|
||||
|
||||
math::Vec size = WINDOW_SIZE_MIN;
|
||||
|
||||
|
@ -176,12 +179,16 @@ struct Window::Internal {
|
|||
int fbCount = 0;
|
||||
|
||||
Internal()
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
: hiddenApp(false),
|
||||
hiddenWindow(hiddenApp)
|
||||
{
|
||||
hiddenWindow.setIgnoringKeyRepeat(true);
|
||||
hiddenApp.idle();
|
||||
}
|
||||
#else
|
||||
{}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -203,12 +210,17 @@ static int loadFallbackFont(NVGcontext* const vg)
|
|||
Window::Window() {
|
||||
internal = new Internal;
|
||||
|
||||
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
||||
|
||||
// Set up NanoVG
|
||||
const int nvgFlags = NVG_ANTIALIAS;
|
||||
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
||||
vg = nvgCreateGL(nvgFlags);
|
||||
#else
|
||||
vg = static_cast<CardinalPluginContext*>(APP)->tlw->getContext();
|
||||
#endif
|
||||
DISTRHO_SAFE_ASSERT_RETURN(vg != nullptr,);
|
||||
|
||||
#ifdef NANOVG_GLES2
|
||||
fbVg = nvgCreateSharedGLES2(vg, nvgFlags);
|
||||
#else
|
||||
|
@ -268,6 +280,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
|||
window->internal->tlw = tlw;
|
||||
window->internal->size = rack::math::Vec(tlw->getWidth(), tlw->getHeight());
|
||||
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
// Set up NanoVG
|
||||
window->internal->r_vg = tlw->getContext();
|
||||
#ifdef NANOVG_GLES2
|
||||
|
@ -299,6 +312,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
|||
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
||||
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init settings
|
||||
WindowParametersRestore(window);
|
||||
|
@ -311,6 +325,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
|||
widget::Widget::ContextDestroyEvent e;
|
||||
APP->scene->onContextDestroy(e);
|
||||
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
// swap contexts
|
||||
window->uiFont->vg = window->internal->o_vg;
|
||||
window->vg = window->internal->o_vg;
|
||||
|
@ -338,6 +353,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
|||
nvgDeleteGLES2(window->internal->r_fbVg);
|
||||
#else
|
||||
nvgDeleteGL2(window->internal->r_fbVg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
window->internal->tlw = nullptr;
|
||||
|
@ -375,6 +391,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
|||
window->internal->ui = ui;
|
||||
window->internal->size = rack::math::Vec(ui->getWidth(), ui->getHeight());
|
||||
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
// Set up NanoVG
|
||||
window->internal->r_vg = ui->getContext();
|
||||
#ifdef NANOVG_GLES2
|
||||
|
@ -406,6 +423,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
|||
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
||||
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init settings
|
||||
WindowParametersRestore(window);
|
||||
|
@ -418,6 +436,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
|||
widget::Widget::ContextDestroyEvent e;
|
||||
APP->scene->onContextDestroy(e);
|
||||
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
// swap contexts
|
||||
window->uiFont->vg = window->internal->o_vg;
|
||||
window->vg = window->internal->o_vg;
|
||||
|
@ -445,6 +464,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
|||
nvgDeleteGLES2(window->internal->r_fbVg);
|
||||
#else
|
||||
nvgDeleteGL2(window->internal->r_fbVg);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
window->internal->tlw = nullptr;
|
||||
|
@ -460,9 +480,11 @@ void WindowSetMods(Window* const window, const int mods)
|
|||
|
||||
Window::~Window() {
|
||||
{
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
||||
internal->hiddenWindow.close();
|
||||
internal->hiddenApp.idle();
|
||||
#endif
|
||||
|
||||
// Fonts and Images in the cache must be deleted before the NanoVG context is deleted
|
||||
internal->fontCache.clear();
|
||||
|
@ -470,12 +492,20 @@ Window::~Window() {
|
|||
|
||||
if (vg != nullptr)
|
||||
{
|
||||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||
#if defined NANOVG_GLES2
|
||||
nvgDeleteGLES2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
||||
nvgDeleteGLES2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
||||
#else
|
||||
nvgDeleteGL2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
||||
nvgDeleteGL2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
||||
#endif
|
||||
#else
|
||||
#if defined NANOVG_GLES2
|
||||
nvgDeleteGLES2(fbVg);
|
||||
#else
|
||||
nvgDeleteGL2(fbVg);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue