Hello @a_block,
Thank you for reaching out to us. Before proposing practical solutions, we should clarify the exact task, as your initial posting is there sending mixed messages at least for me. There are two options:
- Detect that a document has been closed. This approach is unable to modify the document before it is being closed (or gather data on it without reloading the document).
- Detect that a document is in the process of closing. This implies the ability to carry out 'last minute actions' on the document before it actually closes.
Option one is relatively easy to do: Just implement a message data plugin or something else like dialog that provides a timer method and periodically check the list of active documents and cache the information in that list in some form. When the list then does differ on a timer call from its cache state, you know that these documents have been closed since the previous call. This is probably what you are already doing and referring to with 'counting documents'.
Option two requires the node/plugin message system and the message MSG_DOCUMENTINFO_TYPE_REMOVE
of the message family MSG_DOCUMENTINFO
as pointed out by @fwilleke80 (thanks!). As you have already discovered yourself, you will need some form of NodeData
implementation for that, and that in C++ the obvious candidate for that is a SceneHookData
. But there are other node types you can hook into in Python. But be aware that at least c4d.plugins.PreferenceData
will not work for sure in this context (because I tried myself in the past), and I think SceneSaverData
and SceneLoaderData
will work neither. The reason is that not all node/plugin messages are being broadcasted to all node types. The C++ documentation sometimes hints at that in message descriptions but is far from complete in this regard. But you will be able to use ObjectData
or TagData
in this fashion. So, the plan would be:
- Still have Option 1 to detect new documents being opened.
- Insert a custom
MyObjectData
into the document and hide the node.
- When the document is being closed,
MyObjectData.Message
will be invoked.
- Carry out what you want to carry out.
- Remove the node for
MyObjectData
from the document (so that installations without the plugin can still load it properly).
Which is a lot of work and is also a bit dicey in point five. As it does rely on MyObjectData.Message
always being called on the main-thread in this context (or alternatively would have to ignore main-thread restrictions).
If you are only after option one, then a message data plugin or just a timer method in your dialog is the best way, even in C++ IMHO. If you are after option two, I frankly do not see a satisfactory solution. If you are after option two, it might be interesting for our users what workaround you did find, since at least I have no idea other than the proposed one to navigate around the problem.
Cheers,
Ferdinand