Casting references returned from interrogate

I have a function in C that returns a pointer to an interface class. The pointer is referencing an instance to a child class that inherits from that interface. The script knows what child class is actually being returned. But when I try to access a member of the child class it complains: "object has no attribute ‘foo’. Is there a way to tell python what child type the reference is pointing to? I see some symbols in the igate file for upcasting and downcasting. Can you use those in python script somehow? I appreciate your help. Thanks

We don’t have an interface for you to do an on-demand downcast like that, although it probably wouldn’t be hard to provide one (though it would be dangerous, of course). But you can ensure that the downcast happens automatically if you integrate with Panda’s run-time typing mechanism.

To do this, you should inherit from TypedObject, and then define the boilerplate init_type(), get_class_type(), get_type(), etc. methods in your class, as you can see in numerous examples throughout the Panda3D source code. We put lines like this in the bottom of the class definition:

public:
  static TypeHandle get_class_type() {
    return _type_handle;
  }
  static void init_type() {
    PandaNode::init_type();
    register_type(_type_handle, "GeomNode",
                  PandaNode::get_class_type());
  }
  virtual TypeHandle get_type() const {
    return get_class_type();
  }
  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}

private:
  static TypeHandle _type_handle;

Of course, you also have to declare the _type_handle declaration in your .cpp file, since it’s a static data member.

The parameters to register_type() after _type_handle are the name of this class (which must match your actual class name), and the list of (typed) base classes it directly inherits from. If you multiply inherit from one or more untyped base classes as well as your typed classes, you don’t have to mention the untyped classes; and by typed class, I mean one that inherits from TypedObject and defines all this stuff. Note that we ensure that the base classes have already been initialized by calling init_type() on them explicitly.

And then ensure that your new class’s init_type() method is called at application start (we have a call in config_foo.cxx, e.g. config_pgraph.cxx, to init all of the types defined in each module).

That’s pretty much it. If you do this, in the interface class and in each of your child classes, then interrogate will automatically downcast your returned instance to the appropriate Python wrapper.

David

Thanks again David. Again I wish the interrogate and pandac side of things were documented more. Would probably save you alot of time replying to posts like this =)

True enough. Of course, you’re the first person outside of the VR Studio to foray into third-party C++/Panda/Python integration.

Perhaps you’d be up for putting a new section in the manual about the process, now that you’re learning how it’s done, for the benefit of those who will come after you? :slight_smile:

David

:smiley: Its definately a possibility.