Lots of work to make the rtdist work with the new library building system

This commit is contained in:
rdb 2015-01-12 15:02:42 +01:00
parent 88dbb31daa
commit 0aa0f34c74
42 changed files with 762 additions and 782 deletions

View File

@ -4,7 +4,7 @@ for the programmer/user
"""
from LoggerGlobal import defaultLogger
from direct.showbase import PythonUtil
from panda3d.core import ConfigVariableBool
from panda3d.core import ConfigVariableBool, NotifyCategory, StreamWriter, Notify
import time
import types
import sys
@ -18,9 +18,8 @@ class Notifier:
# with the C++ notify system.
streamWriter = None
if ConfigVariableBool('notify-integrate', True):
from panda3d.core import StreamWriter, Notify
streamWriter = StreamWriter(Notify.out(), False)
showTime = ConfigVariableBool('notify-timestamp', False)
def __init__(self, name, logger=None):
@ -44,9 +43,6 @@ class Notifier:
self.__warning = 1
self.__debug = 0
self.__logging = 0
def setServerDelta(self, delta, timezone):
"""
@ -62,7 +58,6 @@ class Notifier:
# The following call is necessary to make the output from C++
# notify messages show the same timestamp as those generated
# from Python-level notify messages.
from pandac.PandaModules import NotifyCategory
NotifyCategory.setServerDelta(self.serverDelta)
self.info("Notify clock adjusted by %s (and timezone adjusted by %s hours) to synchronize with server." % (PythonUtil.formatElapsedSeconds(delta), (time.timezone - timezone) / 3600))
@ -92,7 +87,7 @@ class Notifier:
# Severity funcs
def setSeverity(self, severity):
from pandac.PandaModules import NSDebug, NSInfo, NSWarning, NSError
from panda3d.core import NSDebug, NSInfo, NSWarning, NSError
if severity >= NSError:
self.setWarning(0)
self.setInfo(0)
@ -111,7 +106,7 @@ class Notifier:
self.setDebug(1)
def getSeverity(self):
from pandac.PandaModules import NSDebug, NSInfo, NSWarning, NSError
from panda3d.core import NSDebug, NSInfo, NSWarning, NSError
if self.getDebug():
return NSDebug
elif self.getInfo():

View File

@ -143,7 +143,7 @@ def doGetopts():
doSqueeze = False
elif (flag == '-s'):
deleteSourceAfterSqueeze = False
else:
FFIConstants.notify.error('illegal option: ' + flag)
@ -168,7 +168,7 @@ def doGetopts():
if codeLib not in newLibs:
newLibs.append(codeLib)
codeLibs = newLibs
def doErrorCheck():
global outputCodeDir
@ -278,9 +278,9 @@ def generateNativeWrappers():
# in the runtime (plugin) environment, where all libraries are
# not necessarily downloaded.
if sys.version_info >= (3, 0):
pandaModules.write('try:\n from .%s import *\nexcept ImportError as err:\n if "DLL loader cannot find" not in str(err):\n raise\n' % (metaModuleName))
pandaModules.write('try:\n from .%s import *\nexcept ImportError as err:\n if "DLL loader cannot find" not in str(err):\n raise\n' % (metaModuleName))
else:
pandaModules.write('try:\n from %s import *\nexcept ImportError, err:\n if "DLL loader cannot find" not in str(err):\n raise\n' % (metaModuleName))
pandaModules.write('try:\n from %s import *\nexcept ImportError, err:\n if "DLL loader cannot find" not in str(err):\n raise\n' % (metaModuleName))
# Not sure if this message is helpful or annoying.
#pandaModules.write(' print("Failed to import %s")\n' % (moduleName))
@ -306,7 +306,7 @@ def generateNativeWrappers():
extension = open(extensionFilename, 'r')
moduleModules.write(extension.read())
moduleModules.write('\n')
def run():
global outputCodeDir

View File

@ -25,16 +25,13 @@ if 'VFSImporter' in sys.modules:
direct.showbase.VFSImporter = VFSImporter
sys.modules['direct.showbase.VFSImporter'] = VFSImporter
else:
# Otherwise, we can import the VFSImporter normally. We have to
# import PandaModules first, to get the funny renaming with
# pandaexpress.
import direct
from pandac import PandaModules
# Otherwise, we can import the VFSImporter normally.
from direct.showbase import VFSImporter
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, Thread, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString, ConfigPageManager, initAppForGui
from pandac import PandaModules
from panda3d.core import VirtualFileSystem, Filename, Multifile, loadPrcFileData, unloadPrcFile, getModelPath, Thread, WindowProperties, ExecutionEnvironment, PandaSystem, Notify, StreamWriter, ConfigVariableString, ConfigPageManager
from panda3d.direct import init_app_for_gui
from panda3d import core
from direct.stdpy import file, glob
from direct.task.TaskManagerGlobal import taskMgr
from direct.showbase.MessengerGlobal import messenger
@ -83,7 +80,7 @@ class AppRunner(DirectObject):
# Also from p3d_plugin.h
P3D_CONTENTS_DEFAULT_MAX_AGE = 5
def __init__(self):
DirectObject.__init__(self)
@ -119,8 +116,8 @@ class AppRunner(DirectObject):
self.windowPrc = None
self.http = None
if hasattr(PandaModules, 'HTTPClient'):
self.http = PandaModules.HTTPClient.getGlobalPtr()
if hasattr(core, 'HTTPClient'):
self.http = core.HTTPClient.getGlobalPtr()
self.Undefined = Undefined
self.ConcreteStruct = ConcreteStruct
@ -213,7 +210,7 @@ class AppRunner(DirectObject):
# this instance, e.g. the WindowProperties necessary to
# re-embed a window in the browser frame.
self.windowProperties = None
# Store our pointer so DirectStart-based apps can find us.
if AppRunnerGlobal.appRunner is None:
AppRunnerGlobal.appRunner = self
@ -263,7 +260,7 @@ class AppRunner(DirectObject):
value = bool(value)
return value
def installPackage(self, packageName, version = None, hostUrl = None):
@ -353,7 +350,7 @@ class AppRunner(DirectObject):
# No shenanigans, just return the requested host.
return host
def getHost(self, hostUrl, hostDir = None):
""" Returns a new HostInfo object corresponding to the
indicated host URL. If we have already seen this URL
@ -419,7 +416,7 @@ class AppRunner(DirectObject):
# the host directory too.
del self.hosts[hostUrl]
self.__deleteHostFiles(host)
return packages
def __deleteHostFiles(self, host):
@ -431,7 +428,7 @@ class AppRunner(DirectObject):
self.rmtree(host.hostDir)
self.sendRequest('forget_package', host.hostUrl, '', '')
def freshenFile(self, host, fileSpec, localPathname):
""" Ensures that the localPathname is the most current version
@ -449,18 +446,18 @@ class AppRunner(DirectObject):
doc = None
if self.superMirrorUrl:
# Use the "super mirror" first.
url = PandaModules.URLSpec(self.superMirrorUrl + fileSpec.filename)
url = core.URLSpec(self.superMirrorUrl + fileSpec.filename)
self.notify.info("Freshening %s" % (url))
doc = self.http.getDocument(url)
if not doc or not doc.isValid():
# Failing the super mirror, contact the actual host.
url = PandaModules.URLSpec(host.hostUrlPrefix + fileSpec.filename)
url = core.URLSpec(host.hostUrlPrefix + fileSpec.filename)
self.notify.info("Freshening %s" % (url))
doc = self.http.getDocument(url)
if not doc.isValid():
return False
file = Filename.temporary('', 'p3d_')
if not doc.downloadToFile(file):
# Failed to download.
@ -522,12 +519,11 @@ class AppRunner(DirectObject):
""" Reads the config.xml file that may be present in the root
directory. """
if not hasattr(PandaModules, 'TiXmlDocument'):
if not hasattr(core, 'TiXmlDocument'):
return
from pandac.PandaModules import TiXmlDocument
filename = Filename(self.rootDir, self.ConfigBasename)
doc = TiXmlDocument(filename.toOsSpecific())
doc = core.TiXmlDocument(filename.toOsSpecific())
if not doc.LoadFile():
return
@ -544,7 +540,7 @@ class AppRunner(DirectObject):
called automatically; an application may call this after
adjusting some parameters (such as self.maxDiskUsage). """
from pandac.PandaModules import TiXmlDocument, TiXmlDeclaration, TiXmlElement
from panda3d.core import TiXmlDocument, TiXmlDeclaration, TiXmlElement
filename = Filename(self.rootDir, self.ConfigBasename)
doc = TiXmlDocument(filename.toOsSpecific())
@ -561,7 +557,7 @@ class AppRunner(DirectObject):
tfile = Filename.temporary(self.rootDir.cStr(), '.xml')
if doc.SaveFile(tfile.toOsSpecific()):
tfile.renameTo(filename)
def checkDiskUsage(self):
""" Checks the total disk space used by all packages, and
@ -574,11 +570,11 @@ class AppRunner(DirectObject):
totalSize += packageData.totalSize
self.notify.info("Total Panda3D disk space used: %s MB" % (
(totalSize + 524288) / 1048576))
if self.verifyContents == self.P3DVCNever:
# We're not allowed to delete anything anyway.
return
self.notify.info("Configured max usage is: %s MB" % (
(self.maxDiskUsage + 524288) / 1048576))
if totalSize <= self.maxDiskUsage:
@ -592,7 +588,7 @@ class AppRunner(DirectObject):
if packageData.package and packageData.package.installed:
# Don't uninstall any packages we're currently using.
continue
usedPackages.append((packageData.lastUse, packageData))
# Sort the packages into oldest-first order.
@ -609,13 +605,13 @@ class AppRunner(DirectObject):
packages.append(packageData.package)
else:
# If it's an unknown package, just delete it directly.
print "Deleting unknown package %s" % (packageData.pathname)
print("Deleting unknown package %s" % (packageData.pathname))
self.rmtree(packageData.pathname)
packages = self.deletePackages(packages)
if packages:
print "Unable to delete %s packages" % (len(packages))
print("Unable to delete %s packages" % (len(packages)))
return
def stop(self):
@ -663,10 +659,10 @@ class AppRunner(DirectObject):
for child in filename.scanDirectory():
self.rmtree(Filename(filename, child))
if not filename.rmdir():
print "could not remove directory %s" % (filename)
print("could not remove directory %s" % (filename))
else:
if not filename.unlink():
print "could not delete %s" % (filename)
print("could not delete %s" % (filename))
def setSessionId(self, sessionId):
""" This message should come in at startup. """
@ -747,10 +743,23 @@ class AppRunner(DirectObject):
# will properly get ignored by ShowBase.
self.initialAppImport = True
__import__(moduleName)
main = sys.modules[moduleName]
if hasattr(main, 'main') and hasattr(main.main, '__call__'):
main.main(self)
# Python won't let us import a module named __main__. So,
# we have to do that manually, via the VFSImporter.
if moduleName == '__main__':
dirName = Filename(self.multifileRoot).toOsSpecific()
importer = VFSImporter.VFSImporter(dirName)
loader = importer.find_module('__main__')
if loader is None:
raise ImportError('No module named __main__')
mainModule = loader.load_module('__main__')
else:
__import__(moduleName)
mainModule = sys.modules[moduleName]
# Check if it has a main() function. If so, call it.
if hasattr(mainModule, 'main') and hasattr(mainModule.main, '__call__'):
mainModule.main(self)
# Now clear this flag.
self.initialAppImport = False
@ -814,7 +823,7 @@ class AppRunner(DirectObject):
# Now that we have rootDir, we can read the config file.
self.readConfigXml()
def addPackageInfo(self, name, platform, version, hostUrl, hostDir = None,
recurse = False):
@ -858,7 +867,7 @@ class AppRunner(DirectObject):
# Maybe the contents.xml file isn't current. Re-fetch it.
if host.redownloadContentsFile(self.http):
return self.addPackageInfo(name, platform, version, hostUrl, hostDir = hostDir, recurse = True)
message = "Couldn't find %s %s on %s" % (name, version, hostUrl)
raise OSError, message
@ -866,18 +875,18 @@ class AppRunner(DirectObject):
if not package.downloadDescFile(self.http):
message = "Couldn't get desc file for %s" % (name)
raise OSError, message
if not package.downloadPackage(self.http):
message = "Couldn't download %s" % (name)
raise OSError, message
if not package.installPackage(self):
message = "Couldn't install %s" % (name)
raise OSError, message
if package.guiApp:
self.guiApp = True
initAppForGui()
init_app_for_gui()
def setP3DFilename(self, p3dFilename, tokens, argv, instanceId,
interactiveConsole, p3dOffset = 0, p3dUrl = None):
@ -885,7 +894,7 @@ class AppRunner(DirectObject):
contains the application itself, along with the web tokens
and/or command-line arguments. Once this method has been
called, the application is effectively started. """
# One day we will have support for multiple instances within a
# Python session. Against that day, we save the instance ID
# for this instance.
@ -937,9 +946,9 @@ class AppRunner(DirectObject):
self.allowPythonDev = False
i = mf.findSubfile('p3d_info.xml')
if i >= 0 and hasattr(PandaModules, 'readXmlStream'):
if i >= 0 and hasattr(core, 'readXmlStream'):
stream = mf.openReadSubfile(i)
self.p3dInfo = PandaModules.readXmlStream(stream)
self.p3dInfo = core.readXmlStream(stream)
mf.closeReadSubfile(stream)
if self.p3dInfo:
self.p3dPackage = self.p3dInfo.FirstChildElement('package')
@ -975,7 +984,7 @@ class AppRunner(DirectObject):
ConfigVariableString('frame-rate-meter-text-pattern').setValue('allow_python_dev %0.1f fps')
if self.guiApp:
initAppForGui()
init_app_for_gui()
self.initPackedAppEnvironment()
@ -992,7 +1001,7 @@ class AppRunner(DirectObject):
# provided if available. It is only for documentation
# purposes; the actual p3d file has already been
# downloaded to p3dFilename.
self.p3dUrl = PandaModules.URLSpec(p3dUrl)
self.p3dUrl = core.URLSpec(p3dUrl)
# Send this call to the main thread; don't call it directly.
messenger.send('AppRunner_startIfReady', taskChain = 'default')
@ -1015,14 +1024,14 @@ class AppRunner(DirectObject):
newUrl = xalthost.Attribute('url')
self.altHostMap[origUrl] = newUrl
break
xalthost = xalthost.NextSiblingElement('alt_host')
def loadMultifilePrcFiles(self, mf, root):
""" Loads any prc files in the root of the indicated
Multifile, which is presumed to have been mounted already
under root. """
# We have to load these prc files explicitly, since the
# ConfigPageManager can't directly look inside the vfs. Use
# the Multifile interface to find the prc files, rather than
@ -1046,12 +1055,12 @@ class AppRunner(DirectObject):
cp = loadPrcFileData(pathname, data)
# Set it to sort value 20, behind the implicit pages.
cp.setSort(20)
def __clearWindowProperties(self):
""" Clears the windowPrc file that was created in a previous
call to setupWindow(), if any. """
if self.windowPrc:
unloadPrcFile(self.windowPrc)
self.windowPrc = None
@ -1127,12 +1136,12 @@ class AppRunner(DirectObject):
function that can be used to deliver requests upstream, to the
core API, and thereby to the browser. """
self.requestFunc = func
def sendRequest(self, request, *args):
""" Delivers a request to the browser via self.requestFunc.
This low-level function is not intended to be called directly
by user code. """
assert self.requestFunc
return self.requestFunc(self.instanceId, request, args)
@ -1176,7 +1185,7 @@ class AppRunner(DirectObject):
# Evaluate it now.
return self.scriptRequest('eval', self.dom, value = expression,
needsResponse = needsResponse)
def scriptRequest(self, operation, object, propertyName = '',
value = None, needsResponse = True):
""" Issues a new script request to the browser. This queries
@ -1184,7 +1193,7 @@ class AppRunner(DirectObject):
low-level method that user code should not call directly;
instead, just operate on the Python wrapper objects that
shadow the DOM objects, beginning with appRunner.dom.
operation may be one of [ 'get_property', 'set_property',
'call', 'evaluate' ].
@ -1233,7 +1242,7 @@ def dummyAppRunner(tokens = [], argv = None):
first-look sanity check. """
if AppRunnerGlobal.appRunner:
print "Already have AppRunner, not creating a new one."
print("Already have AppRunner, not creating a new one.")
return AppRunnerGlobal.appRunner
appRunner = AppRunner()
@ -1243,7 +1252,7 @@ def dummyAppRunner(tokens = [], argv = None):
platform = PandaSystem.getPlatform()
version = PandaSystem.getPackageVersionString()
hostUrl = PandaSystem.getPackageHostUrl()
if platform.startswith('win'):
rootDir = Filename(Filename.getUserAppdataDirectory(), 'Panda3D')
elif platform.startswith('osx'):
@ -1256,7 +1265,7 @@ def dummyAppRunner(tokens = [], argv = None):
# Of course we will have the panda3d application loaded.
appRunner.addPackageInfo('panda3d', platform, version, hostUrl)
appRunner.tokens = tokens
appRunner.tokenDict = dict(tokens)
if argv is None:
@ -1274,6 +1283,6 @@ def dummyAppRunner(tokens = [], argv = None):
vfs.mount(cwd, appRunner.multifileRoot, vfs.MFReadOnly)
appRunner.initPackedAppEnvironment()
return appRunner

View File

@ -8,9 +8,9 @@ import os, sys, subprocess, tarfile, shutil, time, zipfile, glob, socket, getpas
from cStringIO import StringIO
from direct.directnotify.DirectNotifyGlobal import *
from direct.showbase.AppRunnerGlobal import appRunner
from pandac.PandaModules import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
from pandac.PandaModules import TiXmlDocument, TiXmlDeclaration, TiXmlElement, readXmlStream
from pandac.PandaModules import PNMImage, PNMFileTypeRegistry
from panda3d.core import PandaSystem, HTTPClient, Filename, VirtualFileSystem, Multifile
from panda3d.core import TiXmlDocument, TiXmlDeclaration, TiXmlElement, readXmlStream
from panda3d.core import PNMImage, PNMFileTypeRegistry
from direct.stdpy.file import *
from direct.p3d.HostInfo import HostInfo
# This is important for some reason
@ -296,7 +296,7 @@ class Icon:
def __init__(self):
self.images = {}
def addImage(self, image):
""" Adds an image to the icon. Returns False on failure, True on success.
Only one image per size can be loaded, and the image size must be square. """
@ -1097,7 +1097,7 @@ class Installer:
# Tell Vista that we require admin rights
print >>nsi, 'RequestExecutionLevel admin'
print >>nsi
print >>nsi
if self.offerRun:
print >>nsi, 'Function launch'
print >>nsi, ' ExecShell "open" "$INSTDIR\\%s.exe"' % self.shortname
@ -1112,7 +1112,7 @@ class Installer:
print >>nsi, ' CreateShortcut "$DESKTOP\\%s.lnk" "$INSTDIR\\%s.exe" "" "$INSTDIR\\%s.ico"' % (self.fullname, self.shortname, self.shortname)
print >>nsi, 'FunctionEnd'
print >>nsi
print >>nsi, '!include "MUI2.nsh"'
print >>nsi, '!define MUI_ABORTWARNING'
if self.offerRun:
@ -1213,7 +1213,7 @@ class Installer:
if icofile is not None:
icofile.unlink()
return output
def os_walk(self, top):

View File

