Class: Tapsoob::Progress::MultiBar

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

Overview

MultiBar 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) ⇒ MultiBar

Returns a new instance of MultiBar.



8
9
10
11
12
13
14
15
16
17
# File 'lib/tapsoob/progress/multi_bar.rb', line 8

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



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

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 = ThreadSafeBar.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



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

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



45
46
47
# File 'lib/tapsoob/progress/multi_bar.rb', line 45

def max_title_width
  @max_title_width
end

#stopObject

Stop all progress bars and keep them visible



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

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



50
51
52
53
54
55
56
57
58
# File 'lib/tapsoob/progress/multi_bar.rb', line 50

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

    @last_update = Time.now
    redraw_all
  end
end