Skip to content

Commit

Permalink
refactor: Make the _local registrations_ of the diagnostics overlay s…
Browse files Browse the repository at this point in the history
…ortable like other registrations
  • Loading branch information
carldebilly committed Nov 1, 2024
1 parent 6bbf32c commit af2d3f0
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 45 deletions.
24 changes: 3 additions & 21 deletions src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,20 @@ internal static class DiagnosticViewRegistry
/// </summary>
/// <param name="view">A diagnostic view to display.</param>
/// <param name="mode">Defines when the registered diagnostic view should be displayed.</param>
public static void Register(IDiagnosticView view, DiagnosticViewRegistrationMode mode = default, DiagnosticViewRegistrationPosition position = default)
public static void Register(IDiagnosticView view, DiagnosticViewRegistrationMode mode = default)
{
ImmutableInterlocked.Update(
ref _registrations,
static (providers, provider) => providers.Add(provider),
new DiagnosticViewRegistration(mode, position, view));
new DiagnosticViewRegistration(mode, view));

Added?.Invoke(null, _registrations);
}
}

internal sealed record DiagnosticViewRegistration(
DiagnosticViewRegistrationMode Mode,
DiagnosticViewRegistrationPosition Position,
IDiagnosticView View) : IComparable<DiagnosticViewRegistration>
{
public int CompareTo(DiagnosticViewRegistration? other)
{
if (other is null)
{
return 1;
}

if (Position == other.Position)
{
// If the position is the same, we compare the view id to ensure a stable order.
return string.Compare(View.Id, other.View.Id, StringComparison.Ordinal);
}

return (int)Position - (int)other.Position;
}
}
IDiagnosticView View);

public enum DiagnosticViewRegistrationMode
{
Expand Down
2 changes: 2 additions & 0 deletions src/Uno.Foundation/Diagnostics/IDiagnosticView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface IDiagnosticView
/// </summary>
string Name { get; }

DiagnosticViewRegistrationPosition Position => DiagnosticViewRegistrationPosition.Normal;

/// <summary>
/// Gets a visual element of the diagnostic, usually a value or an icon.
/// </summary>
Expand Down
1 change: 0 additions & 1 deletion src/Uno.UI.RemoteControl/RemoteControlClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ public void RegisterPreProcessor(IRemoteControlPreProcessor preprocessor)

_status.Report(ConnectionState.Connecting);


const string lastEndpointKey = "__UNO__" + nameof(RemoteControlClient) + "__last_endpoint";
var preferred = ApplicationData.Current.LocalSettings.Values.TryGetValue(lastEndpointKey, out var lastValue) && lastValue is string lastEp
? _serverAddresses.FirstOrDefault(srv => srv.endpoint.Equals(lastEp, StringComparison.OrdinalIgnoreCase)).endpoint
Expand Down
8 changes: 4 additions & 4 deletions src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ public void Show(string viewId)
/// Add a UI diagnostic element to this overlay.
/// </summary>
/// <remarks>This will also make this overlay visible (cf. <see cref="Show(bool?)"/>).</remarks>
public void Add(string id, string name, UIElement preview, Func<UIElement>? details = null)
=> Add(new DiagnosticView(id, name, _ => preview, (_, ct) => new(details?.Invoke())));
public void Add(string id, string name, UIElement preview, Func<UIElement>? details = null, DiagnosticViewRegistrationPosition position = default)
=> Add(new DiagnosticView(id, name, _ => preview, (_, ct) => new(details?.Invoke()), position));

/// <summary>
/// Add a UI diagnostic element to this overlay.
Expand Down Expand Up @@ -463,9 +463,9 @@ private void EnqueueUpdate(bool forceUpdate = false)
var viewsThatShouldBeMaterialized = DiagnosticViewRegistry
.Registrations
.Where(ShouldMaterialize)
.Order() // See DiagnosticViewRegistration.CompareTo
.Select(reg => reg.View)
.Concat(_localRegistrations) // They are at the end of the list.
.Concat(_localRegistrations)
.OrderBy(r => (int)r.Position)
.Distinct();

foreach (var view in viewsThatShouldBeMaterialized)
Expand Down
20 changes: 10 additions & 10 deletions src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public static DiagnosticView<TView> Register<TView>(
DiagnosticViewRegistrationPosition position = default)
where TView : UIElement, new()
{
var provider = new DiagnosticView<TView>(typeof(TView).Name, friendlyName, () => new TView());
DiagnosticViewRegistry.Register(provider, mode, position);
var provider = new DiagnosticView<TView>(typeof(TView).Name, friendlyName, () => new TView(), position: position);
DiagnosticViewRegistry.Register(provider, mode);
return provider;
}

Expand All @@ -56,8 +56,8 @@ public static DiagnosticView<TView> Register<TView>(
DiagnosticViewRegistrationPosition position = default)
where TView : UIElement
{
var provider = new DiagnosticView<TView>(typeof(TView).Name, friendlyName, factory);
DiagnosticViewRegistry.Register(provider, mode, position);
var provider = new DiagnosticView<TView>(typeof(TView).Name, friendlyName, factory, position: position);
DiagnosticViewRegistry.Register(provider, mode);
return provider;
}

Expand All @@ -84,9 +84,9 @@ public static DiagnosticView<TView, TState> Register<TView, TState>(
where TView : FrameworkElement, new()
{
var provider = details is null
? new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, _ => new TView(), update)
: new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, _ => new TView(), update, (ctx, state, ct) => new(details(state)));
DiagnosticViewRegistry.Register(provider, mode, position);
? new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, _ => new TView(), update, position: position)
: new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, _ => new TView(), update, (ctx, state, ct) => new(details(state)), position: position);
DiagnosticViewRegistry.Register(provider, mode);
return provider;
}

