Hello,
this is another question about writing C++ extensions for Panda3D.
What I do: In Python I load a NodePath, but only in local namespace. So the Python object will dealloc as soon as the current method finishes. Then I create an object from my extension and pass the NodePath to this object. The extension objects unpacks the C++ NodePath pointer and stores the NodePath* as a member.
My problem: The extension objects will be alive longer than the (Python) NodePath objects. I want to use the C++ NodePath pointer even after the Python NodePath was destroyed, e.g. like in this pseudo code:
import extension
....
def setup( self ):
np = loader.loadModel( ... )
self.foo = extension.Foo( )
self.foo.setNodePath( np )
# np will dealloc after this line
def test( self ):
print self.foo.getNodePath( )
NodePath doesn’t inherit from ReferenceCount, so I can’t just create another reference in C++ like I could with e.g. geomNode: “geom_node->ref( )”.
So far I have come up with two possible solutions:
(1)
The extension object stores not only the NodePath*, but the Python NodePath objects too (and use Py_INCREF/DECREF when setting the member, initialize to Py_Node and so on…). This way the Python object will be alive as long as the extension object:
typedef struct {
PyObject_HEAD
NodePath* m_np;
PyObject* m_npObject;
} PyFooObject;
(2)
The extension objects doesn’t store the C++ NodePath*, but creates a copy of this NodePath using the copy constructor (and free the allocated object again in ~Foo or when setting again):
NodePath* np = (NodePath*) ( (Dtool_PyInstDef*) _np )->_ptr_to_object; // unpack
self->m_np = new NodePath( *np ); // copy constructor
Both solutions seem to work, but I want to ask if somebody knows possible issues with on or the other way, or perhaps knows a third way.
Thanks,
enn0x