| ... | @@ -68,6 +68,7 @@ pub const Node = struct { | ... | @@ -68,6 +68,7 @@ pub const Node = struct { |
| 68 | context: *Progress, | 68 | context: *Progress, |
| 69 | parent: ?*Node, | 69 | parent: ?*Node, |
| 70 | name: []const u8, | 70 | name: []const u8, |
| | 71 | unit: []const u8 = "", |
| 71 | /// Must be handled atomically to be thread-safe. | 72 | /// Must be handled atomically to be thread-safe. |
| 72 | recently_updated_child: ?*Node = null, | 73 | recently_updated_child: ?*Node = null, |
| 73 | /// Must be handled atomically to be thread-safe. 0 means null. | 74 | /// Must be handled atomically to be thread-safe. 0 means null. |
| ... | @@ -141,6 +142,21 @@ pub const Node = struct { | ... | @@ -141,6 +142,21 @@ pub const Node = struct { |
| 141 | } | 142 | } |
| 142 | } | 143 | } |
| 143 | | 144 | |
| | 145 | /// Thread-safe. |
| | 146 | pub fn setUnit(self: *Node, unit: []const u8) void { |
| | 147 | const progress = self.context; |
| | 148 | progress.update_mutex.lock(); |
| | 149 | defer progress.update_mutex.unlock(); |
| | 150 | self.unit = unit; |
| | 151 | if (self.parent) |parent| { |
| | 152 | @atomicStore(?*Node, &parent.recently_updated_child, self, .Release); |
| | 153 | if (parent.parent) |grand_parent| { |
| | 154 | @atomicStore(?*Node, &grand_parent.recently_updated_child, parent, .Release); |
| | 155 | } |
| | 156 | if (progress.timer) |*timer| progress.maybeRefreshWithHeldLock(timer); |
| | 157 | } |
| | 158 | } |
| | 159 | |
| 144 | /// Thread-safe. 0 means unknown. | 160 | /// Thread-safe. 0 means unknown. |
| 145 | pub fn setEstimatedTotalItems(self: *Node, count: usize) void { | 161 | pub fn setEstimatedTotalItems(self: *Node, count: usize) void { |
| 146 | @atomicStore(usize, &self.unprotected_estimated_total_items, count, .Monotonic); | 162 | @atomicStore(usize, &self.unprotected_estimated_total_items, count, .Monotonic); |
| ... | @@ -307,11 +323,11 @@ fn refreshWithHeldLock(self: *Progress) void { | ... | @@ -307,11 +323,11 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 307 | } | 323 | } |
| 308 | if (eti > 0) { | 324 | if (eti > 0) { |
| 309 | if (need_ellipse) self.bufWrite(&end, " ", .{}); | 325 | if (need_ellipse) self.bufWrite(&end, " ", .{}); |
| 310 | self.bufWrite(&end, "[{d}/{d}] ", .{ current_item, eti }); | 326 | self.bufWrite(&end, "[{d}/{d}{s}] ", .{ current_item, eti, node.unit }); |
| 311 | need_ellipse = false; | 327 | need_ellipse = false; |
| 312 | } else if (completed_items != 0) { | 328 | } else if (completed_items != 0) { |
| 313 | if (need_ellipse) self.bufWrite(&end, " ", .{}); | 329 | if (need_ellipse) self.bufWrite(&end, " ", .{}); |
| 314 | self.bufWrite(&end, "[{d}] ", .{current_item}); | 330 | self.bufWrite(&end, "[{d}{s}] ", .{ current_item, node.unit }); |
| 315 | need_ellipse = false; | 331 | need_ellipse = false; |
| 316 | } | 332 | } |
| 317 | } | 333 | } |