| @@ -0,0 +1,22 @@ | |||
| Checks: > | |||
| -clang-analyzer-cplusplus.NewDeleteLeaks, | |||
| -clang-analyzer-optin.performance.Padding, | |||
| -clang-analyzer-security.FloatLoopCounter, | |||
| -clang-analyzer-security.insecureAPI.strcpy, | |||
| WarningsAsErrors: '*' | |||
| # No negative lookahead available here, which makes things difficult. | |||
| # | |||
| # We want checks to run on JUCE files included from the JUCE modules. We can | |||
| # restrict these to files named `juce_.*`. | |||
| # | |||
| # We also want checks to run on any files inlcuded from the examples or extras | |||
| # directories. However, some include paths generated by the Android Studio build | |||
| # system look like: | |||
| # | |||
| # ~/JUCE/examples/DemoRunner/Builds/Android/app/../../../../../modules/juce_box2d/box2d/Collision/b2CollideEdge.cpp | |||
| # | |||
| # Since we can only opt-in to paths, we restrict the maximum depth of the path | |||
| # past examples/extras. | |||
| HeaderFilterRegex: '(.*\/modules\/juce_.*juce_[^\/]*$)|(\/(examples|extras)(\/[^\/]*){1,7}$)' | |||
| @@ -67,7 +67,7 @@ struct CodeContent : public Component | |||
| codeEditor.setReadOnly (true); | |||
| codeEditor.setScrollbarThickness (8); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| void resized() override | |||
| @@ -83,9 +83,9 @@ struct CodeContent : public Component | |||
| "*******************************************************************************/\n"); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| void updateLookAndFeel() | |||
| { | |||
| auto* v4 = dynamic_cast <LookAndFeel_V4*> (&Desktop::getInstance().getDefaultLookAndFeel()); | |||
| auto* v4 = dynamic_cast<LookAndFeel_V4*> (&Desktop::getInstance().getDefaultLookAndFeel()); | |||
| if (v4 != nullptr && (v4->getCurrentColourScheme() != LookAndFeel_V4::getLightColourScheme())) | |||
| codeEditor.setColourScheme (getDarkColourScheme()); | |||
| @@ -93,6 +93,11 @@ struct CodeContent : public Component | |||
| codeEditor.setColourScheme (getLightColourScheme()); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| CodeDocument document; | |||
| CPlusPlusCodeTokeniser cppTokensier; | |||
| CodeEditorComponent codeEditor { document, &cppTokensier }; | |||
| @@ -115,7 +120,7 @@ DemoContentComponent::DemoContentComponent (Component& mainComponent, std::funct | |||
| addTab ("Settings", Colours::transparentBlack, new SettingsContent (dynamic_cast<MainComponent&> (mainComponent)), true); | |||
| setTabBarDepth (40); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| DemoContentComponent::~DemoContentComponent() | |||
| @@ -182,7 +187,7 @@ void DemoContentComponent::clearCurrentDemo() | |||
| demoChangedCallback (false); | |||
| } | |||
| void DemoContentComponent::lookAndFeelChanged() | |||
| void DemoContentComponent::updateLookAndFeel() | |||
| { | |||
| auto backgroundColour = findColour (ResizableWindow::backgroundColourId); | |||
| @@ -190,6 +195,11 @@ void DemoContentComponent::lookAndFeelChanged() | |||
| setTabBackgroundColour (i, backgroundColour); | |||
| } | |||
| void DemoContentComponent::lookAndFeelChanged() | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| String DemoContentComponent::trimPIP (const String& fileContents) | |||
| { | |||
| auto lines = StringArray::fromLines (fileContents); | |||
| @@ -63,6 +63,7 @@ private: | |||
| int tabBarIndent = 0; | |||
| //============================================================================== | |||
| void updateLookAndFeel(); | |||
| void lookAndFeelChanged() override; | |||
| String trimPIP (const String& fileContents); | |||
| @@ -80,7 +80,7 @@ struct SidePanelHeader : public Component | |||
| addAndMakeVisible (settingsButton); | |||
| settingsButton.onClick = [this] { owner.settingsButtonClicked(); }; | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| void paint (Graphics& g) override | |||
| @@ -102,7 +102,7 @@ struct SidePanelHeader : public Component | |||
| titleLabel.setBounds (bounds); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| void updateLookAndFeel() | |||
| { | |||
| auto& sidePanel = owner.getSidePanel(); | |||
| auto& lf = sidePanel.getLookAndFeel(); | |||
| @@ -117,6 +117,12 @@ struct SidePanelHeader : public Component | |||
| homeButton.setColours (normal, over, down); | |||
| settingsButton.setColours (normal, over, down); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| MainComponent& owner; | |||
| @@ -422,8 +422,8 @@ private: | |||
| if (wi.get() != nullptr && wo.get() != nullptr) | |||
| { | |||
| auto numWritten = wo->writeFromInputStream (*wi, -1); | |||
| jassertquiet (numWritten > 0); | |||
| [[maybe_unused]] auto numWritten = wo->writeFromInputStream (*wi, -1); | |||
| jassert (numWritten > 0); | |||
| wo->flush(); | |||
| } | |||
| } | |||
| @@ -500,14 +500,14 @@ public: | |||
| currentScaleFactor = scale; | |||
| AudioProcessorEditor::setScaleFactor (scale); | |||
| const auto posted = MessageManager::callAsync ([ref = SafePointer<HostAudioProcessorEditor> (this), scale] | |||
| [[maybe_unused]] const auto posted = MessageManager::callAsync ([ref = SafePointer<HostAudioProcessorEditor> (this), scale] | |||
| { | |||
| if (auto* r = ref.getComponent()) | |||
| if (auto* e = r->currentEditorComponent) | |||
| e->setScaleFactor (scale); | |||
| }); | |||
| jassertquiet (posted); | |||
| jassert (posted); | |||
| } | |||
| private: | |||
| @@ -520,8 +520,8 @@ private: | |||
| { | |||
| auto editorComponent = std::make_unique<PluginEditorComponent> (hostProcessor.createInnerEditor(), [this] | |||
| { | |||
| const auto posted = MessageManager::callAsync ([this] { clearPlugin(); }); | |||
| jassertquiet (posted); | |||
| [[maybe_unused]] const auto posted = MessageManager::callAsync ([this] { clearPlugin(); }); | |||
| jassert (posted); | |||
| }); | |||
| editorComponent->setScaleFactor (currentScaleFactor); | |||
| @@ -103,7 +103,7 @@ public: | |||
| if (auto* file = getAppProperties().getUserSettings()) | |||
| file->addChangeListener (this); | |||
| changeListenerCallback (nullptr); | |||
| handleChange(); | |||
| } | |||
| ~CustomPluginScanner() override | |||
| @@ -183,12 +183,17 @@ private: | |||
| } | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) override | |||
| void handleChange() | |||
| { | |||
| if (auto* file = getAppProperties().getUserSettings()) | |||
| scanInProcess = (file->getIntValue (scanModeKey) == 0); | |||
| } | |||
| void changeListenerCallback (ChangeBroadcaster*) override | |||
| { | |||
| handleChange(); | |||
| } | |||
| std::unique_ptr<Superprocess> superprocess; | |||
| std::atomic<bool> scanInProcess { true }; | |||
| @@ -226,10 +231,16 @@ public: | |||
| getAppProperties().getUserSettings()->setValue (scanModeKey, validationModeBox.getSelectedItemIndex()); | |||
| }; | |||
| resized(); | |||
| handleResize(); | |||
| } | |||
| void resized() override | |||
| { | |||
| handleResize(); | |||
| } | |||
| private: | |||
| void handleResize() | |||
| { | |||
| PluginListComponent::resized(); | |||
| @@ -237,7 +248,7 @@ public: | |||
| validationModeBox.setBounds (buttonBounds.withWidth (130).withRightX (getWidth() - buttonBounds.getX())); | |||
| } | |||
| private: | |||
| Label validationModeLabel { {}, "Scan mode" }; | |||
| ComboBox validationModeBox; | |||
| @@ -61,7 +61,7 @@ public: | |||
| OSCReceiver::addListener (this); | |||
| timerCallback(); | |||
| handleTimerCallback(); | |||
| startTimer (2000); | |||
| } | |||
| @@ -200,12 +200,18 @@ private: | |||
| return {}; | |||
| } | |||
| void timerCallback() override | |||
| void handleTimerCallback() | |||
| { | |||
| send (newClientOSCAddress, clientName + ":" + IPAddress::getLocalAddress().toString() | |||
| + ":" + getScreenAreaInGlobalSpace().toString()); | |||
| } | |||
| void timerCallback() override | |||
| { | |||
| handleTimerCallback(); | |||
| } | |||
| void handleAsyncUpdate() override | |||
| { | |||
| const ScopedLock sl (canvasLock); | |||
| @@ -82,7 +82,7 @@ public: | |||
| setWantsKeyboardFocus (true); | |||
| setOpaque (true); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| setSize (300, 350); | |||
| } | |||
| @@ -134,11 +134,16 @@ public: | |||
| URL ("https://juce.com/verification/register").launchInDefaultBrowser(); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| void updateLookAndFeel() | |||
| { | |||
| enableGPLButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| private: | |||
| class ProgressButton : public TextButton, | |||
| private Timer | |||
| @@ -164,7 +164,7 @@ public: | |||
| juceIcon = Drawable::createFromImageData (BinaryData::juce_icon_png, | |||
| BinaryData::juce_icon_pngSize); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| setSize (500, 280); | |||
| } | |||
| @@ -218,12 +218,17 @@ public: | |||
| } | |||
| private: | |||
| void lookAndFeelChanged() override | |||
| void updateLookAndFeel() | |||
| { | |||
| cancelButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); | |||
| releaseNotesEditor.applyFontToAllText (releaseNotesEditor.getFont()); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| void setParentWindow (DialogWindow* parent) | |||
| { | |||
| parentWindow = parent; | |||
| @@ -52,7 +52,7 @@ public: | |||
| setVisible (true); | |||
| static_cast<Component&> (mainWindow).addChildComponent (this); | |||
| componentMovedOrResized (true, true); | |||
| handleComponentMovedOrResized(); | |||
| enterModalState(); | |||
| } | |||
| @@ -80,7 +80,9 @@ private: | |||
| void componentVisibilityChanged() override {} | |||
| using ComponentMovementWatcher::componentVisibilityChanged; | |||
| void componentMovedOrResized (bool, bool) override { triggerAsyncUpdate(); } | |||
| void handleComponentMovedOrResized() { triggerAsyncUpdate(); } | |||
| void componentMovedOrResized (bool, bool) override { handleComponentMovedOrResized(); } | |||
| using ComponentMovementWatcher::componentMovedOrResized; | |||
| void handleAsyncUpdate() override { resized(); } | |||
| @@ -36,7 +36,7 @@ public: | |||
| UnknownDocument (Project* p, const File& f) | |||
| : project (p), file (f) | |||
| { | |||
| reloadFromFile(); | |||
| handleReloadFromFile(); | |||
| } | |||
| //============================================================================== | |||
| @@ -57,7 +57,7 @@ public: | |||
| void saveAsync (std::function<void (bool)>) override {} | |||
| void saveAsAsync (std::function<void (bool)>) override {} | |||
| bool hasFileBeenModifiedExternally() override { return fileModificationTime != file.getLastModificationTime(); } | |||
| void reloadFromFile() override { fileModificationTime = file.getLastModificationTime(); } | |||
| void reloadFromFile() override { handleReloadFromFile(); } | |||
| String getName() const override { return file.getFileName(); } | |||
| File getFile() const override { return file; } | |||
| std::unique_ptr<Component> createEditor() override { return std::make_unique<ItemPreviewComponent> (file); } | |||
| @@ -76,6 +76,8 @@ public: | |||
| } | |||
| private: | |||
| void handleReloadFromFile() { fileModificationTime = file.getLastModificationTime(); } | |||
| Project* const project; | |||
| File file; | |||
| Time fileModificationTime; | |||
| @@ -294,7 +294,7 @@ public: | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageKeepsPropAction (button, layout, newState), "change imagebutton proportion mode"); | |||
| layout.perform (std::make_unique<SetImageKeepsPropAction> (button, layout, newState), "change imagebutton proportion mode"); | |||
| } | |||
| else | |||
| { | |||
| @@ -371,7 +371,7 @@ public: | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageOpacityAction (button, layout, role, opacity), "change imagebutton opacity"); | |||
| layout.perform (std::make_unique<SetImageOpacityAction> (button, layout, role, opacity), "change imagebutton opacity"); | |||
| } | |||
| else | |||
| { | |||
| @@ -453,7 +453,7 @@ public: | |||
| { | |||
| if (undoable) | |||
| { | |||
| layout.perform (new SetImageColourAction (button, layout, role, colour), "change imagebutton colour"); | |||
| layout.perform (std::make_unique<SetImageColourAction> (button, layout, role, colour), "change imagebutton colour"); | |||
| } | |||
| else | |||
| { | |||
| @@ -1017,6 +1017,7 @@ bool PaintElementPath::getPoint (int index, int pointNumber, double& x, double& | |||
| if (pointNumber >= PathPoint::maxRects) | |||
| { | |||
| jassertfalse; | |||
| x = y = 0; | |||
| return false; | |||
| } | |||
| @@ -43,7 +43,7 @@ public: | |||
| PaintElementPath* owner; | |||
| Path::Iterator::PathElementType type; | |||
| RelativePositionedRectangle pos [maxRects]; | |||
| RelativePositionedRectangle pos[maxRects] = {}; | |||
| int getNumPoints() const; | |||
| @@ -422,15 +422,13 @@ public: | |||
| protected: | |||
| class PositionPropLabel : public Label | |||
| { | |||
| PositionPropertyBase& owner; | |||
| public: | |||
| PositionPropLabel (PositionPropertyBase& owner_) | |||
| : Label (String(), String()), | |||
| owner (owner_) | |||
| { | |||
| setEditable (true, true, false); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| TextEditor* createEditorComponent() override | |||
| @@ -447,10 +445,18 @@ protected: | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| private: | |||
| void updateLookAndFeel() | |||
| { | |||
| setColour (backgroundColourId, findColour (widgetBackgroundColourId)); | |||
| setColour (textColourId, findColour (widgetTextColourId)); | |||
| } | |||
| PositionPropertyBase& owner; | |||
| }; | |||
| ComponentLayout* layout; | |||
| @@ -47,7 +47,7 @@ ComponentOverlayComponent::ComponentOverlayComponent (Component* const target_, | |||
| target->addComponentListener (this); | |||
| changeListenerCallback (nullptr); | |||
| updateSelected(); | |||
| layout.getSelectedSet().addChangeListener (this); | |||
| setRepaintsOnMouseActivity (true); | |||
| @@ -62,7 +62,7 @@ ComponentOverlayComponent::~ComponentOverlayComponent() | |||
| target->removeComponentListener (this); | |||
| } | |||
| void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*) | |||
| void ComponentOverlayComponent::updateSelected() | |||
| { | |||
| const bool nowSelected = layout.getSelectedSet().isSelected (target); | |||
| @@ -74,6 +74,11 @@ void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*) | |||
| } | |||
| } | |||
| void ComponentOverlayComponent::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| updateSelected(); | |||
| } | |||
| void ComponentOverlayComponent::paint (Graphics& g) | |||
| { | |||
| jassert (target != nullptr); | |||
| @@ -73,6 +73,7 @@ private: | |||
| void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override; | |||
| void updateSelected(); | |||
| void changeListenerCallback (ChangeBroadcaster*) override; | |||
| std::unique_ptr<ResizableBorderComponent> border; | |||
| @@ -34,13 +34,12 @@ public: | |||
| explicit MagnifierComponent (Component* c) : content (c) | |||
| { | |||
| addAndMakeVisible (content.get()); | |||
| childBoundsChanged (content.get()); | |||
| updateBounds (content.get()); | |||
| } | |||
| void childBoundsChanged (Component* child) | |||
| { | |||
| auto childArea = getLocalArea (child, child->getLocalBounds()); | |||
| setSize (childArea.getWidth(), childArea.getHeight()); | |||
| updateBounds (child); | |||
| } | |||
| double getScaleFactor() const { return scaleFactor; } | |||
| @@ -52,6 +51,12 @@ public: | |||
| } | |||
| private: | |||
| void updateBounds (Component* child) | |||
| { | |||
| auto childArea = getLocalArea(child, child->getLocalBounds()); | |||
| setSize (childArea.getWidth(), childArea.getHeight()); | |||
| } | |||
| double scaleFactor = 1.0; | |||
| std::unique_ptr<Component> content; | |||
| }; | |||
| @@ -350,10 +350,10 @@ JucerDocumentEditor::JucerDocumentEditor (JucerDocument* const doc) | |||
| document->addChangeListener (this); | |||
| resized(); | |||
| handleResize(); | |||
| refreshPropertiesPanel(); | |||
| changeListenerCallback (nullptr); | |||
| handleChange(); | |||
| } | |||
| } | |||
| @@ -428,17 +428,27 @@ void JucerDocumentEditor::paint (Graphics& g) | |||
| g.fillAll (findColour (backgroundColourId)); | |||
| } | |||
| void JucerDocumentEditor::resized() | |||
| void JucerDocumentEditor::handleResize() | |||
| { | |||
| tabbedComponent.setBounds (getLocalBounds().withTrimmedLeft (12)); | |||
| } | |||
| void JucerDocumentEditor::changeListenerCallback (ChangeBroadcaster*) | |||
| void JucerDocumentEditor::resized() | |||
| { | |||
| handleResize(); | |||
| } | |||
| void JucerDocumentEditor::handleChange() | |||
| { | |||
| setName (document->getClassName()); | |||
| updateTabs(); | |||
| } | |||
| void JucerDocumentEditor::changeListenerCallback (ChangeBroadcaster*) | |||
| { | |||
| handleChange(); | |||
| } | |||
| //============================================================================== | |||
| ApplicationCommandTarget* JucerDocumentEditor::getNextCommandTarget() | |||
| { | |||
| @@ -67,6 +67,9 @@ public: | |||
| static JucerDocumentEditor* getActiveDocumentHolder(); | |||
| private: | |||
| void handleResize(); | |||
| void handleChange(); | |||
| void changeListenerCallback (ChangeBroadcaster*) override; | |||
| std::unique_ptr<JucerDocument> document; | |||
| @@ -95,7 +95,7 @@ ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc) | |||
| document.addChangeListener (this); | |||
| handleCommandMessage (1); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| ResourceEditorPanel::~ResourceEditorPanel() | |||
| @@ -180,12 +180,17 @@ int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId) | |||
| return widest + 10; | |||
| } | |||
| void ResourceEditorPanel::lookAndFeelChanged() | |||
| void ResourceEditorPanel::updateLookAndFeel() | |||
| { | |||
| listBox->setColour (ListBox::backgroundColourId, findColour (secondaryBackgroundColourId)); | |||
| listBox->setColour (ListBox::outlineColourId, Colours::transparentBlack); | |||
| } | |||
| void ResourceEditorPanel::lookAndFeelChanged() | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| //============================================================================== | |||
| class ResourceSorter | |||
| { | |||
| @@ -50,6 +50,7 @@ public: | |||
| void selectedRowsChanged (int lastRowSelected) override; | |||
| private: | |||
| void updateLookAndFeel(); | |||
| void lookAndFeelChanged() override; | |||
| void reloadAll(); | |||
| @@ -120,7 +120,7 @@ void TestComponent::updateContents() | |||
| if (loadedDocument != nullptr) | |||
| { | |||
| addAndMakeVisible (loadedDocument->createTestComponent (alwaysFillBackground)); | |||
| resized(); | |||
| handleResize(); | |||
| } | |||
| } | |||
| @@ -155,7 +155,7 @@ void TestComponent::paint (Graphics& g) | |||
| } | |||
| } | |||
| void TestComponent::resized() | |||
| void TestComponent::handleResize() | |||
| { | |||
| if (Component* const c = getChildComponent (0)) | |||
| { | |||
| @@ -164,6 +164,11 @@ void TestComponent::resized() | |||
| } | |||
| } | |||
| void TestComponent::resized() | |||
| { | |||
| handleResize(); | |||
| } | |||
| //============================================================================== | |||
| void TestComponent::showInDialogBox (JucerDocument& document) | |||
| { | |||
| @@ -54,6 +54,8 @@ public: | |||
| //============================================================================== | |||
| void paint (Graphics&) override; | |||
| void handleResize(); | |||
| void resized() override; | |||
| static void showInDialogBox (JucerDocument&); | |||
| @@ -48,19 +48,14 @@ void ComponentLayout::changed() | |||
| document->changed(); | |||
| } | |||
| void ComponentLayout::perform (UndoableAction* action, const String& actionName) | |||
| void ComponentLayout::perform (std::unique_ptr<UndoableAction> action, const String& actionName) | |||
| { | |||
| jassert (document != nullptr); | |||
| if (document != nullptr) | |||
| { | |||
| document->getUndoManager().perform (action, actionName); | |||
| } | |||
| document->getUndoManager().perform (action.release(), actionName); | |||
| else | |||
| { | |||
| std::unique_ptr<UndoableAction> deleter (action); | |||
| action->perform(); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -76,8 +71,8 @@ void ComponentLayout::clearComponents() | |||
| class AddCompAction : public UndoableAction | |||
| { | |||
| public: | |||
| AddCompAction (XmlElement* const xml_, ComponentLayout& layout_) | |||
| : indexAdded (-1), | |||
| AddCompAction (XmlElement* const xml_, ComponentLayout& layout_, int& index) | |||
| : indexRef (index), | |||
| xml (xml_), | |||
| layout (layout_) | |||
| { | |||
| @@ -89,21 +84,21 @@ public: | |||
| Component* const newComp = layout.addComponentFromXml (*xml, false); | |||
| jassert (newComp != nullptr); | |||
| indexAdded = layout.indexOfComponent (newComp); | |||
| jassert (indexAdded >= 0); | |||
| return indexAdded >= 0; | |||
| indexRef = layout.indexOfComponent (newComp); | |||
| jassert (indexRef >= 0); | |||
| return indexRef >= 0; | |||
| } | |||
| bool undo() | |||
| { | |||
| showCorrectTab(); | |||
| layout.removeComponent (layout.getComponent (indexAdded), false); | |||
| layout.removeComponent (layout.getComponent (indexRef), false); | |||
| return true; | |||
| } | |||
| int getSizeInUnits() { return 10; } | |||
| int indexAdded; | |||
| int& indexRef; | |||
| private: | |||
| std::unique_ptr<XmlElement> xml; | |||
| @@ -164,7 +159,7 @@ void ComponentLayout::removeComponent (Component* comp, const bool undoable) | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new DeleteCompAction (comp, *this), "Delete components"); | |||
| perform (std::make_unique<DeleteCompAction> (comp, *this), "Delete components"); | |||
| } | |||
| else | |||
| { | |||
| @@ -224,7 +219,7 @@ void ComponentLayout::componentToFront (Component* comp, const bool undoable) | |||
| if (comp != nullptr && components.contains (comp)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontBackCompAction (comp, *this, -1), "Move components to front"); | |||
| perform (std::make_unique<FrontBackCompAction> (comp, *this, -1), "Move components to front"); | |||
| else | |||
| moveComponentZOrder (components.indexOf (comp), -1); | |||
| } | |||
| @@ -235,7 +230,7 @@ void ComponentLayout::componentToBack (Component* comp, const bool undoable) | |||
| if (comp != nullptr && components.contains (comp)) | |||
| { | |||
| if (undoable) | |||
| perform (new FrontBackCompAction (comp, *this, 0), "Move components to back"); | |||
| perform (std::make_unique<FrontBackCompAction> (comp, *this, 0), "Move components to back"); | |||
| else | |||
| moveComponentZOrder (components.indexOf (comp), 0); | |||
| } | |||
| @@ -432,9 +427,8 @@ Component* ComponentLayout::addComponentFromXml (const XmlElement& xml, const bo | |||
| { | |||
| if (undoable) | |||
| { | |||
| AddCompAction* const action = new AddCompAction (new XmlElement (xml), *this); | |||
| perform (action, "Add new components"); | |||
| return components [action->indexAdded]; | |||
| perform (std::make_unique<AddCompAction> (new XmlElement (xml), *this, addComponentIndexAdded), "Add new components"); | |||
| return components [addComponentIndexAdded]; | |||
| } | |||
| if (ComponentTypeHandler* const type | |||
| @@ -667,7 +661,7 @@ void ComponentLayout::setComponentPosition (Component* comp, | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new ChangeCompPositionAction (comp, *this, newPos), "Move components"); | |||
| perform (std::make_unique<ChangeCompPositionAction> (comp, *this, newPos), "Move components"); | |||
| } | |||
| else | |||
| { | |||
| @@ -701,7 +695,7 @@ void ComponentLayout::setComponentBoundsAndProperties (Component* componentToPos | |||
| { | |||
| if (undoable) | |||
| { | |||
| perform (new ChangeCompBoundsAndPropertiesAction (componentToPosition, *this, newBounds, props), "Change component bounds"); | |||
| perform (std::make_unique<ChangeCompBoundsAndPropertiesAction> (componentToPosition, *this, newBounds, props), "Change component bounds"); | |||
| } | |||
| else | |||
| { | |||
| @@ -118,7 +118,7 @@ public: | |||
| void fillInGeneratedCode (GeneratedCode& code) const; | |||
| void perform (UndoableAction* action, const String& actionName); | |||
| void perform (std::unique_ptr<UndoableAction> action, const String& actionName); | |||
| void moveComponentZOrder (int oldIndex, int newIndex); | |||
| @@ -128,6 +128,8 @@ private: | |||
| SelectedItemSet <Component*> selected; | |||
| int nextCompUID; | |||
| int addComponentIndexAdded = 0; | |||
| String getUnusedMemberName (String nameRoot, Component* comp) const; | |||
| }; | |||
| @@ -712,9 +712,9 @@ Result Project::loadDocument (const File& file) | |||
| return Result::ok(); | |||
| } | |||
| Result Project::saveDocument (const File& file) | |||
| Result Project::saveDocument ([[maybe_unused]] const File& file) | |||
| { | |||
| jassertquiet (file == getFile()); | |||
| jassert (file == getFile()); | |||
| auto sharedResult = Result::ok(); | |||
| @@ -726,9 +726,10 @@ Result Project::saveDocument (const File& file) | |||
| return sharedResult; | |||
| } | |||
| void Project::saveDocumentAsync (const File& file, std::function<void (Result)> afterSave) | |||
| void Project::saveDocumentAsync ([[maybe_unused]] const File& file, | |||
| std::function<void (Result)> afterSave) | |||
| { | |||
| jassertquiet (file == getFile()); | |||
| jassert (file == getFile()); | |||
| saveProject (Async::yes, nullptr, std::move (afterSave)); | |||
| } | |||
| @@ -1263,6 +1264,7 @@ const build_tools::ProjectType& Project::getProjectType() const | |||
| auto* guiType = build_tools::ProjectType::findType (build_tools::ProjectType_GUIApp::getTypeName()); | |||
| jassert (guiType != nullptr); | |||
| // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) | |||
| return *guiType; | |||
| } | |||
| @@ -65,7 +65,7 @@ public: | |||
| CodeBlocksProjectExporter (Project& p, const ValueTree& t, CodeBlocksOS codeBlocksOs) | |||
| : ProjectExporter (p, t), os (codeBlocksOs) | |||
| { | |||
| if (isWindows()) | |||
| if (isWindowsExporter()) | |||
| { | |||
| name = getDisplayNameWindows(); | |||
| targetLocationValue.setDefault (getDefaultBuildsRootFolder() + getTargetFolderNameWindows()); | |||
| @@ -92,7 +92,7 @@ public: | |||
| bool isAndroidStudio() const override { return false; } | |||
| bool isAndroid() const override { return false; } | |||
| bool isWindows() const override { return os == windowsTarget; } | |||
| bool isWindows() const override { return isWindowsExporter(); } | |||
| bool isLinux() const override { return os == linuxTarget; } | |||
| bool isOSX() const override { return false; } | |||
| bool isiOS() const override { return false; } | |||
| @@ -195,6 +195,7 @@ public: | |||
| private: | |||
| ValueTreePropertyWithDefault targetPlatformValue; | |||
| bool isWindowsExporter() const { return os == windowsTarget; } | |||
| String getTargetPlatformString() const { return targetPlatformValue.get(); } | |||
| //============================================================================== | |||
| @@ -1918,8 +1918,8 @@ public: | |||
| { | |||
| name = getDisplayName(); | |||
| targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); | |||
| platformToolsetValue.setDefault (getDefaultToolset()); | |||
| targetPlatformVersion.setDefault (defaultTargetPlatform); | |||
| platformToolsetValue.setDefault (defaultToolset); | |||
| } | |||
| static String getDisplayName() { return "Visual Studio 2017"; } | |||
| @@ -1931,8 +1931,8 @@ public: | |||
| int getVisualStudioVersion() const override { return 15; } | |||
| String getSolutionComment() const override { return "# Visual Studio 15"; } | |||
| String getToolsVersion() const override { return "15.0"; } | |||
| String getDefaultToolset() const override { return "v141"; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return "Latest"; } | |||
| String getDefaultToolset() const override { return defaultToolset; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return defaultTargetPlatform; } | |||
| static MSVCProjectExporterVC2017* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) | |||
| { | |||
| @@ -1948,6 +1948,9 @@ public: | |||
| MSVCProjectExporterBase::createExporterProperties (props); | |||
| } | |||
| private: | |||
| const String defaultToolset { "v141" }, defaultTargetPlatform { "Latest" }; | |||
| JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2017) | |||
| }; | |||
| @@ -1960,8 +1963,8 @@ public: | |||
| { | |||
| name = getDisplayName(); | |||
| targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); | |||
| platformToolsetValue.setDefault (getDefaultToolset()); | |||
| targetPlatformVersion.setDefault (defaultTargetPlatform); | |||
| platformToolsetValue.setDefault (defaultToolset); | |||
| } | |||
| static String getDisplayName() { return "Visual Studio 2019"; } | |||
| @@ -1973,8 +1976,8 @@ public: | |||
| int getVisualStudioVersion() const override { return 16; } | |||
| String getSolutionComment() const override { return "# Visual Studio Version 16"; } | |||
| String getToolsVersion() const override { return "16.0"; } | |||
| String getDefaultToolset() const override { return "v142"; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return "10.0"; } | |||
| String getDefaultToolset() const override { return defaultToolset; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return defaultTargetPlatform; } | |||
| static MSVCProjectExporterVC2019* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) | |||
| { | |||
| @@ -1990,6 +1993,9 @@ public: | |||
| MSVCProjectExporterBase::createExporterProperties (props); | |||
| } | |||
| private: | |||
| const String defaultToolset { "v142" }, defaultTargetPlatform { "10.0" }; | |||
| JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2019) | |||
| }; | |||
| @@ -2002,8 +2008,8 @@ public: | |||
| { | |||
| name = getDisplayName(); | |||
| targetPlatformVersion.setDefault (getDefaultWindowsTargetPlatformVersion()); | |||
| platformToolsetValue.setDefault (getDefaultToolset()); | |||
| targetPlatformVersion.setDefault (defaultTargetPlatform); | |||
| platformToolsetValue.setDefault (defaultToolset); | |||
| } | |||
| static String getDisplayName() { return "Visual Studio 2022"; } | |||
| @@ -2015,8 +2021,8 @@ public: | |||
| int getVisualStudioVersion() const override { return 17; } | |||
| String getSolutionComment() const override { return "# Visual Studio Version 17"; } | |||
| String getToolsVersion() const override { return "17.0"; } | |||
| String getDefaultToolset() const override { return "v143"; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return "10.0"; } | |||
| String getDefaultToolset() const override { return defaultToolset; } | |||
| String getDefaultWindowsTargetPlatformVersion() const override { return defaultTargetPlatform; } | |||
| static MSVCProjectExporterVC2022* createForSettings (Project& projectToUse, const ValueTree& settingsToUse) | |||
| { | |||
| @@ -2032,5 +2038,8 @@ public: | |||
| MSVCProjectExporterBase::createExporterProperties (props); | |||
| } | |||
| private: | |||
| const String defaultToolset { "v143" }, defaultTargetPlatform { "10.0" }; | |||
| JUCE_DECLARE_NON_COPYABLE (MSVCProjectExporterVC2022) | |||
| }; | |||
| @@ -114,7 +114,7 @@ private: | |||
| browseButton.onClick = [this] { browse(); }; | |||
| addAndMakeVisible (browseButton); | |||
| lookAndFeelChanged(); | |||
| updateLookAndFeel(); | |||
| } | |||
| void setTo (File f) | |||
| @@ -187,7 +187,7 @@ private: | |||
| } | |||
| } | |||
| void lookAndFeelChanged() override | |||
| void updateLookAndFeel() | |||
| { | |||
| browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId)); | |||
| browseButton.setColour (TextButton::textColourOffId, Colours::white); | |||
| @@ -195,6 +195,11 @@ private: | |||
| updateEditorColour(); | |||
| } | |||
| void lookAndFeelChanged() override | |||
| { | |||
| updateLookAndFeel(); | |||
| } | |||
| //============================================================================== | |||
| Value textValue; | |||
| @@ -232,18 +237,23 @@ public: | |||
| value (valueToListenTo.getPropertyAsValue()) | |||
| { | |||
| value.addListener (this); | |||
| valueChanged (value); | |||
| handleValueChanged (value); | |||
| } | |||
| ~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); } | |||
| private: | |||
| void valueChanged (Value& v) override | |||
| void handleValueChanged (Value& v) | |||
| { | |||
| FilePathPropertyComponent::valueChanged (v); | |||
| setEnabled (propertyWithDefault.get()); | |||
| } | |||
| void valueChanged (Value& v) override | |||
| { | |||
| handleValueChanged (v); | |||
| } | |||
| ValueTreePropertyWithDefault propertyWithDefault; | |||
| Value value; | |||
| }; | |||
| @@ -68,7 +68,7 @@ public: | |||
| value (valueToListenTo.getPropertyAsValue()) | |||
| { | |||
| value.addListener (this); | |||
| valueChanged (value); | |||
| handleValueChanged(); | |||
| } | |||
| ChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl, | |||
| @@ -84,7 +84,7 @@ public: | |||
| isMultiChoice = true; | |||
| idToCheck = multiChoiceID; | |||
| valueChanged (value); | |||
| handleValueChanged(); | |||
| } | |||
| ChoicePropertyComponentWithEnablement (const ValueTreePropertyWithDefault& valueToControl, | |||
| @@ -95,7 +95,7 @@ public: | |||
| value (valueToListenTo.getPropertyAsValue()) | |||
| { | |||
| value.addListener (this); | |||
| valueChanged (value); | |||
| handleValueChanged(); | |||
| } | |||
| ~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); } | |||
| @@ -120,13 +120,18 @@ private: | |||
| return false; | |||
| } | |||
| void valueChanged (Value&) override | |||
| void handleValueChanged() | |||
| { | |||
| if (isMultiChoice) | |||
| setEnabled (checkMultiChoiceVar()); | |||
| else | |||
| setEnabled (propertyWithDefault.get()); | |||
| } | |||
| void valueChanged (Value&) override | |||
| { | |||
| handleValueChanged(); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| @@ -55,7 +55,7 @@ int main (int argc, char **argv) | |||
| if (args.containsOption ("--help|-h")) | |||
| { | |||
| std::cout << argv[0] << " [--help|-h] [--list-categories] [--category category] [--seed seed]" << std::endl; | |||
| std::cout << argv[0] << " [--help|-h] [--list-categories] [--category=category] [--seed=seed]" << std::endl; | |||
| return 0; | |||
| } | |||
| @@ -136,6 +136,7 @@ public: | |||
| for (int i = 0; i < numSamples; ++i) | |||
| { | |||
| // NOLINTNEXTLINE(clang-analyzer-core.NullDereference) | |||
| const float input = (left[i] + right[i]) * gain; | |||
| float outL = 0, outR = 0; | |||
| @@ -642,18 +642,18 @@ struct iOSAudioIODevice::Pimpl : public AsyncUpdater | |||
| Boolean hostIsCycling = NO; | |||
| Float64 hostCycleStartBeat = 0; | |||
| Float64 hostCycleEndBeat = 0; | |||
| OSStatus err = callbackInfo.transportStateProc2 (callbackInfo.hostUserData, | |||
| &hostIsPlaying, | |||
| &hostIsRecording, | |||
| nullptr, | |||
| &hostCurrentSampleInTimeLine, | |||
| &hostIsCycling, | |||
| &hostCycleStartBeat, | |||
| &hostCycleEndBeat); | |||
| if (err == kAUGraphErr_CannotDoInCurrentContext) | |||
| auto transportErr = callbackInfo.transportStateProc2 (callbackInfo.hostUserData, | |||
| &hostIsPlaying, | |||
| &hostIsRecording, | |||
| nullptr, | |||
| &hostCurrentSampleInTimeLine, | |||
| &hostIsCycling, | |||
| &hostCycleStartBeat, | |||
| &hostCycleEndBeat); | |||
| if (transportErr == kAUGraphErr_CannotDoInCurrentContext) | |||
| return {}; | |||
| jassert (err == noErr); | |||
| jassert (transportErr == noErr); | |||
| PositionInfo result; | |||
| @@ -666,10 +666,10 @@ struct iOSAudioIODevice::Pimpl : public AsyncUpdater | |||
| Float64 hostBeat = 0; | |||
| Float64 hostTempo = 0; | |||
| err = callbackInfo.beatAndTempoProc (callbackInfo.hostUserData, | |||
| &hostBeat, | |||
| &hostTempo); | |||
| jassert (err == noErr); | |||
| [[maybe_unused]] auto batErr = callbackInfo.beatAndTempoProc (callbackInfo.hostUserData, | |||
| &hostBeat, | |||
| &hostTempo); | |||
| jassert (batErr == noErr); | |||
| result.setPpqPosition (hostBeat); | |||
| result.setBpm (hostTempo); | |||
| @@ -677,12 +677,12 @@ struct iOSAudioIODevice::Pimpl : public AsyncUpdater | |||
| Float32 hostTimeSigNumerator = 0; | |||
| UInt32 hostTimeSigDenominator = 0; | |||
| Float64 hostCurrentMeasureDownBeat = 0; | |||
| err = callbackInfo.musicalTimeLocationProc (callbackInfo.hostUserData, | |||
| nullptr, | |||
| &hostTimeSigNumerator, | |||
| &hostTimeSigDenominator, | |||
| &hostCurrentMeasureDownBeat); | |||
| jassert (err == noErr); | |||
| [[maybe_unused]] auto timeErr = callbackInfo.musicalTimeLocationProc (callbackInfo.hostUserData, | |||
| nullptr, | |||
| &hostTimeSigNumerator, | |||
| &hostTimeSigDenominator, | |||
| &hostCurrentMeasureDownBeat); | |||
| jassert (timeErr == noErr); | |||
| result.setPpqPositionOfLastBarStart (hostCurrentMeasureDownBeat); | |||
| result.setTimeSignature (TimeSignature { (int) hostTimeSigNumerator, (int) hostTimeSigDenominator }); | |||
| @@ -346,8 +346,8 @@ public: | |||
| if (client != nullptr) | |||
| { | |||
| const auto result = juce::jack_deactivate (client); | |||
| jassertquiet (result == 0); | |||
| [[maybe_unused]] const auto result = juce::jack_deactivate (client); | |||
| jassert (result == 0); | |||
| juce::jack_set_xrun_callback (client, xrunCallback, nullptr); | |||
| juce::jack_set_process_callback (client, processCallback, nullptr); | |||
| @@ -544,9 +544,9 @@ private: | |||
| } | |||
| } | |||
| static void infoShutdownCallback (jack_status_t code, [[maybe_unused]] const char* reason, void* arg) | |||
| static void infoShutdownCallback ([[maybe_unused]] jack_status_t code, [[maybe_unused]] const char* reason, void* arg) | |||
| { | |||
| jassertquiet (code == 0); | |||
| jassert (code == 0); | |||
| JUCE_JACK_LOG ("Shutting down with message:"); | |||
| JUCE_JACK_LOG (reason); | |||
| @@ -0,0 +1,3 @@ | |||
| # We want to ignore this directory, but we need to enable at least a single | |||
| # check to avoid an error | |||
| Checks: -*,darwin-dispatch-once-nonstatic | |||
| @@ -74,19 +74,19 @@ void ARAAudioSourceReader::willUpdateAudioSourceProperties (ARAAudioSource* audi | |||
| } | |||
| } | |||
| void ARAAudioSourceReader::doUpdateAudioSourceContent (ARAAudioSource* audioSource, | |||
| void ARAAudioSourceReader::doUpdateAudioSourceContent ([[maybe_unused]] ARAAudioSource* audioSource, | |||
| ARAContentUpdateScopes scopeFlags) | |||
| { | |||
| jassertquiet (audioSourceBeingRead == audioSource); | |||
| jassert (audioSourceBeingRead == audioSource); | |||
| // Don't invalidate if the audio signal is unchanged | |||
| if (scopeFlags.affectSamples()) | |||
| invalidate(); | |||
| } | |||
| void ARAAudioSourceReader::willEnableAudioSourceSamplesAccess (ARAAudioSource* audioSource, bool enable) | |||
| void ARAAudioSourceReader::willEnableAudioSourceSamplesAccess ([[maybe_unused]] ARAAudioSource* audioSource, bool enable) | |||
| { | |||
| jassertquiet (audioSourceBeingRead == audioSource); | |||
| jassert (audioSourceBeingRead == audioSource); | |||
| // Invalidate our reader if sample access is disabled | |||
| if (! enable) | |||
| @@ -96,9 +96,9 @@ void ARAAudioSourceReader::willEnableAudioSourceSamplesAccess (ARAAudioSource* a | |||
| } | |||
| } | |||
| void ARAAudioSourceReader::didEnableAudioSourceSamplesAccess (ARAAudioSource* audioSource, bool enable) | |||
| void ARAAudioSourceReader::didEnableAudioSourceSamplesAccess ([[maybe_unused]] ARAAudioSource* audioSource, bool enable) | |||
| { | |||
| jassertquiet (audioSourceBeingRead == audioSource); | |||
| jassert (audioSourceBeingRead == audioSource); | |||
| // Recreate our reader if sample access is enabled | |||
| if (enable && isValid()) | |||
| @@ -108,9 +108,9 @@ void ARAAudioSourceReader::didEnableAudioSourceSamplesAccess (ARAAudioSource* au | |||
| } | |||
| } | |||
| void ARAAudioSourceReader::willDestroyAudioSource (ARAAudioSource* audioSource) | |||
| void ARAAudioSourceReader::willDestroyAudioSource ([[maybe_unused]] ARAAudioSource* audioSource) | |||
| { | |||
| jassertquiet (audioSourceBeingRead == audioSource); | |||
| jassert (audioSourceBeingRead == audioSource); | |||
| invalidate(); | |||
| } | |||
| @@ -290,19 +290,19 @@ void ARAPlaybackRegionReader::willUpdatePlaybackRegionProperties (ARAPlaybackReg | |||
| } | |||
| } | |||
| void ARAPlaybackRegionReader::didUpdatePlaybackRegionContent (ARAPlaybackRegion* playbackRegion, | |||
| void ARAPlaybackRegionReader::didUpdatePlaybackRegionContent ([[maybe_unused]] ARAPlaybackRegion* playbackRegion, | |||
| ARAContentUpdateScopes scopeFlags) | |||
| { | |||
| jassertquiet (ARA::contains (playbackRenderer->getPlaybackRegions(), playbackRegion)); | |||
| jassert (ARA::contains (playbackRenderer->getPlaybackRegions(), playbackRegion)); | |||
| // Invalidate if the audio signal is changed | |||
| if (scopeFlags.affectSamples()) | |||
| invalidate(); | |||
| } | |||
| void ARAPlaybackRegionReader::willDestroyPlaybackRegion (ARAPlaybackRegion* playbackRegion) | |||
| void ARAPlaybackRegionReader::willDestroyPlaybackRegion ([[maybe_unused]] ARAPlaybackRegion* playbackRegion) | |||
| { | |||
| jassertquiet (ARA::contains (playbackRenderer->getPlaybackRegions(), playbackRegion)); | |||
| jassert (ARA::contains (playbackRenderer->getPlaybackRegions(), playbackRegion)); | |||
| invalidate(); | |||
| } | |||
| @@ -85,7 +85,7 @@ public: | |||
| shouldMuteInput.addListener (this); | |||
| shouldMuteInput = ! isInterAppAudioConnected(); | |||
| createPlugin(); | |||
| handleCreatePlugin(); | |||
| auto inChannels = (channelConfiguration.size() > 0 ? channelConfiguration[0].numIns | |||
| : processor->getMainBusNumInputChannels()); | |||
| @@ -117,24 +117,19 @@ public: | |||
| { | |||
| stopTimer(); | |||
| deletePlugin(); | |||
| handleDeletePlugin(); | |||
| shutDownAudioDevices(); | |||
| } | |||
| //============================================================================== | |||
| virtual void createPlugin() | |||
| { | |||
| processor = createPluginFilterOfType (AudioProcessor::wrapperType_Standalone); | |||
| processor->disableNonMainBuses(); | |||
| processor->setRateAndBufferSizeDetails (44100, 512); | |||
| processorHasPotentialFeedbackLoop = (getNumInputChannels() > 0 && getNumOutputChannels() > 0); | |||
| handleCreatePlugin(); | |||
| } | |||
| virtual void deletePlugin() | |||
| { | |||
| stopPlaying(); | |||
| processor = nullptr; | |||
| handleDeletePlugin(); | |||
| } | |||
| int getNumInputChannels() const | |||
| @@ -428,6 +423,23 @@ public: | |||
| ScopedMessageBox messageBox; | |||
| private: | |||
| //============================================================================== | |||
| void handleCreatePlugin() | |||
| { | |||
| processor = createPluginFilterOfType (AudioProcessor::wrapperType_Standalone); | |||
| processor->disableNonMainBuses(); | |||
| processor->setRateAndBufferSizeDetails (44100, 512); | |||
| processorHasPotentialFeedbackLoop = (getNumInputChannels() > 0 && getNumOutputChannels() > 0); | |||
| } | |||
| void handleDeletePlugin() | |||
| { | |||
| stopPlaying(); | |||
| processor = nullptr; | |||
| } | |||
| //============================================================================== | |||
| /* This class can be used to ensure that audio callbacks use buffers with a | |||
| predictable maximum size. | |||
| @@ -457,14 +469,14 @@ private: | |||
| } | |||
| void audioDeviceIOCallbackWithContext (const float* const* inputChannelData, | |||
| int numInputChannels, | |||
| [[maybe_unused]] int numInputChannels, | |||
| float* const* outputChannelData, | |||
| int numOutputChannels, | |||
| [[maybe_unused]] int numOutputChannels, | |||
| int numSamples, | |||
| const AudioIODeviceCallbackContext& context) override | |||
| { | |||
| jassertquiet ((int) storedInputChannels.size() == numInputChannels); | |||
| jassertquiet ((int) storedOutputChannels.size() == numOutputChannels); | |||
| jassert ((int) storedInputChannels.size() == numInputChannels); | |||
| jassert ((int) storedOutputChannels.size() == numOutputChannels); | |||
| int position = 0; | |||
| @@ -901,7 +913,7 @@ private: | |||
| if (editor != nullptr) | |||
| { | |||
| editor->addComponentListener (this); | |||
| componentMovedOrResized (*editor, false, true); | |||
| handleMovedOrResized(); | |||
| addAndMakeVisible (editor.get()); | |||
| } | |||
| @@ -929,20 +941,7 @@ private: | |||
| void resized() override | |||
| { | |||
| auto r = getLocalBounds(); | |||
| if (shouldShowNotification) | |||
| notification.setBounds (r.removeFromTop (NotificationArea::height)); | |||
| if (editor != nullptr) | |||
| { | |||
| const auto newPos = r.getTopLeft().toFloat().transformedBy (editor->getTransform().inverted()); | |||
| if (preventResizingEditor) | |||
| editor->setTopLeftPosition (newPos.roundToInt()); | |||
| else | |||
| editor->setBoundsConstrained (editor->getLocalArea (this, r.toFloat()).withPosition (newPos).toNearestInt()); | |||
| } | |||
| handleResized(); | |||
| } | |||
| ComponentBoundsConstrainer* getEditorConstrainer() const | |||
| @@ -1023,7 +1022,7 @@ private: | |||
| notification.setVisible (shouldShowNotification); | |||
| #if JUCE_IOS || JUCE_ANDROID | |||
| resized(); | |||
| handleResized(); | |||
| #else | |||
| if (editor != nullptr) | |||
| { | |||
| @@ -1045,7 +1044,25 @@ private: | |||
| } | |||
| //============================================================================== | |||
| void componentMovedOrResized (Component&, bool, bool) override | |||
| void handleResized() | |||
| { | |||
| auto r = getLocalBounds(); | |||
| if (shouldShowNotification) | |||
| notification.setBounds (r.removeFromTop (NotificationArea::height)); | |||
| if (editor != nullptr) | |||
| { | |||
| const auto newPos = r.getTopLeft().toFloat().transformedBy (editor->getTransform().inverted()); | |||
| if (preventResizingEditor) | |||
| editor->setTopLeftPosition (newPos.roundToInt()); | |||
| else | |||
| editor->setBoundsConstrained (editor->getLocalArea (this, r.toFloat()).withPosition (newPos).toNearestInt()); | |||
| } | |||
| } | |||
| void handleMovedOrResized() | |||
| { | |||
| const ScopedValueSetter<bool> scope (preventResizingEditor, true); | |||
| @@ -1058,6 +1075,11 @@ private: | |||
| } | |||
| } | |||
| void componentMovedOrResized (Component&, bool, bool) override | |||
| { | |||
| handleMovedOrResized(); | |||
| } | |||
| Rectangle<int> getSizeToContainEditor() const | |||
| { | |||
| if (editor != nullptr) | |||
| @@ -115,9 +115,9 @@ namespace AAXClasses | |||
| return result; | |||
| } | |||
| static void check (AAX_Result result) | |||
| static void check ([[maybe_unused]] AAX_Result result) | |||
| { | |||
| jassertquiet (result == AAX_SUCCESS); | |||
| jassert (result == AAX_SUCCESS); | |||
| } | |||
| // maps a channel index of an AAX format to an index of a juce format | |||
| @@ -1482,8 +1482,8 @@ namespace AAXClasses | |||
| AudioProcessor::BusesLayout& fullLayout) | |||
| { | |||
| auto currentLayout = getDefaultLayout (p, true); | |||
| bool success = p.checkBusesLayoutSupported (currentLayout); | |||
| jassertquiet (success); | |||
| [[maybe_unused]] bool success = p.checkBusesLayoutSupported (currentLayout); | |||
| jassert (success); | |||
| auto numInputBuses = p.getBusCount (true); | |||
| auto numOutputBuses = p.getBusCount (false); | |||
| @@ -1816,7 +1816,7 @@ namespace AAXClasses | |||
| bool getMainBusFormats (AudioChannelSet& inputSet, AudioChannelSet& outputSet) | |||
| { | |||
| auto& audioProcessor = getPluginInstance(); | |||
| [[maybe_unused]] auto& audioProcessor = getPluginInstance(); | |||
| #if JucePlugin_IsMidiEffect | |||
| // MIDI effect plug-ins do not support any audio channels | |||
| @@ -2419,8 +2419,8 @@ namespace AAXClasses | |||
| Array<int32>& pluginIds, | |||
| const int numMeters) | |||
| { | |||
| auto aaxInputFormat = getFormatForAudioChannelSet (fullLayout.getMainInputChannelSet(), false); | |||
| auto aaxOutputFormat = getFormatForAudioChannelSet (fullLayout.getMainOutputChannelSet(), false); | |||
| [[maybe_unused]] auto aaxInputFormat = getFormatForAudioChannelSet (fullLayout.getMainInputChannelSet(), false); | |||
| [[maybe_unused]] auto aaxOutputFormat = getFormatForAudioChannelSet (fullLayout.getMainOutputChannelSet(), false); | |||
| #if JucePlugin_IsSynth | |||
| if (aaxInputFormat == AAX_eStemFormat_None) | |||
| @@ -2589,8 +2589,8 @@ namespace AAXClasses | |||
| static void getPlugInDescription (AAX_IEffectDescriptor& descriptor, [[maybe_unused]] const AAX_IFeatureInfo* featureInfo) | |||
| { | |||
| auto plugin = createPluginFilterOfType (AudioProcessor::wrapperType_AAX); | |||
| auto numInputBuses = plugin->getBusCount (true); | |||
| auto numOutputBuses = plugin->getBusCount (false); | |||
| [[maybe_unused]] auto numInputBuses = plugin->getBusCount (true); | |||
| [[maybe_unused]] auto numOutputBuses = plugin->getBusCount (false); | |||
| auto pluginNames = plugin->getAlternateDisplayNames(); | |||
| @@ -1677,20 +1677,25 @@ public: | |||
| { | |||
| if (detail::PluginUtilities::getHostType().isAbletonLive()) | |||
| { | |||
| static NSTimeInterval lastEventTime = 0; // check we're not recursively sending the same event | |||
| NSTimeInterval eventTime = [[NSApp currentEvent] timestamp]; | |||
| NSEvent* currentEvent = [NSApp currentEvent]; | |||
| if (! approximatelyEqual (lastEventTime, eventTime)) | |||
| if (currentEvent != nil) | |||
| { | |||
| lastEventTime = eventTime; | |||
| static NSTimeInterval lastEventTime = 0; // check we're not recursively sending the same event | |||
| NSTimeInterval eventTime = [currentEvent timestamp]; | |||
| NSView* view = (NSView*) getWindowHandle(); | |||
| NSView* hostView = [view superview]; | |||
| NSWindow* hostWindow = [hostView window]; | |||
| if (! approximatelyEqual (lastEventTime, eventTime)) | |||
| { | |||
| lastEventTime = eventTime; | |||
| auto* view = (NSView*) getWindowHandle(); | |||
| auto* hostView = [view superview]; | |||
| auto* hostWindow = [hostView window]; | |||
| [hostWindow makeFirstResponder: hostView]; | |||
| [hostView keyDown: (NSEvent*) [NSApp currentEvent]]; | |||
| [hostWindow makeFirstResponder: view]; | |||
| [hostWindow makeFirstResponder: hostView]; | |||
| [hostView keyDown: currentEvent]; | |||
| [hostWindow makeFirstResponder: view]; | |||
| } | |||
| } | |||
| } | |||
| @@ -61,7 +61,7 @@ public: | |||
| { | |||
| PropertiesFile::Options options; | |||
| options.applicationName = getApplicationName(); | |||
| options.applicationName = appName; | |||
| options.filenameSuffix = ".settings"; | |||
| options.osxLibrarySubFolder = "Application Support"; | |||
| #if JUCE_LINUX || JUCE_BSD | |||
| @@ -73,7 +73,7 @@ public: | |||
| appProperties.setStorageParameters (options); | |||
| } | |||
| const String getApplicationName() override { return CharPointer_UTF8 (JucePlugin_Name); } | |||
| const String getApplicationName() override { return appName; } | |||
| const String getApplicationVersion() override { return JucePlugin_VersionString; } | |||
| bool moreThanOneInstanceAllowed() override { return true; } | |||
| void anotherInstanceStarted (const String&) override {} | |||
| @@ -140,6 +140,9 @@ public: | |||
| protected: | |||
| ApplicationProperties appProperties; | |||
| std::unique_ptr<StandaloneFilterWindow> mainWindow; | |||
| private: | |||
| const String appName { CharPointer_UTF8 (JucePlugin_Name) }; | |||
| }; | |||
| } // namespace juce | |||
| @@ -327,9 +327,9 @@ public: | |||
| #ifdef JucePlugin_PreferredChannelConfigurations | |||
| short configs[][2] = { JucePlugin_PreferredChannelConfigurations }; | |||
| const int numConfigs = sizeof (configs) / sizeof (short[2]); | |||
| [[maybe_unused]] const int numConfigs = sizeof (configs) / sizeof (short[2]); | |||
| jassertquiet (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0)); | |||
| jassert (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0)); | |||
| pluginInstance->setPlayConfigDetails (configs[0][0], configs[0][1], state->sampleRate, samplesPerBlock); | |||
| #else | |||
| @@ -1943,8 +1943,11 @@ private: | |||
| *pluginInput = cachedInArrangement. getData(); | |||
| *pluginOutput = cachedOutArrangement.getData(); | |||
| SpeakerMappings::channelSetToVstArrangement (processor->getChannelLayoutOfBus (true, 0), **pluginInput); | |||
| SpeakerMappings::channelSetToVstArrangement (processor->getChannelLayoutOfBus (false, 0), **pluginOutput); | |||
| if (*pluginInput != nullptr) | |||
| SpeakerMappings::channelSetToVstArrangement (processor->getChannelLayoutOfBus (true, 0), **pluginInput); | |||
| if (*pluginOutput != nullptr) | |||
| SpeakerMappings::channelSetToVstArrangement (processor->getChannelLayoutOfBus (false, 0), **pluginOutput); | |||
| return 1; | |||
| } | |||
| @@ -51,6 +51,7 @@ CPluginView::CPluginView (const ViewRect* _rect) | |||
| //------------------------------------------------------------------------ | |||
| CPluginView::~CPluginView () | |||
| { | |||
| // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.VirtualCall) | |||
| setFrame (nullptr); | |||
| } | |||
| @@ -1001,12 +1001,11 @@ public: | |||
| if (getElementCount (scope) != n && isBusCountWritable (isInput)) | |||
| { | |||
| OSStatus err; | |||
| auto newCount = static_cast<UInt32> (n); | |||
| layoutHasChanged = true; | |||
| err = AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ElementCount, scope, 0, &newCount, sizeof (newCount)); | |||
| jassertquiet (err == noErr); | |||
| [[maybe_unused]] auto err = AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ElementCount, scope, 0, &newCount, sizeof (newCount)); | |||
| jassert (err == noErr); | |||
| } | |||
| for (int i = 0; i < n; ++i) | |||
| @@ -739,10 +739,11 @@ public: | |||
| LV2_Log_Log* getLogFeature() { return &logFeature; } | |||
| private: | |||
| int vprintfCallback (LV2_URID type, const char* fmt, va_list ap) const | |||
| int vprintfCallback ([[maybe_unused]] LV2_URID type, const char* fmt, va_list ap) const | |||
| { | |||
| // If this is hit, the plugin has encountered some kind of error | |||
| jassertquiet (type != urids->mLV2_LOG__Error && type != urids->mLV2_LOG__Warning); | |||
| ignoreUnused (urids); | |||
| jassert (type != urids->mLV2_LOG__Error && type != urids->mLV2_LOG__Warning); | |||
| return std::vfprintf (stderr, fmt, ap); | |||
| } | |||
| @@ -2118,9 +2119,9 @@ public: | |||
| private: | |||
| template <typename Value> | |||
| static float getValueFrom (const void* data, uint32_t size) | |||
| static float getValueFrom (const void* data, [[maybe_unused]] uint32_t size) | |||
| { | |||
| jassertquiet (size == sizeof (Value)); | |||
| jassert (size == sizeof (Value)); | |||
| return (float) readUnaligned<Value> (data); | |||
| } | |||
| @@ -1166,6 +1166,8 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| // We have to trust that Steinberg won't double-delete | |||
| // NOLINTBEGIN(clang-analyzer-cplusplus.NewDelete) | |||
| template <class ObjectType> | |||
| class VSTComSmartPtr | |||
| { | |||
| @@ -1208,6 +1210,7 @@ public: | |||
| private: | |||
| ObjectType* source; | |||
| }; | |||
| // NOLINTEND(clang-analyzer-cplusplus.NewDelete) | |||
| //============================================================================== | |||
| /* This class stores a plugin's preferred MIDI mappings. | |||
| @@ -448,7 +448,7 @@ void AudioProcessor::checkForDuplicateTrimmedParamID ([[maybe_unused]] AudioProc | |||
| #if JUCE_DEBUG && ! JUCE_DISABLE_CAUTIOUS_PARAMETER_ID_CHECKING | |||
| if (auto* withID = dynamic_cast<HostedAudioProcessorParameter*> (param)) | |||
| { | |||
| constexpr auto maximumSafeAAXParameterIdLength = 31; | |||
| [[maybe_unused]] constexpr auto maximumSafeAAXParameterIdLength = 31; | |||
| const auto paramID = withID->getParameterID(); | |||
| @@ -459,7 +459,7 @@ void AudioProcessor::checkForDuplicateTrimmedParamID ([[maybe_unused]] AudioProc | |||
| // If you need to retain backwards-compatibility and are unable to change | |||
| // the paramID for this reason, you can add JUCE_DISABLE_CAUTIOUS_PARAMETER_ID_CHECKING | |||
| // to your preprocessor definitions to silence this assertion. | |||
| jassertquiet (paramID.length() <= maximumSafeAAXParameterIdLength); | |||
| jassert (paramID.length() <= maximumSafeAAXParameterIdLength); | |||
| // If you hit this assertion, two or more parameters have duplicate paramIDs | |||
| // after they have been truncated to support the AAX format. | |||
| @@ -470,7 +470,7 @@ void AudioProcessor::checkForDuplicateTrimmedParamID ([[maybe_unused]] AudioProc | |||
| // If you need to retain backwards-compatibility and are unable to change | |||
| // the paramID for this reason, you can add JUCE_DISABLE_CAUTIOUS_PARAMETER_ID_CHECKING | |||
| // to your preprocessor definitions to silence this assertion. | |||
| jassertquiet (trimmedParamIDs.insert (paramID.substring (0, maximumSafeAAXParameterIdLength)).second); | |||
| jassert (trimmedParamIDs.insert (paramID.substring (0, maximumSafeAAXParameterIdLength)).second); | |||
| } | |||
| #endif | |||
| } | |||
| @@ -567,14 +567,14 @@ private: | |||
| } | |||
| } | |||
| void checkSourceIsNotAMember (const ElementType& element) | |||
| void checkSourceIsNotAMember ([[maybe_unused]] const ElementType& element) | |||
| { | |||
| // when you pass a reference to an existing element into a method like add() which | |||
| // may need to reallocate the array to make more space, the incoming reference may | |||
| // be deleted indirectly during the reallocation operation! To work around this, | |||
| // make a local copy of the item you're trying to add (and maybe use std::move to | |||
| // move it into the add() method to avoid any extra overhead) | |||
| jassertquiet (std::addressof (element) < begin() || end() <= std::addressof (element)); | |||
| jassert (std::addressof (element) < begin() || end() <= std::addressof (element)); | |||
| } | |||
| //============================================================================== | |||
| @@ -134,8 +134,8 @@ public: | |||
| static constexpr auto vtableForCallable = detail::makeVtable<Fn, Ret, Args...>(); | |||
| vtable = &vtableForCallable; | |||
| auto* ptr = new (&storage) Fn (std::forward<Callable> (callable)); | |||
| jassertquiet ((void*) ptr == (void*) &storage); | |||
| [[maybe_unused]] auto* ptr = new (&storage) Fn (std::forward<Callable> (callable)); | |||
| jassert ((void*) ptr == (void*) &storage); | |||
| } | |||
| /** Move constructor. */ | |||
| @@ -162,6 +162,8 @@ BigInteger& BigInteger::operator= (const BigInteger& other) | |||
| return *this; | |||
| } | |||
| BigInteger::~BigInteger() = default; | |||
| uint32* BigInteger::getValues() const noexcept | |||
| { | |||
| jassert (heapAllocation != nullptr || allocatedSize <= numPreallocatedInts); | |||
| @@ -69,7 +69,7 @@ public: | |||
| BigInteger& operator= (BigInteger&&) noexcept; | |||
| /** Destructor. */ | |||
| ~BigInteger() = default; | |||
| ~BigInteger(); | |||
| //============================================================================== | |||
| /** Copies another BigInteger onto this one. */ | |||
| @@ -109,9 +109,8 @@ public: | |||
| */ | |||
| template <typename SizeType, std::enable_if_t<std::is_convertible_v<SizeType, int>, int> = 0> | |||
| explicit HeapBlock (SizeType numElements) | |||
| : data (static_cast<ElementType*> (std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType)))) | |||
| : data (mallocWrapper (static_cast<size_t> (numElements) * sizeof (ElementType))) | |||
| { | |||
| throwOnAllocationFailure(); | |||
| } | |||
| /** Creates a HeapBlock containing a number of elements. | |||
| @@ -121,11 +120,9 @@ public: | |||
| */ | |||
| template <typename SizeType, std::enable_if_t<std::is_convertible_v<SizeType, int>, int> = 0> | |||
| HeapBlock (SizeType numElements, bool initialiseToZero) | |||
| : data (static_cast<ElementType*> (initialiseToZero | |||
| ? std::calloc (static_cast<size_t> (numElements), sizeof (ElementType)) | |||
| : std::malloc (static_cast<size_t> (numElements) * sizeof (ElementType)))) | |||
| : data (initialiseToZero ? callocWrapper (static_cast<size_t> (numElements), sizeof (ElementType)) | |||
| : mallocWrapper (static_cast<size_t> (numElements) * sizeof (ElementType))) | |||
| { | |||
| throwOnAllocationFailure(); | |||
| } | |||
| /** Destructor. | |||
| @@ -252,8 +249,7 @@ public: | |||
| void malloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType)) | |||
| { | |||
| std::free (data); | |||
| data = static_cast<ElementType*> (std::malloc (static_cast<size_t> (newNumElements) * elementSize)); | |||
| throwOnAllocationFailure(); | |||
| data = mallocWrapper (static_cast<size_t> (newNumElements) * elementSize); | |||
| } | |||
| /** Allocates a specified amount of memory and clears it. | |||
| @@ -263,8 +259,7 @@ public: | |||
| void calloc (SizeType newNumElements, const size_t elementSize = sizeof (ElementType)) | |||
| { | |||
| std::free (data); | |||
| data = static_cast<ElementType*> (std::calloc (static_cast<size_t> (newNumElements), elementSize)); | |||
| throwOnAllocationFailure(); | |||
| data = callocWrapper (static_cast<size_t> (newNumElements), elementSize); | |||
| } | |||
| /** Allocates a specified amount of memory and optionally clears it. | |||
| @@ -275,10 +270,8 @@ public: | |||
| void allocate (SizeType newNumElements, bool initialiseToZero) | |||
| { | |||
| std::free (data); | |||
| data = static_cast<ElementType*> (initialiseToZero | |||
| ? std::calloc (static_cast<size_t> (newNumElements), sizeof (ElementType)) | |||
| : std::malloc (static_cast<size_t> (newNumElements) * sizeof (ElementType))); | |||
| throwOnAllocationFailure(); | |||
| data = initialiseToZero ? callocWrapper (static_cast<size_t> (newNumElements), sizeof (ElementType)) | |||
| : mallocWrapper (static_cast<size_t> (newNumElements) * sizeof (ElementType)); | |||
| } | |||
| /** Re-allocates a specified amount of memory. | |||
| @@ -289,9 +282,7 @@ public: | |||
| template <typename SizeType> | |||
| void realloc (SizeType newNumElements, size_t elementSize = sizeof (ElementType)) | |||
| { | |||
| data = static_cast<ElementType*> (data == nullptr ? std::malloc (static_cast<size_t> (newNumElements) * elementSize) | |||
| : std::realloc (data, static_cast<size_t> (newNumElements) * elementSize)); | |||
| throwOnAllocationFailure(); | |||
| data = reallocWrapper (data, static_cast<size_t> (newNumElements) * elementSize); | |||
| } | |||
| /** Frees any currently-allocated data. | |||
| @@ -327,20 +318,46 @@ public: | |||
| private: | |||
| //============================================================================== | |||
| ElementType* data = nullptr; | |||
| void throwOnAllocationFailure() const | |||
| // Calls to malloc, calloc and realloc with zero size have implementation-defined | |||
| // behaviour where either nullptr or a non-null pointer is returned. | |||
| template <typename Functor> | |||
| static ElementType* wrapper (size_t size, Functor&& f) | |||
| { | |||
| if (size == 0) | |||
| return nullptr; | |||
| auto* memory = static_cast<ElementType*> (f()); | |||
| #if JUCE_EXCEPTIONS_DISABLED | |||
| jassert (data != nullptr); // without exceptions, you'll need to find a better way to handle this failure case. | |||
| jassert (memory != nullptr); // without exceptions, you'll need to find a better way to handle this failure case. | |||
| #else | |||
| HeapBlockHelper::ThrowOnFail<throwOnFailure>::checkPointer (data); | |||
| HeapBlockHelper::ThrowOnFail<throwOnFailure>::checkPointer (memory); | |||
| #endif | |||
| return memory; | |||
| } | |||
| static ElementType* mallocWrapper (size_t size) | |||
| { | |||
| return wrapper (size, [size] { return std::malloc (size); }); | |||
| } | |||
| static ElementType* callocWrapper (size_t num, size_t size) | |||
| { | |||
| return wrapper (num * size, [num, size] { return std::calloc (num, size); }); | |||
| } | |||
| static ElementType* reallocWrapper (void* ptr, size_t newSize) | |||
| { | |||
| return wrapper (newSize, [ptr, newSize] { return std::realloc (ptr, newSize); }); | |||
| } | |||
| template <class OtherElementType, bool otherThrowOnFailure> | |||
| friend class HeapBlock; | |||
| //============================================================================== | |||
| ElementType* data = nullptr; | |||
| #if ! (defined (JUCE_DLL) || defined (JUCE_DLL_BUILD)) | |||
| JUCE_DECLARE_NON_COPYABLE (HeapBlock) | |||
| JUCE_PREVENT_HEAP_ALLOCATION // Creating a 'new HeapBlock' would be missing the point! | |||
| @@ -75,8 +75,6 @@ public: | |||
| beginTest ("operators work as expected"); | |||
| { | |||
| e = {}; | |||
| e = TestEnum::one; | |||
| expect ((e & TestEnum::one) != TestEnum{}); | |||
| e |= TestEnum::other; | |||
| @@ -46,17 +46,22 @@ inline String nsStringToJuce (NSString* s) | |||
| inline NSString* juceStringToNS (const String& s) | |||
| { | |||
| return [NSString stringWithUTF8String: s.toUTF8()]; | |||
| // This cast helps linters determine nullability | |||
| return (NSString* _Nonnull) [NSString stringWithUTF8String: s.toUTF8()]; | |||
| } | |||
| inline NSString* nsStringLiteral (const char* const s) noexcept | |||
| { | |||
| return [NSString stringWithUTF8String: s]; | |||
| jassert (s != nullptr); | |||
| // This cast helps linters determine nullability | |||
| return (NSString* _Nonnull) [NSString stringWithUTF8String: s]; | |||
| } | |||
| inline NSString* nsEmptyString() noexcept | |||
| { | |||
| return [NSString string]; | |||
| // This cast helps linters determine nullability | |||
| return (NSString* _Nonnull) [NSString string]; | |||
| } | |||
| inline NSURL* createNSURLFromFile (const String& f) | |||
| @@ -359,6 +364,8 @@ struct ObjCClass | |||
| ObjCClass (const char* nameRoot) | |||
| : cls (objc_allocateClassPair ([SuperclassType class], getRandomisedName (nameRoot).toUTF8(), 0)) | |||
| { | |||
| // The class could not be created. Is the name already in use? | |||
| jassert (cls != nil); | |||
| } | |||
| ~ObjCClass() | |||
| @@ -371,7 +378,8 @@ struct ObjCClass | |||
| void registerClass() | |||
| { | |||
| objc_registerClassPair (cls); | |||
| if (cls != nil) | |||
| objc_registerClassPair (cls); | |||
| } | |||
| SuperclassType* createInstance() const | |||
| @@ -393,8 +401,8 @@ struct ObjCClass | |||
| void addMethod (SEL selector, Result (*callbackFn) (id, SEL, Args...)) | |||
| { | |||
| const auto s = detail::makeCompileTimeStr (@encode (Result), @encode (id), @encode (SEL), @encode (Args)...); | |||
| const auto b = class_addMethod (cls, selector, (IMP) callbackFn, s.data()); | |||
| jassertquiet (b); | |||
| [[maybe_unused]] const auto b = class_addMethod (cls, selector, (IMP) callbackFn, s.data()); | |||
| jassert (b); | |||
| } | |||
| void addProtocol (Protocol* protocol) | |||
| @@ -163,9 +163,7 @@ namespace juce | |||
| /** Platform-independent assertion macro which suppresses ignored-variable | |||
| warnings in all build modes. You should probably use a plain jassert() | |||
| by default, and only replace it with jassertquiet() once you've | |||
| convinced yourself that any unused-variable warnings emitted by the | |||
| compiler are harmless. | |||
| and [[maybe_unused]] by default. | |||
| */ | |||
| #define jassertquiet(expression) JUCE_BLOCK_WITH_FORCED_SEMICOLON (if (! (expression)) jassertfalse;) | |||
| @@ -108,8 +108,8 @@ bool Base64::convertFromBase64 (OutputStream& binaryOutput, StringRef base64Text | |||
| String Base64::toBase64 (const void* sourceData, size_t sourceDataSize) | |||
| { | |||
| MemoryOutputStream m ((sourceDataSize * 4) / 3 + 3); | |||
| bool ok = convertToBase64 (m, sourceData, sourceDataSize); | |||
| jassertquiet (ok); // should always succeed for this simple case | |||
| [[maybe_unused]] bool ok = convertToBase64 (m, sourceData, sourceDataSize); | |||
| jassert (ok); // should always succeed for this simple case | |||
| return m.toString(); | |||
| } | |||
| @@ -76,11 +76,11 @@ namespace FIR | |||
| //============================================================================== | |||
| /** Prepare this filter for processing. */ | |||
| inline void prepare (const ProcessSpec& spec) noexcept | |||
| inline void prepare ([[maybe_unused]] const ProcessSpec& spec) noexcept | |||
| { | |||
| // This class can only process mono signals. Use the ProcessorDuplicator class | |||
| // to apply this filter on a multi-channel audio stream. | |||
| jassertquiet (spec.numChannels == 1); | |||
| jassert (spec.numChannels == 1); | |||
| reset(); | |||
| } | |||
| @@ -82,9 +82,9 @@ public: | |||
| const auto numInputChannels = inputBlock.getNumChannels(); | |||
| const auto numOutputChannels = outputBlock.getNumChannels(); | |||
| const auto numSamples = outputBlock.getNumSamples(); | |||
| [[maybe_unused]] const auto numSamples = outputBlock.getNumSamples(); | |||
| jassertquiet (inputBlock.getNumSamples() == numSamples); | |||
| jassert (inputBlock.getNumSamples() == numSamples); | |||
| if (numOutputChannels != 2 || numInputChannels == 0 || numInputChannels > 2) | |||
| return; | |||
| @@ -29,8 +29,8 @@ class InternalMessageQueue | |||
| public: | |||
| InternalMessageQueue() | |||
| { | |||
| auto err = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, msgpipe); | |||
| jassertquiet (err == 0); | |||
| [[maybe_unused]] auto err = ::socketpair (AF_LOCAL, SOCK_STREAM, 0, msgpipe); | |||
| jassert (err == 0); | |||
| LinuxEventLoop::registerFdCallback (getReadHandle(), | |||
| [this] (int fd) | |||
| @@ -134,10 +134,10 @@ namespace | |||
| #if JUCE_DEBUG | |||
| const int maxVal = 0x3fffffff; | |||
| jassertquiet ((int) x >= -maxVal && (int) x <= maxVal | |||
| && (int) y >= -maxVal && (int) y <= maxVal | |||
| && (int) w >= 0 && (int) w <= maxVal | |||
| && (int) h >= 0 && (int) h <= maxVal); | |||
| jassert ((int) x >= -maxVal && (int) x <= maxVal | |||
| && (int) y >= -maxVal && (int) y <= maxVal | |||
| && (int) w >= 0 && (int) w <= maxVal | |||
| && (int) h >= 0 && (int) h <= maxVal); | |||
| #endif | |||
| return { x, y, w, h }; | |||
| @@ -53,8 +53,8 @@ namespace | |||
| { | |||
| jassert (family != nullptr); | |||
| ComSmartPtr<IDWriteLocalizedStrings> familyNames; | |||
| auto hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress()); | |||
| jassertquiet (SUCCEEDED (hr)); | |||
| [[maybe_unused]] auto hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress()); | |||
| jassert (SUCCEEDED (hr)); | |||
| return getLocalisedName (familyNames); | |||
| } | |||
| @@ -62,8 +62,8 @@ namespace | |||
| { | |||
| jassert (font != nullptr); | |||
| ComSmartPtr<IDWriteLocalizedStrings> faceNames; | |||
| auto hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress()); | |||
| jassertquiet (SUCCEEDED (hr)); | |||
| [[maybe_unused]] auto hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress()); | |||
| jassert (SUCCEEDED (hr)); | |||
| return getLocalisedName (faceNames); | |||
| } | |||
| @@ -150,8 +150,12 @@ std::unique_ptr<ScopedContentSharerInterface> ScopedContentSharerInterface::shar | |||
| result.add (URL (tempFile)); | |||
| } | |||
| for (const auto& url : result) | |||
| jassertquiet (url.isLocalFile() && url.getLocalFile().existsAsFile()); | |||
| jassert (std::all_of (result.begin(), | |||
| result.end(), | |||
| [] (const auto& url) | |||
| { | |||
| return url.isLocalFile() && url.getLocalFile().existsAsFile(); | |||
| })); | |||
| return { std::move (result), String{} }; | |||
| } | |||
| @@ -246,9 +246,9 @@ struct SpVoiceWrapper : public DeletedAtShutdown | |||
| { | |||
| SpVoiceWrapper() | |||
| { | |||
| auto hr = voice.CoCreateInstance (ComTypes::CLSID_SpVoice); | |||
| [[maybe_unused]] auto hr = voice.CoCreateInstance (ComTypes::CLSID_SpVoice); | |||
| jassertquiet (SUCCEEDED (hr)); | |||
| jassert (SUCCEEDED (hr)); | |||
| } | |||
| ~SpVoiceWrapper() override | |||
| @@ -107,9 +107,9 @@ public: | |||
| link ([display = displayId] | |||
| { | |||
| CVDisplayLinkRef ptr = nullptr; | |||
| const auto result = CVDisplayLinkCreateWithCGDisplay (display, &ptr); | |||
| jassertquiet (result == kCVReturnSuccess); | |||
| jassertquiet (ptr != nullptr); | |||
| [[maybe_unused]] const auto result = CVDisplayLinkCreateWithCGDisplay (display, &ptr); | |||
| jassert (result == kCVReturnSuccess); | |||
| jassert (ptr != nullptr); | |||
| return ptr; | |||
| }()), | |||
| onCallback (std::move (onCallbackIn)) | |||
| @@ -125,11 +125,11 @@ public: | |||
| return kCVReturnSuccess; | |||
| }; | |||
| const auto callbackResult = CVDisplayLinkSetOutputCallback (link.get(), callback, this); | |||
| jassertquiet (callbackResult == kCVReturnSuccess); | |||
| [[maybe_unused]] const auto callbackResult = CVDisplayLinkSetOutputCallback (link.get(), callback, this); | |||
| jassert (callbackResult == kCVReturnSuccess); | |||
| const auto startResult = CVDisplayLinkStart (link.get()); | |||
| jassertquiet (startResult == kCVReturnSuccess); | |||
| [[maybe_unused]] const auto startResult = CVDisplayLinkStart (link.get()); | |||
| jassert (startResult == kCVReturnSuccess); | |||
| } | |||
| ~ScopedDisplayLink() noexcept | |||
| @@ -136,13 +136,13 @@ ChoicePropertyComponent::ChoicePropertyComponent (const String& name) | |||
| ChoicePropertyComponent::ChoicePropertyComponent (const String& name, | |||
| const StringArray& choiceList, | |||
| const Array<var>& correspondingValues) | |||
| [[maybe_unused]] const Array<var>& correspondingValues) | |||
| : PropertyComponent (name), | |||
| choices (choiceList) | |||
| { | |||
| // The array of corresponding values must contain one value for each of the items in | |||
| // the choices array! | |||
| jassertquiet (correspondingValues.size() == choices.size()); | |||
| jassert (correspondingValues.size() == choices.size()); | |||
| } | |||
| ChoicePropertyComponent::ChoicePropertyComponent (const Value& valueToControl, | |||
| @@ -209,12 +209,12 @@ int MultiChoicePropertyComponent::getTotalButtonsHeight (int numButtons) | |||
| MultiChoicePropertyComponent::MultiChoicePropertyComponent (const String& propertyName, | |||
| const StringArray& choices, | |||
| const Array<var>& correspondingValues) | |||
| [[maybe_unused]] const Array<var>& correspondingValues) | |||
| : PropertyComponent (propertyName, jmin (getTotalButtonsHeight (choices.size()), collapsedHeight)) | |||
| { | |||
| // The array of corresponding values must contain one value for each of the items in | |||
| // the choices array! | |||
| jassertquiet (choices.size() == correspondingValues.size()); | |||
| jassert (choices.size() == correspondingValues.size()); | |||
| for (auto choice : choices) | |||
| addAndMakeVisible (choiceButtons.add (new ToggleButton (choice))); | |||
| @@ -504,11 +504,11 @@ void Label::textEditorReturnKeyPressed (TextEditor& ed) | |||
| } | |||
| } | |||
| void Label::textEditorEscapeKeyPressed (TextEditor& ed) | |||
| void Label::textEditorEscapeKeyPressed ([[maybe_unused]] TextEditor& ed) | |||
| { | |||
| if (editor != nullptr) | |||
| { | |||
| jassertquiet (&ed == editor.get()); | |||
| jassert (&ed == editor.get()); | |||
| editor->setText (textValue.toString(), false); | |||
| hideEditor (true); | |||
| @@ -75,10 +75,10 @@ public: | |||
| const auto shouldUseES3 = version != defaultGLVersion | |||
| && [[UIDevice currentDevice].systemVersion floatValue] >= 7.0; | |||
| const auto gotContext = (shouldUseES3 && createContext (kEAGLRenderingAPIOpenGLES3, contextToShare)) | |||
| || createContext (kEAGLRenderingAPIOpenGLES2, contextToShare); | |||
| [[maybe_unused]] const auto gotContext = (shouldUseES3 && createContext (kEAGLRenderingAPIOpenGLES3, contextToShare)) | |||
| || createContext (kEAGLRenderingAPIOpenGLES2, contextToShare); | |||
| jassertquiet (gotContext); | |||
| jassert (gotContext); | |||
| if (context != nil) | |||
| { | |||
| @@ -634,7 +634,7 @@ public: | |||
| // The advantage of this callback is that it will catch *all* errors, even if we | |||
| // forget to check manually. | |||
| DBG ("OpenGL DBG message: " << message); | |||
| jassertquiet (type != GL_DEBUG_TYPE_ERROR && severity != GL_DEBUG_SEVERITY_HIGH); | |||
| jassert (type != GL_DEBUG_TYPE_ERROR && severity != GL_DEBUG_SEVERITY_HIGH); | |||
| }, nullptr); | |||
| } | |||
| #endif | |||
| @@ -52,19 +52,19 @@ struct CameraDevice::Pimpl | |||
| } | |||
| [AVCaptureDevice requestAccessForMediaType: AVMediaTypeVideo | |||
| completionHandler: ^(BOOL granted) | |||
| completionHandler: ^([[maybe_unused]] BOOL granted) | |||
| { | |||
| // Access to video is required for camera to work, | |||
| // black images will be produced otherwise! | |||
| jassertquiet (granted); | |||
| jassert (granted); | |||
| }]; | |||
| [AVCaptureDevice requestAccessForMediaType: AVMediaTypeAudio | |||
| completionHandler: ^(BOOL granted) | |||
| completionHandler: ^([[maybe_unused]] BOOL granted) | |||
| { | |||
| // Access to audio is required for camera to work, | |||
| // silence will be produced otherwise! | |||
| jassertquiet (granted); | |||
| jassert (granted); | |||
| }]; | |||
| captureSession.startSessionForDeviceWithId (cameraId); | |||
| @@ -379,7 +379,7 @@ private: | |||
| { | |||
| NSError* error = nil; | |||
| int successCount = 0; | |||
| [[maybe_unused]] int successCount = 0; | |||
| for (NSString* key : assetKeys.get()) | |||
| { | |||
| @@ -409,7 +409,7 @@ private: | |||
| } | |||
| } | |||
| jassertquiet (successCount == (int) [assetKeys.get() count]); | |||
| jassert (successCount == (int) [assetKeys.get() count]); | |||
| preparePlayerItem(); | |||
| } | |||