[ create a new paste ] login | about

Link: http://codepad.org/wq47m5CI    [ raw code | fork ]

C++, pasted on Dec 27:
#include <osg/ref_ptr>
#include <osg/Referenced>

#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/class.hpp>
#include <boost/python/call_method.hpp>
#include <boost/python/wrapper.hpp>
#include <iostream>

using namespace boost::python;

/**
 * Contrived model of the 3rd-party lib
 */
class VisitorBase : public osg::Referenced {
public:
  virtual const char* name(){  return "VisitorBase";  }
protected :
  virtual ~VisitorBase(){};
};

class DerivedVisitor : public VisitorBase {
public:
  virtual const char* name(){  return "DerivedVisitor";  }
protected :
  virtual ~DerivedVisitor(){};
};

class HelperVisitor : public VisitorBase {
public:
  virtual const char* name(){  return "HelperVisitor";  }
protected :
  virtual ~HelperVisitor(){};
};

class Node {
public:
  virtual void apply( VisitorBase& b ){ 
    std::cerr<<" ( C++ ) Hi my name is "<< b.name() << std::endl ;
  }
};

void check_their_identification( Node& n, VisitorBase& b){
  n.apply( b );
  
  osg::ref_ptr<HelperVisitor> helper = osg::ref_ptr<HelperVisitor>( new HelperVisitor );
  n.apply( *helper );
}

/**
 * This is where the pybindings start
 */

namespace boost { 
namespace python {
  template <class T> struct pointee< osg::ref_ptr<T> >
  {
     typedef T type;
  };
}
}

struct VisitorBase_wrapper : VisitorBase, wrapper<VisitorBase> {
 
  VisitorBase_wrapper( PyObject* o ) : self( o ), VisitorBase() {};
  VisitorBase_wrapper( PyObject* o , const VisitorBase& b) : self( o ), VisitorBase(b) {};

  const char* name(){ 
    if( override name = this->get_override("name") ) return name();
    else  return VisitorBase::name();
  }
  const char* default_name(){  return this->VisitorBase::name();  }

private:
  PyObject* self;
};

struct Node_wrapper : Node, wrapper<Node> {

  void apply( VisitorBase& b ){
    if( override apply = this->get_override("apply") ) {
      // This slices all objects to VisitorBase
      apply( b ); 
      // This fails for objects that are not wrapped
      //apply( boost::ref(b) ); 
    }
    else Node::apply( b );
  }
  void default_apply( VisitorBase& b ){ this->Node::apply( b ); }

};

BOOST_PYTHON_MODULE(boost_python_and_ref_ptr)
{

  class_<osg::Referenced, osg::ref_ptr<osg::Referenced> >("Referenced");
 
  // the order here is important
  // VisitorBase_wrapper *must* come before ref_ptr<VisitorBase>
  class_<VisitorBase, bases<osg::Referenced>, VisitorBase_wrapper, osg::ref_ptr<VisitorBase> >("VisitorBase")
    .add_property("name", &VisitorBase_wrapper::default_name)
    ;
  
  class_<DerivedVisitor, bases<VisitorBase>, osg::ref_ptr<DerivedVisitor> >("DerivedVisitor")
    .add_property("name", &DerivedVisitor::name)
    ;
  
  class_<Node_wrapper, boost::noncopyable>("Node")
    .def("apply", &Node::apply, &Node_wrapper::default_apply)
    ;

  def("check_their_identification", &check_their_identification );
  
}


Create a new paste based on this one


Comments: