// Copyright (c) Arlo Godfrey. All Rights Reserved.
// Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms.
// See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Diagnostics;
using OwlCore.Events;
using OwlCore.Extensions;
using StrixMusic.Sdk.AppModels;
using StrixMusic.Sdk.BaseModels;
using StrixMusic.Sdk.CoreModels;
using StrixMusic.Sdk.Extensions;
using StrixMusic.Sdk.MediaPlayback;
namespace StrixMusic.Sdk.AdapterModels
{
///
/// A base that merges multiple s.
///
public abstract class MergedPlayableCollectionGroupBase : IPlayableCollectionGroup, IMergedMutable
where TCoreBase : class, ICorePlayableCollectionGroup, IAsyncDisposable
{
private readonly MergedCollectionMap _albumCollectionMap;
private readonly MergedCollectionMap _artistCollectionMap;
private readonly MergedCollectionMap _playlistCollectionMap;
private readonly MergedCollectionMap _trackCollectionMap;
private readonly MergedCollectionMap _playableCollectionGroupMap;
private readonly MergedCollectionMap _imageCollectionMap;
private readonly MergedCollectionMap _urlCollectionMap;
private readonly SemaphoreSlim _disposeSemaphore = new(1, 1);
private bool _isDisposed;
///
/// Initializes a new instance of the class.
///
protected MergedPlayableCollectionGroupBase(IEnumerable sources, MergedCollectionConfig config)
{
// TODO: Use top Preferred core.
if (sources is null)
throw new ArgumentNullException(nameof(sources));
StoredSources = sources.ToList();
Guard.HasSizeGreaterThan(StoredSources, 0, nameof(StoredSources));
PreferredSource = StoredSources[0];
_albumCollectionMap = new MergedCollectionMap(this, config);
_artistCollectionMap = new MergedCollectionMap(this, config);
_playlistCollectionMap = new MergedCollectionMap(this, config);
_trackCollectionMap = new MergedCollectionMap(this, config);
_playableCollectionGroupMap = new MergedCollectionMap(this, config);
_imageCollectionMap = new MergedCollectionMap(this, config);
_urlCollectionMap = new MergedCollectionMap(this, config);
AttachPropertyChangedEvents(PreferredSource);
AttachCollectionChangedEvents();
foreach (var item in StoredSources)
{
TotalChildrenCount += item.TotalChildrenCount;
TotalPlaylistItemsCount += item.TotalPlaylistItemsCount;
TotalTrackCount += item.TotalTrackCount;
TotalAlbumItemsCount += item.TotalAlbumItemsCount;
TotalArtistItemsCount += item.TotalArtistItemsCount;
TotalImageCount += item.TotalImageCount;
TotalUrlCount += item.TotalUrlCount;
Duration += item.Duration;
}
Name = PreferredSource.Name;
Description = PreferredSource.Description;
PlaybackState = PreferredSource.PlaybackState;
LastPlayed = PreferredSource.LastPlayed;
AddedAt = PreferredSource.AddedAt;
}
///
/// The top preferred source for this item, used for property getters.
///
protected ICorePlayableCollectionGroup PreferredSource { get; }
///
/// The source items that were merged to create this
///
protected List StoredSources { get; }
private void AttachPropertyChangedEvents(ICorePlayableCollectionGroup source)
{
source.PlaybackStateChanged += PlaybackStateChanged;
source.NameChanged += NameChanged;
source.DescriptionChanged += DescriptionChanged;
source.DurationChanged += DurationChanged;
source.LastPlayedChanged += LastPlayedChanged;
source.IsPlayTrackCollectionAsyncAvailableChanged += IsPlayTrackCollectionAsyncAvailableChanged;
source.IsPauseTrackCollectionAsyncAvailableChanged += IsPauseTrackCollectionAsyncAvailableChanged;
source.IsPlayArtistCollectionAsyncAvailableChanged += IsPlayArtistCollectionAsyncAvailableChanged;
source.IsPauseArtistCollectionAsyncAvailableChanged += IsPauseArtistCollectionAsyncAvailableChanged;
source.IsPlayAlbumCollectionAsyncAvailableChanged += IsPlayAlbumCollectionAsyncAvailableChanged;
source.IsPauseAlbumCollectionAsyncAvailableChanged += IsPauseAlbumCollectionAsyncAvailableChanged;
source.IsChangeNameAsyncAvailableChanged += IsChangeNameAsyncAvailableChanged;
source.IsChangeDurationAsyncAvailableChanged += IsChangeDurationAsyncAvailableChanged;
source.IsChangeDescriptionAsyncAvailableChanged += IsChangeDescriptionAsyncAvailableChanged;
}
private void DetachPropertyChangedEvents(ICorePlayableCollectionGroup source)
{
source.PlaybackStateChanged -= PlaybackStateChanged;
source.NameChanged -= NameChanged;
source.DescriptionChanged -= DescriptionChanged;
source.DurationChanged -= DurationChanged;
source.LastPlayedChanged -= LastPlayedChanged;
source.IsPlayTrackCollectionAsyncAvailableChanged -= IsPlayTrackCollectionAsyncAvailableChanged;
source.IsPauseTrackCollectionAsyncAvailableChanged -= IsPauseTrackCollectionAsyncAvailableChanged;
source.IsPlayArtistCollectionAsyncAvailableChanged -= IsPlayArtistCollectionAsyncAvailableChanged;
source.IsPauseArtistCollectionAsyncAvailableChanged -= IsPauseArtistCollectionAsyncAvailableChanged;
source.IsPlayAlbumCollectionAsyncAvailableChanged -= IsPlayAlbumCollectionAsyncAvailableChanged;
source.IsPauseAlbumCollectionAsyncAvailableChanged -= IsPauseAlbumCollectionAsyncAvailableChanged;
source.IsChangeNameAsyncAvailableChanged -= IsChangeNameAsyncAvailableChanged;
source.IsChangeDurationAsyncAvailableChanged -= IsChangeDurationAsyncAvailableChanged;
source.IsChangeDescriptionAsyncAvailableChanged -= IsChangeDescriptionAsyncAvailableChanged;
}
private void AttachCollectionChangedEvents()
{
_albumCollectionMap.ItemsChanged += AlbumCollectionMap_ItemsChanged;
_artistCollectionMap.ItemsChanged += ArtistCollectionMap_ItemsChanged;
_playlistCollectionMap.ItemsChanged += PlaylistCollectionMap_ItemsChanged;
_playableCollectionGroupMap.ItemsChanged += PlayableCollectionGroupMap_ItemsChanged;
_trackCollectionMap.ItemsChanged += TrackCollectionMap_ItemsChanged;
_imageCollectionMap.ItemsChanged += ImagesCollectionMap_ItemsChanged;
_urlCollectionMap.ItemsChanged += UrlsCollectionMap_ItemsChanged;
_albumCollectionMap.ItemsCountChanged += AlbumCollectionMap_ItemsCountChanged;
_artistCollectionMap.ItemsCountChanged += ArtistCollectionMap_ItemsCountChanged;
_trackCollectionMap.ItemsCountChanged += TrackCollectionMap_ItemsCountChanged;
_playlistCollectionMap.ItemsCountChanged += PlaylistCollectionMap_ItemsCountChanged;
_playableCollectionGroupMap.ItemsCountChanged += PlayableCollectionGroupMap_ItemsCountChanged;
_imageCollectionMap.ItemsCountChanged += ImagesCollectionMap_ItemsCountChanged;
_urlCollectionMap.ItemsCountChanged += UrlsCollectionMap_ItemsCountChanged;
}
private void DetachCollectionChangedEvents()
{
_albumCollectionMap.ItemsChanged -= AlbumCollectionMap_ItemsChanged;
_artistCollectionMap.ItemsChanged -= ArtistCollectionMap_ItemsChanged;
_playlistCollectionMap.ItemsChanged -= PlaylistCollectionMap_ItemsChanged;
_playableCollectionGroupMap.ItemsChanged -= PlayableCollectionGroupMap_ItemsChanged;
_trackCollectionMap.ItemsChanged -= TrackCollectionMap_ItemsChanged;
_imageCollectionMap.ItemsChanged -= ImagesCollectionMap_ItemsChanged;
_urlCollectionMap.ItemsChanged -= UrlsCollectionMap_ItemsChanged;
_albumCollectionMap.ItemsCountChanged -= AlbumCollectionMap_ItemsCountChanged;
_artistCollectionMap.ItemsCountChanged -= ArtistCollectionMap_ItemsCountChanged;
_playlistCollectionMap.ItemsCountChanged -= PlaylistCollectionMap_ItemsCountChanged;
_playableCollectionGroupMap.ItemsCountChanged -= PlayableCollectionGroupMap_ItemsCountChanged;
_imageCollectionMap.ItemsCountChanged -= ImagesCollectionMap_ItemsCountChanged;
_trackCollectionMap.ItemsCountChanged -= TrackCollectionMap_ItemsCountChanged;
_urlCollectionMap.ItemsCountChanged -= UrlsCollectionMap_ItemsCountChanged;
}
///
public event EventHandler? PlaybackStateChanged;
///
public event EventHandler? NameChanged;
///
public event EventHandler? DescriptionChanged;
///
public event EventHandler? DurationChanged;
///
public event EventHandler? LastPlayedChanged;
///
public event EventHandler? IsPlayAlbumCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPauseAlbumCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPlayArtistCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPauseArtistCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPlayPlaylistCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPausePlaylistCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPlayTrackCollectionAsyncAvailableChanged;
///
public event EventHandler? IsPauseTrackCollectionAsyncAvailableChanged;
///
public event EventHandler? IsChangeNameAsyncAvailableChanged;
///
public event EventHandler? IsChangeDescriptionAsyncAvailableChanged;
///
public event EventHandler? IsChangeDurationAsyncAvailableChanged;
///
public event EventHandler? TracksCountChanged;
///
public event EventHandler? ArtistItemsCountChanged;
///
public event EventHandler? AlbumItemsCountChanged;
///
public event EventHandler? PlaylistItemsCountChanged;
///
public event EventHandler? ChildrenCountChanged;
///
public event EventHandler? ImagesCountChanged;
///
public event EventHandler? UrlsCountChanged;
///
public event CollectionChangedEventHandler? TracksChanged;
///
public event CollectionChangedEventHandler? ArtistItemsChanged;
///
public event CollectionChangedEventHandler? AlbumItemsChanged;
///
public event CollectionChangedEventHandler? PlaylistItemsChanged;
///
public event CollectionChangedEventHandler? ChildItemsChanged;
///
public event CollectionChangedEventHandler? ImagesChanged;
///
public event CollectionChangedEventHandler? UrlsChanged;
///
public event EventHandler? DownloadInfoChanged;
private void ImagesCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalImageCount = e;
ImagesCountChanged?.Invoke(this, e);
}
private void UrlsCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalUrlCount = e;
UrlsCountChanged?.Invoke(this, e);
}
private void PlayableCollectionGroupMap_ItemsCountChanged(object sender, int e)
{
TotalChildrenCount = e;
ChildrenCountChanged?.Invoke(this, e);
}
private void PlaylistCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalPlaylistItemsCount = e;
PlaylistItemsCountChanged?.Invoke(this, e);
}
private void ArtistCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalArtistItemsCount = e;
ArtistItemsCountChanged?.Invoke(this, e);
}
private void AlbumCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalAlbumItemsCount = e;
AlbumItemsCountChanged?.Invoke(this, e);
}
private void TrackCollectionMap_ItemsCountChanged(object sender, int e)
{
TotalTrackCount = e;
TracksCountChanged?.Invoke(this, e);
}
private void TrackCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
TracksChanged?.Invoke(this, addedItems, removedItems);
}
private void PlayableCollectionGroupMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
ChildItemsChanged?.Invoke(this, addedItems, removedItems);
}
private void PlaylistCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
PlaylistItemsChanged?.Invoke(this, addedItems, removedItems);
}
private void AlbumCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
AlbumItemsChanged?.Invoke(this, addedItems, removedItems);
}
private void ArtistCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
ArtistItemsChanged?.Invoke(this, addedItems, removedItems);
}
private void ImagesCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
ImagesChanged?.Invoke(this, addedItems, removedItems);
}
private void UrlsCollectionMap_ItemsChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems)
{
UrlsChanged?.Invoke(this, addedItems, removedItems);
}
///
public event EventHandler? SourcesChanged;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
IReadOnlyList IMerged.Sources => StoredSources;
///
public virtual IReadOnlyList Sources => StoredSources;
///
public string Id => PreferredSource.Id;
///
public string Name { get; internal set; }
///
public string? Description { get; internal set; }
///
public PlaybackState PlaybackState { get; internal set; }
///
public DownloadInfo DownloadInfo => default;
///
public TimeSpan Duration { get; internal set; } = new TimeSpan(0);
///
public DateTime? LastPlayed { get; internal set; }
///
public DateTime? AddedAt { get; internal set; }
///
public int TotalChildrenCount { get; internal set; }
///
public int TotalPlaylistItemsCount { get; internal set; }
///
public int TotalTrackCount { get; internal set; }
///
public int TotalAlbumItemsCount { get; internal set; }
///
public int TotalArtistItemsCount { get; internal set; }
///
public int TotalImageCount { get; internal set; }
///
public int TotalUrlCount { get; internal set; }
///
public virtual bool IsPlayAlbumCollectionAsyncAvailable => PreferredSource.IsPlayAlbumCollectionAsyncAvailable;
///
public virtual bool IsPauseAlbumCollectionAsyncAvailable => PreferredSource.IsPauseAlbumCollectionAsyncAvailable;
///
public virtual bool IsPlayArtistCollectionAsyncAvailable => PreferredSource.IsPlayArtistCollectionAsyncAvailable;
///
public virtual bool IsPauseArtistCollectionAsyncAvailable => PreferredSource.IsPauseArtistCollectionAsyncAvailable;
///
public virtual bool IsPlayPlaylistCollectionAsyncAvailable => PreferredSource.IsPlayPlaylistCollectionAsyncAvailable;
///
public virtual bool IsPausePlaylistCollectionAsyncAvailable => PreferredSource.IsPausePlaylistCollectionAsyncAvailable;
///
public virtual bool IsPlayTrackCollectionAsyncAvailable => PreferredSource.IsPlayTrackCollectionAsyncAvailable;
///
public virtual bool IsPauseTrackCollectionAsyncAvailable => PreferredSource.IsPauseTrackCollectionAsyncAvailable;
///
public virtual bool IsChangeNameAsyncAvailable => PreferredSource.IsChangeNameAsyncAvailable;
///
public virtual bool IsChangeDescriptionAsyncAvailable => PreferredSource.IsChangeDescriptionAsyncAvailable;
///
public virtual bool IsChangeDurationAsyncAvailable => PreferredSource.IsChangeDurationAsyncAvailable;
///
public Task IsAddTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => _trackCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _albumCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _artistCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddPlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _playlistCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddChildAvailableAsync(int index, CancellationToken cancellationToken = default) => _playableCollectionGroupMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => _imageCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => _urlCollectionMap.IsAddItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => _trackCollectionMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _artistCollectionMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _albumCollectionMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemovePlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => _playableCollectionGroupMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveChildAvailableAsync(int index, CancellationToken cancellationToken = default) => _playableCollectionGroupMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => _imageCollectionMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => _urlCollectionMap.IsRemoveItemAvailableAsync(index, cancellationToken);
///
public Task PauseAlbumCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PauseAlbumCollectionAsync(cancellationToken);
///
public Task PlayAlbumCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PlayAlbumCollectionAsync(cancellationToken);
///
public Task PauseArtistCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PauseArtistCollectionAsync(cancellationToken);
///
public Task PlayArtistCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PlayArtistCollectionAsync(cancellationToken);
///
public Task PausePlaylistCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PausePlaylistCollectionAsync(cancellationToken);
///
public Task PlayPlaylistCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PlayPlaylistCollectionAsync(cancellationToken);
///
public Task PauseTrackCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PauseTrackCollectionAsync(cancellationToken);
///
public Task PlayTrackCollectionAsync(CancellationToken cancellationToken) => PreferredSource.PlayTrackCollectionAsync(cancellationToken);
///
public Task PlayPlayableCollectionGroupAsync(CancellationToken cancellationToken) => PreferredSource.PlayPlayableCollectionGroupAsync(cancellationToken);
///
public Task PausePlayableCollectionGroupAsync(CancellationToken cancellationToken) => PreferredSource.PausePlayableCollectionGroupAsync(cancellationToken);
///
public Task PlayTrackCollectionAsync(ITrack track, CancellationToken cancellationToken = default)
{
var targetCore = PreferredSource.SourceCore;
var source = track.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
Guard.IsNotNull(source, nameof(source));
return PreferredSource.PlayTrackCollectionAsync(source, cancellationToken);
}
///
public Task PlayArtistCollectionAsync(IArtistCollectionItem artistItem, CancellationToken cancellationToken = default)
{
var targetCore = PreferredSource.SourceCore;
ICoreArtistCollectionItem? source = null;
if (artistItem is IArtist artist)
source = artist.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
if (artistItem is IArtistCollection collection)
source = collection.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
Guard.IsNotNull(source, nameof(source));
return PreferredSource.PlayArtistCollectionAsync(source, cancellationToken);
}
///
public Task PlayAlbumCollectionAsync(IAlbumCollectionItem albumItem, CancellationToken cancellationToken = default)
{
var targetCore = PreferredSource.SourceCore;
ICoreAlbumCollectionItem? source = null;
if (albumItem is IAlbum album)
source = album.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
if (albumItem is IAlbumCollection collection)
source = collection.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
Guard.IsNotNull(source, nameof(source));
return PreferredSource.PlayAlbumCollectionAsync(source, cancellationToken);
}
///
public Task PlayPlaylistCollectionAsync(IPlaylistCollectionItem playlistItem, CancellationToken cancellationToken = default)
{
var targetCore = PreferredSource.SourceCore;
ICorePlaylistCollectionItem? source = null;
if (playlistItem is IPlaylist playlist)
source = playlist.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
if (playlistItem is IPlaylistCollection collection)
source = collection.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
Guard.IsNotNull(source, nameof(source));
return PreferredSource.PlayPlaylistCollectionAsync(source, cancellationToken);
}
///
public Task PlayPlayableCollectionGroupAsync(IPlayableCollectionGroup collectionGroup, CancellationToken cancellationToken = default)
{
var targetCore = PreferredSource.SourceCore;
var source = collectionGroup.GetSources().FirstOrDefault(x => x.SourceCore.InstanceId == targetCore.InstanceId);
Guard.IsNotNull(source, nameof(source));
return PreferredSource.PlayPlayableCollectionGroupAsync(source, cancellationToken);
}
///
public IAsyncEnumerable GetAlbumItemsAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _albumCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetArtistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _artistCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetChildrenAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _playableCollectionGroupMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetPlaylistItemsAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _playlistCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetTracksAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _trackCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetImagesAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _imageCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public IAsyncEnumerable GetUrlsAsync(int limit, int offset, CancellationToken cancellationToken = default)
{
return _urlCollectionMap.GetItemsAsync(limit, offset, cancellationToken);
}
///
public Task ChangeNameAsync(string name, CancellationToken cancellationToken = default)
{
return Sources.InParallel(source => source.IsChangeNameAsyncAvailable ? source.ChangeNameAsync(name) : Task.CompletedTask);
}
///
public Task ChangeDescriptionAsync(string? description, CancellationToken cancellationToken = default)
{
return Sources.InParallel(source => source.IsChangeDescriptionAsyncAvailable ? source.ChangeDescriptionAsync(description) : Task.CompletedTask);
}
///
public Task ChangeDurationAsync(TimeSpan duration, CancellationToken cancellationToken = default)
{
return Sources.InParallel(source => source.IsChangeDurationAsyncAvailable ? source.ChangeDurationAsync(duration) : Task.CompletedTask);
}
///
public Task AddTrackAsync(ITrack track, int index, CancellationToken cancellationToken = default)
{
return _trackCollectionMap.InsertItemAsync(track, index, cancellationToken);
}
///
public Task AddArtistItemAsync(IArtistCollectionItem artistItem, int index, CancellationToken cancellationToken = default)
{
return _artistCollectionMap.InsertItemAsync(artistItem, index, cancellationToken);
}
///
public Task AddAlbumItemAsync(IAlbumCollectionItem albumItem, int index, CancellationToken cancellationToken = default)
{
return _albumCollectionMap.InsertItemAsync(albumItem, index, cancellationToken);
}
///
public Task AddPlaylistItemAsync(IPlaylistCollectionItem playlistItem, int index, CancellationToken cancellationToken = default)
{
return _playlistCollectionMap.InsertItemAsync(playlistItem, index, cancellationToken);
}
///
public Task AddChildAsync(IPlayableCollectionGroup child, int index, CancellationToken cancellationToken = default)
{
return _playableCollectionGroupMap.InsertItemAsync(child, index, cancellationToken);
}
///
public Task AddImageAsync(IImage image, int index, CancellationToken cancellationToken = default)
{
return _imageCollectionMap.InsertItemAsync(image, index, cancellationToken);
}
///
public Task AddUrlAsync(IUrl url, int index, CancellationToken cancellationToken = default)
{
return _urlCollectionMap.InsertItemAsync(url, index, cancellationToken);
}
///
public Task RemoveTrackAsync(int index, CancellationToken cancellationToken = default)
{
return _trackCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemoveArtistItemAsync(int index, CancellationToken cancellationToken = default)
{
return _artistCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemoveAlbumItemAsync(int index, CancellationToken cancellationToken = default)
{
return _albumCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemovePlaylistItemAsync(int index, CancellationToken cancellationToken = default)
{
return _playlistCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemoveChildAsync(int index, CancellationToken cancellationToken = default)
{
return _playableCollectionGroupMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemoveImageAsync(int index, CancellationToken cancellationToken = default)
{
return _imageCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default)
{
return _urlCollectionMap.RemoveAtAsync(index, cancellationToken);
}
///
public Task StartDownloadOperationAsync(DownloadOperation operation, CancellationToken cancellationToken = default)
{
throw new NotSupportedException();
}
///
public void AddSource(TCoreBase itemToAdd)
{
Guard.IsNotNull(itemToAdd, nameof(itemToAdd));
if (!Equals(itemToAdd))
ThrowHelper.ThrowArgumentException("Tried to merge an artistItem that doesn't match. Verify that the item matches before merging the source.");
StoredSources.Add(itemToAdd);
_albumCollectionMap.AddSource(itemToAdd);
_artistCollectionMap.AddSource(itemToAdd);
_playableCollectionGroupMap.AddSource(itemToAdd);
_playlistCollectionMap.AddSource(itemToAdd);
_trackCollectionMap.AddSource(itemToAdd);
_imageCollectionMap.AddSource(itemToAdd);
_urlCollectionMap.AddSource(itemToAdd);
SourcesChanged?.Invoke(this, EventArgs.Empty);
}
///
public void RemoveSource(TCoreBase itemToRemove)
{
Guard.IsNotNull(itemToRemove, nameof(itemToRemove));
StoredSources.Remove(itemToRemove);
_albumCollectionMap.RemoveSource(itemToRemove);
_artistCollectionMap.RemoveSource(itemToRemove);
_playableCollectionGroupMap.RemoveSource(itemToRemove);
_playlistCollectionMap.RemoveSource(itemToRemove);
_trackCollectionMap.RemoveSource(itemToRemove);
_imageCollectionMap.RemoveSource(itemToRemove);
_urlCollectionMap.RemoveSource(itemToRemove);
SourcesChanged?.Invoke(this, EventArgs.Empty);
}
///
public bool Equals(ICorePlaylistCollectionItem other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICorePlaylistCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreTrackCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreAlbumCollectionItem other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreAlbumCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreArtistCollectionItem other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreArtistCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICorePlayableCollectionGroupChildren other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreImageCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICoreUrlCollection other) => Equals(other as ICorePlayableCollectionGroup);
///
public bool Equals(ICorePlayableCollectionGroup? other)
{
return Equals(other as TCoreBase);
}
///
/// Overrides the default equality comparer.
///
/// The object to compare.
/// True if this is a match, otherwise false.
public virtual bool Equals(TCoreBase? other)
{
return other != null && other.Name.Equals(Name, StringComparison.InvariantCulture);
}
///
public async ValueTask DisposeAsync()
{
if (_isDisposed)
return;
using (await OwlCore.Flow.EasySemaphore(_disposeSemaphore))
{
if (_isDisposed)
return;
DetachCollectionChangedEvents();
DetachPropertyChangedEvents(PreferredSource);
await _albumCollectionMap.DisposeAsync();
await _artistCollectionMap.DisposeAsync();
await _playableCollectionGroupMap.DisposeAsync();
await _playlistCollectionMap.DisposeAsync();
await _trackCollectionMap.DisposeAsync();
await _imageCollectionMap.DisposeAsync();
await _urlCollectionMap.DisposeAsync();
await Sources.InParallel(x => x.DisposeAsync().AsTask());
_isDisposed = true;
}
}
}
}