/SpotiFire.SpotifyLib/SpotifyTypes/ArtistBrowse.cs

https://github.com/jgauffin/SpotiFire · C# · 381 lines · 321 code · 60 blank · 0 comment · 24 complexity · c84bc6c76a35670c2c16c5b33732d316 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq.Expressions;
  4. using System.Text;
  5. namespace SpotiFire.SpotifyLib
  6. {
  7. public delegate void ArtistBrowseEventHandler(IArtistBrowse sender, ArtistBrowseEventArgs e);
  8. internal class ArtistBrowse : CountedDisposeableSpotifyObject, IArtistBrowse
  9. {
  10. #region Wrapper
  11. private sealed class ArtistBrowseWrapper : DisposeableSpotifyObject, IArtistBrowse
  12. {
  13. internal ArtistBrowse artistBrowse;
  14. public ArtistBrowseWrapper(ArtistBrowse artistBrowse)
  15. {
  16. this.artistBrowse = artistBrowse;
  17. artistBrowse.Complete += new ArtistBrowseEventHandler(artistBrowse_Complete);
  18. }
  19. void artistBrowse_Complete(IArtistBrowse sender, ArtistBrowseEventArgs e)
  20. {
  21. if (sender == artistBrowse)
  22. if (Complete != null)
  23. Complete(this, e);
  24. }
  25. public event ArtistBrowseEventHandler Complete;
  26. protected override void OnDispose()
  27. {
  28. artistBrowse.Complete -= new ArtistBrowseEventHandler(artistBrowse_Complete);
  29. ArtistBrowse.Delete(artistBrowse.artistBrowsePtr);
  30. artistBrowse = null;
  31. }
  32. public sp_error Error
  33. {
  34. get { IsAlive(true); return artistBrowse.Error; }
  35. }
  36. public IArtist Artist
  37. {
  38. get { IsAlive(true); return artistBrowse.Artist; }
  39. }
  40. public IArray<string> PortraitIds
  41. {
  42. get { IsAlive(true); return artistBrowse.PortraitIds; }
  43. }
  44. public IArray<ITrack> Tracks
  45. {
  46. get { IsAlive(true); return artistBrowse.Tracks; }
  47. }
  48. public IArray<IArtist> SimilarArtists
  49. {
  50. get { IsAlive(true); return artistBrowse.SimilarArtists; }
  51. }
  52. public string Biography
  53. {
  54. get { IsAlive(true); return artistBrowse.Biography; }
  55. }
  56. public ISession Session
  57. {
  58. get { IsAlive(true); return artistBrowse.Session; }
  59. }
  60. public bool IsComplete
  61. {
  62. get { IsAlive(true); return artistBrowse.IsComplete; }
  63. }
  64. protected override int IntPtrHashCode()
  65. {
  66. return IsAlive() ? artistBrowse.artistBrowsePtr.GetHashCode() : 0;
  67. }
  68. }
  69. internal static IntPtr GetPointer(IArtistBrowse artistBrowse)
  70. {
  71. if (artistBrowse.GetType() == typeof(ArtistBrowseWrapper))
  72. return ((ArtistBrowseWrapper)artistBrowse).artistBrowse.artistBrowsePtr;
  73. throw new ArgumentException("Invalid artist browse");
  74. }
  75. #endregion
  76. #region Counter
  77. private static Dictionary<IntPtr, ArtistBrowse> artistBrowsers = new Dictionary<IntPtr, ArtistBrowse>();
  78. private static readonly object artistsBrowseLock = new object();
  79. internal static IArtistBrowse Get(Session session, IntPtr artistBrowsePtr)
  80. {
  81. ArtistBrowse artistBrowse;
  82. lock (artistsBrowseLock)
  83. {
  84. if (!artistBrowsers.ContainsKey(artistBrowsePtr))
  85. {
  86. artistBrowsers.Add(artistBrowsePtr, new ArtistBrowse(session, artistBrowsePtr));
  87. }
  88. artistBrowse = artistBrowsers[artistBrowsePtr];
  89. artistBrowse.AddRef();
  90. }
  91. return new ArtistBrowseWrapper(artistBrowse);
  92. }
  93. internal static void Delete(IntPtr artistBrowsePtr)
  94. {
  95. lock (artistsBrowseLock)
  96. {
  97. ArtistBrowse artistBrowse = artistBrowsers[artistBrowsePtr];
  98. int count = artistBrowse.RemRef();
  99. if (count == 0)
  100. artistBrowsers.Remove(artistBrowsePtr);
  101. }
  102. }
  103. #endregion
  104. #region Delegates
  105. internal delegate void artistbrowse_complete_cb(IntPtr artistBrowsePtr, IntPtr userdataPtr);
  106. #endregion
  107. #region Declarations
  108. internal IntPtr artistBrowsePtr = IntPtr.Zero;
  109. private Session session;
  110. private bool isComplete = false;
  111. internal static artistbrowse_complete_cb artistbrowse_complete = new artistbrowse_complete_cb(_ArtistBrowseCompleteCallback);
  112. private IArtist artist;
  113. private DelegateArray<string> portraitIds;
  114. private DelegateArray<ITrack> tracks;
  115. private DelegateArray<IAlbum> albums;
  116. private DelegateArray<IArtist> similarArtists;
  117. private string biography;
  118. #endregion
  119. #region Constructor and setup
  120. private ArtistBrowse(Session session, IntPtr artistBrowsePtr)
  121. {
  122. if (artistBrowsePtr == IntPtr.Zero)
  123. throw new ArgumentException("artistBrowsePtr can't be zero.");
  124. if (session == null)
  125. throw new ArgumentNullException("Session can't be null.");
  126. this.session = session;
  127. this.artistBrowsePtr = artistBrowsePtr;
  128. this.portraitIds = new DelegateArray<string>(() =>
  129. {
  130. IsAlive(true);
  131. lock (libspotify.Mutex)
  132. return libspotify.sp_artistbrowse_num_portraits(artistBrowsePtr);
  133. }, (index) =>
  134. {
  135. IsAlive(true);
  136. lock (libspotify.Mutex)
  137. return libspotify.ImageIdToString(libspotify.sp_artistbrowse_portrait(artistBrowsePtr, index));
  138. });
  139. this.tracks = new DelegateArray<ITrack>(() =>
  140. {
  141. IsAlive(true);
  142. lock (libspotify.Mutex)
  143. return libspotify.sp_artistbrowse_num_tracks(artistBrowsePtr);
  144. }, (index) =>
  145. {
  146. IsAlive(true);
  147. lock (libspotify.Mutex)
  148. return Track.Get(session, libspotify.sp_artistbrowse_track(artistBrowsePtr, index));
  149. });
  150. this.albums = new DelegateArray<IAlbum>(() =>
  151. {
  152. IsAlive(true);
  153. lock (libspotify.Mutex)
  154. return libspotify.sp_artistbrowse_num_albums(artistBrowsePtr);
  155. }, (index) =>
  156. {
  157. IsAlive(true);
  158. lock (libspotify.Mutex)
  159. return Album.Get(session, libspotify.sp_artistbrowse_album(artistBrowsePtr, index));
  160. });
  161. this.similarArtists = new DelegateArray<IArtist>(() =>
  162. {
  163. IsAlive(true);
  164. lock (libspotify.Mutex)
  165. return libspotify.sp_artistbrowse_num_similar_artists(artistBrowsePtr);
  166. }, (index) =>
  167. {
  168. IsAlive(true);
  169. lock (libspotify.Mutex)
  170. return SpotifyLib.Artist.Get(session, libspotify.sp_artistbrowse_similar_artist(artistBrowsePtr, index));
  171. });
  172. _Complete += new artistbrowse_complete_cb(ArtistBrowse__Complete);
  173. session.DisposeAll += new SessionEventHandler(session_DisposeAll);
  174. }
  175. private void ArtistBrowse__Complete(IntPtr artistBrowsePtr, IntPtr userdataPtr)
  176. {
  177. if (artistBrowsePtr == this.artistBrowsePtr)
  178. {
  179. this.isComplete = true;
  180. session.EnqueueEventWorkItem(new EventWorkItem(CreateDelegate<ArtistBrowseEventArgs>(ab => ab.OnComplete, this), new ArtistBrowseEventArgs(this)));
  181. _Complete -= new artistbrowse_complete_cb(ArtistBrowse__Complete);
  182. }
  183. }
  184. static void _ArtistBrowseCompleteCallback(IntPtr artistBrowsePtr, IntPtr userdataPtr)
  185. {
  186. if (_Complete != null)
  187. _Complete(artistBrowsePtr, userdataPtr);
  188. }
  189. #endregion
  190. #region Properties
  191. public sp_error Error
  192. {
  193. get
  194. {
  195. IsAlive(true);
  196. lock (libspotify.Mutex)
  197. return libspotify.sp_artistbrowse_error(artistBrowsePtr);
  198. }
  199. }
  200. public IArtist Artist
  201. {
  202. get
  203. {
  204. if (artist == null)
  205. {
  206. IsAlive(true);
  207. lock (libspotify.Mutex)
  208. artist = SpotifyLib.Artist.Get(session, libspotify.sp_artistbrowse_artist(artistBrowsePtr));
  209. }
  210. return artist;
  211. }
  212. }
  213. public IArray<string> PortraitIds
  214. {
  215. get
  216. {
  217. return portraitIds;
  218. }
  219. }
  220. public IArray<ITrack> Tracks
  221. {
  222. get
  223. {
  224. return tracks;
  225. }
  226. }
  227. public IArray<IArtist> SimilarArtists
  228. {
  229. get
  230. {
  231. return similarArtists;
  232. }
  233. }
  234. public string Biography
  235. {
  236. get
  237. {
  238. if (biography == null)
  239. {
  240. IsAlive(true);
  241. lock (libspotify.Mutex)
  242. biography = libspotify.GetString(libspotify.sp_artistbrowse_biography(artistBrowsePtr), String.Empty);
  243. }
  244. return biography;
  245. }
  246. }
  247. public ISession Session
  248. {
  249. get
  250. {
  251. IsAlive(true);
  252. return session;
  253. }
  254. }
  255. public bool IsComplete
  256. {
  257. get
  258. {
  259. IsAlive(true);
  260. return isComplete;
  261. }
  262. }
  263. #endregion
  264. #region Public methods
  265. public override string ToString()
  266. {
  267. StringBuilder sb = new StringBuilder();
  268. sb.AppendLine("[ArtistBrowse]");
  269. sb.AppendLine("Error=" + Error);
  270. sb.AppendLine(Artist.ToString());
  271. sb.AppendLine("PortraitsIds.Length=" + PortraitIds.Count);
  272. foreach (string portraitId in PortraitIds)
  273. sb.AppendLine(portraitId);
  274. sb.AppendLine("Tracks.Length=" + Tracks.Count);
  275. foreach (Track t in Tracks)
  276. sb.AppendLine(t.ToString());
  277. sb.AppendLine("SimilarArtists.Length=" + SimilarArtists.Count);
  278. foreach (Artist a in SimilarArtists)
  279. sb.AppendLine(a.ToString());
  280. sb.AppendFormat("Biography:{0}{1}", Environment.NewLine, Biography);
  281. return sb.ToString();
  282. }
  283. #endregion
  284. #region Cleanup
  285. protected override void OnDispose()
  286. {
  287. _Complete -= new artistbrowse_complete_cb(ArtistBrowse__Complete);
  288. session.DisposeAll -= new SessionEventHandler(session_DisposeAll);
  289. if (!session.ProcExit)
  290. lock (libspotify.Mutex)
  291. libspotify.sp_artistbrowse_release(artistBrowsePtr);
  292. artistBrowsePtr = IntPtr.Zero;
  293. }
  294. private void session_DisposeAll(ISession sender, SessionEventArgs e)
  295. {
  296. Dispose();
  297. }
  298. #endregion
  299. #region Private methods
  300. private static Delegate CreateDelegate<T>(Expression<Func<ArtistBrowse, Action<T>>> expr, ArtistBrowse ab) where T : ArtistBrowseEventArgs
  301. {
  302. return expr.Compile().Invoke(ab);
  303. }
  304. #endregion
  305. #region Protected Methods
  306. protected virtual void OnComplete(ArtistBrowseEventArgs args)
  307. {
  308. if (this.Complete != null)
  309. this.Complete(this, args);
  310. }
  311. #endregion
  312. #region Event
  313. public event ArtistBrowseEventHandler Complete;
  314. private static event artistbrowse_complete_cb _Complete;
  315. #endregion
  316. protected override int IntPtrHashCode()
  317. {
  318. throw new NotImplementedException();
  319. }
  320. }
  321. }