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

    Global static classes?

    Cinema 4D SDK
    c++
    2
    4
    549
    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.
    • E
      ECHekman
      last edited by ferdinand

      In the documentation i read the following:

      Do not use global static classes of complex types. Elementary data types (Int32, Float, Char etc.) are allowed, see Primitive Data Types Manual (Cinema API).

      Im not sure what this exactly means. But im trying to create a settings class as a static member to ShaderData nodes that contains information about the derived class that the base class needs to know.

      struct InfoStruct
      {
      public:
          UInt32 SomeID;
          Int32 SomeUI;
      };
      
      PluginNodeBase  : public ShaderData
      {
          INSTANCEOF(PluginNodeBase, ShaderData)
      public:
          virtual PluginNodeInfoStruct& PluginNodeInfo() const = 0;
      }
      
      class SomeClass: public PluginNodeBase
      {
          INSTANCEOF(VolumeMedium, PluginNodeBase)
      
      public:
          // Set plugin node info
          inline static PluginNodeInfoStruct sPluginNodeInfo
          {
            SOME_ID,
            SOME_UI_ID,
          };
          virtual PluginNodeInfoStruct& PluginNodeInfo() const override { return sPluginNodeInfo; };
      
      }
      
      

      Would this be fine? or is there a reason Icould not use static in this way?

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

        Hey @ECHekman,

        Thank you for reaching out to us. You should avoid such things as sPluginNodeInfo (which I assume is meant to return an InfoStruct and not a PluginNodeInfoStruct and to be the focal point of your question). The correct way to do this in the context of NodeData plugin hooks, would be to place an uninitialized field on your node and then initialize it in NodeData::Init (and possibly implement NodeData::CopyTo, ::Read, and ::Write to also support copy and IO events). When you want a const value, implement a function which returns a const value each time when called, possibly pulling up an internal value (a 'getter' property) or simply returning a new value each time.

        You will land in a world of hurt sooner or later when you ignore this in our API (as in access violations, I just had a dev internally who tried to pull up point data in this manner and then ran into said access violations). Your case is probably fine, but you should not do this. I personally would also avoid marking functions as virtual which are not. SomeClass::PluginNodeInfo is likely meant to be a concrete implementation and therefore should not be virtual.

        The same thing applies to global instances (which is probably what was meant in docs primarily).

        // Not a good idea ...
        static InfoStruct g_info;
        
        int main() {
            g_info.Foo();
            return 0;
        }
        

        Cheers,
        Ferdinand

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • E
          ECHekman
          last edited by

          Could you explain the issue with this though? Is C4D doing strange stuff with c++ classes derived from ShaderData?

          I wanted to avoid having to recreate the PluginNodeInfoStruct every time an instance is created by placing it in ::Init. Would the following be fine?

          virtual PluginNodeInfoStruct& PluginNodeInfo() const override 
          { 
              static PluginNodeInfoStruct sPluginNodeInfo
              {
                  SOME_ID,
                  SOME_UI_ID,
              };
              return sPluginNodeInfo; 
          };
          
          1 Reply Last reply Reply Quote 0
          • ferdinandF
            ferdinand
            last edited by ferdinand

            As I said, you will run into access violations when you instantiate your fields on the class instead of the Init function. And as I also said, in your concrete case it would probably even be fine if you would directly do it in the class scope. But I would advise against breaking this rule. There is nothing to optimize here, either return a new instance when this is only called once in a blue moon and you do not want to bother with initializing a field. Or define a field and initialize it up in NodeData::Init. And no, scene elements (NodeData) should not share data on their class. We have types in the Maxon API to deal with this when you really want some heavy data structure which shall be initialized exactly once, but that is total overkill in this case.

            Cheers,
            Ferdinand

            MAXON SDK Specialist
            developers.maxon.net

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