def ParseClient(self, mb): # Free functions that don't start with 'UTIL_' mb.free_functions("ScreenHeight").include() mb.free_functions("ScreenWidth").include() mb.free_functions("GetVectorInScreenSpace").include() mb.free_functions("GetTargetInScreenSpace").include() # Main view mb.free_function("MainViewOrigin").include() mb.free_function("MainViewAngles").include() mb.free_function("MainViewForward").include() mb.free_function("MainViewRight").include() mb.free_function("MainViewUp").include() mb.free_function("MainWorldToViewMatrix").include() # Call policies and excludes if self.settings.branch == "swarm": mb.free_function("UTIL_GetLocalizedKeyString").exclude() mb.free_function("UTIL_MessageText").exclude() mb.free_functions("UTIL_EntityFromUserMessageEHandle").call_policies = call_policies.return_value_policy( call_policies.return_by_value ) mb.free_functions("UTIL_PlayerByUserId").call_policies = call_policies.return_value_policy( call_policies.return_by_value ) # Transformations mb.free_functions("GetVectorInScreenSpace").add_transformation(FT.output("iX"), FT.output("iY")) mb.free_functions("GetTargetInScreenSpace").add_transformation(FT.output("iX"), FT.output("iY"))
def ParseClient(self, mb): # A simple class for python to use projected textures mb.class_('ProjectedTexture').include() # Free functions that don't start with 'UTIL_' mb.free_functions('ScreenHeight').include() mb.free_functions('ScreenWidth').include() mb.free_functions('GetVectorInScreenSpace').include() mb.free_functions('GetTargetInScreenSpace').include() # Main view mb.free_function('MainViewOrigin').include() mb.free_function('MainViewAngles').include() mb.free_function('MainViewForward').include() mb.free_function('MainViewRight').include() mb.free_function('MainViewUp').include() mb.free_function('MainWorldToViewMatrix').include() # Call policies and excludes if settings.ASW_CODE_BASE: mb.free_function('UTIL_GetLocalizedKeyString').exclude() mb.free_function('UTIL_MessageText').exclude() mb.free_functions('UTIL_EntityFromUserMessageEHandle').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) mb.free_functions('UTIL_PlayerByUserId').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) # Transformations mb.free_functions( 'GetVectorInScreenSpace' ).add_transformation( FT.output('iX'), FT.output('iY') ) mb.free_functions( 'GetTargetInScreenSpace' ).add_transformation( FT.output('iX'), FT.output('iY') ) # Exclude # Don't care about the following functions mb.free_functions('UTIL_EmitAmbientSound').exclude() # No definition LOL
def set_call_policies_pointee( mb ): # Set the default policy to deal with pointer/reference return types to reference_existing object # as this is the ogrenewt Default. ## NOTE AJM 1/1/07 -- this function not used as change to ref_existing_object.. from pyplusplus import module_creator mem_funs = mb.calldefs () mem_funs.create_with_signature = True #MSVC 7.1 if function has throw modifier. resolver = module_creator.built_in_resolver_t() for mem_fun in mem_funs: if mem_fun.call_policies: continue decl_call_policies = resolver( mem_fun ) if decl_call_policies: mem_fun.call_policies = decl_call_policies continue rtype = declarations.remove_alias( mem_fun.return_type ) if declarations.is_pointer(rtype) or declarations.is_reference(rtype): # mem_fun.call_policies \ # = call_policies.return_value_policy( call_policies.reference_existing_object ) mem_fun.call_policies \ = call_policies.return_value_policy( '::boost::python::return_pointee_value' ) ## now we fix a problem where the getSingleton policy isn't right mb.mem_funs( 'getSingleton' ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
def ParseClient(self, mb): # Free functions that don't start with 'UTIL_' mb.free_functions('ScreenHeight').include() mb.free_functions('ScreenWidth').include() mb.free_functions('GetVectorInScreenSpace').include() mb.free_functions('GetTargetInScreenSpace').include() # Main view mb.free_function('MainViewOrigin').include() mb.free_function('MainViewAngles').include() mb.free_function('MainViewForward').include() mb.free_function('MainViewRight').include() mb.free_function('MainViewUp').include() mb.free_function('MainWorldToViewMatrix').include() # Call policies and excludes if self.settings.branch == 'swarm': mb.free_function('UTIL_GetLocalizedKeyString').exclude() mb.free_function('UTIL_MessageText').exclude() mb.free_functions('UTIL_EntityFromUserMessageEHandle').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) mb.free_functions('UTIL_PlayerByUserId').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) # Transformations mb.free_functions( 'GetVectorInScreenSpace' ).add_transformation( FT.output('iX'), FT.output('iY') ) mb.free_functions( 'GetTargetInScreenSpace' ).add_transformation( FT.output('iX'), FT.output('iY') )
def customize(self, mb ): mb.calldef( 'return_second_arg' ).call_policies = call_policies.return_arg( 2 ) mb.calldef( 'return_self' ).call_policies = call_policies.return_self() mb.class_( 'impl_details_t' ).opaque = True mb.calldef( 'get_opaque' ).call_policies \ = call_policies.return_value_policy( call_policies.return_opaque_pointer ) mb.calldef( 'get_fundamental_ptr_value' ).call_policies \ = call_policies.return_value_policy( call_policies.return_pointee_value ) mb.calldef( 'get_fundamental_ptr_value_null' ).call_policies \ = call_policies.return_value_policy( call_policies.return_pointee_value ) mb.calldef( 'create_arr_3' ).call_policies \ = call_policies.convert_array_to_tuple( 3, call_policies.memory_managers.delete_ ) image = mb.class_('return_range_image_t') image.add_declaration_code( get_size_code ) image.add_declaration_code( get_create_images_size ) get_raw_data = image.mem_fun( 'get_raw_data' ) get_raw_data.call_policies \ = call_policies.return_range( get_raw_data, 'raw_data_size_t' ) get_raw_data_const = image.mem_fun( 'get_raw_data_const' ) get_raw_data_const.call_policies \ = call_policies.return_range( get_raw_data_const, 'raw_data_size_t' ) create_images = image.mem_fun( 'create_images' ) create_images.call_policies \ = call_policies.return_range( create_images , 'get_create_images_size_t' , call_policies.return_value_policy(call_policies.reference_existing_object) )
def Parse(self, mb): # Exclude everything, then add what we need mb.decls().exclude() mb.free_function('PyMKCreateSession').include() mb.free_function('PyMKCreateSession').rename('CreateSession') mb.free_function('PyMKMatchSession').include() mb.free_function('PyMKMatchSession').rename('MatchSession') mb.free_function('PyMKCloseSession').include() mb.free_function('PyMKCloseSession').rename('CloseSession') mb.free_function('PyMKIsSessionActive').include() mb.free_function('PyMKIsSessionActive').rename('IsSessionActive') cls = mb.class_('PyMatchEventsSubscription') cls.include() cls.rename('matcheventssubscription') cls.mem_funs().virtuality = 'not virtual' cls.mem_fun( 'GetEventData').call_policies = call_policies.return_value_policy( call_policies.return_by_value) cls = mb.class_('PyMatchSession') cls.include() cls.rename('matchsession') cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('GetSessionSystemData' ).call_policies = call_policies.return_value_policy( call_policies.return_by_value) cls.mem_fun('GetSessionSettings' ).call_policies = call_policies.return_value_policy( call_policies.return_by_value) cls = mb.class_('PyMatchSystem') cls.include() cls.rename('matchsystem') cls.mem_funs().virtuality = 'not virtual' cls = mb.class_('PySearchManager') cls.include() cls.rename('SearchManager') #cls.calldefs('PySearchManager').exclude() cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('SetSearchManagerInternal').exclude() cls = mb.class_('PyMatchSearchResult') cls.include() cls.rename('MatchSearchResult') cls.mem_funs().virtuality = 'not virtual' #cls.calldefs('PyMatchSearchResult').exclude() cls.mem_fun('GetGameDetails' ).call_policies = call_policies.return_value_policy( call_policies.return_by_value) cls = mb.class_('PyMatchEventsSink') cls.include() cls.rename('MatchEventsSink') cls = mb.class_('PySteamMatchmaking') cls.include() cls.rename('steammatchmaking')
def ParseISurface(self, mb): cls = mb.class_('CWrapSurface') cls.include() cls.rename('ISurface') mb.free_function('wrapsurface').include() mb.free_function( 'wrapsurface' ).call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) mb.free_function( 'wrapsurface' ).rename('surface') mb.enum('CursorCode').include() mb.enum('FontDrawType_t').include() if self.settings.branch == 'swarm': mb.class_('FontVertex_t').include() else: mb.class_('Vertex_t').include() mb.class_('IntRect').include() cls.mem_funs( 'DrawGetTextPos' ).add_transformation( FT.output('x'), FT.output('y') ) cls.mem_funs( 'DrawGetTextureSize' ).add_transformation( FT.output('wide'), FT.output('tall') ) cls.mem_funs( 'GetScreenSize' ).add_transformation( FT.output('wide'), FT.output('tall') ) cls.mem_funs( 'GetCharABCwide' ).add_transformation( FT.output('a'), FT.output('b'), FT.output('c') ) cls.mem_funs( 'GetWorkspaceBounds' ).add_transformation( FT.output('x'), FT.output('y'), FT.output('wide'), FT.output('tall') ) cls.mem_funs( 'GetAbsoluteWindowBounds' ).add_transformation( FT.output('x'), FT.output('y'), FT.output('wide'), FT.output('tall') ) cls.mem_funs( 'GetProportionalBase' ).add_transformation( FT.output('width'), FT.output('height') ) cls.mem_funs( 'SurfaceGetCursorPos' ).add_transformation( FT.output('x'), FT.output('y') ) cls.mem_funs( 'CreateHTMLWindow' ).call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) cls.mem_funs( 'DrawGetTextureMatInfoFactory' ).call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) cls.mem_funs( 'GetIconImageForFullPath' ).call_policies = call_policies.return_value_policy(call_policies.reference_existing_object)
def Parse(self, mb): # Exclude everything by default mb.decls().exclude() mb.class_('kbutton_t').include() if self.settings.branch == 'swarm': mb.class_('kbutton_t').mem_funs('GetPerUser').exclude() # Include input class cls = mb.class_('CInput') cls.include() cls.mem_funs().virtuality = 'not virtual' if self.settings.branch == 'swarm': #mb.mem_funs('FindKey').exclude() # FIXME mb.mem_funs('FindKey').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) else: mb.mem_funs('FindKey').call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) mb.mem_funs('GetUserCmd').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) # Can't exclude due being abstract mb.mem_funs( 'CAM_OrthographicSize' ).add_transformation( FT.output('w'), FT.output('h') ) mb.add_declaration_code( "CInput *wrap_Input()\r\n{\r\n\treturn (CInput *)::input;\r\n}\r\n" ) mb.add_registration_code( 'bp::def( "input", wrap_Input, bp::return_value_policy<bp::reference_existing_object>() );' ) # ButtonCode. mb.enums('ButtonCode_t').include() # Remove any protected function mb.calldefs( matchers.access_type_matcher_t( 'protected' ) ).exclude()
def Parse(self, mb): # Exclude everything, then add what we need mb.decls().exclude() mb.free_function('PyMKCreateSession').include() mb.free_function('PyMKCreateSession').rename('CreateSession') mb.free_function('PyMKMatchSession').include() mb.free_function('PyMKMatchSession').rename('MatchSession') mb.free_function('PyMKCloseSession').include() mb.free_function('PyMKCloseSession').rename('CloseSession') mb.free_function('PyMKIsSessionActive').include() mb.free_function('PyMKIsSessionActive').rename('IsSessionActive') cls = mb.class_('PyMatchSession') cls.include() cls.rename('matchsession') cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('GetSessionSystemData').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls.mem_fun('GetSessionSettings').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) # Wars mb.free_function('WarsRequestGameServer').include() if self.isserver: mb.enum('EGameServerState').include() mb.free_function('WarsInitGameServer').include() mb.free_function('WarsShutdownGameServer').include() mb.free_function('GetWarsGameServerState').include() mb.free_function('SetWarsGameServerState').include() mb.free_function('GetActiveGameLobbySteamID').include() else: mb.free_function('WarsSendPingMessage').include() mb.free_function('WarsSendPongMessage').include()
def ManualFixes ( mb, ns ): global_ns = mb.global_ns # if MAIN_NAMESPACE: # main_ns = global_ns.namespace( MAIN_NAMESPACE ) # else: # main_ns = global_ns if ns == 'OgreOde': # we only need to do this once ## here we adjust for functions that return poiners to ODE "ID's", which are really C structs ## I may have been over agressive in identifing these functions but hopefully not... for func in mb.namespace( 'OgreOde' ).member_functions(): if func.return_type.decl_string.endswith('ID'): print "Setting ", func.name, "to Opaque" func.opaque = True func.call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer ) ## Functions that return objects we need to manage FunctionsToMemoryManage=[\ '::OgreOde::EntityInformer::createStaticTriangleMesh', '::OgreOde::EntityInformer::createSingleStaticBox', '::OgreOde::EntityInformer::createSingleDynamicBox', '::OgreOde::EntityInformer::createSingleDynamicSphere' ] for cls in FunctionsToMemoryManage: global_ns.mem_fun(cls).call_policies = call_policies.return_value_policy( call_policies.manage_new_object )
def update_builder(builder): include_classes = [ "OutputFileHandler", "RelativeTo", "FileFinder", "RandomNumberGenerator", "Timer", "ChasteBuildInfo", "PetscTools", "ReplicatableVector" ] for eachClass in include_classes: builder.class_(eachClass).include() new_name = generate_bindings.template_replace(eachClass) if (new_name != eachClass): builder.class_(eachClass).rename(new_name) builder.free_function("GetPetscMatForWrapper" ).call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer) builder.class_("PetscTools").member_functions('GetWorld').exclude() builder.class_("PetscTools").member_functions( 'CreateVec').call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer) builder.class_("PetscTools").member_functions( 'CreateAndSetVec').call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer) builder.class_("PetscTools").variables('MASTER_RANK').exclude() builder.class_("OutputFileHandler").member_functions( 'OpenOutputFile').exclude() builder.class_("FileFinder").member_functions('FindMatches').exclude() builder.class_("RandomNumberGenerator").member_function( "Instance").call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) return builder
def ParseHUD(self, mb): # CHud cls = mb.class_('CHud') cls.include() if self.settings.branch == 'swarm': mb.free_function('GetHud').include() mb.free_function('GetHud').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) else: mb.variables('gHUD').include() cls.member_functions( 'FindElement' ).call_policies = call_policies.return_value_policy(call_policies.return_by_value) if self.settings.branch != 'swarm': # ASW should use HudIcons() / CHudIcons #cls.member_functions( 'GetIcon' ).call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) #cls.member_functions( 'AddUnsearchableHudIconToList' ).call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) #cls.member_functions( 'AddSearchableHudIconToList' ).call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) # The HUD only cleans up when you close the game, so internal references should't be a problem. cls.member_functions( 'GetIcon' ).call_policies = call_policies.return_internal_reference() cls.member_functions( 'AddUnsearchableHudIconToList' ).call_policies = call_policies.return_internal_reference() cls.member_functions( 'AddSearchableHudIconToList' ).call_policies = call_policies.return_internal_reference() cls.variables('m_HudList').exclude() if self.settings.branch == 'swarm': cls.member_functions('GetHudList').exclude() cls.member_functions('GetHudPanelList').exclude() cls = mb.class_('CHudElement') cls.include() cls.member_functions('GetName').exclude() cls.variables('m_pyInstance').exclude() cls.member_functions('SetActive').virtuality = 'not virtual' cls.member_functions('IsActive').virtuality = 'not virtual' cls.member_functions('ShouldDraw').virtuality = 'not virtual' # TODO: What if we need better control in Python? cls.member_functions('ProcessInput').virtuality = 'not virtual' # TODO: Do we ever need this in Python? cls = mb.class_('CPyHudElementHelper') cls.include() cls.rename('CHudElementHelper') cls.member_functions('GetNext').exclude() # HudIcons if self.settings.branch == 'swarm': cls = mb.class_('CHudIcons') cls.include() # FIXME cls.member_functions( 'GetIcon' ).call_policies = call_policies.return_internal_reference() #cls.member_functions('GetIcon').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) #cls.member_functions('GetIcon' ).call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) cls.member_functions('AddUnsearchableHudIconToList').exclude() cls.member_functions('AddSearchableHudIconToList').exclude() #cls.member_functions('AddUnsearchableHudIconToList').call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) #cls.member_functions('AddSearchableHudIconToList').call_policies = call_policies.return_value_policy( call_policies.manage_new_object ) mb.free_function('HudIcons').include() mb.free_function('HudIcons').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) # CHudTexture cls = mb.class_('CHudTexture') cls.include() cls.variables().exclude()
def ScrollBar(self, mb): mb.mem_funs( 'GetButton' ).call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.mem_funs( 'GetSlider' ).call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.mem_funs( 'GetRange' ).add_transformation( FT.output('min'), FT.output('max') ) # ScrollBarSlider mb.mem_funs( 'GetNobPos' ).add_transformation( FT.output('min'), FT.output('max') )
def ManualFixes ( mb ): global_ns = mb.global_ns if MAIN_NAMESPACE: main_ns = global_ns.namespace( MAIN_NAMESPACE ) else: main_ns = global_ns mb.class_( "Mouse" ).member_function( "getMouseState" ).call_policies =\ call_policies.return_value_policy( call_policies.reference_existing_object ) mb.class_( "JoyStick" ).member_function( "getJoyStickState" ).call_policies =\ call_policies.return_value_policy( call_policies.reference_existing_object )
def ParseClientEntityRelated(self, mb): # Creating a client class cls = mb.class_("NetworkedClass") cls.include() cls.vars("m_pClientClass").exclude() cls = self.IncludeEmptyClass(mb, "ClientClass") cls.no_init = True cls.calldefs("ClientClass").exclude() cls.mem_fun("GetName").include() # For debugging purposes # Client Entity List cls = mb.class_("CClientEntityList") cls.include() cls.calldefs().virtuality = "not virtual" cls.no_init = True cls.mem_funs().exclude() cls.mem_fun("NumberOfEntities").include() cls.mem_fun("GetHighestEntityIndex").include() cls.mem_fun("GetBaseEntity").include() cls.mem_fun("GetBaseEntity").call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun("GetBaseEntityFromHandle").include() cls.mem_fun("GetBaseEntityFromHandle").call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls.mem_fun("EntIndexToHandle").include() cls.mem_fun("HandleToEntIndex").include() cls.mem_fun("IsHandleValid").include() cls.mem_fun("FirstBaseEntity").include() cls.mem_fun("FirstBaseEntity").call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun("NextBaseEntity").include() cls.mem_fun("NextBaseEntity").call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.free_function("ClientEntityList").include() mb.free_function("ClientEntityList").call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) # PyEntityFactory self.IncludeEmptyClass(mb, "PyEntityFactory") mb.class_("PyEntityFactory").rename("EntityFactory") mb.free_function("PyGetClassByClassname").include() mb.free_function("PyGetClassByClassname").rename("GetClassByClassname") mb.free_function("PyGetAllClassnames").include() mb.free_function("PyGetAllClassnames").rename("GetAllClassnames") # Client only structs cls = mb.class_("SpatializationInfo_t") cls.include() cls.var("pOrigin").exclude() cls.var("pAngles").exclude() cls.var("pflRadius").exclude()
def ParseClientEntityRelated(self, mb): # Creating a client class cls = mb.class_('NetworkedClass') cls.include() cls.vars('m_pClientClass').exclude() cls = self.IncludeEmptyClass(mb, 'ClientClass') cls.no_init = True cls.calldefs('ClientClass').exclude() cls.mem_fun('GetName').include() # For debugging purposes # Client Entity List cls = mb.class_('CClientEntityList') cls.include() cls.calldefs().virtuality = 'not virtual' cls.no_init = True cls.mem_funs().exclude() cls.mem_fun('NumberOfEntities').include() cls.mem_fun('GetHighestEntityIndex').include() cls.mem_fun('GetBaseEntity').include() cls.mem_fun('GetBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('GetBaseEntityFromHandle').include() cls.mem_fun('GetBaseEntityFromHandle').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('EntIndexToHandle').include() cls.mem_fun('HandleToEntIndex').include() cls.mem_fun('IsHandleValid').include() cls.mem_fun('FirstBaseEntity').include() cls.mem_fun('FirstBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('NextBaseEntity').include() cls.mem_fun('NextBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.free_function('ClientEntityList').include() mb.free_function('ClientEntityList').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) # PyEntityFactory self.IncludeEmptyClass(mb, 'PyEntityFactory') mb.class_('PyEntityFactory').rename('EntityFactory') mb.free_function('PyGetClassByClassname').include() mb.free_function('PyGetClassByClassname').rename('GetClassByClassname') mb.free_function('PyGetAllClassnames').include() mb.free_function('PyGetAllClassnames').rename('GetAllClassnames') if self.isserver or self.settings.branch == 'swarm': mb.free_function('PyReadDataDesc').include() mb.free_function('PyReadDataDesc').rename('ReadDataDesc') # Client only structs cls = mb.class_('SpatializationInfo_t') cls.include() cls.var('pOrigin').exclude() cls.var('pAngles').exclude() cls.var('pflRadius').exclude()
def Parse(self, mb): # Exclude everything, then add what we need mb.decls().exclude() mb.free_function('PyMKCreateSession').include() mb.free_function('PyMKCreateSession').rename('CreateSession') mb.free_function('PyMKMatchSession').include() mb.free_function('PyMKMatchSession').rename('MatchSession') mb.free_function('PyMKCloseSession').include() mb.free_function('PyMKCloseSession').rename('CloseSession') mb.free_function('PyMKIsSessionActive').include() mb.free_function('PyMKIsSessionActive').rename('IsSessionActive') cls = mb.class_('PyMatchEventsSubscription') cls.include() cls.rename('matcheventssubscription') cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('GetEventData').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls = mb.class_('PyMatchSession') cls.include() cls.rename('matchsession') cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('GetSessionSystemData').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls.mem_fun('GetSessionSettings').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls = mb.class_('PyMatchSystem') cls.include() cls.rename('matchsystem') cls.mem_funs().virtuality = 'not virtual' cls = mb.class_('PySearchManager') cls.include() cls.rename('SearchManager') #cls.calldefs('PySearchManager').exclude() cls.mem_funs().virtuality = 'not virtual' cls.mem_fun('SetSearchManagerInternal').exclude() cls = mb.class_('PyMatchSearchResult') cls.include() cls.rename('MatchSearchResult') cls.mem_funs().virtuality = 'not virtual' #cls.calldefs('PyMatchSearchResult').exclude() cls.mem_fun('GetGameDetails').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls = mb.class_('PyMatchEventsSink') cls.include() cls.rename('MatchEventsSink') cls = mb.class_('PySteamMatchmaking') cls.include() cls.rename('steammatchmaking')
def ApplyCommonRules(self, mb): # Common function added for getting the "PyObject" of an entity mb.mem_funs('GetPySelf').exclude() ihandleentity = mb.class_('IHandleEntity') # All return values derived from IHandleEntity entity will be returned by value. # This ensures the converter is called testinherit = MatcherTestInheritClass(ihandleentity) decls = mb.calldefs(matchers.custom_matcher_t(testinherit)) decls.call_policies = call_policies.return_value_policy( call_policies.return_by_value) # All CBaseEntity related classes should have a custom call trait self.baseentcls = mb.class_( 'CBaseEntity' if self.isserver else 'C_BaseEntity') def ent_call_trait(type_): return '%(arg)s ? %(arg)s->GetPyHandle() : boost::python::object()' entclasses = mb.classes(self.TestCBaseEntity) for entcls in entclasses: entcls.custom_call_trait = ent_call_trait # All functions receiving an IHandleEntity argument should be converted def ihandleentity_call_trait(type_): return 'PyEntityFromEntityHandle( %(arg)s )' ihandleentity.custom_call_trait = ihandleentity_call_trait # Anything returning KeyValues should be returned by value so it calls the converter keyvalues = mb.class_('KeyValues') mb.calldefs(matchers.calldef_matcher_t( return_type=pointer_t(declarated_t(keyvalues))), allow_empty=True ).call_policies = call_policies.return_value_policy( call_policies.return_by_value) mb.calldefs(matchers.calldef_matcher_t( return_type=pointer_t(const_t(declarated_t(keyvalues)))), allow_empty=True ).call_policies = call_policies.return_value_policy( call_policies.return_by_value) # Anything returning a void pointer is excluded by default mb.calldefs(matchers.calldef_matcher_t( return_type=pointer_t(declarated_t(void_t()))), allow_empty=True).exclude() mb.calldefs(matchers.calldef_matcher_t( return_type=pointer_t(const_t(declarated_t(void_t())))), allow_empty=True).exclude()
def applyDefaultReturnPolicies(functions): for f in functions: if not f.call_policies: return_type = f.return_type if declarations.is_reference(return_type) or declarations.is_pointer(return_type): type_info = return_type type_info = declarations.remove_pointer(type_info) type_info = declarations.remove_reference(type_info) type_info = declarations.remove_const(type_info) # Se il tipo non e' esposto (potrebbe essere una classe, ma non ci sono informazioni perche' la dichiarazione non e' stata incontrata), viene gestito tramite return_opaque_pointer if declarations.is_class(type_info): f.call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) else: f.call_policies = call_policies.return_value_policy(call_policies.return_opaque_pointer)
def ParseClientEntityRelated(self, mb): # Creating a client class cls = mb.class_('NetworkedClass') cls.include() cls.vars('m_pClientClass').exclude() cls = self.IncludeEmptyClass(mb, 'ClientClass') cls.no_init = True cls.calldefs('ClientClass').exclude() cls.mem_fun('GetName').include() # For debugging purposes # Client Entity List cls = mb.class_('CClientEntityList') cls.include() cls.calldefs().virtuality = 'not virtual' cls.no_init = True cls.mem_funs().exclude() cls.mem_fun('NumberOfEntities').include() cls.mem_fun('GetHighestEntityIndex').include() cls.mem_fun('GetBaseEntity').include() cls.mem_fun('GetBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('GetBaseEntityFromHandle').include() cls.mem_fun('GetBaseEntityFromHandle').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('EntIndexToHandle').include() cls.mem_fun('HandleToEntIndex').include() cls.mem_fun('IsHandleValid').include() cls.mem_fun('FirstBaseEntity').include() cls.mem_fun('FirstBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('NextBaseEntity').include() cls.mem_fun('NextBaseEntity').call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.free_function('ClientEntityList').include() mb.free_function('ClientEntityList').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) # PyEntityFactory self.IncludeEmptyClass(mb, 'PyEntityFactory') mb.class_('PyEntityFactory').rename('EntityFactory') mb.free_function('PyGetClassByClassname').include() mb.free_function('PyGetClassByClassname').rename('GetClassByClassname') mb.free_function('PyGetAllClassnames').include() mb.free_function('PyGetAllClassnames').rename('GetAllClassnames') # Client only structs cls = mb.class_('SpatializationInfo_t') cls.include() cls.var('pOrigin').exclude() cls.var('pAngles').exclude() cls.var('pflRadius').exclude()
def Parse(self, mb): mb.decls().exclude() # Material reference cls = mb.class_('CMaterialReference') cls.include() mb.global_ns.mem_opers('*').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) mb.global_ns.mem_opers().exclude() mb.global_ns.casting_operators().exclude() if self.isclient: # Glow Outline manager cls = mb.class_('CGlowObjectManager') cls.include() cls.mem_funs().virtuality = 'not virtual' cls.no_init = True mb.add_registration_code( "bp::scope().attr( \"glowobjectmanager\" ) = boost::ref(g_GlowObjectManager);" ) # A way for creating procedural materials in Python cls = mb.class_('PyProceduralTexture') cls.rename('ProceduralTexture') cls.include() mb.enum('ImageFormat').include() # Material lights cls = mb.class_('LightDesc_t') cls.include() # Remove any protected function mb.calldefs( matchers.access_type_matcher_t( 'protected' ) ).exclude()
def Parse(self, mb): # Exclude everything, then add what we need # Otherwise we get very big source code and dll's mb.decls().exclude() mb.free_function('PyMKCreateSession').include() mb.free_function('PyMKCreateSession').rename('CreateSession') mb.free_function('PyMKMatchSession').include() mb.free_function('PyMKMatchSession').rename('MatchSession') cls = mb.class_('PyMatchSession') cls.include() cls.rename('matchsession') cls.mem_fun('GetSessionSystemData').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) cls.mem_fun('GetSessionSettings').call_policies = call_policies.return_value_policy( call_policies.return_by_value )
def Parse(self, mb): # Exclude everything, then add what we need # Otherwise we get very big source code and dll's mb.decls().exclude() cls = mb.class_('CFogOfWarMgr') cls.include() cls.mem_funs().virtuality = 'not virtual' cls.no_init = True cls.mem_funs().exclude() cls.mem_fun('GetGridSize').include() cls.mem_fun('GetTileSize').include() cls.mem_fun('ComputeFOWPosition').include() cls.mem_fun('ComputeWorldPosition').include() cls.mem_fun('DebugPrintEntities').include() cls.mem_fun('ModifyHeightAtTile').include() cls.mem_fun('ModifyHeightAtPoint').include() cls.mem_fun('ModifyHeightAtExtent').include() cls.mem_fun('GetHeightAtTile').include() cls.mem_fun('GetHeightAtPoint').include() if self.isserver: cls.mem_fun('PointInFOW').include() cls.mem_fun('ForceTransmitUpdateEntity').include() if self.isclient: cls.mem_fun('ResetExplored').include() mb.free_function('FogOfWarMgr').include() mb.free_function('FogOfWarMgr').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
def ParseMisc(self, mb): # Include some empty classes #IncludeEmptyClass(mb, 'CViewSetup') <- TODO: Needed? # Animation Controller mb.free_function('GetAnimationController').include() mb.free_function('GetAnimationController').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) # Screen cls = mb.class_('WarsVGUIScreen') cls.include() # IVGUI/Tick signals mb.add_declaration_code( "void wrap_AddTickSignal( VPANEL panel, int intervalMilliseconds = 0 )\r\n{\r\n\tvgui::ivgui()->AddTickSignal(panel, intervalMilliseconds);\r\n}\r\n" ) mb.add_declaration_code( "void wrap_RemoveTickSignal( VPANEL panel)\r\n{\r\n\tvgui::ivgui()->RemoveTickSignal(panel);\r\n}\r\n" ) mb.add_registration_code( 'bp::def( "AddTickSignal", wrap_AddTickSignal, (bp::arg("panel"), bp::arg("intervalMilliseconds")=0 ) );' ) mb.add_registration_code( 'bp::def( "RemoveTickSignal", wrap_RemoveTickSignal, bp::arg("panel") );' ) # Gameui open? mb.free_function('PyIsGameUIVisible').include() mb.free_function('PyIsGameUIVisible').rename('IsGameUIVisible') mb.free_function('PyGetPanel').include() mb.free_function('PyGetPanel').rename('GetPanel') #mb.free_function('PyGetPanel').call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.enum('VGuiPanel_t').include() mb.free_function('PyGameUICommand').include() # Temporary function mb.free_function('PyGameUICommand').rename('GameUICommand') # Message map types mb.enum('DataType_t').include() # Some defines mb.add_registration_code( "bp::scope().attr( \"INVALID_FONT\" ) = (int)0;" ) mb.add_registration_code( "bp::scope().attr( \"INVALID_PANEL\" ) = (int)0xffffffff;" )
def call_policies(self): """Define default call policies: for anything that returns a reference, return a reference to the existing object. This is potentially dangerous.""" decllist = [ self.mb.member_functions(returns_reference), self.mb.free_functions(returns_reference), self.mb.operators(returns_reference) ] for decls in decllist: for decl in decls: if decl.return_type.decl_string[-7:]=='const &': decl.call_policies = \ call_policies.return_value_policy( call_policies.copy_const_reference) else: decl.call_policies = \ call_policies.return_value_policy( call_policies.reference_existing_object)
def customize( self, mb ): mb.global_ns.exclude() nm_t = declarations.remove_declarated( mb.global_ns.typedef( 'naive_matrix_t' ).type ) nm_t.include() exposed_db = utils.exposed_decls_db_t() exposed_db.register_decls( mb.global_ns, [] ) exposed_db.save( autoconfig.build_dir ) mb.register_module_dependency( autoconfig.build_dir ) sm = mb.global_ns.namespace( name='split_module' ) sm.include() sm.class_( 'op_struct' ).exclude() mb.free_function( 'check_overload' ).add_declaration_code( '//hello check_overload' ) mb.free_function( 'get_opaque' ).add_declaration_code( '//hello get_opaque' ) mb.calldefs( 'check_overload' ).use_overload_macro = True mb.calldefs( 'get_opaque' ).call_policies \ = call_policies.return_value_policy( call_policies.return_opaque_pointer ) mb.class_( 'op_struct' ).exclude() item = mb.class_( 'item_t' ) item.add_declaration_code( '//hello world' ) nested = item.class_( 'nested_t' ) nested.add_declaration_code( '//hello nested decl' ) nested.add_registration_code( '//hello nested reg', False ) mb.free_fun( 'create_empty_mapping' ).include()
def ApplyCommonRules(self, mb): # Common function added for getting the "PyObject" of an entity mb.member_functions('GetPySelf').exclude() ihandleentity = mb.class_('IHandleEntity') # All return values derived from IHandleEntity entity will be returned by value. # This ensures the converter is called testinherit = MatcherTestInheritClass(ihandleentity) decls = mb.calldefs(matchers.custom_matcher_t(testinherit)) decls.call_policies = call_policies.return_value_policy(call_policies.return_by_value) # All CBaseEntity related classes should have a custom call trait self.baseentcls = mb.class_('CBaseEntity' if self.isserver else 'C_BaseEntity') def ent_call_trait(type_): return '%(arg)s ? %(arg)s->GetPyHandle() : boost::python::object()' entclasses = mb.classes(self.TestCBaseEntity) for entcls in entclasses: entcls.custom_call_trait = ent_call_trait # All functions receiving an IHandleEntity argument should be converted def ihandleentity_call_trait(type_): return 'PyEntityFromEntityHandle( %(arg)s )' ihandleentity.custom_call_trait = ihandleentity_call_trait # Anything returning KeyValues should be returned by value so it calls the converter keyvalues = mb.class_('KeyValues') mb.calldefs(calldef_matcher_t(return_type=pointer_t(declarated_t(keyvalues))), allow_empty=True).call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.calldefs(calldef_matcher_t(return_type=pointer_t(const_t(declarated_t(keyvalues)))), allow_empty=True).call_policies = call_policies.return_value_policy(call_policies.return_by_value) # Anything returning a void pointer is excluded by default mb.calldefs(calldef_matcher_t(return_type=pointer_t(declarated_t(void_t()))), allow_empty=True).exclude() mb.calldefs(calldef_matcher_t(return_type=pointer_t(const_t(declarated_t(void_t())))), allow_empty=True).exclude()
def Parse(self, mb): # Exclude everything, then add what we need # Otherwise we get very big source code and dll's mb.decls().exclude() cls = mb.class_('CFogOfWarMgr') cls.include() cls.mem_funs().virtuality = 'not virtual' cls.no_init = True cls.mem_funs().exclude() cls.mem_fun('GetGridSize').include() cls.mem_fun('GetTileSize').include() cls.mem_fun('ComputeFOWPosition').include() cls.mem_fun('ComputeWorldPosition').include() cls.mem_fun('DebugPrintEntities').include() cls.mem_fun('ModifyHeightAtTile').include() cls.mem_fun('ModifyHeightAtPoint').include() cls.mem_fun('ModifyHeightAtExtent').include() cls.mem_fun('GetHeightAtTile').include() cls.mem_fun('GetHeightAtPoint').include() if self.isserver: cls.mem_fun('PointInFOW').include() cls.mem_fun('ForceTransmitUpdateEntity').include() if self.isclient: cls.mem_fun('ResetExplored').include() mb.free_function('FogOfWarMgr').include() mb.free_function( 'FogOfWarMgr').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object)
def call_policies(self): """Define default call policies: for anything that returns a reference, return a reference to the existing object. This is potentially dangerous.""" decllist = [self.mb.member_functions(returns_reference), self.mb.free_functions(returns_reference), self.mb.operators(returns_reference)] for decls in decllist: for decl in decls: if decl.return_type.decl_string[-7:] == 'const &': decl.call_policies = \ call_policies.return_value_policy( call_policies.copy_const_reference) else: decl.call_policies = \ call_policies.return_value_policy( call_policies.reference_existing_object)
def customize(self, mb): mb.mem_funs( 'string_ref' ).call_policies \ = call_policies.return_value_policy( call_policies.copy_non_const_reference ) non_overridable_pv_t = mb.class_('non_overridable_pv_t') non_overridable_pv_t.mem_fun('void_ptr').mark_as_non_overridable( reason='xxx void*')
def Parse(self, mb): mb.decls().exclude() # Material reference cls = mb.class_('CMaterialReference') cls.include() mb.global_ns.member_operators('*').call_policies = call_policies.return_value_policy(call_policies.reference_existing_object) mb.global_ns.member_operators().exclude() mb.global_ns.casting_operators().exclude() if self.isclient: # Glow Outline manager cls = mb.class_('CGlowObjectManager') cls.include() cls.member_functions().virtuality = 'not virtual' cls.no_init = True mb.add_registration_code( "bp::scope().attr( \"glowobjectmanager\" ) = boost::ref(g_GlowObjectManager);" ) # A way for creating procedural materials in Python cls = mb.class_('PyProceduralTexture') cls.rename('ProceduralTexture') cls.include() mb.enumeration('ImageFormat').include() # Material lights cls = mb.class_('LightDesc_t') cls.include() # Remove any protected function mb.calldefs( matchers.access_type_matcher_t( 'protected' ) ).exclude()
def ParseWars(self, mb): if self.isserver: # Send proxies cls = mb.class_('CPythonSendProxyOwnerOnly') cls.rename('SendProxyOwnerOnly') cls.include() cls.calldefs().virtuality = 'not virtual' cls = mb.class_('CPythonSendProxyAlliesOnly') cls.rename('SendProxyAlliesOnly') cls.include() cls.calldefs().virtuality = 'not virtual' # Enums mb.enums('WarsCollision_Group_t').include() # Mouse trace data (HL2Wars player) cls = mb.class_('MouseTraceData_t') cls.include() cls.rename('MouseTraceData') cls.vars('m_vStartPos').rename('startpos') cls.vars('m_vEndPos').rename('endpos') cls.vars('m_vNormal').rename('normal') cls.vars('m_hEnt').exclude() cls.mem_funs().exclude() cls.mem_funs( 'GetEnt').call_policies = call_policies.return_value_policy( call_policies.return_by_value) cls.mem_fun('Clear').include() cls.vars('m_vWorldOnlyEndPos').rename('groundendpos') cls.vars('m_vWorldOnlyNormal').rename('groundnormal') self.SetupProperty(cls, 'ent', 'GetEnt', 'SetEnt') if self.isclient: cls.vars('m_iX').rename('x') cls.vars('m_iY').rename('y') # IMouse mb.class_('IMouse').include() mb.class_('IMouse').rename('IMouseDoNotUse') mb.class_('IMouse').mem_funs( 'GetIMouse').call_policies = call_policies.return_value_policy( call_policies.return_by_value) mb.class_('PyMouse').include() mb.class_('PyMouse').rename('IMouse') mb.add_registration_code("ptr_imouse_to_py_imouse();")
def ParseISurface(self, mb): cls = mb.class_('CWrapSurface') cls.include() cls.rename('ISurface') mb.free_function('wrapsurface').include() mb.free_function( 'wrapsurface').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) mb.free_function('wrapsurface').rename('surface') mb.enum('CursorCode').include() mb.enum('FontDrawType_t').include() if self.settings.branch == 'swarm': mb.class_('FontVertex_t').include() else: mb.class_('Vertex_t').include() mb.class_('IntRect').include() cls.mem_funs('DrawGetTextPos').add_transformation( FT.output('x'), FT.output('y')) cls.mem_funs('DrawGetTextureSize').add_transformation( FT.output('wide'), FT.output('tall')) cls.mem_funs('GetScreenSize').add_transformation( FT.output('wide'), FT.output('tall')) cls.mem_funs('GetCharABCwide').add_transformation( FT.output('a'), FT.output('b'), FT.output('c')) cls.mem_funs('GetWorkspaceBounds').add_transformation( FT.output('x'), FT.output('y'), FT.output('wide'), FT.output('tall')) cls.mem_funs('GetAbsoluteWindowBounds').add_transformation( FT.output('x'), FT.output('y'), FT.output('wide'), FT.output('tall')) cls.mem_funs('GetProportionalBase').add_transformation( FT.output('width'), FT.output('height')) cls.mem_funs('SurfaceGetCursorPos').add_transformation( FT.output('x'), FT.output('y')) cls.mem_funs('CreateHTMLWindow' ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) cls.mem_funs('DrawGetTextureMatInfoFactory' ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) cls.mem_funs('GetIconImageForFullPath' ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object)
def ParseWars(self, mb): if self.isserver: # Send proxies cls = mb.class_("CPythonSendProxyOwnerOnly") cls.rename("SendProxyOwnerOnly") cls.include() cls.calldefs().virtuality = "not virtual" cls = mb.class_("CPythonSendProxyAlliesOnly") cls.rename("SendProxyAlliesOnly") cls.include() cls.calldefs().virtuality = "not virtual" # Enums mb.enums("WarsCollision_Group_t").include() # Mouse trace data (HL2Wars player) cls = mb.class_("MouseTraceData_t") cls.include() cls.rename("MouseTraceData") cls.vars("m_vStartPos").rename("startpos") cls.vars("m_vEndPos").rename("endpos") cls.vars("m_vNormal").rename("normal") cls.vars("m_hEnt").exclude() cls.mem_funs().exclude() cls.mem_funs("GetEnt").call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun("Clear").include() cls.vars("m_vWorldOnlyEndPos").rename("groundendpos") cls.vars("m_vWorldOnlyNormal").rename("groundnormal") self.SetupProperty(cls, "ent", "GetEnt", "SetEnt") if self.isclient: cls.vars("m_iX").rename("x") cls.vars("m_iY").rename("y") # IMouse mb.class_("IMouse").include() mb.class_("IMouse").rename("IMouseDoNotUse") mb.class_("IMouse").mem_funs("GetIMouse").call_policies = call_policies.return_value_policy( call_policies.return_by_value ) mb.class_("PyMouse").include() mb.class_("PyMouse").rename("IMouse") mb.add_registration_code("ptr_imouse_to_py_imouse();")
def ParseWars(self, mb): if self.isserver: # Send proxies cls = mb.class_('CPythonSendProxyOwnerOnly') cls.rename('SendProxyOwnerOnly') cls.include() cls.calldefs().virtuality = 'not virtual' cls = mb.class_('CPythonSendProxyAlliesOnly') cls.rename('SendProxyAlliesOnly') cls.include() cls.calldefs().virtuality = 'not virtual' # Enums mb.enums('WarsCollision_Group_t').include() # Mouse trace data (HL2Wars player) cls = mb.class_('MouseTraceData_t') cls.include() cls.rename('MouseTraceData') cls.vars('m_vStartPos').rename('startpos') cls.vars('m_vEndPos').rename('endpos') cls.vars('m_vNormal').rename('normal') cls.vars('m_hEnt').exclude() cls.mem_funs().exclude() cls.mem_funs('GetEnt').call_policies = call_policies.return_value_policy(call_policies.return_by_value) cls.mem_fun('Clear').include() cls.vars('m_vWorldOnlyEndPos').rename('groundendpos') cls.vars('m_vWorldOnlyNormal').rename('groundnormal') self.SetupProperty(cls, 'ent', 'GetEnt', 'SetEnt') if self.isclient: cls.vars('m_iX').rename('x') cls.vars('m_iY').rename('y') # IMouse mb.class_('IMouse').include() mb.class_('IMouse').rename('IMouseDoNotUse') mb.class_('IMouse').mem_funs('GetIMouse').call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.class_('PyMouse').include() mb.class_('PyMouse').rename('IMouse') mb.add_registration_code( "ptr_imouse_to_py_imouse();" )
def Parse(self, mb): # Exclude everything by default mb.decls().exclude() # EngineSound access mb.class_('PyEngineSound').include() mb.class_('PyEngineSound').rename('EngineSound') # soundengine should follow after PyEngineSound! mb.class_('PyEngineSound').add_registration_code( "}bp::scope().attr( \"soundengine\" ) = boost::ref(pysoundengine);{", False ) # EmitSound_t cls = mb.class_('EmitSound_t') cls.rename('EmitSound') cls.include() cls.var('m_UtlVecSoundOrigin').exclude() cls.var('m_nChannel').rename('channel') cls.var('m_pSoundName').rename('soundname') cls.var('m_flVolume').rename('volume') cls.var('m_SoundLevel').rename('soundlevel') cls.var('m_nFlags').rename('flags') cls.var('m_nPitch').rename('pitch') cls.var('m_pOrigin').rename('origin') cls.var('m_flSoundTime').rename('soundtime') cls.var('m_pflSoundDuration').rename('soundduration') cls.var('m_bEmitCloseCaption').rename('emitclosecaption') cls.var('m_bWarnOnMissingCloseCaption').rename('warnonmissingclosecaption') cls.var('m_bWarnOnDirectWaveReference').rename('warnondirectwavereference') cls.var('m_nSpeakerEntity').rename('speakerentity') cls.var('m_UtlVecSoundOrigin').rename('utlvecsoundorigin') cls.var('m_hSoundScriptHandle').rename('soundscripthandle') # SoundEnvelope mb.class_('CSoundEnvelopeControllerHandle').include() mb.class_('CSoundEnvelopeControllerHandle').calldefs('CSoundEnvelopeControllerHandle').exclude() mb.class_('CSoundEnvelopeControllerHandle').rename('CSoundEnvelopeController') mb.class_('CSoundPatchHandle').include() mb.class_('CSoundPatchHandle').rename('CSoundPatch') mb.mem_funs('SoundCreate').call_policies = call_policies.return_value_policy( call_policies.return_by_value ) mb.vars('m_pSoundPatch').exclude() mb.class_('CSoundPatchHandle').calldefs('CSoundPatchHandle').exclude() # CSoundParameters mb.class_('CSoundParameters').include() # Enums mb.enums('soundcommands_t').include() mb.enums('soundcommands_t').rename('soundcommands') mb.enums('soundlevel_t').include() mb.enums('soundlevel_t').rename('soundlevel') # //-------------------------------------------------------------------------------------------------------------------------------- # Remove any protected function mb.calldefs( matchers.access_type_matcher_t( 'protected' ) ).exclude()
def setDefaultCallPolicies(ns): # Set the default policy to deal with pointer/reference return types to reference_existing object # as this is the CEGUI Default. mem_funs = 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)
def setMemberFunctionCallPolicieByReturn(mb, MemberRetRef, callPolicie): for ref in MemberRetRef: memFuns = mb.global_ns.member_functions(return_type=ref, allow_empty=True) print(ref, len(memFuns)) for memFun in memFuns: if memFun.call_policies: continue else: memFun.call_policies = \ call_policies.return_value_policy(callPolicie)
def Parse(self, mb): # Exclude everything by default mb.decls().exclude() mb.class_('kbutton_t').include() if self.settings.branch == 'swarm': mb.class_('kbutton_t').mem_funs('GetPerUser').exclude() # Include input class cls = mb.class_('CInput') cls.include() cls.mem_funs().virtuality = 'not virtual' if self.settings.branch == 'swarm': #mb.mem_funs('FindKey').exclude() # FIXME mb.mem_funs( 'FindKey').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) else: mb.mem_funs( 'FindKey').call_policies = call_policies.return_value_policy( call_policies.manage_new_object) mb.mem_funs( 'GetUserCmd').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object ) # Can't exclude due being abstract mb.mem_funs('CAM_OrthographicSize').add_transformation( FT.output('w'), FT.output('h')) mb.add_declaration_code( "CInput *wrap_Input()\r\n{\r\n\treturn (CInput *)::input;\r\n}\r\n" ) mb.add_registration_code( 'bp::def( "input", wrap_Input, bp::return_value_policy<bp::reference_existing_object>() );' ) # ButtonCode. mb.enums('ButtonCode_t').include() # Remove any protected function mb.calldefs(matchers.access_type_matcher_t('protected')).exclude()
def setMemberFunctionCallPolicieByReturn(mb, MemberRetRef, callPolicie): for ref in MemberRetRef: memFuns = mb.global_ns.member_functions(return_type=ref, allow_empty=True) # print(ref, len(memFuns)) for memFun in memFuns: if memFun.call_policies: continue else: memFun.call_policies = \ call_policies.return_value_policy(callPolicie)
def customize(self, mb ): opaqueDecls = { 'Path': ['reverse'], 'RailTracking': ['getPath'], 'Track': ['getPath', 'getDefaultPath'] } mb.class_('Path').include() for decl in list(opaqueDecls.items()): cls = mb.class_(decl[0]) for methodName in decl[1]: cls.member_function(methodName).call_policies = call_policies.return_value_policy(call_policies.return_opaque_pointer);
def Set_Call_Policies( mb ): """ set the return call policies on classes that this hasn't already been done for. Set the default policy to deal with pointer/reference return types to reference_existing object """ mem_funs = mb.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 not mem_fun.call_policies and \ (declarations.is_reference (mem_fun.return_type) or declarations.is_pointer (mem_fun.return_type) ): mem_fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object )
def ParseEditablePanel(self, mb): focusnavgroup = mb.class_('FocusNavGroup') buildgroup = mb.class_('BuildGroup') excludetypes = [ pointer_t(const_t(declarated_t(focusnavgroup))), pointer_t(declarated_t(focusnavgroup)), reference_t(declarated_t(focusnavgroup)), pointer_t(const_t(declarated_t(buildgroup))), pointer_t(declarated_t(buildgroup)), reference_t(declarated_t(buildgroup)), ] mb.calldefs(calldef_withtypes(excludetypes), allow_empty=True).exclude() mb.mem_funs( 'GetDialogVariables' ).call_policies = call_policies.return_value_policy(call_policies.return_by_value)
def addSupportForString(mb): # set String as exposed, because we provide converters mb.global_ns.namespace("CEGUI").class_("String").already_exposed = True # we have to set use_make_functions to True for all variables that have CEGUI::String type # converters are only used when using setter / getter functions for var in mb.global_ns.variables(): # we don't check the type directly, because a const could be at the end # this could be replaced with var.type == "CEGUI::String" or var.type == "CEGUI::String const" if str(var.type).startswith("CEGUI::String"): var.use_make_functions = True # we have to use return_by_value to make converters work var.set_getter_call_policies(call_policies.return_value_policy(call_policies.return_by_value))
def customize(self, mb): opaqueDecls = { 'Path': ['reverse'], 'RailTracking': ['getPath'], 'Track': ['getPath', 'getDefaultPath'] } mb.class_('Path').include() for decl in opaqueDecls.items(): cls = mb.class_(decl[0]) for methodName in decl[1]: cls.member_function( methodName ).call_policies = call_policies.return_value_policy( call_policies.return_opaque_pointer)
def ParseMisc(self, mb): # Include some empty classes #IncludeEmptyClass(mb, 'CViewSetup') <- TODO: Needed? # Animation Controller mb.free_function('GetAnimationController').include() mb.free_function('GetAnimationController' ).call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) # Screen cls = mb.class_('WarsVGUIScreen') cls.include() # IVGUI/Tick signals mb.add_declaration_code( "void wrap_AddTickSignal( VPANEL panel, int intervalMilliseconds = 0 )\r\n{\r\n\tvgui::ivgui()->AddTickSignal(panel, intervalMilliseconds);\r\n}\r\n" ) mb.add_declaration_code( "void wrap_RemoveTickSignal( VPANEL panel)\r\n{\r\n\tvgui::ivgui()->RemoveTickSignal(panel);\r\n}\r\n" ) mb.add_registration_code( 'bp::def( "AddTickSignal", wrap_AddTickSignal, (bp::arg("panel"), bp::arg("intervalMilliseconds")=0 ) );' ) mb.add_registration_code( 'bp::def( "RemoveTickSignal", wrap_RemoveTickSignal, bp::arg("panel") );' ) # Gameui open? mb.free_function('PyIsGameUIVisible').include() mb.free_function('PyIsGameUIVisible').rename('IsGameUIVisible') mb.free_function('PyGetPanel').include() mb.free_function('PyGetPanel').rename('GetPanel') #mb.free_function('PyGetPanel').call_policies = call_policies.return_value_policy(call_policies.return_by_value) mb.enum('VGuiPanel_t').include() mb.free_function('PyGameUICommand').include() # Temporary function mb.free_function('PyGameUICommand').rename('GameUICommand') # Message map types mb.enum('DataType_t').include() # Some defines mb.add_registration_code( "bp::scope().attr( \"INVALID_FONT\" ) = (int)0;") mb.add_registration_code( "bp::scope().attr( \"INVALID_PANEL\" ) = (int)0xffffffff;")
def return_optional_by_value(fun): """ Sets a call policy that will unpack `boost::optional` return values to the contained type, which will be returned by-value. If the return value is `boost::none`, `None` will be returned. """ try: klass, args = templates.split(fun.return_type.decl_string) if not (klass.endswith('boost::optional') or klass.endswith('boost::tuples::tuple')): return False except AssertionError: return False fun.parent.include_files.append('pywrap/return_optional.hpp') fun.call_policies = call_policies.return_value_policy( 'return_optional_by_value') return True
def Parse(self, mb): # Exclude everything by default mb.decls().exclude() cls = mb.class_('CEditorSystem') cls.include() cls.calldefs().virtuality = 'not virtual' #cls.no_init = True cls.noncopyable = True mb.free_function('EditorSystem').include() mb.free_function( 'EditorSystem').call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) # Finally apply common rules to all includes functions and classes, etc. self.ApplyCommonRules(mb)
def Parse(self, mb): self.novguilib = (self.settings.branch == 'swarm') # Exclude everything by default mb.decls().exclude() self.ParsePanelHandles(mb) self.ParsePanels(mb) self.ParsePanel(mb) self.ParseEditablePanel(mb) self.ParseFrame(mb) self.ScrollBar(mb) self.ParseAnimationController(mb) self.ParseTextEntry(mb) self.ParseMisc(mb) # Should already be included, but is for some reason not... mb.mem_funs('SetControlEnabled').include() # Anything that returns a Panel should be returned by Value to call the right converter testinherit = MatcherTestInheritClass(mb.class_('Panel')) decls = mb.calldefs(matchers.custom_matcher_t(testinherit)) decls.call_policies = call_policies.return_value_policy( call_policies.return_by_value) # All CBaseEntity related classes should have a custom call trait self.basepanelcls = mb.class_('Panel') def panel_call_trait(type_): return 'boost::python::object(*%(arg)s)' panelclasses = mb.classes(self.TestBasePanel) for panelclass in panelclasses: panelclass.custom_call_trait = panel_call_trait # Remove any protected function #mb.calldefs( matchers.access_type_matcher_t( 'protected' ) ).exclude() self.ParseImageClasses(mb) self.ApplyCommonRules(mb)
def filter_declarations(self): code_generator_t.filter_declarations(self) # rename STL vectors of certain types self.std_ns.class_('vector< ompl::control::Control * >').rename('vectorControlPtr') # don't export variables that need a wrapper self.ompl_ns.variables(lambda decl: decl.is_wrapper_needed()).exclude() # force ControlSpace::allocControl to be exported. # (not sure why this is necessary) allocControlFn = self.ompl_ns.class_('ControlSpace').member_function('allocControl') allocControlFn.include() allocControlFn.call_policies = \ call_policies.return_value_policy(call_policies.reference_existing_object) # don't export components which is of type Control** self.ompl_ns.class_('CompoundControl').variable('components').exclude() # don't export some internal data structure self.ompl_ns.class_('OrderCellsByImportance').exclude() # don't expose this utility function self.ompl_ns.member_functions('getValueAddressAtIndex').exclude() self.ompl_ns.class_('KPIECE1').member_functions('freeGridMotions').exclude() # add array indexing to the RealVectorState self.add_array_access(self.ompl_ns.class_('RealVectorControlSpace').class_('ControlType')) # make objects printable that have a print function self.replace_member_functions(self.ompl_ns.member_functions('print')) # make settings printable self.replace_member_functions(self.ompl_ns.member_functions('printSettings')) # make controls printable self.replace_member_functions(self.ompl_ns.member_functions('printControl')) # print paths as matrices self.replace_member_functions(self.ompl_ns.member_functions('printAsMatrix')) # export ODESolver-derived classes that use Boost.OdeInt for odesolver in ['ODEBasicSolver', 'ODEErrorSolver', 'ODEAdaptiveSolver']: cls = self.ompl_ns.class_(lambda cls, slv=odesolver: cls.name.startswith(slv)) cls.rename(odesolver) if odesolver == 'ODEAdaptiveSolver': cls.include_files.append('boost/numeric/odeint.hpp') self.add_function_wrapper( 'void(const ompl::control::ODESolver::StateType &, const ompl::control::Control*, ' \ 'ompl::control::ODESolver::StateType &)', 'ODE', 'Ordinary differential equation') # workaround for default argument for PostPropagationEvent self.replace_member_function(self.ompl_ns.class_('ODESolver').member_function( 'getStatePropagator')) # LLVM's clang++ compiler doesn't like exporting this method because # the argument type (Grid::Cell) is protected self.ompl_ns.member_functions('computeImportance').exclude() # this method requires ompl::Grid::Coord (aka Eigen::VectorXi) to be exported self.ompl_ns.class_('KPIECE1').member_function('findNextMotion').exclude() # export pure virtual member functions, otherwise code doesn't compile syclop = self.ompl_ns.class_('Syclop') syclop.add_wrapper_code(""" virtual ompl::control::Syclop::Motion* addRoot(const ompl::base::State* s) { bp::override func_addRoot = this->get_override("addRoot"); return func_addRoot(s); } virtual void selectAndExtend(ompl::control::Syclop::Region& region, std::vector<ompl::control::Syclop::Motion*>& newMotions) { bp::override func_selectAndExtend = this->get_override("selectAndExtend"); func_selectAndExtend(region, newMotions); }""") # omit ompl::control::Syclop::Defaults nested subclass, otherwise # code doesn't compile (don't know why) syclop.class_('Defaults').exclude() # add wrappers for std::function types self.add_function_wrapper( 'ompl::control::ControlSamplerPtr(const ompl::control::ControlSpace*)', 'ControlSamplerAllocator', 'Control sampler allocator') self.add_function_wrapper( 'ompl::control::DirectedControlSamplerPtr(const ompl::control::SpaceInformation*)', 'DirectedControlSamplerAllocator', 'Directed control sampler allocator') self.add_function_wrapper( 'void(const ompl::base::State*, const ompl::control::Control*, const double, ' 'ompl::base::State*)', 'StatePropagatorFn', 'State propagator function') self.add_function_wrapper('double(int, int)', 'EdgeCostFactorFn', \ 'Syclop edge cost factor function') self.add_function_wrapper('void(int, int, std::vector<int>&)', 'LeadComputeFn', \ 'Syclop lead compute function') # code generation fails to compile, most likely because of a bug in # Py++'s generation of exposed_decl.pypp.txt. self.ompl_ns.member_functions('getPlannerAllocator').exclude() self.ompl_ns.member_functions('setPlannerAllocator').exclude() self.ompl_ns.namespace('control').class_('SimpleSetup').add_registration_code( 'def("setPlannerAllocator", &ompl::control::SimpleSetup::setPlannerAllocator)') self.ompl_ns.namespace('control').class_('SimpleSetup').add_registration_code( 'def("getPlannerAllocator", &ompl::control::SimpleSetup::getPlannerAllocator, ' \ 'bp::return_value_policy< bp::copy_const_reference >())') # exclude deprecated API function self.ompl_ns.free_function('getDefaultPlanner').exclude() # Do this for all classes that exist with the same name in another namespace # (We also do it for all planners; see below) for cls in ['SimpleSetup', 'SpaceInformation']: self.ompl_ns.namespace('control').class_(cls).wrapper_alias = 'Control%s_wrapper' % cls # Py++ seems to get confused by some methods declared in one module # that are *not* overridden in a derived class in another module. The # Planner class is defined in ompl::base and two of its virtual methods, # setProblemDefinition and checkValidity, and not overridden by most # planners. The code below forces Py++ to do the right thing (or at # least make it work). It seems rather hacky and there may be a better # solution. planners = [p.related_class for p in self.ompl_ns.class_('Planner').recursive_derived] for planner in planners: # many planners exist with the same name in another namespace planner.wrapper_alias = 'Control%s_wrapper' % planner.name planner.add_registration_code( 'def("solve", (::ompl::base::PlannerStatus(::ompl::base::Planner::*)( double ))' \ '(&::ompl::base::Planner::solve), (bp::arg("solveTime")) )') planner.add_registration_code(""" def("setProblemDefinition",&::ompl::base::Planner::setProblemDefinition, &Control%s_wrapper::default_setProblemDefinition, (bp::arg("pdef")) )""" % \ planner.name) planner.add_registration_code(""" def("checkValidity",&::ompl::base::Planner::checkValidity, &Control%s_wrapper::default_checkValidity )""" % planner.name)
def filter_declarations(self): # force ProblemDefinition to be included, because it is used by other modules self.ompl_ns.class_('ProblemDefinition').include() # force the abstract base class Path to be included, because it is used by other modules self.ompl_ns.class_('Path').include() code_generator_t.filter_declarations(self) # rename STL vectors of certain types self.std_ns.class_( 'map< std::string, std::shared_ptr< ompl::base::ProjectionEvaluator > >').rename( 'mapStringToProjectionEvaluator') self.std_ns.class_('vector< ompl::base::State * >').rename('vectorState') try: self.std_ns.class_('vector< ompl::base::State const* >').rename('vectorConstState') except declaration_not_found_t: pass self.std_ns.class_('vector< std::shared_ptr<ompl::base::StateSpace> >').rename( 'vectorStateSpacePtr') #self.std_ns.class_('vector< <ompl::base::PlannerSolution> >').rename( # 'vectorPlannerSolution') self.std_ns.class_('map< std::string, std::shared_ptr<ompl::base::GenericParam> >').rename( 'mapStringToGenericParam') self.std_ns.class_('map< std::string, ompl::base::StateSpace::SubstateLocation >').rename( 'mapStringToSubstateLocation') self.std_ns.class_('vector<ompl::base::PlannerSolution>').rename('vectorPlannerSolution') pairStateDouble = self.std_ns.class_('pair<ompl::base::State *, double>') pairStateDouble.rename('pairStateDouble') pairStateDouble.include() # this operator seems to cause problems with g++-6 pairStateDouble.operators('=').exclude() # rename some templated types self.ompl_ns.class_('SpecificParam< bool >').rename('SpecificParamBool') self.ompl_ns.class_('SpecificParam< char >').rename('SpecificParamChar') self.ompl_ns.class_('SpecificParam< int >').rename('SpecificParamInt') self.ompl_ns.class_('SpecificParam< unsigned int >').rename('SpecificParamUint') self.ompl_ns.class_('SpecificParam< float >').rename('SpecificParamFloat') self.ompl_ns.class_('SpecificParam< double >').rename('SpecificParamDouble') self.ompl_ns.class_('SpecificParam< long double >').rename('SpecificParamLongDouble') self.ompl_ns.class_('SpecificParam< std::basic_string<char> >').rename( 'SpecificParamString') for cls in self.ompl_ns.classes(lambda decl: decl.name.startswith('SpecificParam')): cls.constructors().exclude() # don't export variables that need a wrapper self.ompl_ns.variables(lambda decl: decl.is_wrapper_needed()).exclude() # force StateSpace::allocState to be exported. # (not sure why this is necessary) allocStateFn = self.ompl_ns.class_('StateSpace').member_function('allocState') allocStateFn.include() allocStateFn.call_policies = \ call_policies.return_value_policy(call_policies.reference_existing_object) # rename the abstract base class State to AbstractState state = self.ompl_ns.class_('State') state.rename('AbstractState') # don't export components which is of type State** state = self.ompl_ns.class_('CompoundState') state.variable('components').exclude() state.rename('CompoundStateInternal') # rename a ScopedState<> to State bstate = self.ompl_ns.class_('ScopedState< ompl::base::StateSpace >') bstate.rename('State') bstate.operator('=', arg_types=['::ompl::base::State const &']).exclude() # add array access to double components of state self.add_array_access(bstate, 'double') # loop over all predefined state spaces spaces = [s.related_class.name.replace('StateSpace', '') \ for s in self.ompl_ns.class_('StateSpace').recursive_derived] for stype in spaces: # create a python type for each of their corresponding state types state = self.ompl_ns.class_('ScopedState< ompl::base::%sStateSpace >' % stype) state.rename(stype+'State') state.operator('=', arg_types=['::ompl::base::State const &']).exclude() # add a constructor that allows, e.g., an SE3State to be constructed from a State state.add_registration_code( 'def(bp::init<ompl::base::ScopedState<ompl::base::StateSpace> const &>' \ '(( bp::arg("other") )))') # mark the space statetype as 'internal' to emphasize that it # shouldn't typically be used by a regular python user try: self.ompl_ns.class_(stype + 'StateSpace').decls('StateType').rename( stype + 'StateInternal') except: # ignore derived statespaces that do not define their own StateType pass # add a constructor that allows, e.g., a State to be constructed from a SE3State bstate.add_registration_code( 'def(bp::init<ompl::base::ScopedState<ompl::base::%sStateSpace> const &>' \ '(( bp::arg("other") )))' % stype) # add array access to double components of state self.add_array_access(state, 'double') # I don't know how to export a C-style array of an enum type for stype in ['Dubins', 'ReedsShepp']: self.ompl_ns.enumeration(stype + 'PathSegmentType').exclude() self.ompl_ns.class_(stype + 'Path').exclude() self.ompl_ns.class_(stype + 'StateSpace').member_function( stype[0].lower()+stype[1:]).exclude() # don't expose these utility functions that return double* self.ompl_ns.member_functions('getValueAddressAtIndex').exclude() self.ompl_ns.member_functions('getValueAddressAtName').exclude() self.ompl_ns.member_functions('getValueAddressAtLocation').exclude() # don't export vector<ValueLocation> self.ompl_ns.member_functions('getValueLocations').exclude() # don't export map<std::string, ValueLocation> self.ompl_ns.member_functions('getValueLocationsByName').exclude() # exclude member function for which there are multiple signatures self.ompl_ns.class_('Goal').member_function( 'isSatisfied', arg_types=['::ompl::base::State const *', 'double *']).exclude() # don't expose double* self.ompl_ns.class_('RealVectorStateSpace').class_( 'StateType').variable('values').exclude() try: stateStorage = self.ompl_ns.class_('StateStorage') stateStorage.member_function('getStateSamplerAllocatorRange').exclude() stateStorage.add_registration_code('def("getStateSamplerAllocatorRange", ' \ '&ompl::base::StateStorage::getStateSamplerAllocatorRange)') except declaration_not_found_t: pass cls = self.ompl_ns.class_('PlannerStatus') # rename to something more memorable than the default Py++ name for # the casting operator: # as__scope_ompl_scope_base_scope_PlannerStatus_scope_StatusType cls.operator( lambda decl: decl.name == 'operator ::ompl::base::PlannerStatus::StatusType').rename( 'getStatus') # for python 2.x cls.add_registration_code( 'def("__nonzero__", &ompl::base::PlannerStatus::operator bool)') # for python 3.x cls.add_registration_code( 'def("__bool__", &ompl::base::PlannerStatus::operator bool)') # Using nullptr as a default value in method arguments causes # problems with Boost.Python. # See https://github.com/boostorg/python/issues/60 self.ompl_ns.class_('ProblemDefinition').add_declaration_code('#define nullptr NULL\n') try: for cls in ['AtlasChart', 'AtlasStateSpace', 'ConstrainedStateSpace', \ 'ProjectedStateSpace', 'TangentBundleStateSpace']: self.ompl_ns.class_(cls).add_declaration_code('#define nullptr NULL\n') self.ompl_ns.class_('AtlasChart').member_function('toPolygon').exclude() self.replace_member_function(self.ompl_ns.class_( 'AtlasStateSpace').member_function('printPLY')) self.add_function_wrapper( 'double(ompl::base::AtlasChart *)', 'AtlasChartBiasFunction', 'Bias function for sampling a chart from an atlas.') # add code for numpy.array <-> Eigen conversions self.mb.add_declaration_code(open(join(dirname(__file__), \ 'numpy_eigen.cpp'), 'r').read()) self.mb.add_registration_code(""" EIGEN_ARRAY_CONVERTER(Eigen::MatrixXd, 2) EIGEN_ARRAY_CONVERTER(Eigen::VectorXd, 1) """) self.mb.add_registration_code('np::initialize();', tail=False) self.add_array_access(self.ompl_ns.class_( 'ConstrainedStateSpace').class_('StateType'), 'double') for cls in [self.ompl_ns.class_('Constraint'), self.ompl_ns.class_('ConstraintIntersection')]: for method in ['function', 'jacobian']: cls.member_function(method, arg_types=[ '::Eigen::Ref<const Eigen::Matrix<double, -1, 1, 0, -1, 1>, ' '0, Eigen::InnerStride<1> > const &', None]).add_transformation(FT.input(0)) cls = self.ompl_ns.class_('Constraint') for method in ['distance', 'isSatisfied']: cls.member_function(method, arg_types=[ '::Eigen::Ref<const Eigen::Matrix<double, -1, 1, 0, -1, 1>, ' '0, Eigen::InnerStride<1> > const &']).add_transformation(FT.input(0)) except: # python bindings for constrained planning code is only generated # if boost.numpy was found pass # Exclude PlannerData::getEdges function that returns a map of PlannerDataEdge* for now #self.ompl_ns.class_('PlannerData').member_functions('getEdges').exclude() #self.std_ns.class_('map< unsigned int, ompl::base::PlannerDataEdge const*>').include() mapUintToPlannerDataEdge_cls = self.std_ns.class_( 'map< unsigned int, const ompl::base::PlannerDataEdge *>') mapUintToPlannerDataEdge_cls.rename('mapUintToPlannerDataEdge') mapUintToPlannerDataEdge_cls.indexing_suite.call_policies = \ call_policies.return_value_policy(call_policies.reference_existing_object) # Remove Boost.Graph representation from PlannerData plannerData = self.ompl_ns.class_('PlannerData') plannerData.member_functions('toBoostGraph').exclude() # Make PlannerData printable self.replace_member_function(plannerData.member_function('printGraphviz')) self.replace_member_function(plannerData.member_function('printGraphML')) # serialize passes archive by reference which causes problems self.ompl_ns.class_('PlannerDataVertex').member_functions('serialize').exclude() self.ompl_ns.class_('PlannerDataEdge').member_functions('serialize').exclude() # add array indexing to the RealVectorState self.add_array_access(self.ompl_ns.class_('RealVectorStateSpace').class_('StateType')) # make objects printable that have a print function self.replace_member_functions(self.ompl_ns.member_functions('print')) # handle special case (abstract base class with pure virtual method) self.ompl_ns.class_('Path').add_wrapper_code( 'virtual void print(std::ostream&) const {}') # make settings printable self.replace_member_functions(self.ompl_ns.member_functions('printSettings')) # make properties printable self.replace_member_functions(self.ompl_ns.member_functions('printProperties')) # make states printable self.replace_member_functions(self.ompl_ns.member_functions('printState')) # make list of available projections printable self.replace_member_functions(self.ompl_ns.member_functions('printProjections')) # make projections printable self.replace_member_functions(self.ompl_ns.member_functions('printProjection')) # make state space diagram printable self.replace_member_function(self.ompl_ns.class_('StateSpace').member_function('Diagram')) # make state space list printable self.replace_member_function(self.ompl_ns.class_('StateSpace').member_function('List')) # add wrappers for std::function types self.add_function_wrapper('bool(const ompl::base::GoalLazySamples*, ompl::base::State*)', \ 'GoalSamplingFn', 'Goal sampling function') self.add_function_wrapper('void(const ompl::base::State*)', \ 'NewStateCallbackFn', 'New state callback function') self.add_function_wrapper( 'ompl::base::PlannerPtr(const ompl::base::SpaceInformationPtr&)', 'PlannerAllocator', 'Planner allocator') self.add_function_wrapper('bool()', \ 'PlannerTerminationConditionFn', 'Planner termination condition function') self.add_function_wrapper('bool(const ompl::base::State*)', \ 'StateValidityCheckerFn', 'State validity checker function') self.add_function_wrapper('ompl::base::StateSamplerPtr(const ompl::base::StateSpace*)', \ 'StateSamplerAllocator', 'State sampler allocator') self.add_function_wrapper( 'ompl::base::ValidStateSamplerPtr(ompl::base::SpaceInformation const*)', 'ValidStateSamplerAllocator', 'Valid state allocator function') self.add_function_wrapper('double(const ompl::base::PlannerDataVertex&, ' \ 'const ompl::base::PlannerDataVertex&, const ompl::base::PlannerDataEdge&)', \ 'EdgeWeightFn', 'Edge weight function') self.add_function_wrapper( 'ompl::base::Cost(const ompl::base::State*, const ompl::base::Goal*)', 'CostToGoHeuristic', 'Cost-to-go heuristic for optimizing planners') self.add_function_wrapper('std::string()', 'PlannerProgressProperty', \ 'Function that returns stringified value of a property while a planner is running') # rename SamplerSelectors self.ompl_ns.class_('SamplerSelector< ompl::base::StateSampler >').rename( 'StateSamplerSelector') self.ompl_ns.class_('SamplerSelector< ompl::base::ValidStateSampler >').rename( 'ValidStateSamplerSelector') try: cls = self.ompl_ns.class_('StateStorage').member_functions('load') self.ompl_ns.class_('StateStorage').member_function('load', \ arg_types=['::std::istream &']).exclude() self.ompl_ns.class_('StateStorage').member_function('store', \ arg_types=['::std::ostream &']).exclude() except declaration_not_found_t: pass
def generate(defined_symbols, extraIncludes): messages.disable( messages.W1005 # using a non public variable type for arguments or returns , messages.W1006 # `Py++` need your # help to expose function that takes > as argument/returns C++ arrays. # Take a look on "Function Transformation" > functionality and define # the transformation. , messages.W1007 # more than 10 args -> BOOST_PYTHON_MAX_ARITY is set , messages.W1009 # execution error W1009: The function takes as argument (name=pFunIdx, pos=1) > # non-const reference to Python immutable type - function could not be called > from Python , messages.W1014 # "operator*" is not supported. See , messages.W1016 # `Py++` does not exports non-const casting operators # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X , messages.W1023 # Py++` will generate class wrapper - there are few functions that should be # redefined in class wrapper , messages.W1025 # `Py++` will generate class wrapper - class contains "c_" - T* > member variable , messages.W1026 # `Py++` will generate class wrapper - class contains "arr_" - T& > member variable , messages.W1027 # `Py++` will generate class wrapper - class contains "mat_" - > array member variable , messages.W1035 # error. `Py++` can not expose static pointer member variables. , messages.W1036 # error. `Py++` can not expose pointer to Python immutable > member variables. This # could be changed in future. , messages.W1040 # error. The declaration is unexposed, but there are other > declarations, which # refer to it. This could cause "no to_python converter > found" run # time error # This is serious and lead to RuntimeError: `Py++` is going to write different content to the same file , messages.W1047 # There are two or more classes that use same > alias("MatElement"). Duplicated aliases causes # few problems, but the main one > is that some of the classes will not # be exposed to Python.Other classes : > , messages.W1049 # This method could not be overriden in Python - method returns > # reference to local variable! , messages.W1052 # `Py++` will not expose free operator ) logger.debug("Install SRC: ", os.path.abspath(__file__)) logger.debug("Execute from: ", os.getcwd()) sourcedir = os.path.dirname(os.path.abspath(__file__)) sourceHeader = os.path.abspath(sourcedir + "/" + r"pygimli.h") gimliInclude = os.path.dirname( os.path.abspath(sourcedir + "/../src/" + r"gimli.h")) settings.includesPaths.append(gimliInclude) xml_cached_fc = parser.create_cached_source_fc( sourceHeader, settings.module_name + '.cache') import platform defines = ['PYGIMLI_CAST', 'HAVE_BOOST_THREAD_HPP'] caster = 'gccxml' compiler_path = options.clang if platform.system() == 'Windows': if platform.architecture()[0] == '64bit': #compiler_path = 'C:/msys64/mingw64/bin/clang++' if sys.platform == 'darwin': pass else: defines.append('_WIN64') defines.append('MS_WIN64') logger.info('Marking win64 for gccxml') else: pass #compiler_path = 'C:/msys32/mingw32/bin/clang++' if len(compiler_path) == 0: compiler_path = None for define in [settings.gimli_defines, defined_symbols]: if len(define) > 0: defines.append(define) try: if sys.platform == 'win32': # os.name == 'nt' (default on my mingw)results in wrong commandline # for gccxml os.name = 'mingw' casterpath = settings.caster_path.replace('\\', '\\\\') casterpath = settings.caster_path.replace('/', '\\') if 'gccxml' not in casterpath: caster = 'castxml' if '.exe' not in casterpath: casterpath += '\\' + caster + '.exe' else: casterpath = settings.caster_path if 'gccxml' not in casterpath: caster = 'castxml' except Exception as e: logger.info("caster_path=%s" % casterpath) logger.info(str(e)) raise Exception("Problems determine castxml binary") settings.includesPaths.insert(0, os.path.abspath(extraIncludes)) logger.info("caster_path=%s" % casterpath) logger.info("working_directory=%s" % settings.gimli_path) logger.info("include_paths=%s" % settings.includesPaths) logger.info("define_symbols=%s" % defines) logger.info("compiler_path=%s" % compiler_path) logger.info("indexing_suite_version=2") xml_generator_config = parser.xml_generator_configuration_t( xml_generator=caster, xml_generator_path=casterpath, working_directory=settings.gimli_path, include_paths=settings.includesPaths, define_symbols=defines, ignore_gccxml_output=False, cflags="", compiler_path=compiler_path) mb = module_builder.module_builder_t( [xml_cached_fc], indexing_suite_version=2, xml_generator_config=xml_generator_config ) logger.info("Reading of c++ sources done.") mb.classes().always_expose_using_scope = True mb.calldefs().create_with_signature = True global_ns = mb.global_ns global_ns.exclude() main_ns = global_ns.namespace(MAIN_NAMESPACE) main_ns.include() # for c in main_ns.free_functions(): # print(c) # if 'pow' in c.name: # print(c) # print(c.name) # if c.decl_string.startswith('::GIMLI::pow'): # print(c) # print(c.name) # sys.exit() logger.info("Apply handmade wrappers.") try: hand_made_wrappers.apply(mb) except BaseException as e: print(e) logger.info("Apply custom rvalues.") # START manual r-value converters rvalue_converters = [ 'register_pytuple_to_rvector3_conversion', 'register_pysequence_to_rvector_conversion', # 'register_pysequence_to_bvector_conversion', 'register_pysequence_to_indexvector_conversion', 'register_pysequence_to_r3vector_conversion', 'register_pysequence_to_StdVectorRVector3_conversion', # 'register_rvector_to_ndarray_conversion', ] for converter in rvalue_converters: mb.add_declaration_code('void %s();' % converter) mb.add_registration_code('%s();' % converter) # END manual r-value converters custom_rvalue_path = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp') logger.info("Starting to exclude stuff that we don't need " "or that is known to be spurious.") exclude(main_ns.variables, name=[ 'Triangle6_S1', 'Triangle6_S2', 'Triangle6_S3', 'HexahedronFacesID', 'Hexahedron20FacesID', 'TetrahedronFacesID', 'HexahedronSplit5TetID', 'HexahedronSplit6TetID', 'TriPrismFacesID', 'TriPrimSplit3TetID', 'NodeCoordinates', 'EdgeCoordinates', 'TriCoordinates', 'QuadCoordinates', 'TetCoordinates', 'HexCoordinates', 'PrismCoordinates', 'PyramidCoordinates', 'PyramidFacesID', 'Tet10NodeSplit', 'Tet10NodeSplitZienk', 'Hex20NodeSplit', 'Prism15NodeSplit', 'Pyramid13NodeSplit' ] ) exclude(main_ns.free_functions, return_type=[ 'float *', 'float &', "::GIMLI::__VectorExpr< double, " + "GIMLI::__VectorUnaryExprOp< double, " + "GIMLI::VectorIterator< double >, GIMLI::ABS_ > >"], name=[ 'strReplaceBlankWithUnderscore', 'toStr', 'toInt', 'toFloat', 'toDouble', 'str', 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings', 'abs', 'type'] ) exclude(main_ns.free_operators, name=[''], return_type=['::std::ostream &', '::std::istream &'] ) exclude(main_ns.classes, name=['ABS_', 'ACOT', 'ATAN', 'COS', 'COT', 'EXP', 'ABS_', 'LOG', 'LOG10', 'SIGN', 'SIN', 'SQRT', 'SQR', 'TAN', 'TANH', 'PLUS', 'MINUS', 'MULT', 'DIVID', 'BINASSIGN', 'cerrPtr', 'cerrPtrObject', 'coutPtr', 'coutPtrObject', 'deletePtr', 'edge_', 'distancePair_', 'IPCMessage', 'PythonGILSave', ] ) exclude(main_ns.member_functions, name=['begin', 'end', 'val'], return_type=[''] ) exclude(main_ns.member_operators, symbol=['']) for f in main_ns.declarations: if isinstance(f, decl_wrappers.calldef_wrapper.free_function_t): if (str(f.return_type).find('GIMLI::VectorExpr') != -1): f.exclude() ex = ['::GIMLI::MatrixElement', '::GIMLI::__VectorUnaryExprOp', '::GIMLI::__VectorBinaryExprOp', '::GIMLI::__ValVectorExprOp', '::GIMLI::__VectorValExprOp', '::GIMLI::__VectorExpr', '::GIMLI::Expr', '::GIMLI::InversionBase', 'GIMLI::MatrixElement', 'GIMLI::__VectorUnaryExprOp', 'GIMLI::__VectorBinaryExprOp', 'GIMLI::__ValVectorExprOp', 'GIMLI::__VectorValExprOp', 'GIMLI::__VectorExpr', 'GIMLI::Expr', 'GIMLI::InversionBase', 'std::vector<unsigned long', 'std::vector<bool', 'std::vector<double', ] for c in main_ns.free_functions(): for e in ex: if c.decl_string.find(e) > -1: try: c.exclude() logger.debug("Exclude: " + str(c)) except BaseException as _: logger.debug("Fail to exclude: " + str(c)) for c in main_ns.classes(): for e in ex: if c.decl_string.startswith(e): try: c.exclude() logger.debug("Exclude: " + c.name) except BaseException as _: logger.debug("Fail to exclude: " + c.name) try: for mem in c.variables(): try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) except BaseException as _: # print(c, "has no member functions") pass try: for mem in c.constructors(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) for mem in c.member_functions(): for e in ex: if mem.decl_string.find(e) > -1: try: mem.exclude() # logger.info("Exclude: " + str(mem)) except BaseException as _: logger.debug("Fail to exclude: " + str(mem)) except BaseException as _: # print(c, "has no member functions") pass # print('#'*100) # print(c, c.name) if c.name.startswith('Vector<unsigned long>'): # print(' ', c.name) for mem in c.constructors(): # print("mem", mem, mem.decl_string) if mem.decl_string.find('( ::GIMLI::Index )') > -1: logger.debug("Exclude: " + str(mem)) mem.exclude() # print("mem", mem) try: mb.calldefs(access_type_matcher_t('protected')).exclude() mb.calldefs(access_type_matcher_t('private')).exclude() except BaseException as _: pass # setMemberFunctionCallPolicieByReturn(mb, [ '::GIMLI::Node &' # , '::GIMLI::Cell &' # , '::GIMLI::Boundary &' # , '::GIMLI::Shape &' # , '::GIMLI::Node *' # , '::GIMLI::Cell *' # , '::GIMLI::Boundary *' # , '::GIMLI::Shape *' # ] # , call_policies.reference_existing_object) setMemberFunctionCallPolicieByReturn( mb, ['::std::string *', 'float *', 'double *', 'int *', 'long *', 'long int *', 'long long int *', 'unsigned int *', 'long unsigned int *', 'unsigned long long int *', 'long long unsigned int *', '::GIMLI::Index *', '::GIMLI::SIndex *', 'bool *'], call_policies.return_pointee_value) setMemberFunctionCallPolicieByReturn(mb, ['::std::string &', 'float &', 'double &', 'int &', 'long &', 'long int &', 'long long int &', 'unsigned int &', 'long unsigned int &', 'long long unsigned int &', 'unsigned long long int &', '::GIMLI::Index &', '::GIMLI::SIndex &', 'bool &' ], call_policies.return_by_value) # setMemberFunctionCallPolicieByReturn(mb, # ['::GIMLI::VectorIterator<double> &'] # , call_policies.copy_const_reference) # setMemberFunctionCallPolicieByReturn(mb, [ # , 'double &' ] # , call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.reference_existing_object) # call_policies.return_value_policy(call_policies.copy_non_const_reference) # call_policies.return_value_policy(call_policies.copy_const_reference) # addAutoConversions(mb) # excludeMemberByReturn(main_ns, ['::DCFEMLib::SparseMatrix<double> &']) # fun = mb.global_ns.member_functions('begin', allow_empty=True) # for f in fun: # f.exclude() # excludeFreeFunctionsByName(main_ns, ['strReplaceBlankWithUnderscore' # 'toStr', 'toInt', 'toFloat', 'toDouble', # 'getRowSubstrings', 'getNonEmptyRow', 'getSubstrings' ]) # excludeFreeFunctionsByReturn(main_ns, [ 'float *', 'float &' ]) # fun = ns.free_operators(return_type=funct, allow_empty=True) # excludeMemberOperators(main_ns, ['++', '--', '*']) # exclude all that does not match any predefined callpolicie excludeRest = True if excludeRest: mem_funs = mb.calldefs() for mem_fun in mem_funs: if mem_fun.call_policies: continue if not mem_fun.call_policies and \ (declarations.is_reference(mem_fun.return_type) or declarations.is_pointer(mem_fun.return_type)): # print mem_fun # mem_fun.exclude() mem_fun.call_policies = call_policies.return_value_policy( call_policies.reference_existing_object) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_pointee_value) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.return_opaque_pointer) # mem_fun.call_policies = \ # call_policies.return_value_policy(call_policies.copy_non_const_reference) logger.info("Create api documentation from Doxgen comments.") # Now it is the time to give a name to our module from doxygen import doxygen_doc_extractor extractor = doxygen_doc_extractor() logger.info("Create code creator.") mb.build_code_creator(settings.module_name, doc_extractor=extractor) # It is common requirement in software world-each file should have license # mb.code_creator.license = '//Boost Software # License(http://boost.org/more/license_info.html)' # I don't want absolute includes within code mb.code_creator.user_defined_directories.append(os.path.abspath('.')) # And finally we can write code to the disk def ignore(val): pass logger.info("Create bindings code.") mb.split_module('./generated', on_unused_file_found=ignore) additional_files = [ os.path.join( os.path.abspath(os.path.dirname(__file__)), 'custom_rvalue.cpp'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'generators.h'), os.path.join( os.path.abspath(os.path.dirname(__file__)), 'tuples.hpp')] logger.info("Add additional files.") for sourcefile in additional_files: p, filename = os.path.split(sourcefile) destfile = os.path.join('./generated', filename) if not samefile(sourcefile, destfile): shutil.copy(sourcefile, './generated') logger.info("Updated " + filename + "as it was missing or out of date")