Browse Source

show download progress as a fraction of the total progress, including stuff downloaded previously

David Rose 15 years ago
parent
commit
3a5d9bd327

+ 13 - 0
direct/src/p3d/PackageInfo.py

@@ -166,6 +166,19 @@ class PackageInfo:
         
         return size
 
+    def getPrevDownloadedEffort(self):
+        """ Returns a rough estimate of this package's total download
+        effort, even if it is already downloaded. """
+
+        effort = 0
+        if self.compressedArchive:
+            effort += self.compressedArchive.size * self.downloadFactor
+        if self.uncompressedArchive:
+            effort += self.uncompressedArchive.size * self.uncompressFactor
+        # Don't bother counting unpacking.
+
+        return effort
+
     def getFormattedName(self):
         """ Returns the name of this package, for output to the user.
         This will be the "public" name of the package, as formatted

+ 12 - 11
direct/src/p3d/PackageInstaller.py

@@ -21,11 +21,6 @@ class PackageInstaller(DirectObject):
     Also see DWBPackageInstaller, which does exactly this, to add a
     DirectWaitBar GUI.
 
-    Note that in the default mode, with a one-thread task chain, the
-    packages will all be downloaded in sequence, one after the other.
-    If you add more tasks to the task chain, some of the packages may
-    be downloaded in parallel, and the calls to packageStarted()
-    .. packageFinished() may therefore overlap.
     """
 
     notify = directNotify.newCategory("PackageInstaller")
@@ -81,6 +76,10 @@ class PackageInstaller(DirectObject):
             # getDescFile().
             self.downloadEffort = 0
 
