pattern matching in player watcher

This commit is contained in:
andy 2021-12-18 22:19:11 +00:00
parent 7fe603ab3d
commit a263941e97
4 changed files with 155 additions and 142 deletions

View File

@ -54,9 +54,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("nochange", "album1", "artist1"), isPlaying: true, context: "context1"), Helper.CurrentPlayback(Helper.FullTrack("nochange", "album1", "artist1"), isPlaying: true, context: "context1"),
}, },
// to raise // to raise
new List<string>(){ "ItemChange", "ContextChange", "PlayingChange" }, new List<string>(){ "ItemChange", "ContextChange", "PlayingChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// TRACK CHANGE // TRACK CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -64,9 +64,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("trackchange2", "album1", "artist1")) Helper.CurrentPlayback(Helper.FullTrack("trackchange2", "album1", "artist1"))
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "PlayingChange", "ItemChange" }, new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// ALBUM CHANGE // ALBUM CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -74,9 +74,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("albumchange", "album2", "artist1")) Helper.CurrentPlayback(Helper.FullTrack("albumchange", "album2", "artist1"))
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "AlbumChange" }, new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "AlbumChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "ArtistChange" }
}, },
// ARTIST CHANGE // ARTIST CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -84,9 +84,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("artistchange", "album1", "artist2")) Helper.CurrentPlayback(Helper.FullTrack("artistchange", "album1", "artist2"))
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "ArtistChange" }, new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "ArtistChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange" }
}, },
// CONTEXT CHANGE // CONTEXT CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -94,9 +94,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("contextchange", "album1", "artist1"), context: "context2") Helper.CurrentPlayback(Helper.FullTrack("contextchange", "album1", "artist1"), context: "context2")
}, },
// to raise // to raise
new List<string>(){ "PlayingChange", "ItemChange", "ContextChange" }, new List<string>(){ "PlayingChange", "ItemChange", "ContextChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// PLAYING CHANGE // PLAYING CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -104,9 +104,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("playingchange1", "album1", "artist1"), isPlaying: false, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("playingchange1", "album1", "artist1"), isPlaying: false, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "ItemChange", "PlayingChange" }, new List<string>(){ "ContextChange", "ItemChange", "PlayingChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// PLAYING CHANGE // PLAYING CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -114,9 +114,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("playingchange2", "album1", "artist1"), isPlaying: true, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("playingchange2", "album1", "artist1"), isPlaying: true, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "ItemChange", "PlayingChange" }, new List<string>(){ "ContextChange", "ItemChange", "PlayingChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// CONTENT CHANGE // CONTENT CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -124,9 +124,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullEpisode("contentchange1", "show1", "pub1"), isPlaying: true, context: "context2") Helper.CurrentPlayback(Helper.FullEpisode("contentchange1", "show1", "pub1"), isPlaying: true, context: "context2")
}, },
// to raise // to raise
new List<string>(){ "PlayingChange", "ContentChange", "ContextChange", "ItemChange" }, new List<string>(){ "PlayingChange", "ContentChange", "ContextChange", "ItemChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// CONTENT CHANGE // CONTENT CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -134,9 +134,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("contentchange1", "album1", "artist1"), isPlaying: true, context: "context1") Helper.CurrentPlayback(Helper.FullTrack("contentchange1", "album1", "artist1"), isPlaying: true, context: "context1")
}, },
// to raise // to raise
new List<string>(){ "PlayingChange", "ContentChange", "ContextChange", "ItemChange" }, new List<string>(){ "PlayingChange", "ContentChange", "ContextChange", "ItemChange", "DeviceChange", "VolumeChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "DeviceChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange" }
}, },
// DEVICE CHANGE // DEVICE CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -144,9 +144,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("devicechange", "album1", "artist1"), device: Helper.Device("dev2")) Helper.CurrentPlayback(Helper.FullTrack("devicechange", "album1", "artist1"), device: Helper.Device("dev2"))
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "DeviceChange" }, new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "VolumeChange", "DeviceChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange", "VolumeChange" } new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange" }
}, },
// VOLUME CHANGE // VOLUME CHANGE
new object[] { new List<CurrentlyPlayingContext>(){ new object[] { new List<CurrentlyPlayingContext>(){
@ -154,9 +154,9 @@ namespace Selector.Tests
Helper.CurrentPlayback(Helper.FullTrack("volumechange", "album1", "artist1"), device: Helper.Device("dev1", volume: 60)) Helper.CurrentPlayback(Helper.FullTrack("volumechange", "album1", "artist1"), device: Helper.Device("dev1", volume: 60))
}, },
// to raise // to raise
new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "VolumeChange" }, new List<string>(){ "ContextChange", "PlayingChange", "ItemChange", "VolumeChange", "DeviceChange" },
// to not raise // to not raise
new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange", "DeviceChange" } new List<string>(){ "AlbumChange", "ArtistChange", "ContentChange" }
}, },
// // STARTED PLAYBACK // // STARTED PLAYBACK
// new object[] { new List<CurrentlyPlayingContext>(){ // new object[] { new List<CurrentlyPlayingContext>(){

