3
# Author:: Nathaniel Talbott.
4
# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5
# License:: Ruby license.
7
require 'test/unit/util/procwrapper'
13
# This is a utility class that allows anything mixing
14
# it in to notify a set of listeners about interesting
17
# We use this for defaults since nil might mean something
18
NOTHING = "NOTHING/#{__id__}"
20
# Adds the passed proc as a listener on the
21
# channel indicated by channel_name. listener_key
22
# is used to remove the listener later; if none is
23
# specified, the proc itself is used.
25
# Whatever is used as the listener_key is
26
# returned, making it very easy to use the proc
27
# itself as the listener_key:
29
# listener = add_listener("Channel") { ... }
30
# remove_listener("Channel", listener)
31
def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value
33
raise ArgumentError.new("No callback was passed as a listener")
37
if (listener_key == NOTHING)
38
listener_key = listener
39
key = ProcWrapper.new(listener)
42
channels[channel_name] ||= {}
43
channels[channel_name][key] = listener
47
# Removes the listener indicated by listener_key
48
# from the channel indicated by
49
# channel_name. Returns the registered proc, or
50
# nil if none was found.
51
def remove_listener(channel_name, listener_key)
52
channel = channels[channel_name]
53
return nil unless (channel)
55
if (listener_key.instance_of?(Proc))
56
key = ProcWrapper.new(listener_key)
58
if (channel.has_key?(key))
59
return channel.delete(key)
64
# Calls all the procs registered on the channel
65
# indicated by channel_name. If value is
66
# specified, it is passed in to the procs,
67
# otherwise they are called with no arguments.
71
# Perhaps this should be private? Would it ever
72
# make sense for an external class to call this
74
def notify_listeners(channel_name, *arguments)
75
channel = channels[channel_name]
76
return 0 unless (channel)
77
listeners = channel.values
78
listeners.each { |listener| listener.call(*arguments) }