I'm wondering, is there a message, which gets sent around, when a document gets closed?
I know, sounds like a stupid question, but since R25 the user can use R25's new document tabs to close background documents. Unfortunately I would need to find out about such event.
This is not a high priority request. I do have a working workaround. But I'd rather react to such event specifically, instead of counting docs all the time...
MSG_DOCUMENTINFO with type MSG_DOCUMENTINFO_TYPE_REMOVE doesn't help?
sounds as if it is the message, I was looking for. But in my experience MSG_DOCUMENTINFO is a bit difficult in Python. Fine for NodeData plugins, but unfortunately (and I should have mentioned this from the start, sorry!) I need it in a CommandData/GeDialog/MessageData context. And in neither of these I seem to be receiving MSG_DOCUMENTINFO. Neither in CommandData.Message() or GeDialog.Message(), nor in GeDialog.CoreMessage() or MessageData.CoreMessage().
But to be also completely honest, I must have overlooked MSG_DOCUMENTINFO_TYPE_REMOVE. I was actually looking at that table before posting, but somehow missed it. Either I was to focused on the term "close" or (more likely) I was blind as a mole.
So, thanks for making me aware! Much appreciated.
Unfortunately a quick test seems to prove my experience right, I do not seem to get MSG_DOCUMENTINFO in any of these contexts. But it was really a very quick test in the middle of a good old Star Trek TNG episode, so maybe I have more luck tomorrow...
What I did not try, yet, if I might get it in PluginMessage(). Although I'd be a bit surprised by that.
Well, then we have arrived in the word of fun workarounds
How about a SceneHook that receives MSG_DOCUMENTINFO, and then sends a core message that then will be received by the dialog?
Hehe, a SceneHook in Python? I did not mention Python explicitly in my first post, because I thought the tags stand for themselves.
I think, this topic can already be closed. I was asking, because I had overlooked MSG_DOCUMENTINFO_TYPE_REMOVE. Now, that I know about it, I'm pretty sure, there is no other (why should there be?). And I'm simply in the realm of restrictions of the Python integration. No critique involved, for example I understand pretty well, why one does not want to have SceneHooks in Python. MSG_DOCUMENTINFO would certainly be cool to have in more contexts, but I assume, there are valid reasons not to have it. Also, as always, if it got implemented with any future release, it wouldn't help me at all, as I need solutions to work over a wider range of C4D versions (like in this case for R25 as well, but there will be no more updates to it, if I'm not mistaken).
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:
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:
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.
I only need to know, a document has been closed in the background.
And the MessageData checking for that, I already have. And it needs to iterate the document list. Works, but optimal is different. That was the whole point I was asking.
So, yes, I'm only after option one. And the workaround is to iterate the document list under certain conditions. I am not a fan of polling, so I had hoped for a precise event. But please don't get me wrong, I can live without. I only had hoped for a more efficient solution.
Iteration of the document list surely is no problem, if only done by one plugin. But imagine a whole lot of installed plugins, which all jump through similar hoops. At some point it all adds up.
Ah, damn, I forgot that Python doesn't have SceneHookData. Sorry.