hallon 0.18.1 → 0.18.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f25eaa19120499087ea81ef9f17c7102e3a62177
4
+ data.tar.gz: 1b03b1966751bd123ceb89b3d32364da27b569cc
5
+ SHA512:
6
+ metadata.gz: ed2e9f12f2549234d6cfc6b9a501774b3aac8179bd0f079f6a7da48a5dbcfd353f7d92eb0e760f6ab7e9ca434d77a1e01fec4800ab86f0b629b1d0385446b6a4
7
+ data.tar.gz: 68dfe742b746431e11165cb3e31f977bd5e3efccd80cbbb46aaa0a48180cb900aceb753403b7151342a55d6f65793d038f3ca0bd774e5d01feffeecdbf44c5d1
data/.gitignore CHANGED
@@ -28,3 +28,4 @@ pkg
28
28
 
29
29
  ## Mac OS
30
30
  .DS_Store
31
+ examples/common.rb
@@ -1,5 +1,11 @@
1
1
  language: ruby
2
- bundler_args: --path vendor/bundle
3
2
  rvm:
4
3
  - 1.9.2
5
4
  - 1.9.3
5
+ - 2.0.0
6
+ - rbx-19mode
7
+ - jruby-19mode
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: rbx-19mode
11
+ - rvm: jruby-19mode
@@ -4,6 +4,14 @@ Hallon’s Changelog
4
4
  [HEAD][]
5
5
  ------------------
6
6
 
7
+ [v0.18.2][]
8
+ ------------------
9
+ No changes to public API. Mostly some cleanup, and support for the new
10
+ Spotify gem.
11
+
12
+ - [470bc9786] Use weak_observable gem for weak reference callbacks.
13
+ - [b2feb8095] Require newest FFI and Spotify versions.
14
+
7
15
  [v0.18.1][]
8
16
  ------------------
9
17
  Hallon now supports spotify ~> 12.3.0. As a result, you no longer need to manually install
data/Gemfile CHANGED
@@ -3,10 +3,11 @@ gemspec
3
3
 
4
4
  # Useful for testing out audio.
5
5
  unless ENV["TRAVIS"] # does not build on travis
6
- gem 'hallon-openal'
6
+ gem 'hallon-openal', '~> 1.0.1'
7
7
  end
8
8
 
9
9
  gem 'ruby_parser', '>= 3.0.0.a1', '< 4.0'
10
10
  gem 'pry'
11
11
  gem 'simplecov'
12
- gem 'rb-readline'
12
+ gem 'yard'
13
+ gem 'maruku'
@@ -5,6 +5,14 @@ Hallon (Swedish for “[Raspberry][]”) is _the_ ruby gem for interacting with
5
5
 