@ -1,6 +1,6 @@
import os
import time
from pandac.PandaModules import Filename, HashVal, VirtualFileSystem
from panda3d.core import Filename, HashVal, VirtualFileSystem
class FileSpec:
""" This class represents a disk file whose hash and size
@ -18,13 +18,13 @@ class FileSpec:
def fromFile(self, packageDir, filename, pathname = None, st = None):
""" Reads the file information from the indicated file. If st
is supplied, it is the result of os.stat on the filename. """
vfs = VirtualFileSystem.getGlobalPtr()
filename = Filename(filename)
if pathname is None:
pathname = Filename(packageDir, filename)
self.filename = filename.cStr()
self.basename = filename.getBasename()
@ -41,17 +41,17 @@ class FileSpec:
hv = HashVal()
hv.hashFile(pathname)
self.hash = hv.asHex()
def loadXml(self, xelement):
""" Reads the file information from the indicated XML
element. """
self.filename = xelement.Attribute('filename')
self.basename = None
if self.filename:
self.basename = Filename(self.filename).getBasename()
size = xelement.Attribute('size')
try:
self.size = int(size)
@ -87,7 +87,7 @@ class FileSpec:
xelement.SetAttribute('size', str(self.size))
if self.hash:
xelement.SetAttribute('hash', self.hash)
def quickVerify(self, packageDir = None, pathname = None,
notify = None, correctSelf = False):
""" Performs a quick test to ensure the file has not been
@ -157,8 +157,8 @@ class FileSpec:
self.__updateTimestamp(pathname, st)
return True
def fullVerify(self, packageDir = None, pathname = None, notify = None):
""" Performs a more thorough test to ensure the file has not
been modified. This test is less vulnerable to malicious
@ -235,7 +235,7 @@ class FileSpec:
""" Corrects the internal hash to match the one on disk. """
if not self.actualFile:
self.checkHash(packageDir, pathname, st)
if notify:
notify.info("Correcting hash %s to %s" % (
self.filename, self.actualFile.hash))

View File

@ -1,7 +1,6 @@
from pandac.PandaModules import HashVal, Filename, PandaSystem, DocumentSpec, Ramfile
from pandac.PandaModules import HTTPChannel
from pandac import PandaModules
from libpandaexpress import ConfigVariableInt
from panda3d.core import HashVal, Filename, PandaSystem, DocumentSpec, Ramfile
from panda3d.core import HTTPChannel, ConfigVariableInt
from panda3d import core
from direct.p3d.PackageInfo import PackageInfo
from direct.p3d.FileSpec import FileSpec
from direct.directnotify.DirectNotifyGlobal import directNotify
@ -49,7 +48,7 @@ class HostInfo:
if hostDir and not isinstance(hostDir, Filename):
hostDir = Filename.fromOsSpecific(hostDir)
self.hostDir = hostDir
self.asMirror = asMirror
self.perPlatform = perPlatform
@ -175,7 +174,7 @@ class HostInfo:
statusString = channel.getStatusString()
self.notify.warning("Could not contact download server at %s" % (url,))
self.notify.warning("Status code = %s %s" % (statusCode, statusString))
if not rf:
self.notify.warning("Unable to download %s" % (url,))
try:
@ -206,7 +205,7 @@ class HostInfo:
self.notify.warning("%s" % (str(e),))
pass
return False
tempFilename = Filename.temporary('', 'p3d_', '.xml')
if rf:
f = open(tempFilename.toOsSpecific(), 'wb')
@ -278,7 +277,7 @@ class HostInfo:
now = int(time.time())
return now < self.contentsExpiration and self.hasContentsFile
def readContentsFile(self, tempFilename = None, freshDownload = False):
""" Reads the contents.xml file for this particular host, once
it has been downloaded into the indicated temporary file.
@ -290,7 +289,7 @@ class HostInfo:
there already. If tempFilename is not specified, the standard
filename is read if it is known. """
if not hasattr(PandaModules, 'TiXmlDocument'):
if not hasattr(core, 'TiXmlDocument'):
return False
if not tempFilename:
@ -304,7 +303,7 @@ class HostInfo:
tempFilename = Filename(hostDir, 'contents.xml')
doc = PandaModules.TiXmlDocument(tempFilename.toOsSpecific())
doc = core.TiXmlDocument(tempFilename.toOsSpecific())
if not doc.LoadFile():
return False
@ -337,12 +336,12 @@ class HostInfo:
xcontents.RemoveChild(xorig)
xorig = xcontents.FirstChildElement('orig')
xorig = PandaModules.TiXmlElement('orig')
xorig = core.TiXmlElement('orig')
self.contentsSpec.storeXml(xorig)
xorig.SetAttribute('expiration', str(self.contentsExpiration))
xcontents.InsertEndChild(xorig)
else:
# Read the download hash and expiration time from the XML.
expiration = None
@ -385,7 +384,7 @@ class HostInfo:
perPlatform = int(xpackage.Attribute('per_platform') or '')
except ValueError:
perPlatform = False
package = self.__makePackage(name, platform, version, solo, perPlatform)
package.descFile = FileSpec()
package.descFile.loadXml(xpackage)
@ -418,7 +417,7 @@ class HostInfo:
""" Looks for the <host> or <alt_host> entry in the
contents.xml that corresponds to the URL that we actually
downloaded from. """
xhost = xcontents.FirstChildElement('host')
while xhost:
url = xhost.Attribute('url')
@ -433,7 +432,7 @@ class HostInfo:
self.readHostXml(xalthost)
return
xalthost = xalthost.NextSiblingElement('alt_host')
xhost = xhost.NextSiblingElement('host')
def __findHostXmlForHostDir(self, xcontents):
@ -442,7 +441,7 @@ class HostInfo:
contents.xml from. This is used when reading a contents.xml
file found on disk, as opposed to downloading it from a
site. """
xhost = xcontents.FirstChildElement('host')
while xhost:
url = xhost.Attribute('url')
@ -463,7 +462,7 @@ class HostInfo:
self.readHostXml(xalthost)
return
xalthost = xalthost.NextSiblingElement('alt_host')
xhost = xhost.NextSiblingElement('host')
def readHostXml(self, xhost):
@ -487,7 +486,7 @@ class HostInfo:
self.downloadUrlPrefix += '/'
else:
self.downloadUrlPrefix = self.hostUrlPrefix
xmirror = xhost.FirstChildElement('mirror')
while xmirror:
url = xmirror.Attribute('url')
@ -611,7 +610,7 @@ class HostInfo:
the list of packages that were NOT found. """
packages = packages[:]
for key, platforms in self.packages.items():
for platform, package in platforms.items():
if package in packages:

View File

@ -1,11 +1,11 @@
from pandac.PandaModules import URLSpec
from panda3d.core import URLSpec
class InstalledHostData:
""" A list of instances of this class is returned by
AppRunner.scanInstalledPackages(). Each of these corresponds to a
particular host that has provided packages that have been
installed on the local client. """
def __init__(self, host, dirnode):
self.host = host
self.pathname = dirnode.pathname

View File

@ -1,6 +1,5 @@
from pandac.PandaModules import Filename, URLSpec, DocumentSpec, Ramfile, Multifile, Decompressor, EUOk, EUSuccess, VirtualFileSystem, Thread, getModelPath, ExecutionEnvironment, PStatCollector, TiXmlDocument, TiXmlDeclaration, TiXmlElement
from pandac import PandaModules
from libpandaexpress import ConfigVariableInt
from panda3d.core import Filename, URLSpec, DocumentSpec, Ramfile, Multifile, Decompressor, EUOk, EUSuccess, VirtualFileSystem, Thread, getModelPath, ExecutionEnvironment, PStatCollector, TiXmlDocument, TiXmlDeclaration, TiXmlElement
import panda3d.core as core
from direct.p3d.FileSpec import FileSpec
from direct.p3d.ScanDirectoryNode import ScanDirectoryNode
from direct.showbase import VFSImporter
@ -55,7 +54,7 @@ class PackageInfo:
tokens. This function defines a new generator that yields
each of those tokens, but wraps each call into the nested
generator within a pair of start/stop collector calls. """
self.pStatCol.start()
for token in self.__funcPtr(self):
self.pStatCol.stop()
@ -76,7 +75,7 @@ class PackageInfo:
if self.bytesNeeded == 0:
return 1
return min(float(self.bytesDone) / float(self.bytesNeeded), 1)
def __init__(self, host, packageName, packageVersion, platform = None,
solo = False, asMirror = False, perPlatform = False):
self.host = host
@ -94,7 +93,7 @@ class PackageInfo:
# This will be filled in when the host's contents.xml file is
# read.
self.packageDir = None
# These will be filled in by HostInfo when the package is read
# from contents.xml.
self.descFile = None
@ -110,11 +109,11 @@ class PackageInfo:
self.extracts = []
self.requires = []
self.installPlans = None
# This is updated during downloadPackage(). It is in the
# range 0..1.
self.downloadProgress = 0
# This is set true when the package file has been fully
# downloaded and unpacked.
self.hasPackage = False
@ -133,12 +132,12 @@ class PackageInfo:
This may not be known until the host's contents.xml file has
been downloaded, which informs us of the host's own install
directory. """
if not self.packageDir:
if not self.host.hasContentsFile:
if not self.host.readContentsFile():
self.host.downloadContentsFile(self.http)
# Derive the packageDir from the hostDir.
self.packageDir = Filename(self.host.hostDir, self.packageName)
if self.packageVersion:
@ -159,7 +158,7 @@ class PackageInfo:
# plugin--and we therefore shouldn't include the
# platform in the directory hierarchy.
includePlatform = False
if includePlatform and self.platform:
self.packageDir = Filename(self.packageDir, self.platform)
@ -176,7 +175,7 @@ class PackageInfo:
# Return the size of plan A, assuming it will work.
plan = self.installPlans[0]
size = sum([step.getEffort() for step in plan])
return size
def getPrevDownloadedEffort(self):
@ -209,13 +208,13 @@ class PackageInfo:
name += ' rev %s' % (self.patchVersion)
return name
def setupFilenames(self):
""" This is called by the HostInfo when the package is read
from contents.xml, to set up the internal filenames and such
that rely on some of the information from contents.xml. """
dirname, basename = self.descFile.filename.rsplit('/', 1)
self.descFileDirname = dirname
self.descFileBasename = basename
@ -264,7 +263,7 @@ class PackageInfo:
Thread.considerYield()
return (token == self.stepComplete)
def downloadDescFileGenerator(self, http):
""" A generator function that implements downloadDescFile()
one piece at a time. It yields one of stepComplete,
@ -343,9 +342,9 @@ class PackageInfo:
filename = Filename(self.getPackageDir(), self.descFileBasename)
if not hasattr(PandaModules, 'TiXmlDocument'):
if not hasattr(core, 'TiXmlDocument'):
return False
doc = PandaModules.TiXmlDocument(filename.toOsSpecific())
doc = core.TiXmlDocument(filename.toOsSpecific())
if not doc.LoadFile():
return False
@ -432,7 +431,7 @@ class PackageInfo:
pc.start()
self.hasPackage = False
if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever:
# We're not allowed to download anything.
self.installPlans = []
@ -447,12 +446,12 @@ class PackageInfo:
# archive.
downloadSize = self.compressedArchive.size
func = lambda step, fileSpec = self.compressedArchive: self.__downloadFile(step, fileSpec, allowPartial = True)
step = self.InstallStep(func, downloadSize, self.downloadFactor, 'download')
installPlan = [step]
self.installPlans = [installPlan]
pc.stop()
return
return
# The normal download process. Determine what we will need to
# download, and build a plan (or two) to download it all.
@ -520,9 +519,9 @@ class PackageInfo:
# plan B as the only plan.
self.installPlans = [planB]
# In case of unexpected failures on the internet, we will retry
# In case of unexpected failures on the internet, we will retry
# the full download instead of just giving up.
for retry in range(ConfigVariableInt('package-full-dl-retries', 1)):
for retry in range(core.ConfigVariableInt('package-full-dl-retries', 1)):
self.installPlans.append(planB[:])
pc.stop()
@ -530,7 +529,7 @@ class PackageInfo:
def __scanDirectoryRecursively(self, dirname):
""" Generates a list of Filename objects: all of the files
(not directories) within and below the indicated dirname. """
contents = []
for dirpath, dirnames, filenames in os.walk(dirname.toOsSpecific()):
dirpath = Filename.fromOsSpecific(dirpath)
@ -560,7 +559,7 @@ class PackageInfo:
# Get a list of all of the files in the directory, so we can
# remove files that don't belong.
contents = self.__scanDirectoryRecursively(self.getPackageDir())
contents = self.__scanDirectoryRecursively(self.getPackageDir())
self.__removeFileFromList(contents, self.descFileBasename)
self.__removeFileFromList(contents, self.compressedArchive.filename)
self.__removeFileFromList(contents, self.UsageBasename)
@ -582,7 +581,7 @@ class PackageInfo:
if self.asMirror:
return self.compressedArchive.quickVerify(self.getPackageDir(), notify = self.notify)
allExtractsOk = True
if not self.uncompressedArchive.quickVerify(self.getPackageDir(), notify = self.notify):
self.notify.debug("File is incorrect: %s" % (self.uncompressedArchive.filename))
@ -593,7 +592,7 @@ class PackageInfo:
# shouldn't be a compressed archive file here.
pathname = Filename(self.getPackageDir(), self.compressedArchive.filename)
pathname.unlink()
for file in self.extracts:
if not file.quickVerify(self.getPackageDir(), notify = self.notify):
self.notify.debug("File is incorrect: %s" % (file.filename))
@ -614,7 +613,7 @@ class PackageInfo:
size = self.totalPlanCompleted + self.currentStepEffort * step.getProgress()
self.downloadProgress = min(float(size) / float(self.totalPlanSize), 1)
def downloadPackage(self, http):
""" Downloads the package file, synchronously, then
uncompresses and unpacks it. Returns true on success, false
@ -630,7 +629,7 @@ class PackageInfo:
Thread.considerYield()
return (token == self.stepComplete)
def downloadPackageGenerator(self, http):
""" A generator function that implements downloadPackage() one
piece at a time. It yields one of stepComplete, stepFailed,
@ -655,7 +654,7 @@ class PackageInfo:
yield token
else:
break
while token == self.restartDownload:
# Try again.
for token in self.downloadDescFileGenerator(http):
@ -675,7 +674,7 @@ class PackageInfo:
assert token == self.stepComplete
yield self.stepComplete; return
def __followInstallPlans(self):
""" Performs all of the steps in self.installPlans. Yields
@ -701,16 +700,16 @@ class PackageInfo:
yield token
else:
break
if token == self.restartDownload:
yield token
if token == self.stepFailed:
planFailed = True
break
assert token == self.stepComplete
self.totalPlanCompleted += self.currentStepEffort
if not planFailed:
# Successfully downloaded!
yield self.stepComplete; return
@ -754,7 +753,7 @@ class PackageInfo:
def __downloadFile(self, step, fileSpec, urlbase = None, filename = None,
allowPartial = False):
""" Downloads the indicated file from the host into
packageDir. Yields one of stepComplete, stepFailed,
packageDir. Yields one of stepComplete, stepFailed,
restartDownload, or stepContinue. """
if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever:
@ -806,7 +805,7 @@ class PackageInfo:
url += '?' + str(int(time.time()))
request = DocumentSpec(url)
request.setCacheControl(DocumentSpec.CCNoCache)
self.notify.info("%s downloading %s" % (self.packageName, url))
if not filename:
@ -839,7 +838,7 @@ class PackageInfo:
targetPathname.makeDir()
targetPathname.unlink()
channel.beginGetDocument(request)
channel.downloadToFile(targetPathname)
while channel.run():
if step:
@ -849,7 +848,7 @@ class PackageInfo:
# it's the wrong file.
self.notify.warning("Got more data than expected for download %s" % (url))
break
self.__updateStepProgress(step)
if taskMgr.destroyed:
@ -857,9 +856,9 @@ class PackageInfo:
# be shutting down. Get out of here.
self.notify.warning("Task Manager destroyed, aborting %s" % (url))
yield self.stepFailed; return
yield self.stepContinue
if step:
step.bytesDone = channel.getBytesDownloaded() + channel.getFirstByteDelivered()
self.__updateStepProgress(step)
@ -897,7 +896,7 @@ class PackageInfo:
def __applyPatch(self, step, patchfile):
""" Applies the indicated patching in-place to the current
uncompressed archive. The patchfile is removed after the
operation. Yields one of stepComplete, stepFailed,
operation. Yields one of stepComplete, stepFailed,
restartDownload, or stepContinue. """
self.updated = True
@ -907,7 +906,7 @@ class PackageInfo:
result = Filename.temporary('', 'patch_')
self.notify.info("Patching %s with %s" % (origPathname, patchPathname))
p = PandaModules.Patchfile() # The C++ class
p = core.Patchfile() # The C++ class
ret = p.initiate(patchPathname, origPathname, result)
if ret == EUSuccess:
@ -925,7 +924,7 @@ class PackageInfo:
ret = p.run()
del p
patchPathname.unlink()
if ret < 0:
self.notify.warning("Patching of %s failed." % (origPathname))
result.unlink()
@ -934,12 +933,12 @@ class PackageInfo:
if not result.renameTo(origPathname):
self.notify.warning("Couldn't rename %s to %s" % (result, origPathname))
yield self.stepFailed; return
yield self.stepComplete; return
def __uncompressArchive(self, step):
""" Turns the compressed archive into the uncompressed
archive. Yields one of stepComplete, stepFailed,
archive. Yields one of stepComplete, stepFailed,
restartDownload, or stepContinue. """
if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever:
@ -970,7 +969,7 @@ class PackageInfo:
if result != EUSuccess:
yield self.stepFailed; return
step.bytesDone = totalBytes
self.__updateStepProgress(step)
@ -985,10 +984,10 @@ class PackageInfo:
# Now we can safely remove the compressed archive.
sourcePathname.unlink()
yield self.stepComplete; return
def __unpackArchive(self, step):
""" Unpacks any files in the archive that want to be unpacked
to disk. Yields one of stepComplete, stepFailed,
to disk. Yields one of stepComplete, stepFailed,
restartDownload, or stepContinue. """
if not self.extracts:
@ -1008,7 +1007,7 @@ class PackageInfo:
if not mf.openRead(mfPathname):
self.notify.warning("Couldn't open %s" % (mfPathname))
yield self.stepFailed; return
allExtractsOk = True
step.bytesDone = 0
for file in self.extracts:
@ -1025,7 +1024,7 @@ class PackageInfo:
self.notify.warning("Couldn't extract: %s" % (file.filename))
allExtractsOk = False
continue
if not file.quickVerify(self.getPackageDir(), notify = self.notify):
self.notify.warning("After extracting, still incorrect: %s" % (file.filename))
allExtractsOk = False
@ -1157,7 +1156,7 @@ class PackageInfo:
""" Marks the package as having been used. This is normally
called automatically by installPackage(). """
if not hasattr(PandaModules, 'TiXmlDocument'):
if not hasattr(core, 'TiXmlDocument'):
return
if self.host.appRunner and self.host.appRunner.verifyContents == self.host.appRunner.P3DVCNever:
@ -1174,14 +1173,14 @@ class PackageInfo:
if not doc.LoadFile():
decl = TiXmlDeclaration("1.0", "utf-8", "")
doc.InsertEndChild(decl)
xusage = doc.FirstChildElement('usage')
if not xusage:
doc.InsertEndChild(TiXmlElement('usage'))
xusage = doc.FirstChildElement('usage')
now = int(time.time())
count = xusage.Attribute('count_app')
try:
count = int(count or '')
@ -1214,22 +1213,22 @@ class PackageInfo:
tfile = Filename.temporary(self.getPackageDir().cStr(), '.xml')
if doc.SaveFile(tfile.toOsSpecific()):
tfile.renameTo(filename)
def getUsage(self):
""" Returns the xusage element that is read from the usage.xml
file, or None if there is no usage.xml file. """
if not hasattr(PandaModules, 'TiXmlDocument'):
if not hasattr(core, 'TiXmlDocument'):
return None
filename = Filename(self.getPackageDir(), self.UsageBasename)
doc = TiXmlDocument(filename.toOsSpecific())
if not doc.LoadFile():
return None
xusage = doc.FirstChildElement('usage')
if not xusage:
return None
return copy.copy(xusage)

View File

@ -3,7 +3,7 @@ from direct.stdpy.threading import Lock, RLock
from direct.showbase.MessengerGlobal import messenger
from direct.task.TaskManagerGlobal import taskMgr
from direct.p3d.PackageInfo import PackageInfo
from pandac.PandaModules import TPLow, PStatCollector
from panda3d.core import TPLow, PStatCollector
from direct.directnotify.DirectNotifyGlobal import directNotify
class PackageInstaller(DirectObject):
@ -33,7 +33,7 @@ class PackageInstaller(DirectObject):
S_ready = 1 # donePackages() has been called
S_started = 2 # download has started
S_done = 3 # download is over
class PendingPackage:
""" This class describes a package added to the installer for
download. """
@ -121,12 +121,12 @@ class PackageInstaller(DirectObject):
self.prevDownloadedEffort = self.package.getPrevDownloadedEffort()
return True
def getDescFile(self, http):
""" Synchronously downloads the desc files required for
the package. """
if not self.host.downloadContentsFile(http):
return False
@ -156,10 +156,10 @@ class PackageInstaller(DirectObject):
PackageInstaller.nextUniqueId += 1
finally:
self.globalLock.release()
self.appRunner = appRunner
self.taskChain = taskChain
# If we're to be running on an asynchronous task chain, and
# the task chain hasn't yet been set up already, create the
# default parameters now.
@ -180,7 +180,7 @@ class PackageInstaller(DirectObject):
# A list of packages that are waiting for their desc files.
self.needsDescFile = []
self.descFileTask = None
# A list of packages that are waiting to be downloaded and
# installed.
self.needsDownload = []
@ -198,7 +198,7 @@ class PackageInstaller(DirectObject):
# This task is spawned on the default task chain, to update
# the status during the download.
self.progressTask = None
self.accept('PackageInstaller-%s-allHaveDesc' % self.uniqueId,
self.__allHaveDesc)
self.accept('PackageInstaller-%s-packageStarted' % self.uniqueId,
@ -231,7 +231,7 @@ class PackageInstaller(DirectObject):
self.progressTask = None
self.ignoreAll()
def addPackage(self, packageName, version = None, hostUrl = None):
""" Adds the named package to the list of packages to be
downloaded. Call donePackages() to finish the list. """
@ -256,7 +256,7 @@ class PackageInstaller(DirectObject):
if pp in self.packages:
# Already added.
return
self.packages.append(pp)
# We always add the package to needsDescFile, even if we
@ -323,7 +323,7 @@ class PackageInstaller(DirectObject):
(beginning) to 1 (complete). """
self.notify.debug("packageProgress: %s %s" % (package.packageName, progress))
def downloadProgress(self, overallProgress):
""" This callback is made repeatedly between downloadStarted()
and downloadFinished() to update the current progress through
@ -384,7 +384,7 @@ class PackageInstaller(DirectObject):
""" This method is called internally when all of the pending
packages have their desc info. """
working = True
self.packageLock.acquire()
try:
if self.state == self.S_ready:
@ -489,7 +489,7 @@ class PackageInstaller(DirectObject):
it extracts one package from self.needsDescFile and downloads
its desc file. On success, it adds the package to
self.needsDownload. """
self.packageLock.acquire()
try:
# If we've finished all of the packages that need desc
@ -515,7 +515,7 @@ class PackageInstaller(DirectObject):
# This package is now ready to be downloaded. We always add
# it to needsDownload, even if it's already downloaded, to
# guarantee ordering of packages.
self.packageLock.acquire()
try:
# Also add any packages required by this one.
@ -527,7 +527,7 @@ class PackageInstaller(DirectObject):
self.packageLock.release()
return task.cont
def __downloadPackageTask(self, task):
""" This task runs on the aysynchronous task chain; each pass,
@ -543,7 +543,7 @@ class PackageInstaller(DirectObject):
self.packageLock.release()
yield task.done; return
assert self.state == self.S_started
assert self.state == self.S_started
pp = self.needsDownload[0]
del self.needsDownload[0]
except:
@ -578,7 +578,7 @@ class PackageInstaller(DirectObject):
# Continue the loop without yielding, so we pick up the
# next package within this same frame.
def __donePackage(self, pp, success):
""" Marks the indicated package as done, either successfully
or otherwise. """
@ -630,9 +630,9 @@ class PackageInstaller(DirectObject):
else:
progress = float(currentDownloadSize) / float(downloadEffort)
self.downloadProgress(progress)
finally:
self.callbackLock.release()
return task.cont

View File

@ -1,7 +1,7 @@
from direct.p3d.FileSpec import FileSpec
from direct.p3d.SeqValue import SeqValue
from direct.directnotify.DirectNotifyGlobal import *
from pandac.PandaModules import *
from panda3d.core import *
import copy
import shutil
import os
@ -18,11 +18,11 @@ class PackageMerger:
always the most current version of the file. """
notify = directNotify.newCategory("PackageMerger")
class PackageEntry:
""" This corresponds to a <package> entry in the contents.xml
file. """
def __init__(self, xpackage, sourceDir):
self.sourceDir = sourceDir
self.loadXml(xpackage)
@ -48,7 +48,7 @@ class PackageMerger:
self.descFile.loadXml(xpackage)
self.validatePackageContents()
self.descFile.quickVerify(packageDir = self.sourceDir, notify = PackageMerger.notify, correctSelf = True)
self.packageSeq = SeqValue()
@ -84,7 +84,7 @@ class PackageMerger:
ximport = TiXmlElement('import')
self.importDescFile.storeXml(ximport)
xpackage.InsertEndChild(ximport)
return xpackage
def validatePackageContents(self):
@ -170,7 +170,7 @@ class PackageMerger:
xhost = xcontents.FirstChildElement('host')
if xhost:
self.xhost = xhost.Clone()
xpackage = xcontents.FirstChildElement('package')
while xpackage:
pe = self.PackageEntry(xpackage, sourceDir)
@ -183,7 +183,7 @@ class PackageMerger:
if not other or pe.isNewer(other):
# Store this package in the resulting output.
self.contents[pe.getKey()] = pe
xpackage = xpackage.NextSiblingElement('package')
self.contentsDoc = doc
@ -247,7 +247,7 @@ class PackageMerger:
else:
# Both the source file and target file are
# directories.
# We have to clean out the target directory first.
# Instead of using shutil.rmtree(), remove the files in
# this directory one at a time, so we don't inadvertently
@ -282,10 +282,10 @@ class PackageMerger:
the current pool. If packageNames is not None, it is a list
of package names that we wish to include from the source;
packages not named in this list will be unchanged. """
if not self.__readContentsFile(sourceDir, packageNames):
message = "Couldn't read %s" % (sourceDir)
raise PackageMergerError, message
raise PackageMergerError, message
def close(self):
""" Finalizes the results of all of the previous calls to
@ -302,4 +302,4 @@ class PackageMerger:
self.contentsSeq += 1
self.__writeContentsFile()

