Skip to content
Browse files

CallbackRegistry stores Arrays of callbacks for a given key

  • Loading branch information...
1 parent 258a4a4 commit 2758d1611c39dec9ea52788818566d4e39abf286 @gsterndale committed
Showing with 80 additions and 27 deletions.
  1. +24 −0 lib/reactorb/callback_registry.rb
  2. +15 −26 lib/reactorb/reactor.rb
  3. +30 −0 spec/callback_registry_spec.rb
  4. +11 −1 spec/reactor_spec.rb
View
24 lib/reactorb/callback_registry.rb
@@ -0,0 +1,24 @@
+class CallbackRegistry < Hash
+
+ def initialize(*args, &blk)
+ blk ||= proc {|h,k| h[k] = [] }
+ super *args, &blk
+ end
+
+ def first_key
+ self.keys.sort.first
+ end
+
+ def shift
+ if key = self.first_key
+ self.delete key
+ end
+ end
+
+ def shift_pair
+ if key = self.first_key
+ [ key, self.delete(key) ]
+ end
+ end
+
+end
View
41 lib/reactorb/reactor.rb
@@ -1,10 +1,12 @@
+require 'reactorb/callback_registry'
+
class Reactor
attr_reader :timers
def initialize()
@running = false
- @timers = ShiftableHash.new
+ @timers = CallbackRegistry.new
end
def running?
@@ -24,22 +26,21 @@ def stop
@running = false
end
- def first_tick()
- end
-
- def tick()
- self.call_timers()
+ def tick
+ @tick_time = self.class.now.to_i
+ self.call_timers
+ @tick_time = nil
end
def at(time_or_number, *args, &block)
- @timers[time_or_number.to_i] = [block, args]
+ @timers[time_or_number.to_i] << [block, args]
end
def call_timers
- now = self.class.now
- while @timers.any? && @timers.first_key <= now
- block, args = @timers.shift
- block.call(*args)
+ while @timers.any? && @timers.first_key <= self.tick_time
+ @timers.shift.each do |block, args|
+ block.call(*args)
+ end
end
end
@@ -51,20 +52,8 @@ def self.now
Time.now.to_i
end
-end
+protected
+
+ attr_reader :tick_time
-class ShiftableHash < Hash
- def first_key
- self.keys.sort.first
- end
- def shift
- if key = self.first_key
- self.delete key
- end
- end
- def shift_pair
- if key = self.first_key
- [ key, self.delete(key) ]
- end
- end
end
View
30 spec/callback_registry_spec.rb
@@ -0,0 +1,30 @@
+require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+
+describe CallbackRegistry, ".new" do
+ it "values should default to an empty array" do
+ subject["foo"].should == []
+ end
+end
+
+describe CallbackRegistry, "with keys" do
+ let(:key1) { 1 }
+ let(:key2) { 2 }
+ let(:key3) { 3 }
+ let(:value1) { 'won' }
+ let(:value2) { 'too' }
+ let(:value3) { 'tree' }
+ subject do
+ CallbackRegistry.new.tap do |cr|
+ cr[key3] << value3
+ cr[key1] << value1
+ cr[key2] << value2
+ end
+ end
+ its(:first_key) { should be key1 }
+ its(:shift) { should == [value1] }
+ its(:shift_pair) { should == [key1, [value1]] }
+ describe "#shift'ed" do
+ before { subject.shift }
+ its(:first_key) { should be key2 }
+ end
+end
View
12 spec/reactor_spec.rb
@@ -38,6 +38,16 @@
tally.should == 2
end
end
+ context "with time based events added for the same in the past" do
+ it "should fire events" do
+ tally = 0
+ subject.run do |r|
+ r.at(1){ tally += 1}
+ r.at(1){ tally += 1}
+ end
+ tally.should == 2
+ end
+ end
context "stopped with time based events added in the past" do
it "should fire events" do
tally = 0
@@ -82,7 +92,7 @@
end
it { should_not be_empty }
it "should have block and args as first value in timers" do
- subject.timers.shift.should == [blk, []]
+ subject.timers.shift.should include [blk, []]
end
end
end

0 comments on commit 2758d16

Please sign in to comment.
Something went wrong with that request. Please try again.