adding manager functionality
This commit is contained in:
parent
28b7b954c1
commit
7d5ab4477d
@ -63,7 +63,7 @@ namespace Selector.Tests
|
||||
public void TrackEquality(FullTrack track1, FullTrack track2, bool shouldEqual)
|
||||
{
|
||||
var eq = Equal.String();
|
||||
eq.IsEqual<FullTrack>(track1, track2).Should().Be(shouldEqual);
|
||||
eq.IsEqual(track1, track2).Should().Be(shouldEqual);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> AlbumData =>
|
||||
@ -106,7 +106,7 @@ namespace Selector.Tests
|
||||
public void AlbumEquality(SimpleAlbum album1, SimpleAlbum album2, bool shouldEqual)
|
||||
{
|
||||
var eq = Equal.String();
|
||||
eq.IsEqual<SimpleAlbum>(album1, album2).Should().Be(shouldEqual);
|
||||
eq.IsEqual(album1, album2).Should().Be(shouldEqual);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ArtistData =>
|
||||
@ -131,7 +131,7 @@ namespace Selector.Tests
|
||||
public void ArtistEquality(SimpleArtist artist1, SimpleArtist artist2, bool shouldEqual)
|
||||
{
|
||||
var eq = Equal.String();
|
||||
eq.IsEqual<SimpleArtist>(artist1, artist2).Should().Be(shouldEqual);
|
||||
eq.IsEqual(artist1, artist2).Should().Be(shouldEqual);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> EpisodeData =>
|
||||
@ -156,7 +156,7 @@ namespace Selector.Tests
|
||||
public void EpisodeEquality(FullEpisode episode1, FullEpisode episode2, bool shouldEqual)
|
||||
{
|
||||
var eq = Equal.String();
|
||||
eq.IsEqual<FullEpisode>(episode1, episode2).Should().Be(shouldEqual);
|
||||
eq.IsEqual(episode1, episode2).Should().Be(shouldEqual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
56
Selector.Tests/Manager.cs
Normal file
56
Selector.Tests/Manager.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using Moq;
|
||||
using FluentAssertions;
|
||||
using SpotifyAPI.Web;
|
||||
|
||||
using Selector;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Selector.Tests
|
||||
{
|
||||
public class ManagerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Count()
|
||||
{
|
||||
var manager = new Manager();
|
||||
|
||||
var watcherMock = new Mock<IWatcher>();
|
||||
|
||||
manager.Add(watcherMock.Object);
|
||||
manager.Add(watcherMock.Object);
|
||||
manager.Add(watcherMock.Object);
|
||||
|
||||
manager.Count.Should().Be(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StartAndStop()
|
||||
{
|
||||
var manager = new Manager();
|
||||
|
||||
var watcherMock = new Mock<IWatcher>();
|
||||
|
||||
manager.Add(watcherMock.Object);
|
||||
manager.Count.Should().Be(1);
|
||||
|
||||
manager.Start();
|
||||
|
||||
manager.IsRunning.Should().BeTrue();
|
||||
manager.Running.Count().Should().Be(1);
|
||||
|
||||
var context = manager.Running.First();
|
||||
|
||||
manager.Stop();
|
||||
|
||||
manager.IsRunning.Should().BeFalse();
|
||||
context.IsRunning.Should().BeFalse();
|
||||
|
||||
manager.Running.Count().Should().Be(0);
|
||||
manager.TokenSources.First().IsCancellationRequested.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,8 @@ using FluentAssertions;
|
||||
using SpotifyAPI.Web;
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit.Sdk;
|
||||
|
||||
namespace Selector.Tests
|
||||
{
|
||||
@ -203,11 +205,32 @@ namespace Selector.Tests
|
||||
toNotRaise.ForEach(r => monitoredWatcher.Should().NotRaise(r));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1000, 3500, 4)]
|
||||
[InlineData(500, 3800, 8)]
|
||||
public async void Watch(int pollPeriod, int execTime, int numberOfCalls)
|
||||
{
|
||||
var spotMock = new Mock<IPlayerClient>();
|
||||
var eq = new UriEqual();
|
||||
var watch = new PlayerWatcher(spotMock.Object, eq)
|
||||
{
|
||||
PollPeriod = pollPeriod
|
||||
};
|
||||
|
||||
var tokenSource = new CancellationTokenSource();
|
||||
var task = watch.Watch(tokenSource.Token);
|
||||
|
||||
await Task.Delay(execTime);
|
||||
tokenSource.Cancel();
|
||||
|
||||
spotMock.Verify(s => s.GetCurrentPlayback(), Times.Exactly(numberOfCalls));
|
||||
}
|
||||
|
||||
// [Fact]
|
||||
// public async void Auth()
|
||||
// {
|
||||
// var spot = new SpotifyClient("");
|
||||
// var eq = new UriEquality();
|
||||
// var eq = new UriEqual();
|
||||
// var watch = new PlayerWatcher(spot.Player, eq);
|
||||
|
||||
// var token = new CancellationTokenSource();
|
||||
|
@ -1,10 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
class Playable
|
||||
{
|
||||
public Type Type;
|
||||
public object Obj;
|
||||
}
|
||||
}
|
@ -34,10 +34,7 @@ namespace Selector
|
||||
public void Add(CurrentlyPlayingContext item) => Add(item, DateHelper.FromUnixMilli(item.Timestamp));
|
||||
public void Add(CurrentlyPlayingContext item, DateTime timestamp)
|
||||
{
|
||||
recentlyPlayed.Add(new TimelineItem<CurrentlyPlayingContext>(){
|
||||
Item = item,
|
||||
Time = timestamp
|
||||
});
|
||||
recentlyPlayed.Add(TimelineItem<CurrentlyPlayingContext>.From(item, timestamp));
|
||||
|
||||
if (timestamp < recentlyPlayed.Last().Time && SortOnBackDate)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -8,13 +9,13 @@ namespace Selector
|
||||
{
|
||||
public abstract class BaseWatcher: IWatcher
|
||||
{
|
||||
public abstract Task WatchOne();
|
||||
public abstract Task WatchOne(CancellationToken token);
|
||||
|
||||
public async Task Watch(CancellationToken cancelToken)
|
||||
{
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
await WatchOne();
|
||||
while (true) {
|
||||
cancelToken.ThrowIfCancellationRequested();
|
||||
await WatchOne(cancelToken);
|
||||
await Task.Delay(PollPeriod);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SpotifyAPI.Web;
|
||||
|
||||
namespace Selector
|
||||
@ -15,5 +14,8 @@ namespace Selector
|
||||
public event EventHandler<ListeningChangeEventArgs> VolumeChange;
|
||||
public event EventHandler<ListeningChangeEventArgs> DeviceChange;
|
||||
public event EventHandler<ListeningChangeEventArgs> PlayingChange;
|
||||
|
||||
public CurrentlyPlayingContext Live { get; }
|
||||
public PlayerTimeline Past { get; }
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SpotifyAPI.Web;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
public interface IWatcher
|
||||
{
|
||||
public Task WatchOne();
|
||||
public Task WatchOne(CancellationToken cancelToken);
|
||||
public Task Watch(CancellationToken cancelToken);
|
||||
|
||||
public int PollPeriod { get; set; }
|
||||
|
@ -6,9 +6,10 @@ namespace Selector
|
||||
{
|
||||
interface IManager
|
||||
{
|
||||
public bool IsRunning { get; }
|
||||
public void Add(IWatcher watcher);
|
||||
|
||||
public bool Start();
|
||||
public bool Stop();
|
||||
public void Start();
|
||||
public void Stop();
|
||||
}
|
||||
}
|
63
Selector/Watcher/Manager/Manager.cs
Normal file
63
Selector/Watcher/Manager/Manager.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
public class Manager: IManager, IDisposable
|
||||
{
|
||||
public bool IsRunning { get; private set; } = true;
|
||||
private List<WatcherContext> Watchers { get; set; } = new();
|
||||
public int Count => Watchers.Count;
|
||||
public IEnumerable<Task> Tasks
|
||||
=> Watchers
|
||||
.Select(w => w.Task)
|
||||
.Where(t => t is not null);
|
||||
|
||||
public IEnumerable<CancellationTokenSource> TokenSources
|
||||
=> Watchers
|
||||
.Select(w => w.TokenSource)
|
||||
.Where(t => t is not null);
|
||||
|
||||
public void Add(IWatcher watcher)
|
||||
{
|
||||
var context = WatcherContext.From(watcher);
|
||||
if (IsRunning) context.Start();
|
||||
|
||||
Watchers.Add(context);
|
||||
}
|
||||
|
||||
public IEnumerable<WatcherContext> Running
|
||||
=> Watchers.Where(w => w.IsRunning);
|
||||
|
||||
public void Start()
|
||||
{
|
||||
foreach(var watcher in Watchers)
|
||||
{
|
||||
watcher.Start();
|
||||
}
|
||||
IsRunning = true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
foreach(var watcher in Watchers)
|
||||
{
|
||||
watcher.Stop();
|
||||
}
|
||||
Task.WaitAll(Tasks.ToArray());
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach(var watcher in Watchers)
|
||||
{
|
||||
watcher.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
Selector/Watcher/Manager/WatcherContext.cs
Normal file
61
Selector/Watcher/Manager/WatcherContext.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
public class WatcherContext: IDisposable
|
||||
{
|
||||
public IWatcher Watcher { get; set; }
|
||||
public bool IsRunning { get; private set; }
|
||||
public Task Task { get; set; }
|
||||
public CancellationTokenSource TokenSource { get; set; }
|
||||
|
||||
public WatcherContext(IWatcher watcher)
|
||||
{
|
||||
Watcher = watcher;
|
||||
}
|
||||
|
||||
public static WatcherContext From(IWatcher watcher)
|
||||
{
|
||||
return new(watcher);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (IsRunning)
|
||||
Stop();
|
||||
|
||||
IsRunning = true;
|
||||
TokenSource = new();
|
||||
Task = Watcher.Watch(TokenSource.Token);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
TokenSource.Cancel();
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
private void Clear()
|
||||
{
|
||||
if(IsRunning
|
||||
|| Task.Status == TaskStatus.Running
|
||||
|| Task.Status == TaskStatus.WaitingToRun)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
Task = null;
|
||||
TokenSource = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stop();
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
}
|
@ -33,8 +33,10 @@ namespace Selector
|
||||
PollPeriod = pollPeriod;
|
||||
}
|
||||
|
||||
public override async Task WatchOne()
|
||||
public override async Task WatchOne(CancellationToken token = default)
|
||||
{
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
try{
|
||||
var polledCurrent = await spotifyClient.GetCurrentPlayback();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user