Spaces:
Sleeping
Sleeping
var util = require('util') | |
var TrackerBase = require('./tracker-base.js') | |
var Tracker = require('./tracker.js') | |
var TrackerStream = require('./tracker-stream.js') | |
var TrackerGroup = module.exports = function (name) { | |
TrackerBase.call(this, name) | |
this.parentGroup = null | |
this.trackers = [] | |
this.completion = {} | |
this.weight = {} | |
this.totalWeight = 0 | |
this.finished = false | |
this.bubbleChange = bubbleChange(this) | |
} | |
util.inherits(TrackerGroup, TrackerBase) | |
function bubbleChange (trackerGroup) { | |
return function (name, completed, tracker) { | |
trackerGroup.completion[tracker.id] = completed | |
if (trackerGroup.finished) return | |
trackerGroup.emit('change', name || trackerGroup.name, trackerGroup.completed(), trackerGroup) | |
} | |
} | |
TrackerGroup.prototype.nameInTree = function () { | |
var names = [] | |
var from = this | |
while (from) { | |
names.unshift(from.name) | |
from = from.parentGroup | |
} | |
return names.join('/') | |
} | |
TrackerGroup.prototype.addUnit = function (unit, weight) { | |
if (unit.addUnit) { | |
var toTest = this | |
while (toTest) { | |
if (unit === toTest) { | |
throw new Error( | |
'Attempted to add tracker group ' + | |
unit.name + ' to tree that already includes it ' + | |
this.nameInTree(this)) | |
} | |
toTest = toTest.parentGroup | |
} | |
unit.parentGroup = this | |
} | |
this.weight[unit.id] = weight || 1 | |
this.totalWeight += this.weight[unit.id] | |
this.trackers.push(unit) | |
this.completion[unit.id] = unit.completed() | |
unit.on('change', this.bubbleChange) | |
if (!this.finished) this.emit('change', unit.name, this.completion[unit.id], unit) | |
return unit | |
} | |
TrackerGroup.prototype.completed = function () { | |
if (this.trackers.length === 0) return 0 | |
var valPerWeight = 1 / this.totalWeight | |
var completed = 0 | |
for (var ii = 0; ii < this.trackers.length; ii++) { | |
var trackerId = this.trackers[ii].id | |
completed += valPerWeight * this.weight[trackerId] * this.completion[trackerId] | |
} | |
return completed | |
} | |
TrackerGroup.prototype.newGroup = function (name, weight) { | |
return this.addUnit(new TrackerGroup(name), weight) | |
} | |
TrackerGroup.prototype.newItem = function (name, todo, weight) { | |
return this.addUnit(new Tracker(name, todo), weight) | |
} | |
TrackerGroup.prototype.newStream = function (name, todo, weight) { | |
return this.addUnit(new TrackerStream(name, todo), weight) | |
} | |
TrackerGroup.prototype.finish = function () { | |
this.finished = true | |
if (!this.trackers.length) this.addUnit(new Tracker(), 1, true) | |
for (var ii = 0; ii < this.trackers.length; ii++) { | |
var tracker = this.trackers[ii] | |
tracker.finish() | |
tracker.removeListener('change', this.bubbleChange) | |
} | |
this.emit('change', this.name, 1, this) | |
} | |
var buffer = ' ' | |
TrackerGroup.prototype.debug = function (depth) { | |
depth = depth || 0 | |
var indent = depth ? buffer.substr(0, depth) : '' | |
var output = indent + (this.name || 'top') + ': ' + this.completed() + '\n' | |
this.trackers.forEach(function (tracker) { | |
if (tracker instanceof TrackerGroup) { | |
output += tracker.debug(depth + 1) | |
} else { | |
output += indent + ' ' + tracker.name + ': ' + tracker.completed() + '\n' | |
} | |
}) | |
return output | |
} | |