Provide a realm factory to usages of ToLive/RealmLive

This commit is contained in:
Dean Herbert
2021-12-14 14:21:23 +09:00
parent f9a2db5ec6
commit 441b7baa93
11 changed files with 67 additions and 44 deletions

View File

@ -24,14 +24,22 @@ namespace osu.Game.Database
/// </summary>
private readonly T data;
private readonly RealmContextFactory? realmFactory;
/// <summary>
/// Construct a new instance of live realm data.
/// </summary>
/// <param name="data">The realm data.</param>
public RealmLive(T data)
/// <param name="realmFactory">The realm factory the data was sourced from. May be null for an unmanaged object.</param>
public RealmLive(T data, RealmContextFactory? realmFactory)
{
this.data = data;
if (IsManaged && realmFactory == null)
throw new ArgumentException(@"Realm factory must be provided for a managed instance", nameof(realmFactory));
this.realmFactory = realmFactory;
ID = data.ID;
}
@ -47,7 +55,10 @@ namespace osu.Game.Database
return;
}
using (var realm = Realm.GetInstance(data.Realm.Config))
if (realmFactory == null)
throw new ArgumentException(@"Realm factory must be provided for a managed instance", nameof(realmFactory));
using (var realm = realmFactory.CreateContext())
perform(realm.Find<T>(ID));
}
@ -58,12 +69,15 @@ namespace osu.Game.Database
public TReturn PerformRead<TReturn>(Func<T, TReturn> perform)
{
if (typeof(RealmObjectBase).IsAssignableFrom(typeof(TReturn)))
throw new InvalidOperationException($"Realm live objects should not exit the scope of {nameof(PerformRead)}.");
throw new InvalidOperationException(@$"Realm live objects should not exit the scope of {nameof(PerformRead)}.");
if (!IsManaged)
return perform(data);
using (var realm = Realm.GetInstance(data.Realm.Config))
if (realmFactory == null)
throw new ArgumentException(@"Realm factory must be provided for a managed instance", nameof(realmFactory));
using (var realm = realmFactory.CreateContext())
return perform(realm.Find<T>(ID));
}
@ -74,7 +88,7 @@ namespace osu.Game.Database
public void PerformWrite(Action<T> perform)
{
if (!IsManaged)
throw new InvalidOperationException("Can't perform writes on a non-managed underlying value");
throw new InvalidOperationException(@"Can't perform writes on a non-managed underlying value");
PerformRead(t =>
{
@ -94,11 +108,7 @@ namespace osu.Game.Database
if (!ThreadSafety.IsUpdateThread)
throw new InvalidOperationException($"Can't use {nameof(Value)} on managed objects from non-update threads");
// When using Value, we rely on garbage collection for the realm instance used to retrieve the instance.
// As we are sure that this is on the update thread, there should always be an open and constantly refreshing realm instance to ensure file size growth is a non-issue.
var realm = Realm.GetInstance(data.Realm.Config);
return realm.Find<T>(ID);
return realmFactory!.Context.Find<T>(ID);
}
}