Expand Down Expand Up @@ -115,9 +115,9 @@ public static DiagnosticView<TView, TState> Register<TView, TState>(
where TView : FrameworkElement
{
var provider = details is null
? new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, factory, update)
: new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, factory, update, (ctx, state, ct) => new(details(state)));
DiagnosticViewRegistry.Register(provider, mode, position);
? new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, factory, update, position: position)
: new DiagnosticView<TView, TState>(typeof(TView).Name, friendlyName, factory, update, (ctx, state, ct) => new(details(state)), position: position);
DiagnosticViewRegistry.Register(provider, mode);
return provider;
}
}
5 changes: 4 additions & 1 deletion src/Uno.UI/Diagnostics/DiagnosticView.TView.TState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ public class DiagnosticView<TView, TState>(
string name,
Func<IDiagnosticViewContext, TView> factory,
Action<TView, TState> update,
Func<IDiagnosticViewContext, TState, CancellationToken, ValueTask<object?>>? details = null)
Func<IDiagnosticViewContext, TState, CancellationToken, ValueTask<object?>>? details = null,
DiagnosticViewRegistrationPosition position = default)
: IDiagnosticView
where TView : FrameworkElement
{
Expand All @@ -37,6 +38,8 @@ public void Update(TState status)
/// <inheritdoc />
string IDiagnosticView.Name => name;

DiagnosticViewRegistrationPosition IDiagnosticView.Position => position;

/// <inheritdoc />
object IDiagnosticView.GetElement(IDiagnosticViewContext context)
=> _elementsManager.GetView(context);
Expand Down
10 changes: 7 additions & 3 deletions src/Uno.UI/Diagnostics/DiagnosticView.TView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ public class DiagnosticView<TView>(
string id,
string name,
Func<IDiagnosticViewContext, TView> factory,
Func<IDiagnosticViewContext, CancellationToken, ValueTask<object?>>? details = null)
Func<IDiagnosticViewContext, CancellationToken, ValueTask<object?>>? details = null,
DiagnosticViewRegistrationPosition position = default)
: IDiagnosticView
where TView : UIElement
{
public DiagnosticView(
string id,
string name,
Func<TView> preview,
Func<CancellationToken, ValueTask<object?>>? details = null)
: this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct))
Func<CancellationToken, ValueTask<object?>>? details = null,
DiagnosticViewRegistrationPosition position = default)
: this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct), position)
{
}

Expand All @@ -33,6 +35,8 @@ public DiagnosticView(
/// <inheritdoc />
string IDiagnosticView.Name => name;

DiagnosticViewRegistrationPosition IDiagnosticView.Position => position;

/// <inheritdoc />
object IDiagnosticView.GetElement(IDiagnosticViewContext context) => factory(context);

Expand Down
10 changes: 6 additions & 4 deletions src/Uno.UI/Diagnostics/DiagnosticView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ public partial class DiagnosticView(
string id,
string name,
Func<IDiagnosticViewContext, UIElement> factory,
Func<IDiagnosticViewContext, CancellationToken, ValueTask<object?>>? details = null)
: DiagnosticView<UIElement>(id, name, factory, details)
Func<IDiagnosticViewContext, CancellationToken, ValueTask<object?>>? details = null,
DiagnosticViewRegistrationPosition position = default)
: DiagnosticView<UIElement>(id, name, factory, details, position)
{
public DiagnosticView(
string id,
string name,
Func<UIElement> preview,
Func<CancellationToken, ValueTask<object?>>? details = null)
: this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct))
Func<CancellationToken, ValueTask<object?>>? details = null,
DiagnosticViewRegistrationPosition position = default)
: this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct), position)
{
}
}
4 changes: 3 additions & 1 deletion src/Uno.UI/Diagnostics/DiagnosticViewManager.TView.TState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ namespace Uno.Diagnostics.UI;
/// <typeparam name="TState">Type of the state used to update the <typeparamref name="TView"/>.</typeparam>
/// <param name="factory">Factory to create an instance of the <typeparamref name="TView"/>.</param>
/// <param name="update">Delegate to use to update the <typeparamref name="TView"/> on <see cref="NotifyChanged"/>.</param>
internal class DiagnosticViewManager<TView, TState>(Func<IDiagnosticViewContext, TView> factory, Action<IDiagnosticViewContext, TView, TState> update)
internal class DiagnosticViewManager<TView, TState>(
Func<IDiagnosticViewContext, TView> factory,
Action<IDiagnosticViewContext, TView, TState> update)
where TView : FrameworkElement
{
private event EventHandler<TState>? _changed;
Expand Down

0 comments on commit af2d3f0

Please sign in to comment.