Made repository methods asynchronous. Simplified playlist repository. Use playlist manager in the app, and left playlist repository to only be used by the playlist manager.

This commit is contained in:
2026-07-24 09:49:58 -04:00
parent 0acbab1215
commit 63938b0139
14 changed files with 181 additions and 96 deletions

View File

@@ -8,10 +8,10 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
protected abstract string Extension { get; }
protected abstract string GetNewFileName();
protected abstract string Serialize(TObject playlist);
protected abstract TObject Deserialize(Stream stream);
protected abstract Task<string> SerializeAsync(TObject playlist);
protected abstract Task<TObject> DeserializeAsync(Stream stream);
public FileRepository()
public async Task InitializeAsync()
{
if (string.IsNullOrWhiteSpace(DirectoryName))
return;
@@ -23,7 +23,7 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
return;
List<string> fileNames = GetAllFileNames();
LoadFileNamesIntoMap(fileNames);
await LoadFileNamesIntoMapAsync(fileNames);
}
private List<string> GetAllFileNames()
@@ -36,7 +36,7 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
return [.. fileInfoList.Select(fileInfo => fileInfo.FullName)];
}
private void LoadFileNamesIntoMap(List<string> fileNames)
private async Task LoadFileNamesIntoMapAsync(List<string> fileNames)
{
foreach (var fileName in fileNames)
{
@@ -44,7 +44,7 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
try
{
TObject obj = Deserialize(textReader.BaseStream);
TObject obj = await DeserializeAsync(textReader.BaseStream);
_fileNameMap.Add(obj, fileName);
}
catch (Exception)
@@ -59,9 +59,9 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
return [.. _fileNameMap.Keys];
}
public void Save(TObject obj)
public async Task SaveAsync(TObject obj)
{
string serializedObject = Serialize(obj);
string serializedObject = await SerializeAsync(obj);
string fileName = Path.Combine(DirectoryName, GetFileName(obj));
string? path = Path.GetDirectoryName(fileName);
@@ -72,8 +72,10 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
if (Directory.Exists(path) == false)
Directory.CreateDirectory(path);
using TextWriter textWriter = new StreamWriter(fileName);
textWriter.Write(serializedObject);
//using TextWriter textWriter = new StreamWriter(fileName);
//await textWriter.WriteAsync(serializedObject);
await File.WriteAllTextAsync(fileName, serializedObject);
}
private string GetFileName(TObject obj)
@@ -91,6 +93,8 @@ public abstract class FileRepository<TObject> : IRepository<TObject> where TObje
{
string fileName = Path.Combine(DirectoryName, GetFileName(obj));
_fileNameMap.Remove(obj);
if (File.Exists(fileName))
File.Delete(fileName);
}

View File

@@ -2,7 +2,8 @@
public interface IRepository<TObject>
{
Task InitializeAsync();
List<TObject> Get();
void Save(TObject value);
Task SaveAsync(TObject value);
void Delete(TObject value);
}

View File

@@ -14,13 +14,19 @@ public abstract class JsonFileRepository<TObject> : FileRepository<TObject> wher
protected override string Extension => "json";
protected override TObject Deserialize(Stream stream)
protected override async Task<TObject> DeserializeAsync(Stream stream)
{
return JsonSerializer.Deserialize<TObject>(stream) ?? new();
return await JsonSerializer.DeserializeAsync<TObject>(stream) ?? new();
}
protected override string Serialize(TObject obj)
protected override async Task<string> SerializeAsync(TObject obj)
{
return JsonSerializer.Serialize(obj, _options);
using MemoryStream memoryStream = new();
await JsonSerializer.SerializeAsync(memoryStream, obj, _options);
memoryStream.Position = 0;
using StreamReader reader = new(memoryStream);
return await reader.ReadToEndAsync();
}
}

View File

