lalala
January 5, 2016, 10:32am
1
Is it wrong to setDefaultLookAndFeel with a SharedResourcePointer<LookAndFeel> ?
It seems to lead to some crash under certain circumstances.
Here is how to reproduce with a basic plugin :
- create a brand new plugin with the introjucer
- add 2 private members :
SharedResourcePointer<LookAndFeel_V3> lookAndFeel_V3;
ComboBox comboBox;
and then :
TestPlugAudioProcessorEditor::TestPlugAudioProcessorEditor (TestPlugAudioProcessor& p)
: AudioProcessorEditor (&p), processor (p)
{
LookAndFeel::setDefaultLookAndFeel (lookAndFeel_V3);
addAndMakeVisible (comboBox);
setSize (400, 300);
}
void TestPlugAudioProcessorEditor::resized()
{
comboBox.setBounds (30, 30, 200, 40);
}
- create a new reaper project
- create a new track
- insert the plugin
- click on the comboBox to open its menu
- open the track FX window by clicking on the green "FX" button
- double click on the plugin name that is on the right of that window (see attached pic)
-> crash
jules
January 5, 2016, 11:25am
2
Well, hard to tell exactly what you're doing, but it's probably unsafe because the SharedResourcePointer will delete its object when all the SharedResourcePointers go out of scope, and this would leave the dangling pointer selected as the global L+F..
lalala
January 5, 2016, 1:23pm
3
So what is the reco mmanded way to deal with defaultLookAndFeel and plugins?
Something like that ?
class MyLookAndFeel : public LookAndFeel_V3, public DeletedAtShutdown
{
public:
MyLookAndFeel() { }
~MyLookAndFeel()
{
clearSingletonInstance();
}
juce_DeclareSingleton (MyLookAndFeel, false)
};
juce_ImplementSingleton (MyLookAndFeel)
TestPlugAudioProcessorEditor::TestPlugAudioProcessorEditor (TestPlugAudioProcessor& p)
: AudioProcessorEditor (&p), processor (p)
{
LookAndFeel::setDefaultLookAndFeel (myLookAndFeel.getInstance());
addAndMakeVisible (comboBox);
setSize (400, 300);
}
jules
January 5, 2016, 2:07pm
4
A SharedResourcePointer is OK as long as you make sure that when it is deleted, you stop it being the look+feel.
This is C++ so you should use RAII to do this cleanly, e.g.
struct MyLookAndFeel
{
MyLookAndFeel() { LookAndFeel::setDefaultLookAndFeel (&lf); }
~MyLookAndFeel() { LookAndFeel::setDefaultLookAndFeel (nullptr); }
LookAndFeel_V3 lf;
};
then use SharedResourcePointer<MyLookAndFeel>
lalala
January 5, 2016, 2:26pm
5
of course! :) thanks Jules!