Error Critical Section when Initializing ParameterAttachment

Hey, I am trying to make a custom component that have 2 value.
And I am trying to embed ParameterAttachment inside that component.
Are this is a good idea?
For some reason I cannot initialize ParameterAttachment.
The Critical Section error pop up everytime I run up the code
I need help for this problem.
Or maybe there are another good solution than my code.
Can someone give me solution.
I am looking up for custom parameter attachment thread, but there is no thread than explain the detail.

LFOGraphDot::LFOGraphDot(juce::UndoManager* undo, juce::RangedAudioParameter* x, juce::RangedAudioParameter* y) : 
    xParam(*x), 
    yParam(*y), 
    xAttach(xParam, [this](float) { repaint(); }, undo), << this is the problem
    yAttach(yParam, [this](float) { repaint(); }, undo)
{
    // In your constructor, you should add any child components, and
    // initialise any special settings that your component needs.
    xAttach.sendInitialUpdate();
    yAttach.sendInitialUpdate();
}

First of all: there is a great article on StackOverflow How do I ask a good question? - Help Center - Stack Overflow. Please take your time and read it so we get all the information we need from the start without having to ask for it. :slight_smile:

Second: please share your entire unit (header and implementation)

Third: I’m not entirely sure what your problem is, so I’m taking a shot in the dark right now, but here is how the parameter attachments in JUCE are designed.
The parameter attachments are basically a subclass for two listeners. One listener for the controller interaction from a user and one listener for the parameter in case the audio engine changes it (e.g. via midi automations) or, if its not an audio parameter, a different UI component or maybe a network connection etc. When you want to attach your control / component to a parameter of some sort, you create a new parameter attachment and provide the UI control and a reference to the parameter. I mostly see those parameter attachments stored in a unique pointer inside the parent component.

So imagine you have a box with four sliders, this class Box : juce::Component would have the following member variables: four jute::Slider and four std::unique_ptr<ParameterAttachment>. In the ctor you set up the sliders accordingly (maybe disable mouse wheel interaction etc.) and create the parameter attachments.

The parameter attachment should (in its ctor) take care of setting the UI control to the current value of the parameter (e.g. place the slider to the value 5 if that’s the value of the audio parameter). When setting the value for the UI component, make sure to pass dontSendNotification to prevent your attachment from triggering a change while just initially aligning the control.
Also make sure to unregister the listeners in the dtor to avoid dangling listener pointers. This way, when your Box goes out of scope and destroys the unique pointers, everything will be cleaned up nicely.

And last but not least: here is a parameter attachment I’ve written recently to attach a Slider control to a property of my SharedSoundSettings (the property being defined as a template parameter).

On a side note: the parameter attachment uses AsyncUpdater to suspend the control update (after the parameter changed by some other source) to the next iteration of the message thread loop. This was necessary in my case but nothing you should do if you don’t have to.

template <SoundProperty::Property property>
class SoundSettingSliderAttachment
  : private Slider::Listener,
    private SoundProperty::Listener<property>,
    private juce::AsyncUpdater
{
  public:
                        SoundSettingSliderAttachment(Slider& slider, const SharedSoundSettings& sound, UndoManager& undoManager);
                        ~SoundSettingSliderAttachment();
    
  private:
    void                sliderDragStarted(Slider*) override;
    void                sliderValueChanged(Slider*) override;
    
    void                propertyChanged() override;
    void                handleAsyncUpdate() override;
    
    
    Slider&             slider;
    SharedSoundSettings sound;
    UndoManager&        undoManager;
};


#define DECLARE_SoundSettingSliderAttachment(returntype)  \
  template <SoundProperty::Property property>             \
  returntype SoundSettingSliderAttachment<property>::

DECLARE_SoundSettingSliderAttachment() SoundSettingSliderAttachment(Slider& slider, const SharedSoundSettings& s, UndoManager& undo)
  : slider(slider),
    sound(s),
    undoManager(undo)
{
  slider.addListener(this);
  sound.addPropertyListener(*this);
  
  slider.setValue(sound.getProperty<property>(), dontSendNotification);
}


DECLARE_SoundSettingSliderAttachment(void) sliderDragStarted(Slider*)
{
  undoManager.beginNewTransaction();
}


DECLARE_SoundSettingSliderAttachment(void) sliderValueChanged(Slider*)
{
  sound.setProperty<property>(slider.getValue(), &undoManager);
}


DECLARE_SoundSettingSliderAttachment(void) propertyChanged()
{
  triggerAsyncUpdate();
}


DECLARE_SoundSettingSliderAttachment(void) handleAsyncUpdate()
{
  slider.setValue(sound.getProperty<property>(), dontSendNotification);
}


DECLARE_SoundSettingSliderAttachment() ~SoundSettingSliderAttachment() // TODO: Bring under test
{
  slider.removeListener(this);
}
1 Like

to answer your first question: yeah it’s totally a good idea to make custom component parameters sometimes :slight_smile: can be very useful and you learn a lot while doing so.

your initialization looks good to me. maybe just accidently have the wrong first arg type or so, cause i don’t know if it has to be a rap* or rap& from the top of my head

The initialisation syntax is not the problem. The problem is

1 Like

oh overread that… yeah very weird. why would it happen right in the initializer list already?

Also totally unsure on that :smiley:

Thank you for the reply!
This is my first time writing question like this on forum.
Actually, I already solved my problem.
That critical section error actually showed up because of me trying to access value tree parameter that doesn’t exist.
Anyway thank you for answering my question, and this thread already solved up.