View File

@ -11,6 +11,9 @@ namespace Selector
public bool IsEqual<T>(T item, T other) public bool IsEqual<T>(T item, T other)
{ {
if (item is null && other is null) return true;
if (item is null ^ other is null) return false;
if (comps.ContainsKey(typeof(T))) if (comps.ContainsKey(typeof(T)))
{ {
var comp = (IEqualityComparer<T>) comps[typeof(T)]; var comp = (IEqualityComparer<T>) comps[typeof(T)];

View File

@ -6,6 +6,9 @@ namespace Selector
{ {
public bool IsEqual<T>(T item, T other) public bool IsEqual<T>(T item, T other)
{ {
if (item is null && other is null) return true;
if (item is null ^ other is null) return false;
var uri = typeof(T).GetProperty("Uri"); var uri = typeof(T).GetProperty("Uri");
if(uri is not null) if(uri is not null)

View File

@ -68,127 +68,11 @@ namespace Selector
OnNetworkPoll(GetEvent()); OnNetworkPoll(GetEvent());
// NOT PLAYING CheckPlaying();
if(Previous is null && Live is null) CheckContext();
{ CheckItem();
// Console.WriteLine("not playing"); CheckDevice();
}
else
{
// STARTED PLAYBACK
if(Previous?.Context is null && Live?.Context is not null)
{
Logger.LogDebug("Context started: {context}", Live?.Context.DisplayString());
OnContextChange(GetEvent());
}
if(Previous?.Item is null && Live?.Item is not null)
{
if (Live.Item is FullTrack track)
{
Logger.LogDebug("Item started: {track}", track.DisplayString());
}
else if (Live.Item is FullEpisode episode)
{
Logger.LogDebug("Item started: {episode}", episode.DisplayString());
}
else
{
Logger.LogDebug("Item started: {item}", Live.Item);
}
OnItemChange(GetEvent());
}
if(Previous is null && Live is not null)
{
Logger.LogDebug("Playback started: {context}", Live.DisplayString());
OnPlayingChange(GetEvent());
}
// STOPPED PLAYBACK
else if(Previous is not null && Live is null)
{
Logger.LogDebug("Playback stopped: {context}", Previous.DisplayString());
OnPlayingChange(GetEvent());
OnItemChange(GetEvent());
OnContextChange(GetEvent());
}
// CONTINUING PLAYBACK
else {
// MUSIC
if(Previous.Item is FullTrack previousTrack
&& Live.Item is FullTrack currentTrack)
{
if(!eq.IsEqual(previousTrack, currentTrack)) {
Logger.LogDebug("Track changed: {prevTrack} -> {currentTrack}", previousTrack.DisplayString(), currentTrack.DisplayString());
OnItemChange(GetEvent());
}
if(!eq.IsEqual(previousTrack.Album, currentTrack.Album)) {
Logger.LogDebug($"Album changed: {previousTrack.Album.DisplayString()} -> {currentTrack.Album.DisplayString()}");
OnAlbumChange(GetEvent());
}
if(!eq.IsEqual(previousTrack.Artists[0], currentTrack.Artists[0])) {
Logger.LogDebug($"Artist changed: {previousTrack.Artists.DisplayString()} -> {currentTrack.Artists.DisplayString()}");
OnArtistChange(GetEvent());
}
}
// CHANGED CONTENT TYPE
else if((Previous.Item is FullTrack && Live.Item is FullEpisode)
|| (Previous.Item is FullEpisode && Live.Item is FullTrack))
{
Logger.LogDebug($"Media type changed: {Previous.Item}, {Previous.Item}");
OnContentChange(GetEvent());
OnItemChange(GetEvent());
}
// PODCASTS
else if(Previous.Item is FullEpisode previousEp
&& Live.Item is FullEpisode currentEp)
{
if(!eq.IsEqual(previousEp, currentEp)) {
Logger.LogDebug($"Podcast changed: {previousEp.DisplayString()} -> {currentEp.DisplayString()}");
OnItemChange(GetEvent());
}
}
else if (Previous.Item is null)
{
Logger.LogTrace($"Previous item was null [{Previous.DisplayString()}]");
}
else if (Live.Item is null)
{
Logger.LogTrace($"Live item was null [{Live.DisplayString()}]");
}
else {
Logger.LogError($"Unknown combination of previous and current playing contexts, [{Previous.DisplayString()}] [{Live.DisplayString()}]");
throw new NotSupportedException("Unknown item combination");
}
// CONTEXT
if(!eq.IsEqual(Previous.Context, Live.Context)) {
Logger.LogDebug($"Context changed: {Previous.Context.DisplayString()} -> {Live.Context.DisplayString()}");
OnContextChange(GetEvent());
}
// DEVICE
if(!eq.IsEqual(Previous?.Device, Live?.Device)) {
Logger.LogDebug($"Device changed: {Previous?.Device.DisplayString()} -> {Live?.Device.DisplayString()}");
OnDeviceChange(GetEvent());
}
// IS PLAYING
if(Previous.IsPlaying != Live.IsPlaying) {
Logger.LogDebug($"Playing state changed: {Previous.IsPlaying} -> {Live.IsPlaying}");
OnPlayingChange(GetEvent());
}
// VOLUME
if(Previous.Device.VolumePercent != Live.Device.VolumePercent) {
Logger.LogDebug($"Volume changed: {Previous.Device.VolumePercent}% -> {Live.Device.VolumePercent}%");
OnVolumeChange(GetEvent());
}
}
}
} }
catch(APIUnauthorizedException e) catch(APIUnauthorizedException e)
{ {
@ -208,6 +92,129 @@ namespace Selector
} }
} }
private void CheckItem()
{
switch (Previous, Live)
{
case (null or { Item: null }, { Item: FullTrack track }):
Logger.LogDebug("Item started: {track}", track.DisplayString());
break;
case (null or { Item: null }, { Item: FullEpisode episode }):
Logger.LogDebug("Item started: {episode}", episode.DisplayString());
break;
case (null or { Item: null }, { Item: not null }):
Logger.LogDebug("Item started: {item}", Live.Item);
break;
}
switch (Previous, Live)
{
case (null or { Item: null }, { Item: not null }):
OnItemChange(GetEvent());
break;
case ({ Item: not null }, null or { Item: null }):
Logger.LogDebug("Item stopped: {context}", Previous.DisplayString());
OnItemChange(GetEvent());
break;
}
switch (Previous, Live)
{
case ({ Item: FullTrack previousTrack }, { Item: FullTrack currentTrack }):
if (!eq.IsEqual(previousTrack, currentTrack))
{
Logger.LogDebug("Track changed: {prevTrack} -> {currentTrack}", previousTrack.DisplayString(), currentTrack.DisplayString());
OnItemChange(GetEvent());
}
if (!eq.IsEqual(previousTrack.Album, currentTrack.Album))
{
Logger.LogDebug("Album changed: {previous} -> {current}", previousTrack.Album.DisplayString(), currentTrack.Album.DisplayString());
OnAlbumChange(GetEvent());
}
if (!eq.IsEqual(previousTrack.Artists[0], currentTrack.Artists[0]))
{
Logger.LogDebug("Artist changed: {previous} -> {current}", previousTrack.Artists.DisplayString(), currentTrack.Artists.DisplayString());
OnArtistChange(GetEvent());
}
break;
case ({ Item: FullTrack previousTrack }, { Item: FullEpisode currentEp }):
Logger.LogDebug("Media type changed: {previous}, {current}", previousTrack.DisplayString(), currentEp.DisplayString());
OnContentChange(GetEvent());
OnItemChange(GetEvent());
break;
case ({ Item: FullEpisode previousEpisode }, { Item: FullTrack currentTrack }):
Logger.LogDebug("Media type changed: {previous}, {current}", previousEpisode.DisplayString(), currentTrack.DisplayString());
OnContentChange(GetEvent());
OnItemChange(GetEvent());
break;
case ({ Item: FullEpisode previousEp }, { Item: FullEpisode currentEp }):
if (!eq.IsEqual(previousEp, currentEp))
{
Logger.LogDebug($"Podcast changed: {previousEp.DisplayString()} -> {currentEp.DisplayString()}");
OnItemChange(GetEvent());
}
break;
}
}
private void CheckContext()
{
if ((Previous, Live)
is (null or { Context: null }, { Context: not null }))
{
Logger.LogDebug("Context started: {context}", Live?.Context.DisplayString());
OnContextChange(GetEvent());
}
else if (!eq.IsEqual(Previous?.Context, Live?.Context))
{
Logger.LogDebug($"Context changed: {Previous?.Context?.DisplayString() ?? "none"} -> {Live?.Context?.DisplayString() ?? "none"}");
OnContextChange(GetEvent());
}
}
private void CheckPlaying()
{
switch (Previous, Live)
{
case (null, not null):
Logger.LogDebug("Playback started: {context}", Live.DisplayString());
OnPlayingChange(GetEvent());
break;
case (not null, null):
Logger.LogDebug("Playback stopped: {context}", Previous.DisplayString());
OnPlayingChange(GetEvent());
OnContextChange(GetEvent());
break;
}
// IS PLAYING
if (Previous?.IsPlaying != Live?.IsPlaying)
{
Logger.LogDebug($"Playing state changed: {Previous?.IsPlaying} -> {Live?.IsPlaying}");
OnPlayingChange(GetEvent());
}
}
private void CheckDevice()
{
// DEVICE
if (!eq.IsEqual(Previous?.Device, Live?.Device))
{
Logger.LogDebug($"Device changed: {Previous?.Device?.DisplayString() ?? "none"} -> {Live?.Device?.DisplayString() ?? "none"}");
OnDeviceChange(GetEvent());
}
// VOLUME
if (Previous?.Device?.VolumePercent != Live?.Device?.VolumePercent)
{
Logger.LogDebug($"Volume changed: {Previous?.Device?.VolumePercent}% -> {Live?.Device?.VolumePercent}%");
OnVolumeChange(GetEvent());
}
}
private ListeningChangeEventArgs GetEvent() => ListeningChangeEventArgs.From(Previous, Live, Past, id: Id, username: SpotifyUsername); private ListeningChangeEventArgs GetEvent() => ListeningChangeEventArgs.From(Previous, Live, Past, id: Id, username: SpotifyUsername);
/// <summary> /// <summary>