Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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

    Instance variables static or not?

    General Talk
    c++ macos 2023
    2
    3
    697
    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.
    • W
      wnoyce
      last edited by

      Hi there,

      I am working on an ObjectData derived plugin and can't seem to decide whether to make my private instance variables - simple structs really - static or not.

      So, would

      struct MyPluginParameters
      {
          Float a;
          Int32 b;
          Int32 c;
          Bool d;
          Bool e;
      };
      
      
      struct MyPluginState
      {
          Float f;
          Bool g;
          Int32 h;
          Int32 i;
      };
      
      
      class MyPlugin : public ObjectData
      {
      public:
          virtual Bool Init(GeListNode* node);
      
          virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
          virtual Bool Message(GeListNode* node, Int32 type, void* t_data);
      
          static NodeData* Alloc() { return NewObjClear(MyPlugin); }
      
      private:
          static MyPluginParameters params; 
          static MyPluginState state;
      };
      
      MyPluginParameters MyPlugin::params;
      MyPluginState MyPlugin::state;
      

      be preferred to the simpler:

      class MyPlugin : public ObjectData
      {
      public:
          virtual Bool Init(GeListNode* node);
      
          virtual BaseObject* GetVirtualObjects(BaseObject* op, HierarchyHelp* hh);
          virtual Bool Message(GeListNode* node, Int32 type, void* t_data);
      
          static NodeData* Alloc() { return NewObjClear(MyPlugin); }
      
      private:
          MyPluginParameters params;
          MyPluginState state;
      };
      

      or not? Is there any pragmatic difference between the two options?

      Thank you very much.

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

        Hello @wnoyce,

        Thank you for reaching out to us. Unfortunately, your question is off topic for the forum you have posted in. Please check Forum and Support Guidelines: Forum Structure for an overview of the scope of the different forums.

        In general, we do not provide support on language features itself or third-party libraries. I therefore have moved your posting to the off-topic forum.

        Regarding your Posting

        I am not quite sure how your question is meant; you might want to have a look at static members in the C++ reference. But, yes, there is a fundamental difference between these two options. static MyPluginState state would be class bound, i.e., all instances of MyPlugin would share the same state. MyPluginState state on the other hand is instance bound, i.e., you need an instance of MyPlugin to access it such as myPluginInstance.state. The static variant is always accessed over the class interface, i.e., MyPlugin::state.

        What to do here depends on what you want to achieve with your plugin. Generally speaking, it seems unlikely that you want a static state. You should also be careful with field members on NodeData types, as you can easily produce access violations when you write them from methods which are executed in parallel, e.g., ObjectData::GetVirtualObjects. For instance bound members you are usually somewhat safe, but a class bound MyPluginState would be effectively a global variable shared by all your plugin instances. You will need for sure a signal object here to regulate access. Cinema 4D has multiple mutex/lock/semaphore like objects, most of them are described here. In practice it could look like this (untested pseudo-code):

        class Foo
        {
          private:
            // A global state object used by all Foo instances and a global lock regulating access to it.
            static State g_state;
            static maxon::Spinlock g_state_lock; 
          
          public:
        
            // A method which tries to manipulate g_state.
            static void Bar()
            {
              // When we are not on the main thread, we lock g_state before we start modyfing it. This will
              // effectively sequentialize threads executed in parallel. When you do this for example inside
              // a ObjectData::GetVirtualObjects impl., you will sequentialize the cache building of your
              // plugin. Which is of course quite slow when a user has multiple instances of your object in
              // a scene.
              if (!GeIsmainThread())
              {
                maxon::ScopedLock guard (g_state_lock);
                Foo::g_state.ChangeData();
              }
              // When we are on the main thread we do not need a lock, because the main thread is sequential
              // in nature on its own.
              else
              {
                Foo::g_state.ChangeData();
              }
            }
        }
        

        In our API is also the concept of atomic types, which are inherently thread safe. They are however as their name implies limited to atomic data types. Internally, these types are also just a data field with a lock arround it, but they are much more optimized and faster than a normal signal object.

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        W 1 Reply Last reply Reply Quote 0
        • ferdinandF ferdinand moved this topic from Cinema 4D SDK on
        • W
          wnoyce @ferdinand
          last edited by

          Hi @ferdinand,

          Thank you for moving this topic to its correct category.
          Although I believe we agree on the C++ meaning of static members I really wasn't aware that the use of static plugin parameters and static plugin state could in practice be as problematic as you describe and will certainly heed your advice to no longer use static plugin state.
          Also, your point on field members and parallel execution of member functions is well taken.

          Thanks again!

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