Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed delegate change #3512

Merged
merged 1 commit into from
Feb 7, 2024
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
3 changes: 2 additions & 1 deletion Realm/Realm/DatabaseTypes/Accessors/ManagedAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ public void UnsubscribeFromNotifications()

/// <inheritdoc/>
void INotifiable<NotifiableObjectHandleBase.CollectionChangeSet>.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)
Expand Down
4 changes: 2 additions & 2 deletions Realm/Realm/DatabaseTypes/INotifiable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ internal interface INotifiable<TChangeset>
/// </summary>
/// <param name="changes">The changes that occurred.</param>
/// <param name="type">The type of the key paths collection related to the notification.</param>
/// <param name="callbackNative">The eventual callback to call for the notification (if type == Explicit)</param>
void NotifyCallbacks(TChangeset? changes, KeyPathsCollectionType type, IntPtr callbackNative = default);
/// <param name="callback">The eventual callback to call for the notification (if type == Explicit).</param>
void NotifyCallbacks(TChangeset? changes, KeyPathsCollectionType type, Delegate? callback);
}

internal class NotificationToken<TCallback> : IDisposable
Expand Down
9 changes: 4 additions & 5 deletions Realm/Realm/DatabaseTypes/RealmCollectionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -434,7 +434,7 @@ private void UpdateCollectionChangedSubscriptionIfNecessary(bool isSubscribed)

#endregion INotifyCollectionChanged

void INotifiable<CollectionChangeSet>.NotifyCallbacks(CollectionChangeSet? changes, KeyPathsCollectionType type, IntPtr callbackNative)
void INotifiable<CollectionChangeSet>.NotifyCallbacks(CollectionChangeSet? changes, KeyPathsCollectionType type, Delegate? callback)
{
ChangeSet? changeset = null;
if (changes != null)
Expand All @@ -449,10 +449,9 @@ void INotifiable<CollectionChangeSet>.NotifyCallbacks(CollectionChangeSet? chang
cleared: actualChanges.Cleared);
}

if (type == KeyPathsCollectionType.Explicit
&& GCHandle.FromIntPtr(callbackNative).Target is NotificationCallbackDelegate<T> callback)
if (callback is NotificationCallbackDelegate<T> notificationCallback)
{
callback(this, changeset);
notificationCallback(this, changeset);
return;
}

Expand Down
4 changes: 3 additions & 1 deletion Realm/Realm/DatabaseTypes/RealmDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,13 @@ protected override bool ContainsRealmObjects()
protected override KeyValuePair<string, TValue> GetValueAtIndex(int index) => _dictionaryHandle.GetValueAtIndex<TValue>(index, Realm);

void INotifiable<DictionaryHandle.DictionaryChangeSet>.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)
{
Expand Down
2 changes: 1 addition & 1 deletion Realm/Realm/Handles/DictionaryHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ public static unsafe void NotifyDictionaryChanged(IntPtr managedHandle, Dictiona
{
if (GCHandle.FromIntPtr(managedHandle).Target is INotifiable<DictionaryChangeSet> notifiable)
{
notifiable.NotifyCallbacks(changes == null ? null : *changes, KeyPathsCollectionType.Full);
notifiable.NotifyCallbacks(changes == null ? null : *changes, KeyPathsCollectionType.Full, callback: null);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion Realm/Realm/Handles/NotifiableObjectHandleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public static unsafe void NotifyObjectChanged(IntPtr managedHandle, CollectionCh
{
if (GCHandle.FromIntPtr(managedHandle).Target is INotifiable<CollectionChangeSet> 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);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/Realm.Tests/Database/NotificationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1740,7 +1740,7 @@ void OnNotification(IRealmCollection<TestNotificationObject> s, ChangeSet? chang
}

[Test]
public void SubscribeWithKeypaths_ShallowKeypath_RaisesOnlyCollectioNotifications()
public void SubscribeWithKeypaths_ShallowKeypath_RaisesOnlyCollectionNotifications()
{
var query = _realm.All<TestNotificationObject>();
var changesets = new List<ChangeSet>();
Expand Down
Loading