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
MyPluginState state on the other hand is instance bound, i.e., you need an instance of
MyPlugin to access it such as
static variant is always accessed over the class interface, i.e.,
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):
// 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;
// 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.
maxon::ScopedLock guard (g_state_lock);
// When we are on the main thread we do not need a lock, because the main thread is sequential
// in nature on its own.
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.