2
0
Эх сурвалжийг харах

guarantee proper ordering of download phases

David Rose 16 жил өмнө
parent
commit
6eba1cf08a

+ 12 - 9
direct/src/p3d/AppRunner.py

@@ -39,6 +39,7 @@ from direct.stdpy import file
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase.MessengerGlobal import messenger
 from direct.showbase import AppRunnerGlobal
 from direct.showbase import AppRunnerGlobal
+from direct.directnotify.DirectNotifyGlobal import directNotify
 from direct.p3d.HostInfo import HostInfo
 from direct.p3d.HostInfo import HostInfo
 
 
 # These imports are read by the C++ wrapper in p3dPythonRun.cxx.
 # 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
     It does not usually exist while running Python directly, but you
     can use dummyAppRunner() to create one at startup for testing or
     can use dummyAppRunner() to create one at startup for testing or
     development purposes.  """
     development purposes.  """
+
+    notify = directNotify.newCategory("AppRunner")
     
     
     def __init__(self):
     def __init__(self):
         DirectObject.__init__(self)
         DirectObject.__init__(self)
@@ -171,7 +174,7 @@ class AppRunner(DirectObject):
             if args[1] == 'notify':
             if args[1] == 'notify':
                 # Quietly ignore notifies.
                 # Quietly ignore notifies.
                 return
                 return
-            print "Ignoring request: %s" % (args,)
+            self.notify.info("Ignoring request: %s" % (args,))
         self.requestFunc = defaultRequestFunc
         self.requestFunc = defaultRequestFunc
 
 
         # This will be filled in with the default WindowProperties for
         # This will be filled in with the default WindowProperties for
@@ -245,8 +248,8 @@ class AppRunner(DirectObject):
         # All right, get the package info now.
         # All right, get the package info now.
         package = host.getPackage(packageName, version)
         package = host.getPackage(packageName, version)
         if not package:
         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 False
 
 
         return self.__rInstallPackage(package, [])
         return self.__rInstallPackage(package, [])
@@ -266,7 +269,7 @@ class AppRunner(DirectObject):
             if host.downloadContentsFile(self.http):
             if host.downloadContentsFile(self.http):
                 p2 = host.getPackage(packageName, version)
                 p2 = host.getPackage(packageName, version)
                 if not p2:
                 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:
                 else:
                     if p2 not in nested:
                     if p2 not in nested:
                         self.__rInstallPackage(p2, nested)
                         self.__rInstallPackage(p2, nested)
@@ -279,8 +282,8 @@ class AppRunner(DirectObject):
         if not package.installPackage(self):
         if not package.installPackage(self):
             return False
             return False
 
 
-        print "Package %s %s installed." % (
-            package.packageName, package.packageVersion)
+        self.notify.info("Package %s %s installed." % (
+            package.packageName, package.packageVersion))
         return True
         return True
 
 
     def getHostWithAlt(self, hostUrl):
     def getHostWithAlt(self, hostUrl):
@@ -353,13 +356,13 @@ class AppRunner(DirectObject):
         if self.superMirrorUrl:
         if self.superMirrorUrl:
             # Use the "super mirror" first.
             # Use the "super mirror" first.
             url = PandaModules.URLSpec(self.superMirrorUrl + fileSpec.filename)
             url = PandaModules.URLSpec(self.superMirrorUrl + fileSpec.filename)
-            print "Freshening %s" % (url)
+            self.notify.info("Freshening %s" % (url))
             doc = self.http.getDocument(url)
             doc = self.http.getDocument(url)
             
             
         if not doc or not doc.isValid():
         if not doc or not doc.isValid():
             # Failing the super mirror, contact the actual host.
             # Failing the super mirror, contact the actual host.
             url = PandaModules.URLSpec(host.hostUrlPrefix + fileSpec.filename)
             url = PandaModules.URLSpec(host.hostUrlPrefix + fileSpec.filename)
-            print "Freshening %s" % (url)
+            self.notify.info("Freshening %s" % (url))
             doc = self.http.getDocument(url)
             doc = self.http.getDocument(url)
             if not doc.isValid():
             if not doc.isValid():
                 return False
                 return False
@@ -379,7 +382,7 @@ class AppRunner(DirectObject):
 
 
         if not fileSpec.fullVerify(pathname = localPathname):
         if not fileSpec.fullVerify(pathname = localPathname):
             # No good after download.
             # 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 False
 
 
         return True
         return True

+ 41 - 47
direct/src/p3d/PackageInstaller.py

@@ -4,6 +4,7 @@ from direct.showbase.MessengerGlobal import messenger
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.task.TaskManagerGlobal import taskMgr
 from direct.p3d.PackageInfo import PackageInfo
 from direct.p3d.PackageInfo import PackageInfo
 from pandac.PandaModules import TPLow
 from pandac.PandaModules import TPLow
+from direct.directnotify.DirectNotifyGlobal import directNotify
 
 
 class PackageInstaller(DirectObject):
 class PackageInstaller(DirectObject):
 
 
@@ -27,6 +28,8 @@ class PackageInstaller(DirectObject):
     .. packageFinished() may therefore overlap.
     .. packageFinished() may therefore overlap.
     """
     """
 
 
+    notify = directNotify.newCategory("PackageInstaller")
+
     globalLock = Lock()
     globalLock = Lock()
     nextUniqueId = 1
     nextUniqueId = 1
 
 