@@ -2,20 +2,20 @@
namespace Harmonia.Core.Data;
public abstract class XMLFileRepository<TObject> : FileRepository<TObject> where TObject : notnull, new()
public abstract class XmlFileRepository<TObject> : FileRepository<TObject> where TObject : notnull, new()
{
private readonly XmlSerializer _serializer = new(typeof(TObject));
protected override string Extension => "xml";
protected override TObject Deserialize(Stream stream)
protected override async Task<TObject> DeserializeAsync(Stream stream)
{
using TextReader textReader = new StreamReader(stream);
return (TObject?)_serializer.Deserialize(textReader) ?? new();
}
protected override string Serialize(TObject obj)
protected override async Task<string> SerializeAsync(TObject obj)
{
using TextWriter textWriter = new StringWriter();

View File

@@ -24,4 +24,16 @@ public static class ServiceCollectionExtensions
return services;
}
}
public static class ServiceProviderExtensions
{
public static async Task InitializeHarmoniaAsync(this IServiceProvider serviceProvider)
{
IPlaylistRepository playlistRepository = serviceProvider.GetRequiredService<IPlaylistRepository>();
await playlistRepository.InitializeAsync();
IPlaylistManager playlistManager = serviceProvider.GetRequiredService<IPlaylistManager>();
await playlistManager.InitializeAsync();
}
}

View File

