mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
guarantee proper ordering of download phases
This commit is contained in:
parent
74264f850f
commit
6eba1cf08a
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user