Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Global Variable doesn't work on CoreMessage?

    Cinema 4D SDK
    r21 python
    4
    7
    975
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      bentraje
      last edited by

      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?

      1 Reply Last reply Reply Quote 0
      • C4DSC
        C4DS
        last edited by

        Please use the Markdown to list your code, as mentioned here (link = https://developers.maxon.net/forum/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.

        1 Reply Last reply Reply Quote 1
        • ferdinandF
          ferdinand
          last edited by

          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

          MAXON SDK Specialist
          developers.maxon.net

          1 Reply Last reply Reply Quote 2
          • B
            bentraje
            last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand
              last edited by ferdinand

              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

              MAXON SDK Specialist
              developers.maxon.net

              1 Reply Last reply Reply Quote 2
              • B
                bentraje
                last edited by

                @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.

                1 Reply Last reply Reply Quote 0
                • M
                  m_adam
                  last edited by

                  @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.

                  MAXON SDK Specialist

                  Development Blog, MAXON Registered Developer

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post