David Rose пре 21 година
родитељ
комит
f144196ffe

+ 1 - 1
direct/src/ffi/FFIConstants.py

@@ -4,7 +4,7 @@ from direct.directnotify.DirectNotifyGlobal import *
 notify = directNotify.newCategory("FFI")
 
 # This is the name of the file that the importing code will be stored
-importModuleName = 'PandaModulesUnsqueezed'
+importModuleName = 'PandaModules'
 
 # A header for all the generated files
 generatedHeader = '# This file is automatically generated. It would be unwise to edit.\n\n'

+ 1 - 1
direct/src/ffi/FFIEnvironment.py

@@ -13,7 +13,7 @@ class FFIEnvironment:
     
     def addType(self, typeDescriptor, name):
         if self.types.has_key(name):
-            FFIConstants.notify.warning('Redefining type named: ' + name)
+            FFIConstants.notify.info('Redefining type named: ' + name)
         self.types[name] = typeDescriptor
     
     def getTypeNamed(self, name):

+ 64 - 12
direct/src/ffi/FFIInterrogateDatabase.py

@@ -5,7 +5,7 @@
 
 import string
 import os
-import compileall
+import glob
 
 import FFIEnvironment
 import FFITypes
@@ -15,8 +15,8 @@ import FFIConstants
 import FFIOverload
 from direct.showbase.PythonUtil import *
 
-# FFIConstants.notify.setDebug(1)
 FFIConstants.notify.info('Importing interrogate library: ' + FFIConstants.InterrogateModuleName)
+
 # Note: we do a from lib import * here because we do not want
 # to be dependent on the name of the interrogate library in this code
 exec('from ' + FFIConstants.InterrogateModuleName + ' import *')
@@ -220,7 +220,14 @@ def getTypeName(typeIndex, scoped=0):
 
 class FFIInterrogateDatabase:
 
-    def __init__(self):
+    def __init__(self, etcPath = []):
+        # Temporary try..except for old Panda.
+        try:
+            for dir in etcPath:
+                interrogate_add_search_directory(dir)
+        except:
+            pass
+        
         self.typeIndexMap = {}
         self.environment = FFIEnvironment.FFIEnvironment()
 
@@ -230,7 +237,7 @@ class FFIInterrogateDatabase:
     def constructDescriptor(self, typeIndex):
         if interrogate_type_is_atomic(typeIndex):
             return self.constructPrimitiveTypeDescriptor(typeIndex)
-        
+
         elif interrogate_type_is_enum(typeIndex):
             return self.constructEnumTypeDescriptor(typeIndex)
         
@@ -377,7 +384,6 @@ class FFIInterrogateDatabase:
         descriptor.foreignTypeName = typeName
 
         if (typeName == "TypedObject"):
-            print "Found typed object descriptor"
             FFITypes.TypedObjectDescriptor = descriptor
         
         descriptor.isNested = interrogate_type_is_nested(typeIndex)
@@ -586,9 +592,11 @@ class FFIInterrogateDatabase:
             funcSpec.index = funcIndex
             return funcSpec
     
-    def addTypes(self):
+    def addTypes(self, CModuleName):
         for i in range(interrogate_number_of_global_types()):
-            self.constructDescriptor(interrogate_get_global_type(i))
+            typeIndex = interrogate_get_global_type(i)
+            if self.typeInCModule(typeIndex, CModuleName):
+                self.constructDescriptor(typeIndex)
 
     def addEnvironmentTypes(self):
         for descriptor in self.typeIndexMap.values():
@@ -599,6 +607,11 @@ class FFIInterrogateDatabase:
             moduleName = 'lib' + interrogate_function_module_name(funcIndex)
             return (moduleName == CModuleName)
 
+    def typeInCModule(self, typeIndex, CModuleName):
+        if interrogate_type_has_module_name(typeIndex):
+            moduleName = 'lib' + interrogate_type_module_name(typeIndex)
+            return (moduleName == CModuleName)
+
     
     def constructGlobal(self, globalIndex, CModuleName):
         # We really do not need the descriptor for the value, just
