Class: Tapsoob::Progress::MultiBar
- Inherits:
-
Object
- Object
- Tapsoob::Progress::MultiBar
- Defined in:
- lib/tapsoob/progress/multi_bar.rb
Overview
MultiBar manages multiple progress bars in parallel with a clean interface:
-
N progress bar lines (constantly updating)
-
1 separator line
-
1 info message line (shows latest INFO, gets replaced)
Instance Method Summary collapse
-
#create_bar(title, total) ⇒ Object
Create a new progress bar and return it.
-
#finish_bar(bar) ⇒ Object
Finish a specific bar - mark it as completed.
-
#get_terminal_width ⇒ Object
Get terminal width, default to 160 if can’t detect.
-
#initialize(max_bars = 4) ⇒ MultiBar
constructor
A new instance of MultiBar.
-
#max_title_width ⇒ Object
Get the current maximum title width for alignment Note: Always called from within synchronized methods, so no mutex needed.
-
#set_info(message) ⇒ Object
Update the info message line (called from outside for INFO logs).
-
#stop ⇒ Object
Stop all progress bars and clear them from display.
-
#update ⇒ Object
Called by individual bars when they update.
Constructor Details
#initialize(max_bars = 4) ⇒ MultiBar
Returns a new instance of MultiBar.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 10 def initialize( = 4) @max_bars = @bars = [] @mutex = Mutex.new @active = true @out = STDOUT @last_update = Time.now @max_title_width = 14 # Minimum width, will grow with longer titles @initialized = false @total_lines = 0 # Total lines: max_bars + separator + info line @info_message = "" # Current info message to display @start_time = Time.now # Track total elapsed time @terminal_width = get_terminal_width end |
Instance Method Details
#create_bar(title, total) ⇒ Object
Create a new progress bar and return it
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 34 def (title, total) @mutex.synchronize do # Initialize display area on first bar creation unless @initialized @total_lines = @max_bars + 2 # bars + separator + info line @total_lines.times { @out.print "\n" } @out.flush @initialized = true end # Remove any existing bar with the same title to prevent duplicates @bars.reject! { |b| b.title == title } # Update max title width to accommodate longer titles @max_title_width = [@max_title_width, title.length].max = ThreadSafeBar.new(title, total, self) @bars << end end |
#finish_bar(bar) ⇒ Object
Finish a specific bar - mark it as completed
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 83 def () @mutex.synchronize do return unless @active .mark_finished # Respect throttle when finishing to avoid spamming redraws if should_redraw? @last_update = Time.now redraw_all end # If throttled, the next regular update will show the finished state end end |
#get_terminal_width ⇒ Object
Get terminal width, default to 160 if can’t detect
26 27 28 29 30 31 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 26 def get_terminal_width require 'io/console' IO.console&.winsize&.[](1) || 160 rescue 160 end |
#max_title_width ⇒ Object
Get the current maximum title width for alignment Note: Always called from within synchronized methods, so no mutex needed
67 68 69 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 67 def max_title_width @max_title_width end |
#set_info(message) ⇒ Object
Update the info message line (called from outside for INFO logs)
57 58 59 60 61 62 63 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 57 def set_info() @mutex.synchronize do return unless @active @info_message = redraw_all if @initialized end end |
#stop ⇒ Object
Stop all progress bars and clear them from display
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 99 def stop @mutex.synchronize do return unless @active # Already stopped @active = false # Clear all lines (progress bars + separator + info line) if @total_lines > 0 && @initialized # Move cursor up to first line @out.print "\e[#{@total_lines}A" # Clear each line @total_lines.times do @out.print "\r\e[2K\n" end # Move cursor back to start @out.print "\e[#{@total_lines}A\r" end @out.flush end end |
#update ⇒ Object
Called by individual bars when they update
72 73 74 75 76 77 78 79 80 |
# File 'lib/tapsoob/progress/multi_bar.rb', line 72 def update @mutex.synchronize do return unless @active return unless should_redraw? @last_update = Time.now redraw_all end end |