|
|
module EventDispatcher
def setup_listeners
@listeners = {}
@change = false
end
def register_listener(listener, event)
(@listeners[event] ||= []) << listener
end
def remove_listener(listener, event)
(@listeners[event] ||= []).delete listener
end
def remove_listeners(event)
@listeners[event] = []
end
def count_listeners(event)
(@listeners[event] ||= []).size
end
def changed?
@change
end
protected
def notify(event, arg)
return if not @change
if @listeners[event]
callback = ("update_at_" + event.to_s).to_sym
@listeners[event].each do |listener|
if listener.respond_to? callback
listener.send callback, arg
elsif listener.respond_to? :update
listener.update event, arg
end
end
end
@change = false
return nil
end
def changed
@change = true
end
end
class TestFactory
include EventDispatcher
def initialize
setup_listeners
end
def create_button(color)
changed
notify(:new_button, {:color => color})
end
def create_label(text)
changed
notify(:new_label, {:text => text})
end
end
class TestWidgetCounter
def initialize(widget_factory)
@counts = Hash.new(0)
widget_factory.register_listener(self, :new_button)
widget_factory.register_listener(self, :new_label)
end
def update(event, arg)
case event
when :new_label
puts "#{arg[:text]} label created."
end
end
def update_at_new_button(arg)
color = arg[:color]
@counts[color] += 1
puts "#{@counts[color]} #{color} button(s) created."
end
end
f = TestFactory.new
t = TestWidgetCounter.new(f)
f.create_button("red")
f.create_button("blue")
f.create_button("green")
f.create_label("name")
f.create_button("red")
f.remove_listener(t, :new_label)
f.create_label("cellphone")
f.create_button("blue")
|
Output:
|
|
1 red button(s) created.
1 blue button(s) created.
1 green button(s) created.
name label created.
2 red button(s) created.
2 blue button(s) created.
|
APE 0.50a 포팅할 때 사용하려고 만들었던 EventDispatcher
댓글을 달아 주세요