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

This commit is contained in:
David Rose 2010-06-11 22:22:25 +00:00
parent 44df8cc6a6
commit 3a5d9bd327
7 changed files with 70 additions and 45 deletions

View File

@ -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

View File

@ -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)

View File

@ -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) {

View File

@ -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;

View File

@ -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();
}
////////////////////////////////////////////////////////////////////

View File

@ -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);

View File

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