@@ -7,7 +7,7 @@ namespace Harmonia.Core.Player;
public class AudioPlayer : IAudioPlayer
{
private readonly IAudioEngine _audioEngine;
private readonly IPlaylistRepository _playlistRepository;
private readonly IPlaylistManager _playlistManager;
private Playlist? _playlist;
public Playlist? Playlist
@@ -117,13 +117,13 @@ public class AudioPlayer : IAudioPlayer
public event EventHandler? PlayingSongChanged;
public event PropertyChangedEventHandler? PropertyChanged;
public AudioPlayer(IAudioEngine audioEngine, IPlaylistRepository playlistRepository)
public AudioPlayer(IAudioEngine audioEngine, IPlaylistManager playlistManager)
{
_audioEngine = audioEngine;
_audioEngine.StreamFinished += OnAudioEngineStreamFinished;
_audioEngine.StateChanged += OnMusicEngineStateChanged;
_playlistRepository = playlistRepository;
_playlistManager = playlistManager;
}
private async void OnAudioEngineStreamFinished(object? sender, EventArgs e)
@@ -231,10 +231,7 @@ public class AudioPlayer : IAudioPlayer
{
if (Playlist == null || Playlist.Songs.Contains(song) == false)
{
//Playlist? newPlaylist = _playlistRepository.GetPlaylist(song);
Playlist? newPlaylist = _playlistRepository.Get().FirstOrDefault(playlist =>
playlist.Songs.Contains(song));
Playlist? newPlaylist = _playlistManager.GetPlaylist(song);
if (newPlaylist == null)
return false;

View File

@@ -2,10 +2,13 @@
public interface IPlaylistManager
{
IReadOnlyList<Playlist> Playlists { get; }
Playlist? CurrentPlaylist { get; set; }
void AddPlaylist();
Task InitializeAsync();
Task<Playlist> AddPlaylistAsync();
void RemovePlaylist(Playlist playlist);
Playlist? GetPlaylist(PlaylistSong playlistSong);
event EventHandler? CurrentPlaylistChanged;
event EventHandler<PlaylistAddedEventArgs> PlaylistAdded;

View File

@@ -5,9 +5,9 @@ namespace Harmonia.Core.Playlists;
public interface IPlaylistRepository : IRepository<Playlist>
{
Playlist? GetPlaylist(PlaylistSong playlistSong);
void AddPlaylist();
void RemovePlaylist(Playlist playlist);
//void AddPlaylist();
//void RemovePlaylist(Playlist playlist);
event EventHandler<PlaylistAddedEventArgs> PlaylistAdded;
event EventHandler<PlaylistRemovedEventArgs> PlaylistRemoved;
//event EventHandler<PlaylistAddedEventArgs> PlaylistAdded;
//event EventHandler<PlaylistRemovedEventArgs> PlaylistRemoved;
}

View File

@@ -1,7 +1,12 @@
namespace Harmonia.Core.Playlists;
public class PlaylistManager(IPlaylistRepository playlistRepository) : IPlaylistManager
public class PlaylistManager : IPlaylistManager
{
private readonly IPlaylistRepository playlistRepository;
private readonly List<Playlist> _playlists = [];
public IReadOnlyList<Playlist> Playlists => _playlists;
private Playlist? _currentPlaylist;
public Playlist? CurrentPlaylist
{
@@ -20,22 +25,60 @@ public class PlaylistManager(IPlaylistRepository playlistRepository) : IPlaylist
public event EventHandler<PlaylistAddedEventArgs>? PlaylistAdded;
public event EventHandler<PlaylistRemovedEventArgs>? PlaylistRemoved;
public void AddPlaylist()
public PlaylistManager(IPlaylistRepository playlistRepository)
{
this.playlistRepository = playlistRepository;
}
public async Task InitializeAsync()
{
_playlists.AddRange(playlistRepository.Get());
foreach (Playlist playlist in _playlists)
{
playlist.PlaylistUpdated += OnPlaylistUpdated;
}
CurrentPlaylist = _playlists.Count > 0 ? _playlists[0] : await AddPlaylistAsync();
}
public async Task<Playlist> AddPlaylistAsync()
{
Playlist playlist = new()
{
Name = "New Playlist"
};
playlistRepository.Save(playlist);
playlist.PlaylistUpdated += OnPlaylistUpdated;
_playlists.Add(playlist);
await playlistRepository.SaveAsync(playlist);
PlaylistAdded?.Invoke(this, new(playlist));
return playlist;
}
public void RemovePlaylist(Playlist playlist)
{
playlist.PlaylistUpdated -= OnPlaylistUpdated;
_playlists.Remove(playlist);
playlistRepository.Delete(playlist);
PlaylistRemoved?.Invoke(this, new(playlist));
}
public Playlist? GetPlaylist(PlaylistSong playlistSong)
{
return _playlists.FirstOrDefault(playlist => playlist.Songs.Any(song => song.UID == playlistSong.UID));
}
private async void OnPlaylistUpdated(object? sender, PlaylistUpdatedEventArgs e)
{
if (sender is not Playlist playlist)
return;
await playlistRepository.SaveAsync(playlist);
}
}

View File

@@ -6,26 +6,26 @@ public class PlaylistRepository : JsonFileRepository<Playlist>, IPlaylistReposit
{
protected override string DirectoryName => Path.Combine("Playlists");
public PlaylistRepository()
{
List<Playlist> playlists = Get();
//public PlaylistRepository()
//{
// List<Playlist> playlists = Get();
foreach (Playlist playlist in playlists)
{
playlist.PlaylistUpdated += OnPlaylistUpdated;
}
// foreach (Playlist playlist in playlists)
// {
// playlist.PlaylistUpdated += OnPlaylistUpdated;
// }
if (playlists.Count == 0)
AddPlaylist();
}
// if (playlists.Count == 0)
// AddPlaylist();
//}
private void OnPlaylistUpdated(object? sender, PlaylistUpdatedEventArgs e)
{
if (sender is not Playlist playlist)
return;
//private void OnPlaylistUpdated(object? sender, PlaylistUpdatedEventArgs e)
//{
// if (sender is not Playlist playlist)
// return;
Save(playlist);
}
// Save(playlist);
//}
public Playlist? GetPlaylist(PlaylistSong playlistSong)
{
@@ -46,27 +46,27 @@ public class PlaylistRepository : JsonFileRepository<Playlist>, IPlaylistReposit
throw new Exception("Unable to determine new fileName");
}
public event EventHandler<PlaylistAddedEventArgs>? PlaylistAdded;
public event EventHandler<PlaylistRemovedEventArgs>? PlaylistRemoved;
//public event EventHandler<PlaylistAddedEventArgs>? PlaylistAdded;
//public event EventHandler<PlaylistRemovedEventArgs>? PlaylistRemoved;
public void AddPlaylist()
{
Playlist playlist = new()
{
Name = "New Playlist"
};
//public void AddPlaylist()
//{
// Playlist playlist = new()
// {
// Name = "New Playlist"
// };
playlist.PlaylistUpdated += OnPlaylistUpdated;
// playlist.PlaylistUpdated += OnPlaylistUpdated;
Save(playlist);
PlaylistAdded?.Invoke(this, new(playlist));
}
// Save(playlist);
// PlaylistAdded?.Invoke(this, new(playlist));
//}
public void RemovePlaylist(Playlist playlist)
{
playlist.PlaylistUpdated -= OnPlaylistUpdated;
//public void RemovePlaylist(Playlist playlist)
//{
// playlist.PlaylistUpdated -= OnPlaylistUpdated;
Delete(playlist);
PlaylistRemoved?.Invoke(this, new(playlist));
}
// Delete(playlist);
// PlaylistRemoved?.Invoke(this, new(playlist));
//}
}