6
6
  Code samples can be found under the `examples/` directory. An explanation on how to run them can be found on the [Hallon wiki on GitHub](https://github.com/Burgestrand/Hallon/wiki).
7
7
 
8
+ ### Contact details
9
+
10
+ - __Got questions?__ Ask on the mailing list: <mailto:ruby-hallon@googlegroups.com> (<https://groups.google.com/d/forum/ruby-hallon>)
11
+ - __Found a bug?__ Report an issue: <https://github.com/Burgestrand/Hallon/issues/new>
12
+ - __Have feedback?__ I ❤ feedback! Please send it to the mailing list.
13
+
14
+ If you for some reason cannot use the mailing list or GitHub issue tracker you may contact me directly. My email is found on [my GitHub profile](https://github.com/Burgestrand).
15
+
8
16
  Prerequisites
9
17
  -------------
10
18
 
@@ -60,14 +68,6 @@ gem install hallon-openal
60
68
 
61
69
  For more information about audio support in Hallon, see the section "Audio support" below.
62
70
 
63
- ### Contact details
64
-
65
- - __Got questions?__ Ask on the mailing list: <mailto:ruby-hallon@googlegroups.com> (<https://groups.google.com/d/forum/ruby-hallon>)
66
- - __Found a bug?__ Report an issue: <https://github.com/Burgestrand/Hallon/issues/new>
67
- - __Have feedback?__ I ❤ feedback! Please send it to the mailing list.
68
-
69
- If you for some reason cannot use the mailing list or GitHub issue tracker you may contact me directly. My email is found on [my GitHub profile](https://github.com/Burgestrand), and I’m also available as [@burgestrand on twitter](https://twitter.com/Burgestrand).
70
-
71
71
  Hallon and Spotify objects
72
72
  --------------------------
73
73
  All objects from libspotify have a counterpart in Hallon, and just like in libspotify the objects are populated with information as it becomes available. All objects that behave in this way respond to `#loaded?`, which’ll return true if the object has been populated with data.
@@ -170,6 +170,9 @@ You can only keep one session with Spotify alive at a time within the same proce
170
170
  ### When forking, you need to be extra careful
171
171
  If you fork, you need to instantiate the session within the process you plan to use Hallon in. You want to use Hallon in the parent? Create the session in the parent. You want to use it in the child? Create the session in the child! This is a limitation of libspotify itself.
172
172
 
173
+ ### You must not share cache directory between processes
174
+ Hallon uses `tmp/hallon` as both cache and settings directory by default. If you launch Hallon in multiple processes, you must make sure that `cache_location` is not shared between them, by changing it in the call to [Session.initialize][], or libspotify will lock up.
175
+
173
176
  ### Hallon and platforms
174
177
  Hallon aims to support the available platforms of the Spotify gem, which in turn depends somewhat on the platforms that libspotify support. As of current, Hallon officially supports Mac OS and Linux distributions that libspotify supports. Windows support is possible, but is yet to have been needed.
175
178
 
@@ -185,7 +188,29 @@ Credits
185
188
 
186
189
  License
187
190
  -------
188
- Hallon is licensed under a 2-clause (Simplified) BSD license. More information can be found in the `LICENSE.txt` file.
191
+ Hallon is licensed under a 2-clause (Simplified) BSD license.
192
+
193
+ Copyright 2012 Kim Burgestrand. All rights reserved.
194
+
195
+ Redistribution and use in source and binary forms, with or without modification, are
196
+ permitted provided that the following conditions are met:
197
+
198
+ 1. Redistributions of source code must retain the above copyright notice, this list of
199
+ conditions and the following disclaimer.
200
+
201
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
202
+ of conditions and the following disclaimer in the documentation and/or other materials
203
+ provided with the distribution.
204
+
205
+ THIS SOFTWARE IS PROVIDED BY KIM BURGESTRAND ``AS IS'' AND ANY EXPRESS OR IMPLIED
206
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
207
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KIM BURGESTRAND OR
208
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
209
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
210
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
211
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
212
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
213
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
189
214
 
190
215
  [Raspberry]: http://images.google.com/search?q=raspberry&tbm=isch
191
216
  [Spotify for Ruby]: https://github.com/Burgestrand/spotify
data/Rakefile CHANGED
@@ -4,13 +4,13 @@ require 'rake'
4
4
  begin
5
5
  require 'bundler'
6
6
  Bundler::GemHelper.install_tasks
7
+
8
+ require 'yard'
9
+ YARD::Rake::YardocTask.new
7
10
  rescue LoadError
8
11
  # not everybody needs these
9
12
  end
10
13
 
11
- require 'yard'
12
- YARD::Rake::YardocTask.new
13
-
14
14
  require 'rspec/core/rake_task'
15
15
  RSpec::Core::RakeTask.new('spec') do |task|
16
16
  task.ruby_opts = '-W2'
@@ -42,9 +42,15 @@ end
42
42
 
43
43
  # Making sure you receive the latest of the latest. Hallon does not wish to
44
44
  # be replaced by older versions when showing you the shiny.
45
- $LOAD_PATH.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
45
+ require 'bundler'
46
+ Bundler.setup
46
47
  require 'hallon'
47
48
 
49
+ begin
50
+ require_relative 'common'
51
+ rescue LoadError
52
+ end
53
+
48
54
  # This is a quick sanity check, to make sure we have all the necessities in order.
49
55
  appkey_path = File.expand_path('./spotify_appkey.key')
50
56
  unless File.exists?(appkey_path)
@@ -52,9 +58,6 @@ unless File.exists?(appkey_path)
52
58
  Your Spotify application key could not be found at the path:
53
59
  #{appkey_path}
54
60
 
55
- Please adjust the path in examples/common.rb or put your application key in:
56
- #{appkey_path}
57
-
58
61
  You may download your application key from:
59
62
  https://developer.spotify.com/en/libspotify/application-key/
60
63
  ERROR
@@ -68,8 +71,8 @@ they require actual login credentials before they may run."
68
71
 
69
72
  # Spotify requires a rite of passage. It’s own variant of “open sesame”, so we will
70
73
  # ask you to provide them with your information.
71
- hallon_username = prompt("Please enter your spotify username")
72
- hallon_password = prompt("Please enter your spotify password", hide: true)
74
+ hallon_username = ENV.fetch("SPOTIFY_USERNAME") { prompt("Please enter your spotify username") }
75
+ hallon_password = ENV.fetch("SPOTIFY_PASSWORD") { prompt("Please enter your spotify password", hide: true) }
73
76
  hallon_appkey = IO.read(appkey_path)
74
77
 
75
78
  # Make sure the credentials are there. We don’t want to go without them.
@@ -21,11 +21,9 @@ Gem::Specification.new do |gem|
21
21
  gem.platform = Gem::Platform::RUBY
22
22
  gem.required_ruby_version = '>= 1.9'
23
23
 
24
- gem.add_dependency 'ref', '~> 1.0'
25
- gem.add_dependency 'spotify', '~> 12.3.0'
26
- gem.add_development_dependency 'rake', '~> 0.8'
24
+ gem.add_dependency 'weak_observable', '~> 1.0'
25
+ gem.add_dependency 'spotify', '~> 12.5.1'
26
+ gem.add_dependency 'ffi', '~> 1.8'
27
+ gem.add_development_dependency 'rake'
27
28
  gem.add_development_dependency 'rspec', '~> 2'
28
- gem.add_development_dependency 'yard'
29
- gem.add_development_dependency 'bundler'
30
- gem.add_development_dependency 'rdiscount'
31
29
  end
@@ -3,6 +3,7 @@ require 'spotify'
3
3
  require 'hallon/ext/spotify'
4
4
  require 'hallon/ext/ffi'
5
5
 
6
+ require 'weak_observable'
6
7
  require 'hallon/observable'
7
8
  require 'hallon/linkable'
8
9
  require 'hallon/loadable'
@@ -22,31 +22,7 @@ module Hallon
22
22
  # @param [Object] object
23
23
  # @param [FFI::Pointer] pointer
24
24
  def subscribe(object, pointer)
25
- key = pointer.address
26
- ref = Ref::WeakReference.new(object)
27
-
28
- @lock.synchronize do
29
- if @subscribers_rev[ref.referenced_object_id]
30
- raise ArgumentError, "already subscribed to callbacks"
31
- end
32
-
33
- @subscribers[key] ||= {} # use a hash for fast reverse lookups
34
- @subscribers[key][ref.referenced_object_id] = ref
35
- @subscribers_rev[ref.referenced_object_id] = key
36
- end
37
-
38
- ObjectSpace.define_finalizer(object, @unsubscriber)
39
- end
40
-
41
- # Retrieve all subscribers for a given pointer.
42
- #
43
- # @param [FFI::Pointer] pointer
44
- def subscribers_for(pointer)
45
- key = pointer.address
46
-
47
- @lock.synchronize do
48
- @subscribers.fetch(key, {}).values.map(&:object).compact
49
- end
25
+ @observers.add(pointer.address, object, :trigger)
50
26
  end
51
27
 
52
28
  protected
@@ -57,18 +33,7 @@ module Hallon
57
33
  # track of all subscribers properly.
58
34
  def initialize_observable
59
35
  @callbacks = initialize_callbacks
60
-
61
- @lock = Ref::SafeMonitor.new
62
- @subscribers = {}
63
- @subscribers_rev = {}
64
- @unsubscriber = proc do |object_id|
65
- @lock.synchronize do
66
- if key = @subscribers_rev.delete(object_id)
67
- @subscribers[key].delete(object_id)
68
- @subscribers.delete(key) if @subscribers[key].empty?
69
- end
70
- end
71
- end
36
+ @observers = WeakObservable::Hub.new
72
37
  end
73
38
 
74
39
  # @param [#to_s] name
@@ -86,9 +51,8 @@ module Hallon
86
51
  # @param […] arguments
87
52
  # @return whatever the (last) handler returned
88
53
  def trigger(pointer, event, *arguments)
89
- subscribers_for(pointer).inject(nil) do |_, subscriber|
90
- # trigger is protected, inconvenient but symbolic
91
- subscriber.send(:trigger, event, *arguments)
54
+ if results = @observers.notify(pointer.address, event, *arguments)
55
+ results[-1]
92
56
  end
93
57
  end
94
58
  end
@@ -104,11 +68,10 @@ module Hallon
104
68
  # @return [Proc] the previous handler
105
69
  # @yield (*args) event handler block
106
70
  def on(event, &block)
71
+ event &&= event.to_s
107
72
  raise ArgumentError, "no block given" unless block
108
73
  raise NameError, "no such callback: #{event}" unless has_callback?(event)
109
- handlers[event.to_s].tap do
110
- handlers[event.to_s] = block
111
- end
74
+ handlers[event].tap { handlers[event] = block }
112
75
  end
113
76
 
114
77
  # Wait for the given callbacks to fire until the block returns true
@@ -178,6 +141,15 @@ module Hallon
178
141
  handlers.replace(old_handlers)
179
142
  end
180
143
 
144
+ # @param [#to_s] name
145
+ # @param [...] arguments
146
+ # @return whatever the handler returns
147
+ def trigger(name, *arguments, &block)
148
+ if handler = handlers[name.to_s]
149
+ handler.call(*arguments, &block)
150
+ end
151
+ end
152
+
181
153
  protected
182
154
 
183
155
  # Register this object as interested in callbacks.
@@ -191,15 +163,6 @@ module Hallon
191
163
  end
192
164
  end
193
165
 
194
- # @param [#to_s] name
195
- # @param [...] arguments
196
- # @return whatever the handler returns
197
- def trigger(name, *arguments, &block)
198
- if handler = handlers[name.to_s]
199
- handler.call(*arguments, &block)
200
- end
201
- end
202
-
203
166
  # @return [Hash<String, Proc>]
204
167
  def handlers
205
168
  @__handlers ||= Hash.new(proc {})
@@ -91,13 +91,12 @@ module Hallon::Observable
91
91
  # @yield [format, frames]
92
92
  # @yieldparam [Hash] format (contains :type, :rate, :channels)
93
93
  # @yieldparam [Enumerator<[Integer...]>] frames (each frame is an array containing format[:channels] integers of format[:type])
94
- def music_delivery_callback(pointer, format, frames, num_frames)
95
- struct = Spotify::AudioFormat.new(format)
96
-
97
- format = {}
98
- format[:rate] = struct[:sample_rate]
99
- format[:channels] = struct[:channels]
100
- format[:type] = struct[:sample_type]
94
+ def music_delivery_callback(pointer, format_struct, frames, num_frames)
95
+ format = {
96
+ rate: format_struct[:sample_rate],
97
+ channels: format_struct[:channels],
98
+ type: format_struct[:sample_type]
99
+ }
101
100
 
102
101
  # read the frames of the given type
103
102
  frames = unless num_frames.zero?
@@ -161,7 +160,6 @@ module Hallon::Observable
161
160
  # @yield []
162
161
  # @yieldreturn an integer pair, [samples, dropouts]
163
162
  def get_audio_buffer_stats_callback(pointer, stats)
164
- stats = Spotify::AudioBufferStats.new(stats)
165
163
  samples, dropouts = trigger(pointer, :get_audio_buffer_stats)
166
164
  stats[:samples] = samples.to_i
167
165
  stats[:stutter] = dropouts.to_i
@@ -250,20 +250,8 @@ module Hallon
250
250
  # libspotify does not store more than 500 subscriber names
251
251
  # @return [Array<String>] list of canonical usernames
252
252
  def subscribers
253
- ptr = Spotify.playlist_subscribers(pointer)
254
-
255
- if ptr.null?
256
- []
257
- else
258
- struct = Spotify::Subscribers.new(ptr)
259
- if struct[:count].zero?
260
- []
261
- else
262
- struct[:subscribers].map(&:read_string)
263
- end
264
- end
265
- ensure
266
- Spotify.playlist_subscribers_free(ptr) unless ptr.null?
253
+ subscribers = Spotify.playlist_subscribers(pointer)
254
+ subscribers.to_a
267
255
  end
268
256
 
269
257
  # @return [Integer] total number of subscribers.
@@ -46,7 +46,7 @@ module Hallon
46
46
  # @see (see Session#initialize)
47
47
  # @return [Session]
48
48
  def Session.initialize(appkey, options = {}, &block)
49
- raise "Session has already been initialized" if @__instance__
49
+ raise "Session has already been initialized" if defined?(@__instance__)
50
50
  @__instance__ = new(appkey, options, &block)
51
51
  end
52
52
 
@@ -375,8 +375,8 @@ module Hallon
375
375
  # @see http://developer.spotify.com/en/libspotify/docs/structsp__offline__sync__status.html
376
376
  def offline_sync_status
377
377
  struct = Spotify::OfflineSyncStatus.new
378
- if Spotify.offline_sync_get_status(pointer, struct.pointer)
379
- Hash[struct.members.zip(struct.values)]
378
+ if Spotify.offline_sync_get_status(pointer, struct)
379
+ struct.to_h
380
380
  else
381
381
  {}
382
382
  end
@@ -3,5 +3,5 @@ module Hallon
3
3
  # Current release version of Hallon
4
4
  #
5
5
  # @see http://semver.org/
6
- VERSION = [0, 18, 1].join('.')
6
+ VERSION = [0, 18, 2].join('.')
7
7
  end
@@ -49,15 +49,15 @@ describe Hallon::Observable::Session do
49
49
  frames
50
50
  end
51
51
 
52
- let(:format) do
52
+ let(:format_struct) do
53
53
  struct = Spotify::AudioFormat.new
54
54
  struct[:sample_type] = :int16
55
55
  struct[:sample_rate] = 44100 # 44.1khz
56
56
  struct[:channels] = 2
57
- struct.pointer
57
+ struct
58
58
  end
59
59
 
60
- let(:input) { [a_pointer, format, frames, num_frames] }
60
+ let(:input) { [a_pointer, format_struct, frames, num_frames] }
61
61
  let(:output) { [{rate: 44100, type: :int16, channels: 2}, data.each_slice(2)] }
62
62
 
63
63
  it "should return the resulting value" do
@@ -70,7 +70,7 @@ describe Hallon::Observable::Session do
70
70
  end
71
71
 
72
72
  it "should not go ballistic when there is no audio data" do
73
- subject_callback.call(a_pointer, format, FFI::Pointer::NULL, 0)
73
+ subject_callback.call(a_pointer, format_struct, FFI::Pointer::NULL, 0)
74
74
  end
75
75
  end
76
76
 
@@ -95,7 +95,8 @@ describe Hallon::Observable::Session do
95
95
  end
96
96
 
97
97
  specification_for_callback "get_audio_buffer_stats" do
98
- let(:input) { [a_pointer, Spotify::AudioBufferStats.new.pointer] }
98
+ let(:struct) { Spotify::AudioBufferStats.new }
99
+ let(:input) { [a_pointer, struct] }
99
100
  let(:output) { [] }
100
101
 
101
102
  it "should return the resulting audio buffer stats" do
@@ -104,7 +105,7 @@ describe Hallon::Observable::Session do
104
105
 
105
106
  stats[:samples].should eq 0
106
107
  stats[:stutter].should eq 0
107
- subject_callback.call(a_pointer, stats.pointer)
108
+ subject_callback.call(a_pointer, stats)
108
109
  stats[:samples].should eq 5
109
110
  stats[:stutter].should eq 7
110
111
  end
@@ -114,7 +115,7 @@ describe Hallon::Observable::Session do
114
115
 
115
116
  stats[:samples].should eq 0
116
117
  stats[:stutter].should eq 0
117
- subject_callback.call(a_pointer, stats.pointer)
118
+ subject_callback.call(a_pointer, stats)
118
119
  stats[:samples].should eq 0
119
120
  stats[:stutter].should eq 0
120
121
  end
@@ -54,27 +54,6 @@ describe Hallon::Observable do
54
54
 
55
55
  describe "ClassMethods" do
56
56
  subject { klass }
57
-
58
- describe ".subscribers_for" do
59
- around { |test| Ref::Mock.use(&test) }
60
-
61
- it "should contain a list of weak references to subscribers" do
62
- ptr = FFI::Pointer.new(0xDEADBEEF)
63
-
64
- objA = klass.new
65
- subject.subscribers_for(ptr).should eq [objA]
66
-
67
- objB = klass.new
68
- subject.subscribers_for(ptr).should eq [objA, objB]
69
-
70
- Ref::Mock.gc(objA)
71
- subject.subscribers_for(ptr).should eq [objB]
72
- end
73
-
74
- it "should return an empty array if there are no subscribers" do
75
- subject.subscribers_for(null_pointer).should be_empty
76
- end
77
- end
78
57
  end
79
58
 
80
59
  subject { klass.new }
@@ -124,8 +103,8 @@ describe Hallon::Observable do
124
103
  it "should return the previous callback" do
125
104
  previous = proc { puts "hey!" }
126
105
  new_one = proc { puts "ho!" }
127
- initial = subject.on(:testing, &previous)
128
106
 
107
+ subject.on(:testing, &previous)
129
108
  subject.on(:testing, &new_one).should eq previous
130
109
  subject.on(:testing, &previous).should eq new_one
131
110
  end
@@ -144,11 +123,6 @@ describe Hallon::Observable do
144
123
  expect { subject.send(:subscribe_for_callbacks) }.to raise_error(LocalJumpError)
145
124
  end
146
125
 
147
- it "should raise an error if the same object tries to subscribe twice" do
148
- # we already subscribed for callbacks in initialize
149
- expect { subject.send(:subscribe_for_callbacks) {} }.to raise_error(ArgumentError)
150
- end
151
-
152
126
  it "should do nothing if the result is a null pointer" do
153
127
  klass.should_not_receive(:subscribe)
154
128
  klass.any_instance.stub(:pointer).and_return(FFI::Pointer::NULL)
@@ -34,17 +34,17 @@ module Spotify
34
34
 
35
35
  module Mock
36
36
  class PlaylistTrack < Spotify::Struct
37
- layout :track, Spotify::Track,
37
+ layout :track, :pointer,
38
38
  :create_time, :int,
39
- :creator, Spotify::User,
40
- :message, Spotify::NULString,
39
+ :creator, :pointer,
40
+ :message, Spotify::UTF8StringPointer,
41
41
  :seen, :bool
42
42
  end
43
43
 
44
44
  class PlaylistContainerItem < Spotify::Struct
45
- layout :playlist, Spotify::Playlist,
45
+ layout :playlist, :pointer,
46
46
  :type, :playlist_type,
47
- :folder_name, Spotify::NULString,
47
+ :folder_name, Spotify::UTF8StringPointer,
48
48
  :folder_id, :uint64,
49
49
  :num_seen_tracks, :int,
50
50
  :seen_tracks, :array
@@ -54,25 +54,35 @@ module Spotify
54
54
  class API
55
55
  old_verbose, $VERBOSE = $VERBOSE, true
56
56
 
57
+ # Some of these can accept null pointers, but our type protection ensures
58
+ # that we never pass null values in place of spotify objects, so we work
59
+ # around it by not using the real types. We still want to document the kind
60
+ # used, however.
61
+ typedef :pointer, :track
62
+ typedef :pointer, :album
63
+ typedef :pointer, :artist
64
+ typedef :pointer, :playlist
65
+ typedef :pointer, :user
66
+
57
67
  attach_function :mock_registry_find, [:string], :pointer
58
68
  attach_function :mock_registry_add, [:string, :pointer], :void
59
69
  attach_function :mock_registry_clean, [], :void
60
70
 
61
- attach_function :mock_session_create, [:pointer, :connectionstate, :int, OfflineSyncStatus, :int, :int, Playlist], Session
71
+ attach_function :mock_session_create, [:pointer, :connectionstate, :int, OfflineSyncStatus, :int, :int, :playlist], Session
62
72
  attach_function :mock_user_create, [:string, :string, :bool], User
63
- attach_function :mock_track_create, [:string, :int, :array, Album, :int, :int, :int, :int, :error, :bool, :availability, :track_offline_status, :bool, :bool, Track, :bool, :bool], Track
73
+ attach_function :mock_track_create, [:string, :int, :array, :album, :int, :int, :int, :int, :error, :bool, :availability, :track_offline_status, :bool, :bool, :track, :bool, :bool], Track
64
74
  attach_function :mock_image_create, [ImageID, :imageformat, :size_t, :buffer_in, :error], Image
65
75
  attach_function :mock_artist_create, [:string, ImageID, :bool], Artist
66
- attach_function :mock_album_create, [:string, Artist, :int, ImageID, :albumtype, :bool, :bool], Album
76
+ attach_function :mock_album_create, [:string, :artist, :int, ImageID, :albumtype, :bool, :bool], Album
67
77
 
68
- attach_function :mock_albumbrowse_create, [:error, :int, Album, Artist, :int, :array, :int, :array, :string, :albumbrowse_complete_cb, :userdata], AlbumBrowse
69
- attach_function :mock_artistbrowse_create, [:error, :int, Artist, :int, :array, :int, :array, :int, :array, :int, :array, :int, :array, :string, :artistbrowse_type, :artistbrowse_complete_cb, :userdata], ArtistBrowse
78
+ attach_function :mock_albumbrowse_create, [:error, :int, :album, :artist, :int, :array, :int, :array, :string, :albumbrowse_complete_cb, :userdata], AlbumBrowse
79
+ attach_function :mock_artistbrowse_create, [:error, :int, :artist, :int, :array, :int, :array, :int, :array, :int, :array, :int, :array, :string, :artistbrowse_type, :artistbrowse_complete_cb, :userdata], ArtistBrowse
70
80
  attach_function :mock_toplistbrowse_create, [:error, :int, :int, :array, :int, :array, :int, :array], ToplistBrowse
71
81
 
72
- attach_function :mock_playlist_create, [:string, :bool, User, :bool, :string, ImageID, :bool, :uint, Subscribers, :bool, :playlist_offline_status, :int, :int, :array], Playlist
73
- attach_function :mock_playlistcontainer_create, [User, :bool, :int, :array, PlaylistContainerCallbacks, :userdata], PlaylistContainer
82
+ attach_function :mock_playlist_create, [:string, :bool, :user, :bool, :string, ImageID, :bool, :uint, Subscribers, :bool, :playlist_offline_status, :int, :int, :array], Playlist
83
+ attach_function :mock_playlistcontainer_create, [:user, :bool, :int, :array, PlaylistContainerCallbacks, :userdata], PlaylistContainer
74
84
  attach_function :mock_search_create, [:error, :string, :string, :int, :int, :array, :int, :int, :array, :int, :int, :array, :int, :int, :array, :search_complete_cb, :userdata], Search
75
- attach_function :mock_subscribers, [:int, :array], Subscribers
85
+ attach_function :mock_subscribers, [:int, :array], Subscribers.by_ref
76
86
 
77
87
  # mocked accessors
78
88
  attach_function :mock_playlist_get_autolink_tracks, [Playlist], :bool
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hallon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
5
- prerelease:
4
+ version: 0.18.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Kim Burgestrand
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-09 00:00:00.000000000 Z
11
+ date: 2013-04-25 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: ref
14
+ name: weak_observable
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,99 +27,59 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: spotify
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
37
- version: 12.3.0
33
+ version: 12.5.1
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: 12.3.0
40
+ version: 12.5.1
46
41
  - !ruby/object:Gem::Dependency
47
- name: rake
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: '0.8'
54
- type: :development
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
61
- version: '0.8'
62
- - !ruby/object:Gem::Dependency
63
- name: rspec
42
+ name: ffi
64
43
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
44
  requirements:
67
45
  - - ~>
68
46
  - !ruby/object:Gem::Version
69
- version: '2'
70
- type: :development
47
+ version: '1.8'
48
+ type: :runtime
71
49
  prerelease: false
72
50
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
51
  requirements:
75
52
  - - ~>
76
53
  - !ruby/object:Gem::Version
77
- version: '2'
78
- - !ruby/object:Gem::Dependency
79
- name: yard
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ! '>='
84
- - !ruby/object:Gem::Version
85
- version: '0'
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ! '>='
92
- - !ruby/object:Gem::Version
93
- version: '0'
54
+ version: '1.8'
94
55
  - !ruby/object:Gem::Dependency
95
- name: bundler
56
+ name: rake
96
57
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
58
  requirements:
99
- - - ! '>='
59
+ - - '>='
100
60
  - !ruby/object:Gem::Version
101
61
  version: '0'
102
62
  type: :development
103
63
  prerelease: false
104
64
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
65
  requirements:
107
- - - ! '>='
66
+ - - '>='
108
67
  - !ruby/object:Gem::Version
109
68
  version: '0'
110
69
  - !ruby/object:Gem::Dependency
111
- name: rdiscount
70
+ name: rspec
112
71
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
72
  requirements:
115
- - - ! '>='
73
+ - - ~>
116
74
  - !ruby/object:Gem::Version
117
- version: '0'
75
+ version: '2'
118
76
  type: :development
119
77
  prerelease: false
120
78
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
79
  requirements:
123
- - - ! '>='
80
+ - - ~>
124
81
  - !ruby/object:Gem::Version
125
- version: '0'
82
+ version: '2'
126
83
  description:
127
84
  email: kim@burgestrand.se
128
85
  executables: []
@@ -137,7 +94,6 @@ files:
137
94
  - .yardopts
138
95
  - CHANGELOG.md
139
96
  - Gemfile
140
- - LICENSE.txt
141
97
  - QUIRKS
142
98
  - README.markdown
143
99
  - Rakefile
@@ -275,30 +231,26 @@ files:
275
231
  homepage: http://github.com/Burgestrand/Hallon
276
232
  licenses:
277
233
  - X11 License
234
+ metadata: {}
278
235
  post_install_message:
279
236
  rdoc_options: []
280
237
  require_paths:
281
238
  - lib
282
239
  required_ruby_version: !ruby/object:Gem::Requirement
283
- none: false
284
240
  requirements:
285
- - - ! '>='
241
+ - - '>='
286
242
  - !ruby/object:Gem::Version
287
243
  version: '1.9'
288
244
  required_rubygems_version: !ruby/object:Gem::Requirement
289
- none: false
290
245
  requirements:
291
- - - ! '>='
246
+ - - '>='
292
247
  - !ruby/object:Gem::Version
293
248
  version: '0'
294
- segments:
295
- - 0
296
- hash: 1548945263546800899
297
249
  requirements: []
298
250
  rubyforge_project:
299
- rubygems_version: 1.8.24
251
+ rubygems_version: 2.0.3
300
252
  signing_key:
301
- specification_version: 3
253
+ specification_version: 4
302
254
  summary: Hallon allows you to write Ruby applications utilizing the official Spotify
303
255
  C API.
304
256
  test_files:
@@ -1,21 +0,0 @@
1
- Copyright 2012 Kim Burgestrand. All rights reserved.
2
-
3
- Redistribution and use in source and binary forms, with or without modification, are
4
- permitted provided that the following conditions are met:
5
-
6
- 1. Redistributions of source code must retain the above copyright notice, this list of
7
- conditions and the following disclaimer.
8
-
9
- 2. Redistributions in binary form must reproduce the above copyright notice, this list
10
- of conditions and the following disclaimer in the documentation and/or other materials
11
- provided with the distribution.
12
-
13
- THIS SOFTWARE IS PROVIDED BY KIM BURGESTRAND ``AS IS'' AND ANY EXPRESS OR IMPLIED
14
- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
15
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KIM BURGESTRAND OR
16
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
21
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.