def ManualExclude ( mb ): global_ns = mb.global_ns if MAIN_NAMESPACE: main_ns = global_ns.namespace( MAIN_NAMESPACE ) else: main_ns = global_ns excludes=[] if environment.isLinux(): excludes.append('::btSimulationIslandManager') for e in excludes: print "excluding class", e global_ns.class_(e).exclude() ## these are not yet implemented... excludes = ['::OgreBulletDynamics::RagDoll::rigidityEnable', '::OgreBulletDynamics::RagDoll::ragdollEnable', '::OgreBulletDynamics::RagDoll::isRigidityEnable', '::OgreBulletDynamics::RagDoll::isRagdollEnabled', '::OgreBulletDynamics::RagDoll::isConstraintEnabled', '::OgreBulletDynamics::RagDoll::isCollisionEnabled', '::OgreBulletDynamics::RagDoll::constraintEnable', '::OgreBulletDynamics::RagDoll::collisionEnable' ] for e in excludes: global_ns.member_functions(e).exclude()
def generate_code(): messages.disable( # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X messages.W1020 , messages.W1021 , messages.W1022 , messages.W1023 , messages.W1024 , messages.W1025 , messages.W1026 , messages.W1027 , messages.W1028 , messages.W1029 , messages.W1030 , messages.W1031 # , messages.W1035 # , messages.W1040 # , messages.W1038 # , messages.W1041 , messages.W1036 # pointer to Python immutable member , messages.W1033 # unnamed variables , messages.W1018 # expose unnamed classes , messages.W1049 # returns reference to local variable , messages.W1014 # unsupported '=' operator ) # # Use GCCXML to create the controlling XML file. # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded # NOTE: If you update the source library code you need to manually delete the cache .XML file # xml_cached_fc = parser.create_cached_source_fc( os.path.join( environment.bullet.root_dir, "python_bullet.h" ) , environment.bullet.cache_file ) defined_symbols = [ 'BULLET_EXPORTS', '__GCCXML__', '_MSC_VER', '__MINGW32__' # needed to turn off allocator allignment which boost can't do.. ] defined_symbols.append( 'VERSION_' + environment.bullet.version ) if sys.platform.startswith ( 'linux' ): defined_symbols.append('USE_PTHREADS') # # build the core Py++ system from the GCCXML created source # mb = module_builder.module_builder_t( [ xml_cached_fc ] , gccxml_path=environment.gccxml_bin , working_directory=environment.root_dir , include_paths=environment.bullet.include_dirs , define_symbols=defined_symbols , indexing_suite_version=2 , cflags=environment.bullet.cflags ) # if this module depends on another set it here ## mb.register_module_dependency ( environment.ogre.generated_dir ) # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off mb.constructors().allow_implicit_conversion = False mb.BOOST_PYTHON_MAX_ARITY = 25 mb.classes().always_expose_using_scope = True # # We filter (both include and exclude) specific classes and functions that we want to wrap # global_ns = mb.global_ns global_ns.exclude() if MAIN_NAMESPACE == "" : main_ns = global_ns main_ns.include() else: main_ns = global_ns.namespace( MAIN_NAMESPACE ) main_ns.exclude () AutoInclude ( mb, MAIN_NAMESPACE ) ## note we use our own version, not common_utils common_utils.AutoExclude ( mb, MAIN_NAMESPACE ) ManualInclude ( mb ) # here we fixup functions that expect to modifiy their 'passed' variables ManualTransformations ( mb ) AutoFixes ( mb, MAIN_NAMESPACE ) # # We need to tell boost how to handle calling (and returning from) certain functions # Do this earlier than normal as I need to override the default in ManualFixes common_utils.Set_DefaultCall_Policies ( main_ns ) ManualFixes ( mb ) ManualExclude ( mb ) common_utils.Auto_Functional_Transformation ( main_ns ,special_vars=['btScalar *'] ) # # the manual stuff all done here !!! # hand_made_wrappers.apply( mb ) NoPropClasses = [""] for cls in main_ns.classes(): if cls.name not in NoPropClasses: rec = ogre_properties.ogre_property_recognizer_t() rec.addSetterType ( 'btScalar' ) # this type is a 'float/double' however we need to tell py++ such so it creates setters cls.add_properties( recognizer=rec ) common_utils.Auto_Document( mb, MAIN_NAMESPACE ) ## add additional version information to the module to help identify it correctly common_utils.addDetailVersion ( mb, environment, environment.bullet ) mem_fun = main_ns.member_function('::btVector3::setX') ##print "setter:", property_recognizer_i (mem_fun) if len( mem_fun.arguments ) != 1: print 'False1' if not declarations.is_void( mem_fun.return_type ): print 'False2' if mem_fun.has_const: print 'False3' if mem_fun.overloads: print 'False4' print "OK" ########################################################################################## # # Creating the code. After this step you should not modify/customize declarations. # ########################################################################################## # # extractor = exdoc.doc_extractor( "Ogre" ) # # mb.build_code_creator (module_name='_ogre_' , doc_extractor= extractor ) extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing mb.build_code_creator (module_name='_bullet_' , doc_extractor= extractor ) for inc in environment.bullet.include_dirs: mb.code_creator.user_defined_directories.append(inc ) mb.code_creator.user_defined_directories.append( environment.bullet.generated_dir ) mb.code_creator.replace_included_headers( customization_data.header_files( environment.bullet.version ) ) huge_classes = map( mb.class_, customization_data.huge_classes( environment.bullet.version ) ) mb.split_module(environment.bullet.generated_dir, huge_classes, use_files_sum_repository=False) ## now we need to ensure a series of headers and additional source files are ## copied to the generaated directory.. additional_files=[ os.path.join( os.path.abspath(os.path.dirname(__file__) ), 'python_bullet_masterlist.h' ) ] if environment.isLinux(): #sBulletDNAlen is defined in the cpp file not the header!! additional_files.append ( os.path.join( environment.Config.PATH_Bullet, 'src', 'LinearMath','btSerializer.cpp' ) ) for sourcefile in additional_files: p,filename = os.path.split(sourcefile) destfile = os.path.join(environment.bullet.generated_dir, filename ) if not common_utils.samefile( sourcefile ,destfile ): shutil.copy( sourcefile, environment.bullet.generated_dir ) print "Updated ", filename, "as it was missing or out of date"
def generate_ogrenewt(): xml_cached_fc = parser.create_cached_source_fc( os.path.join( environment.ogrenewt.root_dir, "python_ogrenewt.h" ) , environment.ogrenewt.cache_file ) defined_symbols = [ 'OGRE_NONCLIENT_BUILD','__PYTHONOGRE_BUILD_CODE', 'ogrenewt_NONCLIENT_BUILD','OIS_NONCLIENT_BUILD' ] #, 'OIS_STATIC_BUILD' ] defined_symbols.append( 'VERSION_' + environment.ogrenewt.version ) if environment._USE_THREADS: defined_symbols.append('BOOST_HAS_THREADS') defined_symbols.append('BOOST_HAS_WINTHREADS') if environment.isLinux(): defined_symbols.append('BOOST_IS_ENUM') mb = module_builder.module_builder_t( [ xml_cached_fc ] , gccxml_path=environment.gccxml_bin , working_directory=environment.root_dir , include_paths=environment.ogrenewt.include_dirs , define_symbols=defined_symbols , cflags=environment.ogrenewt.cflags , indexing_suite_version=2 ) ## This module depends on Ogre mb.register_module_dependency ( environment.ogre.generated_dir ) filter_declarations (mb) # # fix shared Ptr's that are defined as references but NOT const... # find_nonconst ( mb.namespace( 'Ogre' ) ) mb.BOOST_PYTHON_MAX_ARITY = 25 mb.classes().always_expose_using_scope = True # # the manual stuff all done here !!! # hand_made_wrappers.apply( mb ) # # We need to tell boost how to handle calling (and returning from) certain functions # set_call_policies ( mb.global_ns.namespace ('OgreNewt') ) # here we fixup functions that expect to modifiy their 'passed' variables # add_transformations ( mb ) # # now add properties # for cls in mb.namespace ('OgreNewt').classes(): cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() ) common_utils.add_LeadingLowerProperties ( cls ) ## add additional version information to the module to help identify it correctly common_utils.addDetailVersion ( mb, environment, environment.ogrenewt ) # create the doc extractor we'll be using extractor = exdoc.doc_extractor("") # #Creating the actual code. After this step you should not modify/customize declarations. # mb.build_code_creator (module_name='_ogrenewt_', doc_extractor= extractor) for incs in environment.ogrenewt.include_dirs: mb.code_creator.user_defined_directories.append( incs ) mb.code_creator.replace_included_headers( customization_data.header_files(environment.ogrenewt.version) ) huge_classes = map( mb.class_, customization_data.huge_classes(environment.ogrenewt.version) ) mb.split_module(environment.ogrenewt.generated_dir, huge_classes) # return_pointee_value_source_path \ # = os.path.join( environment.pyplusplus_install_dir # , 'pyplusplus_dev' # , 'pyplusplus' # , 'code_repository' ) # ## , 'return_pointee_value.hpp' ) ## Removed AJM 1/1/07 # return_pointee_value_target_path \ # = os.path.join( environment.ogrenewt.generated_dir, 'return_pointee_value.hpp' ) # if not os.path.exists( return_pointee_value_target_path ): # shutil.copy( return_pointee_value_source_path, environment.ogrenewt.generated_dir ) if environment.isMac(): ## now we need to ensure a series of headers and additional source files are ## copied to the generated directory.. basePath = os.path.join(environment.Config.PATH_OgreAddons,'ogrenewt', 'OgreNewt_Main') common_utils.copyTree ( sourcePath = os.path.join(basePath, 'inc'), destPath = environment.ogrenewt.generated_dir, recursive= False, extensions = ['h'] ) common_utils.copyTree ( sourcePath = os.path.join(basePath, 'src'), destPath = environment.ogrenewt.generated_dir, recursive= False, collapse = True, # put all the source in a single directory extensions = ['cpp'] )
def generate_code(): if 0: messages.disable( # Warnings 1020 - 1031 are all about why Py++ generates wrapper for class X messages.W1020 , messages.W1021 , messages.W1022 , messages.W1023 , messages.W1024 , messages.W1025 , messages.W1026 , messages.W1027 , messages.W1028 , messages.W1029 , messages.W1030 , messages.W1031 , messages.W1035 , messages.W1040 , messages.W1038 , messages.W1041 , messages.W1036 # pointer to Python immutable member , messages.W1033 # unnamed variables , messages.W1018 # expose unnamed classes , messages.W1049 # returns reference to local variable , messages.W1014 # unsupported '=' operator ) # # Use GCCXML to create the controlling XML file. # If the cache file (../cache/*.xml) doesn't exist it gets created, otherwise it just gets loaded # NOTE: If you update the source library code you need to manually delete the cache .XML file # xml_cached_fc = parser.create_cached_source_fc( os.path.join( environment.ogresdksample.root_dir, "python_ogresdksample.h" ) , environment.ogresdksample.cache_file ) defined_symbols = environment.defined_symbols defined_symbols.append( 'VERSION_' + environment.ogresdksample.version ) print environment.ogresdksample.include_dirs # # build the core Py++ system from the GCCXML created source # mb = module_builder.module_builder_t( [ xml_cached_fc ] , gccxml_path=environment.gccxml_bin , working_directory=environment.root_dir , include_paths=environment.ogresdksample.include_dirs , define_symbols=defined_symbols , indexing_suite_version=2 , cflags=environment.ogresdksample.cflags ) # if this module depends on another set it here mb.register_module_dependency ( environment.ogre.generated_dir ) # normally implicit conversions work OK, however they can cause strange things to happen so safer to leave off mb.constructors().allow_implicit_conversion = False mb.BOOST_PYTHON_MAX_ARITY = 25 mb.classes().always_expose_using_scope = True # # We filter (both include and exclude) specific classes and functions that we want to wrap # global_ns = mb.global_ns global_ns.exclude() main_ns = global_ns.namespace( MAIN_NAMESPACE ) main_ns.include() common_utils.AutoExclude ( mb, MAIN_NAMESPACE ) ManualExclude ( mb ) common_utils.AutoInclude ( mb, MAIN_NAMESPACE ) ManualInclude ( mb ) # here we fixup functions that expect to modifiy their 'passed' variables ManualTransformations ( mb ) AutoFixes ( mb, MAIN_NAMESPACE ) ManualFixes ( mb ) common_utils.Auto_Functional_Transformation ( main_ns ) #, special_vars=[] ) FindProtectedVars ( mb ) # # We need to tell boost how to handle calling (and returning from) certain functions # common_utils.Set_DefaultCall_Policies ( mb.global_ns.namespace ( MAIN_NAMESPACE ) ) # # the manual stuff all done here !!! # hand_made_wrappers.apply( mb ) NoPropClasses = [""] for cls in main_ns.classes(): if cls.name not in NoPropClasses: cls.add_properties( recognizer=ogre_properties.ogre_property_recognizer_t() ) # THIS MUST BE AFTER Auto_Functional_Transformation common_utils.Auto_Document( mb, MAIN_NAMESPACE ) ## add additional version information to the module to help identify it correctly common_utils.addDetailVersion ( mb, environment, environment.ogresdksample ) ########################################################################################## # # Creating the code. After this step you should not modify/customize declarations. # ########################################################################################## extractor = exdoc.doc_extractor() # I'm excluding the UTFstring docs as lots about nothing mb.build_code_creator (module_name='_ogresdksample_' , doc_extractor= extractor ) for inc in environment.ogresdksample.include_dirs: mb.code_creator.user_defined_directories.append(inc ) mb.code_creator.user_defined_directories.append( environment.ogresdksample.generated_dir ) mb.code_creator.replace_included_headers( customization_data.header_files( environment.ogresdksample.version ) ) huge_classes = map( mb.class_, customization_data.huge_classes( environment.ogresdksample.version ) ) mb.split_module(environment.ogresdksample.generated_dir, huge_classes, use_files_sum_repository=False) ## now we need to ensure a series of headers and additional source files are ## copied to the generated directory.. # files = os.listdir( environment.Config.PATH_INCLUDE_sdksample ) # files_filtered = [] # for f in files: # if f.startswith ("Sample") or f.startswith ("FileSystem"): # files_filtered.append (f) # print files_filtered common_utils.copyTree ( sourcePath = environment.Config.PATH_INCLUDE_sdksample, destPath = environment.ogresdksample.generated_dir, recursive=False, extensions=['h'] ) # need the actual implementation file if environment.isWindows(): fileToCopy = ['FileSystemLayerImpl_WIN32.cpp'] elif environment.isLinux(): fileToCopy = ['FileSystemLayerImpl_Unix.cpp'] common_utils.copyTree ( sourcePath = environment.Config.PATH_INCLUDE_sdksample, destPath = environment.ogresdksample.generated_dir, recursive=False, files_in= fileToCopy ) if environment.ogre.version.startswith("1.7"): ## have a code generation issue that needs resolving... filesToFix=['SdkTrayManager.pypp.cpp'] for filename in filesToFix: fname = os.path.join( environment.ogresdksample.generated_dir, filename) try: f = open(fname, 'r') buf = f.read() f.close() if (" MEMCATEGORY_GENERAL" in buf) or ("<MEMCATEGORY_GENERAL" in buf): buf = buf.replace ( " MEMCATEGORY_GENERAL", " Ogre::MEMCATEGORY_GENERAL") buf = buf.replace ( "<MEMCATEGORY_GENERAL", "<Ogre::MEMCATEGORY_GENERAL") f = open ( fname, 'w+') f.write ( buf ) f.close() print "UGLY FIX OK:", fname except: print "ERROR: Unable to fix:", fname
def filter_declarations( mb ): global_ns = mb.global_ns global_ns.exclude() global_ns.namespace('std').class_('pair<float, float>').include() CEGUI_ns = global_ns.namespace( 'CEGUI' ) CEGUI_ns.include() ## not available at link time.. CEGUI_ns.free_functions("lbi_greater").exclude() CEGUI_ns.free_functions("lbi_less").exclude() ## Dumb fix to remove all Properties classes - unfortunately the properties in these classes are indicated as public ## however within their 'parent' class they are defined as private.. ## see MultiLineEditboxProperties ## for cls in mb.global_ns.namespace ('CEGUI').classes(): if "Properties" in cls.decl_string: print "Excluding:", cls.name cls.exclude() ## EventNamespace causes failure when loading the python module ## possibly because of the ugly Properties fix above :) for cls in mb.global_ns.namespace ('CEGUI').classes(): try: cls.variable('EventNamespace').exclude() except: pass ## turns out that in SOME classes this also fails registration (Combodroplist for example) for cls in mb.global_ns.namespace ('CEGUI').classes(): try: cls.variable('WidgetTypeName').exclude() except: pass ## fix due to new gccxml try: global_ns.member_function('::CEGUI::ListboxItem::setSelectionColours', arg_types=['__restrict__ ::CEGUI::colour &']).exclude() global_ns.member_function('::CEGUI::ListboxTextItem::setTextColours', arg_types=['__restrict__ ::CEGUI::colour &']).exclude() except: pass ## Exclude protected and private that are not pure virtual query = declarations.access_type_matcher_t( 'private' ) \ & ~declarations.virtuality_type_matcher_t( declarations.VIRTUALITY_TYPES.PURE_VIRTUAL ) CEGUI_ns.calldefs( query, allow_empty=True ).exclude() ## lets work around a bug in GCCXMl - http://language-binding.net/pygccxml/design.html#patchers draws = mb.member_functions( 'draw' ) # find all the draw functions for draw in draws: for arg in draw.arguments: if arg.default_value == '0ffffffff': arg.default_value = '0xffffffff' ## class to exclude excludes=['::CEGUI::FactoryModule', '::CEGUI::ScriptFunctor', '::CEGUI::CEGUIRQListener', '::CEGUI::RefCounted< CEGUI::FormattedRenderedString >' # not in the debug version ] for e in excludes: try: CEGUI_ns.class_( e ).exclude() except: print "FAILED to exclude:", e ## now have functions in String that return uint arrays a need to be wrapped sc = CEGUI_ns.class_( "String" ) sc.member_functions('data').exclude() sc.member_functions('ptr').exclude() ## and only remove the at functions that are not returning constants ## the const version returns by value which is good, the non const returns a reference which doesn't compile sc.member_function( 'at', lambda decl: decl.has_const == False ).exclude() ## CEGUI::WindowManager::loadWindowLayout can take a function pointer as an agrument whcih isn't supported yet ## so lets remove the versions that expose the pointer lo = CEGUI_ns.class_( 'WindowManager' ).member_function( 'loadWindowLayout', arg_types=[None, None, None, None, None] ) lo.arguments[3].type = lo.arguments[4].type #AJM Not sure how args work so setting the func pointer to a void pointer ## OgreCEGUIRenderer.h has an assumed namespace in one of the default agrs that we need to fix try: orRe = CEGUI_ns.constructor('OgreCEGUIRenderer', arg_types=[None, None, None, None] ) pos = orRe.arguments[1].default_value.index("RENDER_QUEUE_OVERLAY") tempstring = orRe.arguments[1].default_value[:pos]+"::Ogre::"+orRe.arguments[1].default_value[pos:] orRe.arguments[1].default_value = tempstring except: pass # try to force this one.. ## a string one that stops pydoc working against CEGUI CEGUI_ns.class_('ListHeader').variable('SegmentNameSuffix').exclude() #Exclude non default constructors of iterator classes. for cls in CEGUI_ns.classes(): if not declarations.templates.is_instantiation( cls.name ): continue name = declarations.templates.name( cls.name ) if not name.endswith( 'Iterator' ): continue #default constructor does not have arguments constructors = cls.constructors( lambda decl: bool( decl.arguments ) , allow_empty=True , recursive=False ) constructors.exclude() # ## I'm going to exclude all iterators as there is a problem with CEGUIIteratorBase.h for cls in CEGUI_ns.classes(): # # print "checking", cls.name if 'iterator' in cls.name.lower() : cls.exclude() print "Excluding Iterator", cls.name try: # this is in the newer version of cegui so I'm OK if it fails CEGUI_ns.class_('OgreCEGUIResourceProvider').exclude() # it's _ogrePrivate.. except: pass ## Replaced these with 'useful' functions in the handwrappers - take and return python objects CEGUI_ns.class_( "Window" ).member_functions("setUserData").exclude() CEGUI_ns.class_( "Window" ).member_functions("getUserData").exclude() # Py++ doesn't know that this should be noncopyable so we set it here nocopy=['EventSet','GlobalEventSet','MouseCursor','OgreCEGUIRenderer','CEGUIOgreRenderer', ] for c in nocopy: try: CEGUI_ns.class_(c).noncopyable = True except: pass for c in CEGUI_ns.classes(): if c.name.endswith ("Exception"): c.noncopyable=True # changes to latest py++ can gccxml etc June 15 2008 excludes = ['::CEGUI::ItemListBase::getSortCallback', '::CEGUI::OgreRenderer::createOgreImageCodec', '::CEGUI::RefCounted<CEGUI::FormattedRenderedString>::isValid'] for f in excludes: try: CEGUI_ns.member_function(f).exclude() except: print "Couldn't exclude :",f CEGUI_ns.class_('RawDataContainer').exclude() # has pointers that need to be handled -- hopefully not needed CEGUI_ns.member_function("::CEGUI::WindowManager::loadWindowLayout", arg_types=[None,None,None,None,None]).exclude() global_ns.namespace( 'Ogre' ).class_('SceneManager').include(already_exposed=True) global_ns.namespace( 'Ogre' ).class_('RenderWindow').include(already_exposed=True) global_ns.namespace( 'Ogre' ).class_('TexturePtr').include(already_exposed=True) if environment.isLinux(): for c in CEGUI_ns.classes(): if c.name.endswith ('Exception') and c.name != 'Exception' : c.exclude() print "Excluded:", c e = ['::CEGUI::OgreRenderer::destroyOgreImageCodec', # '::CEGUI::FileIOException', ] for c in e: global_ns.member_functions(c).exclude() cls = CEGUI_ns.class_('::CEGUI::RefCounted< CEGUI::BoundSlot >') cls.operator('==').exclude() # not in debug build