What is the best way to share an object only within a plugin instance's fleet of objects?


#1

Hi JUCErs,

I apologize if the question is too plainly asked (I was shooting for clarity :slight_smile:).

So I don’t want to pass pointers around (in the UI for example I have some pretty deep cascades of Components and if I only need that object at the bottom, I still have to pass it through all of the parents), and I want to access something which is basically a singleton, but every plugin instance should have a separate one.

Is there such a tool in the JUCE framework that would allow sharing a plugin-instance-level singleton/shared pointer/reference etc.?

Cheers.


#2

No, that’s not possible - when you make a function call to get this “singleton”, how could it possibly know which one you want unless you tell it which instance you’re using?

What many people do is to just have one large object which contains pointers to all the things an instance may need, so that this is the only reference that all your objects need to share, and any new items you add get added to this container object, making them available everywhere.


#3

Thanks for the fast response, Jules.

This makes sense.

Exactly the problem I don’t know how to solve, but I wasn’t sure if there is some C++ feature I was missing that would allow the callee to somehow identify the source of the caller. Because if that was possible, there could be a State type with a static method
static State* State::getMyPluginInstanceLevelSingleton ()


#4

How could that possibly work!? (In any programming language!)


#5

I am not saying I have used such a feature in another programming language. I am saying that being relatively new to “THE language of all languages” that C++ seems to be, I can imagine it having many features I haven’t used before.


#6

Sure, I meant that I think it’d be impossible to implement that in any language!


#7

I think what you can do instead, is going up the hierarchy, until you reach the ProcessorEditor using Component::findParentComponentOfClass():

if (auto* editor = findParentComponentOfClass<AudioProcessorEditor>()) {
    editor->foo();

HTH


#8

I am glad I can freely share state between instances with no restrictions, so I wouldn’t cry about the lack of plugin sandboxing in hosts, but this would be one way.

And with dynamic languages… that is not a huge problem. Here is a JavaScript example - inside the closure, object a refers to object b directly and it is a different object for each closure.

function createClosure (b) {
    return (function (b) {
        var a = {
           test: function (){ console.log (b); }
        };
        return a;
    }) (b);
}

var a1 = createClosure ("a1");
var a2 = createClosure ("a2");

a1.test (); // prints "a1"
a2.test (); // prints "a2"

And this isn’t a complete sandboxing so you would still be able to refer to other common globals.


#9

This is an option. Thanks daniel.

The only issue I see is, that in the constructor I wouldn’t have the access to the parent (haven’t been added to the Component’s tree yet). And what I have to do is subscribe to the events of that state object, which I would like to do at construction.