Permalink
Browse files

Implement bubbling of events up the type hierarchy.

  • Loading branch information...
1 parent ec1b3bc commit 024de146ac6f26982415ac90708cae09c4a28aa0 @jcoglan committed Jun 18, 2009
Showing with 34 additions and 1 deletion.
  1. +16 −1 lib/eventful.rb
  2. +18 −0 test/test_eventful.rb
View
@@ -38,7 +38,7 @@ def add_observer(*args, &block)
def on(event, &block)
observer = add_observer do |*args|
- type, data = args.first, [self] + args[1..-1]
+ type, data = args[1], [args[0]] + args[2..-1]
if type == event
block ||= observer.to_proc
block.call(*data)
@@ -48,10 +48,25 @@ def on(event, &block)
def fire(*args)
return if defined?(@observer_state) and not @observer_state
+
+ receiver = (Hash === args.first) ? args.shift[:receiver] : self
+ args = [receiver] + args
+
changed(true)
notify_observers(*args)
changed(true)
+
+ args[0] = {:receiver => receiver}
+ self.class.ancestors.each do |klass|
+ klass.fire(*args) if Eventful === klass
+ end
end
+ def self.included(base)
+ base.extend(self)
+ end
+
+ extend(self)
+
end
View
@@ -1,5 +1,6 @@
require "test/unit"
require "eventful"
+require "set"
class Foo
include Eventful
@@ -14,6 +15,10 @@ def bump!(x = 1)
end
end
+class Bar
+ include Eventful
+end
+
class TestEventful < Test::Unit::TestCase
def test_named_events
ayes, noes = 0, 0
@@ -44,4 +49,17 @@ def test_chaining
assert_equal 3, f.count
end
+
+ def test_bubbling
+ bar1, bar2 = Bar.new, Bar.new
+ list = []
+ Bar.on(:aye) { |r| list << r }
+ Eventful.on(:aye) { |r| list << r }
+ Eventful.on(:noe) { |r| list << r }
+
+ bar1.fire(:aye)
+ assert_equal [bar1, bar1], list
+ bar2.fire(:noe)
+ assert_equal [bar1, bar1, bar2], list
+ end
end

0 comments on commit 024de14

Please sign in to comment.