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; | ||||
| } | } | ||||