Event on tag removed or C4D closed?



  • On 19/06/2013 at 00:46, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R13-R14 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I have a tag that adds a Null (helper) object to another object.
    In the case  that this tag is removed by the user, I want the Null to be removed too.
    I have written a destructor, ~MyTag(void), but firstly this has no way to get access to the base object / any node as far as I can see. And secondly, it is called also when C4D closes down, and then maybe there is no reason to remove the helper object?

    I am unsure about how you handle the life cycle of a tag, because it will invariably create BaseArrays and other objects during its life time. In C# I am spoiled because of garbage collection, but I am old enough to be used to cleaning up after me, memory leaks etc., from Delphi's Object Pascal.

    What to do if the user removes the tag?
    What to do when the project closes?
    What to do when C4D closes?



  • On 19/06/2013 at 00:57, xxxxxxxx wrote:

    1. I hope you are creating the helper object from a method called from the main thread, not from any
    other like Execute(). The Message() method fits well for this purpose (MSG_MENUPREPARE)
    2. Your tag should be able to handle if the Null-Object is removed. My advise is to create a link-field
    where the Null-Object is automatically assigned to.
    3. Do not perform the deallocation of an object from the destructor.
    4. If you do not use a link-box as suggested in #2, at least use a BaseLink to reference the
    Null-Object instead of referencing it directly. What would you do if the user removed the Null-Object
    and you are still directly referencing it? BOOM CRASH!

    What to do if the user removes the tag? I'm not sure if there is a message sent when the tag is
    removed. Just print every call to Message() and see if there is. Otherwise, you're left to leave the
    Null-Object in the scene and the user must remove it him/herself.

    What to do when the project closes? Why should there be something left to be done?

    What to do when C4D closes?  Same question.

    -Niklas



  • On 19/06/2013 at 01:46, xxxxxxxx wrote:

    Please see NodeData::Free() in the SDK. Your tag, being a TagData, inherits NodeData, so when the tag is deleted Free() is called. Since it passes a GeListNode you can use this to delete the null object. That's what Free() is for, as the SDK says, to de-allocate stuff you've allocated.

    This will also be called when the scene is closed (so it will be called when Cinema is closed, too). One caveat - if the user *moves* your tag to another object, I don't think Free is called. In fact I don't know what the sequence of events is then.

    Steve



  • On 19/06/2013 at 02:02, xxxxxxxx wrote:

    Hi and thanks to both of you! This cleared up a lot of things.

    Originally posted by xxxxxxxx

    1. I hope you are creating the helper object from a method called from the main thread, not from any other like Execute().

    The Null is created when the user pushes a button. And then sits on the remote object.
    If I remove my tag as it is now, the Null remains there. But I want to remove it, which is easy, I just look for it by iterating the remote object's hierarchy. 
    The Null is not kept anywhere at all in the tag. The owner, though, as a linked object.

    Originally posted by xxxxxxxx

    What to do when the project closes?  Why should there be something left to be done?
    What to do when C4D closes?  Same question.

    This is a good answer :)

    Originally posted by xxxxxxxx

    Please see NodeData::Free() in the SDK.

    Bingo!! That's what I am after. I will look into that!
    And the advice to print the messages is a very good one.

    What I still am a little unsure about is how to manage the life cycle of custom classes I design (not C4D objects). These are classes I very often use, I  store them in BaseArrays*, they hold several values, are placeholders. I have looked at code others have written and I don't see much of freeing up stuff. I am used to (from Delphi's Pascal) to have try..catch..finally blocks, and free up everything as soon as it is used.

    I use several kinds of object, some are stored in the BaseContainer, some are just a public property of my tag, and before I publish my tag I must ensure that all this is proper and that I have no memory leaks. Right now my focus is on making things work.



  • On 19/06/2013 at 02:41, xxxxxxxx wrote:

    Here is an update,  NodeData::Free() is called when the tag is removed, yes. Good. But it is also called when the project is closed. Now, doing my "cleanup" when the projects closes, seems to have no negative effect. But I currently see  no way to differ between the project being closed on on side, and just the tag being removed, on the other side. NodeData::Free() is called regardless.



  • On 19/06/2013 at 03:01, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    What to do if the user removes the tag? I'm not sure if there is a message sent when the tag is
    removed. Just print every call to Message() and see if there is. Otherwise, you're left to leave the
    Null-Object in the scene and the user must remove it him/herself.

    Have you checked the docs, or as I quoted above, checked the messages you recieve? Just as there
    is a MSG_MENUPREPARE message sent when an object is inserted into a document, there might be
    a message sent when the object is removed from the document.



  • On 19/06/2013 at 03:03, xxxxxxxx wrote:

    The only message I saw when I removed the tag, was MSG_DESCRIPTION_POSTSETPARAMETER
    But this message also occurs a lot of times, without the tag being removed.



  • On 19/06/2013 at 04:28, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Here is an update, <span style=": rgb248, 248, 252;"> NodeData::Free() is called when the tag is removed, yes. Good. But it is also called when the project is closed. Now, doing my "cleanup" when the projects closes, seems to have no negative effect. But I currently see  no way to differ between the project being closed on on side, and just the tag being removed, on the other side. </span><span style=": rgb248, 248, 252;">NodeData::Free() is called regardless.</span>

    Why does it matter? In both cases you want to free up memory that's been allocated. Or am I missing something?



  • On 19/06/2013 at 04:58, xxxxxxxx wrote:

    You are correct Steve, I was thinking about removing the aforementioned Null object. Of course is this Free() very important for any resource allocated inside the plugin.



  • On 19/06/2013 at 05:03, xxxxxxxx wrote:

    there is the msg_documentinfo message which allows you to react to various document related 
    events (loading, merging, saving and so on, some of the events are separated into a message 
    before the event and a message after the event). you can also just listen for the core message 
    evmsg_change and then compare the currently active document with a reference to the last
    known document (that has been the official maxon advice on the topic).

    as steve already pointed out you should treat freeing a node always like your document is about 
    to be closed (at least I do understand it that way). There is also PluginMessage() in c4d_plugin 
    which allows you to react to c4ds startup and closing process.



  • On 19/06/2013 at 05:33, xxxxxxxx wrote:

    Great littledevil, very important information.
    _
    _
    > that has been the official maxon advice on the topic
    I see this sometimes, referring to Maxon, and wonder if it is  in the SDK, or if it stems from direct conversation with Maxon.



  • On 19/06/2013 at 06:12, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Great littledevil, very important information.
    _
    _
    > that has been the official maxon advice on the topic
    I see this sometimes, referring to Maxon, and wonder if it is  in the SDK, or if it stems from direct conversation with Maxon.

    it is here in one of the threads, i am not sure anymore if i did ask the question myself, or if i 
    read the answer in another thread. i just know that the topic about reacting to document 
    events does come up regularly and matthias bober (one of the maxon devs) said that listening 
    to evmsg_change would be the common way to do that.

    i have no idea what about the document messages is wrong, i just suspect this was a general
    answer, including plugins which do not have access to nodedata messages, but only to core
    messages, but that is only my interpretation.

    happy rendering,
    ferdinand

    ps: ah found it:

    https://plugincafe.maxon.net/topic/6232/6581_notification-on-change-of-active-document&KW=document+save


Log in to reply