View File

@ -15,6 +15,7 @@ import types
import getpass
import platform
import struct
import subprocess
from direct.p3d.FileSpec import FileSpec
from direct.p3d.SeqValue import SeqValue
from direct.showbase import Loader
@ -58,7 +59,7 @@ class Packager:
self.required = required
if not self.newName:
self.newName = self.filename.cStr()
self.newName = str(self.filename)
ext = Filename(self.newName).getExtension()
if ext == 'pz':
@ -66,7 +67,7 @@ class Packager:
# within the Multifile without it.
filename = Filename(self.newName)
filename.setExtension('')
self.newName = filename.cStr()
self.newName = str(filename)
ext = Filename(self.newName).getExtension()
if self.compress is None:
self.compress = True
@ -80,8 +81,8 @@ class Packager:
if self.executable and self.dependencyDir is None:
# By default, install executable dependencies in the
# same directory with the executable itself.
self.dependencyDir = Filename(self.newName).getDirname()
# root directory, which is the one that's added to PATH.
self.dependencyDir = ''
if self.extract is None:
self.extract = self.executable or (ext in packager.extractExtensions)
@ -93,13 +94,13 @@ class Packager:
if self.executable:
# Look up the filename along the system PATH, if necessary.
if not self.filename.resolveFilename(packager.executablePath):
if not packager.resolveLibrary(self.filename):
# If it wasn't found, try looking it up under its
# basename only. Sometimes a Mac user will copy
# the library file out of a framework and put that
# along the PATH, instead of the framework itself.
basename = Filename(self.filename.getBasename())
if basename.resolveFilename(packager.executablePath):
if packager.resolveLibrary(basename):
self.filename = basename
if ext in packager.textExtensions and not self.executable:
@ -156,7 +157,7 @@ class Packager:
if not self.localOnly:
filename = Filename(filename)
filename.makeCanonical()
self.glob = GlobPattern(filename.cStr())
self.glob = GlobPattern(str(filename))
if self.packager.platform.startswith('win'):
self.glob.setCaseSensitive(False)
@ -167,7 +168,7 @@ class Packager:
if self.localOnly:
return self.glob.matches(filename.getBasename())
else:
return self.glob.matches(filename.cStr())
return self.glob.matches(str(filename))
class PackageEntry:
""" This corresponds to a <package> entry in the contents.xml
@ -586,9 +587,9 @@ class Packager:
# (i.e. missing) modules.
continue
if newName == '__main__':
# Ignore this special case.
continue
#if newName == '__main__':
# # Ignore this special case.
# continue
self.moduleNames[newName] = mdef
@ -937,7 +938,7 @@ class Packager:
# means we should include the manifest
# file itself in the package.
newName = Filename(file.dependencyDir, mfile.getBasename())
self.addFile(mfile, newName = newName.cStr(),
self.addFile(mfile, newName = str(newName),
explicit = False, executable = True)
if afilenames is None and out != 31:
@ -957,7 +958,7 @@ class Packager:
filename.makeTrueCase()
newName = Filename(file.dependencyDir, filename.getBasename())
self.addFile(filename, newName = newName.cStr(),
self.addFile(filename, newName = str(newName),
explicit = False, executable = True)
def __parseDependenciesWindows(self, tempFile):
@ -1172,7 +1173,7 @@ class Packager:
# It's a fully-specified filename; look
# for it under the system root first.
if self.packager.systemRoot:
f2 = Filename(self.packager.systemRoot + filename.cStr())
f2 = Filename(self.packager.systemRoot, filename)
if f2.exists():
filename = f2
@ -1181,7 +1182,7 @@ class Packager:
continue
newName = Filename(file.dependencyDir, filename.getBasename())
self.addFile(filename, newName = newName.cStr(),
self.addFile(filename, newName = str(newName),
explicit = False, executable = True)
def __parseDependenciesOSX(self, tempFile):
@ -1346,6 +1347,7 @@ class Packager:
# If that failed, perhaps ldd will help us.
if filenames is None:
self.notify.warning("Reading ELF library %s failed, using ldd instead" % (file.filename))
tempFile = Filename.temporary('', 'p3d_', '.txt')
command = 'ldd "%s" >"%s"' % (
file.filename.toOsSpecific(),
@ -1379,7 +1381,7 @@ class Packager:
filename.setBinary()
newName = Filename(file.dependencyDir, filename.getBasename())
self.addFile(filename, newName = newName.cStr(),
self.addFile(filename, newName = str(newName),
explicit = False, executable = True)
def __parseDependenciesPosix(self, tempFile):
@ -1470,7 +1472,7 @@ class Packager:
# compatible with older versions of the core API that
# didn't understand the SF_text flag.
filename.setBinary()
doc.SaveFile(filename.toOsSpecific())
# It's important not to compress this file: the core API
@ -1772,8 +1774,6 @@ class Packager:
return xspec
def addPyFile(self, file):
""" Adds the indicated python file, identified by filename
instead of by module name, to the package. """
@ -1793,6 +1793,18 @@ class Packager:
# deal with it again.
return
# Make sure that it is actually in a package.
parentName = moduleName
while '.' in parentName:
parentName = parentName.rsplit('.', 1)[0]
if parentName not in self.freezer.modules:
message = 'Cannot add Python file %s; not in package' % (file.newName)
if file.required or file.explicit:
raise StandardError, message
else:
self.notify.warning(message)
return
self.freezer.addModule(moduleName, filename = file.filename)
def addEggFile(self, file):
@ -1803,7 +1815,7 @@ class Packager:
bamName = Filename(file.newName)
bamName.setExtension('bam')
self.addNode(np.node(), file.filename, bamName.cStr())
self.addNode(np.node(), file.filename, str(bamName))
def addBamFile(self, file):
# Load the bam file so we can massage its textures.
@ -2207,6 +2219,9 @@ class Packager:
cvar = ConfigVariableSearchPath('pdef-path')
self.installSearch = list(map(Filename, cvar.getDirectories()))
# This is where we cache the location of libraries.
self.libraryCache = {}
# The system PATH, for searching dll's and exe's.
self.executablePath = DSearchPath()
@ -2219,22 +2234,36 @@ class Packager:
# Now add the actual system search path.
if self.platform.startswith('win'):
self.addWindowsSearchPath(self.executablePath, "PATH")
elif self.platform.startswith('osx'):
self.addPosixSearchPath(self.executablePath, "DYLD_LIBRARY_PATH")
self.addPosixSearchPath(self.executablePath, "LD_LIBRARY_PATH")
self.addPosixSearchPath(self.executablePath, "PATH")
self.executablePath.appendDirectory('/lib')
self.executablePath.appendDirectory('/usr/lib')
self.executablePath.appendDirectory('/usr/local/lib')
else:
self.addPosixSearchPath(self.executablePath, "LD_LIBRARY_PATH")
self.addPosixSearchPath(self.executablePath, "PATH")
self.executablePath.appendDirectory('/lib')
self.executablePath.appendDirectory('/usr/lib')
self.executablePath.appendDirectory('/usr/local/lib')
import platform
if platform.uname()[1]=="pcbsd":
else:
if self.platform.startswith('osx'):
self.addPosixSearchPath(self.executablePath, "DYLD_LIBRARY_PATH")
self.addPosixSearchPath(self.executablePath, "LD_LIBRARY_PATH")
self.addPosixSearchPath(self.executablePath, "PATH")
if self.platform.startswith('linux'):
# It used to be okay to just add some common paths on Linux.
# But nowadays, each distribution has their own convention for
# where they put their libraries. Instead, we query the ldconfig
# cache, which contains the location of all libraries.
if not self.loadLdconfigCache():
# Ugh, failure. All that remains is to guess. This should
# work for the most common Debian configurations.
multiarchDir = "/lib/%s-linux-gnu" % (os.uname()[4])
if os.path.isdir(multiarchDir):
self.executablePath.appendDirectory(multiarchDir)
if os.path.isdir("/usr/" + multiarchDir):
self.executablePath.appendDirectory("/usr/" + multiarchDir)
else:
# FreeBSD, or some other system that still makes sense.
self.executablePath.appendDirectory('/lib')
self.executablePath.appendDirectory('/usr/lib')
self.executablePath.appendDirectory('/usr/local/lib')
if os.uname()[1] == "pcbsd":
self.executablePath.appendDirectory('/usr/PCBSD/local/lib')
# Set this flag true to automatically add allow_python_dev to
@ -2388,6 +2417,7 @@ class Packager:
GlobPattern('libpthread.so*'),
GlobPattern('libthr.so*'),
GlobPattern('ld-linux.so*'),
GlobPattern('ld-linux-*.so*'),
]
# A Loader for loading models.
@ -2405,6 +2435,60 @@ class Packager:
# file.
self.contents = {}
def loadLdconfigCache(self):
""" On GNU/Linux, runs ldconfig -p to find out where all the
libraries on the system are located. Assumes that the platform
has already been set. """
if not os.path.isfile('/sbin/ldconfig'):
return False
handle = subprocess.Popen(['/sbin/ldconfig', '-p'], stdout=subprocess.PIPE)
out, err = handle.communicate()
if handle.returncode != 0:
self.notify.warning("/sbin/ldconfig -p returned code %d" %(handle.returncode))
return False
for line in out.splitlines():
if '=>' not in line:
continue
prefix, location = line.rsplit('=>', 1)
prefix = prefix.strip()
location = location.strip()
if not location or not prefix or ' ' not in prefix:
self.notify.warning("Ignoring malformed ldconfig -p line: " + line)
continue
lib, opts = prefix.split(' ', 1)
if ('x86-64' in opts) != self.platform.endswith('_amd64'):
# This entry isn't meant for our architecture. I think
# x86-64 is the only platform where ldconfig supplies
# this extra arch string.
continue
self.libraryCache[lib] = Filename.fromOsSpecific(location)
return True
def resolveLibrary(self, filename):
""" Resolves the given shared library filename along the executable path,
or by cross-referencing it with the library cache. """
path = str(filename)
if path in self.libraryCache:
filename.setFullpath(self.libraryCache[path].getFullpath())
return True
if filename.resolveFilename(self.executablePath):
self.libraryCache[path] = Filename(filename)
return True
return False
def setPlatform(self, platform = None):
""" Sets the platform that this Packager will compute for. On
OSX, this can be used to specify the particular architecture
@ -3143,9 +3227,17 @@ class Packager:
for moduleName in args:
self.currentPackage.freezer.excludeModule(moduleName)
def do_main(self, filename):
""" Includes the indicated file as __main__ module of the application.
Also updates mainModule to point to this module. """
self.addModule(['__main__'], '__main__', filename, required = True)
self.currentPackage.mainModule = ('__main__', '__main__')
def do_mainModule(self, moduleName, newName = None, filename = None):
""" Names the indicated module as the "main" module of the
application or exe. """
application or exe. In most cases, you will want to use main()
instead. """
if not self.currentPackage:
raise OutsideOfPackageError
@ -3162,7 +3254,7 @@ class Packager:
newFilename = Filename('/'.join(moduleName.split('.')))
newFilename.setExtension(filename.getExtension())
self.currentPackage.addFile(
filename, newName = newFilename.cStr(),
filename, newName = str(newFilename),
explicit = True, extract = True, required = True)
self.currentPackage.mainModule = (moduleName, newName)
@ -3194,7 +3286,9 @@ class Packager:
# Multifile, so this file can't itself be in the Multifile.
# This requires a bit of care, because we only want to freeze
# VFSImporter.py, and not any other part of direct.
# VFSImporter.py, and not any other part of direct. We do
# also want panda3d/__init__.py, though, since it would
# otherwise be part of the multifile.
self.do_excludeModule('direct')
# Import the actual VFSImporter module to get its filename on
@ -3205,7 +3299,7 @@ class Packager:
self.do_module('VFSImporter', filename = filename)
self.do_freeze('_vfsimporter', compileToExe = False)
self.do_file('libpandaexpress.dll');
self.do_file('panda3d/core.pyd');
# Now that we're done freezing, explicitly add 'direct' to
# counteract the previous explicit excludeModule().
@ -3438,13 +3532,13 @@ class Packager:
# build.
dllFilename = Filename(filename)
dllFilename.setExtension('so')
dllFilename = Filename.dsoFilename(dllFilename.cStr())
dllFilename = Filename.dsoFilename(str(dllFilename))
if dllFilename != filename:
thisFiles = glob.glob(filename.toOsSpecific())
if not thisFiles:
# We have to resolve this filename to
# determine if it's a _d or not.
if dllFilename.resolveFilename(self.executablePath):
if self.resolveLibrary(dllFilename):
thisFiles = [dllFilename.toOsSpecific()]
else:
thisFiles = [filename.toOsSpecific()]
@ -3455,7 +3549,7 @@ class Packager:
prefix = ''
if newDir is not None:
prefix = Filename(newDir).cStr()
prefix = str(Filename(newDir))
if prefix and prefix[-1] != '/':
prefix += '/'
@ -3527,13 +3621,22 @@ class Packager:
sys.path.append(dirname.toOsSpecific())
self.__recurseDir(dirname, newDir, unprocessed = unprocessed)
def __recurseDir(self, filename, newName, unprocessed = None):
def __recurseDir(self, filename, newName, unprocessed = None, packageTree = None):
dirList = vfs.scanDirectory(filename)
if dirList:
# It's a directory name. Recurse.
prefix = newName
if prefix and prefix[-1] != '/':
prefix += '/'
# First check if this is a Python package tree. If so, add it
# implicitly as a module.
for subfile in dirList:
filename = subfile.getFilename()
if filename.getBasename() == '__init__.py':
moduleName = newName.replace("/", ".").rsplit('.', 1)[0]
self.addModule([moduleName], filename=filename)
for subfile in dirList:
filename = subfile.getFilename()
self.__recurseDir(filename, prefix + filename.getBasename(),
@ -3550,7 +3653,7 @@ class Packager:
# Strip off an implicit .pz extension.
newFilename = Filename(filename)
newFilename.setExtension('')
newFilename = Filename(newFilename.cStr())
newFilename = Filename(str(newFilename))
ext = newFilename.getExtension()
if ext in self.knownExtensions:

View File

@ -1,6 +1,6 @@
from direct.p3d.FileSpec import FileSpec
from direct.p3d.SeqValue import SeqValue
from pandac.PandaModules import *
from panda3d.core import *
import copy
class PatchMaker:
@ -14,7 +14,7 @@ class PatchMaker:
the package's "version" string; it also corresponds to the
particular patch version, which increments independently of
the "version". """
def __init__(self, packageName, platform, version, hostUrl, file):
self.packageName = packageName
self.platform = platform
@ -84,7 +84,7 @@ class PatchMaker:
apply in sequence, and the packageVersion object
associated with each patch. Returns (None, None, None) if
there is no way to recreate this archive file. """
if self.tempFile:
return (self.tempFile, self, [])
@ -101,7 +101,7 @@ class PatchMaker:
# version of some package.
package = self.packageCurrent
return (Filename(package.packageDir, package.compressedFilename), self, [])
if self.packageBase:
# This PackageVersion instance represents the base
# (oldest) version of some package.
@ -144,7 +144,7 @@ class PatchMaker:
# Failure trying to decompress the file.
return None
startFile = startPv.tempFile
if not plan:
# If plan is a zero-length list, we're already
# here--return startFile. If plan is None, there's no
@ -162,7 +162,7 @@ class PatchMaker:
if not result:
# Failure trying to re-create the file.
return None
pv.tempFile = result
prevFile = result
@ -194,10 +194,10 @@ class PatchMaker:
return patch.toPv
return None
class Patchfile:
""" A single patchfile for a package. """
def __init__(self, package):
self.package = package
self.packageName = package.packageName
@ -233,7 +233,7 @@ class PatchMaker:
def fromFile(self, packageDir, patchFilename, sourceFile, targetFile):
""" Creates the data structures from an existing patchfile
on disk. """
self.file = FileSpec()
self.file.fromFile(packageDir, patchFilename)
self.sourceFile = sourceFile
@ -241,7 +241,7 @@ class PatchMaker:
def loadXml(self, xpatch):
""" Reads the data structures from an xml file. """
self.packageName = xpatch.Attribute('name') or self.packageName
self.platform = xpatch.Attribute('platform') or self.platform
self.version = xpatch.Attribute('version') or self.version
@ -287,7 +287,7 @@ class PatchMaker:
class Package:
""" This is a particular package. This contains all of the
information needed to reconstruct the package's desc file. """
def __init__(self, packageDesc, patchMaker, xpackage = None):
self.packageDir = Filename(patchMaker.installDir, packageDesc.getDirname())
self.packageDesc = packageDesc
@ -312,19 +312,19 @@ class PatchMaker:
def getCurrentKey(self):
""" Returns the key to locate the current version of this
package. """
return (self.packageName, self.platform, self.version, self.hostUrl, self.currentFile)
def getBaseKey(self):
""" Returns the key to locate the "base" or oldest version
of this package. """
return (self.packageName, self.platform, self.version, self.hostUrl, self.baseFile)
def getTopKey(self):
""" Returns the key to locate the "top" or newest version
of this package. """
return (self.packageName, self.platform, self.version, self.hostUrl, self.topFile)
def getGenericKey(self, fileSpec):
@ -345,7 +345,7 @@ class PatchMaker:
if not self.doc.LoadFile():
print "Couldn't read %s" % (packageDescFullpath)
return False
xpackage = self.doc.FirstChildElement('package')
if not xpackage:
return False
@ -358,7 +358,7 @@ class PatchMaker:
# other hosts, which means we'll need to fill in a value
# here for those hosts.
self.hostUrl = None
self.currentFile = None
self.baseFile = None
self.topFile = None
@ -388,7 +388,7 @@ class PatchMaker:
else:
# There's a new version this pass. Update it.
self.anyChanges = True
else:
# If there isn't a top_version yet, we have to make
# one, by duplicating the currentFile.
@ -516,7 +516,7 @@ class PatchMaker:
xarchive = TiXmlElement('top_version')
self.currentFile.storeXml(xarchive)
xpackage.InsertEndChild(xarchive)
for patchfile in self.patches:
xpatch = patchfile.makeXml(self)
xpackage.InsertEndChild(xpatch)
@ -571,7 +571,7 @@ class PatchMaker:
patches for all packages; otherwise, it should be a list of
package name strings, limiting the set of packages that are
processed. """
if not self.readContentsFile():
return False
self.buildPatchChains()
@ -587,7 +587,7 @@ class PatchMaker:
def cleanup(self):
""" Should be called on exit to remove temporary files and
such created during processing. """
for pv in self.packageVersions.values():
pv.cleanup()
@ -596,11 +596,11 @@ class PatchMaker:
constructs a patch chain from the version represented by
fileSpec to the current version of this package, if possible.
Returns the patch chain if successful, or None otherwise. """
package = self.readPackageDescFile(descFilename)
if not package:
return None
self.buildPatchChains()
fromPv = self.getPackageVersion(package.getGenericKey(fileSpec))
toPv = package.currentPv
@ -619,7 +619,7 @@ class PatchMaker:
package = self.Package(Filename(descFilename), self)
if not package.readDescFile(doProcessing = False):
return None
self.packages.append(package)
return package
@ -640,7 +640,7 @@ class PatchMaker:
contentsSeq.loadXml(xcontents)
contentsSeq += 1
contentsSeq.storeXml(xcontents)
xpackage = xcontents.FirstChildElement('package')
while xpackage:
solo = xpackage.Attribute('solo')
@ -651,7 +651,7 @@ class PatchMaker:
package = self.Package(filename, self, xpackage)
package.readDescFile(doProcessing = True)
self.packages.append(package)
xpackage = xpackage.NextSiblingElement('package')
self.contentsDoc = doc
@ -685,7 +685,7 @@ class PatchMaker:
pv = self.PackageVersion(*key)
self.packageVersions[k] = pv
return pv
def buildPatchChains(self):
""" Builds up the chains of PackageVersions and the patchfiles
that connect them. """
@ -696,7 +696,7 @@ class PatchMaker:
if not package.baseFile:
# This package doesn't have any versions yet.
continue
currentPv = self.getPackageVersion(package.getCurrentKey())
package.currentPv = currentPv
currentPv.packageCurrent = package
@ -710,7 +710,7 @@ class PatchMaker:
topPv = self.getPackageVersion(package.getTopKey())
package.topPv = topPv
topPv.packageTop = package
for patchfile in package.patches:
self.recordPatchfile(patchfile)
@ -757,7 +757,7 @@ class PatchMaker:
# What's the current version on the top of the tree?
topPv = package.topPv
currentPv = package.currentPv
if topPv != currentPv:
# They're different, so build a new patch.
filename = Filename(package.currentFile.filename + '.%s.patch' % (package.patchVersion))
@ -786,7 +786,7 @@ class PatchMaker:
v1.file, v2.file)
package.patches.append(patchfile)
package.anyChanges = True
self.recordPatchfile(patchfile)
return True

