Skip to content

Commit

Permalink
Change to automatically spin top level spinner under multi spinner
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Sep 11, 2017
1 parent dcddf6c commit a0e0853
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
41 changes: 35 additions & 6 deletions lib/tty/spinner/multi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def initialize(*args)
@callbacks = {
success: [],
error: [],
done: []
done: [],
spin: []
}
end

Expand Down Expand Up @@ -122,7 +123,6 @@ def top_spinner
def auto_spin
raise "No top level spinner" if @top_spinner.nil?

@top_spinner.auto_spin
jobs = []
@spinners.each do |spinner|
if spinner.job?
Expand All @@ -139,7 +139,9 @@ def auto_spin
def spin
raise "No top level spinner" if @top_spinner.nil?

@top_spinner.spin
synchronize do
throttle { @top_spinner.spin }
end
end

# Pause all spinners
Expand Down Expand Up @@ -239,14 +241,30 @@ def error
def on(key, &callback)
unless @callbacks.key?(key)
raise ArgumentError, "The event #{key} does not exist. "\
" Use :success, :error, or :done instead"
' Use :spin, :success, :error, or :done instead'
end
@callbacks[key] << callback
self
end

private

# Check if this spinner should revolve to keep constant speed
# matching top spinner interval
#
# @api private
def throttle
sleep_time = 1.0 / @top_spinner.interval
if @last_spin_at && Time.now - @last_spin_at < sleep_time
return
end
yield if block_given?
@last_spin_at = Time.now
end

# Fire an event
#
# @api private
def emit(key, *args)
@callbacks[key].each do |block|
block.call(*args)
Expand All @@ -260,11 +278,22 @@ def emit(key, *args)
#
# @api private
def observe(spinner)
spinner.on(:success, &success_handler)
spinner.on(:spin, &spin_handler)
.on(:success, &success_handler)
.on(:error, &error_handler)
.on(:done, &done_handler)
end

# Handle spin event
#
# @api private
def spin_handler
proc do
spin if @top_spinner
emit(:spin)
end
end

# Handle the success state
#
# @api private
Expand Down Expand Up @@ -295,7 +324,7 @@ def error_handler
def done_handler
proc do
if done?
@top_spinner.stop if @top_spinner
@top_spinner.stop if @top_spinner && !error? && !success?
emit(:done)
end
end
Expand Down
6 changes: 3 additions & 3 deletions spec/unit/multi/auto_spin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
RSpec.describe TTY::Spinner::Multi, '#auto_spin' do
let(:output) { StringIO.new('', 'w+') }

it "auto spins top level spinner" do
it "doesn't auto spin top level spinner" do
spinners = TTY::Spinner::Multi.new("Top level spinner", output: output)
allow_any_instance_of(TTY::Spinner).to receive(:auto_spin)
allow(spinners.top_spinner).to receive(:auto_spin)

spinners.auto_spin

expect(spinners.top_spinner).to have_received(:auto_spin).once
expect(spinners.top_spinner).to_not have_received(:auto_spin)
end

it "raises an exception when called without a top spinner" do
Expand Down

0 comments on commit a0e0853

Please sign in to comment.