Wire up the disposer for cleaning up unused objects, i.e disposing a VM will remove it from the view

This commit is contained in:
TheXamlGuy
2024-01-12 21:05:42 +00:00
parent 814c806240
commit 2a773f26db
37 changed files with 323 additions and 206 deletions
@@ -3,22 +3,17 @@
namespace Hyperbar.Windows.Primary;
public class MediaController :
INotificationHandler<PlayRequest>,
IDisposable
INotificationHandler<PlayRequest>
{
public MediaController(GlobalSystemMediaTransportControlsSession session)
{
private readonly GlobalSystemMediaTransportControlsSession session;
public MediaController(GlobalSystemMediaTransportControlsSession session,
IMediator mediator)
{
this.session = session;
mediator.Subscribe(this);
}
public void Dispose()
{
throw new NotImplementedException();
}
public ValueTask Handle(PlayRequest notification,
CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public async ValueTask Handle(PlayRequest notification, CancellationToken cancellationToken) =>
await session.TryPlayAsync();
}
@@ -1,47 +0,0 @@
using Windows.Media.Control;
namespace Hyperbar.Windows.Primary;
public class MediaControllerInitializer :
IInitializer
{
private readonly List<GlobalSystemMediaTransportControlsSession> sessions = [];
public async Task InitializeAsync()
{
GlobalSystemMediaTransportControlsSessionManager mediaTransportControlsSessionManager =
await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
mediaTransportControlsSessionManager.SessionsChanged += OnSessionsChanged;
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
mediaTransportControlsSessionManager.GetSessions();
foreach (var session in sessions)
{
this.sessions.Add(session);
}
}
private void OnSessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender,
SessionsChangedEventArgs args)
{
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
sender.GetSessions();
foreach (var session in this.sessions.ToList())
{
if (!sessions.Contains(session))
{
this.sessions.Remove(session);
}
}
foreach (var session in sessions)
{
if (!this.sessions.Contains(session))
{
this.sessions.Add(session);
}
}
}
}
@@ -0,0 +1,93 @@
using System.Collections.Concurrent;
using System.Threading.Channels;
using Windows.Media.Control;
namespace Hyperbar.Windows.Primary;
public class MediaControllerManager :
IInitializer
{
private readonly ConcurrentDictionary<GlobalSystemMediaTransportControlsSession, MediaController> cachedSessions = [];
private readonly IMediator mediator;
private readonly Queue<MediaController> mediaControllers;
private readonly IServiceFactory serviceFactory;
public MediaControllerManager(IServiceFactory serviceFactory,
IMediator mediator,
Queue<MediaController> mediaControllers)
{
this.serviceFactory = serviceFactory;
this.mediator = mediator;
this.mediaControllers = mediaControllers;
}
private Channel<MediaController> d;
public async Task InitializeAsync()
{
d = Channel.CreateUnbounded<MediaController>();
_ = Task.Run(async () => {
await foreach (var coordinates in d.Reader.ReadAllAsync())
{
Console.WriteLine(coordinates);
}
});
GlobalSystemMediaTransportControlsSessionManager mediaTransportControlsSessionManager =
await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
mediaTransportControlsSessionManager.SessionsChanged += OnSessionsChanged;
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
mediaTransportControlsSessionManager.GetSessions();
foreach (GlobalSystemMediaTransportControlsSession session in sessions)
{
await InitializeSessionAsync(session);
}
}
private async Task InitializeSessionAsync(GlobalSystemMediaTransportControlsSession session)
{
if (serviceFactory.Create<MediaController>(session) is MediaController mediaController)
{
await d.Writer.WriteAsync(mediaController);
mediaControllers.Enqueue(mediaController);
cachedSessions.TryAdd(session, mediaController);
await mediator.PublishAsync(new Created<MediaController>(mediaController));
}
}
private async void OnSessionsChanged(GlobalSystemMediaTransportControlsSessionManager sender,
SessionsChangedEventArgs args)
{
IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions =
sender.GetSessions();
foreach (KeyValuePair<GlobalSystemMediaTransportControlsSession, MediaController> session in
cachedSessions)
{
if (!sessions.Contains(session.Key))
{
cachedSessions.TryRemove(session);
}
}
foreach (GlobalSystemMediaTransportControlsSession session in sessions)
{
await InitializeSessionAsync(session);
}
}
private void RemoveSession(GlobalSystemMediaTransportControlsSession session)
{
if (serviceFactory.Create<MediaController>(session) is MediaController mediaController)
{
cachedSessions.TryAdd(session, mediaController);
}
}
}
@@ -1,20 +1,17 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace Hyperbar.Windows.Primary;
public partial class MediaInformationViewModel :
WidgetComponentViewModel
{
[ObservableProperty]
private string title = "this is a test";
[ObservableProperty]
private string description = "this is a test description";
public MediaInformationViewModel(ITemplateFactory templateFactory) : base(templateFactory)
{
}
}
//public class MediaControllerViewModelFactory(IServiceFactory service,
// IMediator mediator,
// Queue<MediaController> mediaControllers) :
// IFactory<MediaControllerViewModel>
//{
// public MediaControllerViewModel Create()
// {
// throw new NotImplementedException();
// }
//}
public class MediaControllerViewModel :
ObservableCollectionViewModel<WidgetComponentViewModel>,
@@ -22,7 +19,8 @@ public class MediaControllerViewModel :
{
public MediaControllerViewModel(ITemplateFactory templateFactory,
IServiceFactory serviceFactory,
IMediator mediator) : base(serviceFactory, mediator)
IMediator mediator,
IDisposer disposer) : base(serviceFactory, mediator, disposer)
{
TemplateFactory = templateFactory;
@@ -9,10 +9,8 @@ public class MediaControllerWidgetProvider :
{
public void Create(HostBuilderContext comtext, IServiceCollection services) =>
services.AddWidgetTemplate<MediaControllerWidgetViewModel, MediaControllerWidgetView>()
.AddTransient<IInitializer, MediaControllerInitializer>()
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>()
.AddContentTemplate<MediaInformationViewModel, MediaInformationView>();
.AddSingleton<Queue<MediaController>>()
.AddSingleton<IInitializer, MediaControllerManager>()
.AddContentTemplate<MediaControllerViewModel, MediaControllerView>();
}
@@ -3,8 +3,8 @@
public class MediaControllerWidgetViewModel(ITemplateFactory templateFactory,
IServiceFactory serviceFactory,
IMediator mediator,
IEnumerable<MediaControllerViewModel> items) :
ObservableCollectionViewModel<MediaControllerViewModel>(serviceFactory, mediator, items),
IDisposer disposer) :
ObservableCollectionViewModel<MediaControllerViewModel>(serviceFactory, mediator, disposer),
IWidgetViewModel,
ITemplatedViewModel
{
@@ -0,0 +1,17 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace Hyperbar.Windows.Primary;
public partial class MediaInformationViewModel :
WidgetComponentViewModel
{
[ObservableProperty]
private string title = "this is a test";
[ObservableProperty]
private string description = "this is a test description";
public MediaInformationViewModel(IServiceFactory serviceFactory, IMediator mediator, IDisposer disposer, ITemplateFactory templateFactory) : base(serviceFactory, mediator, disposer, templateFactory)
{
}
}