Skip to content

Commit

Permalink
Merge pull request #17 from celluloid/use-floats-internally
Browse files Browse the repository at this point in the history
Use floats internally
  • Loading branch information
tarcieri committed Nov 30, 2013
2 parents 18a1846 + ad2245a commit be26eed
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
24 changes: 12 additions & 12 deletions lib/timers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ def wait
def wait_interval(now = Time.now)
timer = @timers.first
return unless timer
interval = timer.time - now
interval = timer.offset - Float(now)
interval > 0 ? interval : 0
end

# Fire all timers that are ready
def fire(now = Time.now)
time = now + 0.001 # Fudge 1ms in case of clock imprecision
while (timer = @timers.first) && (time >= timer.time)
time = Float(now) + 0.001 # Fudge 1ms in case of clock imprecision
while (timer = @timers.first) && (time >= timer.offset)
@timers.delete timer
timer.fire(now)
end
Expand Down Expand Up @@ -93,18 +93,18 @@ def delay(seconds)
# An individual timer set to fire a given proc at a given time
class Timer
include Comparable
attr_reader :interval, :time, :recurring
attr_reader :interval, :offset, :recurring

def initialize(timers, interval, recurring = false, &block)
@timers, @interval, @recurring = timers, interval, recurring
@block = block
@time = nil
@block = block
@offset = nil

reset
end

def <=>(other)
@time <=> other.time
@offset <=> other.offset
end

# Cancel this timer
Expand All @@ -115,14 +115,14 @@ def cancel
# Extend this timer
def delay(seconds)
@timers.delete self
@time += seconds
@offset += seconds
@timers.add self
end

# Reset this timer
def reset(now = Time.now)
@timers.cancel self if @time
@time = now + @interval
@offset = Float(now) + @interval
@timers.add self
end

Expand All @@ -148,9 +148,9 @@ def inspect
str = "#<Timers::Timer:#{object_id.to_s(16)} "
now = Time.now

if @time
if @time >= now
str << "fires in #{@time - now} seconds"
if @offset
if @offset >= now
str << "fires in #{@offset - now} seconds"
else
str << "fired #{now - @time} seconds ago"
end
Expand Down
13 changes: 10 additions & 3 deletions spec/timers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
expect(result).to eq [:one, :two, :three]
end

it "raises TypeError if given an invalid time" do
expect do
subject.after(nil) { nil }
end.to raise_exception(TypeError)
end

describe "recurring timers" do
it "continues to fire the timers at each interval" do
result = []
Expand Down Expand Up @@ -121,7 +127,7 @@
it "adds appropriate amount of time to timer" do
timer = subject.after(10)
timer.delay(5)
expect(timer.time - Time.now).to be_within(Q).of(15)
expect(timer.offset - Float(Time.now)).to be_within(Q).of(15)
end
end

Expand All @@ -130,10 +136,11 @@
timer = subject.after(10)
timer2 = subject.after(20)
subject.delay(5)
expect(timer.time - Time.now).to be_within(Q).of(15)
expect(timer2.time - Time.now).to be_within(Q).of(25)
expect(timer.offset - Float(Time.now)).to be_within(Q).of(15)
expect(timer2.offset - Float(Time.now)).to be_within(Q).of(25)
end
end

describe "on delaying a timer" do
it "fires timers in the correct order" do
result = []
Expand Down

0 comments on commit be26eed

Please sign in to comment.