mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
support unknown-sized downloads
This commit is contained in:
parent
7d9d27e74f
commit
a7ac5345f4
@ -27,18 +27,33 @@ get_url() const {
|
||||
// Function: P3DDownload::get_download_progress
|
||||
// Access: Public
|
||||
// Description: Returns an indication of the progress through the
|
||||
// download file, 0.0 to 1.0. Returns 0.0 if the size
|
||||
// download file, 0.0 to 1.0. Returns 1.0 if the size
|
||||
// of the file is not known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline double P3DDownload::
|
||||
get_download_progress() const {
|
||||
if (_total_expected_data == 0) {
|
||||
return 0.0;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return (double)_total_data / (double)_total_expected_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::is_download_progress_known
|
||||
// Access: Public
|
||||
// Description: Returns true if the download progress is known, or
|
||||
// false if it is unknown because the server hasn't told
|
||||
// us the total size it will be feeding us. If this is
|
||||
// false, get_download_progress() will generally always
|
||||
// return 1.0; use get_total_bytes() to measure progress
|
||||
// in this case.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline bool P3DDownload::
|
||||
is_download_progress_known() const {
|
||||
return _progress_known;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::get_total_data
|
||||
// Access: Public
|
||||
@ -49,6 +64,21 @@ get_total_data() const {
|
||||
return _total_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::set_total_expected_data
|
||||
// Access: Public
|
||||
// Description: Sets the total number of bytes expected to be
|
||||
// downloaded. This is used to compute the progress.
|
||||
// Normally, this can be set from the download server,
|
||||
// but there may be cases when the download server
|
||||
// doesn't accurately report it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
inline void P3DDownload::
|
||||
set_total_expected_data(size_t expected_data) {
|
||||
_total_expected_data = expected_data;
|
||||
_progress_known = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DDownload::get_download_finished
|
||||
// Access: Public
|
||||
|
@ -26,6 +26,7 @@ P3DDownload() {
|
||||
_total_data = 0;
|
||||
_total_expected_data = 0;
|
||||
_last_reported_time = 0;
|
||||
_progress_known = false;
|
||||
|
||||
_canceled = false;
|
||||
_download_id = 0;
|
||||
@ -39,7 +40,8 @@ P3DDownload() {
|
||||
P3DDownload::
|
||||
P3DDownload(const P3DDownload ©) :
|
||||
_url(copy._url),
|
||||
_total_expected_data(copy._total_expected_data)
|
||||
_total_expected_data(copy._total_expected_data),
|
||||
_progress_known(copy._progress_known)
|
||||
{
|
||||
_status = P3D_RC_in_progress;
|
||||
_http_status_code = 0;
|
||||
@ -132,12 +134,27 @@ feed_url_stream(P3D_result_code result_code,
|
||||
_total_data += this_data_size;
|
||||
}
|
||||
|
||||
_total_expected_data = max(total_expected_data, _total_data);
|
||||
total_expected_data = max(total_expected_data, _total_data);
|
||||
if (total_expected_data > _total_expected_data) {
|
||||
// If the expected data grows during the download, we don't really
|
||||
// know how much we're getting.
|
||||
_progress_known = false;
|
||||
_total_expected_data = total_expected_data;
|
||||
}
|
||||
if (_total_expected_data > 0 &&
|
||||
(double)_total_data / (double)_total_expected_data < 0.9) {
|
||||
// But if we're not close to our target yet, let's say we do know
|
||||
// (at least until we get there and the target moves again).
|
||||
_progress_known = true;
|
||||
}
|
||||
|
||||
download_progress();
|
||||
|
||||
if (_status != P3D_RC_in_progress) {
|
||||
// We're done.
|
||||
if (get_download_success()) {
|
||||
_progress_known = true;
|
||||
}
|
||||
download_finished(get_download_success());
|
||||
}
|
||||
|
||||
@ -167,9 +184,13 @@ download_progress() {
|
||||
time_t now = time(NULL);
|
||||
if (now - _last_reported_time > 10) {
|
||||
_last_reported_time = now;
|
||||
nout << "Downloading " << get_url() << ": "
|
||||
<< int(get_download_progress() * 1000.0) / 10.0
|
||||
<< ", " << this << "\n";
|
||||
nout << "Downloading " << get_url() << ": ";
|
||||
if (_progress_known) {
|
||||
nout << int(get_download_progress() * 1000.0) / 10.0 << "%";
|
||||
} else {
|
||||
nout << int((double)get_total_data() / 104857.6) / 10.0 << "M";
|
||||
}
|
||||
nout << ", " << this << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +204,11 @@ download_progress() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DDownload::
|
||||
download_finished(bool success) {
|
||||
nout << "Downloaded " << get_url() << ": "
|
||||
<< int(get_download_progress() * 1000.0) / 10.0
|
||||
<< ", " << this << ", success = " << success << "\n";
|
||||
nout << "Downloaded " << get_url() << ": ";
|
||||
if (_progress_known) {
|
||||
nout << int(get_download_progress() * 1000.0) / 10.0 << "%";
|
||||
} else {
|
||||
nout << int((double)get_total_data() / 104857.6) / 10.0 << "M";
|
||||
}
|
||||
nout << ", " << this << ", success = " << success << "\n";
|
||||
}
|
||||
|
@ -38,10 +38,12 @@ public:
|
||||
inline const string &get_url() const;
|
||||
|
||||
inline double get_download_progress() const;
|
||||
inline bool is_download_progress_known() const;
|
||||
inline bool get_download_finished() const;
|
||||
inline bool get_download_success() const;
|
||||
inline bool get_download_terminated() const;
|
||||
inline size_t get_total_data() const;
|
||||
inline void set_total_expected_data(size_t expected_data);
|
||||
|
||||
void cancel();
|
||||
void clear();
|
||||
@ -70,6 +72,7 @@ protected:
|
||||
size_t _total_data;
|
||||
size_t _total_expected_data;
|
||||
time_t _last_reported_time;
|
||||
bool _progress_known;
|
||||
|
||||
private:
|
||||
bool _canceled;
|
||||
|
@ -332,6 +332,9 @@ set_p3d_url(const string &p3d_url) {
|
||||
InstanceDownload *download = new InstanceDownload(this);
|
||||
download->set_url(p3d_url);
|
||||
download->set_filename(_temp_p3d_filename->get_filename());
|
||||
if (_fparams.has_token("p3d_size")) {
|
||||
download->set_total_expected_data(_fparams.lookup_token_int("p3d_size"));
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading_instance");
|
||||
start_download(download);
|
||||
@ -371,6 +374,9 @@ make_p3d_stream(const string &p3d_url) {
|
||||
InstanceDownload *download = new InstanceDownload(this);
|
||||
download->set_url(p3d_url);
|
||||
download->set_filename(_temp_p3d_filename->get_filename());
|
||||
if (_fparams.has_token("p3d_size")) {
|
||||
download->set_total_expected_data(_fparams.lookup_token_int("p3d_size"));
|
||||
}
|
||||
|
||||
_panda_script_object->set_string_property("status", "downloading_instance");
|
||||
return start_download(download, false);
|
||||
@ -2438,7 +2444,7 @@ report_package_info_ready(P3DPackage *package) {
|
||||
// put up a progress bar.
|
||||
make_splash_window();
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_progress(0.0, true, 0);
|
||||
if (package == _certlist_package) {
|
||||
_splash_window->set_install_label("Getting Certificates");
|
||||
} else {
|
||||
@ -2493,7 +2499,7 @@ report_package_info_ready(P3DPackage *package) {
|
||||
}
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_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());
|
||||
@ -2573,7 +2579,7 @@ mark_download_complete() {
|
||||
|
||||
// Take down the download progress bar.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_progress(0.0, true, 0);
|
||||
_splash_window->set_install_label("");
|
||||
}
|
||||
|
||||
@ -2616,7 +2622,8 @@ ready_to_start() {
|
||||
// Description: Notified as the instance file is downloaded.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DInstance::
|
||||
report_instance_progress(double progress) {
|
||||
report_instance_progress(double progress, bool is_progress_known,
|
||||
size_t received_data) {
|
||||
if (!_show_dl_instance_progress) {
|
||||
// If we haven't yet set the download label, set it after a full
|
||||
// second has elapsed. We don't want to set it too soon, because
|
||||
@ -2642,7 +2649,7 @@ report_instance_progress(double progress) {
|
||||
}
|
||||
|
||||
if (_splash_window != NULL && _show_dl_instance_progress) {
|
||||
_splash_window->set_install_progress(progress);
|
||||
_splash_window->set_install_progress(progress, is_progress_known, received_data);
|
||||
}
|
||||
_panda_script_object->set_float_property("instanceDownloadProgress", progress);
|
||||
}
|
||||
@ -2662,7 +2669,7 @@ report_package_progress(P3DPackage *package, double progress) {
|
||||
if (package == _certlist_package || package == _p3dcert_package) {
|
||||
// This gets its own progress bar.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(progress);
|
||||
_splash_window->set_install_progress(progress, true, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2679,7 +2686,7 @@ report_package_progress(P3DPackage *package, double progress) {
|
||||
progress = min(progress, 1.0);
|
||||
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(progress);
|
||||
_splash_window->set_install_progress(progress, true, 0);
|
||||
}
|
||||
_panda_script_object->set_float_property("downloadProgress", progress);
|
||||
|
||||
@ -2754,7 +2761,7 @@ report_package_done(P3DPackage *package, bool success) {
|
||||
|
||||
// Take down the download progress.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_progress(0.0, true, 0);
|
||||
_splash_window->set_install_label("");
|
||||
}
|
||||
|
||||
@ -2770,7 +2777,7 @@ report_package_done(P3DPackage *package, bool success) {
|
||||
|
||||
// Take down the download progress.
|
||||
if (_splash_window != NULL) {
|
||||
_splash_window->set_install_progress(0.0);
|
||||
_splash_window->set_install_progress(0.0, true, 0);
|
||||
_splash_window->set_install_label("");
|
||||
}
|
||||
|
||||
@ -3143,7 +3150,7 @@ InstanceDownload(P3DInstance *inst) :
|
||||
void P3DInstance::InstanceDownload::
|
||||
download_progress() {
|
||||
P3DFileDownload::download_progress();
|
||||
_inst->report_instance_progress(get_download_progress());
|
||||
_inst->report_instance_progress(get_download_progress(), is_download_progress_known(), get_total_data());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -3159,6 +3166,7 @@ download_finished(bool success) {
|
||||
P3DFileDownload::download_finished(success);
|
||||
if (success) {
|
||||
// We've successfully downloaded the instance data.
|
||||
_inst->report_instance_progress(1.0, true, 0);
|
||||
_inst->priv_set_p3d_filename(get_filename());
|
||||
} else {
|
||||
// Oops, no joy on the instance data.
|
||||
|
@ -187,9 +187,10 @@ private:
|
||||
void start_next_download();
|
||||
void mark_download_complete();
|
||||
void ready_to_start();
|
||||
void report_instance_progress(double progress);
|
||||
void report_instance_progress(double progress, bool is_progress_known,
|
||||
size_t received_data);
|
||||
void report_package_progress(P3DPackage *package, double progress);
|
||||
void report_package_done(P3DPackage *package, bool progress);
|
||||
void report_package_done(P3DPackage *package, bool success);
|
||||
void set_install_label(const string &install_label);
|
||||
|
||||
void paint_window();
|
||||
|
@ -185,12 +185,25 @@ set_install_label(const string &install_label) {
|
||||
// Description: Moves the install progress bar from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DOsxSplashWindow::
|
||||
set_install_progress(double install_progress) {
|
||||
if ((int)(install_progress * 500.0) != (int)(_install_progress * 500.0)) {
|
||||
// Only request a refresh if we're changing substantially.
|
||||
set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data) {
|
||||
// Only request a refresh if we're changing substantially.
|
||||
if (is_progress_known != _progress_known) {
|
||||
refresh();
|
||||
} else if (_progress_known) {
|
||||
if ((int)(install_progress * 500.0) != (int)(_install_progress * 500.0)) {
|
||||
refresh();
|
||||
}
|
||||
} else {
|
||||
if ((int)(received_data * _unknown_progress_rate) !=
|
||||
(int)(_received_data * _unknown_progress_rate)) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
_install_progress = install_progress;
|
||||
_progress_known = is_progress_known;
|
||||
_received_data = received_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -343,8 +356,14 @@ paint_window() {
|
||||
|
||||
// Draw the progress bar. We don't draw this bar at all unless we
|
||||
// have nonzero progress.
|
||||
if (_install_progress != 0.0) {
|
||||
paint_progress_bar(context);
|
||||
if (_progress_known) {
|
||||
if (_install_progress != 0.0) {
|
||||
paint_progress_bar(context);
|
||||
}
|
||||
} else {
|
||||
if (_received_data != 0) {
|
||||
paint_progress_bar(context);
|
||||
}
|
||||
}
|
||||
|
||||
CGContextSynchronize(context);
|
||||
@ -507,9 +526,27 @@ paint_progress_bar(CGContextRef context) {
|
||||
CGContextFillPath(context);
|
||||
|
||||
// Draw the interior of the progress bar in blue (or the bar color).
|
||||
int progress_width = (int)((bar_width - 2) * _install_progress);
|
||||
if (progress_width != 0) {
|
||||
CGRect prog = { { bar_xf, bar_yf }, { progress_width, bar_height } };
|
||||
if (_progress_known) {
|
||||
int progress_width = (int)(bar_width * _install_progress + 0.5);
|
||||
if (progress_width != 0) {
|
||||
CGRect prog = { { bar_xf, bar_yf }, { progress_width, bar_height } };
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetFillColorWithColor(context, bar);
|
||||
CGContextAddRect(context, prog);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
} else {
|
||||
// Progress is unknown. Draw a moving block, not a progress bar
|
||||
// filling up.
|
||||
int block_width = (int)(bar_width * 0.1 + 0.5);
|
||||
int block_travel = bar_width - block_width;
|
||||
int progress = (int)(_received_data * _unknown_progress_rate);
|
||||
progress = progress % (block_travel * 2);
|
||||
if (progress > block_travel) {
|
||||
progress = block_travel * 2 - progress;
|
||||
}
|
||||
|
||||
CGRect prog = { { bar_xf + progress, bar_yf }, { block_width, bar_height } };
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetFillColorWithColor(context, bar);
|
||||
CGContextAddRect(context, prog);
|
||||
|
@ -38,7 +38,8 @@ public:
|
||||
virtual void set_image_filename(const string &image_filename,
|
||||
ImagePlacement image_placement);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
virtual void set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data);
|
||||
|
||||
virtual bool handle_event(const P3D_event_data &event);
|
||||
|
||||
@ -81,6 +82,8 @@ private:
|
||||
|
||||
string _install_label;
|
||||
double _install_progress;
|
||||
bool _progress_known;
|
||||
size_t _received_data;
|
||||
|
||||
// Used to track the mouse within the window in the embedded case.
|
||||
bool _mouse_active;
|
||||
|
@ -39,7 +39,9 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo) {
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
|
||||
// The number of pixels to move the block per byte downloaded, when we
|
||||
// don't know the actual file size we're downloading.
|
||||
const double P3DSplashWindow::_unknown_progress_rate = 1.0 / 4096;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DSplashWindow::Constructor
|
||||
@ -192,7 +194,8 @@ set_install_label(const string &install_label) {
|
||||
// Description: Moves the install progress bar from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DSplashWindow::
|
||||
set_install_progress(double install_progress) {
|
||||
set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -58,7 +58,8 @@ public:
|
||||
virtual void set_bgcolor(int r, int g, int b);
|
||||
virtual void set_barcolor(int r, int g, int b);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
virtual void set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data);
|
||||
|
||||
virtual bool handle_event(const P3D_event_data &event);
|
||||
|
||||
@ -120,6 +121,8 @@ protected:
|
||||
bool _mouse_down;
|
||||
bool _button_depressed;
|
||||
ButtonState _bstate;
|
||||
|
||||
static const double _unknown_progress_rate;
|
||||
};
|
||||
|
||||
#include "p3dSplashWindow.I"
|
||||
|
@ -176,7 +176,8 @@ set_install_label(const string &install_label) {
|
||||
// Description: Moves the install progress bar from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DWinSplashWindow::
|
||||
set_install_progress(double install_progress) {
|
||||
set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data) {
|
||||
ACQUIRE_LOCK(_install_lock);
|
||||
_install_progress = install_progress;
|
||||
RELEASE_LOCK(_install_lock);
|
||||
@ -776,7 +777,7 @@ paint_progress_bar(HDC dc) {
|
||||
FillRect(dc, &bar_rect, _bg_brush);
|
||||
|
||||
// Draw the interior of the progress bar in blue (or the bar color).
|
||||
int progress_width = (int)((bar_width - 2) * _drawn_progress);
|
||||
int progress_width = (int)((bar_width - 2) * _drawn_progress + 0.5);
|
||||
if (progress_width != 0) {
|
||||
RECT prog_rect = { bar_x, bar_y, bar_x + progress_width, bar_y + bar_height };
|
||||
FillRect(dc, &prog_rect, _bar_brush);
|
||||
|
@ -40,7 +40,8 @@ public:
|
||||
virtual void set_image_filename(const string &image_filename,
|
||||
ImagePlacement image_placement);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
virtual void set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data);
|
||||
virtual void request_keyboard_focus();
|
||||
|
||||
static void register_window_class();
|
||||
|
@ -156,7 +156,8 @@ set_install_label(const string &install_label) {
|
||||
// Description: Moves the install progress bar from 0.0 to 1.0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void P3DX11SplashWindow::
|
||||
set_install_progress(double install_progress) {
|
||||
set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data) {
|
||||
if (_subprocess_pid == -1) {
|
||||
return;
|
||||
}
|
||||
@ -611,7 +612,7 @@ subprocess_run() {
|
||||
}
|
||||
|
||||
if (needs_update_progress) {
|
||||
int progress_width = (int)((bar_width - 2) * _install_progress);
|
||||
int progress_width = (int)((bar_width - 2) * _install_progress + 0.5);
|
||||
XFillRectangle(_display, _window, _bar_context,
|
||||
bar_x + 1, bar_y + 1,
|
||||
progress_width + 1, bar_height - 1);
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
virtual void set_image_filename(const string &image_filename,
|
||||
ImagePlacement image_placement);
|
||||
virtual void set_install_label(const string &install_label);
|
||||
virtual void set_install_progress(double install_progress);
|
||||
virtual void set_install_progress(double install_progress,
|
||||
bool is_progress_known, size_t received_data);
|
||||
|
||||
virtual void set_button_active(bool flag);
|
||||
|
||||
|
@ -434,7 +434,7 @@ NPP_WriteReady_x(NPP instance, NPStream *stream) {
|
||||
int32_t
|
||||
NPP_Write_x(NPP instance, NPStream *stream, int32_t offset,
|
||||
int32_t len, void *buffer) {
|
||||
// nout << "Write " << stream->url << ", " << len << " for " << instance << ", " << (PPInstance *)(instance->pdata) << "\n";
|
||||
// nout << "Write " << stream->url << ", " << offset << ", " << len << " for " << instance << ", " << (PPInstance *)(instance->pdata) << "\n";
|
||||
PPInstance::generic_browser_call();
|
||||
PPInstance *inst = (PPInstance *)(instance->pdata);
|
||||
assert(inst != NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user