Please don't remove SharedResourcePointer::getReferenceCount()

Hi, JUCE team.

We recently upgraded our JUCE version to v7.0.12 and now We get the following message at build time.

If you are relying on this function please inform the JUCE team as we are planing on removing this in a subsequent release

The plugin we are developing uses juce::SharedResourcePointer::getReferenceCount() to perform processing only when the last instance is destroyed if multiple plugins are running.

I’m reporting this because I don’t want it to be deleted.
Please consider the matter.

1 Like

Isn’t that what the destructor of whatever the shared resource is should do? If you have to check the counter manually to do something, it could hint at something odd in the design.

2 Likes

I agree… I need to call

juce::Logger::setCurrentLogger (nullptr);

only when the last instance is destroyed otherwise the other instances stop logging.

Rail

Could you move that call into the destructor of an object managed by a shared resource pointer?

Seems to me the fix would be making the juce::Logger a sharedResourcePtr instead of a static object.

Rail

Another use case:

I use getReferenceCount() to check if required resource already exists, and doesn’t need to be constructed, in a time-critical constructor, in a debugging context.

@reuk

You could use getSharedObjectWithoutCreating() and check the result to determine if the resource has already been created

Thanks, for the idea.

But the SharedResourcePointer is a member of that class, so it would be already guaranteed that shared object exits.

So I couldn’t do the check in the constructor, I had to do it before construction, which wouldn’t been so comfortable.

class RecycleFFT
    {
    public:
        RecycleFFT ()
        {
            // Please use RecycleFFT ReferenceHolder in the main class, to pre aquire FFT Resources
            jassert (recycler.getReferenceCount() > 1);
        }

    

I’m sorry, I re-read your post but I cannot understand what your (certainly valid, I’m not doubting that) use case is

The construction of this specific shared resource is a heavy task.

I want to ensure that when I create the object which is using the shared resource, the shared source has existed before. To do so it shows me a warning if not.

I can’t use getSharedObjectWithoutCreating in the constructor because then the object is already existing, because the shared resource pointer is a class member.

It seems what you want is a shared resource that only exists “optionally”. You could just wrap your expensive object in a std::optional or some custom wrapper, or initialize the object lazily (in some init() function instead of the constructor).

No, I want nothing I already have it :sweat_smile: It’s SharedResourcePointer::getReferenceCount().
And I think I perfectly described the use case, which differs from you description.

That’s all I did. I can live without that function, but I just followed this command in the JUCE source code.

Ah, I got it now, thanks.

Out of pure curiosity, I spent a minute thinking how I would have resolved the problem, if getReferenceCount() were removed, as if it were a little programming exercise.

What I came up with is this: in the class definition, just above the SharedResourcePointer member variable you already have, I would put another boolean member variable, like this:

using MySRP = juce::SharedResourcePointer <TheDesiredType>;  // abbreviation

const bool recyclerExistedBefore { MySRP::getSharedObjectWithoutCreating().has_value () };

MySRP recycler;    // The instance of SharedResourcePointer that was already in your class

Because recyclerExistedBefore would be initialized before the SharedResourcePointer recycler member, it captures whether the shared resource was already existing before your class construction possibly instantiates it.
Then, in the constrcutor body, you can do

// Please use RecycleFFT ReferenceHolder in the main class, to pre aquire FFT Resources
jassert (recyclerExistedBefore);
2 Likes

I think the bool if it was initialised belongs into the managed object.
So you can add the initialise() call whenever the data is accessed.

class MyObject
{
public:
    MyObject() = default;

    using Ptr = juce::SharedResourcePointer<MyObject>;

    auto& getSomething()
    {
        initialise();

        return initialisedStuff;
    }

private:
    bool initialised = false;

    void initialise()
    {
        if (initialised) return;

        doHeavyInitialisation();
        initialised = true;
    }
};

This way you can add a Ptr wherever you will need it without initialising;