npm
Version:
a package manager for JavaScript
131 lines (112 loc) • 3.59 kB
JavaScript
"use strict"
var stream = require("readable-stream");
var EventEmitter = require("events").EventEmitter
var util = require("util")
var delegate = require("delegates")
var TrackerGroup = exports.TrackerGroup = function (name) {
EventEmitter.call(this)
this.name = name
this.trackGroup = []
var self = this
this.totalWeight = 0
var noteChange = this.noteChange = function (name) {
self.emit("change", name || this.name)
}.bind(this)
this.trackGroup.forEach(function(unit) {
unit.on("change", noteChange)
})
}
util.inherits(TrackerGroup, EventEmitter)
TrackerGroup.prototype.completed = function () {
if (this.trackGroup.length==0) return 0
var valPerWeight = 1 / this.totalWeight
var completed = 0
this.trackGroup.forEach(function(T) {
completed += valPerWeight * T.weight * T.completed()
})
return completed
}
TrackerGroup.prototype.addUnit = function (unit, weight, noChange) {
unit.weight = weight || 1
this.totalWeight += unit.weight
this.trackGroup.push(unit)
unit.on("change", this.noteChange)
if (! noChange) this.emit("change", this.name)
return unit
}
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 () {
if (! this.trackGroup.length) { this.addUnit(new Tracker(), 1, true) }
var self = this
this.trackGroup.forEach(function(T) {
T.removeListener("change", self.noteChange)
T.finish()
})
this.emit("change", this.name)
}
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.trackGroup.forEach(function(T) {
if (T instanceof TrackerGroup) {
output += T.debug(depth + 1)
}
else {
output += indent + " " + T.name + ": " + T.completed() + "\n"
}
})
return output
}
var Tracker = exports.Tracker = function (name,todo) {
EventEmitter.call(this)
this.name = name
this.workDone = 0
this.workTodo = todo || 0
}
util.inherits(Tracker, EventEmitter)
Tracker.prototype.completed = function () {
return this.workTodo==0 ? 0 : this.workDone / this.workTodo
}
Tracker.prototype.addWork = function (work) {
this.workTodo += work
this.emit("change", this.name)
}
Tracker.prototype.completeWork = function (work) {
this.workDone += work
if (this.workDone > this.workTodo) this.workDone = this.workTodo
this.emit("change", this.name)
}
Tracker.prototype.finish = function () {
this.workTodo = this.workDone = 1
this.emit("change", this.name)
}
var TrackerStream = exports.TrackerStream = function (name, size, options) {
stream.Transform.call(this, options)
this.tracker = new Tracker(name, size)
this.name = name
var self = this
this.tracker.on("change", function (name) { self.emit("change", name) })
}
util.inherits(TrackerStream, stream.Transform)
TrackerStream.prototype._transform = function (data, encoding, cb) {
this.tracker.completeWork(data.length ? data.length : 1)
this.push(data)
cb()
}
TrackerStream.prototype._flush = function (cb) {
this.tracker.finish()
cb()
}
delegate(TrackerStream.prototype, "tracker")
.method("completed")
.method("addWork")