Class: Timer

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

Overview

Ruby license. Copyright ©2004-2008 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.

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.



30
31
32
33
# File 'lib/timer.rb', line 30

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

Instance Attribute Details

#periodObject

Returns the value of attribute period.



35
36
37
# File 'lib/timer.rb', line 35

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.



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/timer.rb', line 15

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.



44
45
46
# File 'lib/timer.rb', line 44

def elapsed
  Time.now - @time_start
end

#if_readyObject

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



59
60
61
62
63
64
65
66
# File 'lib/timer.rb', line 59

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).



39
40
41
# File 'lib/timer.rb', line 39

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.



50
51
52
53
54
55
# File 'lib/timer.rb', line 50

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