Where to call OnlineUnlockStatus::load() OnlineUnlockStatus::save()


#1

I was completing my integration of the Juce Tracktion Marketplace registration system for my plugins when I was stuck on where to call OnlineUnlockStatus::load() and OnlineUnlockStatus::save().

Putting "load" in the PluginAudioProcessor constructor seemed like a good start, but didn't quite work right.  And, placing "save" in the PluginEditor destructor didn't work right either.  I mean, suppose something happens (power failure, etc.) before the editor is closed?  Then, the save would never happen!

Jules was kind enough to offer me some guidance.  He suggested,

           "I'd put it in a Timer::timerCallback or AsyncUpdater that gets called after the plugin's constructor.And you'd save only if the                                   user actually unlocks it, so you'd do that e.g. when your unlocking dialog closes." 

I ended up creating an AsyncUpdater to handle both!  And it is all working perfectly.

This all may seem like a strange approach, but my goal was to use the OnlineUnlockStatus and OnlineUnlockForm classes as unchanged as possible.  I wanted to incorporate both classes as close to the original code as I could.  So, my implementation of OnlineUnlockStatus only defines the pure virtual functions.  And, I use the OnlineUnlockForm class straight up!

Because I was trying not to mess with the internal workings of the two classes, it made finding a place to call "save" tricky.  For my purposes, triggering the AsyncUpdater from the PluginEditor paint method works.  But!  You must create a flag to allow it!

What I did was to set a bool in the PluginEditor constructor that knows whether the plugin is Registered (this has to be separate from "isUnlocked"!).  Then, in the paint routine, I test whether Registered is true, then test "isUnlocked", and if so, I trigger the AsyncUpdater.  When you trigger the AsyncUpdater you MUST set Registered = true!  Otherwise, you'll have an edless loop running, and that is why you need both the Registered bool variable and "isUnlocked".


   if( ! Registered)
        if( PluginStatus.isUnlocked() )
        {
            Registered = true;
            regAsyncUpdater.triggerAsyncUpdate();
        }

The Registered bool also provides an efficient way for the paint routine to skip the whole thing in the vast majority of cases.

By the way, my AsyncUpdater does both the saving and the loading job.  It simply checks "isUnlocked" to see which one to call.  For example,

void RegAsyncUpdater::handleAsyncUpdate() override
{
    if( PluginStatus.isUnlocked() )
        PluginStatus.save();
    else
        PluginStatus.load();
}

 

And, of course, this approaoch is born of my desire to avoid changing the OnlineUnlockStatus and OnlineUnlockForm classes.  If you derive from OnlineUnlockForm, you can do more, I am sure.  And so, my approach, though functional, my be naive.

Lastly, it might also be possible to do much better if OnlineUnlockStatus::handleXmlReply and OnlineUnlockStatus::handleFailedConnection were "protected" instead of "private".  It seems to me that derived classes need to see those, and, access to them, allows a more direct way of implementing the "save".