View File

@ -1,9 +1,9 @@
from pandac.PandaModules import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument
from panda3d.core import VirtualFileSystem, VirtualFileMountSystem, Filename, TiXmlDocument
vfs = VirtualFileSystem.getGlobalPtr()
class ScanDirectoryNode:
""" This class is used to scan a list of files on disk. """
def __init__(self, pathname, ignoreUsageXml = False):
self.pathname = pathname
self.filenames = []
@ -38,7 +38,7 @@ class ScanDirectoryNode:
if not isinstance(vfile.getMount(), VirtualFileMountSystem):
# Not a real file; ignore it.
continue
if vfile.isDirectory():
# A nested directory.
subdir = ScanDirectoryNode(vfile.getFilename(), ignoreUsageXml = ignoreUsageXml)
@ -49,7 +49,7 @@ class ScanDirectoryNode:
# A nested file.
self.filenames.append(vfile.getFilename())
self.fileSize += vfile.getFileSize()
else:
# Some other wacky file thing.
self.filenames.append(vfile.getFilename())
@ -78,7 +78,7 @@ class ScanDirectoryNode:
self.nested.remove(subdir)
self.nestedSize -= subdir.getTotalSize()
return subdir
result = subdir.extractSubdir(pathname)
if result:
self.nestedSize -= result.getTotalSize()
@ -89,5 +89,5 @@ class ScanDirectoryNode:
return result
return None

View File

@ -1,4 +1,4 @@
from pandac.PandaModules import getModelPath, Filename, ConfigVariableFilename, DSearchPath, ExecutionEnvironment, PandaSystem
from panda3d.core import getModelPath, Filename, ConfigVariableFilename, DSearchPath, ExecutionEnvironment, PandaSystem
# This file defines a number of standard "packages" that correspond to
# a Panda3D distribution. These packages are built by passing this
@ -57,7 +57,7 @@ class images(package):
basename = '%s.jpg' % (name)
filename = Filename(basename)
found = filename.resolveFilename(search)
if found:
# Add the image file to the package
file(filename, newName = basename, extract = True)
@ -91,7 +91,7 @@ class certlist(package):
# ".pem" or ".crt" extension, and they should be added with the
# extract = True flag so they will be extracted to disk.
pass
class p3dcert(package):
# This special application, used to pop up a dialog to prompt the
@ -102,7 +102,7 @@ class p3dcert(package):
# On Mac, we package up a P3DCert.app bundle. This includes
# specifications in the plist file to avoid creating a dock
# icon and stuff.
# Find p3dcert.plist in the direct source tree.
import direct
plist = Filename(direct.__path__[0], 'plugin/p3dcert.plist')

View File

@ -93,8 +93,8 @@ import os
import getopt
import glob
import direct
from direct.p3d import Packager
from pandac.PandaModules import *
from direct.p3d import Packager
from panda3d.core import *
# Temp hack for debugging.
#from direct.p3d.AppRunner import dummyAppRunner; dummyAppRunner()
@ -113,7 +113,7 @@ def makePackedApp(args):
configFlags = []
requires = []
allowPythonDev = False
for option, value in opts:
if option == '-o':
appFilename = Filename.fromOsSpecific(value)
@ -183,11 +183,7 @@ def makePackedApp(args):
main = os.path.split(main[0])[1]
main = Filename.fromOsSpecific(main)
mainModule = Filename(main)
mainModule.setExtension('')
mainModule = mainModule.cStr().replace('/', '.')
packager.installDir = appDir
packager.allowPythonDev = allowPythonDev
@ -206,7 +202,7 @@ def makePackedApp(args):
# panda3d.
if 'panda3d' not in [t[0] for t in requires]:
packager.do_require('panda3d')
for name, version, host in requires:
packager.do_require(name, version = version, host = host)
@ -214,10 +210,10 @@ def makePackedApp(args):
packager.do_config(**dict(configFlags))
packager.do_dir(root)
packager.do_mainModule(mainModule)
packager.do_main(main)
packager.endPackage()
packager.close()
except Packager.PackagerError:
# Just print the error message and exit gracefully.
inst = sys.exc_info()[1]

View File

@ -1,4 +1,4 @@
from pandac.PandaModules import Filename, PandaSystem, getModelPath
from panda3d.core import Filename, PandaSystem, getModelPath
# This file defines a number of standard "packages" that correspond to
# a Panda3D distribution. These packages are built by passing this
@ -54,7 +54,11 @@ class panda3d(package):
'direct.showutil.*',
'direct.stdpy.*',
'direct.task.*')
module('panda3d')
module('panda3d.core',
'panda3d.direct',
'panda3d.fx',
'panda3d.physics')
# Include various standard Python encodings. The rest is in morepy.
module('encodings', 'encodings.aliases', 'encodings.undefined,'
@ -65,9 +69,19 @@ class panda3d(package):
import direct
file(Filename(direct.__path__[0], 'filter/*.sha'), newDir = 'direct/filter')
# pandac.PandaModules pulls in other Panda3D libs automatically.
# Exclude these Panda3D libs; they are big and many applications don't
# use them. We define them as separate, optional packages, below,
# except for skel - this is useless in a shipped game anyways.
excludeModule('panda3d.egg')
excludeModule('panda3d.ode')
excludeModule('panda3d.bullet')
excludeModule('panda3d.vision')
excludeModule('panda3d.skel')
excludeModule('panda3d.physx')
excludeModule('panda3d.ai')
excludeModule('panda3d.vrpn')
excludeModule('libpandaegg')
excludeModule('libpandaode')
excludeModule('libpandabullet')
@ -89,6 +103,8 @@ class panda3d(package):
excludeModule('MySQLdb', '_mysql')
excludeModule('xml', 'xml.parsers.expat', 'xml.sax')
# Most of the core Panda3D DLL's will be included implicitly due to
# being referenced by the above Python code. Here we name a few more
# that are also needed, but aren't referenced by any code. Again,
@ -269,6 +285,7 @@ class egg(package):
config(display_name = "Panda3D egg loader")
require('panda3d')
module('panda3d.egg', required = True)
file('libpandaegg.dll', required = True)
file('libp3ptloader.dll', required = True)
@ -286,6 +303,7 @@ class ode(package):
config(display_name = "Panda3D Open Dynamics Engine integration")
require('panda3d')
module('panda3d.ode', required = True)
file('libpandaode.dll', required = True)
class bullet(package):
@ -296,6 +314,7 @@ class bullet(package):
config(display_name = "Panda3D Bullet integration")
require('panda3d')
module('panda3d.bullet', required = True)
file('libpandabullet.dll', required = True)
class physx(package):
@ -306,6 +325,7 @@ class physx(package):
config(display_name = "Panda3D PhysX integration")
require('panda3d')
module('panda3d.physx', required = True)
file('libpandaphysx.dll', required = True)
file('physxcudart_20.dll')
file('PhysXDevice.dll')
@ -319,6 +339,7 @@ class ai(package):
config(display_name = "Panda3D AI modules")
require('panda3d')
module('panda3d.ai', required = True)
file('libpandaai.dll', required = True)
class vision(package):
@ -330,6 +351,7 @@ class vision(package):
config(display_name = "Panda3D vision modules")
require('panda3d')
module('panda3d.vision', required = True)
file('libp3vision.dll', required = True)
class rocket(package):
@ -340,6 +362,7 @@ class rocket(package):
config(display_name = "Panda3D libRocket support")
require('panda3d')
module('panda3d.rocket', required = True)
module('_rocketcore', '_rocketcontrols')
file('libp3rocket.dll', required = True)
@ -350,6 +373,7 @@ class vrpn(package):
config(display_name = "Panda3D VRPN support")
require('panda3d')
module('panda3d.vrpn')
file('libp3vrpn.dll', required = True)

View File

@ -102,7 +102,7 @@ Options:
is licensed under.
Only relevant when generating a graphical installer.
-O
-O
Specify this option when generating a graphical installer to omit
the default checkboxes for "run this program" and "install a
desktop shortcut" on completion.
@ -147,7 +147,7 @@ import sys
import os
import getopt
from direct.p3d.DeploymentTools import Standalone, Installer, Icon
from pandac.PandaModules import Filename, PandaSystem
from panda3d.core import Filename, PandaSystem
def usage(code, msg = ''):
if not msg:

View File

@ -47,7 +47,7 @@ import getopt
import os
from direct.p3d import PackageMerger
from pandac.PandaModules import *
from panda3d.core import *
def usage(code, msg = ''):
print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]}
@ -66,7 +66,7 @@ for opt, arg in opts:
installDir = Filename.fromOsSpecific(arg)
elif opt == '-p':
packageNames += arg.split(',')
elif opt == '-h':
usage(0)
else:
@ -92,7 +92,7 @@ try:
for dir in inputDirs:
pm.merge(dir, packageNames = packageNames)
pm.close()
except PackageMerger.PackageMergerError:
# Just print the error message and exit gracefully.
inst = sys.exc_info()[1]

View File

