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 6aa2e295fd90c5f26df8ae5073d50189bbc6a571
parent 9918feaf008b2c845d86d3433b2a71fde6003a0c
Author: dsp56300 <dsp56300@users.noreply.github.com>
Date:   Fri, 31 May 2024 15:10:03 +0200

arp user pattern uses new event system

Diffstat:
Msource/jucePluginLib/event.h | 42++++++++++++++++++++++++++++++++++--------
Msource/jucePluginLib/parameter.h | 2++
Msource/virusJucePlugin/ArpUserPattern.cpp | 33+++++++++++++--------------------
Msource/virusJucePlugin/ArpUserPattern.h | 17++++++++++-------
4 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/source/jucePluginLib/event.h b/source/jucePluginLib/event.h @@ -3,6 +3,7 @@ #include <functional> #include <map> #include <cassert> +#include <optional> namespace pluginLib { @@ -49,6 +50,14 @@ namespace pluginLib m_listeners.erase(_id); } + std::optional<Callback> getListener(const ListenerId _id) const + { + const auto it = m_listeners.find(_id); + if(it != m_listeners.end()) + return it->second; + return {}; + } + void clear() { m_listeners.clear(); @@ -140,13 +149,34 @@ namespace pluginLib m_listenerId = m_event->addListener(_func); } - void set(Event<Ts...>& _event, const MyCallback& _func) + void set(MyEvent& _event, const MyCallback& _func) { removeListener(); m_event = &_event; m_listenerId = _event.addListener(_func); } + void set(MyEvent& _event) + { + if(&_event == m_event) + return; + + if(isBound()) + { + if(auto callback = m_event->getListener(m_listenerId)) + { + m_event->removeListener(m_listenerId); + m_listenerId = _event.addListener(callback); + } + else + { + removeListener(); + } + } + + m_event = &_event; + } + bool isBound() const { return m_listenerId != InvalidListenerId; } bool isValid() const { return m_event != nullptr; } @@ -156,17 +186,12 @@ namespace pluginLib return *this; } - EventListener& operator = (Event<Ts...>& _event) noexcept + EventListener& operator = (MyEvent& _event) noexcept { - if(&_event == m_event) - return *this; - - removeListener(); - m_event = &_event; + set(_event); return *this; } - private: void removeListener() { if(m_listenerId == InvalidListenerId) @@ -176,6 +201,7 @@ namespace pluginLib m_listenerId = InvalidListenerId; } + private: MyEvent* m_event = nullptr; MyListenerId m_listenerId = InvalidListenerId; }; diff --git a/source/jucePluginLib/parameter.h b/source/jucePluginLib/parameter.h @@ -119,4 +119,6 @@ namespace pluginLib uint32_t m_uniqueDelayCallbackId = 0; bool m_isLocked = false; }; + + using ParameterValueChangeListener = EventListener<Parameter*>; } diff --git a/source/virusJucePlugin/ArpUserPattern.cpp b/source/virusJucePlugin/ArpUserPattern.cpp @@ -8,11 +8,6 @@ namespace genericVirusUI { - namespace - { - constexpr uint32_t g_listenerId = 0xaa; - } - ArpUserPattern::ArpUserPattern(const VirusEditor& _editor) : m_controller(_editor.getController()) { bindParameters(); @@ -20,7 +15,7 @@ namespace genericVirusUI void ArpUserPattern::paint(juce::Graphics& g) { - if(!m_patternLength) + if(!m_patternLength.first) return; if(m_gradientStrength <= 0.0f) @@ -50,13 +45,13 @@ namespace genericVirusUI float x = 0.0f; - for(int i=0; i<std::min(m_patternLength->getUnnormalizedValue() + 1, static_cast<int>(m_steps.size())); ++i) + for(int i=0; i<std::min(m_patternLength.first->getUnnormalizedValue() + 1, static_cast<int>(m_steps.size())); ++i) { - const auto stepW = m_steps[i].length->getValue() * maxstepW; - const auto stepH = m_steps[i].velocity->getValue() * h; + const auto stepW = m_steps[i].length.first->getValue() * maxstepW; + const auto stepH = m_steps[i].velocity.first->getValue() * h; const auto y = h - stepH; - g.setGradientFill(m_steps[i].bitfield->getUnnormalizedValue() > 0 ? rectGradientActive : rectGradientInactive); + g.setGradientFill(m_steps[i].bitfield.first->getUnnormalizedValue() > 0 ? rectGradientActive : rectGradientInactive); g.fillRect(x, y, stepW, stepH); x += maxstepW; @@ -83,16 +78,16 @@ namespace genericVirusUI m_patternLength = bindParameter("Arpeggiator/UserPatternLength"); } - void ArpUserPattern::unbindParameter(pluginLib::Parameter*& _parameter) + void ArpUserPattern::unbindParameter(BoundParam& _parameter) { - assert(_parameter); - _parameter->removeListener(g_listenerId); - _parameter = nullptr; + assert(_parameter.first); + _parameter.second.removeListener(); + _parameter.first = nullptr; } void ArpUserPattern::unbindParameters() { - if(!m_patternLength) + if(!m_patternLength.first) return; unbindParameter(m_patternLength); @@ -105,19 +100,17 @@ namespace genericVirusUI } } - pluginLib::Parameter* ArpUserPattern::bindParameter(const std::string& _name) + ArpUserPattern::BoundParam ArpUserPattern::bindParameter(const std::string& _name) { const auto idx = m_controller.getParameterIndexByName(_name); assert(idx != pluginLib::Controller::InvalidParameterIndex); auto* p = m_controller.getParameter(idx, m_controller.getCurrentPart()); assert(p); - p->onValueChanged.emplace_back(g_listenerId, [this]() + return std::make_pair(p, pluginLib::ParameterValueChangeListener(p->evValueChanged, [this](pluginLib::Parameter*) { onParameterChanged(); - }); - - return p; + })); } void ArpUserPattern::onParameterChanged() diff --git a/source/virusJucePlugin/ArpUserPattern.h b/source/virusJucePlugin/ArpUserPattern.h @@ -2,10 +2,11 @@ #include "juce_gui_basics/juce_gui_basics.h" +#include "../jucePluginLib/parameter.h" + namespace pluginLib { class Controller; - class Parameter; } namespace genericVirusUI @@ -15,6 +16,8 @@ namespace genericVirusUI class ArpUserPattern : public juce::Component { public: + using BoundParam = std::pair<pluginLib::Parameter*, pluginLib::ParameterValueChangeListener>; + ArpUserPattern(const VirusEditor& _editor); void paint(juce::Graphics& g) override; @@ -23,22 +26,22 @@ namespace genericVirusUI private: void unbindParameters(); void bindParameters(); - static void unbindParameter(pluginLib::Parameter*& _parameter); + static void unbindParameter(BoundParam& _parameter); - pluginLib::Parameter* bindParameter(const std::string& _name); + BoundParam bindParameter(const std::string& _name); void onParameterChanged(); struct Step { - pluginLib::Parameter* length = nullptr; - pluginLib::Parameter* velocity = nullptr; - pluginLib::Parameter* bitfield = nullptr; + BoundParam length; + BoundParam velocity; + BoundParam bitfield; }; pluginLib::Controller& m_controller; std::array<Step, 32> m_steps; - pluginLib::Parameter* m_patternLength = nullptr; + BoundParam m_patternLength; juce::Colour m_colRectFillActive = juce::Colour(0xddffffff); juce::Colour m_colRectFillInactive = juce::Colour(0x77aaaaaa);