mirror of https://github.com/ppy/osu
Avoid creating realm contexts or refetching when accessing `RealmLive` from the update thread
This commit is contained in:
parent
cdd63e428c
commit
d76822b685
|
@ -2,6 +2,7 @@
|
|||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Development;
|
||||
using Realms;
|
||||
|
||||
|
@ -22,7 +23,9 @@ public class RealmLive<T> : ILive<T> where T : RealmObject, IHasGuidPrimaryKey
|
|||
/// <summary>
|
||||
/// The original live data used to create this instance.
|
||||
/// </summary>
|
||||
private readonly T data;
|
||||
private T data;
|
||||
|
||||
private bool dataIsFromUpdateThread;
|
||||
|
||||
private readonly RealmAccess realm;
|
||||
|
||||
|
@ -37,6 +40,7 @@ public RealmLive(T data, RealmAccess realm)
|
|||
this.realm = realm;
|
||||
|
||||
ID = data.ID;
|
||||
dataIsFromUpdateThread = ThreadSafety.IsUpdateThread;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,7 +55,17 @@ public void PerformRead(Action<T> perform)
|
|||
return;
|
||||
}
|
||||
|
||||
realm.Run(r => perform(retrieveFromID(r, ID)));
|
||||
realm.Run(r =>
|
||||
{
|
||||
if (ThreadSafety.IsUpdateThread)
|
||||
{
|
||||
ensureDataIsFromUpdateThread();
|
||||
perform(data);
|
||||
return;
|
||||
}
|
||||
|
||||
perform(retrieveFromID(r, ID));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -63,6 +77,12 @@ public TReturn PerformRead<TReturn>(Func<T, TReturn> perform)
|
|||
if (!IsManaged)
|
||||
return perform(data);
|
||||
|
||||
if (ThreadSafety.IsUpdateThread)
|
||||
{
|
||||
ensureDataIsFromUpdateThread();
|
||||
return perform(data);
|
||||
}
|
||||
|
||||
return realm.Run(r =>
|
||||
{
|
||||
var returnData = perform(retrieveFromID(r, ID));
|
||||
|
@ -101,10 +121,22 @@ public T Value
|
|||
if (!ThreadSafety.IsUpdateThread)
|
||||
throw new InvalidOperationException($"Can't use {nameof(Value)} on managed objects from non-update threads");
|
||||
|
||||
return realm.Realm.Find<T>(ID);
|
||||
ensureDataIsFromUpdateThread();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureDataIsFromUpdateThread()
|
||||
{
|
||||
Debug.Assert(ThreadSafety.IsUpdateThread);
|
||||
|
||||
if (dataIsFromUpdateThread)
|
||||
return;
|
||||
|
||||
dataIsFromUpdateThread = true;
|
||||
data = retrieveFromID(realm.Realm, ID);
|
||||
}
|
||||
|
||||
private T retrieveFromID(Realm realm, Guid id)
|
||||
{
|
||||
var found = realm.Find<T>(ID);
|
||||
|
|
Loading…
Reference in New Issue