From 59232bf34e156ac6610c43d0e39675d551755a0c Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Wed, 7 Feb 2024 07:16:12 +0100 Subject: [PATCH] Proposed delegate change (#3512) --- Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs | 3 ++- Realm/Realm/DatabaseTypes/INotifiable.cs | 4 ++-- Realm/Realm/DatabaseTypes/RealmCollectionBase.cs | 9 ++++----- Realm/Realm/DatabaseTypes/RealmDictionary.cs | 4 +++- Realm/Realm/Handles/DictionaryHandle.cs | 2 +- Realm/Realm/Handles/NotifiableObjectHandleBase.cs | 3 ++- Tests/Realm.Tests/Database/NotificationTests.cs | 2 +- 7 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs b/Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs index c8c8751d0d..917b1ce86a 100644 --- a/Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs +++ b/Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs @@ -210,8 +210,9 @@ public void UnsubscribeFromNotifications() /// void INotifiable.NotifyCallbacks(NotifiableObjectHandleBase.CollectionChangeSet? changes, - KeyPathsCollectionType type, IntPtr callback) + KeyPathsCollectionType type, Delegate? callback) { + Debug.Assert(callback == null, "Object notifications don't support keypaths, so callback should always be null"); if (changes.HasValue) { foreach (var propertyIndex in changes.Value.Properties) diff --git a/Realm/Realm/DatabaseTypes/INotifiable.cs b/Realm/Realm/DatabaseTypes/INotifiable.cs index bf553721f6..8220db146a 100644 --- a/Realm/Realm/DatabaseTypes/INotifiable.cs +++ b/Realm/Realm/DatabaseTypes/INotifiable.cs @@ -34,8 +34,8 @@ internal interface INotifiable /// /// The changes that occurred. /// The type of the key paths collection related to the notification. - /// The eventual callback to call for the notification (if type == Explicit) - void NotifyCallbacks(TChangeset? changes, KeyPathsCollectionType type, IntPtr callbackNative = default); + /// The eventual callback to call for the notification (if type == Explicit). + void NotifyCallbacks(TChangeset? changes, KeyPathsCollectionType type, Delegate? callback); } internal class NotificationToken : IDisposable diff --git a/Realm/Realm/DatabaseTypes/RealmCollectionBase.cs b/Realm/Realm/DatabaseTypes/RealmCollectionBase.cs index 993f11a0a5..146413db4a 100644 --- a/Realm/Realm/DatabaseTypes/RealmCollectionBase.cs +++ b/Realm/Realm/DatabaseTypes/RealmCollectionBase.cs @@ -214,7 +214,7 @@ internal IDisposable SubscribeForNotificationsImpl(NotificationCallbackDelegate< var token = Handle.Value.AddNotificationCallback(GCHandle.ToIntPtr(managedResultsHandle), keyPathsCollection, GCHandle.ToIntPtr(callbackHandle)); - return NotificationToken.Create(callback, c => token.Dispose()); + return NotificationToken.Create(callback, _ => token.Dispose()); } // For notifications with type Default or Shallow we cache the callbacks on the managed level, to avoid creating multiple notifications in core @@ -434,7 +434,7 @@ private void UpdateCollectionChangedSubscriptionIfNecessary(bool isSubscribed) #endregion INotifyCollectionChanged - void INotifiable.NotifyCallbacks(CollectionChangeSet? changes, KeyPathsCollectionType type, IntPtr callbackNative) + void INotifiable.NotifyCallbacks(CollectionChangeSet? changes, KeyPathsCollectionType type, Delegate? callback) { ChangeSet? changeset = null; if (changes != null) @@ -449,10 +449,9 @@ void INotifiable.NotifyCallbacks(CollectionChangeSet? chang cleared: actualChanges.Cleared); } - if (type == KeyPathsCollectionType.Explicit - && GCHandle.FromIntPtr(callbackNative).Target is NotificationCallbackDelegate callback) + if (callback is NotificationCallbackDelegate notificationCallback) { - callback(this, changeset); + notificationCallback(this, changeset); return; } diff --git a/Realm/Realm/DatabaseTypes/RealmDictionary.cs b/Realm/Realm/DatabaseTypes/RealmDictionary.cs index 96c4e7a32d..6e7985ab63 100644 --- a/Realm/Realm/DatabaseTypes/RealmDictionary.cs +++ b/Realm/Realm/DatabaseTypes/RealmDictionary.cs @@ -255,11 +255,13 @@ protected override bool ContainsRealmObjects() protected override KeyValuePair GetValueAtIndex(int index) => _dictionaryHandle.GetValueAtIndex(index, Realm); void INotifiable.NotifyCallbacks(DictionaryHandle.DictionaryChangeSet? changes, - KeyPathsCollectionType type, IntPtr callback) + KeyPathsCollectionType type, Delegate? callback) { Debug.Assert(type == KeyPathsCollectionType.Full, "Notifications should always be default here as we don't expose a way to configure it."); + Debug.Assert(callback == null, "Dictionary notifications don't expose keypaths, so the callback should always be null"); + DictionaryChangeSet? changeset = null; if (changes != null) { diff --git a/Realm/Realm/Handles/DictionaryHandle.cs b/Realm/Realm/Handles/DictionaryHandle.cs index f115186f38..03f6e01c58 100644 --- a/Realm/Realm/Handles/DictionaryHandle.cs +++ b/Realm/Realm/Handles/DictionaryHandle.cs @@ -350,7 +350,7 @@ public static unsafe void NotifyDictionaryChanged(IntPtr managedHandle, Dictiona { if (GCHandle.FromIntPtr(managedHandle).Target is INotifiable notifiable) { - notifiable.NotifyCallbacks(changes == null ? null : *changes, KeyPathsCollectionType.Full); + notifiable.NotifyCallbacks(changes == null ? null : *changes, KeyPathsCollectionType.Full, callback: null); } } } diff --git a/Realm/Realm/Handles/NotifiableObjectHandleBase.cs b/Realm/Realm/Handles/NotifiableObjectHandleBase.cs index 1f6b4da6d4..e530114748 100644 --- a/Realm/Realm/Handles/NotifiableObjectHandleBase.cs +++ b/Realm/Realm/Handles/NotifiableObjectHandleBase.cs @@ -60,7 +60,8 @@ public static unsafe void NotifyObjectChanged(IntPtr managedHandle, CollectionCh { if (GCHandle.FromIntPtr(managedHandle).Target is INotifiable notifiable) { - notifiable.NotifyCallbacks(changes == null ? null : *changes, type, callback); + var managedCallback = type == KeyPathsCollectionType.Explicit && GCHandle.FromIntPtr(callback).Target is Delegate c ? c : null; + notifiable.NotifyCallbacks(changes == null ? null : *changes, type, managedCallback); } } } diff --git a/Tests/Realm.Tests/Database/NotificationTests.cs b/Tests/Realm.Tests/Database/NotificationTests.cs index 5f45c5689c..7a75955ebe 100644 --- a/Tests/Realm.Tests/Database/NotificationTests.cs +++ b/Tests/Realm.Tests/Database/NotificationTests.cs @@ -1740,7 +1740,7 @@ void OnNotification(IRealmCollection s, ChangeSet? chang } [Test] - public void SubscribeWithKeypaths_ShallowKeypath_RaisesOnlyCollectioNotifications() + public void SubscribeWithKeypaths_ShallowKeypath_RaisesOnlyCollectionNotifications() { var query = _realm.All(); var changesets = new List();