more changes
This commit is contained in:
@@ -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 :
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user