Little code organization tweaks

This commit is contained in:
Théo Marchal 2021-09-03 00:21:15 +02:00
parent be8cef35d3
commit b87bff54c4
6 changed files with 140 additions and 83 deletions

View File

@ -36,6 +36,9 @@ namespace unison
private readonly System.Timers.Timer _elapsedTimer; private readonly System.Timers.Timer _elapsedTimer;
private DispatcherTimer _retryTimer; private DispatcherTimer _retryTimer;
bool _isUpdatingStatus = false;
bool _isUpdatingSong = false;
private event EventHandler ConnectionChanged; private event EventHandler ConnectionChanged;
private event EventHandler StatusChanged; private event EventHandler StatusChanged;
private event EventHandler SongChanged; private event EventHandler SongChanged;
@ -117,6 +120,44 @@ namespace unison
}); });
} }
public void SendCommand<T>(IMpcCommand<T> command)
{
Task.Run(async () =>
{
await SafelySendCommandAsync(command);
});
}
public async Task<T> SafelySendCommandAsync<T>(IMpcCommand<T> command)
{
if (_commandConnection == null)
{
Trace.WriteLine("[SafelySendCommandAsync] no command connection");
return default(T);
}
try
{
IMpdMessage<T> response = await _commandConnection.SendAsync(command);
if (!response.IsResponseValid)
{
var mpdError = response.Response?.Result?.MpdError;
if (mpdError != null && mpdError != "")
throw new Exception(mpdError);
else
throw new Exception($"Invalid server response: {response}.");
}
return response.Response.Content;
}
catch (Exception e)
{
Trace.WriteLine($"Sending {command.GetType().Name} failed: {e.Message}");
}
return default(T);
}
private void Initialize(object sender, EventArgs e) private void Initialize(object sender, EventArgs e)
{ {
if (!_connected) if (!_connected)
@ -177,6 +218,16 @@ namespace unison
return connection; return connection;
} }
private void Disconnected()
{
_connected = false;
_connection = null;
_commandConnection = null;
ConnectionChanged?.Invoke(this, EventArgs.Empty);
}
private void Loop(CancellationToken token) private void Loop(CancellationToken token)
{ {
Task.Run(async () => Task.Run(async () =>
@ -205,16 +256,6 @@ namespace unison
}).ConfigureAwait(false); }).ConfigureAwait(false);
} }
private void Disconnected()
{
_connected = false;
_connection = null;
_commandConnection = null;
ConnectionChanged?.Invoke(this, EventArgs.Empty);
}
private async Task HandleIdleResponseAsync(string subsystems) private async Task HandleIdleResponseAsync(string subsystems)
{ {
try try
@ -224,9 +265,7 @@ namespace unison
await UpdateStatusAsync(); await UpdateStatusAsync();
if (subsystems.Contains("player")) if (subsystems.Contains("player"))
{
await UpdateSongAsync(); await UpdateSongAsync();
}
} }
} }
catch (Exception e) catch (Exception e)
@ -235,12 +274,11 @@ namespace unison
} }
} }
bool _isUpdatingStatus = false;
private async Task UpdateStatusAsync() private async Task UpdateStatusAsync()
{ {
if (_connection == null) return; if (_connection == null || _isUpdatingStatus)
return;
if (_isUpdatingStatus) return;
_isUpdatingStatus = true; _isUpdatingStatus = true;
try try
@ -258,15 +296,15 @@ namespace unison
{ {
Trace.WriteLine($"Error in Idle connection thread: {e.Message}"); Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
} }
_isUpdatingStatus = false; _isUpdatingStatus = false;
} }
bool _isUpdatingSong = false;
private async Task UpdateSongAsync() private async Task UpdateSongAsync()
{ {
if (_connection == null) return; if (_connection == null || _isUpdatingSong)
return;
if (_isUpdatingSong) return;
_isUpdatingSong = true; _isUpdatingSong = true;
try try
@ -278,57 +316,17 @@ namespace unison
UpdateSong(); UpdateSong();
} }
else else
{
throw new Exception(); throw new Exception();
}
} }
catch (Exception e) catch (Exception e)
{ {
Trace.WriteLine($"Error in Idle connection thread: {e.Message}"); Trace.WriteLine($"Error in Idle connection thread: {e.Message}");
} }
_isUpdatingSong = false; _isUpdatingSong = false;
} }
public void SendCommand<T>(IMpcCommand<T> command) private async void GetAlbumCover(string path, CancellationToken token = default)
{
Task.Run(async () =>
{
await SafelySendCommandAsync(command);
});
}
public async Task<T> SafelySendCommandAsync<T>(IMpcCommand<T> command)
{
if (_commandConnection == null)
{
Trace.WriteLine("[SafelySendCommandAsync] no command connection");
return default(T);
}
try
{
IMpdMessage<T> response = await _commandConnection.SendAsync(command);
if (!response.IsResponseValid)
{
// If we have an MpdError string, only show that as the error to avoid extra noise
var mpdError = response.Response?.Result?.MpdError;
if (mpdError != null && mpdError != "")
throw new Exception(mpdError);
else
throw new Exception($"Invalid server response: {response}.");
}
return response.Response.Content;
}
catch (Exception e)
{
Trace.WriteLine($"Sending {command.GetType().Name} failed: {e.Message}");
}
return default(T);
}
private async void GetAlbumBitmap(string path, CancellationToken token = default)
{ {
List<byte> data = new List<byte>(); List<byte> data = new List<byte>();
try try
@ -370,11 +368,23 @@ namespace unison
UpdateCover(); UpdateCover();
} }
public void UpdateStatus()
{
if (!_connected || _currentStatus == null)
return;
_currentRandom = _currentStatus.Random;
_currentRepeat = _currentStatus.Repeat;
_currentConsume = _currentStatus.Consume;
_currentSingle = _currentStatus.Single;
_currentVolume = _currentStatus.Volume;
StatusChanged?.Invoke(this, EventArgs.Empty);
}
public void UpdateSong() public void UpdateSong()
{ {
if (!_connected) if (!_connected || _currentSong == null)
return;
if (_currentSong == null)
return; return;
_currentTime = _currentStatus.Elapsed.TotalSeconds; _currentTime = _currentStatus.Elapsed.TotalSeconds;
@ -385,7 +395,7 @@ namespace unison
SongChanged?.Invoke(this, EventArgs.Empty); SongChanged?.Invoke(this, EventArgs.Empty);
string uri = Regex.Escape(_currentSong.Path); string uri = Regex.Escape(_currentSong.Path);
GetAlbumBitmap(uri); GetAlbumCover(uri);
} }
public void UpdateCover() public void UpdateCover()
@ -393,22 +403,6 @@ namespace unison
CoverChanged?.Invoke(this, EventArgs.Empty); CoverChanged?.Invoke(this, EventArgs.Empty);
} }
public void UpdateStatus()
{
if (!_connected)
return;
if (_currentStatus == null)
return;
_currentRandom = _currentStatus.Random;
_currentRepeat = _currentStatus.Repeat;
_currentConsume = _currentStatus.Consume;
_currentSingle = _currentStatus.Single;
_currentVolume = _currentStatus.Volume;
StatusChanged?.Invoke(this, EventArgs.Empty);
}
public IMpdFile GetCurrentSong() => _currentSong; public IMpdFile GetCurrentSong() => _currentSong;
public MpdStatus GetStatus() => _currentStatus; public MpdStatus GetStatus() => _currentStatus;
public BitmapFrame GetCover() => _cover; public BitmapFrame GetCover() => _cover;

