Global Variable doesn't work on CoreMessage?



  • Hi,

    I have two main classes. One for TreeView and the other for GeDialog.

    I have inserted c4d.SpecialEventAdd() in Treeview
    The event triggers well under the CoreMessage of GeDialog.

    The problem is global variable is not being updated under the CoreMessage
    In the illustration below, the console always prints "images".
    It should, however, be changed to whatever Tree Item is selected.
    https://www.dropbox.com/s/gjdvda8n4b16rs9/c4d264_global_variable_doesn't_work_on_core_message.mp4?dl=0

    You can check the CoreMessage function in the source code below:
    https://www.dropbox.com/sh/lpfpmux073toork/AACTxFpGmMK2MpgoCI0N-3Eba?dl=0

    Is there a way around this?



  • Please use the Markdown to list your code, as mentioned here (link = https://plugincafe.maxon.net/topic/10953/how-to-post-questions). It's easier for anyone to look at your code in your topic, instead of following a link. Thanks.



  • Hi,

    cur_folder is not a global variable, but a module level variable. The only place where you modify cur_folder is in TreeData.Select. You will need to test if that branch of the method is ever executed.

    On a side note: Never use global variables, because they are the devils work and module level variables are also a dangerous thing in a threaded environment (but you should be safe here, since everything should normally run on the main thread in your code).

    Cheers,
    zipit



  • Thanks for the response

    @C4DS
    I usually put markdowns on my code whenever I ask questions.
    It's just there are dependencies on the code, so I didn't.
    Anyway, here is the CoreMessage section

        def CoreMessage(self, id, msg):
            if id==PLUGIN_ID:
                #Fired by the main thread...
                print cur_folder
                return True
    
            return gui.GeDialog.CoreMessage(self, id, msg)
    

    @zipit

    RE: cur_folder is not a global variable
    Oh but I actually declared it before any Class or Functions.
    The variable is at the top under the import statements.

    RE: You will need to test if that branch of the method is ever executed.
    Whenever I print the cur_folder inside the class Tree Data > def Select, it works as expected (i.e. it prints a different variable whenever I click a folder)

    It's on the class GeDialog>def CoreMessage that for some reason stuck at the initial variable declaration (i.e. "images")

    Let me know if you need further clarification.



  • Hi,

    I was just pointing out that global has slightly different meaning in Python than in other languages. global is a keyword with which you can shadow a variable of an inner scope with an variable of an outer scope. Your variable is neither global nor really a variable, but an attribute bound to a module.

    When you assign the name to cur_value in Select, you do this to a variable called cur_value in the scope of the method Select, not to the attribute of the same name of the module.

    SOME_ATTRIBUTE = "Bob is your uncle"
    
    class MyObject():
        def do(self):
            """
            """
            SOME_ATTRIBUTE = "This won't work"
    
        def do_global(self):
            """
            """
            # Bad, really bad! Do not do this.
            global SOME_ATTRIBUTE
            SOME_ATTRIBUTE = "This will work"
    
    obj = MyObject()
    
    print SOME_ATTRIBUTE
    obj.do()
    print SOME_ATTRIBUTE
    obj.do_global()
    print SOME_ATTRIBUTE
    
    
    Bob is your uncle
    Bob is your uncle
    This will work
    [Finished in 0.1s]
    

    The correct way would either be to bind your cur_folder to an object over which you have more control (a class or an instance of class) or just send cur_folder along with the message as message data.

    Cheers,
    zipit



  • @zipit

    Thanks for the warning.
    Yep, the adding class or an instance of class seems to work as expected.
    I ended up using dict/list since I have to store the variable along with its designated path.

    RE: just send cur_folder along with the message as message data
    I'm not sure how to do this. I'll just probably create a separate thread for this one.

    Thanks again for help.



  • @bentraje I don't have that much to add on your topic since I think @zipit already explained everything nicely.

    In any case some good resource for you about how global variable works in Python Global keyword in Python and Mutable vs Immutable Objects in Python.

    Regarding your last question, I think you should open a new topic, but the short answer there is no way to pass directly a variable with a MessageData, the best way is to use a scope accessible by both part and store this variable in this shared scope (can be global or any other).

    Cheers,
    Maxime.


Log in to reply