source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/test/unit/util/observable.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 2.8 KB
Line 
1#--
2#
3# Author:: Nathaniel Talbott.
4# Copyright:: Copyright (c) 2000-2002 Nathaniel Talbott. All rights reserved.
5# License:: Ruby license.
6
7require 'test/unit/util/procwrapper'
8
9module Test
10 module Unit
11 module Util
12
13 # This is a utility class that allows anything mixing
14 # it in to notify a set of listeners about interesting
15 # events.
16 module Observable
17 # We use this for defaults since nil might mean something
18 NOTHING = "NOTHING/#{__id__}"
19
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.
24 #
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:
28 #
29 # listener = add_listener("Channel") { ... }
30 # remove_listener("Channel", listener)
31 def add_listener(channel_name, listener_key=NOTHING, &listener) # :yields: value
32 unless(block_given?)
33 raise ArgumentError.new("No callback was passed as a listener")
34 end
35
36 key = listener_key
37 if (listener_key == NOTHING)
38 listener_key = listener
39 key = ProcWrapper.new(listener)
40 end
41
42 channels[channel_name] ||= {}
43 channels[channel_name][key] = listener
44 return listener_key
45 end
46
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)
54 key = listener_key
55 if (listener_key.instance_of?(Proc))
56 key = ProcWrapper.new(listener_key)
57 end
58 if (channel.has_key?(key))
59 return channel.delete(key)
60 end
61 return nil
62 end
63
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.
68 #
69 #--
70 #
71 # Perhaps this should be private? Would it ever
72 # make sense for an external class to call this
73 # method directly?
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) }
79 return listeners.size
80 end
81
82 private
83 def channels
84 @channels ||= {}
85 return @channels
86 end
87 end
88 end
89 end
90end
Note: See TracBrowser for help on using the repository browser.