UNPKG

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