Skip to content

Commit

Permalink
[UIKit] Inline the UITraitChangeObservable protocol into the classes …
Browse files Browse the repository at this point in the history
…that implement it. Fixes #20265.

This also required fixing:

* A bug in the static registrar where we'd ignore the generic parameters in a method
  when looking for methods implementing an interface.

* A bug in the generator where we'd throw You_Should_Not_Call_base_In_This_Method()
  in some cases where we shouldn't.

Also:

* Enable nullability and fix any resulting issues.
* Clean up some legacy code we don't need anymore.

Ref: #19410 (comment)

Fixes #20265.
  • Loading branch information
rolfbjarne committed Nov 21, 2024
1 parent 611c7a1 commit 2bfed6b
Show file tree
Hide file tree
Showing 9 changed files with 755 additions and 103 deletions.
119 changes: 119 additions & 0 deletions src/UIKit/UIPresentationController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
using System;
using System.Runtime.InteropServices;

using Foundation;
using ObjCRuntime;

#nullable enable

namespace UIKit {
public partial class UIPresentationController {
#region Inlined from the UITraitChangeObservable protocol
/// <summary>
/// Registers a callback handler that will be executed when one of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Action<IUITraitEnvironment, UITraitCollection> handler)
{
return IUITraitChangeObservable._RegisterForTraitChanges (this, traits, handler);
}

/// <summary>
/// Registers a callback handler that will be executed when one of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges (Action<IUITraitEnvironment, UITraitCollection> handler, params Type [] traits)
{
// Add an override with 'params', unfortunately this means reordering the parameters.
return IUITraitChangeObservable._RegisterForTraitChanges (this, handler, traits);
}

/// <summary>
/// Registers a callback handler that will be executed when the specified trait changes.
/// </summary>
/// <typeparam name="T">The trait to observe.</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T : IUITraitDefinition
{
return IUITraitChangeObservable._RegisterForTraitChanges<T> (this, handler);
}

/// <summary>
/// Registers a callback handler that will be executed when any of the specified traits changes.
/// </summary>
/// <typeparam name="T1">A trait to observe</typeparam>
/// <typeparam name="T2">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
{
return IUITraitChangeObservable._RegisterForTraitChanges<T1, T2> (this, handler);
}

/// <summary>
/// Registers a callback handler that will be executed when any of the specified traits changes.
/// </summary>
/// <typeparam name="T1">A trait to observe</typeparam>
/// <typeparam name="T2">A trait to observe</typeparam>
/// <typeparam name="T3">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
{
return IUITraitChangeObservable._RegisterForTraitChanges<T1, T2, T3> (this, handler);
}

/// <summary>
/// Registers a callback handler that will be executed when any of the specified traits changes.
/// </summary>
/// <typeparam name="T1">A trait to observe</typeparam>
/// <typeparam name="T2">A trait to observe</typeparam>
/// <typeparam name="T3">A trait to observe</typeparam>
/// <typeparam name="T4">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3, T4> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
where T4 : IUITraitDefinition
{
return IUITraitChangeObservable._RegisterForTraitChanges<T1, T2, T3, T4> (this, handler);
}

/// <summary>
/// Registers a selector that will be called on the specified object when any of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="target">The object whose specified selector will be called.</param>
/// <param name="action">The selector to call on the specified object.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, NSObject target, Selector action)
{
return IUITraitChangeObservable._RegisterForTraitChanges (this, traits, target, action);
}

/// <summary>
/// Registers a selector that will be called on the current object when any of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="action">The selector to call on the current object.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Selector action)
{
return IUITraitChangeObservable._RegisterForTraitChanges (this, traits, action);
}
#endregion
}
}
128 changes: 63 additions & 65 deletions src/UIKit/UITraitChangeObservable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// Copyright 2023 Microsoft Corp. All rights reserved.
//

#if !__WATCHOS__

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
Expand All @@ -17,10 +15,6 @@
using Foundation;
using ObjCRuntime;

#if !NET
using NativeHandle = System.IntPtr;
#endif

#nullable enable

