Saving pointers to BaseObjects for use between scene updates



  • I'm trying to build a list of objects pulled in from the scene and save that list for use in future scene updates.

    This seems to work fairly well using maxon::BaseArray<BaseObject *>. I can use a combination of GetDirty()/GetHDirty() to keep track of hierarchy changes and invalidate the list when the dirty count is increased. However, if I do an undo in the scene, GetDirty()/GetHDirty() do not update and yet the object pointers are changed- leading to an immediate crash when I try to access them again.

    What is the proper way of keeping internal references to objects within the scene? At first glance, BaseLink looks like it might have been the way to go, but I can't seen to figure that one out since creating a new BaseLink with BaseLink::Alloc() and subsequently calling myBaseLink->SetLink(obj) followed by BaseObject *myObject = static_cast<BaseObject *>(myBaseLink->GetLink(doc)) just causes an immediate segmentation fault.

    How can I store objects in a safe manner so that I can access them later on (assuming they're still part of the scene)?

    Cheers,
    -CMPX



  • Hi cmpxchg8b and thanks for reaching out us.

    With regard to your issue, it's explicitly discouraged, as written in the C++ API documentation, to store BaseObject pointers and to use them for further operations especially when object creation/deletion and undo processes steps takes place.

    It's instead recommended using the BaseLinkwhich provides a convenient and reliable way to refer to BaseList2D elements in a scene.

    BaseLink principles and use are well explained here.

    Finally, the code below doesn't show the segmentation fault you've mentioned.

    maxon::Result<void> Check(BaseDocument *doc)
    {
    	// check for passed parameter
    	if (!doc)
    		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    	
    	// get the active BaseObject
    	BaseObject* obj = doc->GetActiveObject();
    	if (!obj)
    		return maxon::OK;
    	
    	// print the object's name
    	DiagnosticOutput ("Object [@]", maxon::String(obj->GetName()));
    	
    	// allocate a BaseLink
    	BaseLink *link = BaseLink::Alloc();
    	if (!link)
    		return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    	
    	// connect to the object
    	link->SetLink(obj);
    	
    	// access the BaseObject referred by the link
    	BaseObject* const linkedObj = static_cast<BaseObject*>(link->GetLink(doc));
    	
    	// print the referred object's name
    	DiagnosticOutput ("Linked Object [@]", maxon::String(linkedObj->GetName()));
    	
    	// assert returned names are equal
    	DebugAssert(obj->GetName() == linkedObj->GetName());
    	
    	return maxon::OK;
    }
    

    Looking forward further feedback, give best.
    Riccardo



  • Hi cmpxchg8b and thanks for reaching out us.

    With regard to your issue, it's explicitly discouraged, as written in the C++ API documentation, to store BaseObject pointers and to use them for further operations especially when object creation/deletion and undo processes steps takes place.

    It's instead recommended using the BaseLinkwhich provides a convenient and reliable way to refer to BaseList2D elements in a scene.

    BaseLink principles and use are well explained here.

    Finally, the code below doesn't show the segmentation fault you've mentioned.

    maxon::Result<void> Check(BaseDocument *doc)
    {
    	// check for passed parameter
    	if (!doc)
    		return maxon::IllegalArgumentError(MAXON_SOURCE_LOCATION);
    	
    	// get the active BaseObject
    	BaseObject* obj = doc->GetActiveObject();
    	if (!obj)
    		return maxon::OK;
    	
    	// print the object's name
    	DiagnosticOutput ("Object [@]", maxon::String(obj->GetName()));
    	
    	// allocate a BaseLink
    	BaseLink *link = BaseLink::Alloc();
    	if (!link)
    		return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION);
    	
    	// connect to the object
    	link->SetLink(obj);
    	
    	// access the BaseObject referred by the link
    	BaseObject* const linkedObj = static_cast<BaseObject*>(link->GetLink(doc));
    	
    	// print the referred object's name
    	DiagnosticOutput ("Linked Object [@]", maxon::String(linkedObj->GetName()));
    	
    	// assert returned names are equal
    	DebugAssert(obj->GetName() == linkedObj->GetName());
    	
    	return maxon::OK;
    }
    

    Looking forward further feedback, give best.
    Riccardo



  • Greetings!

    Thanks for the reply.

    I kinda goofed up- apparently my objects were being improperly deconstructed before I was trying to use them, which was causing the BaseLink to get deleted and crash on subsequent access. BaseLink does indeed work fine and solves my problem. Sorry for the confusion!

    -CMPX


Log in to reply