Class: MultiProgressBar

Inherits:
Object
  • Object
show all
Defined in:
lib/tapsoob/multi_progress_bar.rb

Overview

MultiProgressBar manages multiple progress bars in parallel Each bar gets its own line in the terminal

Instance Method Summary collapse

Constructor Details

#initialize(max_bars = 4) ⇒ MultiProgressBar

Returns a new instance of MultiProgressBar.



7
8
9
10
11
12
13
14
15
16
# File 'lib/tapsoob/multi_progress_bar.rb', line 7

def initialize(max_bars = 4)
  @max_bars = max_bars
  @bars = []
  @mutex = Mutex.new
  @active = true
  @out = STDOUT
  @last_update = Time.now
  @reserved_lines = 0  # Track how many lines we've actually reserved
  @max_title_width = 14  # Minimum width, will grow with longer titles
end

Instance Method Details

#create_bar(title, total) ⇒ Object

Create a new progress bar and return it



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/tapsoob/multi_progress_bar.rb', line 19

def create_bar(title, total)
  @mutex.synchronize do
    # 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

    bar = ThreadSafeProgressBar.new(title, total, self)

    # Reserve a line for this new bar during active updates
    # Cap at 2 * max_bars to show active workers + some recent finished bars
    if @reserved_lines < @max_bars * 2
      @out.print "\n"
      @out.flush
      @reserved_lines += 1
    end

    @bars << bar
    bar
  end
end

#finish_bar(bar) ⇒ Object

Finish a specific bar - mark it as completed



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/tapsoob/multi_progress_bar.rb', line 60

def finish_bar(bar)
  @mutex.synchronize do
    return unless @active

    bar.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

#max_title_widthObject

Get the current maximum title width for alignment Note: Always called from within synchronized methods, so no mutex needed



44
45
46
# File 'lib/tapsoob/multi_progress_bar.rb', line 44

def max_title_width
  @max_title_width
end

#stopObject

Stop all progress bars and keep them visible



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/tapsoob/multi_progress_bar.rb', line 76

def stop
  @mutex.synchronize do
    @active = false

    # Final cleanup: remove any duplicate titles (keep the last occurrence of each unique title)
    @bars = @bars.reverse.uniq { |bar| bar.title }.reverse

    # Final redraw to show completed state (skip active check)
    redraw_all(true)
    # Move cursor past all bars
    @out.print "\n"
    @out.flush
  end
end

#updateObject

Called by individual bars when they update



49
50
51
52
53
54
55
56
57
# File 'lib/tapsoob/multi_progress_bar.rb', line 49

def update
  @mutex.synchronize do
    return unless @active
    return unless should_redraw?

    @last_update = Time.now
    redraw_all
  end
end