Signed-off-by: falkTX <falktx@falktx.com>tags/22.02
| @@ -32,67 +32,88 @@ | |||
| #include <unordered_map> | |||
| #include "DistrhoUtils.hpp" | |||
| 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> | |||
| 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; | |||
| m->model = this; | |||
| 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()) | |||
| { | |||
| widgetNeedsDeletion[m] = false; | |||
| return widgets[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); | |||
| 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); | |||
| widgetNeedsDeletion.erase(m); | |||
| } | |||
| }; | |||
| template <class TModule, class TModuleWidget> | |||
| 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 | |||
| #include_next "helpers.hpp" | |||
| #undef createModel | |||
| @@ -208,6 +208,8 @@ static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpc | |||
| // -------------------------------------------------------------------------------------------------------------------- | |||
| static Mutex sPluginInfoLoadMutex; | |||
| struct IldaeilModule : Module { | |||
| enum ParamIds { | |||
| NUM_PARAMS | |||
| @@ -243,7 +245,6 @@ struct IldaeilModule : Module { | |||
| mutable NativeTimeInfo fCarlaTimeInfo; | |||
| void* fUI = nullptr; | |||
| Mutex fPluginLoadMutex; | |||
| float audioDataIn1[BUFFER_SIZE]; | |||
| float audioDataIn2[BUFFER_SIZE]; | |||
| @@ -417,7 +418,7 @@ struct IldaeilModule : Module { | |||
| CarlaEngine* const engine = carla_get_engine_from_handle(fCarlaHostHandle); | |||
| water::XmlDocument xml(projectState); | |||
| const MutexLocker cml(fPluginLoadMutex); | |||
| const MutexLocker cml(sPluginInfoLoadMutex); | |||
| engine->loadProjectInternal(xml, true); | |||
| } | |||
| @@ -641,12 +642,10 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||
| bool idleCallbackActive = false; | |||
| IldaeilModule* const module; | |||
| Mutex& fPluginLoadMutex; | |||
| IldaeilWidget(IldaeilModule* const m) | |||
| : ImGuiWidget(), | |||
| module(m), | |||
| fPluginLoadMutex(m->fPluginLoadMutex) | |||
| module(m) | |||
| { | |||
| 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); | |||
| const MutexLocker cml(fPluginLoadMutex); | |||
| const MutexLocker cml(sPluginInfoLoadMutex); | |||
| if (carla_add_plugin(handle, BINARY_NATIVE, fPluginType, nullptr, nullptr, | |||
| label, 0, 0x0, PLUGIN_OPTIONS_NULL)) | |||
| @@ -1018,7 +1017,7 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||
| if (path != nullptr) | |||
| 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)) | |||
| { | |||
| @@ -1432,12 +1431,12 @@ struct IldaeilModuleWidget : ModuleWidget { | |||
| addOutput(createOutput<PJ301MPort>(Vec(3, 54 + 60), module, IldaeilModule::OUTPUT1)); | |||
| 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) | |||
| @@ -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/pffft | |||
| ifeq ($(DEBUG),true) | |||
| BASE_FLAGS += -UDEBUG | |||
| endif | |||
| ifeq ($(HEADLESS),true) | |||
| BASE_FLAGS += -DHEADLESS | |||
| endif | |||
| ifeq ($(WASM),true) | |||
| BASE_FLAGS += -DNANOVG_GLES2=1 | |||
| BASE_FLAGS += -msse -msse2 -msse3 -msimd128 | |||
| @@ -611,7 +614,10 @@ BASE_FLAGS += -Wno-unused-variable | |||
| # also from plugins | |||
| BASE_FLAGS += -Wno-deprecated-declarations | |||
| ifeq ($(MACOS),true) | |||
| BASE_FLAGS += -Wno-unknown-warning-option | |||
| endif | |||
| # -------------------------------------------------------------- | |||
| # Build targets | |||
| @@ -50,6 +50,10 @@ BASE_FLAGS += -IRack/dep/osdialog | |||
| BASE_FLAGS += -IRack/dep/oui-blendish | |||
| BASE_FLAGS += -IRack/dep/pffft | |||
| ifeq ($(DEBUG),true) | |||
| BASE_FLAGS += -UDEBUG | |||
| endif | |||
| ifeq ($(HEADLESS),true) | |||
| BASE_FLAGS += -DHEADLESS | |||
| endif | |||
| @@ -558,6 +558,10 @@ void Engine::removeModule_NoLock(Module* module) { | |||
| // Check that the module actually exists | |||
| auto it = std::find(internal->modules.begin(), internal->modules.end(), module); | |||
| 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 | |||
| Module::RemoveEvent eRemove; | |||
| module->onRemove(eRemove); | |||
| @@ -586,9 +590,6 @@ void Engine::removeModule_NoLock(Module* module) { | |||
| m->rightExpander.module = NULL; | |||
| } | |||
| } | |||
| // Remove from widgets cache | |||
| if (auto* const helper = reinterpret_cast<CardinalPluginModelHelper*>(module->model)) | |||
| helper->clearCachedModuleWidget(module); | |||
| // Remove module | |||
| internal->modulesCache.erase(module->id); | |||
| internal->modules.erase(it); | |||
| @@ -989,10 +990,11 @@ void Engine::fromJson(json_t* rootJ) { | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(module != nullptr); | |||
| // 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); | |||
| helper->createCachedModuleWidget(module); | |||
| app::ModuleWidget* const moduleWidget = helper->createModuleWidgetFromEngineLoad(module); | |||
| DISTRHO_SAFE_ASSERT_CONTINUE(moduleWidget != nullptr); | |||
| try { | |||
| // 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) { | |||
| WARN("Cannot load module: %s", e.what()); | |||
| // APP->patch->log(e.what()); | |||
| helper->removeCachedModuleWidget(module); | |||
| delete module; | |||
| continue; | |||
| } | |||