more changes

This commit is contained in:
TheXamlGuy
2024-02-17 20:27:40 +00:00
parent 43178429d2
commit c32a2d2f85
10 changed files with 86 additions and 61 deletions
@@ -1,5 +1,7 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Hyperbar.UI.Windows; using Hyperbar.UI.Windows;
using System.Collections.Concurrent;
using System.Threading.Channels;
namespace Hyperbar.Widget.Windows; namespace Hyperbar.Widget.Windows;
@@ -10,6 +12,7 @@ public partial class WidgetConfigurationViewModel<TConfiguration, TValue> :
class class
{ {
private readonly Func<TConfiguration, TValue> read; private readonly Func<TConfiguration, TValue> read;
private readonly Func<TValue, TConfiguration> write;
[ObservableProperty] [ObservableProperty]
private string? description; private string? description;
@@ -23,10 +26,12 @@ public partial class WidgetConfigurationViewModel<TConfiguration, TValue> :
IDisposer disposer, IDisposer disposer,
ISubscriber subscriber, ISubscriber subscriber,
string? title, string? title,
Func<TConfiguration, TValue> read) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) Func<TConfiguration, TValue> read,
Func<TValue, TConfiguration> write) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{ {
this.title = title; this.title = title;
this.read = read; this.read = read;
this.write = write;
} }
public WidgetConfigurationViewModel(IServiceProvider serviceProvider, public WidgetConfigurationViewModel(IServiceProvider serviceProvider,
@@ -36,12 +41,14 @@ public partial class WidgetConfigurationViewModel<TConfiguration, TValue> :
ISubscriber subscriber, ISubscriber subscriber,
string? title, string? title,
string? description, string? description,
Func<TConfiguration, TValue> read) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer) Func<TConfiguration, TValue> read,
Func<TValue, TConfiguration> write) : base(serviceProvider, serviceFactory, publisher, subscriber, disposer)
{ {
this.title = title; this.title = title;
this.description = description; this.description = description;
this.read = read; this.read = read;
this.write = write;
} }
public Task Handle(Changed<TConfiguration> args, public Task Handle(Changed<TConfiguration> args,
@@ -54,6 +61,11 @@ public partial class WidgetConfigurationViewModel<TConfiguration, TValue> :
return Task.CompletedTask; return Task.CompletedTask;
} }
protected override void OnChanged(TValue? value)
{
base.OnChanged(value);
}
} }
public class WidgetConfigurationViewModel : public class WidgetConfigurationViewModel :
+2 -2
View File
@@ -42,7 +42,7 @@ public class WidgetBuilder :
services.AddSingleton<IDisposer, Disposer>(); services.AddSingleton<IDisposer, Disposer>();
services.AddHandler<WidgetAvailabilityChangedHandler>(); services.AddHandler<WidgetAvailabilityChangedHandler>();
services.AddConfigurationChanged<WidgetConfiguration, services.AddConfiguration<WidgetConfiguration,
WidgetAvailability>((config) => (args) => WidgetAvailability>((config) => (args) =>
{ {
args.Value = config.IsEnabled; args.Value = config.IsEnabled;
@@ -80,7 +80,7 @@ public class WidgetBuilder :
hostBuilder.ConfigureServices(services => hostBuilder.ConfigureServices(services =>
{ {
services.AddHandler<WidgetConfigurationHandler>(); // services.AddHandler<WidgetConfigurationHandler>();
services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name, services.AddConfiguration<WidgetConfiguration>(section: configuration.GetType().Name,
configuration: configuration); configuration: configuration);
@@ -1,19 +0,0 @@
namespace Hyperbar.Widget;
public class WidgetConfigurationHandler(IEnumerable<IConfigurationChangedPublisher<WidgetConfiguration>>
configurationValueChangedNotifications) :
INotificationHandler<Changed<WidgetConfiguration>>
{
public async Task Handle(Changed<WidgetConfiguration> args,
CancellationToken cancellationToken)
{
if (args.Value is WidgetConfiguration configuration)
{
foreach (IConfigurationChangedPublisher<WidgetConfiguration> notification in
configurationValueChangedNotifications)
{
await notification.PublishAsync(configuration);
}
}
}
}
+26
View File
@@ -0,0 +1,26 @@
namespace Hyperbar;
public class UpdateConfigurationHandler<TConfiguration, TValue> :
INotificationHandler<Update<TValue>>
{
}
public class ConfigurationChangedHandler<TConfiguration, TValue>(ConfigurationValue<TConfiguration, TValue> configurationValue) :
INotificationHandler<Changed<TConfiguration>>
where TValue :
class, new()
{
public Task Handle(Changed<TConfiguration> args,
CancellationToken cancellationToken = default)
{
if (args.Value is TConfiguration configuration)
{
if (configurationValue.TryUpdate(configuration, out TValue value))
{
}
}
return Task.CompletedTask;
}
}
-24
View File
@@ -1,24 +0,0 @@
namespace Hyperbar;
public class ConfigurationChangedPublisher<TConfiguration, TValue>(IPublisher publisher,
Func<TConfiguration, Action<TValue>> factory) :
IConfigurationChangedPublisher<TConfiguration>
where TConfiguration :
class
where TValue :
class, new()
{
private TValue? value;
public async Task PublishAsync(TConfiguration configuration)
{
TValue newValue = new();
factory(configuration).Invoke(newValue);
if (value is null || !value.Equals(newValue))
{
value = newValue;
await publisher.PublishAsync(new Changed<TValue>(value));
}
}
}
+25
View File
@@ -0,0 +1,25 @@
namespace Hyperbar;
public class ConfigurationValue<TConfiguration, TValue>(Func<TConfiguration, Action<TValue>> changed)
where TValue :
class, new()
{
private TValue? currentValue;
public bool TryUpdate(TConfiguration configuration,
out TValue value)
{
TValue newValue = new();
changed(configuration).Invoke(newValue);
if (!EqualityComparer<TValue>.Default.Equals(currentValue, newValue))
{
value = newValue;
currentValue = newValue;
return true;
}
value = currentValue!;
return false;
}
}
+4
View File
@@ -0,0 +1,4 @@
namespace Hyperbar;
public interface IConfigurationChanged<TConfiguration> :
IInitializer;
@@ -1,6 +0,0 @@
namespace Hyperbar;
public interface IConfigurationChangedPublisher<TConfiguration>
{
Task PublishAsync(TConfiguration configuration);
}
+8 -8
View File
@@ -10,16 +10,16 @@ namespace Hyperbar;
public static class IServiceCollectionExtensions public static class IServiceCollectionExtensions
{ {
public static IServiceCollection AddConfigurationChanged<TConfiguration, TValue>(this IServiceCollection services, public static IServiceCollection AddConfiguration<TConfiguration,
Func<TConfiguration, Action<TValue>> factory) TValue>(this IServiceCollection services,
Func<TConfiguration, Action<TValue>> changed)
where TConfiguration : where TConfiguration :
class class
where TValue : where TValue :
class, new() class, new()
{ {
services.AddSingleton<IConfigurationChangedPublisher<TConfiguration>>(provider => services.AddSingleton(new ConfigurationValue<TConfiguration, TValue>(changed));
new ConfigurationChangedPublisher<TConfiguration, TValue>(provider.GetRequiredService<IPublisher>(), services.AddHandler<ConfigurationChangedHandler<TConfiguration, TValue>>();
factory));
return services; return services;
} }
@@ -214,8 +214,7 @@ public static class IServiceCollectionExtensions
contract.GetGenericArguments() is { Length: 1 } notificationArguments) contract.GetGenericArguments() is { Length: 1 } notificationArguments)
{ {
Type notificationType = notificationArguments[0]; Type notificationType = notificationArguments[0];
services.Add(new ServiceDescriptor( services.Add(new ServiceDescriptor(typeof(INotificationHandler<>).MakeGenericType(notificationType),
typeof(INotificationHandler<>).MakeGenericType(notificationType),
typeof(THandler), typeof(THandler),
lifetime)); lifetime));
} }
@@ -235,7 +234,8 @@ public static class IServiceCollectionExtensions
provider.GetService<IServiceFactory>()?.Create( provider.GetService<IServiceFactory>()?.Create(
wrapperType, wrapperType,
provider.GetRequiredService<THandler>(), provider.GetRequiredService<THandler>(),
provider.GetServices(typeof(IPipelineBehavior<,>).MakeGenericType(requestType, responseType)) provider.GetServices(typeof(IPipelineBehavior<,>)
.MakeGenericType(requestType, responseType))
)!, )!,
lifetime lifetime
)); ));
+7
View File
@@ -11,4 +11,11 @@ public partial class ValueViewModel<TValue>(IServiceProvider serviceProvider,
{ {
[ObservableProperty] [ObservableProperty]
private TValue? value; private TValue? value;
protected virtual void OnChanged(TValue? value)
{
}
partial void OnValueChanged(TValue? value) => OnChanged(value);
} }