@ -132,7 +132,7 @@ import getopt
import os
from direct.p3d import Packager
from pandac.PandaModules import *
from panda3d.core import *
def usage(code, msg = ''):
print >> sys.stderr, usageText % {

View File

@ -60,7 +60,7 @@ import getopt
import os
from direct.p3d.PatchMaker import PatchMaker
from pandac.PandaModules import *
from panda3d.core import *
def usage(code, msg = ''):
print >> sys.stderr, usageText % {'prog' : os.path.split(sys.argv[0])[1]}
@ -76,7 +76,7 @@ installDir = None
for opt, arg in opts:
if opt == '-i':
installDir = Filename.fromOsSpecific(arg)
elif opt == '-h':
usage(0)
else:

View File

@ -28,7 +28,7 @@ import sys
import getopt
from AppRunner import AppRunner, ArgumentError
from direct.task.TaskManagerGlobal import taskMgr
from pandac.PandaModules import Filename
from panda3d.core import Filename
def parseSysArgs():
""" Handles sys.argv, if there are any local arguments, and

View File

@ -13,7 +13,7 @@
# Also see panda3d.pdef.
from pandac.PandaModules import Filename
from panda3d.core import Filename
import sys
class wx(package):
@ -95,7 +95,7 @@ class twisted(package):
'twisted.runner', 'twisted.scripts', 'twisted.spread',
'twisted.tap', 'twisted.trial', 'twisted.vfs',
'twisted.web', 'twisted.web2', 'twisted.words')
module('twisted.*', 'twisted.*.*')
class pil(package):

View File

@ -34,11 +34,11 @@ TypeHandle P3DPythonRun::P3DWindowHandle::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: P3DPythonRun::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
P3DPythonRun::
P3DPythonRun(const char *program_name, const char *archive_file,
FHandle input_handle, FHandle output_handle,
FHandle input_handle, FHandle output_handle,
const char *log_pathname, bool interactive_console) {
P3DWindowHandle::init_type();
init_xml();
@ -115,7 +115,7 @@ P3DPythonRun(const char *program_name, const char *archive_file,
////////////////////////////////////////////////////////////////////
// Function: P3DPythonRun::Destructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
P3DPythonRun::
~P3DPythonRun() {
@ -150,72 +150,32 @@ run_python() {
PyRun_SimpleString("import sys; sys.dll_suffix = '_d'");
#endif
// We'll need libpandaexpress to be imported before we can load
// _vfsimporter. So, find it and load it.
Filename libpandaexpress;
Filename dir = _archive_file.get_dirname();
#ifdef _WIN32
// Of course it's already resident, so use that version.
wstring basename = Filename::dso_filename("libpandaexpress.so").to_os_specific_w();
HMODULE h = GetModuleHandleW(basename.c_str());
if (h == NULL) {
nout << "Can't find libpandaexpress in memory.\n";
} else {
static const int buffer_size = 4096;
wchar_t buffer[buffer_size];
GetModuleFileNameW(h, buffer, buffer_size);
libpandaexpress = Filename::from_os_specific_w(buffer);
}
#endif // _WIN32
if (libpandaexpress.empty()) {
// Go look for it on disk.
libpandaexpress = Filename(_archive_file.get_dirname(),
Filename::dso_filename("libpandaexpress.so"));
#if defined(__APPLE__) && PY_VERSION_HEX < 0x02050000
// On OSX, for Python versions 2.4 and before, we have to load the
// .so file, not the .dylib file.
libpandaexpress.set_type(Filename::T_general);
#endif
}
if (!libpandaexpress.exists()) {
nout << "Can't find " << libpandaexpress << "\n";
return false;
}
// We need the "imp" built-in module for that.
PyObject *imp_module = PyImport_ImportModule("imp");
if (imp_module == NULL) {
nout << "Failed to import module imp\n";
// We'll need to synthesize a 'panda3d' module before loading
// VFSImporter. We could simply freeze it, but Python has a bug
// setting __path__ of frozen modules properly.
PyObject *panda3d_module = PyImport_AddModule("panda3d");
if (panda3d_module == NULL) {
nout << "Failed to create panda3d module:\n";
PyErr_Print();
return false;
}
// And here's where we run into a brick wall attempting to make the
// whole plugin system Unicode-safe for Windows. It turns out that
// this Python call, imp.load_dynamic(), will not accept a Unicode
// pathname. So if the DLL in question is in a location that
// contains non-ASCII characters, it can't be loaded.
string os_specific = libpandaexpress.to_os_specific();
PyObject *result = PyObject_CallMethod
(imp_module, (char *)"load_dynamic", (char *)"ss",
"libpandaexpress", os_specific.c_str());
if (result == NULL) {
nout << "Failed to import libpandaexpress as a module\n";
PyErr_Print();
return false;
}
Py_DECREF(result);
Py_DECREF(imp_module);
// Set the __path__ such that it can find panda3d/core.pyd, etc.
Filename panda3d_dir(dir, "panda3d");
string dir_str = panda3d_dir.to_os_specific();
PyObject *panda3d_dict = PyModule_GetDict(panda3d_module);
PyObject *panda3d_path = Py_BuildValue("[s#]", dir_str.data(), dir_str.length());
PyDict_SetItemString(panda3d_dict, "__path__", panda3d_path);
Py_DECREF(panda3d_path);
// Now we can load _vfsimporter.pyd. Since this is a magic frozen
// pyd, importing it automatically makes all of its frozen contents
// available to import as well.
PyObject *vfsimporter = PyImport_ImportModule("_vfsimporter");
if (vfsimporter == NULL) {
nout << "Failed to import _vfsimporter\n";
nout << "Failed to import _vfsimporter:\n";
PyErr_Print();
return false;
}
@ -224,15 +184,15 @@ run_python() {
// And now we can import the VFSImporter module that was so defined.
PyObject *vfsimporter_module = PyImport_ImportModule("VFSImporter");
if (vfsimporter_module == NULL) {
nout << "Failed to import VFSImporter\n";
nout << "Failed to import VFSImporter:\n";
PyErr_Print();
return false;
}
// And register the VFSImporter.
result = PyObject_CallMethod(vfsimporter_module, (char *)"register", (char *)"");
PyObject *result = PyObject_CallMethod(vfsimporter_module, (char *)"register", (char *)"");
if (result == NULL) {
nout << "Failed to call VFSImporter.register()\n";
nout << "Failed to call VFSImporter.register():\n";
PyErr_Print();
return false;
}
@ -248,7 +208,6 @@ run_python() {
nout << "Could not read " << _archive_file << "\n";
return false;
}
Filename dir = _archive_file.get_dirname();
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->mount(mf, dir, VirtualFileSystem::MF_read_only)) {
nout << "Could not mount " << _archive_file << "\n";
@ -346,7 +305,7 @@ run_python() {
}
Py_DECREF(result);
Py_DECREF(request_func);
// Now add check_comm() as a task. It can be a threaded task, but
// this does mean that application programmers will have to be alert
@ -545,7 +504,7 @@ handle_command(TiXmlDocument *doc) {
assert(!needs_response);
int instance_id;
TiXmlElement *xwparams = xcommand->FirstChildElement("wparams");
if (xwparams != (TiXmlElement *)NULL &&
if (xwparams != (TiXmlElement *)NULL &&
xcommand->QueryIntAttribute("instance_id", &instance_id) == TIXML_SUCCESS) {
setup_window(instance_id, xwparams);
}
@ -591,7 +550,7 @@ handle_command(TiXmlDocument *doc) {
_sent_objects.erase(si);
}
}
} else {
nout << "Unhandled command " << cmd << "\n";
if (needs_response) {
@ -678,7 +637,7 @@ handle_pyobj_command(TiXmlElement *xcommand, bool needs_response,
if (method_name == NULL) {
// No method name; call the object directly.
result = PyObject_CallObject(obj, params);
// Several special-case "method" names.
} else if (strcmp(method_name, "__bool__") == 0) {
result = PyBool_FromLong(PyObject_IsTrue(obj));
@ -713,7 +672,7 @@ handle_pyobj_command(TiXmlElement *xcommand, bool needs_response,
PyErr_Clear();
}
}
// If the object supports the mapping protocol, store it
// in the object's dictionary.
if (!success && PyMapping_Check(obj)) {
@ -761,7 +720,7 @@ handle_pyobj_command(TiXmlElement *xcommand, bool needs_response,
PyErr_Clear();
}
}
if (success) {
result = Py_True;
} else {
@ -1066,8 +1025,8 @@ py_request_func(PyObject *args) {
PyObject *value;
int needs_response;
int unique_id;
if (!PyArg_ParseTuple(extra_args, "sOsOii",
&operation, &object, &property_name, &value,
if (!PyArg_ParseTuple(extra_args, "sOsOii",
&operation, &object, &property_name, &value,
&needs_response, &unique_id)) {
return NULL;
}
@ -1256,7 +1215,7 @@ set_instance_info(P3DCInstance *inst, TiXmlElement *xinstance) {
xinstance->Attribute("respect_per_platform", &respect_per_platform);
PyObject *result = PyObject_CallMethod
(_runner, (char *)"setInstanceInfo", (char *)"sssiOi", root_dir,
(_runner, (char *)"setInstanceInfo", (char *)"sssiOi", root_dir,
log_directory, super_mirror, verify_contents, main, respect_per_platform);
Py_DECREF(main);
@ -1347,7 +1306,7 @@ set_p3d_filename(P3DCInstance *inst, TiXmlElement *xfparams) {
value = value_c;
}
PyObject *tuple = Py_BuildValue("(ss)", keyword.c_str(),
PyObject *tuple = Py_BuildValue("(ss)", keyword.c_str(),
value.c_str());
PyList_Append(token_list, tuple);
Py_DECREF(tuple);
@ -1419,7 +1378,7 @@ setup_window(P3DCInstance *inst, TiXmlElement *xwparams) {
}
int win_x, win_y, win_width, win_height;
xwparams->Attribute("win_x", &win_x);
xwparams->Attribute("win_y", &win_y);
xwparams->Attribute("win_width", &win_width);
@ -1531,7 +1490,7 @@ terminate_session() {
Py_DECREF(result);
}
}
_session_terminated = true;
}
}
@ -1772,7 +1731,7 @@ xml_to_pyobj(TiXmlElement *xvalue) {
int object_id;
if (xvalue->QueryIntAttribute("object_id", &object_id) == TIXML_SUCCESS) {
// Construct a new BrowserObject wrapper around this object.
return PyObject_CallFunction(_browser_object_class, (char *)"Oi",
return PyObject_CallFunction(_browser_object_class, (char *)"Oi",
_runner, object_id);
}
@ -1852,7 +1811,7 @@ rt_thread_run() {
}
// Successfully read an XML document.
// Check for one special case: the "exit" command means we shut
// down the read thread along with everything else.
TiXmlElement *xcommand = doc->FirstChildElement("command");
@ -1875,7 +1834,7 @@ rt_thread_run() {
////////////////////////////////////////////////////////////////////
// Function: P3DPythonRun::P3DWindowHandle::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
P3DPythonRun::P3DWindowHandle::
P3DWindowHandle(P3DPythonRun *p3dpython, P3DCInstance *inst,

View File

@ -28,10 +28,10 @@
////////////////////////////////////////////////////////////////////
// Function: P3DX11SplashWindow::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
P3DX11SplashWindow::
P3DX11SplashWindow(P3DInstance *inst, bool make_visible) :
P3DX11SplashWindow(P3DInstance *inst, bool make_visible) :
P3DSplashWindow(inst, make_visible)
{
// Init for parent process
@ -61,7 +61,7 @@ P3DX11SplashWindow(P3DInstance *inst, bool make_visible) :
////////////////////////////////////////////////////////////////////
// Function: P3DX11SplashWindow::Destructor
// Access: Public, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
P3DX11SplashWindow::
~P3DX11SplashWindow() {
@ -312,13 +312,13 @@ stop_subprocess() {
_pipe_write.close();
static const int max_wait_ms = 2000;
// Wait for a certain amount of time for the process to stop by
// itself.
struct timeval start;
gettimeofday(&start, NULL);
int start_ms = start.tv_sec * 1000 + start.tv_usec / 1000;
int status;
pid_t result = waitpid(_subprocess_pid, &status, WNOHANG);
while (result != _subprocess_pid) {
@ -326,20 +326,20 @@ stop_subprocess() {
perror("waitpid");
break;
}
struct timeval now;
gettimeofday(&now, NULL);
int now_ms = now.tv_sec * 1000 + now.tv_usec / 1000;
int elapsed = now_ms - start_ms;
if (elapsed > max_wait_ms) {
// Tired of waiting. Kill the process.
nout << "Force-killing splash window process, pid " << _subprocess_pid
nout << "Force-killing splash window process, pid " << _subprocess_pid
<< "\n";
kill(_subprocess_pid, SIGKILL);
start_ms = now_ms;
}
// Yield the timeslice and wait some more.
struct timeval tv;
tv.tv_sec = 0;
@ -353,7 +353,7 @@ stop_subprocess() {
nout << " exited normally, status = "
<< WEXITSTATUS(status) << "\n";
} else if (WIFSIGNALED(status)) {
nout << " signalled by " << WTERMSIG(status) << ", core = "
nout << " signalled by " << WTERMSIG(status) << ", core = "
<< WCOREDUMP(status) << "\n";
} else if (WIFSTOPPED(status)) {
nout << " stopped by " << WSTOPSIG(status) << "\n";
@ -396,7 +396,7 @@ check_stopped() {
nout << " exited normally, status = "
<< WEXITSTATUS(status) << "\n";
} else if (WIFSIGNALED(status)) {
nout << " signalled by " << WTERMSIG(status) << ", core = "
nout << " signalled by " << WTERMSIG(status) << ", core = "
<< WCOREDUMP(status) << "\n";
} else if (WIFSTOPPED(status)) {
nout << " stopped by " << WSTOPSIG(status) << "\n";
@ -522,14 +522,14 @@ subprocess_run() {
_win_height = event.xconfigure.height;
set_button_range(_button_ready_image);
// If the window changes size, we need to recompute the
// composed image.
_needs_new_composite = true;
}
needs_redraw = true;
break;
case MotionNotify:
set_mouse_data(event.xmotion.x, event.xmotion.y, _mouse_down);
break;
@ -537,7 +537,7 @@ subprocess_run() {
case ButtonPress:
set_mouse_data(_mouse_x, _mouse_y, true);
break;
case ButtonRelease:
set_mouse_data(_mouse_x, _mouse_y, false);
break;
@ -563,7 +563,7 @@ subprocess_run() {
needs_redraw = true;
prev_label = _install_label;
}
if (_progress_known != prev_progress_known) {
needs_update_progress = true;
needs_redraw_progress = true;
@ -592,7 +592,7 @@ subprocess_run() {
needs_redraw = true;
}
}
if (needs_redraw) {
redraw();
XFlush(_display);
@ -619,23 +619,23 @@ subprocess_run() {
text_width + 4, text_height + 4, false);
XDrawString(_display, _window, _graphics_context, text_x, text_y,
_install_label.c_str(), _install_label.size());
needs_draw_label = false;
}
if (needs_redraw_progress) {
XClearArea(_display, _window,
XClearArea(_display, _window,
bar_x, bar_y, bar_width, bar_height, false);
XDrawRectangle(_display, _window, _graphics_context,
XDrawRectangle(_display, _window, _graphics_context,
bar_x, bar_y, bar_width, bar_height);
needs_update_progress = true;
needs_redraw_progress = false;
}
if (needs_update_progress) {
if (_progress_known) {
int progress_width = (int)((bar_width - 2) * _install_progress + 0.5);
XFillRectangle(_display, _window, _bar_context,
XFillRectangle(_display, _window, _bar_context,
bar_x + 1, bar_y + 1,
progress_width + 1, bar_height - 1);
} else {
@ -649,7 +649,7 @@ subprocess_run() {
progress = block_travel * 2 - progress;
}
XFillRectangle(_display, _window, _bar_context,
XFillRectangle(_display, _window, _bar_context,
bar_x + 1 + progress, bar_y + 1,
block_width + 1, bar_height - 1);
}
@ -665,7 +665,7 @@ subprocess_run() {
fd_set fds;
FD_ZERO(&fds);
FD_SET(read_fd, &fds);
// Sleep a bit to yield the timeslice if there's nothing new.
struct timeval tv;
tv.tv_sec = 0;
@ -729,27 +729,30 @@ receive_command() {
} else if (strcmp(cmd, "set_image_filename") == 0) {
const string *image_filename = xcommand->Attribute(string("image_filename"));
int image_placement;
if (image_filename != NULL &&
if (image_filename != NULL &&
xcommand->QueryIntAttribute("image_placement", &image_placement) == TIXML_SUCCESS) {
X11ImageData *image = NULL;
switch ((ImagePlacement)image_placement) {
case IP_background:
image = &_background_image;
break;
case IP_button_ready:
image = &_button_ready_image;
set_button_range(_button_ready_image);
break;
case IP_button_rollover:
image = &_button_rollover_image;
break;
case IP_button_click:
image = &_button_click_image;
break;
case IP_none:
break;
}
if (image != NULL) {
if (image->_filename != *image_filename) {
@ -804,7 +807,7 @@ redraw() {
// If we have an image, draw it.
int xo = (_win_width - _composite_width) / 2;
int yo = (_win_height - _composite_height) / 2;
XPutImage(_display, _window, _graphics_context, _composite_image, 0, 0,
XPutImage(_display, _window, _graphics_context, _composite_image, 0, 0,
xo, yo, _composite_width, _composite_height);
// Then clear the rectangles around it carefully (rather than just
@ -840,12 +843,12 @@ make_window() {
}
X11_Window parent = 0;
// Hum, if we use the display provided by the browser,
// it causes a crash in some browsers when you make an Xlib
// call with the plugin window minimized.
// So I kept XOpenDisplay until we have a better workaround.
//_display = (X11_Display*) _wparams.get_parent_window()._xdisplay;
//_own_display = false;
//if (_display == 0) {
@ -871,7 +874,7 @@ make_window() {
// Create a toplevel window.
parent = XRootWindow(_display, _screen);
}
assert(parent != None);
int depth = DefaultDepth(_display, _screen);
@ -955,7 +958,7 @@ setup_gc() {
XFontStruct* fs = XLoadQueryFont(_display, "6x13");
XGCValues gcval;
gcval.font = fs->fid;
gcval.font = fs->fid;
gcval.function = GXcopy;
gcval.plane_mask = AllPlanes;
gcval.foreground = BlackPixel(_display, _screen);
@ -966,8 +969,8 @@ setup_gc() {
if (_bg_pixel != -1) {
gcval.background = _bg_pixel;
}
_graphics_context = XCreateGC(_display, _window,
GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval);
_graphics_context = XCreateGC(_display, _window,
GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval);
// Also create a gc for filling in the interior of the progress bar
// in a pleasant blue color (or whatever color the user requested).
@ -983,7 +986,7 @@ setup_gc() {
gcval.foreground = bar.pixel;
}
_bar_context = XCreateGC(_display, _window,
_bar_context = XCreateGC(_display, _window,
GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground, &gcval);
}
@ -998,7 +1001,7 @@ close_window() {
XDestroyImage(_composite_image);
_composite_image = NULL;
}
if (_bar_context != None) {
if (_bar_context != _graphics_context) {
XFreeGC(_display, _bar_context);
@ -1009,22 +1012,22 @@ close_window() {
Colormap colormap = DefaultColormap(_display, _screen);
XFreeColors(_display, colormap, &_bar_pixel, 1, 0);
}
if (_fg_pixel != -1) {
Colormap colormap = DefaultColormap(_display, _screen);
XFreeColors(_display, colormap, &_fg_pixel, 1, 0);
}
if (_bg_pixel != -1) {
Colormap colormap = DefaultColormap(_display, _screen);
XFreeColors(_display, colormap, &_bg_pixel, 1, 0);
}
if (_graphics_context != None) {
XFreeGC(_display, _graphics_context);
_graphics_context = None;
}
if (_window != None) {
XDestroyWindow(_display, _window);
_window = None;
@ -1150,7 +1153,7 @@ compose_image() {
}
// Now load the image.
_composite_image = XCreateImage(_display, CopyFromParent, DefaultDepth(_display, _screen),
_composite_image = XCreateImage(_display, CopyFromParent, DefaultDepth(_display, _screen),
ZPixmap, 0, (char *)new_data, image1_width, image1_height, 32, 0);
_composite_width = image1_width;
_composite_height = image1_height;

View File

@ -2,7 +2,7 @@
__all__ = ['BufferViewer']
from pandac.PandaModules import *
from panda3d.core import *
from direct.task import Task
from direct.directnotify.DirectNotifyGlobal import *
from direct.showbase.DirectObject import DirectObject

View File

@ -5,7 +5,6 @@ __all__ = ['DirectObject']
from direct.directnotify.DirectNotifyGlobal import directNotify
from MessengerGlobal import messenger
from direct.showbase.PythonUtil import ClassTree
class DirectObject:
"""
@ -42,9 +41,6 @@ class DirectObject:
def isIgnoring(self, event):
return messenger.isIgnoring(event, self)
def classTree(self):
return ClassTree(self)
#This function must be used if you want a managed task
def addTask(self, *args, **kwargs):
if(not hasattr(self,"_taskList")):

View File

@ -5,11 +5,8 @@ __all__ = ['EventManager']
from MessengerGlobal import *
from direct.directnotify.DirectNotifyGlobal import *
# This module may not import pandac.PandaModules, since it is imported
# by the Toontown Launcher before the complete PandaModules have been
# downloaded.
#from pandac.PandaModules import *
from panda3d.core import PStatCollector, EventQueue, EventHandler
from panda3d.core import EventStorePandaNode
class EventManager:
@ -43,7 +40,6 @@ class EventManager:
"""
if self._wantPstats is None:
self._wantPstats = config.GetBool('pstats-eventmanager', 0)
from pandac.PandaModules import PStatCollector
EventManager.PStatCollector = PStatCollector
# use different methods for handling events with and without pstats tracking
# for efficiency
@ -83,10 +79,7 @@ class EventManager:
# which will be downcast to that type
ptr = eventParameter.getPtr()
if EventManager.EventStorePandaNode is None:
from pandac.PandaModules import EventStorePandaNode
EventManager.EventStorePandaNode = EventStorePandaNode
if isinstance(ptr, EventManager.EventStorePandaNode):
if isinstance(ptr, EventStorePandaNode):
# Actually, it's a kludgey wrapper around a PandaNode
# pointer. Return the node.
ptr = ptr.getValue()
@ -190,22 +183,17 @@ class EventManager:
def restart(self):
if None in (EventManager.EventQueue, EventManager.EventHandler):
from pandac.PandaModules import EventQueue, EventHandler
EventManager.EventQueue = EventQueue
EventManager.EventHandler = EventHandler
if self.eventQueue == None:
self.eventQueue = EventManager.EventQueue.getGlobalEventQueue()
self.eventQueue = EventQueue.getGlobalEventQueue()
if self.eventHandler == None:
if self.eventQueue == EventManager.EventQueue.getGlobalEventQueue():
if self.eventQueue == EventQueue.getGlobalEventQueue():
# If we are using the global event queue, then we also
# want to use the global event handler.
self.eventHandler = EventManager.EventHandler.getGlobalEventHandler()
self.eventHandler = EventHandler.getGlobalEventHandler()
else:
# Otherwise, we need our own event handler.
self.eventHandler = EventManager.EventHandler(self.eventQueue)
self.eventHandler = EventHandler(self.eventQueue)
# Should be safe to import the global taskMgr by now.
from direct.task.TaskManagerGlobal import taskMgr

View File

@ -1,4 +1,4 @@
from pandac.PandaModules import getConfigShowbase
from panda3d.direct import get_config_showbase
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.showbase.PythonUtil import fastRepr
import sys
@ -6,7 +6,7 @@ import types
import traceback
notify = directNotify.newCategory("ExceptionVarDump")
config = getConfigShowbase()
config = get_config_showbase()
reentry = 0
@ -154,7 +154,7 @@ def _excepthookDumpVars(eType, eValue, tb):
for attrName in attrNames:
obj = attrName2obj[attrName]
stateStack.push(['%s.%s' % (name, attrName), obj, ids])
tb = tb.tb_next
if foundRun:

View File

@ -1,7 +1,7 @@
from direct.showbase.DirectObject import DirectObject
if __debug__:
from pandac.PandaModules import PStatCollector
from panda3d.core import PStatCollector
class Job(DirectObject):
# Base class for cpu-intensive or non-time-critical operations that

View File

@ -7,78 +7,8 @@ from PythonUtil import *
from direct.directnotify import DirectNotifyGlobal
import types
from panda3d.core import ConfigVariableBool
# If using the Toontown ActiveX launcher, this must be set true.
# Also, Panda must be compiled with SIMPLE_THREADS or no HAVE_THREADS
# at all. In the normal Panda case, this should be set false.
if ConfigVariableBool('delay-messenger-lock', False).getValue():
class Lock:
""" This is a cheesy delayed implementation of Lock, designed to
support the Toontown ActiveX launch, which must import Messenger
before it has downloaded the rest of Panda. Note that this
cheesy lock isn't thread-safe if the application starts any
threads before acquiring the Messenger lock the first time.
(However, it's mostly thread-safe if Panda is compiled with
SIMPLE_THREADS.) """
notify = DirectNotifyGlobal.directNotify.newCategory("Messenger.Lock")
def __init__(self):
self.locked = 0
def acquire(self):
# Before we download Panda, we can't use any threading
# interfaces. So don't, until we observe that we have some
# actual contention on the lock.
if self.locked:
# We have contention.
return self.__getLock()
# This relies on the fact that any individual Python statement
# is atomic.
self.locked += 1
if self.locked > 1:
# Whoops, we have contention.
self.locked -= 1
return self.__getLock()
def release(self):
if self.locked:
# Still using the old, cheesy lock.
self.locked -= 1
return
# The new lock must have been put in place.
self.release = self.lock.release
return self.lock.release()
def __getLock(self):
# Now that we've started Panda, it's safe to import the Mutex
# class, which becomes our actual lock.
# From now on, this lock will be used.
self.notify.info("Acquiring Panda lock for the first time.")
from pandac.PandaModules import Thread, Mutex
self.__dict__.setdefault('lock', Mutex('Messenger'))
self.lock.acquire()
self.acquire = self.lock.acquire
# Wait for the cheesy lock to be released before we return.
self.notify.info("Waiting for cheesy lock to be released.")
while self.locked:
Thread.forceYield()
self.notify.info("Got cheesy lock.")
# We return with the lock acquired.
else:
# In the normal case, there's no reason not to import all of
# libpanda right away, and so we can just use Lock directly. This
# is perfectly thread-safe.
from direct.stdpy.threading import Lock
from panda3d.core import ConfigVariableBool, Thread, Mutex
from direct.stdpy.threading import Lock
class Messenger:
@ -215,7 +145,7 @@ class Messenger:
# on this particular object.
if id in acceptorDict:
# TODO: we're replacing the existing callback. should this be an error?
if notifyDebug:
if notifyDebug:
oldMethod = acceptorDict[id][0]
if oldMethod == method:
self.notify.warning(
@ -420,7 +350,7 @@ class Messenger:
if not eventTuple:
# No event; we're done.
return task.done
self.__dispatch(*eventTuple)
finally:
self.lock.release()
@ -450,7 +380,7 @@ class Messenger:
if (len(eventDict) == 0):
del self.__objectEvents[id]
self._releaseObject(self._getObject(id))
del acceptorDict[id]
# If the dictionary at this event is now empty, remove
# the event entry from the Messenger altogether

View File

@ -1,12 +0,0 @@
"""Undocumented Module"""
__all__ = []
## from DirectObject import *
## from pandac.PandaModules import *
##
## class PandaObject(DirectObject):
## """
## This is the class that all Panda/Show classes should inherit from
## """
## pass

View File

@ -8,11 +8,11 @@ __all__ = ['ShowBase', 'WindowControls']
#import VerboseImport
from panda3d.core import *
from panda3d.direct import *
from panda3d.direct import get_config_showbase, throw_new_frame
# This needs to be available early for DirectGUI imports
import __builtin__
__builtin__.config = getConfigShowbase()
__builtin__.config = get_config_showbase()
from direct.directnotify.DirectNotifyGlobal import *
from MessengerGlobal import *
@ -46,7 +46,7 @@ import AppRunnerGlobal
__builtin__.FADE_SORT_INDEX = 1000
__builtin__.NO_FADE_SORT_INDEX = 2000
# Now ShowBase is a DirectObject. We need this so ShowBase can hang
# hooks on messages, particularly on window-event. This doesn't
@ -58,7 +58,7 @@ class ShowBase(DirectObject.DirectObject):
def __init__(self, fStartDirect = True, windowType = None):
self.__dev__ = config.GetBool('want-dev', __debug__)
__builtin__.__dev__ = self.__dev__
logStackDump = (config.GetBool('log-stack-dump', False) or
config.GetBool('client-log-stack-dump', False))
uploadStackDump = config.GetBool('upload-stack-dump', False)
@ -74,7 +74,7 @@ class ShowBase(DirectObject.DirectObject):
#debug running multiplier
self.debugRunningMultiplier = 4
# Get the dconfig object
self.config = config
# Setup wantVerifyPdb as soon as reasonable:
@ -91,7 +91,7 @@ class ShowBase(DirectObject.DirectObject):
self.nextWindowIndex = 1
self.__directStarted = False
self.__deadInputs = 0
# Store dconfig variables
self.sfxActive = self.config.GetBool('audio-sfx-active', 1)
self.musicActive = self.config.GetBool('audio-music-active', 1)
@ -253,7 +253,7 @@ class ShowBase(DirectObject.DirectObject):
self.loader = Loader.Loader(self)
self.graphicsEngine.setDefaultLoader(self.loader.loader)
self.eventMgr = eventMgr
self.messenger = messenger
self.bboard = bulletinBoard
@ -315,7 +315,7 @@ class ShowBase(DirectObject.DirectObject):
# Make sure we're not making more than one ShowBase.
if 'base' in __builtin__.__dict__:
raise StandardError, "Attempt to spawn multiple ShowBase instances!"
__builtin__.base = self
__builtin__.render2d = self.render2d
__builtin__.aspect2d = self.aspect2d
@ -357,7 +357,7 @@ class ShowBase(DirectObject.DirectObject):
# set up recording of Functor creation stacks in __dev__
PythonUtil.recordFunctorCreationStacks()
if __dev__ or self.config.GetBool('want-e3-hacks', False):
if self.config.GetBool('track-gui-items', True):
# dict of guiId to gui item, for tracking down leaks
@ -386,7 +386,7 @@ class ShowBase(DirectObject.DirectObject):
sleepTime = self.config.GetFloat('client-sleep', 0.0)
self.clientSleep = 0.0
self.setSleep(sleepTime)
# Extra sleep for running 4+ clients on a single machine
# adds a sleep right after the main render in igloop
# tends to even out the frame rate and keeps it from going
@ -414,7 +414,7 @@ class ShowBase(DirectObject.DirectObject):
# Start IGLOOP
self.restart()
# add a collision traverser via pushCTrav and remove it via popCTrav
# that way the owner of the new cTrav doesn't need to hold onto the
# previous one in order to put it back
@ -427,7 +427,7 @@ class ShowBase(DirectObject.DirectObject):
def __setupProfile(self):
""" Sets up the Python profiler, if avaialable, according to
some Panda config settings. """
try:
import profile, pstats
except ImportError:
@ -499,7 +499,7 @@ class ShowBase(DirectObject.DirectObject):
vfs = VirtualFileSystem.getGlobalPtr()
vfs.unmountAll()
def exitfunc(self):
"""
@ -609,7 +609,7 @@ class ShowBase(DirectObject.DirectObject):
If requireWindow is true, it means that the function should
raise an exception if the window fails to open correctly.
"""
# Save this lambda here for convenience; we'll use it to call
@ -622,19 +622,19 @@ class ShowBase(DirectObject.DirectObject):
keepCamera = keepCamera, scene = scene, stereo = stereo,
unexposedDraw = unexposedDraw,
callbackWindowDict = callbackWindowDict)
if self.win:
# If we've already opened a window before, this is just a
# pass-through to _doOpenWindow().
win = func()
self.graphicsEngine.openWindows()
return win
if type is None:
type = self.windowType
if requireWindow is None:
requireWindow = self.requireWindow
win = func()
# Give the window a chance to truly open.
@ -699,7 +699,7 @@ class ShowBase(DirectObject.DirectObject):
# GSG from that buffer.
host = gsg
gsg = gsg.getGsg()
# If we are using DirectX, force a new GSG to be created,
# since at the moment DirectX seems to misbehave if we do
# not do this. This will cause a delay while all textures
@ -764,7 +764,7 @@ class ShowBase(DirectObject.DirectObject):
func = callbackWindowDict.get(callbackName, None)
if not func:
continue
setCallbackName = 'set%sCallback' % (callbackName)
setCallback = getattr(win, setCallbackName)
setCallback(PythonCallbackObject(func))
@ -804,10 +804,10 @@ class ShowBase(DirectObject.DirectObject):
pointer to None.
"""
win.setActive(False)
# First, remove all of the cameras associated with display
# regions on the window.
numRegions = win.getNumDisplayRegions()
numRegions = win.getNumDisplayRegions()
for i in range(numRegions):
dr = win.getDisplayRegion(i)
# [gjeon] remove drc in base.direct.drList
@ -816,9 +816,9 @@ class ShowBase(DirectObject.DirectObject):
if drc.cam == dr.getCamera():
base.direct.drList.displayRegionList.remove(drc)
break
cam = NodePath(dr.getCamera())
dr.setCamera(NodePath())
if not cam.isEmpty() and \
@ -905,7 +905,7 @@ class ShowBase(DirectObject.DirectObject):
closed window).
"""
keepCamera = kw.get('keepCamera', False)
success = 1
oldWin = self.win
oldLens = self.camLens
@ -1066,7 +1066,7 @@ class ShowBase(DirectObject.DirectObject):
self.aspect2d = self.render2d.attachNewNode(PGTop("aspect2d"))
self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0)
self.a2dBackground = self.aspect2d.attachNewNode("a2dBackground")
self.a2dBackground = self.aspect2d.attachNewNode("a2dBackground")
# It's important to know the bounds of the aspect2d screen.
self.a2dTop = 1.0
@ -1110,7 +1110,7 @@ class ShowBase(DirectObject.DirectObject):
self.a2dBottomLeftNs.setPos(self.a2dLeft, 0, self.a2dBottom)
self.a2dBottomRight.setPos(self.a2dRight, 0, self.a2dBottom)
self.a2dBottomRightNs.setPos(self.a2dRight, 0, self.a2dBottom)
# This special root, pixel2d, uses units in pixels that are relative
# to the window. The upperleft corner of the window is (0, 0),
# the lowerleft corner is (xsize, -ysize), in this coordinate system.
@ -1182,7 +1182,7 @@ class ShowBase(DirectObject.DirectObject):
self.a2dpTopRight.setPos(self.a2dpRight, 0, self.a2dpTop)
self.a2dpBottomLeft.setPos(self.a2dpLeft, 0, self.a2dpBottom)
self.a2dpBottomRight.setPos(self.a2dpRight, 0, self.a2dpBottom)
# This special root, pixel2d, uses units in pixels that are relative
# to the window. The upperleft corner of the window is (0, 0),
# the lowerleft corner is (xsize, -ysize), in this coordinate system.
@ -1229,7 +1229,7 @@ class ShowBase(DirectObject.DirectObject):
if aspectRatio == 0:
return 1
return aspectRatio
def getSize(self, win = None):
@ -1337,7 +1337,7 @@ class ShowBase(DirectObject.DirectObject):
# we will if clearDepth is specified.
if clearDepth:
dr.setClearDepthActive(1)
if clearColor:
dr.setClearColorActive(1)
dr.setClearColor(clearColor)
@ -1370,7 +1370,7 @@ class ShowBase(DirectObject.DirectObject):
cam2dNode = Camera('cam2d_' + cameraName)
else:
cam2dNode = Camera('cam2d')
if lens == None:
lens = OrthographicLens()
lens.setFilmSize(right - left, top - bottom)
@ -1480,12 +1480,12 @@ class ShowBase(DirectObject.DirectObject):
if fMultiWin:
return bts[0]
self.buttonThrowers = bts[:]
self.pointerWatcherNodes = pws[:]
self.mouseWatcher = self.buttonThrowers[0].getParent()
self.mouseWatcherNode = self.mouseWatcher.node()
self.mouseWatcherNode = self.mouseWatcher.node()
if self.mouseInterface:
self.mouseInterface.reparentTo(self.mouseWatcher)
@ -1553,7 +1553,7 @@ class ShowBase(DirectObject.DirectObject):
# track the left and right halves of the screen
# individually.
mw.node().setDisplayRegion(win.getOverlayDisplayRegion())
mb = mw.node().getModifierButtons()
mb.addButton(KeyboardButton.shift())
mb.addButton(KeyboardButton.control())
@ -1675,7 +1675,7 @@ class ShowBase(DirectObject.DirectObject):
port = -1
PStatClient.connect(hostname, port)
return PStatClient.isConnected()
def addSfxManager(self, extraSfxManager):
# keep a list of sfx manager objects to apply settings to,
@ -1841,11 +1841,11 @@ class ShowBase(DirectObject.DirectObject):
case we're responsible for taking out Panda's garbage from
time to time. This is not to be confused with Python's
garbage collection. """
TransformState.garbageCollect()
RenderState.garbageCollect()
return Task.cont
def __igLoop(self, state):
# We render the watch variables for the onScreenDebug as soon
# as we reasonably can before the renderFrame().
@ -1881,7 +1881,7 @@ class ShowBase(DirectObject.DirectObject):
# Lerp stuff needs this event, and it must be generated in
# C++, not in Python.
throwNewFrame()
throw_new_frame()
return Task.cont
@ -1927,8 +1927,8 @@ class ShowBase(DirectObject.DirectObject):
# Lerp stuff needs this event, and it must be generated in
# C++, not in Python.
throwNewFrame()
return Task.cont
throw_new_frame()
return Task.cont
def restart(self,clusterSync=False,cluster=None):
self.shutdown()
@ -2196,7 +2196,7 @@ class ShowBase(DirectObject.DirectObject):
self.showVertices = self.cam.attachNewNode(cam)
dr.setCamera(self.showVertices)
def oobe(self, cam = None):
"""
@ -2221,7 +2221,7 @@ class ShowBase(DirectObject.DirectObject):
"""
if cam is None:
cam = self.cam
# If oobeMode was never set, set it to false and create the
# structures we need to implement OOBE.
if not hasattr(self, 'oobeMode'):
@ -2645,7 +2645,7 @@ class ShowBase(DirectObject.DirectObject):
# If we have not forced the aspect ratio, let's see if it has
# changed and update the camera lenses and aspect2d parameters
self.adjustWindowAspectRatio(self.getAspectRatio())
# Temporary hasattr for old Pandas
if not hasattr(win, 'getSbsLeftXSize'):
self.pixel2d.setScale(2.0 / win.getXSize(), 1.0, 2.0 / win.getYSize())
@ -2659,7 +2659,7 @@ class ShowBase(DirectObject.DirectObject):
windowEvent(), but it may also be called to explicitly adjust
the aspect ratio of the render/render2d DisplayRegion, by a
class that has redefined these. """
if self.__configAspectRatio:
aspectRatio = self.__configAspectRatio
@ -2694,13 +2694,13 @@ class ShowBase(DirectObject.DirectObject):
self.a2dpTop = 1.0
self.a2dpBottom = -1.0
self.a2dpLeft = -aspectRatio
self.a2dpRight = aspectRatio
self.a2dpRight = aspectRatio
# Reposition the aspect2d marker nodes
self.a2dTopCenter.setPos(0, self.a2dTop, self.a2dTop)
self.a2dBottomCenter.setPos(0, self.a2dBottom, self.a2dBottom)
self.a2dLeftCenter.setPos(self.a2dLeft, 0, 0)
self.a2dRightCenter.setPos(self.a2dRight, 0, 0)
self.a2dRightCenter.setPos(self.a2dRight, 0, 0)
self.a2dTopLeft.setPos(self.a2dLeft, self.a2dTop, self.a2dTop)
self.a2dTopRight.setPos(self.a2dRight, self.a2dTop, self.a2dTop)
self.a2dBottomLeft.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom)
@ -2710,17 +2710,17 @@ class ShowBase(DirectObject.DirectObject):
self.a2dTopCenterNs.setPos(0, self.a2dTop, self.a2dTop)
self.a2dBottomCenterNs.setPos(0, self.a2dBottom, self.a2dBottom)
self.a2dLeftCenterNs.setPos(self.a2dLeft, 0, 0)
self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0)
self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0)
self.a2dTopLeftNs.setPos(self.a2dLeft, self.a2dTop, self.a2dTop)
self.a2dTopRightNs.setPos(self.a2dRight, self.a2dTop, self.a2dTop)
self.a2dBottomLeftNs.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom)
self.a2dBottomRightNs.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom)
self.a2dBottomRightNs.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom)
# Reposition the aspect2dp marker nodes
self.a2dpTopCenter.setPos(0, self.a2dpTop, self.a2dpTop)
self.a2dpBottomCenter.setPos(0, self.a2dpBottom, self.a2dpBottom)
self.a2dpLeftCenter.setPos(self.a2dpLeft, 0, 0)
self.a2dpRightCenter.setPos(self.a2dpRight, 0, 0)
self.a2dpRightCenter.setPos(self.a2dpRight, 0, 0)
self.a2dpTopLeft.setPos(self.a2dpLeft, self.a2dpTop, self.a2dpTop)
self.a2dpTopRight.setPos(self.a2dpRight, self.a2dpTop, self.a2dpTop)
self.a2dpBottomLeft.setPos(self.a2dpLeft, self.a2dpBottom, self.a2dpBottom)
@ -2728,7 +2728,7 @@ class ShowBase(DirectObject.DirectObject):
# If anybody needs to update their GUI, put a callback on this event
messenger.send("aspectRatioChanged")
def userExit(self):
# The user has requested we exit the program. Deal with this.
if self.exitFunc:
@ -2752,7 +2752,7 @@ class ShowBase(DirectObject.DirectObject):
This sets up a wxTimer callback so that Panda still gets
updated, but wxPython owns the main loop (which seems to make
it happier than the other way around). """
if self.wxApp:
# Don't do this twice.
return
@ -2767,7 +2767,7 @@ class ShowBase(DirectObject.DirectObject):
# Put wxPython in charge of the main loop. It really
# seems to like this better; some features of wx don't
# work properly unless this is true.
# Set a timer to run the Panda frame 60 times per second.
wxFrameRate = ConfigVariableDouble('wx-frame-rate', 60.0)
self.wxTimer = wx.Timer(self.wxApp)
@ -2802,19 +2802,19 @@ class ShowBase(DirectObject.DirectObject):
# This happens when the wxTimer expires while igLoop is
# rendering. Ignore it.
return
self.taskMgr.step()
def wxRun(self):
""" This method replaces base.run() after we have called
spawnWxLoop(). Since at this point wxPython now owns the main
loop, this method is a call to wxApp.MainLoop(). """
if Thread.getCurrentThread().getCurrentTask():
# This happens in the p3d environment during startup.
# Ignore it.
return
self.wxApp.MainLoop()
def startTk(self, fWantTk = True):
@ -2829,7 +2829,7 @@ class ShowBase(DirectObject.DirectObject):
This sets up a timer callback so that Panda still gets
updated, but Tkinter owns the main loop (which seems to make
it happier than the other way around). """
if self.tkRoot:
# Don't do this twice.
return
@ -2847,7 +2847,7 @@ class ShowBase(DirectObject.DirectObject):
# Put Tkinter in charge of the main loop. It really
# seems to like this better; the GUI otherwise becomes
# largely unresponsive on Mac OS X unless this is true.
# Set a timer to run the Panda frame 60 times per second.
tkFrameRate = ConfigVariableDouble('tk-frame-rate', 60.0)
self.tkDelay = int(1000.0 / tkFrameRate.getValue())
@ -2885,12 +2885,12 @@ class ShowBase(DirectObject.DirectObject):
""" This method replaces base.run() after we have called
spawnTkLoop(). Since at this point Tkinter now owns the main
loop, this method is a call to tkRoot.mainloop(). """
if Thread.getCurrentThread().getCurrentTask():
# This happens in the p3d environment during startup.
# Ignore it.
return
self.tkRoot.mainloop()
def startDirect(self, fWantDirect = 1, fWantTk = 1, fWantWx = 0):
@ -2913,7 +2913,7 @@ class ShowBase(DirectObject.DirectObject):
if self.__directStarted:
return
self.__directStarted = False
# Start Tk, Wx and DIRECT if specified by Config.prc
fTk = self.config.GetBool('want-tk', 0)
fWx = self.config.GetBool('want-wx', 0)