View File

@ -46,7 +46,10 @@ namespace unison
} }
catch (Exception err) catch (Exception err)
{ {
MessageBox.Show($"[Snapcast error]\nInvalid path: {err.Message}\n\nCurrent path: {Properties.Settings.Default.snapcast_path}\nYou can reset it in the settings if needed.", MessageBox.Show($"[{unison.Resources.Resources.Snapcast_Popup1}]\n" +
$"{unison.Resources.Resources.Snapcast_Popup2} {err.Message}\n\n" +
$"{unison.Resources.Resources.Snapcast_Popup3} {Properties.Settings.Default.snapcast_path}\n" +
$"{unison.Resources.Resources.Snapcast_Popup4}",
"unison", MessageBoxButton.OK, MessageBoxImage.Error); "unison", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }

View File

@ -366,6 +366,42 @@ namespace unison.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Snapcast error.
/// </summary>
public static string Snapcast_Popup1 {
get {
return ResourceManager.GetString("Snapcast_Popup1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid path:.
/// </summary>
public static string Snapcast_Popup2 {
get {
return ResourceManager.GetString("Snapcast_Popup2", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Current path:.
/// </summary>
public static string Snapcast_Popup3 {
get {
return ResourceManager.GetString("Snapcast_Popup3", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You can reset it in the settings if needed..
/// </summary>
public static string Snapcast_Popup4 {
get {
return ResourceManager.GetString("Snapcast_Popup4", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Start Snapcast. /// Looks up a localized string similar to Start Snapcast.
/// </summary> /// </summary>

View File

@ -219,6 +219,18 @@
<data name="ShowWindow" xml:space="preserve"> <data name="ShowWindow" xml:space="preserve">
<value>Montrer la fenêtre</value> <value>Montrer la fenêtre</value>
</data> </data>
<data name="Snapcast_Popup1" xml:space="preserve">
<value>Erreur Snapcast</value>
</data>
<data name="Snapcast_Popup2" xml:space="preserve">
<value>Chemin invalide :</value>
</data>
<data name="Snapcast_Popup3" xml:space="preserve">
<value>Chemin actuel :</value>
</data>
<data name="Snapcast_Popup4" xml:space="preserve">
<value>Vous pouvez le réinitialiser dans la configuration.</value>
</data>
<data name="StartSnapcast" xml:space="preserve"> <data name="StartSnapcast" xml:space="preserve">
<value>Démarrer Snapcast</value> <value>Démarrer Snapcast</value>
</data> </data>

View File

@ -219,6 +219,18 @@
<data name="ShowWindow" xml:space="preserve"> <data name="ShowWindow" xml:space="preserve">
<value>Show window</value> <value>Show window</value>
</data> </data>
<data name="Snapcast_Popup1" xml:space="preserve">
<value>Snapcast error</value>
</data>
<data name="Snapcast_Popup2" xml:space="preserve">
<value>Invalid path:</value>
</data>
<data name="Snapcast_Popup3" xml:space="preserve">
<value>Current path:</value>
</data>
<data name="Snapcast_Popup4" xml:space="preserve">
<value>You can reset it in the settings if needed.</value>
</data>
<data name="StartSnapcast" xml:space="preserve"> <data name="StartSnapcast" xml:space="preserve">
<value>Start Snapcast</value> <value>Start Snapcast</value>
</data> </data>

View File

@ -7,7 +7,7 @@
<ApplicationIcon>Resources\icon-full.ico</ApplicationIcon> <ApplicationIcon>Resources\icon-full.ico</ApplicationIcon>
<Win32Resource></Win32Resource> <Win32Resource></Win32Resource>
<StartupObject>unison.App</StartupObject> <StartupObject>unison.App</StartupObject>
<Version>0.0.1</Version> <Version>1.0</Version>
<Company /> <Company />
<Authors>Théo Marchal</Authors> <Authors>Théo Marchal</Authors>
<PackageLicenseFile>LICENSE</PackageLicenseFile> <PackageLicenseFile>LICENSE</PackageLicenseFile>