def wrap(self): mb = self.mb # Wrap everything in the "osg" namespace osgGA = mb.namespace("osgGA") osgGA.include() # Wrap methods that begin with "osg", even if not in osg namespace mb.free_functions(lambda f: f.name.startswith('osgGA')).include() hide_nonpublic(mb) wrap_call_policies(self.mb) # linux compile error HalfWayMapGenerator.pypp.cpp:13:113: error: `HalfWayMapGenerator_wrapper` was not declared in this scope for cls_name in [ "EventQueue", "PointerData", ]: cls = osgGA.class_(cls_name) cls.wrapper_alias = cls.decl_string self.wrap_all_osg_referenced(osgGA) self.wrap_guieventadapter() self.wrap_cameramanipulator() self.wrap_standardmanipulator() # self.wrap_firstpersonmanipulator() self.wrap_manipulators() hack_osg_arg( self.mb.namespace("osgGA").class_("Device"), "sendEvent", "ea") for cls_name in [ "GUIEventHandler", ]: for fn in osgGA.class_(cls_name).member_functions( lambda f: f.name.startswith("handle")): pass # fn.exclude() fn.add_transformation( FT.modify_type(0, remove_const_from_reference)) # avoid ugly alias fn.transformations[-1].alias = fn.alias hack_osg_arg(osgGA.class_("Device"), "sendEvent", 0) fn = osgGA.class_("StateSetManipulator").member_function("handle") fn.add_transformation(FT.modify_type(0, remove_const_from_reference)) # Write results self.generate_module_code("_osgGA")
def wrap(self): mb = self.mb # Wrap everything in the "osg" namespace osgGA = mb.namespace("osgGA") osgGA.include() # Wrap methods that begin with "osg", even if not in osg namespace mb.free_functions(lambda f: f.name.startswith('osgGA')).include() hide_nonpublic(mb) wrap_call_policies(self.mb) # linux compile error HalfWayMapGenerator.pypp.cpp:13:113: error: `HalfWayMapGenerator_wrapper` was not declared in this scope for cls_name in [ "EventQueue", "PointerData", ]: cls = osgGA.class_(cls_name) cls.wrapper_alias = cls.decl_string self.wrap_all_osg_referenced(osgGA) self.wrap_guieventadapter() self.wrap_cameramanipulator() self.wrap_standardmanipulator() # self.wrap_firstpersonmanipulator() self.wrap_manipulators() hack_osg_arg( self.mb.namespace("osgGA").class_("Device"), "sendEvent", "ea") for cls_name in [ "GUIEventHandler", ]: for fn in osgGA.class_(cls_name).member_functions(lambda f: f.name.startswith("handle")): pass # fn.exclude() fn.add_transformation(FT.modify_type(0, remove_const_from_reference)) # avoid ugly alias fn.transformations[-1].alias = fn.alias hack_osg_arg(osgGA.class_("Device"), "sendEvent", 0) fn = osgGA.class_("StateSetManipulator").member_function("handle") fn.add_transformation(FT.modify_type(0, remove_const_from_reference)) # Write results self.generate_module_code("_osgGA")
def wrap_camera(self): camera = self.mb.class_("Camera") dc = camera.class_("DrawCallback") # expose_ref_ptr_class(dc) dc.constructors( arg_types=[None, None]).exclude() # copy-ish constructor # C:\boost\include\boost-1_56\boost/python/detail/destroy.hpp(33) : error C2248: 'osg::Camera::~Camera' : cannot access protected member declared in class 'osg::Camera' # Offending method is virtual void osg::Camera::DrawCallback::operator() (const osg::Camera & arg0) const call_op = dc.member_operators("operator()")[ 1] # Is it always the second "operator()"? # call_op.exclude() call_op.add_transformation( FT.modify_type("arg0", remove_const_from_reference)) call_op.transformations[-1].alias = "__call__" # Parentheses in "operator()" cause compile error on generated function name # TODO - need to rename wrapper class function name to not have "operator()" in it fn_string = call_op.transformations[-1].unique_name fn_string = fn_string.replace("operator()", "operator_call") call_op.transformations[-1].unique_name = fn_string # dc.exclude() for cls in camera.classes(lambda c: c.name.endswith("Callback")): expose_ref_ptr_class(cls) # make overridable for fn in camera.member_functions(lambda f: f.name.startswith("set") and f.name.endswith("Callback")): fn.call_policies = with_custodian_and_ward(2, 1)
def wrap(self): mb = self.mb # Wrap everything in the "osgManipulator" namespace osgManipulator = mb.namespace("osgManipulator") osgManipulator.include() mb.free_functions(lambda f: f.name.startswith("osgManipulator")).include() wrap_call_policies(self.mb) # linux compile error HalfWayMapGenerator.pypp.cpp:13:113: error: `HalfWayMapGenerator_wrapper` was not declared in this scope for cls_name in [ "CommandManager", ]: cls = osgManipulator.class_(cls_name) cls.wrapper_alias = cls.decl_string self.wrap_all_osg_referenced(osgManipulator) hide_nonpublic(mb) # cls = osgManipulator.class_("Dragger") # Putting the transformation in the correct base class can make a big difference # 1>C:\boost\include\boost-1_56\boost/python/detail/destroy.hpp(33) : error C2248: 'osgManipulator::MotionCommand::~MotionCommand' : cannot access protected member declared in class 'osgManipulator::MotionCommand' cls.member_functions("dispatch").add_transformation(FT.modify_type("command", remove_const_from_reference)) cls.member_functions("receive").add_transformation(FT.modify_type("command", remove_const_from_reference)) hack_osg_arg(cls, "handle", "arg1") # C:\boost\include\boost-1_56\boost/python/detail/destroy.hpp(33) : error C2248: 'osgGA::GUIEventAdapter::~GUIEventAdapter' : cannot access protected member declared in class 'osgGA::GUIEventAdapter' for cls in osgManipulator.classes(lambda c: c.name.endswith("Dragger")): hack_osg_arg(cls, "handle", "ea") # 2>C:\boost\include\boost-1_56\boost/python/detail/destroy.hpp(33) : error C2248: 'osgManipulator::Constraint::~Constraint' : cannot access protected member declared in class 'osgManipulator::Constraint' for cls in osgManipulator.classes(lambda c: c.name.endswith("Command")): hack_osg_arg(cls, "accept", "constraint") # many protected destructor compile errors related to "receive" method for cls in osgManipulator.classes(lambda c: c.name.endswith("Callback")): hack_osg_arg(cls, "receive", "command") hack_osg_arg(cls, "receive", "arg0") osgManipulator.class_("CompositeDragger").member_function("findDragger").exclude() self.generate_module_code('_osgManipulator')
def customize(self, mb ): def tt( type_ ): type_ = declarations.remove_reference( type_ ) type_ = declarations.remove_const( type_ ) return declarations.reference_t( type_ ) mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True mb.class_( 'Callback' ).add_wrapper_code( '//hhhh' ) execute = mb.class_( 'Callback' ).mem_fun( 'execute' ) execute.add_transformation( ft.modify_type(0, tt ) )
def customize(self, mb): def tt(type_): type_ = declarations.remove_reference(type_) type_ = declarations.remove_const(type_) return declarations.reference_t(type_) mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True mb.class_('Callback').add_wrapper_code('//hhhh') execute = mb.class_('Callback').mem_fun('execute') execute.add_transformation(ft.modify_type(0, tt))
def wrap_screencapturehandler(self): cls = self.mb.class_("ScreenCaptureHandler") # cls.member_operators("operator()").exclude() # co = cls.class_("CaptureOperation") # co.exclude() for cls_name in ["CaptureOperation", "WriteToFile", ]: wtf = cls.class_(cls_name) call_op = wtf.member_operator("operator()") call_op.add_transformation(FT.modify_type("image", remove_const_from_reference)) xform = call_op.transformations[-1] xform.alias = "__call__" xform.unique_name = xform.unique_name.replace("operator()", "operator_call")
def set_call_policies( mb ): CEGUI_ns = mb.global_ns.namespace ('CEGUI') # Set the default policy to deal with pointer/reference return types to reference_existing object # as this is the CEGUI Default. mem_funs = CEGUI_ns.calldefs () mem_funs.create_with_signature = True #Generated code will not compile on #MSVC 7.1 if function has throw modifier. for mem_fun in mem_funs: if mem_fun.call_policies: continue if declarations.is_pointer (mem_fun.return_type) or declarations.is_reference (mem_fun.return_type): mem_fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) ## OK so the CEGUI String class is ugly (from a python perspective) ## I'm going to fix the pointer arguments so you can use ctypes to use the class ## however real work is in hand_made_wrappers with a new 'assign' function for fun in CEGUI_ns.class_('String').member_functions(): arg_position = 0 for arg in fun.arguments: if declarations.type_traits.is_pointer(arg.type): # fun.add_transformation( ft.modify_type(arg_position,common_utils._ReturnUnsignedInt ), alias=fun.name ) fun.documentation = common_utils.docit ("Modified Input Argument to work with CTypes", "Argument "+arg.name+ "(pos:" + str(arg_position)\ +") takes a CTypes.adddressof(xx)", "...") break arg_position +=1 for fun in CEGUI_ns.class_('String').constructors(): arg_position = 0 for arg in fun.arguments: if declarations.type_traits.is_pointer(arg.type): fun.add_transformation( ft.modify_type(arg_position,common_utils._ReturnUnsignedInt ), alias=fun.name ) fun.documentation = common_utils.docit ("Modified Input Argument to work with CTypes", "Argument "+arg.name+ "(pos:" + str(arg_position)\ +") takes a CTypes.adddressof(xx)", "...") break arg_position +=1
def hack_osg_arg(cls, fn_name, arg_name): "Convert one const reference function argument to non-const reference" for fn in cls.member_functions(fn_name, allow_empty=True): found_arg = False for arg in fn.arguments: if arg.name == arg_name: found_arg = True break if not found_arg: continue fn.add_transformation(FT.modify_type(arg_name, remove_const_from_reference)) # avoid ugly alias fn.transformations[-1].alias = fn.alias
def hack_osg_arg(cls, fn_name, arg_name): "Convert one const reference function argument to non-const reference" for fn in cls.member_functions(fn_name, allow_empty=True): found_arg = False for arg in fn.arguments: if arg.name == arg_name: found_arg = True break if not found_arg: continue fn.add_transformation( FT.modify_type(arg_name, remove_const_from_reference)) # avoid ugly alias fn.transformations[-1].alias = fn.alias
def Fix_Void_Ptr_Args ( mb ): """ we modify functions that take void *'s in their argument list to instead take unsigned ints, which allows us to use CTypes buffers """ for fun in mb.member_functions(): arg_position = 0 for arg in fun.arguments: if declarations.type_traits.is_void_pointer(arg.type) or arg.type.decl_string == "void const *": fun.add_transformation( ft.modify_type(arg_position,_ReturnUnsignedInt ), alias=fun.name ) fun.documentation = docit ("Modified Input Argument to work with CTypes", "Argument "+arg.name+ "(pos:" + str(arg_position)\ +") takes a CTypes.adddressof(xx)", "...") print "Fixed Void Ptr", fun, arg_position break arg_position +=1 ## lets go and look for stuff that might be a problem pointee_types=['unsigned int',' int ', ' float ', ' Real ', 'uchar', 'uint8', 'unsigned char'] function_names=[] for fun in mb.member_functions(): if fun.documentation or fun.ignore: continue ## means it's been tweaked somewhere else for n in function_names: if n in fun.name: print "CHECK :", fun break arg_position = 0 for arg in fun.arguments: if declarations.is_pointer(arg.type): ## and "const" not in arg.type.decl_string: for i in pointee_types: if i in arg.type.decl_string: print '"',arg.type.decl_string, '"' print "CHECK ", fun, str(arg_position) fun.documentation=docit("SUSPECT - MAYBE BROKEN", "....", "...") break arg_position +=1 ## NEED To do the same for constructors for fun in mb.constructors(): arg_position = 0 for arg in fun.arguments: if declarations.is_pointer(arg.type): ## and "const" not in arg.type.decl_string: for i in pointee_types: if i in arg.type.decl_string: print '"',arg.type.decl_string, '"' print "Excluding: ", fun fun.exclude() break arg_position +=1
def Fix_Void_Ptr_Args ( mb ): """ we modify functions that take void *'s in their argument list to instead take unsigned ints, which allows us to use CTypes buffers """ for fun in mb.member_functions(): arg_position = 0 for arg in fun.arguments: if declarations.type_traits.is_void_pointer(arg.type): fun.add_transformation( ft.modify_type(arg_position,_ReturnUnsignedInt ) ) fun.documentation = docit ("Modified Input Argument to work with CTypes", "Argument "+arg.name+ "(pos:" + str(arg_position)\ +") takes a CTypes.adddressof(xx)", "...") #print "Fixed Void Ptr", fun, arg_position break arg_position +=1
def wrap_screencapturehandler(self): cls = self.mb.class_("ScreenCaptureHandler") # cls.member_operators("operator()").exclude() # co = cls.class_("CaptureOperation") # co.exclude() for cls_name in [ "CaptureOperation", "WriteToFile", ]: wtf = cls.class_(cls_name) call_op = wtf.member_operator("operator()") call_op.add_transformation( FT.modify_type("image", remove_const_from_reference)) xform = call_op.transformations[-1] xform.alias = "__call__" xform.unique_name = xform.unique_name.replace( "operator()", "operator_call")
def fixVoids ( fun ): arg_position = 0 trans=[] desc="" for arg in fun.arguments: if arg.type.decl_string == 'void const *' or arg.type.decl_string == 'void *': trans.append( ft.modify_type(arg_position,_ReturnUnsignedInt ) ) desc = desc +"Argument: "+arg.name+ "( pos:" + str(arg_position) +") takes a CTypes.addressof(xx). " arg_position +=1 if trans: # if fun.virtuality == "pure virtual": # print "*** WARNING: Unable to apply transformation to PURE VIRTUAL function", fun, desc # else: print ("Tranformation applied to ", fun, desc, fun.virtuality) fun.add_transformation ( * trans , **{"alias":fun.name} ) fun.documentation = docit ("Modified Input Argument to work with CTypes", desc, "...")
def ManualTransformations ( mb ): def _ReturnUnsignedInt( type_ ): """helper to return an UnsignedInt call for tranformation functions """ return declarations.cpptypes.unsigned_int_t() global_ns = mb.global_ns main_ns = global_ns def create_output( size ): return [ ft.output( i ) for i in range( size ) ] ## hack to get things working -- needs to be wrapped to handle a python call back change = ['loopSample', 'loopMusic','playSample','playMusic'] for fun in change: f = global_ns.class_('::slScheduler').mem_fun(fun) f.add_transformation( ft.modify_type('cb',_ReturnUnsignedInt ), alias=fun ) print "Changed ", f
def find_nonconst ( mb ): """ we have problems with sharedpointer arguments that are defined as references but are NOT const. Boost doesn't understand how to match them and you get a C++ Signature match fails. In reality the Ogre code probably needs to be patched as all of these should (??) be const. However we'll fix it with a function transformation wrapper """ funcs = mb.member_functions( ) for fun in funcs: arg_position = 0 for arg in fun.arguments: if 'Ptr' in arg.type.decl_string: if not 'const' in arg.type.decl_string and '&' in arg.type.decl_string: try: fun.add_transformation( ft.modify_type(arg_position,declarations.remove_reference ) ) print "Fixing Const", fun.parent.name,"::", fun.name, "::", arg_position except: print "Unable to fix const", fun.parent.name,"::", fun.name, "::", arg_position arg_position +=1
def wrap_camera(self): camera = self.mb.class_("Camera") dc = camera.class_("DrawCallback") # expose_ref_ptr_class(dc) dc.constructors(arg_types=[None, None]).exclude() # copy-ish constructor # C:\boost\include\boost-1_56\boost/python/detail/destroy.hpp(33) : error C2248: 'osg::Camera::~Camera' : cannot access protected member declared in class 'osg::Camera' # Offending method is virtual void osg::Camera::DrawCallback::operator() (const osg::Camera & arg0) const call_op = dc.member_operators("operator()")[1] # Is it always the second "operator()"? # call_op.exclude() call_op.add_transformation(FT.modify_type("arg0", remove_const_from_reference)) call_op.transformations[-1].alias = "__call__" # Parentheses in "operator()" cause compile error on generated function name # TODO - need to rename wrapper class function name to not have "operator()" in it fn_string = call_op.transformations[-1].unique_name fn_string = fn_string.replace("operator()", "operator_call") call_op.transformations[-1].unique_name = fn_string # dc.exclude() for cls in camera.classes(lambda c: c.name.endswith("Callback")): expose_ref_ptr_class(cls) # make overridable for fn in camera.member_functions(lambda f: f.name.startswith("set") and f.name.endswith("Callback")): fn.call_policies = with_custodian_and_ward(2, 1)
def customize( self, mb ): mb.global_ns.calldefs().create_with_signature = True hello_world = mb.free_fun( 'hello_world' ) hello_world.add_transformation( ft.output(0) ) calc = mb.class_('calculator_t' ) assign_funs = calc.mem_funs( lambda decl: decl.name.startswith( 'assign' ) ) assign_funs.add_transformation( ft.output(0), ft.output(1) ) clone_and_assign_5 = calc.mem_fun( 'clone_and_assign_5' ) clone_and_assign_5.add_transformation( ft.output(0) ) clone_and_assign_5.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) window = mb.class_( 'window_t' ) window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) window.mem_fun( 'resize_in_out' ).add_transformation( ft.inout(0), ft.inout(1) ) point3d = mb.class_( 'point3d_t' ) point3d.add_wrapper_code( '' ) point3d.mem_fun( 'initialize' ).add_transformation( ft.input_static_array(0, size=3) ) point3d.mem_fun( 'position' ).add_transformation( ft.output_static_array(0, size=3) ) point3d.mem_fun( 'distance' ).add_transformation( ft.output(1) ) image = mb.class_( "image_t" ) image.always_expose_using_scope = True image.member_function( "get_size" ) image.member_function( "get_size" ).add_transformation( ft.output(0), ft.output(1) ) image.member_function( "get_one_value" ).add_transformation( ft.output(0) ) image.member_function( "get_size2" ).add_transformation( ft.output(0), ft.output(1) ) image.member_function( "input_arg" ).add_transformation( ft.input(0) ) image.member_function( "fixed_input_array" ).add_transformation( ft.input_static_array(0,3) ) image.member_function( "fixed_output_array" ).add_transformation( ft.output_static_array(0,3) ) mb.free_function("get_cpp_instance").call_policies \ = call_policies.return_value_policy(call_policies.reference_existing_object) mb.variable( "cpp_instance" ).exclude() cls = mb.class_("no_virtual_members_t") cls.member_function("member").add_transformation( ft.output(0) ) cls = mb.class_("ft_private_destructor_t") cls.member_function("get_value").add_transformation( ft.output(0) ) mb.decls(lambda decl: decl.name.startswith("_")).exclude() cls = mb.class_("bug_render_target_t") cls.mem_fun("get_statistics", arg_types=['float &']*2).add_transformation( ft.output(0), ft.output(1) ) cls = mb.class_( 'modify_type_tester_t' ) do_nothing = cls.mem_fun( 'do_nothing' ) do_nothing.add_transformation( ft.modify_type(0, declarations.remove_reference ) ) clone = cls.mem_fun( 'clone' ) clone.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) clone.add_transformation( ft.modify_type(0, declarations.remove_reference ) ) cls = mb.class_( 'input_c_buffer_tester_t') write_mf = cls.mem_fun( 'write' ) write_mf.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) write_s = cls.mem_fun( 'write_s' ) write_s.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) resource = mb.class_( 'resources_t' ) resource.held_type = 'std::auto_ptr< %s >' % resource.decl_string transfer_ownership_tester = mb.class_( 'transfer_ownership_tester_t' ) tester = transfer_ownership_tester.mem_fun( 'tester' ) tester.add_transformation( ft.transfer_ownership( 0 ) ) render_queue_listener_t = mb.class_( 'render_queue_listener_t' ) render_queue_ended = render_queue_listener_t.mem_fun( 'render_queue_ended' ) render_queue_ended.add_transformation( ft.inout(2) )
def wrap(self): mb = self.mb # Wrap everything in the "osg" namespace osgDB = mb.namespace("osgDB") osgDB.include() # Wrap methods that begin with "osg", even if not in osg namespace mb.free_functions(lambda f: f.name.startswith('osgDB')).include() wrap_call_policies(self.mb) hide_nonpublic(self.mb) # linux compile error HalfWayMapGenerator.pypp.cpp:13:113: error: `HalfWayMapGenerator_wrapper` was not declared in this scope for cls_name in [ "AuthenticationDetails", "DotOsgWrapper", "DynamicLibrary", "InputException", "ObjectWrapper", "ObjectWrapperManager", "OutputException", "ReaderWriterInfo", "XmlNode", ]: cls = osgDB.class_(cls_name) cls.wrapper_alias = cls.decl_string self.wrap_all_osg_referenced(osgDB) for cls_inner in [ ["ImageOptions", "TexCoordRange"], ]: cls = osgDB.class_(cls_inner[0]).class_(cls_inner[1]) cls.held_type = 'osg::ref_ptr< %s >' % cls.decl_string # decl_string not wrapper_alias self.wrap_options() self.wrap_input() self.wrap_imagepager() self.wrap_databasepager() osgDB.class_("Output").member_function("writeObject").exclude() osgDB.class_("BaseSerializer").member_function("write").exclude() osgDB.class_("ObjectWrapper").member_function("write").exclude() osgDB.class_("Field").member_function("takeStr").exclude() hack_osg_arg(osgDB.class_("ExternalFileWriter"), "write", "obj") for fn_name in [ "getDataFilePathList", "getLibraryFilePathList", "openArchive", "readHeightFieldFile", "readImageFile", "readNodeFile", "readNodeFiles", "readObjectFile", "readShaderFile", "readXmlFile", "readXmlStream", ]: for fn in mb.free_functions(fn_name): fn.call_policies = return_value_policy( reference_existing_object) mb.free_functions("fopen").exclude() osgDB.free_functions("open").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeImageFile").exclude() # mb.free_functions("writeNodeFile").exclude() # mb.free_functions("writeObjectFile").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeHeightFieldFile").exclude() for fn_name in [ "writeHeightFieldFile", "writeImageFile", "writeNodeFile", "writeObjectFile", "writeShaderFile", ]: for fn in mb.free_functions(fn_name): fn.add_transformation( FT.modify_type(0, remove_const_from_reference)) fn.transformations[-1].alias = fn.alias # Exclude difficult classes for now for cls_name in [ "ifstream", "ofstream", "Archive", "DatabaseRevision", "DatabaseRevisions", "DeprecatedDotOsgWrapperManager", "FileCache", "FileList", # "ReaderWriter", # "Registry", "SharedStateManager", # "WriteFileCallback", ]: osgDB.classes(cls_name).exclude() osgDB.classes( lambda c: c.name.startswith("TemplateSerializer<")).exclude() for cls_name in [ "Registry", "WriteFileCallback", ]: cls = osgDB.class_(cls_name) for fn in cls.member_functions( lambda f: f.name.startswith("write")): hack_osg_arg(cls, fn.name, "obj") hack_osg_arg(cls, fn.name, "node") for cls_name in [ "ReaderWriter", ]: cls = osgDB.class_(cls_name) name_set = set() for fn in cls.member_functions( lambda f: f.name.startswith("write")): if fn.name in name_set: # Avoid duplicate function names, they will be handled anyway continue hack_osg_arg(cls, fn.name, "arg0") name_set.add(fn.name) # TODO no_init may be part of the derivable/overridable class pattern cls = osgDB.class_("ReadFileCallback") cls.no_init = False # Important! So derived class can call parent constructor cls.held_type = 'osg::ref_ptr< %s >' % cls.wrapper_alias # Important! So overridden method gets called # Write results self.generate_module_code("_osgDB")
def wrap(self): mb = self.mb # Wrap everything in the "osg" namespace osgDB = mb.namespace("osgDB") osgDB.include() # Wrap methods that begin with "osg", even if not in osg namespace mb.free_functions(lambda f: f.name.startswith('osgDB')).include() wrap_call_policies(self.mb) hide_nonpublic(self.mb) self.wrap_all_osg_referenced(osgDB) self.wrap_options() self.wrap_input() self.wrap_imagepager() self.wrap_databasepager() osgDB.class_("Output").member_function("writeObject").exclude() osgDB.class_("BaseSerializer").member_function("write").exclude() osgDB.class_("ObjectWrapper").member_function("write").exclude() osgDB.class_("Field").member_function("takeStr").exclude() hack_osg_arg(osgDB.class_("ExternalFileWriter"), "write", "obj") for fn_name in [ "getDataFilePathList", "getLibraryFilePathList", "openArchive", "readHeightFieldFile", "readImageFile", "readNodeFile", "readNodeFiles", "readObjectFile", "readShaderFile", "readXmlFile", "readXmlStream", ]: for fn in mb.free_functions(fn_name): fn.call_policies = return_value_policy(reference_existing_object) mb.free_functions("fopen").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeImageFile").exclude() # mb.free_functions("writeNodeFile").exclude() # mb.free_functions("writeObjectFile").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeHeightFieldFile").exclude() for fn_name in [ "writeHeightFieldFile", "writeImageFile", "writeNodeFile", "writeObjectFile", "writeShaderFile", ]: for fn in mb.free_functions(fn_name): fn.add_transformation(FT.modify_type(0, remove_const_from_reference)) fn.transformations[-1].alias = fn.alias # Exclude difficult classes for now for cls_name in [ "Archive", "DatabaseRevision", "DatabaseRevisions", "DeprecatedDotOsgWrapperManager", "FileCache", "FileList", # "ReaderWriter", # "Registry", "SharedStateManager", # "WriteFileCallback", ]: osgDB.classes(cls_name).exclude() osgDB.classes(lambda c: c.name.startswith("TemplateSerializer<")).exclude() for cls_name in ["Registry", "WriteFileCallback", ]: cls = osgDB.class_(cls_name) for fn in cls.member_functions(lambda f: f.name.startswith("write")): hack_osg_arg(cls, fn.name, "obj") hack_osg_arg(cls, fn.name, "node") for cls_name in ["ReaderWriter", ]: cls = osgDB.class_(cls_name) name_set = set() for fn in cls.member_functions(lambda f: f.name.startswith("write")): if fn.name in name_set: # Avoid duplicate function names, they will be handled anyway continue hack_osg_arg(cls, fn.name, "arg0") name_set.add(fn.name) # TODO no_init may be part of the derivable/overridable class pattern cls = osgDB.class_("ReadFileCallback") cls.no_init = False # Important! So derived class can call parent constructor cls.held_type = 'osg::ref_ptr< %s >' % cls.wrapper_alias # Important! So overridden method gets called self.mb.build_code_creator(module_name='_osgDB') self.mb.split_module(os.path.join(os.path.abspath('.'), 'generated_code')) # Create a file to indicate completion of wrapping script open(os.path.join(os.path.abspath('.'), 'generated_code', 'generate_module.stamp'), "w").close()
def customize( self, mb ): mb.global_ns.calldefs().create_with_signature = True hello_world = mb.free_fun( 'hello_world' ) hello_world.add_transformation( ft.output(0) ) calc = mb.class_('calculator_t' ) assign_funs = calc.mem_funs( lambda decl: decl.name.startswith( 'assign' ) ) assign_funs.add_transformation( ft.output(0), ft.output(1) ) clone_and_assign_5 = calc.mem_fun( 'clone_and_assign_5' ) clone_and_assign_5.add_transformation( ft.output(0) ) clone_and_assign_5.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) window = mb.class_( 'window_t' ) window.mem_fun( 'resize' ).add_transformation( ft.input(0), ft.input(1) ) window.mem_fun( 'resize_in_out' ).add_transformation( ft.inout(0), ft.inout(1) ) point3d = mb.class_( 'point3d_t' ) point3d.add_wrapper_code( '' ) point3d.mem_fun( 'initialize' ).add_transformation( ft.input_static_array(0, size=3) ) point3d.mem_fun( 'position' ).add_transformation( ft.output_static_array(0, size=3) ) distance = point3d.mem_fun( 'distance' ) distance.add_transformation( ft.output(1) ) distance.transformations[0].controller.add_pre_call_code( '//dddddddddddddd' ) distance.transformations[0].controller.add_post_call_code( '//qqqqqqqqqqqqq' ) image = mb.class_( "image_t" ) image.always_expose_using_scope = True image.member_function( "get_size" ) image.member_function( "get_size" ).add_transformation( ft.output(0), ft.output(1) ) image.member_function( "get_one_value" ).add_transformation( ft.output(0) ) image.member_function( "get_size2" ).add_transformation( ft.output(0), ft.output(1) ) image.member_function( "input_arg" ).add_transformation( ft.input(0) ) image.member_function( "fixed_input_array" ).add_transformation( ft.input_static_array(0,3) ) image.member_function( "fixed_output_array" ).add_transformation( ft.output_static_array(0,3) ) mb.free_function("get_cpp_instance").call_policies \ = call_policies.return_value_policy(call_policies.reference_existing_object) mb.variable( "cpp_instance" ).exclude() cls = mb.class_("no_virtual_members_t") cls.member_function("member").add_transformation( ft.output(0) ) cls = mb.class_("ft_private_destructor_t") cls.member_function("get_value").add_transformation( ft.output(0) ) mb.decls(lambda decl: decl.name.startswith("_")).exclude() cls = mb.class_("bug_render_target_t") cls.mem_fun("get_statistics", arg_types=['float &']*2).add_transformation( ft.output(0), ft.output(1) ) cls = mb.class_( 'modify_type_tester_t' ) do_nothing = cls.mem_fun( 'do_nothing' ) do_nothing.add_transformation( ft.modify_type(0, declarations.remove_reference ) ) clone = cls.mem_fun( 'clone' ) clone.call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) clone.add_transformation( ft.modify_type(0, declarations.remove_reference ) ) cls = mb.class_( 'input_c_buffer_tester_t') write_mf = cls.mem_fun( 'write' ) write_mf.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) write_s = cls.mem_fun( 'write_s' ) write_s.add_transformation( ft.input_c_buffer( 'buffer', 'size' ) ) resource = mb.class_( 'resources_t' ) resource.held_type = 'std::auto_ptr< %s >' % resource.decl_string transfer_ownership_tester = mb.class_( 'transfer_ownership_tester_t' ) tester = transfer_ownership_tester.mem_fun( 'tester' ) tester.add_transformation( ft.transfer_ownership( 0 ) ) render_queue_listener_t = mb.class_( 'render_queue_listener_t' ) render_queue_ended = render_queue_listener_t.mem_fun( 'render_queue_ended' ) render_queue_ended.add_transformation( ft.inout(2) ) ft_bugs = mb.namespace( 'ft_bugs' ) h = ft_bugs.mem_fun( 'h' ) h.add_transformation( ft.modify_type(0, remove_const_ref ) ) h.call_policies = call_policies.return_internal_reference() h2 = ft_bugs.mem_fun( 'h2' ) h2.add_transformation( ft.modify_type(0, remove_const_ref ) ) h2.call_policies = call_policies.return_internal_reference() ft_bugs.class_( 'B' ).always_expose_using_scope = True ft_bugs.mem_fun( 'get_a' ).call_policies \ = call_policies.return_value_policy( call_policies.reference_existing_object ) ft_bugs2 = mb.namespace( 'ft_bugs2' ) g = ft_bugs2.mem_fun( 'g' ) g.add_transformation( ft.modify_type(0, remove_const_ref ) ) g.call_policies = call_policies.return_internal_reference()
def wrap(self): mb = self.mb # Wrap everything in the "osg" namespace osgDB = mb.namespace("osgDB") osgDB.include() # Wrap methods that begin with "osg", even if not in osg namespace mb.free_functions(lambda f: f.name.startswith('osgDB')).include() wrap_call_policies(self.mb) hide_nonpublic(self.mb) # linux compile error HalfWayMapGenerator.pypp.cpp:13:113: error: `HalfWayMapGenerator_wrapper` was not declared in this scope for cls_name in [ "AuthenticationDetails", "DotOsgWrapper", "DynamicLibrary", "InputException", "ObjectWrapper", "ObjectWrapperManager", "OutputException", "ReaderWriterInfo", "XmlNode", ]: cls = osgDB.class_(cls_name) cls.wrapper_alias = cls.decl_string self.wrap_all_osg_referenced(osgDB) for cls_inner in [ ["ImageOptions","TexCoordRange"], ]: cls = osgDB.class_(cls_inner[0]).class_(cls_inner[1]) cls.held_type = 'osg::ref_ptr< %s >' % cls.decl_string # decl_string not wrapper_alias self.wrap_options() self.wrap_input() self.wrap_imagepager() self.wrap_databasepager() osgDB.class_("Output").member_function("writeObject").exclude() osgDB.class_("BaseSerializer").member_function("write").exclude() osgDB.class_("ObjectWrapper").member_function("write").exclude() osgDB.class_("Field").member_function("takeStr").exclude() hack_osg_arg(osgDB.class_("ExternalFileWriter"), "write", "obj") for fn_name in [ "getDataFilePathList", "getLibraryFilePathList", "openArchive", "readHeightFieldFile", "readImageFile", "readNodeFile", "readNodeFiles", "readObjectFile", "readShaderFile", "readXmlFile", "readXmlStream", ]: for fn in mb.free_functions(fn_name): fn.call_policies = return_value_policy(reference_existing_object) mb.free_functions("fopen").exclude() osgDB.free_functions("open").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeImageFile").exclude() # mb.free_functions("writeNodeFile").exclude() # mb.free_functions("writeObjectFile").exclude() # mb.free_functions("writeShaderFile").exclude() # mb.free_functions("writeHeightFieldFile").exclude() for fn_name in [ "writeHeightFieldFile", "writeImageFile", "writeNodeFile", "writeObjectFile", "writeShaderFile", ]: for fn in mb.free_functions(fn_name): fn.add_transformation(FT.modify_type(0, remove_const_from_reference)) fn.transformations[-1].alias = fn.alias # Exclude difficult classes for now for cls_name in [ "ifstream", "ofstream", "Archive", "DatabaseRevision", "DatabaseRevisions", "DeprecatedDotOsgWrapperManager", "FileCache", "FileList", # "ReaderWriter", # "Registry", "SharedStateManager", # "WriteFileCallback", ]: osgDB.classes(cls_name).exclude() osgDB.classes(lambda c: c.name.startswith("TemplateSerializer<")).exclude() for cls_name in ["Registry", "WriteFileCallback", ]: cls = osgDB.class_(cls_name) for fn in cls.member_functions(lambda f: f.name.startswith("write")): hack_osg_arg(cls, fn.name, "obj") hack_osg_arg(cls, fn.name, "node") for cls_name in ["ReaderWriter", ]: cls = osgDB.class_(cls_name) name_set = set() for fn in cls.member_functions(lambda f: f.name.startswith("write")): if fn.name in name_set: # Avoid duplicate function names, they will be handled anyway continue hack_osg_arg(cls, fn.name, "arg0") name_set.add(fn.name) # TODO no_init may be part of the derivable/overridable class pattern cls = osgDB.class_("ReadFileCallback") cls.no_init = False # Important! So derived class can call parent constructor cls.held_type = 'osg::ref_ptr< %s >' % cls.wrapper_alias # Important! So overridden method gets called # Write results self.generate_module_code("_osgDB")
def Auto_Functional_Transformation ( mb, ignore_funs=[], special_vars=[]): toprocess = [] aliases={} for fun in mb.member_functions(allow_empty=True): toprocess.append( fun ) for fun in mb.free_functions(allow_empty=True): toprocess.append( fun ) for fun in toprocess: fun_demangled = fun.demangled # need to check as extern functions don't have demangled name... if fun_demangled: # try: # ugly wrapping in a try :( fullname = fun.demangled.split('(')[0] if fullname not in ignore_funs and not fun.ignore: outputonly = False arg_position = 0 trans=[] desc="" ft_type = None ctypes_conversion = False for arg in fun.arguments: rawarg = declarations.remove_declarated( declarations.remove_const( declarations.remove_reference( declarations.remove_pointer ( arg.type )))) ## now check if the arg is a fundemental type (int float etc), a void ## or a special .. if declarations.is_arithmetic (rawarg)\ or declarations.is_void(rawarg)\ or arg.type.decl_string in special_vars: if declarations.is_pointer(arg.type): #we convert any pointers to unsigned int's # now look to see if it's a char * and if so we treat it as a string.. # # print "**" , declarations.remove_alias( rawarg ), declarations.type_traits.create_cv_types( declarations.cpptypes.char_t()) if declarations.remove_alias( rawarg ) in declarations.type_traits.create_cv_types( declarations.cpptypes.char_t() ): print ("MATCHED CString", fun) trans.append( ft.input_c_string(arg_position, 4096 ) ) desc = desc +"Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\ arg.type.decl_string + " ) takes a python string. \\n" ctypes_conversion = True ctypes_arg = arg.type.decl_string.split()[0] ft_type = 'CTYPES' else: trans.append( ft.modify_type(arg_position,_ReturnUnsignedInt ) ) desc = desc +"Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\ arg.type.decl_string + " ) takes a CTypes.addressof(xx). \\n" ctypes_conversion = True ctypes_arg = arg.type.decl_string.split()[0] ft_type = 'CTYPES' elif declarations.is_reference(arg.type)and not declarations.is_const(declarations.remove_reference( arg.type)): # seen functions passing const ref's trans.append( ft.inout(arg_position ) ) desc = desc + "Argument: "+arg.name+ "( pos:" + str(arg_position) + " - " +\ arg.type.decl_string + " ) converted to an input/output (change to return types).\\n" ft_type = 'INOUT' elif declarations.is_reference(arg.type): print ("Warning: - possible code change.", fun,arg," not wrapped as const reference to base type invalid") else: pass # it isn't a pointer or reference so doesn't need wrapping else: pass # it's not a var we need to handle arg_position += 1 if trans: const_return = False # declarations.is_const(fun) if fun.decl_string.endswith('const'): const_return=True simple_return = declarations.is_arithmetic(fun.return_type) or declarations.is_void(fun.return_type) nonpublic_destructor = declarations.is_class(fun.parent) and declarations.has_destructor(fun.parent) and\ not declarations.has_public_destructor(fun.parent) if fun.documentation or fun.transformations: # it's already be tweaked: print ("AUTOFT ERROR: Duplicate Tranforms.", fun, fun.documentation) # if the class has a protected destruction AND the return value is const or a non arithmatic value then exclude it. elif nonpublic_destructor and const_return: print ("AUTOFT ERROR Const: Parent has non public destructor and const return.", fun.parent.name, fun.return_type.decl_string, fun) fun.documentation="Python-Ogre Warning: function required transformation - not possible due to non public destructor and const return value.." elif nonpublic_destructor and not simple_return: print ("AUTOFT ERROR Const: Parent has non public destructor and complex return value.", fun.parent.name, fun.return_type.decl_string, fun) fun.documentation="Python-Ogre Warning: function required transformation - not possible due to non public destructor and complex return value.." else: new_alias = fun.name if ctypes_conversion: # only manage name changes if ctypes changing # now lets look for a duplicate function name with the same number arguments f= [None]*len(fun.arguments) s = mb.member_functions("::" + fullname, arg_types=f, allow_empty=True) if len (s) > 1: # there are duplicate names so need to create something unique ctypes_arg = ctypes_arg.replace("::", "_") # to clean up function names... new_alias = fun.name + ctypes_arg[0].upper() + ctypes_arg[1:] # now for REAL ugly code -- we have faked a new alias and it may not be unique # so we track previous alias + class name to ensure unique names are generated keyname = fullname + new_alias # we use the full class + function name + alias as the key if keyname in aliases: # already exists, need to fake another version.. new_alias = new_alias + "_" + str( aliases[keyname] ) aliases[keyname] = aliases[keyname] + 1 else: aliases[keyname] = 1 desc = desc + "\\\nWARNING FUNCTION NAME CHANGE - from "+fun.name + " -- " + fun.decl_string +" to " + new_alias + " \\n" print ("INFO: Adjusting Alias as multiple overlapping functions:", new_alias) print ("AUTOFT OK: Tranformed ", fun.return_type.decl_string, fun, "(",new_alias,")") fun.add_transformation ( * trans , **{"alias":new_alias} ) fun.documentation = docit ("Auto Modified Arguments:", desc, "...")
def customize(self, mb): mb.global_ns.calldefs().create_with_signature = True hello_world = mb.free_fun("hello_world") hello_world.add_transformation(ft.output(0)) calc = mb.class_("calculator_t") assign_funs = calc.mem_funs(lambda decl: decl.name.startswith("assign")) assign_funs.add_transformation(ft.output(0), ft.output(1)) clone_and_assign_5 = calc.mem_fun("clone_and_assign_5") clone_and_assign_5.add_transformation(ft.output(0)) clone_and_assign_5.call_policies = call_policies.return_value_policy(call_policies.manage_new_object) window = mb.class_("window_t") window.mem_fun("resize").add_transformation(ft.input(0), ft.input(1)) window.mem_fun("resize_in_out").add_transformation(ft.inout(0), ft.inout(1)) point3d = mb.class_("point3d_t") point3d.add_wrapper_code("") point3d.mem_fun("initialize").add_transformation(ft.input_static_array(0, size=3)) point3d.mem_fun("position").add_transformation(ft.output_static_array(0, size=3)) point3d.mem_fun("distance").add_transformation(ft.output(1)) image = mb.class_("image_t") image.always_expose_using_scope = True image.member_function("get_size") image.member_function("get_size").add_transformation(ft.output(0), ft.output(1)) image.member_function("get_one_value").add_transformation(ft.output(0)) image.member_function("get_size2").add_transformation(ft.output(0), ft.output(1)) image.member_function("input_arg").add_transformation(ft.input(0)) image.member_function("fixed_input_array").add_transformation(ft.input_static_array(0, 3)) image.member_function("fixed_output_array").add_transformation(ft.output_static_array(0, 3)) mb.free_function("get_cpp_instance").call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) mb.variable("cpp_instance").exclude() cls = mb.class_("no_virtual_members_t") cls.member_function("member").add_transformation(ft.output(0)) cls = mb.class_("ft_private_destructor_t") cls.member_function("get_value").add_transformation(ft.output(0)) mb.decls(lambda decl: decl.name.startswith("_")).exclude() cls = mb.class_("bug_render_target_t") cls.mem_fun("get_statistics", arg_types=["float &"] * 2).add_transformation(ft.output(0), ft.output(1)) cls = mb.class_("modify_type_tester_t") do_nothing = cls.mem_fun("do_nothing") do_nothing.add_transformation(ft.modify_type(0, declarations.remove_reference)) clone = cls.mem_fun("clone") clone.call_policies = call_policies.return_value_policy(call_policies.manage_new_object) clone.add_transformation(ft.modify_type(0, declarations.remove_reference)) cls = mb.class_("input_c_buffer_tester_t") write_mf = cls.mem_fun("write") write_mf.add_transformation(ft.input_c_buffer("buffer", "size")) write_s = cls.mem_fun("write_s") write_s.add_transformation(ft.input_c_buffer("buffer", "size")) resource = mb.class_("resources_t") resource.held_type = "std::auto_ptr< %s >" % resource.decl_string transfer_ownership_tester = mb.class_("transfer_ownership_tester_t") tester = transfer_ownership_tester.mem_fun("tester") tester.add_transformation(ft.transfer_ownership(0)) render_queue_listener_t = mb.class_("render_queue_listener_t") render_queue_ended = render_queue_listener_t.mem_fun("render_queue_ended") render_queue_ended.add_transformation(ft.inout(2))