Improve the progress events
At the moment the progress events are reported for each download operation separately. Combined with the fact that the size of the dives isn't known in advance, and thus the progress events are based on a worst case value, the user experience is far from optimal. In practice, the progress goes from 0 to 100% for every manifest, and it stays close to zero while downloading the dives. This is improved by combining the individual progress events into a single progress for the entire download. This global progress simply counts the number of individual download operations. Since each operation is now subdivided into a fixed number of steps, regardless of the size of the transfer, the perceived speed is no longer constant.
This commit is contained in:
parent
2d7d5152b4
commit
2ced18870d
@ -342,7 +342,7 @@ shearwater_common_transfer (shearwater_common_device_t *device, const unsigned c
|
||||
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression)
|
||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress)
|
||||
{
|
||||
dc_device_t *abstract = (dc_device_t *) device;
|
||||
dc_status_t rc = DC_STATUS_SUCCESS;
|
||||
@ -370,9 +370,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
||||
}
|
||||
|
||||
// Enable progress notifications.
|
||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||
progress.maximum = 3 + size + 1;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
unsigned int initial = 0, current = 0, maximum = 3 + size + 1;
|
||||
if (progress) {
|
||||
initial = progress->current;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||
}
|
||||
|
||||
// Transfer the init request.
|
||||
rc = shearwater_common_transfer (device, req_init, sizeof (req_init), response, 3, &n);
|
||||
@ -387,8 +389,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current += 3;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
if (progress) {
|
||||
current += 3;
|
||||
progress->current = initial + STEP (current, maximum);
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||
}
|
||||
|
||||
unsigned int done = 0;
|
||||
unsigned char block = 1;
|
||||
@ -415,8 +420,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current += length;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
if (progress) {
|
||||
current += length;
|
||||
progress->current = initial + STEP (current, maximum);
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||
}
|
||||
|
||||
if (compression) {
|
||||
if (shearwater_common_decompress_lre (response + 2, length, buffer, &done) != 0) {
|
||||
@ -454,8 +462,11 @@ shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buf
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current += 1;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
if (progress) {
|
||||
current += 1;
|
||||
progress->current = initial + STEP (current, maximum);
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, progress);
|
||||
}
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -39,6 +39,9 @@ extern "C" {
|
||||
#define PERDIX 5
|
||||
#define PERDIXAI 6
|
||||
|
||||
#define NSTEPS 10000
|
||||
#define STEP(i,n) ((NSTEPS * (i) + (n) / 2) / (n))
|
||||
|
||||
typedef struct shearwater_common_device_t {
|
||||
dc_device_t base;
|
||||
dc_serial_t *port;
|
||||
@ -54,7 +57,7 @@ dc_status_t
|
||||
shearwater_common_transfer (shearwater_common_device_t *device, const unsigned char input[], unsigned int isize, unsigned char output[], unsigned int osize, unsigned int *actual);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression);
|
||||
shearwater_common_download (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int address, unsigned int size, unsigned int compression, dc_event_progress_t *progress);
|
||||
|
||||
dc_status_t
|
||||
shearwater_common_identifier (shearwater_common_device_t *device, dc_buffer_t *buffer, unsigned int id);
|
||||
|
||||
@ -168,6 +168,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
// Enable progress notifications.
|
||||
unsigned int current = 0, maximum = 0;
|
||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
// Read the serial number.
|
||||
rc = shearwater_common_identifier (&device->base, buffer, ID_SERIAL);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
@ -240,8 +245,16 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
while (1) {
|
||||
// Update the progress state.
|
||||
// Assume the worst case scenario of a full manifest, and adjust the
|
||||
// value with the actual number of dives after the manifest has been
|
||||
// processed.
|
||||
maximum += 1 + RECORD_COUNT;
|
||||
|
||||
// Download a manifest.
|
||||
rc = shearwater_common_download (&device->base, buffer, MANIFEST_ADDR, MANIFEST_SIZE, 0);
|
||||
progress.current = NSTEPS * current;
|
||||
progress.maximum = NSTEPS * maximum;
|
||||
rc = shearwater_common_download (&device->base, buffer, MANIFEST_ADDR, MANIFEST_SIZE, 0, &progress);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to download the manifest.");
|
||||
dc_buffer_free (buffer);
|
||||
@ -270,6 +283,10 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
count++;
|
||||
}
|
||||
|
||||
// Update the progress state.
|
||||
current += 1;
|
||||
maximum -= RECORD_COUNT - count;
|
||||
|
||||
// Append the manifest records to the main buffer.
|
||||
if (!dc_buffer_append (manifests, data, count * RECORD_SIZE)) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
@ -283,6 +300,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
break;
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current = NSTEPS * current;
|
||||
progress.maximum = NSTEPS * maximum;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
// Cache the buffer pointer and size.
|
||||
unsigned char *data = dc_buffer_get_data (manifests);
|
||||
unsigned int size = dc_buffer_get_size (manifests);
|
||||
@ -293,7 +315,9 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
unsigned int address = array_uint32_be (data + offset + 20);
|
||||
|
||||
// Download the dive.
|
||||
rc = shearwater_common_download (&device->base, buffer, DIVE_ADDR + address, DIVE_SIZE, 1);
|
||||
progress.current = NSTEPS * current;
|
||||
progress.maximum = NSTEPS * maximum;
|
||||
rc = shearwater_common_download (&device->base, buffer, DIVE_ADDR + address, DIVE_SIZE, 1, &progress);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
ERROR (abstract->context, "Failed to download the dive.");
|
||||
dc_buffer_free (buffer);
|
||||
@ -301,6 +325,9 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Update the progress state.
|
||||
current += 1;
|
||||
|
||||
unsigned char *buf = dc_buffer_get_data (buffer);
|
||||
unsigned int len = dc_buffer_get_size (buffer);
|
||||
if (callback && !callback (buf, len, buf + 12, sizeof (device->fingerprint), userdata))
|
||||
@ -309,6 +336,11 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call
|
||||
offset += RECORD_SIZE;
|
||||
}
|
||||
|
||||
// Update and emit a progress event.
|
||||
progress.current = NSTEPS * current;
|
||||
progress.maximum = NSTEPS * maximum;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
dc_buffer_free (manifests);
|
||||
dc_buffer_free (buffer);
|
||||
|
||||
|
||||
@ -133,7 +133,12 @@ shearwater_predator_device_dump (dc_device_t *abstract, dc_buffer_t *buffer)
|
||||
return DC_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
return shearwater_common_download (device, buffer, 0xDD000000, SZ_MEMORY, 0);
|
||||
// Enable progress notifications.
|
||||
dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER;
|
||||
progress.current = 0;
|
||||
progress.maximum = NSTEPS;
|
||||
|
||||
return shearwater_common_download (device, buffer, 0xDD000000, SZ_MEMORY, 0, &progress);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user