@@ -724,18 +737,57 @@ class FFIInterrogateDatabase:
         file = open(init, 'w')
         file.close()
 
-        # Commented out based upon assumption that squeeze will do the compile
-        #FFIConstants.notify.info( 'Compiling code...')
-        #compileall.compile_dir(codeDir)
+    def squeezeGeneratedCode(self, outputDir):
+
+        # Since we will be squeezing the importModuleName file, rename
+        # the original to something we can import from within the
+        # squeezed version.
+        squeezedName = FFIConstants.importModuleName
+        unsqueezedName = FFIConstants.importModuleName + 'Unsqueezed'
+
+        os.rename(os.path.join(outputDir, squeezedName + '.py'),
+                  os.path.join(outputDir, unsqueezedName + '.py'))
+
+        # Get the list of files to squeeze.  This is all of the .py
+        # files in the output directory except for the __init__.py
+        # file.
+        
+        files = glob.glob(os.path.join(outputDir, '*.py'))
+        init = os.path.join(outputDir, '__init__.py')
+        try:
+            files.remove(init)
+        except:
+            pass
+
+        print "Squeezing %s files." % (len(files))
+
+        from direct.showbase import pandaSqueezeTool
+        
+        pandaSqueezeTool.squeeze(squeezedName, unsqueezedName,
+                                 files, outputDir)
+
+        # Remove the now-squeezed source files.
+        for file in files:
+            os.remove(file)
+        
 
     def generateCodeLib(self, codeDir, extensionsDir, CModuleName):
         # Reset the environment so we are clean from any old modules
         self.environment.reset()
 
         FFIConstants.notify.info('='*50)
-        FFIConstants.notify.info('Importing code library: ' + CModuleName)
+        FFIConstants.notify.warning('Importing code library: ' + CModuleName)
         exec('import ' + CModuleName)
 
+        # Temporary try..except for old Panda.
+        try:
+            errorFlag = interrogate_error_flag()
+        except:
+            errorFlag = False
+
+        if errorFlag:
+            FFIConstants.notify.error("Error reading interrogate database; can't continue.")
+
         self.updateBindings(CModuleName)
         
         FFIConstants.notify.info( 'Generating type code...')
@@ -803,7 +855,7 @@ class FFIInterrogateDatabase:
     def updateBindings(self, CModuleName):
         FFIConstants.notify.info( 'Updating Bindings')
         FFIConstants.notify.info( 'Adding Types...')
-        self.addTypes()
+        self.addTypes(CModuleName)
         FFIConstants.notify.info( 'Adding global values...')
         self.addGlobalValues(CModuleName)
         FFIConstants.notify.info( 'Adding global functions...')

+ 11 - 1
direct/src/ffi/Sources.pp

@@ -1 +1,11 @@
-#define INSTALL_SCRIPTS generatePythonCode genPyCode
+#define INSTALL_SCRIPTS genPyCode.py
+
+// If we're on Win32 without Cygwin, install the genPyCode.bat file;
+// for all other platforms, install the genPyCode sh script.
+#if $[eq $[PLATFORM],Win32]
+  #define INSTALL_SCRIPTS $[INSTALL_SCRIPTS] genPyCode.bat
+#else
+  #define INSTALL_SCRIPTS $[INSTALL_SCRIPTS] genPyCode
+#endif
+
+#include $[THISDIRPREFIX]genPyCode.pp

+ 0 - 124
direct/src/ffi/genPyCode