View File

@ -1,14 +1,13 @@
__all__ = ['register', 'sharedPackages',
'reloadSharedPackage', 'reloadSharedPackages']
from panda3d.core import Filename, VirtualFileSystem, VirtualFileMountSystem, OFileStream, copyStream
import sys
import os
import marshal
import imp
import types
import __builtin__
__all__ = ['register', 'sharedPackages',
'reloadSharedPackage', 'reloadSharedPackages']
# The sharedPackages dictionary lists all of the "shared packages",
# special Python packages that automatically span multiple directories
# via magic in the VFSImporter. You can make a package "shared"
@ -76,14 +75,13 @@ class VFSImporter:
for desc in imp.get_suffixes():
if desc[2] != imp.C_EXTENSION:
continue
filename = Filename(path)
filename.setExtension(desc[0][1:])
vfile = vfs.getFile(filename, True)
if vfile:
return VFSLoader(dir_path, vfile, filename, FTExtensionModule,
desc = desc)
# Finally, consider a package, i.e. a directory containing
# __init__.py.
@ -105,7 +103,7 @@ class VFSImporter:
class VFSLoader:
""" The second part of VFSImporter, this is created for a
particular .py file or directory. """
def __init__(self, dir_path, vfile, filename, fileType,
desc = None, packagePath = None):
self.dir_path = dir_path
@ -116,7 +114,7 @@ class VFSLoader:
self.fileType = fileType
self.desc = desc
self.packagePath = packagePath
def load_module(self, fullname, loadingShared = False):
#print >>sys.stderr, "load_module(%s), dir_path = %s, filename = %s" % (fullname, self.dir_path, self.filename)
if self.fileType == FTFrozenModule:
@ -136,11 +134,11 @@ class VFSLoader:
loader = importer.find_module(fullname, path = path)
assert loader
return loader.load_module(fullname)
code = self._read_code()
if not code:
raise ImportError, 'No Python code in %s' % (fullname)
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
mod.__file__ = self.filename.toOsSpecific()
mod.__loader__ = self
@ -169,15 +167,15 @@ class VFSLoader:
def get_filename(self, fullname):
return self.filename.toOsSpecific()
def _read_source(self):
""" Returns the Python source for this file, if it is
available, or None if it is not. May raise IOError. """
if self.fileType == FTPythonCompiled or \
self.fileType == FTExtensionModule:
return None
filename = Filename(self.filename)
filename.setExtension('py')
filename.setText()
@ -281,7 +279,7 @@ class VFSLoader:
def _loadPyc(self, vfile, timestamp):
""" Reads and returns the marshal data from a .pyc file.
Raises ValueError if there is a problem. """
code = None
data = vfile.readFile(True)
if data[:4] == imp.get_magic():
@ -294,13 +292,13 @@ class VFSLoader:
else:
raise ValueError, 'Bad magic number in %s' % (vfile)
return code
def _compile(self, filename, source):
""" Compiles the Python source code to a code object and
attempts to write it to an appropriate .pyc file. May raise
SyntaxError or other errors generated by the compiler. """
if source and source[-1] != '\n':
source = source + '\n'
code = __builtin__.compile(source, filename.toOsSpecific(), 'exec')
@ -335,7 +333,7 @@ class VFSSharedImporter:
def __init__(self):
pass
def find_module(self, fullname, path = None, reload = False):
#print >>sys.stderr, "shared find_module(%s), path = %s" % (fullname, path)
@ -364,14 +362,14 @@ class VFSSharedImporter:
for dir in path:
if dir in excludePaths:
continue
importer = sys.path_importer_cache.get(dir, None)
if importer is None:
try:
importer = VFSImporter(dir)
except ImportError:
continue
sys.path_importer_cache[dir] = importer
try:
@ -391,6 +389,9 @@ class VFSSharedImporter:
""" Returns the directory name that the indicated
conventionally-loaded module must have been loaded from. """
if not hasattr(mod, __file__) or mod.__file__ is None:
return None
fullname = mod.__name__
dirname = Filename.fromOsSpecific(mod.__file__).getDirname()
@ -414,15 +415,15 @@ class VFSSharedImporter:
# Couldn't figure it out.
return None
class VFSSharedLoader:
""" The second part of VFSSharedImporter, this imports a list of
packages and combines them. """
def __init__(self, loaders, reload):
self.loaders = loaders
self.reload = reload
def load_module(self, fullname):
#print >>sys.stderr, "shared load_module(%s), loaders = %s" % (fullname, map(lambda l: l.dir_path, self.loaders))
@ -475,7 +476,7 @@ def register():
_registered = True
sys.path_hooks.insert(0, VFSImporter)
sys.meta_path.insert(0, VFSSharedImporter())
# Blow away the importer cache, so we'll come back through the
# VFSImporter for every folder in the future, even those
# folders that previously were loaded directly.

