Here is some code. The main idea is that I don't want to expose each derived module classes but only the interface IModule that contains all the necessary information at run-time.
The following code is actually working but produces the following warning: to-Python converter for class ModuleConfiguration already registered; second conversion method ignored This sounds normal as the class is exposed each time a new instance of MyModule or MySecondModule is created. // Dummy class for test class IModule : public Vx::VxInputOutputInterface { public: IModule() {} }; class ModuleConfiguration { public: ModuleConfiguration(IModule& iProxy); IModule& mProxy; }; template<typename T> struct GetParameterFunctor; template<> struct GetParameterFunctor<int> { GetParameterFunctor(const std::string& iName) : mName(iName) { } int operator()(ModuleConfiguration* iProxy) { return iProxy->mProxy.getParameter(mName).getFieldBase().toInteger(); } std::string mName; }; template<typename T> struct SetParameterFunctor { SetParameterFunctor(const std::string& iName) : mName(iName) { } int operator()(ModuleConfiguration* iProxy, T iValue) { return iProxy->mProxy.getParameter(mName).setValue(iValue); } std::string mName; }; namespace boostVx { namespace python { namespace detail { boostVx::mpl::vector<int, ModuleConfiguration*> get_signature(boostVx::function<int (ModuleConfiguration*)>, ModuleConfiguration*) { return boostVx::mpl::vector<int, ModuleConfiguration*>(); } boostVx::mpl::vector<int, ModuleConfiguration*, int> get_signature(boostVx::function<int (ModuleConfiguration*, int)>, ModuleConfiguration*) { return boostVx::mpl::vector<int, ModuleConfiguration*, int>(); } } } } class CreateGetParameterFieldVisitor : public VxData::FieldVisitor { public: CreateGetParameterFieldVisitor(boostVx::python::class_<ModuleConfiguration>& iPythonConfigurationWrapper) : mPythonConfigurationWrapper(iPythonConfigurationWrapper) {} virtual void visit(VxData::Field<int>& i_field) { GetParameterFunctor<int> getP(i_field.getID().asString()); SetParameterFunctor<int> setP(i_field.getID().asString()); mPythonConfigurationWrapper.add_property(i_field.getID().asString(), boostVx::function<int (ModuleConfiguration*)>(getP), boostVx::function<int (ModuleConfiguration*, int)>(setP)); } private: boostVx::python::class_<ModuleConfiguration>& mPythonConfigurationWrapper; }; ModuleConfiguration::ModuleConfiguration(IModule& iProxy) : mProxy(iProxy) { boostVx::python::class_<ModuleConfiguration> pythonConfigurationWrapper("ModuleConfiguration", boostVx::python::no_init); CreateGetParameterFieldVisitor visitor(pythonConfigurationWrapper); const_cast<VxData::Container&>(mProxy.getParameterContainer()).accept(visitor); } class ModuleWrapperInterface { public: ModuleWrapperInterface(IModule* iProxy) : mProxy(iProxy) , mConfiguration(*iProxy) { } ModuleConfiguration& getModuleConfiguration() { return mConfiguration; } private: IModule* mProxy; ModuleConfiguration mConfiguration; }; class MyModule : public IModule { public: MyModule() : mThreshold(5, "threshold", this) , mCeil(10, "ceil", this) { } const char* getClassName() const { return "MyModule"; } private: Vx::VxParameter<int> mThreshold; Vx::VxParameter<int> mCeil; }; class MySecondModule : public IModule { public: MySecondModule() : mTorque(120, "torque", this) { } const char* getClassName() const { return "MySecondModule"; } private: Vx::VxParameter<int> mTorque; }; boostVx::shared_ptr<ModuleWrapperInterface> createModule(const std::string& iName) { if( iName == "first" ) return boostVx::shared_ptr<ModuleWrapperInterface>(new ModuleWrapperInterface(new MyModule()), NullDeleter()); else if( iName == "second" ) return boostVx::shared_ptr<ModuleWrapperInterface>(new ModuleWrapperInterface(new MySecondModule()), NullDeleter()); else { std::cerr << "No module with name " << iName << " found, returning MyModule." << std::endl; return boostVx::shared_ptr<ModuleWrapperInterface>(new ModuleWrapperInterface(new MyModule()), NullDeleter()); } } BOOST_PYTHON_MODULE(Modules) { boostVx::python::class_<ModuleWrapperInterface, boostVx::shared_ptr<ModuleWrapperInterface>, boostVx::noncopyable>("ModuleInterface", boostVx::python::no_init) .def("getParameters", &ModuleWrapperInterface::getModuleConfiguration, boostVx::python::return_internal_reference<>() ); boostVx::python::def("createModule", &createModule); } -- Christophe Tornieri Tech Lead, Software Architect Sub-sea division christophe.torni...@cm-labs.com http://www.vxsim.com/
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig