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