diff --git a/direct/src/p3d/AppRunner.py b/direct/src/p3d/AppRunner.py index 149e318dfd..4e691f90ec 100644 --- a/direct/src/p3d/AppRunner.py +++ b/direct/src/p3d/AppRunner.py @@ -39,6 +39,7 @@ from direct.stdpy import file from direct.task.TaskManagerGlobal import taskMgr from direct.showbase.MessengerGlobal import messenger from direct.showbase import AppRunnerGlobal +from direct.directnotify.DirectNotifyGlobal import directNotify from direct.p3d.HostInfo import HostInfo # These imports are read by the C++ wrapper in p3dPythonRun.cxx. @@ -63,6 +64,8 @@ class AppRunner(DirectObject): It does not usually exist while running Python directly, but you can use dummyAppRunner() to create one at startup for testing or development purposes. """ + + notify = directNotify.newCategory("AppRunner") def __init__(self): DirectObject.__init__(self) @@ -171,7 +174,7 @@ class AppRunner(DirectObject): if args[1] == 'notify': # Quietly ignore notifies. return - print "Ignoring request: %s" % (args,) + self.notify.info("Ignoring request: %s" % (args,)) self.requestFunc = defaultRequestFunc # This will be filled in with the default WindowProperties for @@ -245,8 +248,8 @@ class AppRunner(DirectObject): # All right, get the package info now. package = host.getPackage(packageName, version) if not package: - print "Package %s %s not known on %s" % ( - packageName, version, hostUrl) + self.notify.warning("Package %s %s not known on %s" % ( + packageName, version, hostUrl)) return False return self.__rInstallPackage(package, []) @@ -266,7 +269,7 @@ class AppRunner(DirectObject): if host.downloadContentsFile(self.http): p2 = host.getPackage(packageName, version) if not p2: - print "Couldn't find %s %s on %s" % (packageName, version, host.hostUrl) + self.notify.warning("Couldn't find %s %s on %s" % (packageName, version, host.hostUrl)) else: if p2 not in nested: self.__rInstallPackage(p2, nested) @@ -279,8 +282,8 @@ class AppRunner(DirectObject): if not package.installPackage(self): return False - print "Package %s %s installed." % ( - package.packageName, package.packageVersion) + self.notify.info("Package %s %s installed." % ( + package.packageName, package.packageVersion)) return True def getHostWithAlt(self, hostUrl): @@ -353,13 +356,13 @@ class AppRunner(DirectObject): if self.superMirrorUrl: # Use the "super mirror" first. url = PandaModules.URLSpec(self.superMirrorUrl + fileSpec.filename) - print "Freshening %s" % (url) + 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) - print "Freshening %s" % (url) + self.notify.info("Freshening %s" % (url)) doc = self.http.getDocument(url) if not doc.isValid(): return False @@ -379,7 +382,7 @@ class AppRunner(DirectObject): if not fileSpec.fullVerify(pathname = localPathname): # No good after download. - print "%s is still no good after downloading." % (url) + self.notify.info("%s is still no good after downloading." % (url)) return False return True diff --git a/direct/src/p3d/PackageInstaller.py b/direct/src/p3d/PackageInstaller.py index c8f485267c..1959e0f731 100644 --- a/direct/src/p3d/PackageInstaller.py +++ b/direct/src/p3d/PackageInstaller.py @@ -4,6 +4,7 @@ from direct.showbase.MessengerGlobal import messenger from direct.task.TaskManagerGlobal import taskMgr from direct.p3d.PackageInfo import PackageInfo from pandac.PandaModules import TPLow +from direct.directnotify.DirectNotifyGlobal import directNotify class PackageInstaller(DirectObject): @@ -27,6 +28,8 @@ class PackageInstaller(DirectObject): .. packageFinished() may therefore overlap. """ + notify = directNotify.newCategory("PackageInstaller") + globalLock = Lock() nextUniqueId = 1 @@ -101,8 +104,8 @@ class PackageInstaller(DirectObject): # All right, get the package info now. package = self.host.getPackage(self.packageName, self.version) if not package: - print "Package %s %s not known on %s" % ( - self.packageName, self.version, self.host.hostUrl) + self.notify.warning("Package %s %s not known on %s" % ( + self.packageName, self.version, self.host.hostUrl)) return False self.package = package @@ -126,8 +129,8 @@ class PackageInstaller(DirectObject): # All right, get the package info now. package = self.host.getPackage(self.packageName, self.version) if not package: - print "Package %s %s not known on %s" % ( - self.packageName, self.version, self.host.hostUrl) + self.notify.warning("Package %s %s not known on %s" % ( + self.packageName, self.version, self.host.hostUrl)) return False self.package = package @@ -251,30 +254,15 @@ class PackageInstaller(DirectObject): return self.packages.append(pp) - if not pp.checkDescFile(): - # Still need to download the desc file. - self.needsDescFile.append(pp) - if not self.descFileTask: - self.descFileTask = taskMgr.add( - self.__getDescFileTask, 'getDescFile', - taskChain = self.taskChain) - else: - # The desc file is ready, which means so are the requirements. - for packageName, version, host in pp.package.requires: - pp2 = self.PendingPackage(packageName, version, host) - self.__internalAddPackage(pp2) - - # Now that we've added the required packages, add the - # package itself. - if not pp.package.hasPackage: - # The desc file is good, but the package itself needs - # to be downloaded. - self.needsDownload.append(pp) - - else: - # The package is already fully downloaded. - self.earlyDone.append(pp) + # We always add the package to needsDescFile, even if we + # already have its desc file; this guarantees that packages + # are downloaded in the order they are added. + self.needsDescFile.append(pp) + if not self.descFileTask: + self.descFileTask = taskMgr.add( + self.__getDescFileTask, 'getDescFile', + taskChain = self.taskChain) def donePackages(self): """ After calling addPackage() for each package to be @@ -314,27 +302,31 @@ class PackageInstaller(DirectObject): is called; at the time of this callback, the total download size is known, and we can sensibly report progress through the whole. """ - pass + + self.notify.info("downloadStarted") def packageStarted(self, package): """ This callback is made for each package between downloadStarted() and downloadFinished() to indicate the start of a new package. """ - pass + + self.notify.debug("packageStarted: %s" % (package.packageName)) def packageProgress(self, package, progress): """ This callback is made repeatedly between packageStarted() and packageFinished() to update the current progress on the indicated package only. The progress value ranges from 0 (beginning) to 1 (complete). """ - pass + + 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 all packages. The progress value ranges from 0 (beginning) to 1 (complete). """ - pass + + self.notify.debug("downloadProgress: %s" % (overallProgress)) def packageFinished(self, package, success): """ This callback is made for each package between @@ -346,7 +338,8 @@ class PackageInstaller(DirectObject): already downloaded), this callback will be made immediately, *without* a corresponding call to packageStarted(), and may even be made before downloadStarted(). """ - pass + + self.notify.info("packageFinished: %s %s" % (package.packageName, success)) def downloadFinished(self, success): """ This callback is made when all of the packages have been @@ -356,7 +349,8 @@ class PackageInstaller(DirectObject): If there were no packages that required downloading, this callback will be made immediately, *without* a corresponding call to downloadStarted(). """ - pass + + self.notify.info("downloadFinished: %s" % (success)) def __prepareToStart(self): """ This is called internally when transitioning from S_ready @@ -401,14 +395,14 @@ class PackageInstaller(DirectObject): def __packageStarted(self, pp): """ This method is called when a single package is beginning to download. """ - print "Downloading package %s" % (pp.packageName) + self.__callDownloadStarted() self.__callPackageStarted(pp) def __packageDone(self, pp): """ This method is called when a single package has been downloaded and installed, or has failed. """ - print "Downloaded %s: %s" % (pp.packageName, pp.success) + self.__callPackageFinished(pp, pp.success) pp.notified = True @@ -507,16 +501,15 @@ class PackageInstaller(DirectObject): self.packageLock.release() # Now serve this one package. - if not pp.getDescFile(self.appRunner.http): - self.__donePackage(pp, False) - return task.cont + if not pp.checkDescFile(): + if not pp.getDescFile(self.appRunner.http): + self.__donePackage(pp, False) + return task.cont - if pp.package.hasPackage: - # This package is already downloaded. - self.__donePackage(pp, True) - return task.cont - - # This package is now ready to be downloaded. + # 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. @@ -552,9 +545,10 @@ class PackageInstaller(DirectObject): messenger.send('PackageInstaller-%s-packageStarted' % self.uniqueId, [pp], taskChain = 'default') - if not pp.package.downloadPackage(self.appRunner.http): - self.__donePackage(pp, False) - return task.cont + if not pp.package.hasPackage: + if not pp.package.downloadPackage(self.appRunner.http): + self.__donePackage(pp, False) + return task.cont # Successfully downloaded and installed. self.__donePackage(pp, True)