class MotionWiretap::Wiretap
Attributes
wiretaps have an intrinsic “current value”
Public Class Methods
# File lib/motion-wiretap/all/wiretap.rb, line 15 def initialize(&block) @is_torn_down = false @is_completed = false @is_error = false @queue = nil @value = nil @listener_handlers = [] @completion_handlers = [] @error_handlers = [] listen &block if block end
Public Instance Methods
called when no more values are expected
# File lib/motion-wiretap/all/wiretap.rb, line 101 def and_then(wiretap=nil, &block) raise "Block or Wiretap is expected in #{self.class.name}##{__method__}" unless block || wiretap raise "Only Block *or* Wiretap is expected in #{self.class.name}##{__method__}" if block && wiretap @completion_handlers << (block ? block.weak! : wiretap) if @is_completed trigger_completed_on(block || wiretap) end return self end
this is the preferred way to turn off a wiretap; child classes override ‘teardown`, which is only ever called once.
# File lib/motion-wiretap/all/wiretap.rb, line 36 def cancel! return if @is_torn_down @is_torn_down = true teardown end
Returns a Wiretap
that combines all the values into one value (the values are all passed in at the same time) @example
wiretap.combine do |one, two| one ? two : nil end
# File lib/motion-wiretap/all/wiretap.rb, line 188 def combine(&block) return WiretapCombiner.new(self, block) end
# File lib/motion-wiretap/all/wiretap.rb, line 29 def dealloc self.cancel! super end
send a block to the GCD queue
# File lib/motion-wiretap/all/wiretap.rb, line 54 def enqueue(&block) if @queue @queue.async(&block) else block.call end end
Returns a Wiretap
that will only be called if the &condition block returns true
# File lib/motion-wiretap/all/wiretap.rb, line 178 def filter(&block) return WiretapFilter.new(self, block) end
called when the value changes
# File lib/motion-wiretap/all/wiretap.rb, line 67 def listen(wiretap=nil, &block) raise "Block or Wiretap is expected in #{self.class.name}##{__method__}" unless block || wiretap raise "Only Block *or* Wiretap is expected in #{self.class.name}##{__method__}" if block && wiretap @listener_handlers << (block ? block.weak! : wiretap) self end
Returns a Wiretap
that passes each value through the provided block @example
wiretap.map do |item| item.to_s end
# File lib/motion-wiretap/all/wiretap.rb, line 208 def map(&block) return WiretapMapper.new(self, block) end
called when an error occurs, and no more values are expected
# File lib/motion-wiretap/all/wiretap.rb, line 135 def on_error(wiretap=nil, &block) raise "Block or Wiretap is expected in #{self.class.name}##{__method__}" unless block || wiretap raise "Only Block *or* Wiretap is expected in #{self.class.name}##{__method__}" if block && wiretap @error_handlers << (block ? block.weak! : wiretap) if @is_error trigger_error_on(block || wiretap, @is_error) end return self end
specify the GCD queue that the listeners should be run on
# File lib/motion-wiretap/all/wiretap.rb, line 48 def queue(queue) @queue = queue return self end
Returns a Wiretap
that passes each value through the block, and also the previous return value (memo). @example
# returns the total of all the prices wiretap.reduce(0) do |memo, item| memo + item.price end
# File lib/motion-wiretap/all/wiretap.rb, line 199 def reduce(memo=nil, &block) return WiretapReducer.new(self, memo, block) end
Overridden by subclasses to turn off observation, unregister notifications, etc.
# File lib/motion-wiretap/all/wiretap.rb, line 44 def teardown end
# File lib/motion-wiretap/all/wiretap.rb, line 74 def trigger_changed(*values) return if @is_torn_down || @is_completed || @is_error if values.length == 1 @value = values.first else @value = values end @listener_handlers.each do |block_or_wiretap| trigger_changed_on(block_or_wiretap, values) end return self end
Sends the block or wiretap a changed signal
# File lib/motion-wiretap/all/wiretap.rb, line 90 def trigger_changed_on(block_or_wiretap, values) if block_or_wiretap.is_a? Wiretap block_or_wiretap.trigger_changed(*values) else enqueue do block_or_wiretap.call(*values) end end end
# File lib/motion-wiretap/all/wiretap.rb, line 111 def trigger_completed return if @is_torn_down || @is_completed || @is_error @is_completed = true @completion_handlers.each do |block_or_wiretap| trigger_completed_on(block_or_wiretap) end cancel! return self end
Sends the block or wiretap a completed signal
# File lib/motion-wiretap/all/wiretap.rb, line 124 def trigger_completed_on(block_or_wiretap) if block_or_wiretap.is_a? Wiretap block_or_wiretap.trigger_completed else enqueue do block_or_wiretap.call end end end
# File lib/motion-wiretap/all/wiretap.rb, line 145 def trigger_error(error=SINGLETON) return if @is_torn_down || @is_completed || @is_error raise "You must pass a truthy value to `trigger_error()`" unless error # convert SINGLETON to a default error value error = true if error == SINGLETON @is_error = error @error_handlers.each do |block_or_wiretap| trigger_error_on(block_or_wiretap, error) end cancel! return self end
Sends the block or wiretap an error value
# File lib/motion-wiretap/all/wiretap.rb, line 162 def trigger_error_on(block_or_wiretap, error) if block_or_wiretap.is_a? Wiretap block_or_wiretap.trigger_error(error) else enqueue do block_or_wiretap.call(error) end end end