View File

@ -17,9 +17,8 @@ except ImportError:
p3extend_frozen = None
import direct
from pandac.PandaModules import *
from panda3d.core import *
from pandac.extension_native_helpers import dll_suffix, dll_ext
import panda3d
# Check to see if we are running python_d, which implies we have a
# debug build, and we have to build the module with debug options.
@ -578,6 +577,8 @@ class Freezer:
if self.platform.startswith('win'):
self.objectExtension = '.obj'
self.keepTemporaryFiles = True
# Change any of these to change the generated startup and glue
# code.
self.frozenMainCode = frozenMainCode
@ -912,7 +913,7 @@ class Freezer:
continue
if origName in self.modules:
continue
# This module is missing. Let it be missing in the
# runtime also.
self.modules[origName] = self.ModuleDef(origName, exclude = True,
@ -1110,7 +1111,7 @@ class Freezer:
# The "module" may end in __init__, but that really means
# the parent directory.
dirnames = dirnames[:-1]
self.__addPythonDirs(multifile, moduleDirs, dirnames[:-1], compressionLevel)
filename = '/'.join(dirnames)
@ -1328,10 +1329,11 @@ class Freezer:
try:
compileFunc(filename, basename)
finally:
if (os.path.exists(filename)):
os.unlink(filename)
if (os.path.exists(basename + self.objectExtension)):
os.unlink(basename + self.objectExtension)
if not self.keepTemporaryFiles:
if os.path.exists(filename):
os.unlink(filename)
if os.path.exists(basename + self.objectExtension):
os.unlink(basename + self.objectExtension)
return target
@ -1378,19 +1380,6 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
def __init__(self, *args, **kw):
modulefinder.ModuleFinder.__init__(self, *args, **kw)
def import_module(self, partname, fqname, parent):
if parent and parent.__name__ == 'panda3d':
# A special case: map a reference to the "panda3d.blah"
# module into the appropriate Panda3D dll.
m = getattr(panda3d, partname, None)
if m and hasattr(m, '__libraries__'):
libname = m.__libraries__[-1]
partname = libname
fqname = libname
parent = None
return modulefinder.ModuleFinder.import_module(self, partname, fqname, parent)
def find_module(self, name, path, parent=None):
try:
return modulefinder.ModuleFinder.find_module(self, name, path, parent = parent)
@ -1425,7 +1414,7 @@ class PandaModuleFinder(modulefinder.ModuleFinder):
m = self.add_module(fqname)
m.__file__ = '<frozen>'
if isPackage:
m.__path__ = pathname
m.__path__ = [pathname]
co = marshal.loads(co)
if self.replace_paths:
co = self.replace_paths_in_code(co)

View File

@ -10,10 +10,10 @@ __all__ = [
'execfile',
]
from pandac import PandaModules as pm
from panda3d import core
import types
_vfs = pm.VirtualFileSystem.getGlobalPtr()
_vfs = core.VirtualFileSystem.getGlobalPtr()
class file:
def __init__(self, filename, mode = 'r', bufsize = None,
@ -36,14 +36,14 @@ class file:
readMode = False
writeMode = False
if isinstance(filename, pm.Istream) or isinstance(filename, pm.Ostream):
if isinstance(filename, core.Istream) or isinstance(filename, core.Ostream):
# If we were given a stream instead of a filename, assign
# it directly.
self.__stream = filename
readMode = isinstance(filename, pm.Istream)
writeMode = isinstance(filename, pm.Ostream)
readMode = isinstance(filename, core.Istream)
writeMode = isinstance(filename, core.Ostream)
elif isinstance(filename, pm.VirtualFile):
elif isinstance(filename, core.VirtualFile):
# We can also "open" a VirtualFile object for reading.
self.__stream = filename.openReadFile(autoUnwrap)
if not self.__stream:
@ -57,10 +57,10 @@ class file:
if isinstance(filename, types.StringTypes):
# If a raw string is given, assume it's an os-specific
# filename.
filename = pm.Filename.fromOsSpecific(filename)
filename = core.Filename.fromOsSpecific(filename)
else:
# If a Filename is given, make a writable copy anyway.
filename = pm.Filename(filename)
filename = core.Filename(filename)
self.filename = filename
self.name = filename.toOsSpecific()
@ -97,7 +97,7 @@ class file:
message = 'Could not open %s for writing' % (filename)
raise IOError, message
writeMode = True
elif mode == 'a':
self.__stream = _vfs.openAppendFile(filename)
if not self.__stream:
@ -142,14 +142,14 @@ class file:
self.__needsVfsClose = True
if readMode:
self.__reader = pm.StreamReader(self.__stream, False)
self.__reader = core.StreamReader(self.__stream, False)
if writeMode:
self.__writer = pm.StreamWriter(self.__stream, False)
self.__writer = core.StreamWriter(self.__stream, False)
self.__lastWrite = True
def __del__(self):
self.close()
def close(self):
if self.__needsVfsClose:
if self.__reader and self.__writer:
@ -158,13 +158,13 @@ class file:
_vfs.closeReadFile(self.__stream)
else: # self.__writer:
_vfs.closeWriteFile(self.__stream)
self.__needsVfsClose = False
self.__stream = None
self.__needsVfsClose = False
self.__reader = None
self.__writer = None
def flush(self):
if self.__stream:
self.__stream.clear() # clear eof flag
@ -188,7 +188,7 @@ class file:
# The stream is open only in write mode.
message = 'Attempt to read from write-only stream'
raise IOError, message
self.__stream.clear() # clear eof flag
self.__lastWrite = False
if size >= 0:
@ -199,7 +199,7 @@ class file:
while not self.__stream.eof():
result += self.__reader.extractBytes(1024)
return result
def readline(self, size = -1):
if not self.__reader:
if not self.__writer:
@ -213,7 +213,7 @@ class file:
self.__stream.clear() # clear eof flag
self.__lastWrite = False
return self.__reader.readline()
def readlines(self, sizehint = -1):
lines = []
line = self.readline()
@ -241,7 +241,7 @@ class file:
return self.__stream.tellg()
message = 'I/O operation on closed file'
raise ValueError, message
def truncate(self):
""" Sorry, this isn't supported by Panda's low-level I/O,
because it isn't supported by the standard C++ library. """
@ -287,7 +287,7 @@ open = file
def listdir(path):
""" Implements os.listdir over vfs. """
files = []
dirlist = _vfs.scanDirectory(pm.Filename.fromOsSpecific(path))
dirlist = _vfs.scanDirectory(core.Filename.fromOsSpecific(path))
if dirlist is None:
message = 'No such file or directory: %s' % (path)
raise OSError, message
@ -338,31 +338,31 @@ def join(path, *args):
return path
def isfile(path):
return _vfs.isRegularFile(pm.Filename.fromOsSpecific(path))
return _vfs.isRegularFile(core.Filename.fromOsSpecific(path))
def isdir(path):
return _vfs.isDirectory(pm.Filename.fromOsSpecific(path))
return _vfs.isDirectory(core.Filename.fromOsSpecific(path))
def exists(path):
return _vfs.exists(pm.Filename.fromOsSpecific(path))
return _vfs.exists(core.Filename.fromOsSpecific(path))
def lexists(path):
return _vfs.exists(pm.Filename.fromOsSpecific(path))
return _vfs.exists(core.Filename.fromOsSpecific(path))
def getmtime(path):
file = _vfs.getFile(pm.Filename.fromOsSpecific(path), True)
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:
raise os.error
return file.getTimestamp()
def getsize(path):
file = _vfs.getFile(pm.Filename.fromOsSpecific(path), True)
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:
raise os.error
return file.getFileSize()
def execfile(path, globals=None, locals=None):
file = _vfs.getFile(pm.Filename.fromOsSpecific(path), True)
file = _vfs.getFile(core.Filename.fromOsSpecific(path), True)
if not file:
raise os.error

View File

@ -23,7 +23,7 @@ support extensions of this nature. """
from types import *
from copy_reg import dispatch_table
from pandac.PandaModules import BamWriter, BamReader
from panda3d.core import BamWriter, BamReader
# A funny replacement for "import pickle" so we don't get confused
# with the local pickle.py.
@ -37,7 +37,7 @@ class Pickler(pickle.Pickler):
# We have to duplicate most of the save() method, so we can add
# support for __reduce_persist__().
def save(self, obj):
# Check for persistent id (defined by a subclass)
pid = self.persistent_id(obj)
@ -116,7 +116,7 @@ class Unpickler(pickle.Unpickler):
# Duplicate the load_reduce() function, to provide a special case
# for the reduction function.
def load_reduce(self):
stack = self.stack
args = stack.pop()

View File

@ -14,13 +14,12 @@ __all__ = [
'forceYield', 'considerYield',
]
# Import PandaModules as pm, so we don't have any namespace collisions.
from pandac import PandaModules as pm
from panda3d import core
# These methods are defined in Panda, and are particularly useful if
# you may be running in Panda's SIMPLE_THREADS compilation mode.
forceYield = pm.Thread.forceYield
considerYield = pm.Thread.considerYield
forceYield = core.Thread.forceYield
considerYield = core.Thread.considerYield
class error(StandardError):
pass
@ -31,10 +30,10 @@ class LockType:
provide the described Python lock semantics. In particular, this
allows a different thread to release the lock than the one that
acquired it. """
def __init__(self):
self.__lock = pm.Mutex('PythonLock')
self.__cvar = pm.ConditionVar(self.__lock)
self.__lock = core.Mutex('PythonLock')
self.__cvar = core.ConditionVar(self.__lock)
self.__locked = False
def acquire(self, waitflag = 1):
@ -44,7 +43,7 @@ class LockType:
return False
while self.__locked:
self.__cvar.wait()
self.__locked = True
return True
@ -56,16 +55,16 @@ class LockType:
try:
if not self.__locked:
raise error, 'Releasing unheld lock.'
self.__locked = False
self.__cvar.notify()
finally:
self.__lock.release()
def locked(self):
return self.__locked
__enter__ = acquire
def __exit__(self, t, v, tb):
@ -73,7 +72,7 @@ class LockType:
_threads = {}
_nextThreadId = 0
_threadsLock = pm.Mutex('thread._threadsLock')
_threadsLock = core.Mutex('thread._threadsLock')
def start_new_thread(function, args, kwargs = {}, name = None):
def threadFunc(threadId, function = function, args = args, kwargs = kwargs):
@ -94,31 +93,31 @@ def start_new_thread(function, args, kwargs = {}, name = None):
if name is None:
name = 'PythonThread-%s' % (threadId)
thread = pm.PythonThread(threadFunc, [threadId], name, name)
thread = core.PythonThread(threadFunc, [threadId], name, name)
thread.setPythonData(threadId)
_threads[threadId] = (thread, {}, None)
thread.start(pm.TPNormal, False)
thread.start(core.TPNormal, False)
return threadId
finally:
_threadsLock.release()
def _add_thread(thread, wrapper):
""" Adds the indicated pm.Thread object, with the indicated Python
""" Adds the indicated core.Thread object, with the indicated Python
wrapper, to the thread list. Returns the new thread ID. """
global _nextThreadId
_threadsLock.acquire()
try:
threadId = _nextThreadId
_nextThreadId += 1
thread.setPythonData(threadId)
_threads[threadId] = (thread, {}, wrapper)
return threadId
finally:
_threadsLock.release()
@ -130,7 +129,7 @@ def _get_thread_wrapper(thread, wrapperClass):
threadId = thread.getPythonData()
if threadId is None:
# The thread has never been assigned a threadId. Go assign one.
global _nextThreadId
_threadsLock.acquire()
try:
@ -166,7 +165,7 @@ def _get_thread_locals(thread, i):
threadId = thread.getPythonData()
if threadId is None:
# The thread has never been assigned a threadId. Go assign one.
global _nextThreadId
_threadsLock.acquire()
try:
@ -195,14 +194,14 @@ def _get_thread_locals(thread, i):
def _remove_thread_id(threadId):
""" Removes the thread with the indicated ID from the thread list. """
_threadsLock.acquire()
try:
thread, locals, wrapper = _threads[threadId]
assert thread.getPythonData() == threadId
del _threads[threadId]
thread.setPythonData(None)
finally:
_threadsLock.release()
@ -218,7 +217,7 @@ def allocate_lock():
return LockType()
def get_ident():
return pm.Thread.getCurrentThread().this
return core.Thread.getCurrentThread().this
def stack_size(size = 0):
raise error
@ -244,18 +243,18 @@ class _local(object):
_threadsLock.release()
def __setattr__(self, key, value):
d = _get_thread_locals(pm.Thread.getCurrentThread(), id(self))
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
d[key] = value
## def __getattr__(self, key):
## d = _get_thread_locals(pm.Thread.getCurrentThread(), id(self))
## d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
## try:
## return d[key]
## except KeyError:
## raise AttributeError
def __getattribute__(self, key):
d = _get_thread_locals(pm.Thread.getCurrentThread(), id(self))
d = _get_thread_locals(core.Thread.getCurrentThread(), id(self))
if key == '__dict__':
return d
try:
@ -263,5 +262,5 @@ class _local(object):
except KeyError:
return object.__getattribute__(self, key)

View File

@ -21,11 +21,8 @@ easier to use and understand.
It is permissible to mix-and-match both threading and threading2
within the same application. """
# We import PandaModules as the name pm, so we can avoid namespace
# collisions between native Panda objects, and our own class
# definitions in this module. """
import direct
from pandac import PandaModules as pm
from panda3d import core
from direct.stdpy import thread as _thread
import sys as _sys
@ -55,10 +52,10 @@ class ThreadBase:
def getName(self):
return self.name
def is_alive(self):
return self.__thread.isStarted()
def isAlive(self):
return self.__thread.isStarted()
@ -68,9 +65,9 @@ class ThreadBase:
def setDaemon(self, daemon):
if self.is_alive():
raise RuntimeError
self.__dict__['daemon'] = daemon
def __setattr__(self, key, value):
if key == 'name':
self.setName(value)
@ -84,8 +81,8 @@ class ThreadBase:
# Copy these static methods from Panda's Thread object. These are
# useful if you may be running in Panda's SIMPLE_THREADS compilation
# mode.
ThreadBase.forceYield = pm.Thread.forceYield
ThreadBase.considerYield = pm.Thread.considerYield
ThreadBase.forceYield = core.Thread.forceYield
ThreadBase.considerYield = core.Thread.considerYield
class Thread(ThreadBase):
""" This class provides a wrapper around Panda's PythonThread
@ -108,21 +105,21 @@ class Thread(ThreadBase):
self.__dict__['daemon'] = current.daemon
self.__dict__['name'] = name
self.__thread = pm.PythonThread(self.run, None, name, name)
self.__thread = core.PythonThread(self.run, None, name, name)
threadId = _thread._add_thread(self.__thread, weakref.proxy(self))
self.__dict__['ident'] = threadId
def __del__(self):
# On interpreter shutdown, the _thread module might have
# already been cleaned up.
if _thread and _thread._remove_thread_id:
if _thread and _thread._remove_thread_id:
_thread._remove_thread_id(self.ident)
def start(self):
if self.__thread.isStarted():
raise RuntimeError
if not self.__thread.start(pm.TPNormal, True):
if not self.__thread.start(core.TPNormal, True):
raise RuntimeError
def run(self):
@ -132,7 +129,7 @@ class Thread(ThreadBase):
_sys.setprofile(_setprofile_func)
self.__target(*self.__args, **self.__kwargs)
def join(self, timeout = None):
# We don't support a timed join here, sorry.
assert timeout is None
@ -146,10 +143,10 @@ class Thread(ThreadBase):
class ExternalThread(ThreadBase):
""" Returned for a Thread object that wasn't created by this
interface. """
def __init__(self, extThread, threadId):
ThreadBase.__init__(self)
self.__thread = extThread
self.__dict__['daemon'] = True
self.__dict__['name'] = self.__thread.getName()
@ -157,10 +154,10 @@ class ExternalThread(ThreadBase):
def start(self):
raise RuntimeError
def run(self):
raise RuntimeError
def join(self, timeout = None):
raise RuntimeError
@ -169,53 +166,53 @@ class ExternalThread(ThreadBase):
class MainThread(ExternalThread):
""" Returned for the MainThread object. """
def __init__(self, extThread, threadId):
ExternalThread.__init__(self, extThread, threadId)
self.__dict__['daemon'] = False
class Lock(pm.Mutex):
class Lock(core.Mutex):
""" This class provides a wrapper around Panda's Mutex object.
The wrapper is designed to emulate Python's own threading.Lock
object. """
def __init__(self, name = "PythonLock"):
pm.Mutex.__init__(self, name)
core.Mutex.__init__(self, name)
def acquire(self, blocking = True):
if blocking:
pm.Mutex.acquire(self)
core.Mutex.acquire(self)
return True
else:
return pm.Mutex.tryAcquire(self)
return core.Mutex.tryAcquire(self)
__enter__ = acquire
def __exit__(self, t, v, tb):
self.release()
class RLock(pm.ReMutex):
class RLock(core.ReMutex):
""" This class provides a wrapper around Panda's ReMutex object.
The wrapper is designed to emulate Python's own threading.RLock
object. """
def __init__(self, name = "PythonRLock"):
pm.ReMutex.__init__(self, name)
core.ReMutex.__init__(self, name)
def acquire(self, blocking = True):
if blocking:
pm.ReMutex.acquire(self)
core.ReMutex.acquire(self)
return True
else:
return pm.ReMutex.tryAcquire(self)
return core.ReMutex.tryAcquire(self)
__enter__ = acquire
def __exit__(self, t, v, tb):
self.release()
class Condition(pm.ConditionVarFull):
class Condition(core.ConditionVarFull):
""" This class provides a wrapper around Panda's ConditionVarFull
object. The wrapper is designed to emulate Python's own
threading.Condition object. """
@ -229,7 +226,7 @@ class Condition(pm.ConditionVarFull):
assert isinstance(lock, Lock)
self.__lock = lock
pm.ConditionVarFull.__init__(self, self.__lock)
core.ConditionVarFull.__init__(self, self.__lock)
def acquire(self, *args, **kw):
return self.__lock.acquire(*args, **kw)
@ -239,35 +236,35 @@ class Condition(pm.ConditionVarFull):
def wait(self, timeout = None):
if timeout is None:
pm.ConditionVarFull.wait(self)
core.ConditionVarFull.wait(self)
else:
pm.ConditionVarFull.wait(self, timeout)
core.ConditionVarFull.wait(self, timeout)
def notifyAll(self):
pm.ConditionVarFull.notifyAll(self)
core.ConditionVarFull.notifyAll(self)
notify_all = notifyAll
__enter__ = acquire
def __exit__(self, t, v, tb):
self.release()
class Semaphore(pm.Semaphore):
class Semaphore(core.Semaphore):
""" This class provides a wrapper around Panda's Semaphore
object. The wrapper is designed to emulate Python's own
threading.Semaphore object. """
def __init__(self, value = 1):
pm.Semaphore.__init__(self, value)
core.Semaphore.__init__(self, value)
def acquire(self, blocking = True):
if blocking:
pm.Semaphore.acquire(self)
core.Semaphore.acquire(self)
return True
else:
return pm.Semaphore.tryAcquire(self)
return core.Semaphore.tryAcquire(self)
__enter__ = acquire
def __exit__(self, t, v, tb):
@ -293,8 +290,8 @@ class Event:
object. """
def __init__(self):
self.__lock = pm.Lock("Python Event")
self.__cvar = pm.ConditionVarFull(self.__lock)
self.__lock = core.Lock("Python Event")
self.__cvar = core.ConditionVarFull(self.__lock)
self.__flag = False
def is_set(self):
@ -310,7 +307,7 @@ class Event:
finally:
self.__lock.release()
def clear(self):
self.__lock.acquire()
try:
@ -318,7 +315,7 @@ class Event:
finally:
self.__lock.release()
def wait(self, timeout = None):
self.__lock.acquire()
try:
@ -326,15 +323,15 @@ class Event:
while not self.__flag:
self.__cvar.wait()
else:
clock = pm.TrueClock.getGlobalPtr()
clock = core.TrueClock.getGlobalPtr()
expires = clock.getShortTime() + timeout
while not self.__flag:
wait = expires - clock.getShortTime()
if wait < 0:
return
self.__cvar.wait(wait)
finally:
self.__lock.release()
@ -366,7 +363,7 @@ class Timer(Thread):
def _create_thread_wrapper(t, threadId):
""" Creates a thread wrapper for the indicated external thread. """
if isinstance(t, pm.MainThread):
if isinstance(t, core.MainThread):
pyt = MainThread(t, threadId)
else:
pyt = ExternalThread(t, threadId)
@ -374,7 +371,7 @@ def _create_thread_wrapper(t, threadId):
return pyt
def current_thread():
t = pm.Thread.getCurrentThread()
t = core.Thread.getCurrentThread()
return _thread._get_thread_wrapper(t, _create_thread_wrapper)
currentThread = current_thread
@ -410,7 +407,7 @@ def stack_size(size = None):
def _test():
from collections import deque
_sleep = pm.Thread.sleep
_sleep = core.Thread.sleep
_VERBOSE = False

View File

@ -17,8 +17,8 @@ import sys as _sys
from direct.stdpy import thread
from direct.stdpy.thread import stack_size, _local as local
from pandac import PandaModules as pm
_sleep = pm.Thread.sleep
from panda3d import core
_sleep = core.Thread.sleep
from time import time as _time
from traceback import format_exc as _format_exc

View File

@ -16,7 +16,7 @@ import time
import random
import string
from pandac.PandaModules import *
from panda3d.core import *
def print_exc_plus():
"""
@ -114,7 +114,7 @@ class TaskManager:
self._frameProfileQueue = Queue()
# this will be set when it's safe to import StateVar
# this will be set when it's safe to import StateVar
self._profileFrames = None
self._frameProfiler = None
self._profileTasks = None
@ -231,7 +231,7 @@ class TaskManager:
in proportion to their time used and to their priority value.
See AsyncTaskManager.setTimeslicePriority() for more.
"""
chain = self.mgr.makeTaskChain(chainName)
if numThreads is not None:
chain.setNumThreads(numThreads)
@ -249,7 +249,7 @@ class TaskManager:
def hasTaskNamed(self, taskName):
"""Returns true if there is at least one task, active or
sleeping, with the indicated name. """
return bool(self.mgr.findTask(taskName))
def getTasksNamed(self, taskName):
@ -261,7 +261,7 @@ class TaskManager:
"""Returns a list of all tasks, active or sleeping, with a
name that matches the pattern, which can include standard
shell globbing characters like *, ?, and []. """
return self.__makeTaskList(self.mgr.findTasksMatching(GlobPattern(taskPattern)))
def getAllTasks(self):
@ -298,7 +298,7 @@ class TaskManager:
wish to specify a task that will run in the next frame, use a
delayTime of 0.
"""
if delayTime < 0:
assert self.notify.warning('doMethodLater: added task: %s with negative delay: %s' % (name, delayTime))
@ -310,7 +310,7 @@ class TaskManager:
def add(self, funcOrTask, name = None, sort = None, extraArgs = None,
priority = None, uponDeath = None, appendTask = False,
taskChain = None, owner = None):
"""
Add a new task to the taskMgr. The task will begin executing
immediately, or next frame if its sort value has already
@ -363,7 +363,7 @@ class TaskManager:
added, or the original Task object that was passed in.
"""
task = self.__setupTask(funcOrTask, name, priority, sort, extraArgs, taskChain, appendTask, owner, uponDeath)
self.mgr.add(task)
return task
@ -412,7 +412,7 @@ class TaskManager:
task.setUponDeath(uponDeath)
return task
def remove(self, taskOrName):
"""Removes a task from the task manager. The task is stopped,
almost as if it had returned task.done. (But if the task is
@ -421,7 +421,7 @@ class TaskManager:
Task object, or the name of a task. If you specify a name,
all tasks with the indicated name are removed. Returns the
number of tasks removed. """
if isinstance(taskOrName, types.StringTypes):
tasks = self.mgr.findTasks(taskOrName)
return self.mgr.remove(tasks)
@ -463,7 +463,7 @@ class TaskManager:
# This is the spot for an internal yield function
nextTaskTime = self.mgr.getNextWakeTime()
self.doYield(startFrameTime, nextTaskTime)
# Restore default interrupt handler
signal.signal(signal.SIGINT, signal.default_int_handler)
if self.fKeyboardInterrupt:
@ -472,7 +472,7 @@ class TaskManager:
def run(self):
"""Starts the task manager running. Does not return until an
exception is encountered (including KeyboardInterrupt). """
# Set the clock to have last frame's time in case we were
# Paused at the prompt for a long time
t = self.globalClock.getFrameTime()
@ -554,7 +554,7 @@ class TaskManager:
def __tryReplaceTaskMethod(self, task, oldMethod, newFunction):
if not isinstance(task, PythonTask):
return 0
method = task.getFunction()
if (type(method) == types.MethodType):
function = method.im_func
@ -730,10 +730,10 @@ class TaskManager:
delta = minFinTime - self.globalClock.getRealTime()
while(delta > 0.002):
print ' sleep %s'% (delta)
time.sleep(delta)
time.sleep(delta)
delta = minFinTime - self.globalClock.getRealTime()
"""
if __debug__:
# to catch memory leaks during the tests at the bottom of the file
def _startTrackingMemLeaks(self):

View File

@ -68,7 +68,7 @@ COREAPI_VERSION=None
PLUGIN_VERSION=None
OSXTARGET=None
UNIVERSAL=False
HOST_URL="https://runtime.panda3d.org/"
HOST_URL=None
global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
STRDXSDKVERSION = 'default'
STRMSPLATFORMVERSION = 'default'
@ -429,11 +429,16 @@ SdkAutoDisablePhysX()
SdkAutoDisableSpeedTree()
if (RTDIST and DISTRIBUTOR == "cmu"):
HOST_URL = "https://runtime.panda3d.org/"
if (RTDIST_VERSION == "cmu_1.7" and SDK["PYTHONVERSION"] != "python2.6"):
exit("The CMU 1.7 runtime distribution must be built against Python 2.6!")
elif (RTDIST_VERSION == "cmu_1.8" and SDK["PYTHONVERSION"] != "python2.7"):
exit("The CMU 1.8 runtime distribution must be built against Python 2.7!")
elif RTDIST and not HOST_URL:
exit("You must specify a host URL when building the rtdist!")
########################################################################
##
## Choose a Compiler.
@ -1562,8 +1567,8 @@ def CompileLink(dll, obj, opts):
CopyFile(new_path, dll)
oscmd('%s --strip-unneeded %s' % (GetStrip(), BracketNameWithQuotes(new_path)))
elif (GetOrigExt(dll)==".exe" and GetOptimizeOption(opts)==4 and "NOSTRIP" not in opts):
oscmd(GetStrip() + " -x " + BracketNameWithQuotes(dll))
elif (GetOptimizeOption(opts)==4 and GetTarget() == 'linux'):
oscmd(GetStrip() + " --strip-unneeded " + BracketNameWithQuotes(dll))
os.system("chmod +x " + BracketNameWithQuotes(dll))
@ -4681,7 +4686,7 @@ if (RTDIST or RUNTIME):
TargetAdd('p3dpython.exe', input='p3dpython_p3dPythonMain.obj')
TargetAdd('p3dpython.exe', input=COMMON_PANDA_LIBS)
TargetAdd('p3dpython.exe', input='libp3tinyxml.ilb')
TargetAdd('p3dpython.exe', opts=['NOSTRIP', 'PYTHON', 'WINUSER'])
TargetAdd('p3dpython.exe', opts=['PYTHON', 'WINUSER'])
TargetAdd('libp3dpython.dll', input='p3dpython_p3dpython_composite1.obj')
TargetAdd('libp3dpython.dll', input=COMMON_PANDA_LIBS)
@ -4719,7 +4724,7 @@ if (RTDIST or RUNTIME):
TargetAdd('p3dcert.exe', input='plugin_mkdir_complete.obj')
TargetAdd('p3dcert.exe', input='plugin_wstring_encode.obj')
TargetAdd('p3dcert.exe', input='plugin_p3dCert.obj')
OPTS=['NOSTRIP', 'OPENSSL', 'WX', 'CARBON', 'WINOLE', 'WINOLEAUT', 'WINUSER', 'ADVAPI', 'WINSHELL', 'WINCOMCTL', 'WINGDI', 'WINCOMDLG']
OPTS=['OPENSSL', 'WX', 'CARBON', 'WINOLE', 'WINOLEAUT', 'WINUSER', 'ADVAPI', 'WINSHELL', 'WINCOMCTL', 'WINGDI', 'WINCOMDLG']
if GetTarget() == "darwin":
OPTS += ['GL', 'OPT:2']
TargetAdd('p3dcert.exe', opts=OPTS)
@ -4836,7 +4841,7 @@ if (RUNTIME):
TargetAdd('Panda3D.app', input='libp3tinyxml.ilb')
TargetAdd('Panda3D.app', input='panda3d_mac.plist', ipath=OPTS)
TargetAdd('Panda3D.app', input='models/plugin_images/panda3d.icns')
TargetAdd('Panda3D.app', opts=['NOSTRIP', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'WINSHELL', 'ADVAPI', 'WINSOCK2', 'WINOLE', 'CARBON'])
TargetAdd('Panda3D.app', opts=['OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'WINSHELL', 'ADVAPI', 'WINSOCK2', 'WINOLE', 'CARBON'])
elif (GetTarget() == 'windows'):
TargetAdd('plugin_standalone_panda3dWinMain.obj', opts=OPTS, input='panda3dWinMain.cxx')
TargetAdd('panda3dw.exe', input='plugin_standalone_panda3d.obj')
@ -4899,7 +4904,7 @@ if (RTDIST):
TargetAdd('p3dembed.exe', input='libp3subprocbuffer.ilb')
TargetAdd('p3dembed.exe', input='libp3tinyxml.ilb')
TargetAdd('p3dembed.exe', input='libp3d_plugin_static.ilb')
TargetAdd('p3dembed.exe', opts=['NOICON', 'NOSTRIP', 'WINGDI', 'WINSOCK2', 'ZLIB', 'WINUSER', 'OPENSSL', 'JPEG', 'WINOLE', 'CARBON', 'MSIMG', 'WINCOMCTL', 'ADVAPI', 'WINSHELL', 'X11', 'PNG'])
TargetAdd('p3dembed.exe', opts=['NOICON', 'WINGDI', 'WINSOCK2', 'ZLIB', 'WINUSER', 'OPENSSL', 'JPEG', 'WINOLE', 'CARBON', 'MSIMG', 'WINCOMCTL', 'ADVAPI', 'WINSHELL', 'X11', 'PNG'])
if GetTarget() == 'windows':
OPTS.append("P3DEMBEDW")
@ -4925,7 +4930,7 @@ if (RTDIST):
TargetAdd('p3dembedw.exe', input='plugin_common.obj')
TargetAdd('p3dembedw.exe', input='libp3tinyxml.ilb')
TargetAdd('p3dembedw.exe', input='libp3d_plugin_static.ilb')
TargetAdd('p3dembedw.exe', opts=['NOICON', 'NOSTRIP', 'WINGDI', 'WINSOCK2', 'ZLIB', 'WINUSER', 'OPENSSL', 'JPEG', 'WINOLE', 'MSIMG', 'WINCOMCTL', 'ADVAPI', 'WINSHELL', 'PNG'])
TargetAdd('p3dembedw.exe', opts=['NOICON', 'WINGDI', 'WINSOCK2', 'ZLIB', 'WINUSER', 'OPENSSL', 'JPEG', 'WINOLE', 'MSIMG', 'WINCOMCTL', 'ADVAPI', 'WINSHELL', 'PNG'])
#
# DIRECTORY: pandatool/src/pandatoolbase/