hallon 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +1 -0
- data/{CHANGELOG → CHANGELOG.md} +82 -27
- data/Gemfile +1 -0
- data/README.markdown +1 -1
- data/Rakefile +8 -6
- data/examples/adding_tracks_to_playlist.rb +3 -0
- data/examples/logging_in.rb +3 -0
- data/examples/playing_audio.rb +130 -0
- data/examples/printing_link_information.rb +3 -0
- data/examples/show_published_playlists_of_user.rb +5 -13
- data/hallon.gemspec +2 -2
- data/lib/hallon.rb +15 -0
- data/lib/hallon/album.rb +1 -1
- data/lib/hallon/album_browse.rb +4 -3
- data/lib/hallon/artist.rb +1 -1
- data/lib/hallon/artist_browse.rb +5 -4
- data/lib/hallon/base.rb +7 -2
- data/lib/hallon/error.rb +1 -1
- data/lib/hallon/ext/spotify.rb +26 -42
- data/lib/hallon/image.rb +7 -8
- data/lib/hallon/observable.rb +134 -62
- data/lib/hallon/observable/album_browse.rb +30 -0
- data/lib/hallon/observable/artist_browse.rb +31 -0
- data/lib/hallon/observable/image.rb +31 -0
- data/lib/hallon/observable/player.rb +13 -0
- data/lib/hallon/observable/playlist.rb +194 -0
- data/lib/hallon/observable/playlist_container.rb +74 -0
- data/lib/hallon/observable/post.rb +30 -0
- data/lib/hallon/observable/search.rb +29 -0
- data/lib/hallon/observable/session.rb +236 -0
- data/lib/hallon/observable/toplist.rb +30 -0
- data/lib/hallon/player.rb +8 -17
- data/lib/hallon/playlist.rb +11 -7
- data/lib/hallon/playlist_container.rb +11 -4
- data/lib/hallon/queue.rb +71 -0
- data/lib/hallon/search.rb +10 -7
- data/lib/hallon/session.rb +18 -21
- data/lib/hallon/toplist.rb +4 -3
- data/lib/hallon/user.rb +5 -5
- data/lib/hallon/version.rb +1 -1
- data/spec/hallon/album_browse_spec.rb +4 -0
- data/spec/hallon/artist_browse_spec.rb +4 -0
- data/spec/hallon/base_spec.rb +26 -9
- data/spec/hallon/hallon_spec.rb +0 -18
- data/spec/hallon/image_spec.rb +0 -1
- data/spec/hallon/link_spec.rb +14 -0
- data/spec/hallon/observable/album_browse_spec.rb +7 -0
- data/spec/hallon/observable/artist_browse_spec.rb +7 -0
- data/spec/hallon/observable/image_spec.rb +8 -0
- data/spec/hallon/observable/playlist_container_spec.rb +21 -0
- data/spec/hallon/observable/playlist_spec.rb +85 -0
- data/spec/hallon/observable/post_spec.rb +8 -0
- data/spec/hallon/observable/search_spec.rb +7 -0
- data/spec/hallon/observable/session_spec.rb +143 -0
- data/spec/hallon/observable/toplist_spec.rb +7 -0
- data/spec/hallon/observable_spec.rb +134 -65
- data/spec/hallon/playlist_container_spec.rb +24 -18
- data/spec/hallon/playlist_spec.rb +2 -0
- data/spec/hallon/queue_spec.rb +35 -0
- data/spec/hallon/session_spec.rb +4 -4
- data/spec/hallon/spotify_spec.rb +35 -9
- data/spec/mockspotify.rb +2 -3
- data/spec/spec_helper.rb +0 -1
- data/spec/support/common_objects.rb +27 -15
- data/spec/support/enumerable_comparison.rb +9 -0
- data/spec/support/shared_for_callbacks.rb +60 -0
- data/spec/support/shared_for_linkable_objects.rb +1 -1
- metadata +56 -20
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::AlbumBrowse} objects.
|
3
|
+
module AlbumBrowse
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Method] load callback
|
12
|
+
def initialize_callbacks
|
13
|
+
callback_for(:load)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This callback is fired when the AlbumBrowse object is fully loaded.
|
17
|
+
#
|
18
|
+
# @example listening to this callback
|
19
|
+
# browse = AlbumBrowse.new(album)
|
20
|
+
# browse.on(:load) do
|
21
|
+
# puts "Album browser has loaded!"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @yield [self]
|
25
|
+
# @yieldparam [AlbumBrowse] self
|
26
|
+
def load_callback(pointer, userdata)
|
27
|
+
trigger(pointer, :load)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::ArtistBrowse} objects.
|
3
|
+
module ArtistBrowse
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Method] load callback
|
12
|
+
def initialize_callbacks
|
13
|
+
callback_for(:load)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This callback is fired when the ArtistBrowse object is fully loaded.
|
17
|
+
#
|
18
|
+
# @example listening to this callback
|
19
|
+
# browse = ArtistBrowse.new(album)
|
20
|
+
# browse.on(:load) do
|
21
|
+
# puts "Artist browser has loaded!"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @yield [self]
|
25
|
+
# @yieldparam [ArtistBrowse] self
|
26
|
+
def load_callback(pointer, userdata)
|
27
|
+
trigger(pointer, :load)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::Image} objects.
|
3
|
+
module Image
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Method] load callback
|
12
|
+
def initialize_callbacks
|
13
|
+
callback_for(:load)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This callback is fired when the Image object is fully loaded.
|
17
|
+
#
|
18
|
+
# @example listening to this callback
|
19
|
+
# image = Image.new("spotify:image:3ad93423add99766e02d563605c6e76ed2b0e450")
|
20
|
+
# image.on(:load) do
|
21
|
+
# puts "Image has loaded"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @yield [self]
|
25
|
+
# @yieldparam [Image] self
|
26
|
+
def load_callback(pointer, userdata)
|
27
|
+
trigger(pointer, :load)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# We only care about a few of the Session callbacks, actually,
|
3
|
+
# but since this object is not *really* a Spotify object we do
|
4
|
+
# cheat a little bit.
|
5
|
+
module Player
|
6
|
+
# Includes {Hallon::Observable} for you.
|
7
|
+
def self.extended(other)
|
8
|
+
other.send(:include, Hallon::Observable)
|
9
|
+
end
|
10
|
+
|
11
|
+
include Hallon::Observable::Session
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::Playlist} objects.
|
3
|
+
module Playlist
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Spotify::PlaylistCallbacks]
|
12
|
+
def initialize_callbacks
|
13
|
+
struct = Spotify::PlaylistCallbacks.new
|
14
|
+
struct.members.each do |member|
|
15
|
+
struct[member] = callback_for(member)
|
16
|
+
end
|
17
|
+
struct
|
18
|
+
end
|
19
|
+
|
20
|
+
# @example listening to this event
|
21
|
+
# playlist.on(:tracks_added) do |tracks, position, playlist|
|
22
|
+
# puts "#{tracks.map(&:name).join(', ')} added at #{position} to #{playlist.name}"
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @yield [tracks, position, self] tracks_added
|
26
|
+
# @yieldparam [Array<Track>] tracks
|
27
|
+
# @yieldparam [Integer] position
|
28
|
+
# @yieldparam [Playlist] self
|
29
|
+
def tracks_added_callback(pointer, tracks, num_tracks, position, userdata)
|
30
|
+
trigger(pointer, :tracks_added, callback_make_tracks(tracks, num_tracks), position)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @example listening to this event
|
34
|
+
# playlist.on(:tracks_removed) do |tracks, playlist|
|
35
|
+
# puts "#{tracks.map(&:name).join(', ') removed from #{playlist.name}"
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# @yield [tracks, self] tracks_removed
|
39
|
+
# @yieldparam [Array<Track>] tracks
|
40
|
+
# @yieldparam [Playlist] self
|
41
|
+
def tracks_removed_callback(pointer, tracks, num_tracks, userdata)
|
42
|
+
trigger(pointer, :tracks_removed, callback_make_tracks(tracks, num_tracks))
|
43
|
+
end
|
44
|
+
|
45
|
+
# @example listening to this event
|
46
|
+
# playlist.on(:tracks_moved) do |tracks, new_position, playlist|
|
47
|
+
# puts "#{tracks.map(&:name).join(', ')} moved to #{new_position} to #{playlist.name}"
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# @yield [tracks, new_position, self] tracks_moved
|
51
|
+
# @yieldparam [Array<Track>] tracks
|
52
|
+
# @yieldparam [Integer] new_position
|
53
|
+
# @yieldparam [Playlist] self
|
54
|
+
def tracks_moved_callback(pointer, tracks, num_tracks, new_position, userdata)
|
55
|
+
trigger(pointer, :tracks_moved, callback_make_tracks(tracks, num_tracks), new_position)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @example listening to this event
|
59
|
+
# playlist.on(:playlist_renamed) do |playlist|
|
60
|
+
# puts "#{playlist.name} was now previously named something else \o/"
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# @yield [self] playlist_renamed
|
64
|
+
# @yieldparam [Playlist] self
|
65
|
+
def playlist_renamed_callback(pointer, userdata)
|
66
|
+
trigger(pointer, :playlist_renamed)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @example listening to this event
|
70
|
+
# playlist.on(:playlist_state_changed) do |playlist|
|
71
|
+
# puts "playlist state changed… to what? from what? D:"
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# @yield [self] playlist_state_changed
|
75
|
+
# @yieldparam [Playlist] self
|
76
|
+
def playlist_state_changed_callback(pointer, userdata)
|
77
|
+
trigger(pointer, :playlist_state_changed)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @example listening to this event
|
81
|
+
# playlist.on(:playlist_update_in_progress) do |is_done, playlist|
|
82
|
+
# puts(is_done ? "DONE!" : "not done :(")
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# @yield [is_done, self] playlist_update_in_progress
|
86
|
+
# @yieldparam [Boolean] is_done
|
87
|
+
# @yieldparam [Playlist] self
|
88
|
+
def playlist_update_in_progress_callback(pointer, done, userdata)
|
89
|
+
trigger(pointer, :playlist_update_in_progress, done)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @example listening to this event
|
93
|
+
# playlist.on(:playlist_metadata_updated) do |playlist|
|
94
|
+
# puts "#{playlist.name} metadata updated"
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# @yield [self] playlist_metadata_updated
|
98
|
+
# @yieldparam [Playlist] self
|
99
|
+
def playlist_metadata_updated_callback(pointer, userdata)
|
100
|
+
trigger(pointer, :playlist_metadata_updated)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @example listening to this event
|
104
|
+
# playlist.on(:track_created_changed) do |position, user, created_at, playlist|
|
105
|
+
# track = playlist.tracks[position]
|
106
|
+
# puts "#{track.name} created-info changed"
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# @yield [position, user, created_at, self] track_created_changed
|
110
|
+
# @yieldparam [Integer] position
|
111
|
+
# @yieldparam [User] user
|
112
|
+
# @yieldparam [Time] created_at
|
113
|
+
# @yieldparam [Playlist] self
|
114
|
+
def track_created_changed_callback(pointer, position, user, created_at, userdata)
|
115
|
+
user = Spotify::Pointer.new(user, :user, true)
|
116
|
+
trigger(pointer, :track_created_changed, position, Hallon::User.new(user), Time.at(created_at))
|
117
|
+
end
|
118
|
+
|
119
|
+
# @example listening to this event
|
120
|
+
# playlist.on(:track_seen_changed) do |position, seen, playlist|
|
121
|
+
# track = playlist.tracks[position]
|
122
|
+
# puts "#{track.name}#seen? is #{seen}"
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# @yield [position, is_seen, self] track_seen_changed
|
126
|
+
# @yieldparam [Integer] position
|
127
|
+
# @yieldparam [Boolean] is_seen
|
128
|
+
# @yieldparam [Playlist] self
|
129
|
+
def track_seen_changed_callback(pointer, position, seen, userdata)
|
130
|
+
trigger(pointer, :track_seen_changed, position, seen)
|
131
|
+
end
|
132
|
+
|
133
|
+
# @example listening to this event
|
134
|
+
# playlist.on(:track_message_changed) do |position, message, playlist|
|
135
|
+
# track = playlist.tracks[position]
|
136
|
+
# puts "#{track.name} new message: #{message}"
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
# @yield [position, message, self] track_message_changed
|
140
|
+
# @yieldparam [Integer] position
|
141
|
+
# @yieldparam [String] message
|
142
|
+
# @yieldparam [Playlist] self
|
143
|
+
def track_message_changed_callback(pointer, position, message, userdata)
|
144
|
+
trigger(pointer, :track_message_changed, position, message)
|
145
|
+
end
|
146
|
+
|
147
|
+
# @example listening to this event
|
148
|
+
# playlist.on(:description_changed) do |description, playlist|
|
149
|
+
# puts "#{playlist.name} new description: #{description}"
|
150
|
+
# end
|
151
|
+
#
|
152
|
+
# @yield [description, self] description_changed
|
153
|
+
# @yieldparam [String] description
|
154
|
+
# @yieldparam [Playlist] self
|
155
|
+
def description_changed_callback(pointer, description, userdata)
|
156
|
+
trigger(pointer, :description_changed, description)
|
157
|
+
end
|
158
|
+
|
159
|
+
# @example listening to this event
|
160
|
+
# playlist.on(:image_changed) do |image, playlist|
|
161
|
+
# puts "#{playlist.name} has got a new image: #{image.to_link}"
|
162
|
+
# end
|
163
|
+
#
|
164
|
+
# @yield [image, self] image_changed
|
165
|
+
# @yieldparam [Image, nil] image or nil
|
166
|
+
# @yieldparam [Playlist] self
|
167
|
+
def image_changed_callback(pointer, image, userdata)
|
168
|
+
image = Hallon::Image.from(image)
|
169
|
+
trigger(pointer, :image_changed, image)
|
170
|
+
end
|
171
|
+
|
172
|
+
# @example listening to this event
|
173
|
+
# playlist.on(:subscribers_changed) do |playlist|
|
174
|
+
# puts "#{playlist.name} updated its’ subscribers"
|
175
|
+
# end
|
176
|
+
#
|
177
|
+
# @yield [self] subscribers_changed
|
178
|
+
# @yieldparam [Playlist] self
|
179
|
+
def subscribers_changed_callback(pointer, userdata)
|
180
|
+
trigger(pointer, :subscribers_changed)
|
181
|
+
end
|
182
|
+
|
183
|
+
protected
|
184
|
+
# @param [FFI::Pointer] tracks
|
185
|
+
# @param [Integer] num_tracks
|
186
|
+
# @param [Array<Track>]
|
187
|
+
def callback_make_tracks(tracks, num_tracks)
|
188
|
+
tracks.read_array_of_pointer(num_tracks).map do |track|
|
189
|
+
ptr = Spotify::Pointer.new(track, :track, true)
|
190
|
+
Hallon::Track.new(ptr)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::PlaylistContainer} objects.
|
3
|
+
module PlaylistContainer
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Spotify::PlaylistContainerCallbacks]
|
12
|
+
def initialize_callbacks
|
13
|
+
struct = Spotify::PlaylistContainerCallbacks.new
|
14
|
+
struct.members.each do |member|
|
15
|
+
struct[member] = callback_for(member)
|
16
|
+
end
|
17
|
+
struct
|
18
|
+
end
|
19
|
+
|
20
|
+
# @example listening to this event
|
21
|
+
# playlist_container.on(:playlist_added) do |playlist, position, container|
|
22
|
+
# puts playlist.name + " added at #{position}."
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# @yield [playlist, position, self] playlist_added
|
26
|
+
# @yieldparam [Playlist] playlist
|
27
|
+
# @yieldparam [Integer] position
|
28
|
+
# @yieldparam [PlaylistContainer] self
|
29
|
+
def playlist_added_callback(pointer, playlist, position, userdata)
|
30
|
+
playlist = Spotify::Pointer.new(playlist, :playlist, true)
|
31
|
+
trigger(pointer, :playlist_added, Hallon::Playlist.new(playlist), position)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @example listening to this event
|
35
|
+
# playlist_container.on(:playlist_removed) do |playlist, position, container|
|
36
|
+
# puts playlist.name + " removed from #{position}."
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @yield [playlist, position, self] playlist_removed
|
40
|
+
# @yieldparam [Playlist] playlist
|
41
|
+
# @yieldparam [Integer] position
|
42
|
+
# @yieldparam [PlaylistContainer] self
|
43
|
+
def playlist_removed_callback(pointer, playlist, position, userdata)
|
44
|
+
playlist = Spotify::Pointer.new(playlist, :playlist, true)
|
45
|
+
trigger(pointer, :playlist_removed, Hallon::Playlist.new(playlist), position)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @example listening to this event
|
49
|
+
# playlist_container.on(:playlist_moved) do |playlist, position, new_position, container|
|
50
|
+
# puts "moved #{playlist.name} from #{position} to #{new_position}"
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# @yield [playlist, position, new_position, self] playlist_moved
|
54
|
+
# @yieldparam [Playlist] playlist
|
55
|
+
# @yieldparam [Integer] position
|
56
|
+
# @yieldparam [Integer] new_position
|
57
|
+
# @yieldparam [PlaylistContainer] self
|
58
|
+
def playlist_moved_callback(pointer, playlist, position, new_position, userdata)
|
59
|
+
playlist = Spotify::Pointer.new(playlist, :playlist, true)
|
60
|
+
trigger(pointer, :playlist_moved, Hallon::Playlist.new(playlist), position, new_position)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @example listening to this event
|
64
|
+
# playlist_container.on(:container_loaded) do |container|
|
65
|
+
# puts "#{container.owner.name}s container loaded!"
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# @yield [self] container_loaded
|
69
|
+
# @yieldparam [PlaylistContainer] self
|
70
|
+
def container_loaded_callback(pointer, userdata)
|
71
|
+
trigger(pointer, :container_loaded)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::User::Post} objects.
|
3
|
+
module Post
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Method] complete callback
|
12
|
+
def initialize_callbacks
|
13
|
+
callback_for(:complete)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This callback is fired when the Image object is fully loaded.
|
17
|
+
#
|
18
|
+
# @example listening to this callback
|
19
|
+
# post = user.post(track)
|
20
|
+
# post.on(:complete) do
|
21
|
+
# puts "ze user be havin’ sum posts"
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# @yield [self]
|
25
|
+
# @yieldparam [User::Post] self
|
26
|
+
def complete_callback(pointer, userdata)
|
27
|
+
trigger(pointer, :complete)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Hallon::Observable
|
2
|
+
# Callbacks related to {Hallon::Search} objects.
|
3
|
+
module Search
|
4
|
+
# Includes {Hallon::Observable} for you.
|
5
|
+
def self.extended(other)
|
6
|
+
other.send(:include, Hallon::Observable)
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
# @return [Method] load callback
|
12
|
+
def initialize_callbacks
|
13
|
+
callback_for(:load)
|
14
|
+
end
|
15
|
+
|
16
|
+
# This callback is fired when the Image object is fully loaded.
|
17
|
+
#
|
18
|
+
# @example listening to this callback
|
19
|
+
# search.on(:load) do |search|
|
20
|
+
# puts "search for #{search.query} is complete!"
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# @yield [self]
|
24
|
+
# @yieldparam [Search] self
|
25
|
+
def load_callback(pointer, userdata)
|
26
|
+
trigger(pointer, :load)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,236 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Hallon::Observable
|
3
|
+
# Callbacks related to the {Hallon::Session} object.
|
4
|
+
module Session
|
5
|
+
# Includes {Hallon::Observable} for you.
|
6
|
+
def self.extended(other)
|
7
|
+
other.send(:include, Hallon::Observable)
|
8
|
+
end
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
# @return [Spotify::SessionCallbacks]
|
13
|
+
def initialize_callbacks
|
14
|
+
struct = Spotify::SessionCallbacks.new
|
15
|
+
struct.members.each do |member|
|
16
|
+
struct[member] = callback_for(member)
|
17
|
+
end
|
18
|
+
struct
|
19
|
+
end
|
20
|
+
|
21
|
+
# @example listening to this event
|
22
|
+
# session.on(:logged_in) do |error|
|
23
|
+
# puts "Logged in: " + Hallon::Error.explain(error)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# @yield [error, self] logged_in
|
27
|
+
# @yieldparam [Symbol] error
|
28
|
+
# @yieldparam [Session] self
|
29
|
+
# @see Error
|
30
|
+
def logged_in_callback(pointer, error)
|
31
|
+
trigger(pointer, :logged_in, error)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @example listening to this event
|
35
|
+
# session.on(:logged_out) do
|
36
|
+
# puts "AHHH!"
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# @yield [self]
|
40
|
+
# @yieldparam [Session] self
|
41
|
+
def logged_out_callback(pointer)
|
42
|
+
trigger(pointer, :logged_out)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @example listening to this event
|
46
|
+
# session.on(:metadata_updated) do
|
47
|
+
# puts "wut wut"
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# @yield [self]
|
51
|
+
# @yieldparam [Session] self
|
52
|
+
def metadata_updated_callback(pointer)
|
53
|
+
trigger(pointer, :metadata_updated)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @example listening to this event
|
57
|
+
# session.on(:connection_error) do |error|
|
58
|
+
# puts "Oh noes: " + Hallon::Error.explain(error)
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# @yield [error, self]
|
62
|
+
# @yieldparam [Symbol] error
|
63
|
+
# @yieldparam [Session] self
|
64
|
+
# @see Error
|
65
|
+
def connection_error_callback(pointer, error)
|
66
|
+
trigger(pointer, :connection_error, error)
|
67
|
+
end
|
68
|
+
|
69
|
+
# @example listening to this event
|
70
|
+
# session.on(:message_to_user) do |message|
|
71
|
+
# puts "OH HAI: #{message}"
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# @yield [message, self]
|
75
|
+
# @yieldparam [String] message
|
76
|
+
# @yieldparam [Session] self
|
77
|
+
def message_to_user_callback(pointer, message)
|
78
|
+
trigger(pointer, :message_to_user, message)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @example listening to this event
|
82
|
+
# session.on(:notify_main_thread) do
|
83
|
+
# puts "main thread turn on"
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# @yield [self]
|
87
|
+
# @yieldparam [Session] self
|
88
|
+
def notify_main_thread_callback(pointer)
|
89
|
+
trigger(pointer, :notify_main_thread)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @example listening to this event
|
93
|
+
# session.on(:music_delivery) do |format, frames|
|
94
|
+
# puts ""
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# @yield [format, frames, self]
|
98
|
+
# @yieldparam [Hash] format (contains :type, :rate, :channels)
|
99
|
+
# @yieldparam [Enumerator<[Integer...]>] frames (each frame is an array containing format[:channels] integers of format[:type])
|
100
|
+
# @yieldparam [Session] self
|
101
|
+
def music_delivery_callback(pointer, format, frames, num_frames)
|
102
|
+
struct = Spotify::AudioFormat.new(format)
|
103
|
+
|
104
|
+
format = {}
|
105
|
+
format[:rate] = struct[:sample_rate]
|
106
|
+
format[:channels] = struct[:channels]
|
107
|
+
format[:type] = struct[:sample_type]
|
108
|
+
|
109
|
+
# read the frames of the given type
|
110
|
+
frames = frames.public_send("read_array_of_#{format[:type]}", num_frames * format[:channels])
|
111
|
+
|
112
|
+
# pass the frames to the callback, allowing it to do whatever
|
113
|
+
consumed_frames = trigger(pointer, :music_delivery, format, frames.each_slice(format[:channels]))
|
114
|
+
|
115
|
+
# finally return how many frames the callback reportedly consumed
|
116
|
+
consumed_frames.to_i # very important to return something good here!
|
117
|
+
end
|
118
|
+
|
119
|
+
# @example listening to this event
|
120
|
+
# session.on(:play_token_lost) do
|
121
|
+
# puts "another user set us up the bomb!"
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# @yield [self]
|
125
|
+
# @yieldparam [Session] self
|
126
|
+
def play_token_lost_callback(pointer)
|
127
|
+
trigger(pointer, :play_token_lost)
|
128
|
+
end
|
129
|
+
|
130
|
+
# @example listening to this event
|
131
|
+
# session.on(:end_of_track) do
|
132
|
+
# puts "all your base are belong to us"
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# @yield [self]
|
136
|
+
# @yieldparam [Session] self
|
137
|
+
def end_of_track_callback(pointer)
|
138
|
+
trigger(pointer, :end_of_track)
|
139
|
+
end
|
140
|
+
|
141
|
+
# @example listening to this event
|
142
|
+
# session.on(:start_playback) do
|
143
|
+
# puts "dum dum tiss"
|
144
|
+
# end
|
145
|
+
#
|
146
|
+
# @yield [self]
|
147
|
+
# @yieldparam [Session] self
|
148
|
+
def start_playback_callback(pointer)
|
149
|
+
trigger(pointer, :start_playback)
|
150
|
+
end
|
151
|
+
|
152
|
+
# @example listening to this event
|
153
|
+
# session.on(:stop_playback) do
|
154
|
+
# puts "dum dum tiss"
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# @yield [self]
|
158
|
+
# @yieldparam [Session] self
|
159
|
+
def stop_playback_callback(pointer)
|
160
|
+
trigger(pointer, :stop_playback)
|
161
|
+
end
|
162
|
+
|
163
|
+
# @example listening to this event
|
164
|
+
# session.on(:get_audio_buffer_stats) do
|
165
|
+
# puts "que?"
|
166
|
+
# end
|
167
|
+
#
|
168
|
+
# @yield [self]
|
169
|
+
# @yieldparam [Session] self
|
170
|
+
# @yieldreturn an integer pair, [samples, dropouts]
|
171
|
+
def get_audio_buffer_stats_callback(pointer, stats)
|
172
|
+
stats = Spotify::AudioBufferStats.new(stats)
|
173
|
+
samples, dropouts = trigger(pointer, :get_audio_buffer_stats)
|
174
|
+
stats[:samples] = samples.to_i
|
175
|
+
stats[:stutter] = dropouts.to_i
|
176
|
+
end
|
177
|
+
|
178
|
+
# @example listening to this event
|
179
|
+
# session.on(:streaming_error) do |error|
|
180
|
+
# puts "boo: " + Hallon::Error.explain(error)
|
181
|
+
# end
|
182
|
+
#
|
183
|
+
# @yield [error, self]
|
184
|
+
# @yieldparam [Symbol] error
|
185
|
+
# @yieldparam [Session] self
|
186
|
+
def streaming_error_callback(pointer, error)
|
187
|
+
trigger(pointer, :streaming_error, error)
|
188
|
+
end
|
189
|
+
|
190
|
+
# @example listening to this event
|
191
|
+
# session.on(:userinfo_updated) do
|
192
|
+
# puts "who am I?!"
|
193
|
+
# end
|
194
|
+
#
|
195
|
+
# @yield [self]
|
196
|
+
# @yieldparam [Session] self
|
197
|
+
def userinfo_updated_callback(pointer)
|
198
|
+
trigger(pointer, :userinfo_updated)
|
199
|
+
end
|
200
|
+
|
201
|
+
# @example listening to this event
|
202
|
+
# session.on(:log_message) do |message|
|
203
|
+
# puts "for great justice: #{message}"
|
204
|
+
# end
|
205
|
+
#
|
206
|
+
# @yield [message, self]
|
207
|
+
# @yieldparam [String] message
|
208
|
+
# @yieldparam [Session] self
|
209
|
+
def log_message_callback(pointer, message)
|
210
|
+
trigger(pointer, :log_message, message)
|
211
|
+
end
|
212
|
+
|
213
|
+
# @example listening to this event
|
214
|
+
# session.on(:offline_status_updated) do |session|
|
215
|
+
# puts "All systems: #{session.status}"
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# @yield [self]
|
219
|
+
# @yieldparam [Session] self
|
220
|
+
def offline_status_updated_callback(pointer)
|
221
|
+
trigger(pointer, :offline_status_updated)
|
222
|
+
end
|
223
|
+
|
224
|
+
# @example listening to this event
|
225
|
+
# session.on(:offline_error) do |error|
|
226
|
+
# puts "FAIL: " + Hallon::Error.explain(error)
|
227
|
+
# end
|
228
|
+
#
|
229
|
+
# @yield [error, self]
|
230
|
+
# @yieldparam [Symbol] error
|
231
|
+
# @yieldparam [Session] self
|
232
|
+
def offline_error_callback(pointer, error)
|
233
|
+
trigger(pointer, :offline_error, error)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|