diff --git a/direct/src/p3d/PackageInfo.py b/direct/src/p3d/PackageInfo.py index 6739a95b0d..dc2d2007d6 100644 --- a/direct/src/p3d/PackageInfo.py +++ b/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 diff --git a/direct/src/p3d/PackageInstaller.py b/direct/src/p3d/PackageInstaller.py index 58b8eb37a2..2c97d3c7e6 100644 --- a/direct/src/p3d/PackageInstaller.py +++ b/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) diff --git a/direct/src/plugin/p3dInstance.cxx b/direct/src/plugin/p3dInstance.cxx index b5278eafa8..05a540d697 100644 --- a/direct/src/plugin/p3dInstance.cxx +++ b/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) { diff --git a/direct/src/plugin/p3dInstance.h b/direct/src/plugin/p3dInstance.h index b31a2ed658..7efdc89473 100644 --- a/direct/src/plugin/p3dInstance.h +++ b/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; diff --git a/direct/src/plugin/p3dPackage.I b/direct/src/plugin/p3dPackage.I index 7b904490c5..e4d09e4a5c 100755 --- a/direct/src/plugin/p3dPackage.I +++ b/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(); } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/plugin/p3dPackage.cxx b/direct/src/plugin/p3dPackage.cxx index 46e4322c88..2fec7a8286 100755 --- a/direct/src/plugin/p3dPackage.cxx +++ b/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); diff --git a/direct/src/plugin/p3dPackage.h b/direct/src/plugin/p3dPackage.h index d071258c5f..6c938325c3 100755 --- a/direct/src/plugin/p3dPackage.h +++ b/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;