Issue with handleAsyncUpdate: UI get refreshed only after user close and reopen plugin

Hi All,

 

I have an issue when loading preset in my personal plugin. Values are set correctly but UI do not refresh using the handleAsyncUpdate method after call of triggerAsyncUpdate method. UI is only correctly shown after user close and reopen plugin.

 

Is there any possible explanation or any example that demonstrate how juce force update of UI using asynchronous update ?

Thanks,

Well handleAsyncUpdate() gots called? You are self responsible to refresh your ui (for example calling repaint() or whatever it needs to update your UI controls)

handleAsyncUpdate is called and i tried to call repaint method using getActiveEditor without success.

UI is still not refreshing. I debugged the code and message seems to be correctly sent.

 

If repainting didn't work, no juce plugins would work at all! Must be something you're doing wrong, e.g. repainting the wrong component, blocking the message thread, etc., but impossible for us to guess what.

Is this with all hosts/OS/formats?

We experienced a problem in Pro Tools where the messaging didn’t work correctly if MessageManager stuff (timers, async updates, listener notifications etc.) is used before the GUI was created. Maybe something like this is happening here, too.

This could for example be the case if your AudioProcessor is derived from Timer and calls startTimer() in its constructor.

I may add that triggerAsyncUpdate and handleAsyncUpdate are called in a seperate thread. How can i notify principale thread that UI needs to be refreshed ?

GUI is already created and I'm not using a timer.

I try to load preset using a custom button in my GUI. Everything works as expected except UI is not refreshing with new values.

Audio processor Editor  is derived from juce::AudioProcessorEditor.

Basically here is what i use:

- Editor class derived from juce::AudioProcessorEditor and juce::Button::Listener

- Load button has a listener in this editor

- Processor class that implement createEditor()

- Engine class derived from juce::Thread and juce::AsyncUpdater.

- Engine class implement run method, handleAsyncUpdate method and execute method

- In run() method, I execute the treatment for load preset and then I call triggerAsyncUpdate

=> Params are updated but UI is not refreshing!

 

What Im doing wrong ?

 

Really not possible for us to know what's wrong with code that we can't see!

You probably need to debug deeper into things like your repaint call, to see what's going on.

And like ckk suggested, try it in some other hosts, just in case whatever host you're using is doing something weird.

I'm using Reaper as host.

When do you start the thread and has the editor been created when you call triggerAsyncUpdate()? If not, this could lead to what I described in my previous post.


void EngineBase::run()
    {
        if (mProcessor.hasEditor())
        {
            execute();
            triggerAsyncUpdate();
        }
    }

hasEditor retruns true and the trigger is executed.

hasEditor() only states whether the plugin supplies its own editor and will always return true for most plugins.

Try setting breakpoints in createEditor() and in run() and have a look which breakpoint gets reached first. If the one in run() is reached first, you are probably seeing the issue described in my first post.

We added the following assertion to startTimer(), triggerAsyncUpdate() and similar functions to catch this issue:

jassert(MessageManager::getInstanceWithoutCreating() != nullptr);

Maybe this should also be added to JUCE.

Really good idea about adding those assertions, thanks!

Thanks ckk for the feedback.

I tested the scenario that you mentioned and the createEditor() is called first. 

Actually, the editor is created and it contains a load preset button that will update parameters.

Nobody asked which host, we suggested that you try some other ones for comparison.

And you might want to try the juce demo host so you can debug the entire system.