lib/openwfe/util/observable.rb in openwferu-0.9.10.653 vs lib/openwfe/util/observable.rb in openwferu-0.9.11

- old
+ new

@@ -51,32 +51,89 @@ # # Observers will register themselves to the Observable via # this method. # - def add_observer (channel, &callback) - (@observers[channel] ||= []) << callback + # An observer is an instance which responds to call(channel, *args) + # + def add_observer (channel, observer=nil, &callback) + observer = callback unless observer + (@observers[channel] ||= []) << observer end + # + # Removes an observer (this obviously doesn't work well when + # the actual observer is a block). + # If a channel is given, the observer will only get removed when + # registered for that channel. + # + def remove_observer (observer, channel=nil) + + channels = if channel + [ channel ] + else + @observers.keys + end + + channels.each do |c| + do_remove_observer observer, c + end + end + protected # # Observable classes do call this method to notify their - # observers + # observers. # + # Returns true if there was an observer registered. + # def onotify (channel, *args) - do_notify(channel, channel, *args) + do_notify(:all, channel, *args) + do_notify(channel, channel, *args) end private + def do_remove_observer (observer, channel) + + observers = @observers[channel] + observers.delete(observer) if observers + end + def do_notify (target_channel, channel, *args) - if @observers[target_channel] - @observers[target_channel].each do |obs| - obs.call channel, *args + + if target_channel.is_a?(String) + + observers = [] + + @observers.each do |c, o| + + if c.is_a?(String) + next unless target_channel.match(c) + elsif c.is_a?(Regexp) + next unless c.match(target_channel) + else + next + end + + observers = observers + o end + else + + observers = @observers[target_channel] end + + return false unless observers + + observers.each do |obs| + obs.call channel, *args + end + + observers.size > 0 + # + # returns true if at least one observer was called end end end