namespace UIKit {
Expand Down Expand Up @@ -48,7 +42,12 @@ public static Class [] ToClasses (params Type [] traits)
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Action<IUITraitEnvironment, UITraitCollection> handler)
{
return RegisterForTraitChanges (ToClasses (traits), handler);
return _RegisterForTraitChanges (this, traits, handler);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges (IUITraitChangeObservable This, Type [] traits, Action<IUITraitEnvironment, UITraitCollection> handler)
{
return _RegisterForTraitChanges (This, ToClasses (traits), handler);
}

/// <summary>
Expand All @@ -57,10 +56,15 @@ public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Actio
/// <param name="traits">The traits to observe.</param>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges (Action<IUITraitEnvironment, UITraitCollection> handler, params Type [] traits)
public IUITraitChangeRegistration RegisterForTraitChanges (Action<IUITraitEnvironment, UITraitCollection> handler, params Type [] traits)
{
return _RegisterForTraitChanges (this, handler, traits);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges (IUITraitChangeObservable This, Action<IUITraitEnvironment, UITraitCollection> handler, params Type [] traits)
{
// Add an override with 'params', unfortunately this means reordering the parameters.
return RegisterForTraitChanges (ToClasses (traits), handler);
return _RegisterForTraitChanges (This, ToClasses (traits), handler);
}

/// <summary>
Expand All @@ -69,10 +73,16 @@ public unsafe IUITraitChangeRegistration RegisterForTraitChanges (Action<IUITrai
/// <typeparam name="T">The trait to observe.</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T> (Action<IUITraitEnvironment, UITraitCollection> handler)
public IUITraitChangeRegistration RegisterForTraitChanges<T> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T : IUITraitDefinition
{
return _RegisterForTraitChanges<T> (this, handler);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges<T> (IUITraitChangeObservable This, Action<IUITraitEnvironment, UITraitCollection> handler)
where T : IUITraitDefinition
{
return RegisterForTraitChanges (ToClasses (typeof (T)), handler);
return _RegisterForTraitChanges (This, ToClasses (typeof (T)), handler);
}

/// <summary>
Expand All @@ -82,11 +92,18 @@ public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T> (Action<IUIT
/// <typeparam name="T2">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2> (Action<IUITraitEnvironment, UITraitCollection> handler)
public IUITraitChangeRegistration RegisterForTraitChanges<T1, T2> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
{
return _RegisterForTraitChanges<T1, T2> (this, handler);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges<T1, T2> (IUITraitChangeObservable This, Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
{
return RegisterForTraitChanges (ToClasses (typeof (T1), typeof (T2)), handler);
return _RegisterForTraitChanges (This, ToClasses (typeof (T1), typeof (T2)), handler);
}

/// <summary>
Expand All @@ -97,12 +114,20 @@ public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2> (Action
/// <typeparam name="T3">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3> (Action<IUITraitEnvironment, UITraitCollection> handler)
public IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
{
return _RegisterForTraitChanges<T1, T2, T3> (this, handler);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges<T1, T2, T3> (IUITraitChangeObservable This, Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
{
return RegisterForTraitChanges (ToClasses (typeof (T1), typeof (T2), typeof (T3)), handler);
return _RegisterForTraitChanges (This, ToClasses (typeof (T1), typeof (T2), typeof (T3)), handler);
}

/// <summary>
Expand All @@ -114,13 +139,22 @@ public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3> (Ac
/// <typeparam name="T4">A trait to observe</typeparam>
/// <param name="handler">The callback to execute when any of the specified traits changes.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3, T4> (Action<IUITraitEnvironment, UITraitCollection> handler)
public IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3, T4> (Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
where T4 : IUITraitDefinition
{
return RegisterForTraitChanges (ToClasses (typeof (T1), typeof (T2), typeof (T3), typeof (T4)), handler);
return _RegisterForTraitChanges<T1, T2, T3, T3> (this, handler);
}

internal static IUITraitChangeRegistration _RegisterForTraitChanges<T1, T2, T3, T4> (IUITraitChangeObservable This, Action<IUITraitEnvironment, UITraitCollection> handler)
where T1 : IUITraitDefinition
where T2 : IUITraitDefinition
where T3 : IUITraitDefinition
where T4 : IUITraitDefinition
{
return _RegisterForTraitChanges (This, ToClasses (typeof (T1), typeof (T2), typeof (T3), typeof (T4)), handler);
}

/// <summary>
Expand All @@ -132,65 +166,29 @@ public unsafe IUITraitChangeRegistration RegisterForTraitChanges<T1, T2, T3, T4>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, NSObject target, Selector action)
{
return RegisterForTraitChanges (ToClasses (traits), target, action);
}

/// <summary>
/// Registers a selector that will be called on the current object when any of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="action">The selector to call on the current object.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Selector action)
{
return RegisterForTraitChanges (ToClasses (traits), action);
return _RegisterForTraitChanges (this, traits, target, action);
}


#if !NET
[BindingImpl (BindingImplOptions.Optimizable)]
public IUITraitChangeRegistration RegisterForTraitChanges (Class [] traits, global::System.Action<IUITraitEnvironment, UITraitCollection> handler)
internal static IUITraitChangeRegistration _RegisterForTraitChanges (IUITraitChangeObservable This, Type [] traits, NSObject target, Selector action)
{
// The manual block code is somewhat annoying to implement, so at least don't do it twice (once for .NET and once for legacy Xamarin) unless we really need to.
throw new NotImplementedException ("This API has not been implemented for legacy Xamarin. Please upgrade to .NET");
return _RegisterForTraitChanges (This, ToClasses (traits), target, action);
}

/// <summary>
/// Registers a selector that will be called on the specified object when any of the specified traits changes.
/// Registers a selector that will be called on the current object when any of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="target">The object whose specified selector will be called.</param>
/// <param name="action">The selector to call on the specified object.</param>
/// <param name="action">The selector to call on the current object.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
[BindingImpl (BindingImplOptions.Optimizable)]
public IUITraitChangeRegistration RegisterForTraitChanges (Class [] traits, NSObject target, Selector action)
public IUITraitChangeRegistration RegisterForTraitChanges (Type [] traits, Selector action)
{
global::UIKit.UIApplication.EnsureUIThread ();
if (traits is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (traits));
var target__handle__ = target!.GetNonNullHandle (nameof (target));
var action__handle__ = action!.GetNonNullHandle (nameof (action));
using var nsa_traits = NSArray.FromNSObjects (traits);
return Runtime.GetINativeObject<IUITraitChangeRegistration> (NativeHandle_objc_msgSend_NativeHandle_NativeHandle_NativeHandle (this.Handle, Selector.GetHandle ("registerForTraitChanges:withTarget:action:"), nsa_traits.Handle, target__handle__, action.Handle), false)!;
return _RegisterForTraitChanges (this, traits, action);
}

/// <summary>
/// Registers a selector that will be called on the specified object when any of the specified traits changes.
/// </summary>
/// <param name="traits">The traits to observe.</param>
/// <param name="action">The selector to call on the current object.</param>
/// <returns>A token that can be used to unregister the callback by calling <see cref="M:UnregisterForTraitChanges" />.</returns>
[BindingImpl (BindingImplOptions.Optimizable)]
public IUITraitChangeRegistration RegisterForTraitChanges (Class [] traits, Selector action)
internal static IUITraitChangeRegistration _RegisterForTraitChanges (IUITraitChangeObservable This, Type [] traits, Selector action)
{
global::UIKit.UIApplication.EnsureUIThread ();
if (traits is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (traits));
var action__handle__ = action!.GetNonNullHandle (nameof (action));
using var nsa_traits = NSArray.FromNSObjects (traits);
return Runtime.GetINativeObject<IUITraitChangeRegistration> (NativeHandle_objc_msgSend_NativeHandle_NativeHandle (this.Handle, Selector.GetHandle ("registerForTraitChanges:withAction:"), nsa_traits.Handle, action.Handle), false)!;
return _RegisterForTraitChanges (This, ToClasses (traits), action);
}
#endif // !NET

#if XAMCORE_5_0
private static Class [] ToClasses (IUITraitDefinition [] traits)
Expand All @@ -207,6 +205,7 @@ public static Class [] ToClasses (IUITraitDefinition [] traits)
return traitsClasses;
}

#if !XAMCORE_5_0
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use the 'UITraitChangeObservable.RegisterForTraitChanges (Class[], Action<IUITraitEnvironment, UITraitCollection>)' method instead.")]
public IUITraitChangeRegistration RegisterForTraitChanges (IUITraitDefinition [] traits, Action<IUITraitEnvironment, UITraitCollection> handler)
Expand All @@ -227,6 +226,7 @@ public IUITraitChangeRegistration RegisterForTraitChanges (IUITraitDefinition []
{
return RegisterForTraitChanges (ToClasses (traits), action);
}
#endif // !XACMORE_5_0

[DllImport (Messaging.LIBOBJC_DYLIB, EntryPoint = "objc_msgSend")]
#if XAMCORE_5_0
Expand All @@ -253,7 +253,7 @@ public IUITraitChangeRegistration RegisterForTraitChanges (IUITraitDefinition []
#endif
}

#if !XAMCORE_5_0 && NET
#if !XAMCORE_5_0
public partial class UIPresentationController {
[Obsolete ("Use the 'UITraitChangeObservable.RegisterForTraitChanges (Class[], Action<IUITraitEnvironment, UITraitCollection>)' method instead.", false)]
[EditorBrowsable (EditorBrowsableState.Never)]
Expand Down Expand Up @@ -415,5 +415,3 @@ public static IUITraitChangeRegistration RegisterForTraitChanges (this IUITraitC
}
#endif
}

#endif // !__WATCHOS__
Loading

0 comments on commit 2bfed6b

Please sign in to comment.