// namespaces
var dwv = dwv || {};
dwv.utils = dwv.utils || {};
/**
* Multiple progresses handler.
* Stores a multi dimensional list of progresses to allow to
* calculate a global progress.
*
* @param {Function} callback The function to pass the global progress to.
*/
dwv.utils.MultiProgressHandler = function (callback) {
// closure to self
var self = this;
/**
* List of progresses.
* First dimension is a list of item for which the progress is recorded,
* for example file names.
* Second dimension is a list of possible progresses, for example
* the progress of the download and the progress of the decoding.
*
* @private
* @type {Array}
*/
var progresses = [];
/**
* Number of dimensions.
*
* @private
* @type {number}
*/
var numberOfDimensions = 2;
/**
* Set the number of dimensions.
*
* @param {number} num The number.
*/
this.setNumberOfDimensions = function (num) {
numberOfDimensions = num;
};
/**
* Set the number of data to load.
*
* @param {number} n The number of data to load.
*/
this.setNToLoad = function (n) {
for (var i = 0; i < n; ++i) {
progresses[i] = [];
for (var j = 0; j < numberOfDimensions; ++j) {
progresses[i][j] = 0;
}
}
};
/**
* Handle a load progress.
* Call the member callback with a global event.
*
* @param {object} event The progress event.
*/
this.onprogress = function (event) {
// check event
if (!event.lengthComputable) {
return;
}
if (typeof event.subindex === 'undefined') {
return;
}
if (typeof event.index === 'undefined') {
return;
}
// calculate percent
var percent = (event.loaded * 100) / event.total;
// set percent for index
progresses[event.index][event.subindex] = percent;
// item progress
var item = null;
if (typeof event.item !== 'undefined') {
item = event.item;
} else {
item = {
loaded: getItemProgress(event.index),
total: 100,
source: event.source
};
}
// call callback with a global event
callback({
lengthComputable: true,
loaded: getGlobalPercent(),
total: 100,
item: item
});
};
/**
* Get the item load percent.
*
* @param {number} index The index of the item.
* @returns {number} The load percentage.
* @private
*/
function getItemProgress(index) {
var sum = 0;
for (var j = 0; j < numberOfDimensions; ++j) {
sum += progresses[index][j];
}
return sum / numberOfDimensions;
}
/**
* Get the global load percent including the provided one.
*
* @returns {number} The accumulated percentage.
* @private
*/
function getGlobalPercent() {
var sum = 0;
var lenprog = progresses.length;
for (var i = 0; i < lenprog; ++i) {
sum += getItemProgress(i);
}
return Math.round(sum / lenprog);
}
/**
* Create a mono progress event handler.
*
* @param {number} index The index of the data.
* @param {number} subindex The sub-index of the data.
* @returns {Function} A progress handler function.
*/
this.getMonoProgressHandler = function (index, subindex) {
return function (event) {
event.index = index;
event.subindex = subindex;
self.onprogress(event);
};
};
/**
* Create a mono progress event handler with an undefined index.
* Warning: The caller handles the progress index.
*
* @param {number} subindex The sub-index of the data.
* @returns {Function} A progress handler function.
*/
this.getUndefinedMonoProgressHandler = function (subindex) {
return function (event) {
event.subindex = subindex;
self.onprogress(event);
};
};
};