gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

commit 87396ebf3445a9602aea4f0a9c5bef65a6247c21
parent 016202706a6e2dd530bb7c19581db28e62518f56
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Sat,  3 Dec 2022 03:00:08 +0100

fix UI not updating if multiple UI objects reference the same parameter

Diffstat:
Msource/jucePlugin/VirusController.cpp | 4++--
Msource/jucePlugin/VirusParameterBinding.cpp | 18++++++++++++++----
Msource/jucePlugin/VirusParameterBinding.h | 2++
Msource/jucePluginLib/parameter.cpp | 23+++++++++++++++++++++--
Msource/jucePluginLib/parameter.h | 4+++-
5 files changed, 42 insertions(+), 9 deletions(-)

diff --git a/source/jucePlugin/VirusController.cpp b/source/jucePlugin/VirusController.cpp @@ -51,7 +51,7 @@ namespace Virus const auto& params = findSynthParam(0, 0x72, 0x7a); for (const auto& parameter : params) { - parameter->onValueChanged = [this] { + parameter->onValueChanged.emplace_back(std::make_pair(0, [this] { const uint8_t prg = isMultiMode() ? 0x0 : virusLib::SINGLE; requestSingle(0, prg); requestMulti(0, prg); @@ -60,7 +60,7 @@ namespace Virus { onMsgDone(); } - }; + })); } requestTotal(); requestArrangement(); diff --git a/source/jucePlugin/VirusParameterBinding.cpp b/source/jucePlugin/VirusParameterBinding.cpp @@ -18,7 +18,8 @@ void VirusParameterBinding::clearBindings() if(slider != nullptr) removeMouseListener(*slider); - b.parameter->onValueChanged = nullptr; + if(b.onChangeListenerId) + b.parameter->removeListener(b.onChangeListenerId); } m_bindings.clear(); @@ -136,7 +137,8 @@ void VirusParameterBinding::bind(juce::ComboBox& _combo, const uint32_t _param, } //_combo.addItemList(v->getAllValueStrings(), 1); _combo.setSelectedId(static_cast<int>(v->getValueObject().getValueSource().getValue()) + 1, juce::dontSendNotification); - _combo.onChange = [this, &_combo, v]() { + _combo.onChange = [this, &_combo, v]() + { if(v->getDescription().isPublic) { v->beginChangeGesture(); @@ -145,8 +147,16 @@ void VirusParameterBinding::bind(juce::ComboBox& _combo, const uint32_t _param, } v->getValueObject().getValueSource().setValue((int)_combo.getSelectedId() - 1); }; - v->onValueChanged = [this, &_combo, v]() { _combo.setSelectedId(static_cast<int>(v->getValueObject().getValueSource().getValue()) + 1, juce::dontSendNotification); }; - const BoundParameter p{v, &_combo, _param, _part}; + + const auto listenerId = m_nextListenerId++; + + v->onValueChanged.emplace_back(std::make_pair(listenerId, [this, &_combo, v]() + { + const auto value = static_cast<int>(v->getValueObject().getValueSource().getValue()); + _combo.setSelectedId(value + 1, juce::dontSendNotification); + })); + + const BoundParameter p{v, &_combo, _param, _part, listenerId}; m_bindings.emplace_back(p); } diff --git a/source/jucePlugin/VirusParameterBinding.h b/source/jucePlugin/VirusParameterBinding.h @@ -49,8 +49,10 @@ private: juce::Component* component = nullptr; uint32_t type = 0xffffffff; uint8_t part = CurrentPart; + uint32_t onChangeListenerId = 0; }; std::vector<BoundParameter> m_bindings; std::map<juce::Slider*, MouseListener*> m_sliderMouseListeners; + uint32_t m_nextListenerId = 1; }; diff --git a/source/jucePluginLib/parameter.cpp b/source/jucePluginLib/parameter.cpp @@ -25,8 +25,9 @@ namespace pluginLib m_ctrl.sendParameterChange(*this, value); m_lastValue = value; } - if (onValueChanged) - onValueChanged(); + + for (const auto& func : onValueChanged) + func.second(); } void Parameter::setLinkedValue(const int _value) @@ -102,6 +103,24 @@ namespace pluginLib m_changingLinkedValues = false; } + bool Parameter::removeListener(const uint32_t _id) + { + bool res = false; + for(auto it = onValueChanged.begin(); it !=onValueChanged.end();) + { + if(it->first == _id) + { + it = onValueChanged.erase(it); + res = true; + } + else + { + ++it; + } + } + return res; + } + juce::String Parameter::genId(const pluginLib::Description &d, const int part, const int uniqueId) { if(uniqueId > 0) diff --git a/source/jucePluginLib/parameter.h b/source/jucePluginLib/parameter.h @@ -57,7 +57,7 @@ namespace pluginLib // allow 'injecting' additional code for specific parameter. // eg. multi/single value change requires triggering more logic. - std::function<void()> onValueChanged = {}; + std::list<std::pair<uint32_t, std::function<void()>>> onValueChanged; void addLinkedParameter(Parameter* _param); @@ -65,6 +65,8 @@ namespace pluginLib const std::set<Parameter*>& getLinkedParameters() { return m_linkedParameters; } + bool removeListener(uint32_t _id); + private: static juce::String genId(const Description &d, int part, int uniqueId); void valueChanged(juce::Value &) override;