weakref to NodePath?

Hi all!

I’m attempting to provide a weak back-reference to a NodePath, so that I don’t create a circular reference (the reference is occuring in a class that functions as an aspect, so it will frequently be used as a mixin to other classes). It appears, however, that this is impossible:

>>> foo=NodePath('foo')
bar=weakref.ref(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot create weak reference to 'libpanda.NodePath' object

Am I doing this wrong, or is it impossible?

As a related code-design question: The reason I’m bothering with this style is that I don’t want to subclass NodePath, since the behavior I am trying to encapsulate in this class can be mixed with other classes that themselves could subclass NodePath (so if I made a new subclass that inherited from both this class and one of my other classes, and they both inherited from NodePath, the inheritance tree gets silly fast). Can anyone suggest a better way to achieve that goal that doesn’t involve using weakrefs back to the NodePath that I am “subclassing?”

from the Python documentation:

Panda3D is an extension module, I assume it’s not supporting weak referencing.

I’m not sure if the subclassing you are describing will be a problem in Python. Really depends more on the relationsships you have in mind.

Hope that helps,
kaweh

Ah, thank you for finding that reference! I see what the difficulty was now.

I had thought weakrefs to NodePaths worked because I was certain I had done them in the past. It turns out that what I had done was to weakref a class that inherits from NodePath; this is valid (the class is a class), whereas attempting to weakref a NodePath directly is not (the NodePath type cannot be weakly referenced). I do this often; for example, nodes that have special and instance-specific behavior when they collide with something can have that behavior squirreled away by extending NodePath with a class that describes the behavior, scribbling a weakref to the class onto itself (using setPythonTag(‘collideBehavior’,weakref.ref(self)) ), then using getNetPythonTag to retrieve the collision behavior when any child node is collided against.

In terms of the subclassing, the issue I’m having is that I wanted to extend NodePath in two directions: one to support objects that can be selected by clicking on them, one to support NodePaths that can behave in a certain way (they automatically have animations defined for them). While there are a number of ways to accomplish this goal, this seemed to be the most conceptually clean.

The problem occured because I ran into the need to construct objects that were both selectable AND had these pre-generated animations. So I tried to create a new class

class MyClass(SelectClass, AnimClass):
  def __init__(self,name):
    SelectClass.__init__(self,name)
    AnimClass.__init__(self,name)

This doesn’t work because both SelectClass and AnimClass’s initializers want to call NodePath.init; Panda only lets that get called once, so it cries when I try to create one of these objects.

The solution I moved to was to break the animations out to be the responsibility of another module and leave the SelectClass intact. However, I’m all ears if someone has a suggestion as to how to accomplish the original design I’d had in mine, where one object inherits from both SelectClass and AnimClass.

Take care,
Mark

It is the same sort of problem we have struggled with in the VR Studio for years. We haven’t yet found a solution that everyone likes. By now, we just chalk it up as “one of those problems inherent with using multiple inheritance.”

David