@@ -1,124 +0,0 @@
-#! /bin/bash
-
-# This is just a helper script to generatePythonCode to cover
-# the three or four cases we use all the time
-# usage: genPyCode [opts] [linux|win-debug|win-release|win-publish|install|release] [other libs]
-
-# -g adds libgateway
-# -t adds libtoontown
-# -p adds libpirates
-# -v adds libvrpn
-# -e adds libpandaegg
-# -n doesn't perform a squeeze
-
-base_dir=$(pwd)
-extra_genPyCode_libs=""
-squeezeFlag=""
-optimizeFlag=""
-ppython=ppython
-ppythonOptimizeFlag=""
-
-while getopts ogtpven flag; do
-  case $flag in
-    o) extra_genPyCode_libs="$extra_genPyCode_libs libotp" ;;
-    g) extra_genPyCode_libs="$extra_genPyCode_libs libgateway" ;;
-    t) extra_genPyCode_libs="$extra_genPyCode_libs libtoontown" ;;
-    p) extra_genPyCode_libs="$extra_genPyCode_libs libpirates" ;;
-    v) extra_genPyCode_libs="$extra_genPyCode_libs libvrpn" ;;
-    e) extra_genPyCode_libs="$extra_genPyCode_libs libpandaegg" ;;
-    n) doSqueeze="-n" ;;
-  esac
-done
-
-shift `expr $OPTIND - 1`
-
-buildType="$1"
-shift
-extra_genPyCode_libs="$extra_genPyCode_libs $*"
-
-if [ "$INSTALL_DIR" != "" ]; then
-    install_dir="$INSTALL_DIR"
-elif [ "$PANDA_INSTALL" != "" ]; then
-    install_dir="$PANDA_INSTALL"
-elif [ "$DIRECT" != "" ]; then
-    install_dir="$DIRECT"
-else
-    install_dir=./install
-fi
-
-if [ "$DIRECT" == "" ]; then
-  if [ "$PLAYER" != "" -a -d "$PLAYER/direct" ]; then
-    DIRECT="$PLAYER/direct"
-  elif [ -d direct ]; then
-    DIRECT=direct
-  else
-    echo "Define PLAYER to point to the panda & direct source root."
-    exit 1
-  fi
-fi
-
-pyDir=$DIRECT/lib/pandac
-extDir=$DIRECT/src/extensions
-pSqueezer=$DIRECT/src/showbase/pandaSqueezer.py
-
-if [ "$buildType" = "linux" ]; then
-    cd $DIRECT/bin
-    ppython -d generatePythonCode -v -d $pyDir $doSqueeze -e $extDir -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-    pSqueezer=$DIRECT/src/showbase/pandaSqueezer.py
-
-elif [ "$buildType" = "win-debug" ]; then
-    cd $DIRECT/bin
-    pyDir="$(cygpath -w $pyDir)"
-    extDir="$(cygpath -w $extDir)"
-    pSqueezer="$(cygpath -w $pSqueezer)"
-    ppython -d generatePythonCode -v -d $pyDir $doSqueeze -e $extDir -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-elif [ "$buildType" = "win-release" ]; then
-    cd $DIRECT/bin
-    pyDir="$(cygpath -w $pyDir)"
-    extDir="$(cygpath -w $extDir)"
-    pSqueezer="$(cygpath -w $pSqueezer)"
-    ppython generatePythonCode -v -d $pyDir $doSqueeze -e $extDir -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-elif [ "$buildType" = "win-publish" ]; then
-    # no assertions, no comments, no docstrings
-    cd $DIRECT/bin
-    pyDir="$(cygpath -w $pyDir)"
-    extDir="$(cygpath -w $extDir)"
-    pSqueezer="$(cygpath -w $pSqueezer)"
-    ppython -OO generatePythonCode -O -v -d $pyDir $doSqueeze -e $extDir -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-    optimizeFlag="-O"
-    ppythonOptimizeFlag="-OO"
-
-elif [ "$buildType" = "install" ]; then
-    # Use relative paths; as installed on a machine without ctattach etc.
-    pyDir=$install_dir/lib/pandac
-    ppython=$install_dir/bin/ppython
-    pSqueezer=$DIRECT/src/showbase/pandaSqueezer.py
-    $ppython -d $install_dir/bin/generatePythonCode -O -v -d $pyDir $doSqueeze -e $DIRECT/src/extensions -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-elif [ "$buildType" = "release" ]; then
-    # Use relative paths; as installed on a machine without ctattach etc.
-    pyDir=$install_dir/lib/pandac
-    ppython=$install_dir/bin/ppython
-    pSqueezer=$DIRECT/src/showbase/pandaSqueezer.py
-    $ppython $install_dir/bin/generatePythonCode -v -d $pyDir $doSqueeze -e $DIRECT/src/extensions -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect $extra_genPyCode_libs || exit
-else
-    echo "Invalid parameter: $buildType"
-    exit 1
-fi
-
-# The squeeze step is now performed as part of generatePythonCode.
-
-#if [ "$fSqueeze" = "squeezeMe" ]; then
-#    echo SQUEEZING PandaModules
-#    rm -f $pyDir/PandaModules.py* $pyDir/__init__.py || exit
-#    $ppython $ppythonOptimizeFlag $pSqueezer $optimizeFlag -d $pyDir || exit
-#    touch $pyDir/__init__.py || exit
-#else
-#    # renaming PandaModulesUnsqueezed.py to PandaModules.py
-#    cd $pyDir              || exit
-#    rm -f PandaModules.py* || exit
-#    echo # junk line needed to keep mv from failing
-#    mv PandaModulesUnsqueezed.py PandaModules.py || exit
-#fi
-
-echo DONE
-

