Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/rgen/Microsoft.Macios.Generator/Emitters/ClassEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,41 @@ void EmitProperties (in BindingContext context, TabbedWriter<StringWriter> class

void EmitNotifications (in ImmutableArray<Property> properties, TabbedWriter<StringWriter> classBlock)
{
// to be implemented, do not throw or tests will fail.
if (properties.Length == 0)
return;

// default values
const string defaultNotificationCenter = "NSNotificationCenter.DefaultCenter";
const string defaultEventArgument = "Foundation.NSNotificationEventArgs";

// add a space just to make it nicer to read
classBlock.WriteLine ();

// create a nested static class with the notification helpers
using (var notificationClass = classBlock.CreateBlock ("public static partial class Notifications", true)) {
notificationClass.WriteLine ();
// generate two methods per notification
foreach (var notification in properties) {
var count = 12; // == "Notification".Length;
var name = $"Observe{notification.Name [..^count]}";
var notificationCenter = notification.ExportFieldData?.FieldData.NotificationCenter ?? defaultNotificationCenter;
var eventType = notification.ExportFieldData?.FieldData.Type ?? defaultEventArgument;
// use the raw writer which makes it easier to read in this case
notificationClass.WriteRaw (
@$"public static NSObject {name} (EventHandler<{eventType}> handler)
{{
return {notificationCenter}.AddObserver ({notification.Name}, notification => handler (null, new {eventType} (notification)));
}}

public static NSObject {name} (NSObject objectToObserve, EventHandler<{eventType}> handler)
{{
return {notificationCenter}.AddObserver ({notification.Name}, notification => handler (null, new {eventType} (notification)), objectToObserve);
}}

"
);
}
}
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public class TestDataGenerator : BaseTestDataGenerator, IEnumerable<object []> {
(ApplePlatform.MacOSX, "AppKitPropertyTests", "AppKitPropertyTests.cs", "ExpectedAppKitPropertyTests.cs", null),
(ApplePlatform.MacOSX, "ThreadSafeAppKitPropertyTests", "ThreadSafeAppKitPropertyTests.cs", "ExpectedThreadSafeAppKitPropertyTests.cs", null),

(ApplePlatform.iOS, "NSUserDefaults", "NSUserDefaults.cs", "ExpectedNSUserDefaults.cs", null),
(ApplePlatform.TVOS, "NSUserDefaults", "NSUserDefaults.cs", "ExpectedNSUserDefaults.cs", null),
(ApplePlatform.MacCatalyst, "NSUserDefaults", "NSUserDefaults.cs", "ExpectedNSUserDefaults.cs", null),
(ApplePlatform.MacOSX, "NSUserDefaults", "NSUserDefaults.cs", "ExpectedNSUserDefaults.cs", null),
};

public IEnumerator<object []> GetEnumerator ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,5 +127,20 @@ public static partial int FormatRGBA16Int
return Dlfcn.GetInt32 (Libraries.TestNamespace.Handle, "FormatRGBA16Int");
}
}

public static partial class Notifications
{

public static NSObject ObserveDidProcessEditing (EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (DidProcessEditingNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)));
}

public static NSObject ObserveDidProcessEditing (NSObject objectToObserve, EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (DidProcessEditingNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)), objectToObserve);
}

}
// TODO: add binding code here
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// <auto-generated />

#nullable enable

using Foundation;
using ObjCBindings;
using ObjCRuntime;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;

namespace Foundation;

