App->shutdown() and values


#1

Is the Message loop stopped by the time this method runs? I have a window I want to remove by triggering a value, and I can see the value get triggered right up to posting a message, but the value changed callback doesn’t fire.

Is there a standard shutdown option while the message loop is still running in that case?

Bruce


#2

I believe shutdown is called after the message loop exits.

You say that you are triggering a Value object? I thought this used juce::ListenerList? Or are you relying on an AsyncUpdater?


#3

juce_Application.cpp

int JUCEApplication::main()
{
...
    JUCE_TRY
    {
        // loop until a quit message is received..
        MessageManager::getInstance()->runDispatchLoop();
    }
    JUCE_CATCH_EXCEPTION
...
    return app->shutdownApp();
}

#4

You could try the trick I use in the introjucer: if you try to quit while there’s a modal component open, it tells the modal comp to close, then cancels the quit operation, but triggers a timer that will attempt to quit again after a short pause.


#5

Right, right. My problem is that it’s not modal, it’s a global utility window. I’m trying not to make my app class a malevolent spider controlling everything in the app, so I’m trying to have the window’s owner listen to a value to show and hide it.

Works great until shut down time, where it’s detected as a leak.

Bruce


#6

This is why singletons and statics are best avoided. Nowadays I always try to make my app class own (either directly or indirectly) everything that the app uses, so that it’s all guaranteed to go down with the ship.


#7

Well, it’s a window owned by a Logger, and that hasn’t joined the new century, afaict. Making the app own the window, and then the logger having to know about the app, seems a bit messy.

I was trying to avoid the main app owning everything, it seems to always turn that class into a mess, but I’ll look again.

Bruce


#8

You never answered this question. Because ListenerList doesn’t depend on the message pump being run (i.e. it works even in shutdown()).


#9

The default SimpleValueSource that just wraps a var uses an AsyncUpdater internally which dispatches change messages asynchronously. Thats one of the reasons I use them and why they are good for things like slider drag changes. You could always create a syncronous custom ValueSource which would be quite simple:

[code]//==============================================================================
class SimpleSyncronousValueSource : public Value::ValueSource
{
public:
SimpleSyncronousValueSource()
{
}

SimpleSyncronousValueSource (const var& initialValue)
    : value (initialValue)
{
}

var getValue() const
{
    return value;
}

void setValue (const var& newValue)
{
    if (! newValue.equalsWithSameType (value))
    {
        value = newValue;
        sendChangeMessage (true); //xxx this is the only difference to the default
    }
}

private:
var value;

JUCE_DECLARE_NON_COPYABLE (SimpleSyncronousValueSource);

};
[/code]

You would then just use the Value constructor that takes a pointer to a Value::ValueSource and supply it with one of these. I haven’t tested this code yet but I think its sound.


#10

Yes Dave (Vinnie), that’s the situation.

That is a good fix, but it would mean I’ll two classes of ValueSource, and I’d worry about not having the ‘right type’ and messing up.

That is a great insight into ValueSources though - thanks! I will use that feature, for sure.

Bruce