@@ -101,8 +104,8 @@ class PackageInstaller(DirectObject):
             # All right, get the package info now.
             # All right, get the package info now.
             package = self.host.getPackage(self.packageName, self.version)
             package = self.host.getPackage(self.packageName, self.version)
             if not package:
             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
                 return False
 
 
             self.package = package
             self.package = package
@@ -126,8 +129,8 @@ class PackageInstaller(DirectObject):
             # All right, get the package info now.
             # All right, get the package info now.
             package = self.host.getPackage(self.packageName, self.version)
             package = self.host.getPackage(self.packageName, self.version)
             if not package:
             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
                 return False
 
 
             self.package = package
             self.package = package
@@ -251,30 +254,15 @@ class PackageInstaller(DirectObject):
             return
             return
         
         
         self.packages.append(pp)
         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):
     def donePackages(self):
         """ After calling addPackage() for each package to be
         """ 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
         is called; at the time of this callback, the total download
         size is known, and we can sensibly report progress through the
         size is known, and we can sensibly report progress through the
         whole. """
         whole. """
-        pass
+
+        self.notify.info("downloadStarted")
 
 
     def packageStarted(self, package):
     def packageStarted(self, package):
         """ This callback is made for each package between
         """ This callback is made for each package between
         downloadStarted() and downloadFinished() to indicate the start
         downloadStarted() and downloadFinished() to indicate the start
         of a new package. """
         of a new package. """
-        pass
+
+        self.notify.debug("packageStarted: %s" % (package.packageName))
 
 
     def packageProgress(self, package, progress):
     def packageProgress(self, package, progress):
         """ This callback is made repeatedly between packageStarted()
         """ This callback is made repeatedly between packageStarted()
         and packageFinished() to update the current progress on the
         and packageFinished() to update the current progress on the
         indicated package only.  The progress value ranges from 0
         indicated package only.  The progress value ranges from 0
         (beginning) to 1 (complete). """
         (beginning) to 1 (complete). """
-        pass
+
+        self.notify.debug("packageProgress: %s %s" % (package.packageName, progress))
         
         
     def downloadProgress(self, overallProgress):
     def downloadProgress(self, overallProgress):
         """ This callback is made repeatedly between downloadStarted()
         """ This callback is made repeatedly between downloadStarted()
         and downloadFinished() to update the current progress through
         and downloadFinished() to update the current progress through
         all packages.  The progress value ranges from 0 (beginning) to
         all packages.  The progress value ranges from 0 (beginning) to
         1 (complete). """
         1 (complete). """
-        pass
+
+        self.notify.debug("downloadProgress: %s" % (overallProgress))
 
 
     def packageFinished(self, package, success):
     def packageFinished(self, package, success):
         """ This callback is made for each package between
         """ This callback is made for each package between
@@ -346,7 +338,8 @@ class PackageInstaller(DirectObject):
         already downloaded), this callback will be made immediately,
         already downloaded), this callback will be made immediately,
         *without* a corresponding call to packageStarted(), and may
         *without* a corresponding call to packageStarted(), and may
         even be made before downloadStarted(). """
         even be made before downloadStarted(). """
-        pass
+
+        self.notify.info("packageFinished: %s %s" % (package.packageName, success))
 
 
     def downloadFinished(self, success):
     def downloadFinished(self, success):
         """ This callback is made when all of the packages have been
         """ 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
         If there were no packages that required downloading, this
         callback will be made immediately, *without* a corresponding
         callback will be made immediately, *without* a corresponding
         call to downloadStarted(). """
         call to downloadStarted(). """
-        pass
+
+        self.notify.info("downloadFinished: %s" % (success))
 
 
     def __prepareToStart(self):
     def __prepareToStart(self):
         """ This is called internally when transitioning from S_ready
         """ This is called internally when transitioning from S_ready
@@ -401,14 +395,14 @@ class PackageInstaller(DirectObject):
     def __packageStarted(self, pp):
     def __packageStarted(self, pp):
         """ This method is called when a single package is beginning
         """ This method is called when a single package is beginning
         to download. """
         to download. """
-        print "Downloading package %s" % (pp.packageName)
+
         self.__callDownloadStarted()
         self.__callDownloadStarted()
         self.__callPackageStarted(pp)
         self.__callPackageStarted(pp)
 
 
     def __packageDone(self, pp):
     def __packageDone(self, pp):
         """ This method is called when a single package has been
         """ This method is called when a single package has been
         downloaded and installed, or has failed. """
         downloaded and installed, or has failed. """
-        print "Downloaded %s: %s" % (pp.packageName, pp.success)
+
         self.__callPackageFinished(pp, pp.success)
         self.__callPackageFinished(pp, pp.success)
         pp.notified = True
         pp.notified = True
 
 
@@ -507,16 +501,15 @@ class PackageInstaller(DirectObject):
             self.packageLock.release()
             self.packageLock.release()
 
 
         # Now serve this one package.
         # Now serve this one package.
-        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
+        if not pp.checkDescFile():
+            if not pp.getDescFile(self.appRunner.http):
+                self.__donePackage(pp, False)
+                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()
         self.packageLock.acquire()
         try:
         try:
             # Also add any packages required by this one.
             # Also add any packages required by this one.
@@ -552,9 +545,10 @@ class PackageInstaller(DirectObject):
         messenger.send('PackageInstaller-%s-packageStarted' % self.uniqueId,
         messenger.send('PackageInstaller-%s-packageStarted' % self.uniqueId,
                        [pp], taskChain = 'default')
                        [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.
         # Successfully downloaded and installed.
         self.__donePackage(pp, True)
         self.__donePackage(pp, True)