Class: Spotify::ManagedPointer Private
- Inherits:
-
FFI::AutoPointer
- Object
- FFI::AutoPointer
- Spotify::ManagedPointer
- Extended by:
- TypeSafety
- Defined in:
- lib/spotify/managed_pointer.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
The default ManagedPointer does not retain its pointer after initialization, but provides a class that does through ManagedPointer.retaining_class. This is better as it allows you to err on the side of segfaulting, instead of leaking memory.
An autopointer base class for Spotify pointers.
It contains a default implementation for release, retain, and a default constructor. When the underlying pointer is garbage collected, the pointer is released automatically.
This class is never instantiated; instead you’ll be dealing with any of it’s subclasses.
Direct Known Subclasses
Album, AlbumBrowse, Artist, ArtistBrowse, Image, Inbox, Link, Playlist, PlaylistContainer, Search, Session, ToplistBrowse, Track, User
Class Method Summary collapse
-
.from_native(pointer, ctx) ⇒ Object
private
Casts all null pointers to nil.
-
.release(pointer) ⇒ Object
private
Schedules given pointer for release.
-
.retain(pointer) ⇒ Object
private
Retains the given pointer if it is not null.
-
.retaining_class ⇒ self
private
Retaining class is needed for the functions that return a pointer that does not have its reference count increased.
-
.size ⇒ Integer
private
Size of the native type, defined for JRuby.
-
.to_native(value, ctx) ⇒ Object
private
Makes all ManagedPointers typesafe in the sense that they will raise an argument error on any value that is not of the same kind.
-
.type ⇒ Object
private
Retrieves the normalized and downcased name of self, so for Spotify::Album we’ll receive just “album”.
Instance Method Summary collapse
-
#free ⇒ Object
private
Immediately releases the underlying pointer.
-
#inspect ⇒ String
(also: #to_s)
private
String representation of self.
- #type ⇒ Object private
Methods included from TypeSafety
Class Method Details
.from_native(pointer, ctx) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Casts all null pointers to nil.
59 60 61 62 |
# File 'lib/spotify/managed_pointer.rb', line 59 def from_native(pointer, ctx) value = super value unless value.null? end |
.release(pointer) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Schedules given pointer for release.
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/spotify/managed_pointer.rb', line 24 def release(pointer) unless pointer.null? # this is to circumvent the type protection, and wrap the pointer # with the correct type for later freeing freeable = type_class.new(pointer) # and this is to not make this pointer trigger release again freeable.autorelease = false Spotify.performer.async { freeable.free } end end |
.retain(pointer) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Retains the given pointer if it is not null.
This method derives the retain method from the class name.
41 42 43 44 45 46 |
# File 'lib/spotify/managed_pointer.rb', line 41 def retain(pointer) unless pointer.null? Spotify.log "Spotify.#{type}_add_ref(#{pointer.inspect})" Spotify.public_send(:"#{type}_add_ref", pointer) end end |
.retaining_class ⇒ self
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Retaining class is needed for the functions that return a pointer that does not have its reference count increased. This class is a subclass of the ManagedPointer, and should behave the same in all circumstances except for during initialization.
This dynamic method is needed to DRY the pointers up. We have about ten subclasses of ManagedPointer; all of them need a subclass that retains its pointer on initialization. We could create one manually for each Album, Artist, Track, and so on, but that would be annoying.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/spotify/managed_pointer.rb', line 81 def retaining_class if defined?(self::Retaining) self::Retaining else subclass = Class.new(self) do class << self def type superclass.type end protected def type_class superclass end end alias_method :super_initialize, :initialize def initialize(*args, &block) super_initialize(*args, &block) self.class.retain(self) end end const_set("Retaining", subclass) end end |
.size ⇒ Integer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns size of the native type, defined for JRuby.
66 67 68 |
# File 'lib/spotify/managed_pointer.rb', line 66 def size FFI.type_size(:pointer) end |
.to_native(value, ctx) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Makes all ManagedPointers typesafe in the sense that they will raise an argument error on any value that is not of the same kind.
50 51 52 53 54 55 56 |
# File 'lib/spotify/managed_pointer.rb', line 50 def to_native(value, ctx) if value.nil? or value.null? raise TypeError, "#{name} pointers cannot be null, was #{value.inspect}" else super end end |
.type ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Retrieves the normalized and downcased name of self, so for Spotify::Album we’ll receive just “album”.
111 112 113 |
# File 'lib/spotify/managed_pointer.rb', line 111 def type name.split('::')[-1].downcase end |
Instance Method Details
#free ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Does NOT call self.class.release.
This is NOT idempotent.
Immediately releases the underlying pointer.
125 126 127 128 129 130 131 |
# File 'lib/spotify/managed_pointer.rb', line 125 def free unless null? self.autorelease = false Spotify.log "Spotify.#{type}_release(#{inspect})" Spotify.public_send(:"#{type}_release", self) end end |
#inspect ⇒ String Also known as: to_s
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns string representation of self.
134 135 136 |
# File 'lib/spotify/managed_pointer.rb', line 134 def inspect "#<#{self.class} address=0x%x>" % address end |
#type ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
117 118 119 |
# File 'lib/spotify/managed_pointer.rb', line 117 def type self.class.type end |