Design Choices for shared variables across Plugins & Classes



  • Hey everyone,

    not sure I'm finding the right words, or the right explanation for my problem, but I'll try to explain as thorough as possible. :)

    I'm currently developing a new plugin that shares one important global variable, amongst others, across different CommandData plugins. It's a "global" filepath called rootfolder a user can select within a GeDialog.

    I guess my main question is, how one would go about sharing this filepath with different classes, because I find it kind of ugly to init the same thing over and over again...

    For example, I have a myObject() within myOverview() within a ListView(c4d.gui.TreeViewFunctions) and every class should know about the rootfolder deriving from the OptionsDialog(c4d.gui.GeDialog).

    Currently my OptionsDialog(c4d.gui.GeDialog) is initialized like this:

        def __init__(self):
            self._treegui = None  # Our CustomGui TreeView
            self._listView = None # Our Instance of c4d.gui.TreeViewFunctions
    
            #loading from c4d.plugins.GetWorldPluginData()
            self._data = myContainer.load()
    
            self.rootfolder = self._data.GetFilename(ids.IDC_FILEPATH) or self.GetFilename(ids.IDC_FILEPATH) or None
    

    I basically could use myContainer.load().GetFilename(ids.IDC_FILEPATH) in every other class, but it seems a little bit awkward, so I'm just wondering what's the best way to store this "global" path from the GeDialog and it reusing all over the places.

    How would you guys go about this, is c4d.plugins.GetWorldPluginData() really the best way store the data and initializing it in every Class..? I mean it's working okay I guess, but I was wondering if there are better decisions code/design wise out there...

    If you need any further explanation or examples, I'm happy to see what I can share.

    Thanks for reading, and happy coding.

    Cheers,
    Lasse



  • Hi,

    I am not suite sure if I do understand your question correctly. Why would a simple module level variable not be sufficient? You could of course do more fancy stuff like binding a property to a class instead of binding it to an instance [1], but I do not see the point of doing that if the property is meant to be global anyways.

    Cheers,
    zipit

    [1] Something like that:

    class Foo():
        """
        """
        something = None
        
        @classmethod
        def set_something(cls, value):
            """
            """
            cls.something = value
            
        @classmethod
        def get_something(cls):
            """
            """
            return cls.something 
    
    a = Foo()
    b = Foo()
    
    print 'a: ', a.get_something()
    print 'b: ', a.get_something()
    
    a.set_something('bob is your uncle.')
    
    print 'a: ', a.get_something()
    print 'b: ', a.get_something()
    
    b.set_something('42 is the answer.')
    
    del(a)
    del(b)
    
    print 'Foo: ', Foo.get_something()
    
    """ 
    
    -- Output ---------------------------------------------------------------------
    
    a:  None
    b:  None
    a:  bob is your uncle.
    b:  bob is your uncle.
    Foo:  42 is the answer.
    """
    


  • hi,

    as @zipit said (and thanks for that) you can use a static class variable for that.
    Be aware that as Zipit did it, (using setter and getter) you will be sure that you are changing the value of the class variable.

    if you are trying to access the variable you will create a new variable in that instance. (and not change the class's one)

    # this is really wrong, do NOT use this code
    b.set_something('42 is the answer.')
    b.something = "this is another thing" # this is dangerous here.
    
    print "without setter", b.something
    print "with setter", Foo.something
    

    That solved the problem of sharing values between classes.

    If you want to share value between different plugins and your plugins are totaly separated, than you can use a BaseContainer stored either in the document if it's document related or in the WorldContainer.

    Be aware that you should avoid using the WorldContainer to store your plugins data if you have other solution.

    But depending of you workflow, in this case, we can consider that you are setting a preference.

    On GitHub we have this example that show How to Expose parameters as global Preference

    Cheers,
    Manuel



  • hello,

    I will consider this thread as solved without new information from you :)

    Cheers,
    Manuel