Hello @pim,
thank you for reaching out to us. The proposed solution of @fwilleke80 sort of works, but has its problems in Python. There is no type BaseLink
in Python and you can therefore not use it directly. You can add a parameter of type DTYPE_BASELISTLINK
to a BaseList2D
of your choice and then store there the reference to the node. But that always requires a node where you are okay with "polluting" its GUI in this manner. You could of course hide these parameters in the UI, but that all could come a bit messy, especially when it is more than one parameter to reference.
There are two alternative solutions:
- EVMSG_CHANGE: This core message is being sent when a document has changed. This includes, but is not limited to, objects being removed. You get here no further information except for the fact that
EVMSG_CHANGE
has occurred. You must determine yourself if an event x
, e.g., the object with the name "foo" has been deleted, has occurred. One usually must deal with the UUID markers of nodes when doing something like this. We talked often about UUID markers on this forum, for example here I went over the whole approach.
- BaseList2D.AddEventNotification: With this method you can let yourself be informed about events that happen to a specific node, including
NOTIFY_EVENT_REMOVE
. I showed how to use this internal method here.
When we compare the two approaches, we can note a few drawbacks for each of them:
EVMSG_CHANGE
:
- Requires a
MessageData
plugin, or a GeDialog/GeUserArea
to receive the core message in the first place.
- The message itself is very broad, and one must do substantial work to narrow down an event. If done naively, this can become a substantial bottleneck.
- So, when you want to be informed inside an
ObjectData
implementation O if a node n has been removed, you would implement a MessageData
M, which listens for EVMSG_CHANGE
, then traverses the scene to check if N is still there, and finally informs all instances of O by sending a MSG_BASECONTAINER
to them with the event data.
- All in all, this can be quite a bit of work, but it is the most robust approach when executed properly.
AddEventNotification
:
- Requires access to some kind of
NodeData
, e.g., an ObjectData
, implementation because without access to a NodeData.Message
to receive the event notification, adding an event notification is meaningless.
- This method family is internal for a reason. When used improperly, it is easy to crash or freeze Cinema 4D with it.
NOTIFY_EVENT_REMOVE
is unfortunately very literal in its event handling. When we have the element hierarchy root->a->b
and we register for NOTIFY_EVENT_REMOVE
for b
, we will only be informed when b.Remove()
is being called, but not when a.Remove()
is being called, although both events have effectively the result that b
is not part of the element tree root
anymore.
What to do concretely depends on your plugin. Please share code and details about your project, as answering your question will otherwise be speculative.
Cheers,
Ferdinand