App->shutdown() and values

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

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?

juce_Application.cpp

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

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.

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

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.

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

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

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.

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