diff --git a/direct/src/ffi/FFIConstants.py b/direct/src/ffi/FFIConstants.py index 0bc8139461..6e2cdf1ae8 100644 --- a/direct/src/ffi/FFIConstants.py +++ b/direct/src/ffi/FFIConstants.py @@ -3,10 +3,6 @@ from DirectNotifyGlobal import * 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 importModuleName = 'PandaModules' diff --git a/direct/src/ffi/FFIEnvironment.py b/direct/src/ffi/FFIEnvironment.py index a4fa0eaabd..5461291fea 100644 --- a/direct/src/ffi/FFIEnvironment.py +++ b/direct/src/ffi/FFIEnvironment.py @@ -2,8 +2,12 @@ import FFIConstants class FFIEnvironment: def __init__(self): + self.reset() + + def reset(self): self.types = {} self.globalFunctions = [] + self.downcastFunctions = [] self.globalValues = [] self.manifests = [] @@ -20,6 +24,8 @@ class FFIEnvironment: def addGlobalFunction(self, typeDescriptor): self.globalFunctions.append(typeDescriptor) + def addDowncastFunction(self, typeDescriptor): + self.downcastFunctions.append(typeDescriptor) def addGlobalValue(self, typeDescriptor): self.globalValues.append(typeDescriptor) def addManifest(self, typeDescriptor): diff --git a/direct/src/ffi/FFIExternalObject.py b/direct/src/ffi/FFIExternalObject.py index caf63e9b06..3bc2bfc478 100644 --- a/direct/src/ffi/FFIExternalObject.py +++ b/direct/src/ffi/FFIExternalObject.py @@ -4,26 +4,19 @@ import TypedObject WrapperClassMap = {} +# For testing, you can turn verbose and debug on +FFIConstants.notify.setVerbose(1) +FFIConstants.notify.setDebug(1) -def getDowncastFunctions(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 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 +# Register a python class in the type map if it is a typed object +# The type map is used for upcasting and downcasting through +# the panda inheritance chain +def registerInTypeMap(pythonClass): + if issubclass(pythonClass, TypedObject.TypedObject): + typeIndex = pythonClass.getClassType().getIndex() + WrapperClassMap[typeIndex] = pythonClass + class FFIExternalObject: @@ -32,23 +25,52 @@ class FFIExternalObject: self.userManagesMemory = 0 # Start with a null this pointer 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): if (self.this == 0): # Null pointer, return None return None # 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 # Ok, it is a typed object. See what type it really is and downcast # 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 if (exactWrapperClass and (exactWrapperClass != self.__class__)): # Create a new wrapper class instance @@ -71,16 +93,10 @@ class FFIExternalObject: else: return None - def registerInTypeMap(self): - global WrapperClassMap - if self.isTypedObject(): - typeIndex = self.__class__.getClassType().getIndex() - WrapperClassMap[typeIndex] = self.__class__ - def downcast(self, specificClass): FFIConstants.notify.debug('downcasting from %s to %s' % \ (self.__class__.__name__, specificClass.__name__)) - downcastChain = getDowncastFunctions(specificClass, self.__class__, []) + downcastChain = self.getDowncastFunctions(specificClass, self.__class__, []) FFIConstants.notify.debug('downcast chain: ' + `downcastChain`) newObject = self if (downcastChain == None): @@ -124,7 +140,4 @@ class FFIExternalObject: - - - diff --git a/direct/src/ffi/FFIInterrogateDatabase.py b/direct/src/ffi/FFIInterrogateDatabase.py index 700c5b1205..02bcdce1ab 100644 --- a/direct/src/ffi/FFIInterrogateDatabase.py +++ b/direct/src/ffi/FFIInterrogateDatabase.py @@ -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 exec('from ' + FFIConstants.InterrogateModuleName + ' import *') -# Import all the C++ modules -for CModuleName in FFIConstants.CodeModuleNameList: - FFIConstants.notify.info('Importing code library: ' + CModuleName) - exec('import ' + CModuleName) - -def constructGlobalFile(codeDir): +def constructGlobalFile(codeDir, CModuleName): """ 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 -def constructImportFile(codeDir): + +def constructDowncastFile(codeDir, CModuleName): """ 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 -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 file.write(FFIConstants.generatedHeader) @@ -48,15 +52,34 @@ def outputGlobalFileImports(file, methodList): file.write('import types\n') # 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') moduleList = [] for method in methodList: returnType = method.typeDescriptor.returnType.recursiveTypeDescriptor() - if (not (returnType.foreignTypeName in moduleList)): + returnTypeName = returnType.foreignTypeName + if (not (returnTypeName in moduleList)): 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: file.write('import ' + moduleName + '\n') @@ -64,7 +87,7 @@ def outputGlobalFileImports(file, methodList): 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 """ @@ -76,10 +99,8 @@ def outputImportFileImports(file, typeList): file.write('import ' + FFIConstants.InterrogateModuleName + '\n') file.write('\n') - file.write('# Import the C modules\n') - for CModuleName in FFIConstants.CodeModuleNameList: - file.write('import ' + CModuleName + '\n') - file.write('\n') + file.write('# Import the C module\n') + file.write('import ' + CModuleName + '\n') # Filter out only the class and enum type descriptors (not const, pointers, etc) classTypeList = [] @@ -96,12 +117,9 @@ def outputImportFileImports(file, typeList): classTypeList.sort(FFIOverload.inheritanceLevelSort) moduleList = [] - for type in classTypeList: + for type in classTypeList: moduleList.append(type.foreignTypeName) - file.write('import FFIExternalObject\n') - file.write('\n') - file.write('# Import enums into the global name space\n') for type in enumTypeList: file.write('from ' + type.enumName + ' import *\n') @@ -113,25 +131,28 @@ def outputImportFileImports(file, typeList): file.write('\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('# Now generate the classes\n') + file.write('# Generate the classes\n') for moduleName in moduleList: file.write(moduleName + '.generateClass_' + moduleName + '()\n') file.write('\n') - file.write('# Now put the classes in the wrapper class map\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') + file.write('# Copy the classes into our own namespace\n') for moduleName in moduleList: file.write(moduleName + ' = ' + moduleName + '.' + moduleName + '\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): """ 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 downcastToNode(ptrBoundedObject) will appear in Node's list of methods 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) for i in range(numFuncs): @@ -481,15 +506,21 @@ class FFIInterrogateDatabase: funcIndex = interrogate_type_get_downcast(typeIndex, i) typeDescs = self.constructFunctionTypeDescriptors(funcIndex) for typeDesc in typeDescs: - funcSpec = FFISpecs.MethodSpecification() + funcSpec = FFISpecs.GlobalFunctionSpecification() funcSpec.name = FFIRename.methodNameFromCppName( interrogate_function_name(funcIndex)) funcSpec.typeDescriptor = typeDesc funcSpec.index = funcIndex # Here we look for the class in the first argument 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 - fromClass.downcastMethods.append(funcSpec) + # fromClass.downcastMethods.append(funcSpec) + self.environment.addDowncastFunction(funcSpec) def constructConstructorSpecifications(self, typeIndex): funcSpecs = [] @@ -532,8 +563,14 @@ class FFIInterrogateDatabase: def addEnvironmentTypes(self): for descriptor in self.typeIndexMap.values(): 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 # the getter and setter # typeIndex = interrogate_element_type(globalIndex) @@ -541,12 +578,18 @@ class FFIInterrogateDatabase: if interrogate_element_has_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) else: getter = None if interrogate_element_has_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) else: setter = None @@ -570,21 +613,23 @@ class FFIInterrogateDatabase: funcSpec.index = globalIndex return funcSpec - def addGlobalFunctions(self): + def addGlobalFunctions(self, CModuleName): numGlobals = interrogate_number_of_global_functions() for i in range(numGlobals): funcIndex = interrogate_get_global_function(i) - newGlob = self.constructGlobalFunction(funcIndex) - if newGlob: - self.environment.addGlobalFunction(newGlob) + if self.functionInCModule(funcIndex, CModuleName): + newGlob = self.constructGlobalFunction(funcIndex) + if newGlob: + self.environment.addGlobalFunction(newGlob) + """ # Take all the global functions that have a Panda Class as their # first argument and make them class methods on that class # For example the global function # get_distance(node1, node2) # becomes: # node1.getDistance(node2) - + # Functions that do not get moved will be stored here temporarily tempGlobalFunctions = [] for funcSpec in self.environment.globalFunctions: @@ -602,15 +647,17 @@ class FFIInterrogateDatabase: else: # Copy this function into the temp list 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 + """ - def addGlobalValues(self): + def addGlobalValues(self, CModuleName): numGlobals = interrogate_number_of_globals() for i in range(numGlobals): globalIndex = interrogate_get_global(i) - newGlob = self.constructGlobal(globalIndex) - self.environment.addGlobalValue(newGlob) + newGlob = self.constructGlobal(globalIndex, CModuleName) + if newGlob: + self.environment.addGlobalValue(newGlob) def constructManifest(self, manifestIndex): @@ -656,18 +703,50 @@ class FFIInterrogateDatabase: FFIConstants.notify.info( 'Generating static class...') 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...') for type in self.environment.types.values(): # Do not generate code for nested types at the top level if (not type.isNested): 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...') - globalFile = constructGlobalFile(codeDir) + globalFile = constructGlobalFile(codeDir, CModuleName) # 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 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 for globalValue in self.environment.globalValues: if globalValue.getter: @@ -675,7 +754,7 @@ class FFIInterrogateDatabase: if globalValue.setter: globalFunctions.append(globalValue.setter) # Output all the imports based on this list of functions - outputGlobalFileImports(globalFile, globalFunctions) + outputGlobalFileImports(globalFile, globalFunctions, CModuleName) FFIConstants.notify.info( 'Generating global value code...') for type in self.environment.globalValues: @@ -692,21 +771,17 @@ class FFIInterrogateDatabase: globalFile.close() FFIConstants.notify.info( 'Generating import code...') - importFile = constructImportFile(codeDir) - outputImportFileImports(importFile, self.environment.types.values()) + importFile = constructImportFile(codeDir, CModuleName) + outputImportFileImports(importFile, self.environment.types.values(), CModuleName) - FFIConstants.notify.info( 'Compiling code...') - compileall.compile_dir(codeDir) - - - def updateBindings(self): + def updateBindings(self, CModuleName): FFIConstants.notify.info( 'Updating Bindings') FFIConstants.notify.info( 'Adding Types...') self.addTypes() FFIConstants.notify.info( 'Adding global values...') - self.addGlobalValues() + self.addGlobalValues(CModuleName) FFIConstants.notify.info( 'Adding global functions...') - self.addGlobalFunctions() + self.addGlobalFunctions(CModuleName) FFIConstants.notify.info( 'Adding manifests symbols...') self.addManifestSymbols() FFIConstants.notify.info( 'Adding environment types...') diff --git a/direct/src/ffi/FFITypes.py b/direct/src/ffi/FFITypes.py index 471c67e641..93cf635937 100644 --- a/direct/src/ffi/FFITypes.py +++ b/direct/src/ffi/FFITypes.py @@ -235,29 +235,35 @@ class ClassTypeDescriptor(BaseTypeDescriptor): """ Return a list of all the C modules this class references """ - moduleList = [] - for method in (self.constructors + [self.destructor] + self.instanceMethods - + self.upcastMethods + self.downcastMethods - + self.staticMethods + self.globalMethods): - if method: - 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 - # a multiple inheritance node and get their C modules - if (len(self.parentTypes) >= 2): - for parentType in self.parentTypes: - for method in parentType.instanceMethods: - if (not (method.typeDescriptor.moduleName in moduleList)): - moduleList.append(method.typeDescriptor.moduleName) - for method in parentType.upcastMethods: - if (not (method.typeDescriptor.moduleName in moduleList)): - moduleList.append(method.typeDescriptor.moduleName) - for method in parentType.globalMethods: - if (not (method.typeDescriptor.moduleName in moduleList)): - moduleList.append(method.typeDescriptor.moduleName) - - return moduleList + try: + # Prevent from doing the work twice + # if CModules is already defined, just return it + return self.CModules + except: + # Otherwise, it must be our first time through, do the real work + self.CModules = [] + for method in (self.constructors + [self.destructor] + self.instanceMethods + + self.upcastMethods + self.downcastMethods + + self.staticMethods + self.globalMethods): + if method: + if (not (method.typeDescriptor.moduleName in self.CModules)): + self.CModules.append(method.typeDescriptor.moduleName) + + # Now look at all the methods that we might inherit if we are at + # a multiple inheritance node and get their C modules + if (len(self.parentTypes) >= 2): + for parentType in self.parentTypes: + for method in parentType.instanceMethods: + if (not (method.typeDescriptor.moduleName in self.CModules)): + self.CModules.append(method.typeDescriptor.moduleName) + for method in parentType.upcastMethods: + 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): @@ -586,6 +592,7 @@ class ClassTypeDescriptor(BaseTypeDescriptor): indent(file, 0, '# Import all the C modules this class uses\n') for moduleName in self.getCModules(): indent(file, 0, 'import ' + moduleName + '\n') + indent(file, 0, 'import ' + moduleName + 'Downcasts\n') indent(file, 0, '\n') indent(file, 0, 'import FFIExternalObject\n') @@ -637,7 +644,12 @@ class ClassTypeDescriptor(BaseTypeDescriptor): # that we will call later if (nesting==0): 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, ' 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 indent(file, nesting, ' class ' + self.foreignTypeName) else: @@ -655,13 +667,22 @@ class ClassTypeDescriptor(BaseTypeDescriptor): file.write(parentTypeName + '.' + parentTypeName) file.write(', ') file.write('FFIExternalObject.FFIExternalObject):\n') + # Store the class C modules for the class so they do not # get garbage collected before we do + # TODO: this did not appear to work indent(file, nesting+1, '__CModules__ = [') for moduleName in self.getCModules(): file.write(moduleName + ',') 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): 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: indent(file, nesting, 'returnObject.userManagesMemory = 1\n') if needsDowncast: - indent(file, nesting, 'downcastObject = returnObject.setPointer()\n') - indent(file, nesting, 'return downcastObject\n') + indent(file, nesting, 'return returnObject.setPointer()\n') else: indent(file, nesting, 'return returnObject\n') diff --git a/direct/src/ffi/generatePythonCode b/direct/src/ffi/generatePythonCode index f73c835fa9..723bf661c3 100644 --- a/direct/src/ffi/generatePythonCode +++ b/direct/src/ffi/generatePythonCode @@ -109,6 +109,5 @@ else: # Ok, now we can start generating code import FFIInterrogateDatabase db = FFIInterrogateDatabase.FFIInterrogateDatabase() -db.updateBindings() db.generateCode(outputDir, extensionsDir) diff --git a/direct/src/showbase/ShowBase.py b/direct/src/showbase/ShowBase.py index 34f7c5237f..bb4556be0f 100644 --- a/direct/src/showbase/ShowBase.py +++ b/direct/src/showbase/ShowBase.py @@ -42,12 +42,13 @@ class ShowBase: self.dataRoot = NodePath(NamedNode('dataRoot'), DataRelation.getClassType()) self.dataUnused = NodePath(NamedNode('dataUnused'), DataRelation.getClassType()) self.pipe = makeGraphicsPipe() - self.win = self.pipe.makeGraphicsWindow(self.renderTop.node(), - self.camera.node(), - self.dataRoot.node(), - self.initialState) + self.win = makeGraphicsWindow(self.pipe, + self.renderTop.node(), + self.camera.node(), + 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 self.camList = [] for camera in self.cameraList: @@ -105,13 +106,13 @@ class ShowBase: self.eventMgr.shutdown() def toggleBackface(self): - self.initialState.toggleBackface() + toggleBackface(self.initialState) def toggleTexture(self): - self.initialState.toggleTexture() + toggleTexture(self.initialState) def toggleWireframe(self): - self.initialState.toggleWireframe() + toggleWireframe(self.initialState) def disableMouse(self): self.drive.reparentTo(self.dataUnused) diff --git a/direct/src/showbase/Task.py b/direct/src/showbase/Task.py index fb82a8f12c..a1b86582ba 100644 --- a/direct/src/showbase/Task.py +++ b/direct/src/showbase/Task.py @@ -8,20 +8,22 @@ exit = -1 done = 0 cont = 1 +# Store the global clock +globalClock = ClockObject.getGlobalClock() def getTimeFrame(): # WARNING: If you are testing tasks without an igloop, # you must manually tick the clock # 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 # Paused at the prompt for a long time - ClockObject.getGlobalClock().setTime(t) + globalClock.setTime(t) # Get the new frame count - f = ClockObject.getGlobalClock().getFrameCount() + f = globalClock.getFrameCount() return t, f