On 9/7/06, Allen Bierbaum <abierbaum@gmail.com> wrote:
On 9/7/06, Alex Mohr <amohr@pixar.com> wrote:
The non-obvious part of this for me is:
- Does this mean that I now need to explicitly wrap (expose using bp::class_ ) all the ref_ptr<> types?
I haven't had to do that thus far because it was handled internally somehow because I used it has the held_type for all my classes. If I expose them manually do I run the risk of breaking any of the held_type functionality?
I'm not sure what you mean... If ref_ptr<T> is the held type for T, then just provide __eq__ in terms of ref_ptr<T>...
template <class T> static bool ref_ptr_eq(ref_ptr<T> const &self, ref_ptr<T> const &other) { return self == other; }
class_<T, ... ref_ptr<T> ... >(...) .def("__eq__", ref_ptr_eq<T>) ;
Am I misunderstanding your situation?
Ahhh....
No I see what you are meaning. So I need the __eq__ op on the class itself. Ok. That makes more sense. I thought I may have to wrap the ref_ptr<T> as a class a and put the __eq__ op on it.
Something like:
class_<ref_ptr<T>, ..>(..) .def("__eq__", ref_ptr_eq<T>) ;
Thanks for the feedback. I will try your method out and reply to the list with the results so other people following along can see what ended up working.
(I apologize for the length of this e-mail, I just want to make sure I describe everything in case there is something basic I am missing) This did not work out well. It still has major problems because: - Object allocated in python, passed to C++, and then returned from C++ can't be compared - Objects can't be compared to None anymore Here is what I have done so far, if anyone has suggestions please let me know (code generated from py++). This is a combination of all the ideas discussed in this thread. You will notice that instead of defining an __eq__ I defined __cmp__ so all the comparison operations would work. typedef ::boost::python::class_< Group_wrapper, ::boost::python::bases< ::osg::GroupBase >, OSG::GroupRefPtr, ::boost::noncopyable > Group_exposer_t; Group_exposer_t Group_exposer = Group_exposer_t( "Group", ::boost::python::no_init ); ... Group_exposer.def("__cmp__",pyopensg::cmp_ref_ptrs<OSG::GroupRefPtr>); Group_exposer.def("__hash__",pyopensg::hash_ref_ptr<OSG::GroupRefPtr>); register_fcptr_to_python<RefPtrType>::execute(); fcptr_from_python<typename RefPtrType::FCPtrType>(); bp::implicitly_convertible< OSG::GroupRefPtr, OSG::GroupPtr >(); bp::implicitly_convertible< OSG::GroupRefPtr, OSG::NodeCoreRefPtr >(); } } // Helpers are attached to the mail There is also a class Node involved in the example code below. In the example I use two methods from there: void Node::setCore(ptr<Base>); ptr<Base> Node::getCore(); Here is some code that shows the problems
g = osg.Group.create() g2 = osg.Group.create() g3 = g g == g2 False g == g3 True hash(g) 163 hash(g2) 164 n = osg.Node.create() n.setCore(g) core_g = n.getCore() core_g <osg._osg.Group object at 0xafbf722c> g <osg._osg.Group object at 0xb781fdac>
// Next line shows problem where the object coming back // out of C++ can't be compared. It is like it thinks it has // a different type.
g == core_g Traceback (most recent call last): File "<input>", line 1, in ? ArgumentError: Python argument types in Group.__cmp__(Group, Group) did not match C++ signature: __cmp__(osg::RefPtr<osg::FCPtr<osg::FCPtr<osg::AttachmentContainerPtr, osg::NodeCore>, osg::Group> >, osg::RefPtr<osg::FCPtr<osg::FCPtr<osg::AttachmentContainerPtr, osg::NodeCore>, osg::Group> >)
// This line shows the same problem with __hash__
hash(core_g) Traceback (most recent call last): File "<input>", line 1, in ? ArgumentError: Python argument types in Group.__hash__(Group) did not match C++ signature: __hash__(osg::RefPtr<osg::FCPtr<osg::FCPtr<osg::AttachmentContainerPtr, osg::NodeCore>, osg::Group> >)
// And here is the problem comparing to None
g == None Traceback (most recent call last): File "<input>", line 1, in ? ArgumentError: Python argument types in Group.__cmp__(Group, NoneType) did not match C++ signature: __cmp__(osg::RefPtr<osg::FCPtr<osg::FCPtr<osg::AttachmentContainerPtr, osg::NodeCore>, osg::Group> >, osg::RefPtr<osg::FCPtr<osg::FCPtr<osg::AttachmentContainerPtr, osg::NodeCore>, osg::Group> >)
I am at a loss to see what is causing this signature problem. I don't know of any way to ask boost.python to give me the "signature" of python object at run-time, so I can't compare this signature with the "good" signatures that work above. From what I see though they look very much the same. I am going to try to trace back through the mailing list and look for the object identity discussions you mentioned. Maybe something in those threads will provide a workaround that I can use. As always, feel free to tell me if something looks way off. Thanks, Allen