+            # Similar, but this is the theoretical effort if the
+            # package were already downloaded.
+            self.prevDownloadedEffort = 0
+
         def __cmp__(self, pp):
             """ Python comparision function.  This makes all
             PendingPackages withe same (packageName, version, host)
@@ -117,6 +116,9 @@ class PackageInstaller(DirectObject):
                 return False
 
             self.downloadEffort = self.package.getDownloadEffort()
+            self.prevDownloadEffort = 0
+            if self.downloadEffort == 0:
+                self.prevDownloadedEffort = self.package.getPrevDownloadedEffort()
 
             return True
             
@@ -141,6 +143,9 @@ class PackageInstaller(DirectObject):
 
             self.package.checkStatus()
             self.downloadEffort = self.package.getDownloadEffort()
+            self.prevDownloadEffort = 0
+            if self.downloadEffort == 0:
+                self.prevDownloadedEffort = self.package.getPrevDownloadedEffort()
 
             return True
 
@@ -193,10 +198,6 @@ class PackageInstaller(DirectObject):
         # This task is spawned on the default task chain, to update
         # the status during the download.
         self.progressTask = None
-
-        # The totalDownloadSize is None, until all package desc files
-        # have been read.
-        self.totalDownloadSize = None
         
         self.accept('PackageInstaller-%s-allHaveDesc' % self.uniqueId,
                     self.__allHaveDesc)
@@ -618,9 +619,9 @@ class PackageInstaller(DirectObject):
             downloadEffort = 0
             currentDownloadSize = 0
             for pp in self.packages:
-                downloadEffort += pp.downloadEffort
+                downloadEffort += pp.downloadEffort + pp.prevDownloadedEffort
                 packageProgress = pp.getProgress()
-                currentDownloadSize += pp.downloadEffort * packageProgress
+                currentDownloadSize += pp.downloadEffort * packageProgress + pp.prevDownloadedEffort
                 if pp.calledPackageStarted and not pp.calledPackageFinished:
                     self.packageProgress(pp.package, packageProgress)
 

+ 39 - 23
direct/src/plugin/p3dInstance.cxx

@@ -151,6 +151,7 @@ P3DInstance(P3D_request_ready_func *func,
   _instance_window_attached = false;
   _stuff_to_download = false;
   _download_package_index = 0;
+  _prev_downloaded = 0;
   _total_download_size = 0;
   _total_downloaded = 0;
   _packages_specified = false;
@@ -2143,21 +2144,8 @@ add_packages() {
   }
 
   _packages_specified = true;
-  if (get_packages_info_ready()) {
-    // All packages are ready to go.  Let's start some download
-    // action.
-    _downloading_packages.clear();
-    _total_download_size = 0;
-    Packages::const_iterator pi;
-    for (pi = _packages.begin(); pi != _packages.end(); ++pi) {
-      P3DPackage *package = (*pi);
-      if (package->get_info_ready() && !package->get_ready()) {
-        _downloading_packages.push_back(package);
-        _total_download_size += package->get_download_size();
-      }
-    }
-    ready_to_install();
-  }
+
+  consider_start_download();
 }
 
 
@@ -2892,17 +2880,33 @@ report_package_info_ready(P3DPackage *package) {
                 rp._host);
   }
 
+  consider_start_download();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: P3DInstance::consider_start_download
+//       Access: Private
+//  Description: When all package info files have been obtained,
+//               begins downloading stuff.
+////////////////////////////////////////////////////////////////////
+void P3DInstance::
+consider_start_download() {
   if (get_packages_info_ready()) {
     // All packages are ready to go.  Let's start some download
     // action.
     _downloading_packages.clear();
+    _prev_downloaded = 0;
     _total_download_size = 0;
     Packages::const_iterator pi;
     for (pi = _packages.begin(); pi != _packages.end(); ++pi) {
       P3DPackage *package = (*pi);
-      if (package->get_info_ready() && !package->get_ready()) {
-        _downloading_packages.push_back(package);
-        _total_download_size += package->get_download_size();
+      if (package->get_info_ready()) {
+        if (!package->get_ready()) {
+          _downloading_packages.push_back(package);
+          _total_download_size += package->get_download_size();
+        } else {
+          _prev_downloaded += package->get_download_size();
+        }
       }
     }
     ready_to_install();
@@ -2942,7 +2946,8 @@ ready_to_install() {
 
     nout << "Beginning install of " << _downloading_packages.size()
          << " packages, total " << _total_download_size
-         << " bytes required.\n";
+         << " bytes required (" << _prev_downloaded
+         << " previously downloaded).\n";
     
     if (_downloading_packages.size() > 0) {
       _stuff_to_download = true;
@@ -2951,14 +2956,25 @@ ready_to_install() {
       make_splash_window();
     }
     
-    if (_splash_window != NULL) {
-      _splash_window->set_install_progress(0.0, true, 0);
-    }
     _panda_script_object->set_string_property("status", "downloading");
     _panda_script_object->set_int_property("numDownloadingPackages", _downloading_packages.size());
     _panda_script_object->set_int_property("totalDownloadSize", _total_download_size);
     _panda_script_object->set_int_property("downloadElapsedSeconds", 0);
     _panda_script_object->set_undefined_property("downloadRemainingSeconds");
+
+    double progress = 0.0;
+    if (_prev_downloaded != 0) {
+      // We might start off with more than 0 progress, if we've
+      // already downloaded some of it previously.
+      progress = (_prev_downloaded) / (_total_download_size + _prev_downloaded);
+      progress = min(progress, 1.0);
+
+      _panda_script_object->set_float_property("downloadProgress", progress);
+    }
+    if (_splash_window != NULL) {
+      _splash_window->set_install_progress(progress, true, 0);
+    }
+
     send_notify("ondownloadbegin");
     
     start_next_download();
@@ -3151,7 +3167,7 @@ report_package_progress(P3DPackage *package, double progress) {
   }
 
   // Scale the progress into the range appropriate to this package.
-  progress = (progress * package->get_download_size() + _total_downloaded) / _total_download_size;
+  progress = (progress * package->get_download_size() + _total_downloaded + _prev_downloaded) / (_total_download_size + _prev_downloaded);
   progress = min(progress, 1.0);
 
   if (_splash_window != NULL) {

+ 2 - 0
direct/src/plugin/p3dInstance.h

@@ -193,6 +193,7 @@ private:
   void set_background_image(ImageType image_type);
   void set_button_image(ImageType image_type);
   void report_package_info_ready(P3DPackage *package);
+  void consider_start_download();
   void ready_to_install();
   void start_next_download();
   void mark_download_complete();
@@ -348,6 +349,7 @@ private:
   Packages _packages;
   Packages _downloading_packages;
   int _download_package_index;
+  size_t _prev_downloaded;
   size_t _total_download_size;
   size_t _total_downloaded;
   bool _packages_specified;

+ 3 - 5
direct/src/plugin/p3dPackage.I

@@ -28,17 +28,15 @@ get_info_ready() const {
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DPackage::get_download_size
 //       Access: Public
-//  Description: If get_info_ready() is true but get_ready() is false,
-//               it means the package is ready to be downloaded.  In
-//               this case, this method returns the number of bytes
-//               that need to be downloaded for this package.  This is
+//  Description: Returns the number of bytes that will need to be
+//               downloaded, when this package is downloaded.  This is
 //               intended to be used to estimate the download time for
 //               this package relative to other packages, for instance
 //               to update a progress bar sensibly.
 ////////////////////////////////////////////////////////////////////
 inline size_t P3DPackage::
 get_download_size() const {
-  return _download_size;
+  return _compressed_archive.get_size();
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 5
direct/src/plugin/p3dPackage.cxx

@@ -66,7 +66,6 @@ P3DPackage(P3DHost *host, const string &package_name,
 
   _computed_plan_size = false;
   _info_ready = false;
-  _download_size = 0;
   _allow_data_download = false;
   _ready = false;
   _failed = false;
@@ -1149,7 +1148,6 @@ report_progress(P3DPackage::InstallStep *step) {
 void P3DPackage::
 report_info_ready() {
   _info_ready = true;
-  _download_size = _compressed_archive.get_size();
 
   Instances::iterator ii;
   for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
@@ -1184,9 +1182,7 @@ report_done(bool success) {
 
   if (!_allow_data_download && success) {
     // If we haven't been authorized to start downloading yet, just
-    // report that we're ready to start, but that we don't have to
-    // download anything.
-    _download_size = 0;
+    // report that we're ready to start.
     Instances::iterator ii;
     for (ii = _instances.begin(); ii != _instances.end(); ++ii) {
       (*ii)->report_package_info_ready(this);

+ 0 - 1
direct/src/plugin/p3dPackage.h

@@ -278,7 +278,6 @@ private:
   string _desc_file_pathname;
 
   bool _info_ready;
-  size_t _download_size;
   bool _allow_data_download;
   bool _ready;
   bool _failed;