class Thyme::Timer
The actual timer logic where you can pause, unpause, or stop one or more timers
Public Class Methods
new(config)
click to toggle source
# File lib/thyme/timer.rb, line 4 def initialize(config) @config = config @format = Format.new(config) @tmux = Tmux.new(config) end
Public Instance Methods
run()
click to toggle source
# File lib/thyme/timer.rb, line 14 def run # pause/unpause timer if it's already running send_signal('USR1') and return if File.exists?(Config::PID_FILE) begin File.open(Config::PID_FILE, "w") { |f| f.print(Process.pid) } @tmux.open if @config.repeat == 1 run_single else while @config.repeat_index <= @config.repeat || @config.repeat == 0 @config.break = false run_single if @config.repeat_index < @config.repeat || @config.repeat == 0 @config.break = true run_single end @config.repeat_index += 1 end end rescue Thyme::StopTimer # stop signal received ensure @tmux.close File.delete(Config::PID_FILE) if File.exists?(Config::PID_FILE) end end
stop()
click to toggle source
# File lib/thyme/timer.rb, line 10 def stop send_signal('TERM') end
Private Instance Methods
first?()
click to toggle source
# File lib/thyme/timer.rb, line 104 def first? @config.repeat == 1 || (!@config.break && @config.repeat_index == 1) end
last?()
click to toggle source
# File lib/thyme/timer.rb, line 108 def last? @config.repeat == @config.repeat_index end
run_single()
click to toggle source
TODO: refactor this method, too large!
# File lib/thyme/timer.rb, line 45 def run_single seconds_total = @config.break ? @config.timer_break : @config.timer seconds_left = seconds_total + 1 start_time = DateTime.now paused_time = nil min_length = (seconds_left / 60).floor.to_s.length started = false @bar ||= ENV['THYME_TEST'].nil? && !@config.daemon ? ProgressBar.create( title: @format.time_left(seconds_left-1, min_length), total: seconds_total, length: 50, format: '[%B] %t') : nil @bar.reset if @bar while seconds_left > 0 begin if paused_time sleep(@config.interval) next end seconds_passed = @format.seconds_since(start_time) seconds_left = [seconds_total - seconds_passed, 0].max title = @format.time_left(seconds_left, min_length) if @bar @bar.title = title if seconds_left == 0 && !last? @bar.progress = seconds_passed - 0.01 # prevent bar from finishing else @bar.progress = seconds_passed end end @tmux.tick(@format.tmux_color(seconds_left), title) unless started started = true @config.send_to_plugin(:before_all) if first? @config.send_to_plugin(:before) end @config.send_to_plugin(:tick, seconds_left) sleep(@config.interval) rescue SignalException => e if e.signm == 'SIGUSR1' && paused_time.nil? paused_time = DateTime.now elsif e.signm == 'SIGUSR1' delta = DateTime.now - paused_time start_time += delta paused_time = nil else puts "" @interrupted = true raise Thyme::StopTimer end end end ensure seconds_left = [seconds_total - @format.seconds_since(start_time), 0].max @config.send_to_plugin(:after, seconds_left) @config.send_to_plugin(:after_all) if @interrupted || last? end
send_signal(signal)
click to toggle source
Since timers can be daemonized, we'll use Unix signals to trigger events such as pause/unpause in a separate process.
# File lib/thyme/timer.rb, line 114 def send_signal(signal) pid = File.read(Config::PID_FILE).to_i Process.kill(signal, pid) if pid > 1 rescue Errno::ESRCH, Errno::ENOENT # process is already dead, cleanup files File.delete(Config::TMUX_FILE) if File.exists?(Config::TMUX_FILE) File.delete(Config::PID_FILE) if File.exists?(Config::PID_FILE) ensure true end