+ 141 - 0
direct/src/ffi/genPyCode.pp

@@ -0,0 +1,141 @@
+//
+// genPyCode.pp
+//
+// This file defines the script to auto-generate a sensible genPyCode
+// for the user based on the Config.pp variables in effect at the time
+// ppremake is run.  The generated script will know which directories
+// to generate its output to, as well as which source files to read
+// for the input.
+//
+
+#define hash #
+
+#define install_dir $[$[upcase $[PACKAGE]]_INSTALL]
+#define install_lib_dir $[or $[INSTALL_LIB_DIR],$[install_dir]/lib]
+#define install_bin_dir $[or $[INSTALL_BIN_DIR],$[install_dir]/bin]
+#define install_igatedb_dir $[or $[INSTALL_IGATEDB_DIR],$[install_dir]/etc]
+
+// If we're on Win32 without Cygwin, generate a genPyCode.bat file;
+// for all other platforms, generate a genPyCode sh script.  Although
+// it's true that on non-Win32 platforms we don't need the script
+// (since the python file itself could be made directly executable),
+// we generate the script anyway to be consistent with Win32, which
+// does require it.
+
+#if $[eq $[PLATFORM],Win32]
+
+#output genPyCode.bat
+@echo off
+python $[osfilename $[install_bin_dir]/genPyCode.py]
+#end genPyCode.bat
+
+#else  // Win32
+
+#output genPyCode
+$[hash]! /bin/sh
+python $[install_bin_dir]/genPyCode.py
+#end genPyCode
+
+#endif  // Win32
+
+#output genPyCode.py
+$[hash]! /usr/bin/env python
+
+import os
+import sys
+import glob
+
+#if $[CTPROJS]
+# This script was generated while the user was using the ctattach
+# tools.  That had better still be the case.
+
+ctprojs = os.getenv('CTPROJS')
+if not ctprojs:
+    print "You are no longer attached to any trees!"
+    sys.exit(1)
+    
+directDir = os.getenv('DIRECT')
+if not directDir:
+    print "You are not attached to DIRECT!"
+    sys.exit(1)
+
+# Make sure that direct/src/showbase/sitecustomize.py gets loaded.
+parent, base = os.path.split(directDir)
+
+if parent not in sys.path:
+    sys.path.append(parent)
+
+import direct.showbase.sitecustomize
+
+#endif
+
+from direct.ffi import DoGenPyCode
+from direct.ffi import FFIConstants
+
+# The following parameters were baked in to this script at the time
+# ppremake was run in Direct.
+DoGenPyCode.outputDir = '$[osfilename $[install_lib_dir]/pandac]'
+DoGenPyCode.extensionsDir = '$[osfilename $[TOPDIR]/src/extensions]'
+DoGenPyCode.interrogateLib = 'libdtoolconfig'
+DoGenPyCode.codeLibs = '$[GENPYCODE_LIBS]'.split()
+DoGenPyCode.etcPath = ['$[osfilename $[install_igatedb_dir]]']
+
+#if $[>= $[OPTIMIZE], 4]
+FFIConstants.wantComments = 0
+FFIConstants.wantTypeChecking = 0
+#endif
+
+#if $[CTPROJS]
+
+# Actually, the user is expected to be using ctattach, so never mind
+# on the baked-in stuff--replace it with the dynamic settings from
+# ctattach.
+DoGenPyCode.outputDir = os.path.join(directDir, 'lib', 'pandac')
+DoGenPyCode.extensionsDir = os.path.join(directDir, 'src', 'extensions')
+DoGenPyCode.etcPath = []
+
+# Look for additional packages (other than the basic three)
+# that the user might be dynamically attached to.
+packages = []
+for proj in ctprojs.split():
+    projName = proj.split(':')[0]
+    packages.append(projName)
+packages.reverse()
+
+for package in packages:
+    packageDir = os.getenv(package)
+    if packageDir:
+        etcDir = os.path.join(packageDir, 'etc')
+        try:
+            inFiles = glob.glob(os.path.join(etcDir, '*.in'))
+        except:
+            inFiles = []
+        if inFiles:
+            DoGenPyCode.etcPath.append(etcDir)
+
+        if package not in ['DTOOL', 'DIRECT', 'PANDA']:
+            libDir = os.path.join(packageDir, 'lib')
+            try:
+                files = os.listdir(libDir)
+            except:
+                files = []
+            for file in files:
+                if os.path.isfile(os.path.join(libDir, file)):
+                    basename, ext = os.path.splitext(file)
+
+                    # Try to import the library.  If we can import it,
+                    # instrument it.
+                    try:
+                        __import__(basename, globals(), locals())
+                        isModule = True
+                    except:
+                        isModule = False
+
+                    if isModule:
+                        if basename not in DoGenPyCode.codeLibs:
+                            DoGenPyCode.codeLibs.append(basename)
+#endif
+
+DoGenPyCode.run()
+
+#end genPyCode.py

