Method: Hallon::Observable#wait_for

Defined in:
lib/hallon/observable.rb

#wait_for(*events) {|Symbol, *args| ... } ⇒ Object

Note:

Given block will be called once instantly without parameters.

Note:

If no events happen for 0.25 seconds, the block will be called without parameters.

Wait for the given callbacks to fire until the block returns true

Parameters:

  • events (Symbol, ...)

    list of events to wait for

Yields:

  • (Symbol, *args)

    name of the event that fired, and its’ arguments

Returns:

  • whatever the block returns



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/hallon/observable.rb', line 84

def wait_for(*events)
  channel = SizedQueue.new(10) # sized just to be safe

  old_handlers = events.each_with_object({}) do |event, hash|
    hash[event] = on(event) do |*args|
      channel << [event, *args]
      hash[event].call(*args)
    end
  end

  old_notify = session.on(:notify_main_thread) do
    channel << :notify
  end

  if result = yield
    return result
  end

  loop do
    begin
      timeout = [session.process_events.fdiv(1000), 2].min # scope to two seconds
      timeout = timeout + 0.010 # minimum of ten miliseconds timeout
      params = Timeout::timeout(timeout) { channel.pop }
      redo if params == :notify
    rescue Timeout::Error
      params = nil
    end

    if result = yield(*params)
      return result
    end
  end
ensure
  old_handlers.each_pair do |event, handler|
    on(event, &handler)
  end unless old_handlers.nil?
  session.on(:notify_main_thread, &old_notify) unless old_notify.nil?
end