mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
*** empty log message ***
This commit is contained in:
parent
1f4c504b42
commit
0901fd9c20
@ -3,10 +3,6 @@
|
|||||||
from DirectNotifyGlobal import *
|
from DirectNotifyGlobal import *
|
||||||
notify = directNotify.newCategory("FFI")
|
notify = directNotify.newCategory("FFI")
|
||||||
|
|
||||||
# This is the name of the file that the global functions and values
|
|
||||||
# will be stored
|
|
||||||
globalModuleName = 'PandaGlobals'
|
|
||||||
|
|
||||||
# This is the name of the file that the importing code will be stored
|
# This is the name of the file that the importing code will be stored
|
||||||
importModuleName = 'PandaModules'
|
importModuleName = 'PandaModules'
|
||||||
|
|
||||||
|
@ -2,8 +2,12 @@ import FFIConstants
|
|||||||
|
|
||||||
class FFIEnvironment:
|
class FFIEnvironment:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.reset()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
self.types = {}
|
self.types = {}
|
||||||
self.globalFunctions = []
|
self.globalFunctions = []
|
||||||
|
self.downcastFunctions = []
|
||||||
self.globalValues = []
|
self.globalValues = []
|
||||||
self.manifests = []
|
self.manifests = []
|
||||||
|
|
||||||
@ -20,6 +24,8 @@ class FFIEnvironment:
|
|||||||
|
|
||||||
def addGlobalFunction(self, typeDescriptor):
|
def addGlobalFunction(self, typeDescriptor):
|
||||||
self.globalFunctions.append(typeDescriptor)
|
self.globalFunctions.append(typeDescriptor)
|
||||||
|
def addDowncastFunction(self, typeDescriptor):
|
||||||
|
self.downcastFunctions.append(typeDescriptor)
|
||||||
def addGlobalValue(self, typeDescriptor):
|
def addGlobalValue(self, typeDescriptor):
|
||||||
self.globalValues.append(typeDescriptor)
|
self.globalValues.append(typeDescriptor)
|
||||||
def addManifest(self, typeDescriptor):
|
def addManifest(self, typeDescriptor):
|
||||||
|
@ -4,26 +4,19 @@ import TypedObject
|
|||||||
|
|
||||||
WrapperClassMap = {}
|
WrapperClassMap = {}
|
||||||
|
|
||||||
|
# For testing, you can turn verbose and debug on
|
||||||
|
FFIConstants.notify.setVerbose(1)
|
||||||
|
FFIConstants.notify.setDebug(1)
|
||||||
|
|
||||||
|
|
||||||
def getDowncastFunctions(thisClass, baseClass, chain):
|
# Register a python class in the type map if it is a typed object
|
||||||
if (thisClass == baseClass):
|
# The type map is used for upcasting and downcasting through
|
||||||
# Found it, return true
|
# the panda inheritance chain
|
||||||
return 1
|
def registerInTypeMap(pythonClass):
|
||||||
elif (len(thisClass.__bases__) == 0):
|
if issubclass(pythonClass, TypedObject.TypedObject):
|
||||||
# Not here, return 0
|
typeIndex = pythonClass.getClassType().getIndex()
|
||||||
return 0
|
WrapperClassMap[typeIndex] = pythonClass
|
||||||
else:
|
|
||||||
# Look recursively in the classes thisClass inherits from
|
|
||||||
for base in thisClass.__bases__:
|
|
||||||
# If it finds it, append the base class's downcast function
|
|
||||||
# to the chain if it has one
|
|
||||||
if getDowncastFunctions(base, baseClass, chain):
|
|
||||||
downcastFuncName = 'downcastTo' + thisClass.__name__
|
|
||||||
if base.__dict__.has_key(downcastFuncName):
|
|
||||||
FFIConstants.notify.debug('Found downcast function %s in %s' % (downcastFuncName, base.__name__))
|
|
||||||
chain.append(base.__dict__[downcastFuncName])
|
|
||||||
return chain
|
|
||||||
|
|
||||||
|
|
||||||
class FFIExternalObject:
|
class FFIExternalObject:
|
||||||
@ -32,23 +25,52 @@ class FFIExternalObject:
|
|||||||
self.userManagesMemory = 0
|
self.userManagesMemory = 0
|
||||||
# Start with a null this pointer
|
# Start with a null this pointer
|
||||||
self.this = 0
|
self.this = 0
|
||||||
|
|
||||||
|
|
||||||
|
def getDowncastFunctions(self, thisClass, baseClass, chain):
|
||||||
|
if (thisClass == baseClass):
|
||||||
|
# Found it, return true
|
||||||
|
return 1
|
||||||
|
elif (len(thisClass.__bases__) == 0):
|
||||||
|
# Not here, return 0
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
# Look recursively in the classes thisClass inherits from
|
||||||
|
for base in thisClass.__bases__:
|
||||||
|
# If it finds it, append the base class's downcast function
|
||||||
|
# to the chain if it has one
|
||||||
|
if self.getDowncastFunctions(base, baseClass, chain):
|
||||||
|
downcastFuncName = ('downcastTo' + thisClass.__name__
|
||||||
|
+ 'From' + base.__name__)
|
||||||
|
# Look over this classes global modules dictionaries
|
||||||
|
# for the downcast function name
|
||||||
|
for globmod in self.__class__.__CModuleDowncasts__:
|
||||||
|
if globmod.__dict__.has_key(downcastFuncName):
|
||||||
|
func = globmod.__dict__[downcastFuncName]
|
||||||
|
FFIConstants.notify.debug('Found downcast function %s in %s'
|
||||||
|
% (downcastFuncName, globmod.__name__))
|
||||||
|
chain.append(func)
|
||||||
|
return chain
|
||||||
|
else:
|
||||||
|
FFIConstants.notify.debug('Did not find downcast function %s in %s'
|
||||||
|
% (downcastFuncName, globmod.__name__))
|
||||||
|
# In any case, return the chain
|
||||||
|
return chain
|
||||||
|
# Probably went up the wrong tree and did not find the rootClass
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
def asExactType(self):
|
|
||||||
return self.getType()
|
|
||||||
|
|
||||||
def isTypedObject(self):
|
|
||||||
return isinstance(self, TypedObject.TypedObject)
|
|
||||||
|
|
||||||
def setPointer(self):
|
def setPointer(self):
|
||||||
if (self.this == 0):
|
if (self.this == 0):
|
||||||
# Null pointer, return None
|
# Null pointer, return None
|
||||||
return None
|
return None
|
||||||
# If it is not a typed object, our work is done, just return the object
|
# If it is not a typed object, our work is done, just return the object
|
||||||
if (not self.isTypedObject()):
|
if (not isinstance(self, TypedObject.TypedObject)):
|
||||||
return self
|
return self
|
||||||
# Ok, it is a typed object. See what type it really is and downcast
|
# Ok, it is a typed object. See what type it really is and downcast
|
||||||
# to that type (if necessary)
|
# to that type (if necessary)
|
||||||
exactWrapperClass = self.wrapperClassForTypeHandle(self.asExactType())
|
exactWrapperClass = self.wrapperClassForTypeHandle(self.getType())
|
||||||
# We do not need to downcast if we already have the same class
|
# We do not need to downcast if we already have the same class
|
||||||
if (exactWrapperClass and (exactWrapperClass != self.__class__)):
|
if (exactWrapperClass and (exactWrapperClass != self.__class__)):
|
||||||
# Create a new wrapper class instance
|
# Create a new wrapper class instance
|
||||||
@ -71,16 +93,10 @@ class FFIExternalObject:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def registerInTypeMap(self):
|
|
||||||
global WrapperClassMap
|
|
||||||
if self.isTypedObject():
|
|
||||||
typeIndex = self.__class__.getClassType().getIndex()
|
|
||||||
WrapperClassMap[typeIndex] = self.__class__
|
|
||||||
|
|
||||||
def downcast(self, specificClass):
|
def downcast(self, specificClass):
|
||||||
FFIConstants.notify.debug('downcasting from %s to %s' % \
|
FFIConstants.notify.debug('downcasting from %s to %s' % \
|
||||||
(self.__class__.__name__, specificClass.__name__))
|
(self.__class__.__name__, specificClass.__name__))
|
||||||
downcastChain = getDowncastFunctions(specificClass, self.__class__, [])
|
downcastChain = self.getDowncastFunctions(specificClass, self.__class__, [])
|
||||||
FFIConstants.notify.debug('downcast chain: ' + `downcastChain`)
|
FFIConstants.notify.debug('downcast chain: ' + `downcastChain`)
|
||||||
newObject = self
|
newObject = self
|
||||||
if (downcastChain == None):
|
if (downcastChain == None):
|
||||||
@ -124,7 +140,4 @@ class FFIExternalObject:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,26 +21,30 @@ FFIConstants.notify.info('Importing interrogate library: ' + FFIConstants.Interr
|
|||||||
# to be dependent on the name of the interrogate library in this code
|
# to be dependent on the name of the interrogate library in this code
|
||||||
exec('from ' + FFIConstants.InterrogateModuleName + ' import *')
|
exec('from ' + FFIConstants.InterrogateModuleName + ' import *')
|
||||||
|
|
||||||
# Import all the C++ modules
|
def constructGlobalFile(codeDir, CModuleName):
|
||||||
for CModuleName in FFIConstants.CodeModuleNameList:
|
|
||||||
FFIConstants.notify.info('Importing code library: ' + CModuleName)
|
|
||||||
exec('import ' + CModuleName)
|
|
||||||
|
|
||||||
def constructGlobalFile(codeDir):
|
|
||||||
"""
|
"""
|
||||||
Open a file that will hold the global values and functions code
|
Open a file that will hold the global values and functions code
|
||||||
"""
|
"""
|
||||||
file = open(os.path.join(codeDir, FFIConstants.globalModuleName + '.py'), 'w')
|
file = open(os.path.join(codeDir, CModuleName + 'Globals' + '.py'), 'w')
|
||||||
return file
|
return file
|
||||||
|
|
||||||
def constructImportFile(codeDir):
|
|
||||||
|
def constructDowncastFile(codeDir, CModuleName):
|
||||||
"""
|
"""
|
||||||
Open a file that will hold the global values and functions code
|
Open a file that will hold the global values and functions code
|
||||||
"""
|
"""
|
||||||
file = open(os.path.join(codeDir, FFIConstants.importModuleName + '.py'), 'w')
|
file = open(os.path.join(codeDir, CModuleName + 'Downcasts' + '.py'), 'w')
|
||||||
return file
|
return file
|
||||||
|
|
||||||
def outputGlobalFileImports(file, methodList):
|
|
||||||
|
def constructImportFile(codeDir, CModuleName):
|
||||||
|
"""
|
||||||
|
Open a file that will hold the global values and functions code
|
||||||
|
"""
|
||||||
|
file = open(os.path.join(codeDir, CModuleName + 'Modules' + '.py'), 'w')
|
||||||
|
return file
|
||||||
|
|
||||||
|
def outputGlobalFileImports(file, methodList, CModuleName):
|
||||||
# Print the standard header
|
# Print the standard header
|
||||||
file.write(FFIConstants.generatedHeader)
|
file.write(FFIConstants.generatedHeader)
|
||||||
|
|
||||||
@ -48,15 +52,34 @@ def outputGlobalFileImports(file, methodList):
|
|||||||
file.write('import types\n')
|
file.write('import types\n')
|
||||||
|
|
||||||
# Import the C modules
|
# Import the C modules
|
||||||
for CModuleName in FFIConstants.CodeModuleNameList:
|
CModuleList = []
|
||||||
|
for method in methodList:
|
||||||
|
if (not (method.typeDescriptor.moduleName in CModuleList)):
|
||||||
|
CModuleList.append(method.typeDescriptor.moduleName)
|
||||||
|
for CModuleName in CModuleList:
|
||||||
file.write('import ' + CModuleName + '\n')
|
file.write('import ' + CModuleName + '\n')
|
||||||
|
|
||||||
moduleList = []
|
moduleList = []
|
||||||
for method in methodList:
|
for method in methodList:
|
||||||
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor()
|
||||||
if (not (returnType.foreignTypeName in moduleList)):
|
returnTypeName = returnType.foreignTypeName
|
||||||
|
if (not (returnTypeName in moduleList)):
|
||||||
if (returnType.__class__ == FFITypes.ClassTypeDescriptor):
|
if (returnType.__class__ == FFITypes.ClassTypeDescriptor):
|
||||||
moduleList.append(returnType.foreignTypeName)
|
moduleList.append(returnTypeName)
|
||||||
|
|
||||||
|
# Look at all the arguments
|
||||||
|
argTypes = method.typeDescriptor.argumentTypes
|
||||||
|
for argType in argTypes:
|
||||||
|
# Get the real return type (not derived)
|
||||||
|
argType = argType.typeDescriptor.recursiveTypeDescriptor()
|
||||||
|
argTypeName = argType.foreignTypeName
|
||||||
|
# Do not put our own module in the import list
|
||||||
|
# Do not put modules already in the list (like a set)
|
||||||
|
if (not (argTypeName in moduleList)):
|
||||||
|
# If this is a class (not a primitive), put it on the list
|
||||||
|
if (argType.__class__ == FFITypes.ClassTypeDescriptor):
|
||||||
|
moduleList.append(argTypeName)
|
||||||
|
|
||||||
|
|
||||||
for moduleName in moduleList:
|
for moduleName in moduleList:
|
||||||
file.write('import ' + moduleName + '\n')
|
file.write('import ' + moduleName + '\n')
|
||||||
@ -64,7 +87,7 @@ def outputGlobalFileImports(file, methodList):
|
|||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
|
|
||||||
def outputImportFileImports(file, typeList):
|
def outputImportFileImports(file, typeList, CModuleName):
|
||||||
"""
|
"""
|
||||||
This is the file that we will import to get all the panda modules
|
This is the file that we will import to get all the panda modules
|
||||||
"""
|
"""
|
||||||
@ -76,10 +99,8 @@ def outputImportFileImports(file, typeList):
|
|||||||
file.write('import ' + FFIConstants.InterrogateModuleName + '\n')
|
file.write('import ' + FFIConstants.InterrogateModuleName + '\n')
|
||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
file.write('# Import the C modules\n')
|
file.write('# Import the C module\n')
|
||||||
for CModuleName in FFIConstants.CodeModuleNameList:
|
file.write('import ' + CModuleName + '\n')
|
||||||
file.write('import ' + CModuleName + '\n')
|
|
||||||
file.write('\n')
|
|
||||||
|
|
||||||
# Filter out only the class and enum type descriptors (not const, pointers, etc)
|
# Filter out only the class and enum type descriptors (not const, pointers, etc)
|
||||||
classTypeList = []
|
classTypeList = []
|
||||||
@ -96,12 +117,9 @@ def outputImportFileImports(file, typeList):
|
|||||||
classTypeList.sort(FFIOverload.inheritanceLevelSort)
|
classTypeList.sort(FFIOverload.inheritanceLevelSort)
|
||||||
|
|
||||||
moduleList = []
|
moduleList = []
|
||||||
for type in classTypeList:
|
for type in classTypeList:
|
||||||
moduleList.append(type.foreignTypeName)
|
moduleList.append(type.foreignTypeName)
|
||||||
|
|
||||||
file.write('import FFIExternalObject\n')
|
|
||||||
file.write('\n')
|
|
||||||
|
|
||||||
file.write('# Import enums into the global name space\n')
|
file.write('# Import enums into the global name space\n')
|
||||||
for type in enumTypeList:
|
for type in enumTypeList:
|
||||||
file.write('from ' + type.enumName + ' import *\n')
|
file.write('from ' + type.enumName + ' import *\n')
|
||||||
@ -113,25 +131,28 @@ def outputImportFileImports(file, typeList):
|
|||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
file.write('# Import the global module file into our name space\n')
|
file.write('# Import the global module file into our name space\n')
|
||||||
file.write('from ' + FFIConstants.globalModuleName + ' import *\n')
|
file.write('from ' + CModuleName + 'Globals' + ' import *\n')
|
||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
file.write('# Now generate the classes\n')
|
file.write('# Generate the classes\n')
|
||||||
for moduleName in moduleList:
|
for moduleName in moduleList:
|
||||||
file.write(moduleName + '.generateClass_' + moduleName + '()\n')
|
file.write(moduleName + '.generateClass_' + moduleName + '()\n')
|
||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
file.write('# Now put the classes in the wrapper class map\n')
|
file.write('# Copy the classes into our own namespace\n')
|
||||||
for moduleName in moduleList:
|
|
||||||
file.write('obj = ' + moduleName + '.' + moduleName + '(None)\n')
|
|
||||||
file.write('obj.registerInTypeMap()\n')
|
|
||||||
file.write('\n')
|
|
||||||
|
|
||||||
file.write('# Now copy the classes into our own namespace\n')
|
|
||||||
for moduleName in moduleList:
|
for moduleName in moduleList:
|
||||||
file.write(moduleName + ' = ' + moduleName + '.' + moduleName + '\n')
|
file.write(moduleName + ' = ' + moduleName + '.' + moduleName + '\n')
|
||||||
file.write('\n')
|
file.write('\n')
|
||||||
|
|
||||||
|
file.write('# Put the classes in the wrapper class map\n')
|
||||||
|
file.write('from FFIExternalObject import registerInTypeMap\n')
|
||||||
|
file.write('\n')
|
||||||
|
for moduleName in moduleList:
|
||||||
|
file.write('registerInTypeMap(' + moduleName + ')\n')
|
||||||
|
file.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generateStaticClass(codeDir):
|
def generateStaticClass(codeDir):
|
||||||
"""
|
"""
|
||||||
Create a file that will hold the static class definition
|
Create a file that will hold the static class definition
|
||||||
@ -472,6 +493,10 @@ class FFIInterrogateDatabase:
|
|||||||
built into the class they are being downcast from. For instance, a method
|
built into the class they are being downcast from. For instance, a method
|
||||||
downcastToNode(ptrBoundedObject) will appear in Node's list of methods
|
downcastToNode(ptrBoundedObject) will appear in Node's list of methods
|
||||||
but should be compiled into BoundedObject's class
|
but should be compiled into BoundedObject's class
|
||||||
|
UPDATE: These are no longer compiled into the from-class. That was
|
||||||
|
preventing the libraries from being independent since the from class
|
||||||
|
now had knowledge of the to class which is potentially in a library
|
||||||
|
downstream. Now these functions are just global functions
|
||||||
"""
|
"""
|
||||||
numFuncs = interrogate_type_number_of_derivations(typeIndex)
|
numFuncs = interrogate_type_number_of_derivations(typeIndex)
|
||||||
for i in range(numFuncs):
|
for i in range(numFuncs):
|
||||||
@ -481,15 +506,21 @@ class FFIInterrogateDatabase:
|
|||||||
funcIndex = interrogate_type_get_downcast(typeIndex, i)
|
funcIndex = interrogate_type_get_downcast(typeIndex, i)
|
||||||
typeDescs = self.constructFunctionTypeDescriptors(funcIndex)
|
typeDescs = self.constructFunctionTypeDescriptors(funcIndex)
|
||||||
for typeDesc in typeDescs:
|
for typeDesc in typeDescs:
|
||||||
funcSpec = FFISpecs.MethodSpecification()
|
funcSpec = FFISpecs.GlobalFunctionSpecification()
|
||||||
funcSpec.name = FFIRename.methodNameFromCppName(
|
funcSpec.name = FFIRename.methodNameFromCppName(
|
||||||
interrogate_function_name(funcIndex))
|
interrogate_function_name(funcIndex))
|
||||||
funcSpec.typeDescriptor = typeDesc
|
funcSpec.typeDescriptor = typeDesc
|
||||||
funcSpec.index = funcIndex
|
funcSpec.index = funcIndex
|
||||||
# Here we look for the class in the first argument
|
# Here we look for the class in the first argument
|
||||||
fromClass = typeDesc.argumentTypes[0].typeDescriptor.recursiveTypeDescriptor()
|
fromClass = typeDesc.argumentTypes[0].typeDescriptor.recursiveTypeDescriptor()
|
||||||
|
|
||||||
|
# Append the from class name on the method to uniquify it now
|
||||||
|
# that these are global methods
|
||||||
|
funcSpec.name = funcSpec.name + 'From' + fromClass.foreignTypeName
|
||||||
|
|
||||||
# Append this funcSpec to that class's downcast methods
|
# Append this funcSpec to that class's downcast methods
|
||||||
fromClass.downcastMethods.append(funcSpec)
|
# fromClass.downcastMethods.append(funcSpec)
|
||||||
|
self.environment.addDowncastFunction(funcSpec)
|
||||||
|
|
||||||
def constructConstructorSpecifications(self, typeIndex):
|
def constructConstructorSpecifications(self, typeIndex):
|
||||||
funcSpecs = []
|
funcSpecs = []
|
||||||
@ -532,8 +563,14 @@ class FFIInterrogateDatabase:
|
|||||||
def addEnvironmentTypes(self):
|
def addEnvironmentTypes(self):
|
||||||
for descriptor in self.typeIndexMap.values():
|
for descriptor in self.typeIndexMap.values():
|
||||||
self.environment.addType(descriptor, descriptor.foreignTypeName)
|
self.environment.addType(descriptor, descriptor.foreignTypeName)
|
||||||
|
|
||||||
|
def functionInCModule(self, funcIndex, CModuleName):
|
||||||
|
if interrogate_function_has_module_name(funcIndex):
|
||||||
|
moduleName = 'lib' + interrogate_function_module_name(funcIndex)
|
||||||
|
return (moduleName == CModuleName)
|
||||||
|
|
||||||
|
|
||||||
def constructGlobal(self, globalIndex):
|
def constructGlobal(self, globalIndex, CModuleName):
|
||||||
# We really do not need the descriptor for the value, just
|
# We really do not need the descriptor for the value, just
|
||||||
# the getter and setter
|
# the getter and setter
|
||||||
# typeIndex = interrogate_element_type(globalIndex)
|
# typeIndex = interrogate_element_type(globalIndex)
|
||||||
@ -541,12 +578,18 @@ class FFIInterrogateDatabase:
|
|||||||
|
|
||||||
if interrogate_element_has_getter(globalIndex):
|
if interrogate_element_has_getter(globalIndex):
|
||||||
getterIndex = interrogate_element_getter(globalIndex)
|
getterIndex = interrogate_element_getter(globalIndex)
|
||||||
|
# If this function is not in this Cmodule just return
|
||||||
|
if not self.functionInCModule(getterIndex, CModuleName):
|
||||||
|
return None
|
||||||
getter = self.constructGlobalFunction(getterIndex)
|
getter = self.constructGlobalFunction(getterIndex)
|
||||||
else:
|
else:
|
||||||
getter = None
|
getter = None
|
||||||
|
|
||||||
if interrogate_element_has_setter(globalIndex):
|
if interrogate_element_has_setter(globalIndex):
|
||||||
setterIndex = interrogate_element_setter(globalIndex)
|
setterIndex = interrogate_element_setter(globalIndex)
|
||||||
|
# If this function is not in this Cmodule just return
|
||||||
|
if not self.functionInCModule(setterIndex, CModuleName):
|
||||||
|
return None
|
||||||
setter = self.constructGlobalFunction(setterIndex)
|
setter = self.constructGlobalFunction(setterIndex)
|
||||||
else:
|
else:
|
||||||
setter = None
|
setter = None
|
||||||
@ -570,21 +613,23 @@ class FFIInterrogateDatabase:
|
|||||||
funcSpec.index = globalIndex
|
funcSpec.index = globalIndex
|
||||||
return funcSpec
|
return funcSpec
|
||||||
|
|
||||||
def addGlobalFunctions(self):
|
def addGlobalFunctions(self, CModuleName):
|
||||||
numGlobals = interrogate_number_of_global_functions()
|
numGlobals = interrogate_number_of_global_functions()
|
||||||
for i in range(numGlobals):
|
for i in range(numGlobals):
|
||||||
funcIndex = interrogate_get_global_function(i)
|
funcIndex = interrogate_get_global_function(i)
|
||||||
newGlob = self.constructGlobalFunction(funcIndex)
|
if self.functionInCModule(funcIndex, CModuleName):
|
||||||
if newGlob:
|
newGlob = self.constructGlobalFunction(funcIndex)
|
||||||
self.environment.addGlobalFunction(newGlob)
|
if newGlob:
|
||||||
|
self.environment.addGlobalFunction(newGlob)
|
||||||
|
|
||||||
|
"""
|
||||||
# Take all the global functions that have a Panda Class as their
|
# Take all the global functions that have a Panda Class as their
|
||||||
# first argument and make them class methods on that class
|
# first argument and make them class methods on that class
|
||||||
# For example the global function
|
# For example the global function
|
||||||
# get_distance(node1, node2)
|
# get_distance(node1, node2)
|
||||||
# becomes:
|
# becomes:
|
||||||
# node1.getDistance(node2)
|
# node1.getDistance(node2)
|
||||||
|
|
||||||
# Functions that do not get moved will be stored here temporarily
|
# Functions that do not get moved will be stored here temporarily
|
||||||
tempGlobalFunctions = []
|
tempGlobalFunctions = []
|
||||||
for funcSpec in self.environment.globalFunctions:
|
for funcSpec in self.environment.globalFunctions:
|
||||||
@ -602,15 +647,17 @@ class FFIInterrogateDatabase:
|
|||||||
else:
|
else:
|
||||||
# Copy this function into the temp list
|
# Copy this function into the temp list
|
||||||
tempGlobalFunctions.append(funcSpec)
|
tempGlobalFunctions.append(funcSpec)
|
||||||
# Now copy the temp list back over the real list
|
# Copy the temp list back over the real list
|
||||||
self.environment.globalFunctions = tempGlobalFunctions
|
self.environment.globalFunctions = tempGlobalFunctions
|
||||||
|
"""
|
||||||
|
|
||||||
def addGlobalValues(self):
|
def addGlobalValues(self, CModuleName):
|
||||||
numGlobals = interrogate_number_of_globals()
|
numGlobals = interrogate_number_of_globals()
|
||||||
for i in range(numGlobals):
|
for i in range(numGlobals):
|
||||||
globalIndex = interrogate_get_global(i)
|
globalIndex = interrogate_get_global(i)
|
||||||
newGlob = self.constructGlobal(globalIndex)
|
newGlob = self.constructGlobal(globalIndex, CModuleName)
|
||||||
self.environment.addGlobalValue(newGlob)
|
if newGlob:
|
||||||
|
self.environment.addGlobalValue(newGlob)
|
||||||
|
|
||||||
|
|
||||||
def constructManifest(self, manifestIndex):
|
def constructManifest(self, manifestIndex):
|
||||||
@ -656,18 +703,50 @@ class FFIInterrogateDatabase:
|
|||||||
FFIConstants.notify.info( 'Generating static class...')
|
FFIConstants.notify.info( 'Generating static class...')
|
||||||
generateStaticClass(codeDir)
|
generateStaticClass(codeDir)
|
||||||
|
|
||||||
|
# Import all the C++ modules
|
||||||
|
for CModuleName in FFIConstants.CodeModuleNameList:
|
||||||
|
self.generateCodeLib(codeDir, extensionsDir, CModuleName)
|
||||||
|
|
||||||
|
# For convenience, output a file that imports all the c module files
|
||||||
|
file = open(os.path.join(codeDir, FFIConstants.importModuleName + '.py'), 'w')
|
||||||
|
for CModuleName in FFIConstants.CodeModuleNameList:
|
||||||
|
file.write('from ' + CModuleName + 'Modules import *\n')
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
FFIConstants.notify.info( 'Compiling code...')
|
||||||
|
compileall.compile_dir(codeDir)
|
||||||
|
|
||||||
|
def generateCodeLib(self, codeDir, extensionsDir, CModuleName):
|
||||||
|
# Reset the environment so we are clean from any old modules
|
||||||
|
self.environment.reset()
|
||||||
|
|
||||||
|
FFIConstants.notify.info('==================================================')
|
||||||
|
FFIConstants.notify.info('Importing code library: ' + CModuleName)
|
||||||
|
exec('import ' + CModuleName)
|
||||||
|
|
||||||
|
self.updateBindings(CModuleName)
|
||||||
|
|
||||||
FFIConstants.notify.info( 'Generating type code...')
|
FFIConstants.notify.info( 'Generating type code...')
|
||||||
for type in self.environment.types.values():
|
for type in self.environment.types.values():
|
||||||
# Do not generate code for nested types at the top level
|
# Do not generate code for nested types at the top level
|
||||||
if (not type.isNested):
|
if (not type.isNested):
|
||||||
type.generateGlobalCode(codeDir, extensionsDir)
|
type.generateGlobalCode(codeDir, extensionsDir)
|
||||||
|
|
||||||
|
|
||||||
|
FFIConstants.notify.info( 'Generating global downcast code...')
|
||||||
|
downcastFile = constructDowncastFile(codeDir, CModuleName)
|
||||||
|
# Output all the imports based on this list of functions
|
||||||
|
outputGlobalFileImports(downcastFile, self.environment.downcastFunctions, CModuleName)
|
||||||
|
for type in self.environment.downcastFunctions:
|
||||||
|
type.generateGlobalCode(downcastFile)
|
||||||
|
|
||||||
FFIConstants.notify.info( 'Generating global value code...')
|
FFIConstants.notify.info( 'Generating global value code...')
|
||||||
globalFile = constructGlobalFile(codeDir)
|
globalFile = constructGlobalFile(codeDir, CModuleName)
|
||||||
|
|
||||||
# Make a list of all the global functions. This includes the normal
|
# Make a list of all the global functions. This includes the normal
|
||||||
# global functions as well as the getters and setters on all the
|
# global functions as well as the getters and setters on all the
|
||||||
# global values. This list is used to figure out what files to import
|
# global values. This list is used to figure out what files to import
|
||||||
|
# Only include the global functions from the current C module
|
||||||
globalFunctions = self.environment.globalFunctions
|
globalFunctions = self.environment.globalFunctions
|
||||||
for globalValue in self.environment.globalValues:
|
for globalValue in self.environment.globalValues:
|
||||||
if globalValue.getter:
|
if globalValue.getter:
|
||||||
@ -675,7 +754,7 @@ class FFIInterrogateDatabase:
|
|||||||
if globalValue.setter:
|
if globalValue.setter:
|
||||||
globalFunctions.append(globalValue.setter)
|
globalFunctions.append(globalValue.setter)
|
||||||
# Output all the imports based on this list of functions
|
# Output all the imports based on this list of functions
|
||||||
outputGlobalFileImports(globalFile, globalFunctions)
|
outputGlobalFileImports(globalFile, globalFunctions, CModuleName)
|
||||||
|
|
||||||
FFIConstants.notify.info( 'Generating global value code...')
|
FFIConstants.notify.info( 'Generating global value code...')
|
||||||
for type in self.environment.globalValues:
|
for type in self.environment.globalValues:
|
||||||
@ -692,21 +771,17 @@ class FFIInterrogateDatabase:
|
|||||||
globalFile.close()
|
globalFile.close()
|
||||||
|
|
||||||
FFIConstants.notify.info( 'Generating import code...')
|
FFIConstants.notify.info( 'Generating import code...')
|
||||||
importFile = constructImportFile(codeDir)
|
importFile = constructImportFile(codeDir, CModuleName)
|
||||||
outputImportFileImports(importFile, self.environment.types.values())
|
outputImportFileImports(importFile, self.environment.types.values(), CModuleName)
|
||||||
|
|
||||||
FFIConstants.notify.info( 'Compiling code...')
|
def updateBindings(self, CModuleName):
|
||||||
compileall.compile_dir(codeDir)
|
|
||||||
|
|
||||||
|
|
||||||
def updateBindings(self):
|
|
||||||
FFIConstants.notify.info( 'Updating Bindings')
|
FFIConstants.notify.info( 'Updating Bindings')
|
||||||
FFIConstants.notify.info( 'Adding Types...')
|
FFIConstants.notify.info( 'Adding Types...')
|
||||||
self.addTypes()
|
self.addTypes()
|
||||||
FFIConstants.notify.info( 'Adding global values...')
|
FFIConstants.notify.info( 'Adding global values...')
|
||||||
self.addGlobalValues()
|
self.addGlobalValues(CModuleName)
|
||||||
FFIConstants.notify.info( 'Adding global functions...')
|
FFIConstants.notify.info( 'Adding global functions...')
|
||||||
self.addGlobalFunctions()
|
self.addGlobalFunctions(CModuleName)
|
||||||
FFIConstants.notify.info( 'Adding manifests symbols...')
|
FFIConstants.notify.info( 'Adding manifests symbols...')
|
||||||
self.addManifestSymbols()
|
self.addManifestSymbols()
|
||||||
FFIConstants.notify.info( 'Adding environment types...')
|
FFIConstants.notify.info( 'Adding environment types...')
|
||||||
|
@ -235,29 +235,35 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
"""
|
"""
|
||||||
Return a list of all the C modules this class references
|
Return a list of all the C modules this class references
|
||||||
"""
|
"""
|
||||||
moduleList = []
|
try:
|
||||||
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
# Prevent from doing the work twice
|
||||||
+ self.upcastMethods + self.downcastMethods
|
# if CModules is already defined, just return it
|
||||||
+ self.staticMethods + self.globalMethods):
|
return self.CModules
|
||||||
if method:
|
except:
|
||||||
if (not (method.typeDescriptor.moduleName in moduleList)):
|
# Otherwise, it must be our first time through, do the real work
|
||||||
moduleList.append(method.typeDescriptor.moduleName)
|
self.CModules = []
|
||||||
|
for method in (self.constructors + [self.destructor] + self.instanceMethods
|
||||||
# Now look at all the methods that we might inherit if we are at
|
+ self.upcastMethods + self.downcastMethods
|
||||||
# a multiple inheritance node and get their C modules
|
+ self.staticMethods + self.globalMethods):
|
||||||
if (len(self.parentTypes) >= 2):
|
if method:
|
||||||
for parentType in self.parentTypes:
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
for method in parentType.instanceMethods:
|
self.CModules.append(method.typeDescriptor.moduleName)
|
||||||
if (not (method.typeDescriptor.moduleName in moduleList)):
|
|
||||||
moduleList.append(method.typeDescriptor.moduleName)
|
# Now look at all the methods that we might inherit if we are at
|
||||||
for method in parentType.upcastMethods:
|
# a multiple inheritance node and get their C modules
|
||||||
if (not (method.typeDescriptor.moduleName in moduleList)):
|
if (len(self.parentTypes) >= 2):
|
||||||
moduleList.append(method.typeDescriptor.moduleName)
|
for parentType in self.parentTypes:
|
||||||
for method in parentType.globalMethods:
|
for method in parentType.instanceMethods:
|
||||||
if (not (method.typeDescriptor.moduleName in moduleList)):
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
moduleList.append(method.typeDescriptor.moduleName)
|
self.CModules.append(method.typeDescriptor.moduleName)
|
||||||
|
for method in parentType.upcastMethods:
|
||||||
return moduleList
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
|
self.CModules.append(method.typeDescriptor.moduleName)
|
||||||
|
for method in parentType.globalMethods:
|
||||||
|
if (not (method.typeDescriptor.moduleName in self.CModules)):
|
||||||
|
self.CModules.append(method.typeDescriptor.moduleName)
|
||||||
|
|
||||||
|
return self.CModules
|
||||||
|
|
||||||
|
|
||||||
def getReturnTypeModules(self):
|
def getReturnTypeModules(self):
|
||||||
@ -586,6 +592,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
indent(file, 0, '# Import all the C modules this class uses\n')
|
indent(file, 0, '# Import all the C modules this class uses\n')
|
||||||
for moduleName in self.getCModules():
|
for moduleName in self.getCModules():
|
||||||
indent(file, 0, 'import ' + moduleName + '\n')
|
indent(file, 0, 'import ' + moduleName + '\n')
|
||||||
|
indent(file, 0, 'import ' + moduleName + 'Downcasts\n')
|
||||||
indent(file, 0, '\n')
|
indent(file, 0, '\n')
|
||||||
indent(file, 0, 'import FFIExternalObject\n')
|
indent(file, 0, 'import FFIExternalObject\n')
|
||||||
|
|
||||||
@ -637,7 +644,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
# that we will call later
|
# that we will call later
|
||||||
if (nesting==0):
|
if (nesting==0):
|
||||||
indent(file, nesting, '# Delay the definition of this class until all the imports are done\n')
|
indent(file, nesting, '# Delay the definition of this class until all the imports are done\n')
|
||||||
|
indent(file, nesting, '# Make sure we only define this class once\n')
|
||||||
|
indent(file, nesting, 'classDefined = 0\n')
|
||||||
indent(file, nesting, 'def generateClass_' + self.foreignTypeName + '():\n')
|
indent(file, nesting, 'def generateClass_' + self.foreignTypeName + '():\n')
|
||||||
|
indent(file, nesting, ' if classDefined: return\n')
|
||||||
|
indent(file, nesting, ' global classDefined\n')
|
||||||
|
indent(file, nesting, ' classDefined = 1\n')
|
||||||
# Start the class definition indented a space to account for the function
|
# Start the class definition indented a space to account for the function
|
||||||
indent(file, nesting, ' class ' + self.foreignTypeName)
|
indent(file, nesting, ' class ' + self.foreignTypeName)
|
||||||
else:
|
else:
|
||||||
@ -655,13 +667,22 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
file.write(parentTypeName + '.' + parentTypeName)
|
file.write(parentTypeName + '.' + parentTypeName)
|
||||||
file.write(', ')
|
file.write(', ')
|
||||||
file.write('FFIExternalObject.FFIExternalObject):\n')
|
file.write('FFIExternalObject.FFIExternalObject):\n')
|
||||||
|
|
||||||
# Store the class C modules for the class so they do not
|
# Store the class C modules for the class so they do not
|
||||||
# get garbage collected before we do
|
# get garbage collected before we do
|
||||||
|
# TODO: this did not appear to work
|
||||||
indent(file, nesting+1, '__CModules__ = [')
|
indent(file, nesting+1, '__CModules__ = [')
|
||||||
for moduleName in self.getCModules():
|
for moduleName in self.getCModules():
|
||||||
file.write(moduleName + ',')
|
file.write(moduleName + ',')
|
||||||
file.write(']\n')
|
file.write(']\n')
|
||||||
|
|
||||||
|
# Store the downcast function modules so the FFIExternalObject
|
||||||
|
# can index into them to find the downcast functions
|
||||||
|
indent(file, nesting+1, '__CModuleDowncasts__ = [')
|
||||||
|
for moduleName in self.getCModules():
|
||||||
|
file.write(moduleName + 'Downcasts,')
|
||||||
|
file.write(']\n')
|
||||||
|
|
||||||
|
|
||||||
def outputClassFooter(self, file):
|
def outputClassFooter(self, file):
|
||||||
indent(file, 0, " # When this class gets defined, put it in this module's namespace\n")
|
indent(file, 0, " # When this class gets defined, put it in this module's namespace\n")
|
||||||
@ -744,8 +765,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor):
|
|||||||
if userManagesMemory:
|
if userManagesMemory:
|
||||||
indent(file, nesting, 'returnObject.userManagesMemory = 1\n')
|
indent(file, nesting, 'returnObject.userManagesMemory = 1\n')
|
||||||
if needsDowncast:
|
if needsDowncast:
|
||||||
indent(file, nesting, 'downcastObject = returnObject.setPointer()\n')
|
indent(file, nesting, 'return returnObject.setPointer()\n')
|
||||||
indent(file, nesting, 'return downcastObject\n')
|
|
||||||
else:
|
else:
|
||||||
indent(file, nesting, 'return returnObject\n')
|
indent(file, nesting, 'return returnObject\n')
|
||||||
|
|
||||||
|
@ -109,6 +109,5 @@ else:
|
|||||||
# Ok, now we can start generating code
|
# Ok, now we can start generating code
|
||||||
import FFIInterrogateDatabase
|
import FFIInterrogateDatabase
|
||||||
db = FFIInterrogateDatabase.FFIInterrogateDatabase()
|
db = FFIInterrogateDatabase.FFIInterrogateDatabase()
|
||||||
db.updateBindings()
|
|
||||||
db.generateCode(outputDir, extensionsDir)
|
db.generateCode(outputDir, extensionsDir)
|
||||||
|
|
||||||
|
@ -42,12 +42,13 @@ class ShowBase:
|
|||||||
self.dataRoot = NodePath(NamedNode('dataRoot'), DataRelation.getClassType())
|
self.dataRoot = NodePath(NamedNode('dataRoot'), DataRelation.getClassType())
|
||||||
self.dataUnused = NodePath(NamedNode('dataUnused'), DataRelation.getClassType())
|
self.dataUnused = NodePath(NamedNode('dataUnused'), DataRelation.getClassType())
|
||||||
self.pipe = makeGraphicsPipe()
|
self.pipe = makeGraphicsPipe()
|
||||||
self.win = self.pipe.makeGraphicsWindow(self.renderTop.node(),
|
self.win = makeGraphicsWindow(self.pipe,
|
||||||
self.camera.node(),
|
self.renderTop.node(),
|
||||||
self.dataRoot.node(),
|
self.camera.node(),
|
||||||
self.initialState)
|
self.dataRoot.node(),
|
||||||
|
self.initialState)
|
||||||
|
|
||||||
self.render2d = NodePath(self.win.setupPanda2d())
|
self.render2d = NodePath(setupPanda2d(self.win))
|
||||||
# This is a list of cams associated with the display region's cameras
|
# This is a list of cams associated with the display region's cameras
|
||||||
self.camList = []
|
self.camList = []
|
||||||
for camera in self.cameraList:
|
for camera in self.cameraList:
|
||||||
@ -105,13 +106,13 @@ class ShowBase:
|
|||||||
self.eventMgr.shutdown()
|
self.eventMgr.shutdown()
|
||||||
|
|
||||||
def toggleBackface(self):
|
def toggleBackface(self):
|
||||||
self.initialState.toggleBackface()
|
toggleBackface(self.initialState)
|
||||||
|
|
||||||
def toggleTexture(self):
|
def toggleTexture(self):
|
||||||
self.initialState.toggleTexture()
|
toggleTexture(self.initialState)
|
||||||
|
|
||||||
def toggleWireframe(self):
|
def toggleWireframe(self):
|
||||||
self.initialState.toggleWireframe()
|
toggleWireframe(self.initialState)
|
||||||
|
|
||||||
def disableMouse(self):
|
def disableMouse(self):
|
||||||
self.drive.reparentTo(self.dataUnused)
|
self.drive.reparentTo(self.dataUnused)
|
||||||
|
@ -8,20 +8,22 @@ exit = -1
|
|||||||
done = 0
|
done = 0
|
||||||
cont = 1
|
cont = 1
|
||||||
|
|
||||||
|
# Store the global clock
|
||||||
|
globalClock = ClockObject.getGlobalClock()
|
||||||
|
|
||||||
def getTimeFrame():
|
def getTimeFrame():
|
||||||
# WARNING: If you are testing tasks without an igloop,
|
# WARNING: If you are testing tasks without an igloop,
|
||||||
# you must manually tick the clock
|
# you must manually tick the clock
|
||||||
|
|
||||||
# Ask for the time last frame
|
# Ask for the time last frame
|
||||||
t = ClockObject.getGlobalClock().getTime()
|
t = globalClock.getTime()
|
||||||
|
|
||||||
# Set the clock to have last frame's time in case we were
|
# Set the clock to have last frame's time in case we were
|
||||||
# Paused at the prompt for a long time
|
# Paused at the prompt for a long time
|
||||||
ClockObject.getGlobalClock().setTime(t)
|
globalClock.setTime(t)
|
||||||
|
|
||||||
# Get the new frame count
|
# Get the new frame count
|
||||||
f = ClockObject.getGlobalClock().getFrameCount()
|
f = globalClock.getFrameCount()
|
||||||
|
|
||||||
return t, f
|
return t, f
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user