Class: Timer

Inherits:
Object
  • Object
show all
Defined in:
lib/tkar/timer.rb

Overview

Ruby license. Copyright ©2004-2009 Joel VanderWerf. Contact [email protected].

A lightweight, non-drifting, self-correcting timer. Average error is bounded as long as, on average, there is enough time to complete the work done, and the timer is checked often enough. It is lightweight in the sense that no threads are created. Can be used either as an internal iterator (Timer.every) or as an external iterator (Timer.new). Obviously, the GC can cause a temporary slippage.

Simple usage:

require 'timer'

Timer.every(0.1, 0.5) { |elapsed| puts elapsed }

timer = Timer.new(0.1)
5.times do
  puts timer.elapsed
  timer.wait
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(period = 1) ⇒ Timer

Make a Timer that can be checked when needed, using #wait or #if_ready. The advantage over Timer.every is that the timer can be checked on separate passes through a loop.



42
43
44
45
# File 'lib/tkar/timer.rb', line 42

def initialize(period = 1)
  @period = period
  restart
end

Instance Attribute Details

#periodObject

Returns the value of attribute period.



47
48
49
# File 'lib/tkar/timer.rb', line 47

def period
  @period
end

Class Method Details

.every(period, expire = nil) ⇒ Object

Yields to the supplied block every period seconds. The value yielded is the total elapsed time (an instance of Time). If expire is given, then #every returns after that amount of elapsed time.



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/tkar/timer.rb', line 27

def Timer.every(period, expire = nil)
  target = time_start = Time.now
  loop do
    elapsed = Time.now - time_start
    break if expire and elapsed > expire
    yield elapsed
    target += period
    error = target - Time.now
    sleep error if error > 0
  end
end

Instance Method Details

#elapsedObject

Time on timer since instantiation or last #restart.



56
57
58
# File 'lib/tkar/timer.rb', line 56

def elapsed
  Time.now - @time_start
end

#if_readyObject

Yield to the block if no time remains in cycle. Otherwise, return immediately to caller



71
72
73
74
75
76
77
78
# File 'lib/tkar/timer.rb', line 71

def if_ready
  error = @target + @period - Time.now
  if error <= 0
    @target += @period
    elapsed = Time.now - @time_start
    yield elapsed
  end
end

#restartObject

Call this to restart the timer after a period of inactivity (e.g., the user hits the pause button, and then hits the go button).



51
52
53
# File 'lib/tkar/timer.rb', line 51

def restart
  @target = @time_start = Time.now
end

#wait(per = nil) ⇒ Object

Wait for the next cycle, if time remains in the current cycle. Otherwise, return immediately to caller.



62
63
64
65
66
67
# File 'lib/tkar/timer.rb', line 62

def wait(per = nil)
  @target += per || @period
  error = @target - Time.now
  sleep error if error > 0
  true
end