// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using Realms; namespace osu.Game.Database { public static class RealmExtensions { /// /// Performs a . /// If a match was not found, a is performed before trying a second time. /// This ensures that an instance is found even if the realm requested against was not in a consistent state. /// /// The realm to operate on. /// The ID of the entity to find in the realm. /// The type of the entity to find in the realm. /// /// The retrieved entity of type . /// Can be if the entity is still not found by even after a refresh. /// public static T? FindWithRefresh(this Realm realm, Guid id) where T : IRealmObject { var found = realm.Find(id); if (found == null) { // It may be that we access this from the update thread before a refresh has taken place. // To ensure that behaviour matches what we'd expect (the object generally *should be* available), force // a refresh to bring in any off-thread changes immediately. realm.Refresh(); found = realm.Find(id); } return found; } /// /// Perform a write operation against the provided realm instance. /// /// /// This will automatically start a transaction if not already in one. /// /// The realm to operate on. /// The write operation to run. public static void Write(this Realm realm, Action function) { Transaction? transaction = null; try { if (!realm.IsInTransaction) transaction = realm.BeginWrite(); function(realm); transaction?.Commit(); } finally { transaction?.Dispose(); } } /// /// Perform a write operation against the provided realm instance. /// /// /// This will automatically start a transaction if not already in one. /// /// The realm to operate on. /// The write operation to run. public static T Write(this Realm realm, Func function) { Transaction? transaction = null; try { if (!realm.IsInTransaction) transaction = realm.BeginWrite(); var result = function(realm); transaction?.Commit(); return result; } finally { transaction?.Dispose(); } } /// /// Whether the provided change set has changes to the top level collection. /// /// /// Realm subscriptions fire on both collection and property changes (including *all* nested properties). /// Quite often we only care about changes at a collection level. This can be used to guard and early-return when no such changes are in a callback. /// public static bool HasCollectionChanges(this ChangeSet changes) => changes.InsertedIndices.Length > 0 || changes.DeletedIndices.Length > 0 || changes.Moves.Length > 0; } }