UNPKG

3.59 kBJavaScriptView Raw
1"use strict"
2var stream = require("readable-stream");
3var EventEmitter = require("events").EventEmitter
4var util = require("util")
5var delegate = require("delegates")
6
7var TrackerGroup = exports.TrackerGroup = function (name) {
8 EventEmitter.call(this)
9 this.name = name
10 this.trackGroup = []
11 var self = this
12 this.totalWeight = 0
13 var noteChange = this.noteChange = function (name) {
14 self.emit("change", name || this.name)
15 }.bind(this)
16 this.trackGroup.forEach(function(unit) {
17 unit.on("change", noteChange)
18 })
19}
20util.inherits(TrackerGroup, EventEmitter)
21
22TrackerGroup.prototype.completed = function () {
23 if (this.trackGroup.length==0) return 0
24 var valPerWeight = 1 / this.totalWeight
25 var completed = 0
26 this.trackGroup.forEach(function(T) {
27 completed += valPerWeight * T.weight * T.completed()
28 })
29 return completed
30}
31
32TrackerGroup.prototype.addUnit = function (unit, weight, noChange) {
33 unit.weight = weight || 1
34 this.totalWeight += unit.weight
35 this.trackGroup.push(unit)
36 unit.on("change", this.noteChange)
37 if (! noChange) this.emit("change", this.name)
38 return unit
39}
40
41TrackerGroup.prototype.newGroup = function (name, weight) {
42 return this.addUnit(new TrackerGroup(name), weight)
43}
44
45TrackerGroup.prototype.newItem = function (name, todo, weight) {
46 return this.addUnit(new Tracker(name, todo), weight)
47}
48
49TrackerGroup.prototype.newStream = function (name, todo, weight) {
50 return this.addUnit(new TrackerStream(name, todo), weight)
51}
52
53TrackerGroup.prototype.finish = function () {
54 if (! this.trackGroup.length) { this.addUnit(new Tracker(), 1, true) }
55 var self = this
56 this.trackGroup.forEach(function(T) {
57 T.removeListener("change", self.noteChange)
58 T.finish()
59 })
60 this.emit("change", this.name)
61}
62
63var buffer = " "
64TrackerGroup.prototype.debug = function (depth) {
65 depth = depth || 0
66 var indent = depth ? buffer.substr(0,depth) : ""
67 var output = indent + (this.name||"top") + ": " + this.completed() + "\n"
68 this.trackGroup.forEach(function(T) {
69 if (T instanceof TrackerGroup) {
70 output += T.debug(depth + 1)
71 }
72 else {
73 output += indent + " " + T.name + ": " + T.completed() + "\n"
74 }
75 })
76 return output
77}
78
79var Tracker = exports.Tracker = function (name,todo) {
80 EventEmitter.call(this)
81 this.name = name
82 this.workDone = 0
83 this.workTodo = todo || 0
84}
85util.inherits(Tracker, EventEmitter)
86
87Tracker.prototype.completed = function () {
88 return this.workTodo==0 ? 0 : this.workDone / this.workTodo
89}
90
91Tracker.prototype.addWork = function (work) {
92 this.workTodo += work
93 this.emit("change", this.name)
94}
95
96Tracker.prototype.completeWork = function (work) {
97 this.workDone += work
98 if (this.workDone > this.workTodo) this.workDone = this.workTodo
99 this.emit("change", this.name)
100}
101
102Tracker.prototype.finish = function () {
103 this.workTodo = this.workDone = 1
104 this.emit("change", this.name)
105}
106
107
108var TrackerStream = exports.TrackerStream = function (name, size, options) {
109 stream.Transform.call(this, options)
110 this.tracker = new Tracker(name, size)
111 this.name = name
112 var self = this
113 this.tracker.on("change", function (name) { self.emit("change", name) })
114}
115util.inherits(TrackerStream, stream.Transform)
116
117TrackerStream.prototype._transform = function (data, encoding, cb) {
118 this.tracker.completeWork(data.length ? data.length : 1)
119 this.push(data)
120 cb()
121}
122
123TrackerStream.prototype._flush = function (cb) {
124 this.tracker.finish()
125 cb()
126}
127
128delegate(TrackerStream.prototype, "tracker")
129 .method("completed")
130 .method("addWork")