Class: Tahweel::CLI::ProgressRenderer

Inherits:
Object
  • Object
show all
Defined in:
lib/tahweel/cli/progress_renderer.rb

Overview

Handles thread-safe rendering of the progress dashboard for the CLI.

This class manages ANSI escape codes to create a dynamic, multi-line progress display showing global status and individual worker threads.

Constant Summary collapse

RESET =

ANSI Color Codes

"\e[0m"
BOLD =
"\e[1m"
RED =
"\e[31m"
GREEN =
"\e[32m"
YELLOW =
"\e[33m"
BLUE =
"\e[34m"
CYAN =
"\e[36m"
DIM =
"\e[2m"

Instance Method Summary collapse

Constructor Details

#initialize(total_files, concurrency) ⇒ ProgressRenderer

Initializes the renderer and prepares the terminal.

Parameters:

  • total_files (Integer)

    Total number of files to process.

  • concurrency (Integer)

    Number of concurrent worker threads.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/tahweel/cli/progress_renderer.rb', line 26

def initialize(total_files, concurrency) # rubocop:disable Metrics/MethodLength
  @total_files = total_files
  @concurrency = concurrency
  @processed_files = 0
  @worker_states = Array.new(concurrency)
  @mutex = Mutex.new
  @start_time = Time.now
  @running = true

  # Hide cursor
  $stdout.print "\e[?25l"

  # Reserve space for global status + 1 line per worker
  $stdout.print "\n" * (@concurrency + 1)

  # Trap Interrupt to restore cursor
  trap("INT") do
    @running = false
    $stdout.print "\e[?25h"
    exit
  end

  start_ticker
end

Instance Method Details

#finish_allObject

Restores the cursor and finalizes the display.



96
97
98
99
100
101
# File 'lib/tahweel/cli/progress_renderer.rb', line 96

def finish_all
  @running = false
  @ticker_thread&.join
  render # Ensure final state is drawn
  $stdout.print "\e[?25h"
end

#finish_file(worker_index) ⇒ Object

Marks a worker as finished with its current file.

Parameters:

  • worker_index (Integer)

    The index of the worker thread.



88
89
90
91
92
93
# File 'lib/tahweel/cli/progress_renderer.rb', line 88

def finish_file(worker_index)
  @mutex.synchronize do
    @processed_files += 1
    @worker_states[worker_index] = nil # Idle
  end
end

#start_file(worker_index, file) ⇒ Object

Updates the state for a worker starting a new file.

Parameters:

  • worker_index (Integer)

    The index of the worker thread (0-based).

  • file (String)

    The path of the file being started.



55
56
57
58
59
60
61
62
63
64
# File 'lib/tahweel/cli/progress_renderer.rb', line 55

def start_file(worker_index, file)
  @mutex.synchronize do
    @worker_states[worker_index] = {
      file:,
      stage: "Starting...",
      percentage: 0,
      details: ""
    }
  end
end

#update(worker_index, progress) ⇒ Object

Updates the progress for a specific worker.

Parameters:

  • worker_index (Integer)

    The index of the worker thread.

  • progress (Hash)

    The progress hash containing stage, percentage, etc.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/tahweel/cli/progress_renderer.rb', line 70

def update(worker_index, progress)
  @mutex.synchronize do
    return unless @worker_states[worker_index]

    stage = progress[:stage].to_s.capitalize
    percentage = progress[:percentage]
    current_page = progress[:current_page]
    total_pages = current_page + progress[:remaining_pages]

    @worker_states[worker_index][:stage] = stage
    @worker_states[worker_index][:percentage] = percentage
    @worker_states[worker_index][:details] = "(#{current_page}/#{total_pages})"
  end
end