Module: Hallon::Observable
- Defined in:
- lib/hallon/observable.rb,
lib/hallon/observable/post.rb,
lib/hallon/observable/image.rb,
lib/hallon/observable/player.rb,
lib/hallon/observable/search.rb,
lib/hallon/observable/session.rb,
lib/hallon/observable/toplist.rb,
lib/hallon/observable/playlist.rb,
lib/hallon/observable/album_browse.rb,
lib/hallon/observable/artist_browse.rb,
lib/hallon/observable/playlist_container.rb
Overview
A module providing event capabilities to Hallon objects.
Defined Under Namespace
Modules: AlbumBrowse, ArtistBrowse, ClassMethods, Image, Player, Playlist, PlaylistContainer, Post, Search, Session, Toplist
Class Method Summary collapse
-
.included(other) ⇒ Object
Will extend
other
with ClassMethods.
Instance Method Summary collapse
- #handlers ⇒ Hash<String, Proc> protected
-
#has_callback?(name) ⇒ Boolean
True if a callback with
name
exists. -
#on(event) {|*args| ... } ⇒ Proc
Defines a handler for the given event.
-
#protecting_handlers { ... } ⇒ Object
Run a given block, and once it exits restore all handlers to the way they were before running the block.
-
#subscribe_for_callbacks {|callback| ... } ⇒ Object
protected
Register this object as interested in callbacks.
-
#trigger(name, *arguments, &block) ⇒ Object
Whatever the handler returns.
-
#wait_for(*events) {|Symbol, *args| ... } ⇒ Object
Wait for the given callbacks to fire until the block returns true.
Class Method Details
.included(other) ⇒ Object
Will extend other
with ClassMethods.
61 62 63 |
# File 'lib/hallon/observable.rb', line 61 def self.included(other) other.extend(ClassMethods) end |
Instance Method Details
#handlers ⇒ Hash<String, Proc> (protected)
167 168 169 |
# File 'lib/hallon/observable.rb', line 167 def handlers @__handlers ||= Hash.new(proc {}) end |
#has_callback?(name) ⇒ Boolean
Returns true if a callback with name
exists.
126 127 128 |
# File 'lib/hallon/observable.rb', line 126 def has_callback?(name) self.class.respond_to?("#{name}_callback", true) end |
#on(event) {|*args| ... } ⇒ Proc
Defines a handler for the given event.
70 71 72 73 74 75 |
# File 'lib/hallon/observable.rb', line 70 def on(event, &block) event &&= event.to_s raise ArgumentError, "no block given" unless block raise NameError, "no such callback: #{event}" unless has_callback?(event) handlers[event].tap { handlers[event] = block } end |
#protecting_handlers { ... } ⇒ Object
Run a given block, and once it exits restore all handlers to the way they were before running the block.
This allows you to temporarily use different handlers for some events.
137 138 139 140 141 142 |
# File 'lib/hallon/observable.rb', line 137 def protecting_handlers old_handlers = handlers.dup yield ensure handlers.replace(old_handlers) end |
#subscribe_for_callbacks {|callback| ... } ⇒ Object (protected)
Register this object as interested in callbacks.
160 161 162 163 164 |
# File 'lib/hallon/observable.rb', line 160 def subscribe_for_callbacks yield(self.class.callbacks).tap do self.class.subscribe(self, pointer) unless pointer.null? end end |
#trigger(name, *arguments, &block) ⇒ Object
Returns whatever the handler returns.
147 148 149 150 151 |
# File 'lib/hallon/observable.rb', line 147 def trigger(name, *arguments, &block) if handler = handlers[name.to_s] handler.call(*arguments, &block) end end |
#wait_for(*events) {|Symbol, *args| ... } ⇒ Object
Given block will be called once instantly without parameters.
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
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 |