From 6ad14ecf4f800f5f0914ac279bfa5df5c98ec3a3 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Thu, 31 Oct 2024 16:32:47 -0400 Subject: [PATCH 1/6] feat: Added the ability to specify a positionning to DiagnosticsView registrations --- .../Diagnostics/DiagnosticViewRegistry.cs | 45 ++++++++++++++++--- .../Diagnostics/DiagnosticsOverlay.cs | 7 +-- .../Diagnostics/DiagnosticView.Factories.cs | 34 ++++++++++---- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs b/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs index 41a3a91a7b64..f0e22250f3a0 100644 --- a/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs +++ b/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs @@ -12,7 +12,7 @@ internal static class DiagnosticViewRegistry { internal static EventHandler>? Added; - private static ImmutableArray _registrations = ImmutableArray.Empty; + private static ImmutableArray _registrations = []; /// /// Gets the list of registered diagnostic providers. @@ -24,18 +24,38 @@ internal static class DiagnosticViewRegistry /// /// A diagnostic view to display. /// Defines when the registered diagnostic view should be displayed. - public static void Register(IDiagnosticView view, DiagnosticViewRegistrationMode mode = default) + public static void Register(IDiagnosticView view, DiagnosticViewRegistrationMode mode = default, DiagnosticViewRegistrationPosition position = default) { ImmutableInterlocked.Update( ref _registrations, static (providers, provider) => providers.Add(provider), - new DiagnosticViewRegistration(mode, view)); + new DiagnosticViewRegistration(mode, position, view)); Added?.Invoke(null, _registrations); } } -internal record DiagnosticViewRegistration(DiagnosticViewRegistrationMode Mode, IDiagnosticView View); +internal sealed record DiagnosticViewRegistration( + DiagnosticViewRegistrationMode Mode, + DiagnosticViewRegistrationPosition Position, + IDiagnosticView View) : IComparable +{ + 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; + } +} public enum DiagnosticViewRegistrationMode { @@ -43,7 +63,7 @@ public enum DiagnosticViewRegistrationMode /// Diagnostic is being display on at least one window. /// I.e. only the main/first opened but move to the next one if the current window is closed. /// - One, + One, // Default /// /// Diagnostic is being rendered as overlay on each window. @@ -55,3 +75,18 @@ public enum DiagnosticViewRegistrationMode /// OnDemand } + +public enum DiagnosticViewRegistrationPosition +{ + Normal = 0, // Default + + /// + /// Register as the first diagnostic view, ensuring it is displayed first. + /// + First = -1, + + /// + /// Register as the last diagnostic view, ensuring it is displayed last. + /// + Last = 1, +} diff --git a/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs b/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs index 20ad0d418211..f5aafa64ffaf 100644 --- a/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs +++ b/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs @@ -2,6 +2,7 @@ #if WINUI || HAS_UNO_WINUI using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; @@ -462,10 +463,10 @@ private void EnqueueUpdate(bool forceUpdate = false) var viewsThatShouldBeMaterialized = DiagnosticViewRegistry .Registrations .Where(ShouldMaterialize) + .Order() // See DiagnosticViewRegistration.CompareTo .Select(reg => reg.View) - .Concat(_localRegistrations) - .Distinct() - .ToList(); + .Concat(_localRegistrations) // They are at the end of the list. + .Distinct(); foreach (var view in viewsThatShouldBeMaterialized) { diff --git a/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs b/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs index d67177d8ce0f..2ec8b905a3bb 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs @@ -21,11 +21,16 @@ partial class DiagnosticView /// /// Type of the control. /// The user-friendly name of the diagnostics view. - public static DiagnosticView Register(string friendlyName) + /// Defines when the registered diagnostic view should be displayed. + /// Defines where the item should be placed in the overlay. + public static DiagnosticView Register( + string friendlyName, + DiagnosticViewRegistrationMode mode = default, + DiagnosticViewRegistrationPosition position = default) where TView : UIElement, new() { var provider = new DiagnosticView(typeof(TView).Name, friendlyName, () => new TView()); - DiagnosticViewRegistry.Register(provider); + DiagnosticViewRegistry.Register(provider, mode, position); return provider; } @@ -43,11 +48,16 @@ public static DiagnosticView Register(string friendlyName) /// The user-friendly name of the diagnostics view. /// Factory to create an instance of the control. /// Defines when the registered diagnostic view should be displayed. - public static DiagnosticView Register(string friendlyName, Func factory, DiagnosticViewRegistrationMode mode = default) + /// Defines where the item should be placed in the overlay. + public static DiagnosticView Register( + string friendlyName, + Func factory, + DiagnosticViewRegistrationMode mode = default, + DiagnosticViewRegistrationPosition position = default) where TView : UIElement { var provider = new DiagnosticView(typeof(TView).Name, friendlyName, factory); - DiagnosticViewRegistry.Register(provider, mode); + DiagnosticViewRegistry.Register(provider, mode, position); return provider; } @@ -62,17 +72,21 @@ public static DiagnosticView Register(string friendlyName, FuncThe user-friendly name of the diagnostics view. /// Delegate to use to update the when the is being updated. /// Optional delegate used to show more details about the diagnostic info when user taps on the view. + /// Defines when the registered diagnostic view should be displayed. + /// Defines where the item should be placed in the overlay. /// A diagnostic view helper class which can be used to push updates of the state (cf. ). public static DiagnosticView Register( string friendlyName, Action update, - Func? details = null) + Func? details = null, + DiagnosticViewRegistrationMode mode = default, + DiagnosticViewRegistrationPosition position = default) where TView : FrameworkElement, new() { var provider = details is null ? new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update) : new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update, (ctx, state, ct) => new(details(state))); - DiagnosticViewRegistry.Register(provider); + DiagnosticViewRegistry.Register(provider, mode, position); return provider; } @@ -88,18 +102,22 @@ public static DiagnosticView Register( /// Factory to create an instance of the generic element. /// Delegate to use to update the when the is being updated. /// Optional delegate used to show more details about the diagnostic info when user taps on the view. + /// Defines when the registered diagnostic view should be displayed. + /// Defines where the item should be placed in the overlay. /// A diagnostic view helper class which can be used to push updates of the state (cf. ). public static DiagnosticView Register( string friendlyName, Func factory, Action update, - Func? details = null) + Func? details = null, + DiagnosticViewRegistrationMode mode = default, + DiagnosticViewRegistrationPosition position = default) where TView : FrameworkElement { var provider = details is null ? new DiagnosticView(typeof(TView).Name, friendlyName, factory, update) : new DiagnosticView(typeof(TView).Name, friendlyName, factory, update, (ctx, state, ct) => new(details(state))); - DiagnosticViewRegistry.Register(provider); + DiagnosticViewRegistry.Register(provider, mode, position); return provider; } } From 49243e3c889c68606559aa7daeddb12780d10cca Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Thu, 31 Oct 2024 17:40:58 -0400 Subject: [PATCH 2/6] feat: Added the ability to wait for the RemoteControlClient to be available --- .../RemoteControlClient.cs | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/Uno.UI.RemoteControl/RemoteControlClient.cs b/src/Uno.UI.RemoteControl/RemoteControlClient.cs index c05abcabf61a..de8d05b302b3 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlClient.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlClient.cs @@ -33,7 +33,63 @@ public partial class RemoteControlClient : IRemoteControlClient public delegate void RemoteControlClientEventEventHandler(object sender, ClientEventEventArgs args); public delegate void SendMessageFailedEventHandler(object sender, SendMessageFailedEventArgs args); - public static RemoteControlClient? Instance { get; private set; } + public static RemoteControlClient? Instance + { + get => _instance; + private set + { + _instance = value; + + if (value is { }) + { + while (Interlocked.Exchange(ref _waitingList, null) is { } waitingList) + { + foreach (var action in waitingList) + { + action(value); + } + } + } + } + } + + private static IReadOnlyCollection>? _waitingList; + + /// + /// Add a callback to be called when the Instance is available. + /// + /// + /// Will be called synchronously if the instance is already available, no need to check for it before. + /// + public static void OnRemoteControlClientAvailable(Action action) + { + if(Instance is not null) + { + action(Instance); + } + else + { + // Thread-safe way to add the action to a waiting list for the client to be available + while (true) + { + var waitingList = _waitingList; + IReadOnlyCollection> newList = waitingList is null + ? [action] + : [.. waitingList, action]; + + if(Instance is { } i) // Last chance to avoid the waiting list + { + action(i); + break; + } + + if (ReferenceEquals(Interlocked.CompareExchange(ref _waitingList, newList, waitingList), waitingList)) + { + break; + } + } + } + } public static RemoteControlClient Initialize(Type appType) => Instance = new RemoteControlClient(appType); @@ -59,6 +115,7 @@ internal static RemoteControlClient Initialize(Type appType, ServerEndpointAttri private readonly StatusSink _status; private static readonly TimeSpan _keepAliveInterval = TimeSpan.FromSeconds(30); + private static RemoteControlClient? _instance; private readonly (string endpoint, int port)[]? _serverAddresses; private readonly Dictionary _processors = new(); private readonly List _preprocessors = new(); From 9e74167589a1dc2064d59e3afd9f2d068815d559 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Thu, 31 Oct 2024 22:04:29 -0400 Subject: [PATCH 3/6] ci: Fix build --- src/Uno.UI.RemoteControl/RemoteControlClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Uno.UI.RemoteControl/RemoteControlClient.cs b/src/Uno.UI.RemoteControl/RemoteControlClient.cs index de8d05b302b3..306aea9a7390 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlClient.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlClient.cs @@ -63,7 +63,7 @@ private set /// public static void OnRemoteControlClientAvailable(Action action) { - if(Instance is not null) + if (Instance is { }) { action(Instance); } @@ -77,7 +77,7 @@ public static void OnRemoteControlClientAvailable(Action ac ? [action] : [.. waitingList, action]; - if(Instance is { } i) // Last chance to avoid the waiting list + if (Instance is { } i) // Last chance to avoid the waiting list { action(i); break; From 6bbf32cd0d853ff9b66f61289222535a1db8d562 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Fri, 1 Nov 2024 13:12:11 -0400 Subject: [PATCH 4/6] feat: Improved the error logging to give more context on the connection failed reason --- .../RemoteControlClient.cs | 3 ++- .../RemoteControlStatus.cs | 21 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Uno.UI.RemoteControl/RemoteControlClient.cs b/src/Uno.UI.RemoteControl/RemoteControlClient.cs index 306aea9a7390..9d35fad28c75 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlClient.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlClient.cs @@ -486,7 +486,8 @@ private async Task Connect(Uri serverUri, int delay, CancellationTok { if (this.Log().IsEnabled(LogLevel.Trace)) { - this.Log().Trace($"Connecting to [{serverUri}] failed: {e.Message}"); + var innerMessage = e.InnerException is { } ie ? $" ({ie.Message})" : ""; + this.Log().Trace($"Connecting to [{serverUri}] failed: {e.Message}{innerMessage}"); } return new(this, serverUri, watch, null); diff --git a/src/Uno.UI.RemoteControl/RemoteControlStatus.cs b/src/Uno.UI.RemoteControl/RemoteControlStatus.cs index 87de6eb8d095..f1915e455f34 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlStatus.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlStatus.cs @@ -12,8 +12,27 @@ public record RemoteControlStatus( ImmutableHashSet MissingRequiredProcessors, (long Count, ImmutableHashSet Types) InvalidFrames) { - public bool IsAllGood => State == ConnectionState.Connected && IsVersionValid == true && MissingRequiredProcessors.IsEmpty && KeepAlive.State == KeepAliveState.Ok && InvalidFrames.Count == 0; + /// + /// A boolean indicating if everything is fine with the connection and the handshaking succeeded. + /// + public bool IsAllGood => + State == ConnectionState.Connected +#if !DEBUG + // For debug builds, it's annoying to have the version mismatch preventing the connection + // Only Uno devs should get this issue, let's not block them. + && IsVersionValid == true +#endif + && MissingRequiredProcessors.IsEmpty + && KeepAlive.State == KeepAliveState.Ok + && InvalidFrames.Count == 0; + + /// + /// If the connection is problematic, meaning that the connection is not in a good state. + /// + /// + /// It's just a negation of . + /// public bool IsProblematic => !IsAllGood; public (Classification kind, string message) GetSummary() From af2d3f000940b88d164f043438582a0e94065e3d Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Fri, 1 Nov 2024 19:35:56 -0400 Subject: [PATCH 5/6] refactor: Make the _local registrations_ of the diagnostics overlay sortable like other registrations --- .../Diagnostics/DiagnosticViewRegistry.cs | 24 +++---------------- .../Diagnostics/IDiagnosticView.cs | 2 ++ .../RemoteControlClient.cs | 1 - .../Diagnostics/DiagnosticsOverlay.cs | 8 +++---- .../Diagnostics/DiagnosticView.Factories.cs | 20 ++++++++-------- .../DiagnosticView.TView.TState.cs | 5 +++- .../Diagnostics/DiagnosticView.TView.cs | 10 +++++--- src/Uno.UI/Diagnostics/DiagnosticView.cs | 10 ++++---- .../DiagnosticViewManager.TView.TState.cs | 4 +++- 9 files changed, 39 insertions(+), 45 deletions(-) diff --git a/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs b/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs index f0e22250f3a0..d153d4bf4347 100644 --- a/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs +++ b/src/Uno.Foundation/Diagnostics/DiagnosticViewRegistry.cs @@ -24,12 +24,12 @@ internal static class DiagnosticViewRegistry /// /// A diagnostic view to display. /// Defines when the registered diagnostic view should be displayed. - 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); } @@ -37,25 +37,7 @@ public static void Register(IDiagnosticView view, DiagnosticViewRegistrationMode internal sealed record DiagnosticViewRegistration( DiagnosticViewRegistrationMode Mode, - DiagnosticViewRegistrationPosition Position, - IDiagnosticView View) : IComparable -{ - 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 { diff --git a/src/Uno.Foundation/Diagnostics/IDiagnosticView.cs b/src/Uno.Foundation/Diagnostics/IDiagnosticView.cs index 34847ce89737..2e35bbd3021b 100644 --- a/src/Uno.Foundation/Diagnostics/IDiagnosticView.cs +++ b/src/Uno.Foundation/Diagnostics/IDiagnosticView.cs @@ -21,6 +21,8 @@ public interface IDiagnosticView /// string Name { get; } + DiagnosticViewRegistrationPosition Position => DiagnosticViewRegistrationPosition.Normal; + /// /// Gets a visual element of the diagnostic, usually a value or an icon. /// diff --git a/src/Uno.UI.RemoteControl/RemoteControlClient.cs b/src/Uno.UI.RemoteControl/RemoteControlClient.cs index 9d35fad28c75..12f6223f5874 100644 --- a/src/Uno.UI.RemoteControl/RemoteControlClient.cs +++ b/src/Uno.UI.RemoteControl/RemoteControlClient.cs @@ -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 diff --git a/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs b/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs index f5aafa64ffaf..b26d78949ad9 100644 --- a/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs +++ b/src/Uno.UI.Toolkit/Diagnostics/DiagnosticsOverlay.cs @@ -317,8 +317,8 @@ public void Show(string viewId) /// Add a UI diagnostic element to this overlay. /// /// This will also make this overlay visible (cf. ). - public void Add(string id, string name, UIElement preview, Func? details = null) - => Add(new DiagnosticView(id, name, _ => preview, (_, ct) => new(details?.Invoke()))); + public void Add(string id, string name, UIElement preview, Func? details = null, DiagnosticViewRegistrationPosition position = default) + => Add(new DiagnosticView(id, name, _ => preview, (_, ct) => new(details?.Invoke()), position)); /// /// Add a UI diagnostic element to this overlay. @@ -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) diff --git a/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs b/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs index 2ec8b905a3bb..393379f0fcc6 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticView.Factories.cs @@ -29,8 +29,8 @@ public static DiagnosticView Register( DiagnosticViewRegistrationPosition position = default) where TView : UIElement, new() { - var provider = new DiagnosticView(typeof(TView).Name, friendlyName, () => new TView()); - DiagnosticViewRegistry.Register(provider, mode, position); + var provider = new DiagnosticView(typeof(TView).Name, friendlyName, () => new TView(), position: position); + DiagnosticViewRegistry.Register(provider, mode); return provider; } @@ -56,8 +56,8 @@ public static DiagnosticView Register( DiagnosticViewRegistrationPosition position = default) where TView : UIElement { - var provider = new DiagnosticView(typeof(TView).Name, friendlyName, factory); - DiagnosticViewRegistry.Register(provider, mode, position); + var provider = new DiagnosticView(typeof(TView).Name, friendlyName, factory, position: position); + DiagnosticViewRegistry.Register(provider, mode); return provider; } @@ -84,9 +84,9 @@ public static DiagnosticView Register( where TView : FrameworkElement, new() { var provider = details is null - ? new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update) - : new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update, (ctx, state, ct) => new(details(state))); - DiagnosticViewRegistry.Register(provider, mode, position); + ? new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update, position: position) + : new DiagnosticView(typeof(TView).Name, friendlyName, _ => new TView(), update, (ctx, state, ct) => new(details(state)), position: position); + DiagnosticViewRegistry.Register(provider, mode); return provider; } @@ -115,9 +115,9 @@ public static DiagnosticView Register( where TView : FrameworkElement { var provider = details is null - ? new DiagnosticView(typeof(TView).Name, friendlyName, factory, update) - : new DiagnosticView(typeof(TView).Name, friendlyName, factory, update, (ctx, state, ct) => new(details(state))); - DiagnosticViewRegistry.Register(provider, mode, position); + ? new DiagnosticView(typeof(TView).Name, friendlyName, factory, update, position: position) + : new DiagnosticView(typeof(TView).Name, friendlyName, factory, update, (ctx, state, ct) => new(details(state)), position: position); + DiagnosticViewRegistry.Register(provider, mode); return provider; } } diff --git a/src/Uno.UI/Diagnostics/DiagnosticView.TView.TState.cs b/src/Uno.UI/Diagnostics/DiagnosticView.TView.TState.cs index a2bcbf6b0851..2c8fbbabcf79 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticView.TView.TState.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticView.TView.TState.cs @@ -15,7 +15,8 @@ public class DiagnosticView( string name, Func factory, Action update, - Func>? details = null) + Func>? details = null, + DiagnosticViewRegistrationPosition position = default) : IDiagnosticView where TView : FrameworkElement { @@ -37,6 +38,8 @@ public void Update(TState status) /// string IDiagnosticView.Name => name; + DiagnosticViewRegistrationPosition IDiagnosticView.Position => position; + /// object IDiagnosticView.GetElement(IDiagnosticViewContext context) => _elementsManager.GetView(context); diff --git a/src/Uno.UI/Diagnostics/DiagnosticView.TView.cs b/src/Uno.UI/Diagnostics/DiagnosticView.TView.cs index 3f0cf8997cb1..619d748bea12 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticView.TView.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticView.TView.cs @@ -14,7 +14,8 @@ public class DiagnosticView( string id, string name, Func factory, - Func>? details = null) + Func>? details = null, + DiagnosticViewRegistrationPosition position = default) : IDiagnosticView where TView : UIElement { @@ -22,8 +23,9 @@ public DiagnosticView( string id, string name, Func preview, - Func>? details = null) - : this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct)) + Func>? details = null, + DiagnosticViewRegistrationPosition position = default) + : this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct), position) { } @@ -33,6 +35,8 @@ public DiagnosticView( /// string IDiagnosticView.Name => name; + DiagnosticViewRegistrationPosition IDiagnosticView.Position => position; + /// object IDiagnosticView.GetElement(IDiagnosticViewContext context) => factory(context); diff --git a/src/Uno.UI/Diagnostics/DiagnosticView.cs b/src/Uno.UI/Diagnostics/DiagnosticView.cs index 9849ba1e2294..4a7eebf30157 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticView.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticView.cs @@ -14,15 +14,17 @@ public partial class DiagnosticView( string id, string name, Func factory, - Func>? details = null) - : DiagnosticView(id, name, factory, details) + Func>? details = null, + DiagnosticViewRegistrationPosition position = default) + : DiagnosticView(id, name, factory, details, position) { public DiagnosticView( string id, string name, Func preview, - Func>? details = null) - : this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct)) + Func>? details = null, + DiagnosticViewRegistrationPosition position = default) + : this(id, name, _ => preview(), async (_, ct) => details is null ? null : await details(ct), position) { } } diff --git a/src/Uno.UI/Diagnostics/DiagnosticViewManager.TView.TState.cs b/src/Uno.UI/Diagnostics/DiagnosticViewManager.TView.TState.cs index 9598b2262813..ece3e7235dc3 100644 --- a/src/Uno.UI/Diagnostics/DiagnosticViewManager.TView.TState.cs +++ b/src/Uno.UI/Diagnostics/DiagnosticViewManager.TView.TState.cs @@ -12,7 +12,9 @@ namespace Uno.Diagnostics.UI; /// Type of the state used to update the . /// Factory to create an instance of the . /// Delegate to use to update the on . -internal class DiagnosticViewManager(Func factory, Action update) +internal class DiagnosticViewManager( + Func factory, + Action update) where TView : FrameworkElement { private event EventHandler? _changed; From 87ac235a17a887cc064d138a97d456e512fbd1f1 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Fri, 1 Nov 2024 20:51:30 -0400 Subject: [PATCH 6/6] ci: Fix build by adjusting PackageDiff --- build/PackageDiffIgnore.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/PackageDiffIgnore.xml b/build/PackageDiffIgnore.xml index 875317d81ea1..6f0c700a3375 100644 --- a/build/PackageDiffIgnore.xml +++ b/build/PackageDiffIgnore.xml @@ -1982,6 +1982,10 @@ + + + +