[Register ("NSUserDefaults", true)]
public partial class NSUserDefaults
{
[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
static readonly NativeHandle class_ptr = Class.GetHandle ("NSUserDefaults");

public override NativeHandle ClassHandle => class_ptr;

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[DesignatedInitializer]
[Export ("init")]
public NSUserDefaults () : base (NSObjectFlag.Empty)
{
if (IsDirectBinding)
InitializeHandle (global::ObjCRuntime.Messaging.IntPtr_objc_msgSend (this.Handle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
else
InitializeHandle (global::ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
}

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected NSUserDefaults (NSObjectFlag t) : base (t) {}

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[EditorBrowsable (EditorBrowsableState.Advanced)]
protected internal NSUserDefaults (NativeHandle handle) : base (handle) {}

static Foundation.NSString? _CompletedInitialSyncNotification;

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[Advice ("Use 'NSUserDefaults.Notifications.CompletedInitialSyncNotification' helper method instead.")]
public static partial Foundation.NSString CompletedInitialSyncNotification
{
get
{
if (_CompletedInitialSyncNotification is null)
_CompletedInitialSyncNotification = Dlfcn.GetStringConstant (Libraries.Foundation.Handle, "NSUbiquitousUserDefaultsCompletedInitialSyncNotification")!;
return _CompletedInitialSyncNotification;
}
}

static Foundation.NSString? _DidChangeAccountsNotification;

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[Advice ("Use 'NSUserDefaults.Notifications.DidChangeAccountsNotification' helper method instead.")]
public static partial Foundation.NSString DidChangeAccountsNotification
{
get
{
if (_DidChangeAccountsNotification is null)
_DidChangeAccountsNotification = Dlfcn.GetStringConstant (Libraries.Foundation.Handle, "NSUbiquitousUserDefaultsDidChangeAccountsNotification")!;
return _DidChangeAccountsNotification;
}
}

static Foundation.NSString? _NoCloudAccountNotification;

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[Advice ("Use 'NSUserDefaults.Notifications.NoCloudAccountNotification' helper method instead.")]
public static partial Foundation.NSString NoCloudAccountNotification
{
get
{
if (_NoCloudAccountNotification is null)
_NoCloudAccountNotification = Dlfcn.GetStringConstant (Libraries.Foundation.Handle, "NSUbiquitousUserDefaultsNoCloudAccountNotification")!;
return _NoCloudAccountNotification;
}
}

static Foundation.NSString? _SizeLimitExceededNotification;

[BindingImpl (BindingImplOptions.GeneratedCode | BindingImplOptions.Optimizable)]
[Advice ("Use 'NSUserDefaults.Notifications.SizeLimitExceededNotification' helper method instead.")]
public static partial Foundation.NSString SizeLimitExceededNotification
{
get
{
if (_SizeLimitExceededNotification is null)
_SizeLimitExceededNotification = Dlfcn.GetStringConstant (Libraries.Foundation.Handle, "NSUserDefaultsSizeLimitExceededNotification")!;
return _SizeLimitExceededNotification;
}
}

public static partial class Notifications
{

public static NSObject ObserveCompletedInitialSync (EventHandler<Foundation.MyNotificationArgs> handler)
{
return SharedWorkspace.NotificationCenter.AddObserver (CompletedInitialSyncNotification, notification => handler (null, new Foundation.MyNotificationArgs (notification)));
}

public static NSObject ObserveCompletedInitialSync (NSObject objectToObserve, EventHandler<Foundation.MyNotificationArgs> handler)
{
return SharedWorkspace.NotificationCenter.AddObserver (CompletedInitialSyncNotification, notification => handler (null, new Foundation.MyNotificationArgs (notification)), objectToObserve);
}

public static NSObject ObserveDidChangeAccounts (EventHandler<Foundation.MyNotificationArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (DidChangeAccountsNotification, notification => handler (null, new Foundation.MyNotificationArgs (notification)));
}

public static NSObject ObserveDidChangeAccounts (NSObject objectToObserve, EventHandler<Foundation.MyNotificationArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (DidChangeAccountsNotification, notification => handler (null, new Foundation.MyNotificationArgs (notification)), objectToObserve);
}

public static NSObject ObserveNoCloudAccount (EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return SharedWorkspace.NotificationCenter.AddObserver (NoCloudAccountNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)));
}

public static NSObject ObserveNoCloudAccount (NSObject objectToObserve, EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return SharedWorkspace.NotificationCenter.AddObserver (NoCloudAccountNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)), objectToObserve);
}

public static NSObject ObserveSizeLimitExceeded (EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (SizeLimitExceededNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)));
}

public static NSObject ObserveSizeLimitExceeded (NSObject objectToObserve, EventHandler<Foundation.NSNotificationEventArgs> handler)
{
return NSNotificationCenter.DefaultCenter.AddObserver (SizeLimitExceededNotification, notification => handler (null, new Foundation.NSNotificationEventArgs (notification)), objectToObserve);
}

}
// TODO: add binding code here
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Runtime.Versioning;
using Foundation;
using ObjCBindings;

namespace Foundation

public partial class MyNotificationArgs {

}

[BindingType<Class>]
public partial class NSUserDefaults : NSObject {

// default values

[Field<Property> ("NSUserDefaultsSizeLimitExceededNotification", Flags = Property.Notification)]
public static partial NSString SizeLimitExceededNotification { get; }

// special notification center
[Field<Property> ("NSUbiquitousUserDefaultsNoCloudAccountNotification", Flags = Property.Notification, NotificationCenter = "SharedWorkspace.NotificationCenter")]
public static partial NSString NoCloudAccountNotification { get; }

// special args
[Field<Property> ("NSUbiquitousUserDefaultsDidChangeAccountsNotification", Flags = Property.Notification, Type = typeof (MyNotificationArgs))]
public static partial NSString DidChangeAccountsNotification { get; }

// full customization
[Field<Property> ("NSUbiquitousUserDefaultsCompletedInitialSyncNotification", Flags = Property.Notification, Type = typeof (MyNotificationArgs), NotificationCenter = "SharedWorkspace.NotificationCenter")]
public static partial NSString CompletedInitialSyncNotification { get; }
}