From b6c111645a8f17d045faa3a5a3f58652d660ef49 Mon Sep 17 00:00:00 2001 From: jules Date: Wed, 12 Jun 2019 14:14:45 +0100 Subject: [PATCH] Refactored some AudioProcessor addParam methods to make sure the parameters always have a valid index set --- .../processors/juce_AudioProcessor.cpp | 96 ++++++++++++------- .../processors/juce_AudioProcessor.h | 8 +- 2 files changed, 66 insertions(+), 38 deletions(-) diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp index 4a4ab1cb77..dcd264429d 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.cpp @@ -420,68 +420,92 @@ AudioProcessorListener* AudioProcessor::getListenerLocked (int index) const noex void AudioProcessor::updateHostDisplay() { for (int i = listeners.size(); --i >= 0;) - if (auto* l = getListenerLocked (i)) + if (auto l = getListenerLocked (i)) l->audioProcessorChanged (this); } -const Array& AudioProcessor::getParameters() const +#if JUCE_DEBUG +void AudioProcessor::checkDuplicateParamIDs() { - if (flatParamListNeedsRebuilding) - { - flatParamListNeedsRebuilding = false; - flatParameterList = parameterTree.getParameters (true); + duplicateParamIDCheck.reset(); - #ifdef JUCE_DEBUG - StringArray usedIDs; - usedIDs.ensureStorageAllocated (flatParameterList.size()); - #endif + StringArray usedIDs; + usedIDs.ensureStorageAllocated (flatParameterList.size()); - int index = 0; + for (auto& p : flatParameterList) + if (auto* withID = dynamic_cast (p)) + usedIDs.add (withID->paramID); - for (auto& p : flatParameterList) - { - p->processor = const_cast (this); - p->parameterIndex = index++; + usedIDs.sort (false); - #ifdef JUCE_DEBUG - if (auto* withID = dynamic_cast (p)) - usedIDs.add (withID->paramID); - #endif - } + // This assertion checks whether you attempted to add two or more parameters with the same ID + for (int i = 1; i < usedIDs.size(); ++i) + jassert (usedIDs[i - 1] != usedIDs[i]); +} - #ifdef JUCE_DEBUG - usedIDs.sort (false); +struct AudioProcessor::DuplicateParamIDCheck : private AsyncUpdater +{ + DuplicateParamIDCheck (AudioProcessor& p) : owner (p) { triggerAsyncUpdate(); } + void handleAsyncUpdate() override { owner.checkDuplicateParamIDs(); } - // This assertion checks whether you attempted to add two or more parameters with the same ID - for (int i = 1; i < usedIDs.size(); ++i) - jassert (usedIDs[i - 1] != usedIDs[i]); - #endif - } + AudioProcessor& owner; +}; +#endif - return flatParameterList; +void AudioProcessor::triggerDuplicateParamIDCheck() +{ + #if JUCE_DEBUG + if (MessageManager::getInstanceWithoutCreating() != nullptr) + duplicateParamIDCheck = std::make_unique (*this); + #endif } +const Array& AudioProcessor::getParameters() const { return flatParameterList; } +const AudioProcessorParameterGroup& AudioProcessor::getParameterTree() const { return parameterTree; } + void AudioProcessor::addParameter (AudioProcessorParameter* param) { + jassert (param != nullptr); parameterTree.addChild (std::unique_ptr (param)); - flatParamListNeedsRebuilding = true; + + param->processor = this; + param->parameterIndex = flatParameterList.size(); + flatParameterList.add (param); + + triggerDuplicateParamIDCheck(); } void AudioProcessor::addParameterGroup (std::unique_ptr group) { - parameterTree.addChild (std::move (group)); - flatParamListNeedsRebuilding = true; -} + jassert (group != nullptr); -const AudioProcessorParameterGroup& AudioProcessor::getParameterTree() const -{ - return parameterTree; + auto oldSize = flatParameterList.size(); + flatParameterList.addArray (group->getParameters (true)); + + for (int i = oldSize; i < flatParameterList.size(); ++i) + { + auto p = flatParameterList.getUnchecked (i); + p->processor = this; + p->parameterIndex = i; + } + + parameterTree.addChild (std::move (group)); + triggerDuplicateParamIDCheck(); } void AudioProcessor::setParameterTree (AudioProcessorParameterGroup&& newTree) { parameterTree = std::move (newTree); - flatParamListNeedsRebuilding = true; + flatParameterList = parameterTree.getParameters (true); + + for (int i = 0; i < flatParameterList.size(); ++i) + { + auto p = flatParameterList.getUnchecked (i); + p->processor = this; + p->parameterIndex = i; + } + + triggerDuplicateParamIDCheck(); } void AudioProcessor::refreshParameterList() {} diff --git a/modules/juce_audio_processors/processors/juce_AudioProcessor.h b/modules/juce_audio_processors/processors/juce_AudioProcessor.h index 26965b754f..434e96f5af 100644 --- a/modules/juce_audio_processors/processors/juce_AudioProcessor.h +++ b/modules/juce_audio_processors/processors/juce_AudioProcessor.h @@ -1467,8 +1467,7 @@ private: int cachedTotalIns = 0, cachedTotalOuts = 0; AudioProcessorParameterGroup parameterTree; - mutable Array flatParameterList; - mutable bool flatParamListNeedsRebuilding = true; + Array flatParameterList; AudioProcessorParameter* getParamChecked (int) const; @@ -1478,12 +1477,17 @@ private: #endif bool textRecursionCheck = false; + + struct DuplicateParamIDCheck; + std::unique_ptr duplicateParamIDCheck; + void checkDuplicateParamIDs(); #endif AudioProcessorListener* getListenerLocked (int) const noexcept; void updateSpeakerFormatStrings(); void audioIOChanged (bool busNumberChanged, bool channelNumChanged); void getNextBestLayout (const BusesLayout&, BusesLayout&) const; + void triggerDuplicateParamIDCheck(); template void processBypassed (AudioBuffer&, MidiBuffer&);