Skip to content

Commit

Permalink
Add: Ability To Allow Different Projectors To Be Used For Time Estimates
Browse files Browse the repository at this point in the history
Why This Change Is Necessary
========================================================================

The current projector we've had in the code for over a decade now has
served us well, but there has been a desire to have some different types
of projectors (eg windowed by item count or by time).  This was
previously difficult to do but with this change we should be able to
allow the user to swap different ones out fairly easily.

What These Changes Do To Address the Issue
========================================================================

Add a new `Projector` class that manages all other projectors.

Side Effects Caused By This Change
========================================================================

None expected.
  • Loading branch information
jfelchner committed Mar 4, 2023
1 parent 616a7b3 commit e1e7f0c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
10 changes: 7 additions & 3 deletions lib/ruby-progressbar/base.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require 'forwardable'

require 'ruby-progressbar/calculators/smoothed_average'
require 'ruby-progressbar/components/bar'
require 'ruby-progressbar/components/percentage'
require 'ruby-progressbar/components/rate'
Expand All @@ -11,6 +10,7 @@
require 'ruby-progressbar/outputs/non_tty'
require 'ruby-progressbar/outputs/tty'
require 'ruby-progressbar/progress'
require 'ruby-progressbar/projector'
require 'ruby-progressbar/timer'

class ProgressBar
Expand Down Expand Up @@ -43,12 +43,14 @@ class Base
:total

def initialize(options = {}) # rubocop:disable Metrics/AbcSize
options[:projector] ||= {}

self.autostart = options.fetch(:autostart, true)
self.autofinish = options.fetch(:autofinish, true)
self.finished = false

self.timer = Timer.new(options)
projector_opts = if options[:projector]
projector_opts = if options[:projector].any?
options[:projector]
elsif options[:smoothing]
warn SMOOTHING_DEPRECATION_WARNING
Expand All @@ -61,7 +63,9 @@ def initialize(options = {}) # rubocop:disable Metrics/AbcSize
else
{}
end
self.projector = Calculators::SmoothedAverage.new(projector_opts)
self.projector = Projector.
from_type(options[:projector][:type]).
new(projector_opts)
self.progressable = Progress.new(options)

options = options.merge(:progress => progressable,
Expand Down
14 changes: 14 additions & 0 deletions lib/ruby-progressbar/projector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'ruby-progressbar/calculators/smoothed_average'

class ProgressBar
class Projector
DEFAULT_PROJECTOR = ProgressBar::Calculators::SmoothedAverage
NAME_TO_PROJECTOR_MAP = {
'smoothed' => ProgressBar::Calculators::SmoothedAverage
}.freeze

def self.from_type(name)
NAME_TO_PROJECTOR_MAP.fetch(name, DEFAULT_PROJECTOR)
end
end
end
20 changes: 20 additions & 0 deletions spec/lib/ruby-progressbar/projector_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'spec_helper'
require 'ruby-progressbar/projector'

class ProgressBar
describe Projector do
describe '.from_type' do
it 'has a default projector' do
projector = Projector.from_type(nil)

expect(projector).to be ProgressBar::Calculators::SmoothedAverage
end

it 'can return a specific projector' do
projector = Projector.from_type('smoothed')

expect(projector).to be ProgressBar::Calculators::SmoothedAverage
end
end
end
end

0 comments on commit e1e7f0c

Please sign in to comment.