+ 0 - 157
direct/src/ffi/generatePythonCode

@@ -1,157 +0,0 @@
-#!/usr/local/bin/python
-
-
-import getopt
-import sys
-import os
-import glob
-from direct.ffi import FFIConstants
-
-# Define a help string for the user
-helpString ="""
-generatePythonCode [opts] -i libtool libcode1 libcode2 ...
-
-Generates Python code for the C++ libraries listed.
-
-Example:
-Linux:
-  ppython -d generatePythonCode -v -d $DIRECT/lib/py -e $DIRECT/src/extensions -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect libtoontown 
-
-Windows debug:
-  ppython -d generatePythonCode -v -d `cygpath -w $DIRECT/lib/py` -e `cygpath -w $DIRECT/src/extensions` -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect libtoontown 
-
-Windows release:
-  ppython generatePythonCode -v -d `cygpath -w $DIRECT/lib/py` -e `cygpath -w $DIRECT/src/extensions` -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect libtoontown 
-
-Windows publish (no assertions, no comments, no docstrings):
-  ppython -OO generatePythonCode -O -v -d `cygpath -w $DIRECT/lib/py` -e `cygpath -w $DIRECT/src/extensions` -i libdtoolconfig libpandaexpress libpanda libpandaphysics libdirect libtoontown 
-
-
-Options:
-  -h          print this message
-  -v          verbose
-  -d dir      directory to write output code       
-  -e dir      directory to pull extension code from       
-  -i lib      interrogate library
-  -O          no C++ comments or assertion statements
-  -n          Don't use squeezeTool to squeeze the result into one .pyz file
-"""
-
-# Initialize variables
-outputDir = ''
-extensionsDir = ''
-interrogateLib = ''
-codeLibs = []
-doSqueeze = True
-    
-
-# Extract the args the user passed in
-try:
-    opts, pargs = getopt.getopt(sys.argv[1:], 'hvOd:e:i:n')
-except Exception, e:
-    # User passed in a bad option, print the error and the help, then exit
-    print e
-    print helpString
-    sys.exit()
-
-if len(opts)==0:
-    print helpString
-    sys.exit()
-
-
-# Store the option values into our variables
-for opt in opts:
-    flag, value = opt
-    if (flag == '-h'):
-        print helpString
-        sys.exit()
-    elif (flag == '-v'):
-        FFIConstants.notify.setInfo(1)
-    elif (flag == '-d'):
-        outputDir = value
-    elif (flag == '-e'):
-        extensionsDir = value
-    elif (flag == '-i'):
-        interrogateLib = value
-    elif (flag == '-O'):
-        FFIConstants.wantComments = 0
-        FFIConstants.wantTypeChecking = 0
-    elif (flag == '-n'):
-        doSqueeze = False
-    else:
-        FFIConstants.notify.error('illegal option: ' + flag)
-
-# Store the program arguments into the codeLibs
-codeLibs = pargs
-
-# Now do some error checking and verbose output
-if (not interrogateLib):
-    FFIConstants.notify.error('You must specify an interrogate library (-i lib)')
-else:
-    FFIConstants.notify.info('Setting interrogate library to: ' + interrogateLib)
-    FFIConstants.InterrogateModuleName = interrogateLib
-
-if (not outputDir):
-    FFIConstants.notify.info('Setting output directory to current directory')
-    outputDir = '.'
-elif (not os.path.exists(outputDir)):
-    FFIConstants.notify.info('Directory does not exist, creating: ' + outputDir)
-    os.mkdir(outputDir)
-    FFIConstants.notify.info('Setting output directory to: ' + outputDir)
-else:
-    FFIConstants.notify.info('Setting output directory to: ' + outputDir)
-
-
-if (not extensionsDir):
-    FFIConstants.notify.info('Setting extensions directory to current directory')
-    extensionsDir = '.'
-elif (not os.path.exists(extensionsDir)):
-    FFIConstants.notify.error('Directory does not exists: ' + extensionsDir)
-else:
-    FFIConstants.notify.info('Setting extensions directory to: ' + extensionsDir)
-
-
-if (not codeLibs):
-    FFIConstants.notify.error('You must specify one or more libraries to generate code from')
-else:
-    FFIConstants.notify.info('Generating code for: ' + `codeLibs`)
-    FFIConstants.CodeModuleNameList = codeLibs
-
-# Ok, now we can start generating code
-from direct.ffi import FFIInterrogateDatabase
-db = FFIInterrogateDatabase.FFIInterrogateDatabase()
-db.generateCode(outputDir, extensionsDir)
-
-
-# Remove any leftover junk files in outputDir from a previous run.
-print "outputDir = %s, doSqueeze = %s" % (outputDir, doSqueeze)
-for file in glob.glob(os.path.join(outputDir, 'PandaModules.py*')):
-    print "removing junk %s" % (file)
-    os.remove(file)
-
-if doSqueeze:
-    # Invoke the squeezer.
-    files = glob.glob(os.path.join(outputDir, '*.py'))
-    init = os.path.join(outputDir, '__init__.py')
-    try:
-        files.remove(init)
-    except:
-        pass
-
-    print "Squeezing %s files." % (len(files))
-    
-    from direct.showbase import pandaSqueezeTool
-    pandaSqueezeTool.squeeze("PandaModules", "PandaModulesUnsqueezed",
-                             files, outputDir)
-
-    # Remove the squeezed source files.
-    for file in files:
-        os.remove(file)
-
-else:
-    print "Not squeezing."
-    os.rename(os.path.join(outputDir, 'PandaModulesUnsqueezed.py'),
-              os.path.join(outputDir, 'PandaModules.py'))
-    
-
-