diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cd8cad2..8cc9e80d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ In this document, Mod is Ctrl on Windows/Linux and Cmd on Mac. - Add "Primary module" context menu item to VCV Audio modules to select which audio device clocks the engine. - Allow other modules such as VCV Recorder to be the primary module, to render audio faster than real-time. - Remove "Real-time priority" menu item, since the thread priority is now managed elsewhere (RtAudio, etc). +- Replace module disabling with bypassing, which directly routes certain inputs to outputs if specified by the plugin. - Duplicate cables patched to inputs when a module is duplicated. - Add module tags to module context menu. - Add module manual URL (if plugin developer supplies it) to module context menu item. diff --git a/include/app/ModuleWidget.hpp b/include/app/ModuleWidget.hpp index 157b1118..ca0ea6a8 100644 --- a/include/app/ModuleWidget.hpp +++ b/include/app/ModuleWidget.hpp @@ -82,7 +82,7 @@ struct ModuleWidget : widget::OpaqueWidget { void randomizeAction(); void disconnectAction(); void cloneAction(); - void disableAction(); + void bypassAction(); /** Deletes `this` */ void removeAction(); void createContextMenu(); diff --git a/include/engine/Engine.hpp b/include/engine/Engine.hpp index 1d6c72db..a6462a1a 100644 --- a/include/engine/Engine.hpp +++ b/include/engine/Engine.hpp @@ -50,7 +50,7 @@ struct Engine { Module* getModule(int moduleId); void resetModule(Module* module); void randomizeModule(Module* module); - void disableModule(Module* module, bool disabled); + void bypassModule(Module* module, bool bypassed); // Cables /** Adds a cable to the rack engine. diff --git a/include/engine/Module.hpp b/include/engine/Module.hpp index 2275754d..e1a137a0 100644 --- a/include/engine/Module.hpp +++ b/include/engine/Module.hpp @@ -85,10 +85,7 @@ struct Module { Only written when CPU timing is enabled, since time measurement is expensive. */ float cpuTime = 0.f; - /** Whether the Module is skipped from stepping by the engine. - Module subclasses should not read/write this variable. - */ - bool disabled = false; + bool bypassed = false; /** Constructs a Module with no params, inputs, outputs, and lights. */ Module(); @@ -181,6 +178,7 @@ struct Module { virtual void step() {} /** Called instead of process() when Module is bypassed. Typically you do not need to override this. Use configBypass() instead. + If you do override it, avoid reading param values, since the state of the module should have no effect on routing. */ virtual void processBypass(const ProcessArgs& args); @@ -219,15 +217,15 @@ struct Module { onRemove(); } - struct EnableEvent {}; - /** Called after enabling the module. + struct BypassEvent {}; + /** Called after bypassing the module. */ - virtual void onEnable(const EnableEvent& e) {} + virtual void onBypass(const BypassEvent& e) {} - struct DisableEvent {}; - /** Called after disabling the module. + struct UnBypassEvent {}; + /** Called after enabling the module. */ - virtual void onDisable(const DisableEvent& e) {} + virtual void onUnBypass(const UnBypassEvent& e) {} struct PortChangeEvent { /** True if connecting, false if disconnecting. */ diff --git a/include/history.hpp b/include/history.hpp index 4f5aaa16..9b8a2a8d 100644 --- a/include/history.hpp +++ b/include/history.hpp @@ -97,12 +97,12 @@ struct ModuleMove : ModuleAction { }; -struct ModuleDisable : ModuleAction { - bool disabled; +struct ModuleBypass : ModuleAction { + bool bypassed; void undo() override; void redo() override; - ModuleDisable() { - name = "disable module"; + ModuleBypass() { + name = "bypass module"; } }; diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index c64a1d25..c78c981a 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -257,10 +257,10 @@ struct ModuleCloneItem : ui::MenuItem { }; -struct ModuleDisableItem : ui::MenuItem { +struct ModuleBypassItem : ui::MenuItem { ModuleWidget* moduleWidget; void onAction(const event::Action& e) override { - moduleWidget->disableAction(); + moduleWidget->bypassAction(); } }; @@ -299,7 +299,7 @@ ModuleWidget::~ModuleWidget() { void ModuleWidget::draw(const DrawArgs& args) { nvgScissor(args.vg, RECT_ARGS(args.clipBox)); - if (module && module->disabled) { + if (module && module->bypassed) { nvgGlobalAlpha(args.vg, 0.33); } @@ -409,7 +409,7 @@ void ModuleWidget::onHoverKey(const event::HoverKey& e) { } break; case GLFW_KEY_E: { if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { - disableAction(); + bypassAction(); e.consume(this); } } break; @@ -833,14 +833,14 @@ void ModuleWidget::cloneAction() { APP->history->push(h); } -void ModuleWidget::disableAction() { +void ModuleWidget::bypassAction() { assert(module); - APP->engine->disableModule(module, !module->disabled); + APP->engine->bypassModule(module, !module->bypassed); - // history::ModuleDisable - history::ModuleDisable* h = new history::ModuleDisable; + // history::ModuleBypass + history::ModuleBypass* h = new history::ModuleBypass; h->moduleId = module->id; - h->disabled = module->disabled; + h->bypassed = module->bypassed; APP->history->push(h); } @@ -905,13 +905,13 @@ void ModuleWidget::createContextMenu() { cloneItem->moduleWidget = this; menu->addChild(cloneItem); - ModuleDisableItem* disableItem = new ModuleDisableItem; - disableItem->text = "Disable"; - disableItem->rightText = RACK_MOD_CTRL_NAME "+E"; - if (module && module->disabled) - disableItem->rightText = CHECKMARK_STRING " " + disableItem->rightText; - disableItem->moduleWidget = this; - menu->addChild(disableItem); + ModuleBypassItem* bypassItem = new ModuleBypassItem; + bypassItem->text = "Bypass"; + bypassItem->rightText = RACK_MOD_CTRL_NAME "+E"; + if (module && module->bypassed) + bypassItem->rightText = CHECKMARK_STRING " " + bypassItem->rightText; + bypassItem->moduleWidget = this; + menu->addChild(bypassItem); ModuleDeleteItem* deleteItem = new ModuleDeleteItem; deleteItem->text = "Delete"; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 05dd14c0..9874c1e0 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -229,7 +229,7 @@ static void Engine_stepModulesWorker(Engine* that, int threadId) { } // Step module - if (!module->disabled) + if (!module->bypassed) module->process(processArgs); else module->processBypass(processArgs); @@ -626,25 +626,25 @@ void Engine::randomizeModule(Module* module) { } -void Engine::disableModule(Module* module, bool disabled) { +void Engine::bypassModule(Module* module, bool bypassed) { std::lock_guard lock(internal->mutex); assert(module); - if (module->disabled == disabled) + if (module->bypassed == bypassed) return; // Clear outputs and set to 1 channel for (Output& output : module->outputs) { // This zeros all voltages, but the channel is set to 1 if connected output.setChannels(0); } - module->disabled = disabled; + module->bypassed = bypassed; // Trigger event - if (disabled) { - Module::DisableEvent eDisable; - module->onDisable(eDisable); + if (bypassed) { + Module::BypassEvent eBypass; + module->onBypass(eBypass); } else { - Module::EnableEvent eEnable; - module->onEnable(eEnable); + Module::UnBypassEvent eUnBypass; + module->onUnBypass(eUnBypass); } } diff --git a/src/engine/Module.cpp b/src/engine/Module.cpp index d6cffe90..13dbb053 100644 --- a/src/engine/Module.cpp +++ b/src/engine/Module.cpp @@ -91,9 +91,9 @@ json_t* Module::toJson() { } json_object_set_new(rootJ, "params", paramsJ); - // disabled - if (disabled) - json_object_set_new(rootJ, "disabled", json_boolean(disabled)); + // bypassed + if (bypassed) + json_object_set_new(rootJ, "bypassed", json_boolean(bypassed)); // leftModuleId if (leftExpander.moduleId >= 0) @@ -183,13 +183,16 @@ void Module::fromJson(json_t* rootJ) { params[paramId].setValue(json_number_value(valueJ)); } - // disabled - json_t* disabledJ = json_object_get(rootJ, "disabled"); - // legacy bypass - if (!disabledJ) - disabledJ = json_object_get(rootJ, "bypass"); - if (disabledJ) - disabled = json_boolean_value(disabledJ); + // bypassed + json_t* bypassedJ = json_object_get(rootJ, "bypassed"); + // legacy "bypass" in v0.6 or early v1 (don't remember) + if (!bypassedJ) + bypassedJ = json_object_get(rootJ, "bypass"); + // legacy "disabled" in v1 + if (!bypassedJ) + bypassedJ = json_object_get(rootJ, "disabled"); + if (bypassedJ) + bypassed = json_boolean_value(bypassedJ); // These do not need to be deserialized, since the module positions will set them correctly when added to the rack. // // leftModuleId diff --git a/src/history.cpp b/src/history.cpp index 6444429f..8c5e7854 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -83,16 +83,16 @@ void ModuleMove::redo() { } -void ModuleDisable::undo() { +void ModuleBypass::undo() { engine::Module* module = APP->engine->getModule(moduleId); assert(module); - APP->engine->disableModule(module, !disabled); + APP->engine->bypassModule(module, !bypassed); } -void ModuleDisable::redo() { +void ModuleBypass::redo() { engine::Module* module = APP->engine->getModule(moduleId); assert(module); - APP->engine->disableModule(module, disabled); + APP->engine->bypassModule(module, bypassed); } diff --git a/src/plugin/Plugin.cpp b/src/plugin/Plugin.cpp index 7e41f8ba..be50bbf5 100644 --- a/src/plugin/Plugin.cpp +++ b/src/plugin/Plugin.cpp @@ -102,7 +102,7 @@ void Plugin::fromJson(json_t* rootJ) { size_t moduleId; json_t* moduleJ; json_array_foreach(modulesJ, moduleId, moduleJ) { - // Check if module is disabled + // Check if model is disabled json_t* disabledJ = json_object_get(moduleJ, "disabled"); if (disabledJ) { if (json_boolean_value(disabledJ))