Signed-off-by: falkTX <falktx@falktx.com>tags/22.02
@@ -32,67 +32,88 @@ | |||||
#include <unordered_map> | #include <unordered_map> | ||||
#include "DistrhoUtils.hpp" | |||||
namespace rack { | namespace rack { | ||||
struct CardinalPluginModelHelper { | |||||
virtual ~CardinalPluginModelHelper() {} | |||||
virtual void createCachedModuleWidget(rack::engine::Module* m) = 0; | |||||
virtual void clearCachedModuleWidget(rack::engine::Module* m) = 0; | |||||
struct CardinalPluginModelHelper : plugin::Model { | |||||
virtual app::ModuleWidget* createModuleWidgetFromEngineLoad(engine::Module* m) = 0; | |||||
virtual void removeCachedModuleWidget(engine::Module* m) = 0; | |||||
}; | }; | ||||
template <class TModule, class TModuleWidget> | template <class TModule, class TModuleWidget> | ||||
struct CardinalPluginModel : plugin::Model, CardinalPluginModelHelper | |||||
struct CardinalPluginModel : CardinalPluginModelHelper | |||||
{ | { | ||||
std::unordered_map<rack::engine::Module*, app::ModuleWidget*> widgets; | |||||
std::unordered_map<engine::Module*, TModuleWidget*> widgets; | |||||
std::unordered_map<engine::Module*, bool> widgetNeedsDeletion; | |||||
rack::engine::Module* createModule() override | |||||
engine::Module* createModule() override | |||||
{ | { | ||||
engine::Module* const m = new TModule; | engine::Module* const m = new TModule; | ||||
m->model = this; | m->model = this; | ||||
return m; | return m; | ||||
} | } | ||||
app::ModuleWidget* createModuleWidget(rack::engine::Module* const m) override | |||||
app::ModuleWidget* createModuleWidget(engine::Module* const m) override | |||||
{ | { | ||||
TModule* tm = NULL; | |||||
if (m) { | |||||
assert(m->model == this); | |||||
TModule* tm = nullptr; | |||||
if (m) | |||||
{ | |||||
DISTRHO_SAFE_ASSERT_RETURN(m->model == this, nullptr); | |||||
if (widgets.find(m) != widgets.end()) | if (widgets.find(m) != widgets.end()) | ||||
{ | |||||
widgetNeedsDeletion[m] = false; | |||||
return widgets[m]; | return widgets[m]; | ||||
} | |||||
tm = dynamic_cast<TModule*>(m); | tm = dynamic_cast<TModule*>(m); | ||||
} | } | ||||
app::ModuleWidget* mw = new TModuleWidget(tm); | |||||
mw->setModel(this); | |||||
return mw; | |||||
app::ModuleWidget* const tmw = new TModuleWidget(tm); | |||||
tmw->setModel(this); | |||||
return tmw; | |||||
} | } | ||||
void createCachedModuleWidget(rack::engine::Module* const m) override | |||||
app::ModuleWidget* createModuleWidgetFromEngineLoad(engine::Module* const m) override | |||||
{ | { | ||||
assert(m != nullptr); if (m == nullptr) return; | |||||
assert(m->model == this); if (m->model != this) return; | |||||
DISTRHO_SAFE_ASSERT_RETURN(m != nullptr, nullptr); | |||||
DISTRHO_SAFE_ASSERT_RETURN(m->model == this, nullptr); | |||||
TModule* const tm = dynamic_cast<TModule*>(m); | TModule* const tm = dynamic_cast<TModule*>(m); | ||||
TModuleWidget* const mw = new TModuleWidget(tm); | |||||
mw->setModel(this); | |||||
widgets[m] = mw; | |||||
DISTRHO_SAFE_ASSERT_RETURN(tm != nullptr, nullptr); | |||||
TModuleWidget* const tmw = new TModuleWidget(tm); | |||||
tmw->setModel(this); | |||||
widgets[m] = tmw; | |||||
widgetNeedsDeletion[m] = true; | |||||
return tmw; | |||||
} | } | ||||
void clearCachedModuleWidget(rack::engine::Module* const m) override | |||||
void removeCachedModuleWidget(engine::Module* const m) override | |||||
{ | { | ||||
assert(m != nullptr); if (m == nullptr) return; | |||||
assert(m->model == this); if (m->model != this) return; | |||||
DISTRHO_SAFE_ASSERT_RETURN(m != nullptr,); | |||||
DISTRHO_SAFE_ASSERT_RETURN(m->model == this,); | |||||
if (widgets.find(m) == widgets.end()) | |||||
return; | |||||
if (widgetNeedsDeletion[m]) | |||||
delete widgets[m]; | |||||
widgets.erase(m); | widgets.erase(m); | ||||
widgetNeedsDeletion.erase(m); | |||||
} | } | ||||
}; | }; | ||||
template <class TModule, class TModuleWidget> | template <class TModule, class TModuleWidget> | ||||
CardinalPluginModel<TModule, TModuleWidget>* createModel(std::string slug) | CardinalPluginModel<TModule, TModuleWidget>* createModel(std::string slug) | ||||
{ | { | ||||
CardinalPluginModel<TModule, TModuleWidget>* const o = new CardinalPluginModel<TModule, TModuleWidget>(); | |||||
o->slug = slug; | |||||
return o; | |||||
CardinalPluginModel<TModule, TModuleWidget>* const o = new CardinalPluginModel<TModule, TModuleWidget>(); | |||||
o->slug = slug; | |||||
return o; | |||||
} | } | ||||
} | } | ||||
#define createModel createModelOldVCV | #define createModel createModelOldVCV | ||||
#include_next "helpers.hpp" | #include_next "helpers.hpp" | ||||
#undef createModel |
@@ -208,6 +208,8 @@ static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpc | |||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
static Mutex sPluginInfoLoadMutex; | |||||
struct IldaeilModule : Module { | struct IldaeilModule : Module { | ||||
enum ParamIds { | enum ParamIds { | ||||
NUM_PARAMS | NUM_PARAMS | ||||
@@ -243,7 +245,6 @@ struct IldaeilModule : Module { | |||||
mutable NativeTimeInfo fCarlaTimeInfo; | mutable NativeTimeInfo fCarlaTimeInfo; | ||||
void* fUI = nullptr; | void* fUI = nullptr; | ||||
Mutex fPluginLoadMutex; | |||||
float audioDataIn1[BUFFER_SIZE]; | float audioDataIn1[BUFFER_SIZE]; | ||||
float audioDataIn2[BUFFER_SIZE]; | float audioDataIn2[BUFFER_SIZE]; | ||||
@@ -417,7 +418,7 @@ struct IldaeilModule : Module { | |||||
CarlaEngine* const engine = carla_get_engine_from_handle(fCarlaHostHandle); | CarlaEngine* const engine = carla_get_engine_from_handle(fCarlaHostHandle); | ||||
water::XmlDocument xml(projectState); | water::XmlDocument xml(projectState); | ||||
const MutexLocker cml(fPluginLoadMutex); | |||||
const MutexLocker cml(sPluginInfoLoadMutex); | |||||
engine->loadProjectInternal(xml, true); | engine->loadProjectInternal(xml, true); | ||||
} | } | ||||
@@ -641,12 +642,10 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||||
bool idleCallbackActive = false; | bool idleCallbackActive = false; | ||||
IldaeilModule* const module; | IldaeilModule* const module; | ||||
Mutex& fPluginLoadMutex; | |||||
IldaeilWidget(IldaeilModule* const m) | IldaeilWidget(IldaeilModule* const m) | ||||
: ImGuiWidget(), | : ImGuiWidget(), | ||||
module(m), | |||||
fPluginLoadMutex(m->fPluginLoadMutex) | |||||
module(m) | |||||
{ | { | ||||
if (module->fCarlaHostHandle == nullptr) | if (module->fCarlaHostHandle == nullptr) | ||||
{ | { | ||||
@@ -836,7 +835,7 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||||
carla_set_engine_option(handle, ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, fPluginWillRunInBridgeMode, nullptr); | carla_set_engine_option(handle, ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, fPluginWillRunInBridgeMode, nullptr); | ||||
const MutexLocker cml(fPluginLoadMutex); | |||||
const MutexLocker cml(sPluginInfoLoadMutex); | |||||
if (carla_add_plugin(handle, BINARY_NATIVE, fPluginType, nullptr, nullptr, | if (carla_add_plugin(handle, BINARY_NATIVE, fPluginType, nullptr, nullptr, | ||||
label, 0, 0x0, PLUGIN_OPTIONS_NULL)) | label, 0, 0x0, PLUGIN_OPTIONS_NULL)) | ||||
@@ -1018,7 +1017,7 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||||
if (path != nullptr) | if (path != nullptr) | ||||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, pluginType, path); | carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, pluginType, path); | ||||
const MutexLocker cml(fPluginLoadMutex); | |||||
const MutexLocker cml(sPluginInfoLoadMutex); | |||||
if (const uint count = carla_get_cached_plugin_count(pluginType, path)) | if (const uint count = carla_get_cached_plugin_count(pluginType, path)) | ||||
{ | { | ||||
@@ -1432,12 +1431,12 @@ struct IldaeilModuleWidget : ModuleWidget { | |||||
addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 60), module, IldaeilModule::OUTPUT1)); | addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 60), module, IldaeilModule::OUTPUT1)); | ||||
addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 90), module, IldaeilModule::OUTPUT2)); | addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 90), module, IldaeilModule::OUTPUT2)); | ||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 135), module, IldaeilModule::PITCH_INPUT)); | |||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 165), module, IldaeilModule::GATE_INPUT)); | |||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 195), module, IldaeilModule::VEL_INPUT)); | |||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 225), module, IldaeilModule::AFT_INPUT)); | |||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 255), module, IldaeilModule::PW_INPUT)); | |||||
addOutput(createInput<PJ301MPort>(Vec(3, 54 + 285), module, IldaeilModule::MW_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 135), module, IldaeilModule::PITCH_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 165), module, IldaeilModule::GATE_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 195), module, IldaeilModule::VEL_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 225), module, IldaeilModule::AFT_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 255), module, IldaeilModule::PW_INPUT)); | |||||
addInput(createInput<PJ301MPort>(Vec(3, 54 + 285), module, IldaeilModule::MW_INPUT)); | |||||
} | } | ||||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(IldaeilModuleWidget) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(IldaeilModuleWidget) | ||||
@@ -570,11 +570,14 @@ BASE_FLAGS += -I../src/Rack/dep/osdialog | |||||
BASE_FLAGS += -I../src/Rack/dep/oui-blendish | BASE_FLAGS += -I../src/Rack/dep/oui-blendish | ||||
BASE_FLAGS += -I../src/Rack/dep/pffft | BASE_FLAGS += -I../src/Rack/dep/pffft | ||||
ifeq ($(DEBUG),true) | |||||
BASE_FLAGS += -UDEBUG | |||||
endif | |||||
ifeq ($(HEADLESS),true) | ifeq ($(HEADLESS),true) | ||||
BASE_FLAGS += -DHEADLESS | BASE_FLAGS += -DHEADLESS | ||||
endif | endif | ||||
ifeq ($(WASM),true) | ifeq ($(WASM),true) | ||||
BASE_FLAGS += -DNANOVG_GLES2=1 | BASE_FLAGS += -DNANOVG_GLES2=1 | ||||
BASE_FLAGS += -msse -msse2 -msse3 -msimd128 | BASE_FLAGS += -msse -msse2 -msse3 -msimd128 | ||||
@@ -611,7 +614,10 @@ BASE_FLAGS += -Wno-unused-variable | |||||
# also from plugins | # also from plugins | ||||
BASE_FLAGS += -Wno-deprecated-declarations | BASE_FLAGS += -Wno-deprecated-declarations | ||||
ifeq ($(MACOS),true) | |||||
BASE_FLAGS += -Wno-unknown-warning-option | BASE_FLAGS += -Wno-unknown-warning-option | ||||
endif | |||||
# -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
# Build targets | # Build targets | ||||
@@ -50,6 +50,10 @@ BASE_FLAGS += -IRack/dep/osdialog | |||||
BASE_FLAGS += -IRack/dep/oui-blendish | BASE_FLAGS += -IRack/dep/oui-blendish | ||||
BASE_FLAGS += -IRack/dep/pffft | BASE_FLAGS += -IRack/dep/pffft | ||||
ifeq ($(DEBUG),true) | |||||
BASE_FLAGS += -UDEBUG | |||||
endif | |||||
ifeq ($(HEADLESS),true) | ifeq ($(HEADLESS),true) | ||||
BASE_FLAGS += -DHEADLESS | BASE_FLAGS += -DHEADLESS | ||||
endif | endif | ||||
@@ -558,6 +558,10 @@ void Engine::removeModule_NoLock(Module* module) { | |||||
// Check that the module actually exists | // Check that the module actually exists | ||||
auto it = std::find(internal->modules.begin(), internal->modules.end(), module); | auto it = std::find(internal->modules.begin(), internal->modules.end(), module); | ||||
DISTRHO_SAFE_ASSERT_RETURN(it != internal->modules.end(),); | DISTRHO_SAFE_ASSERT_RETURN(it != internal->modules.end(),); | ||||
// Remove from widgets cache | |||||
CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(module->model); | |||||
DISTRHO_SAFE_ASSERT_RETURN(helper != nullptr,); | |||||
helper->removeCachedModuleWidget(module); | |||||
// Dispatch RemoveEvent | // Dispatch RemoveEvent | ||||
Module::RemoveEvent eRemove; | Module::RemoveEvent eRemove; | ||||
module->onRemove(eRemove); | module->onRemove(eRemove); | ||||
@@ -586,9 +590,6 @@ void Engine::removeModule_NoLock(Module* module) { | |||||
m->rightExpander.module = NULL; | m->rightExpander.module = NULL; | ||||
} | } | ||||
} | } | ||||
// Remove from widgets cache | |||||
if (auto* const helper = reinterpret_cast<CardinalPluginModelHelper*>(module->model)) | |||||
helper->clearCachedModuleWidget(module); | |||||
// Remove module | // Remove module | ||||
internal->modulesCache.erase(module->id); | internal->modulesCache.erase(module->id); | ||||
internal->modules.erase(it); | internal->modules.erase(it); | ||||
@@ -989,10 +990,11 @@ void Engine::fromJson(json_t* rootJ) { | |||||
DISTRHO_SAFE_ASSERT_CONTINUE(module != nullptr); | DISTRHO_SAFE_ASSERT_CONTINUE(module != nullptr); | ||||
// Create the widget too, needed by a few modules | // Create the widget too, needed by a few modules | ||||
auto* const helper = reinterpret_cast<CardinalPluginModelHelper*>(model); | |||||
CardinalPluginModelHelper* const helper = dynamic_cast<CardinalPluginModelHelper*>(model); | |||||
DISTRHO_SAFE_ASSERT_CONTINUE(helper != nullptr); | DISTRHO_SAFE_ASSERT_CONTINUE(helper != nullptr); | ||||
helper->createCachedModuleWidget(module); | |||||
app::ModuleWidget* const moduleWidget = helper->createModuleWidgetFromEngineLoad(module); | |||||
DISTRHO_SAFE_ASSERT_CONTINUE(moduleWidget != nullptr); | |||||
try { | try { | ||||
// This doesn't need a lock because the Module is not added to the Engine yet. | // This doesn't need a lock because the Module is not added to the Engine yet. | ||||
@@ -1009,6 +1011,7 @@ void Engine::fromJson(json_t* rootJ) { | |||||
catch (Exception& e) { | catch (Exception& e) { | ||||
WARN("Cannot load module: %s", e.what()); | WARN("Cannot load module: %s", e.what()); | ||||
// APP->patch->log(e.what()); | // APP->patch->log(e.what()); | ||||
helper->removeCachedModuleWidget(module); | |||||
delete module; | delete module; | ||||
continue; | continue; | ||||
} | } | ||||