1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 10:52:53 +08:00

Add Register method for subscription purposes and update safeties

This commit is contained in:
Dean Herbert 2022-01-21 18:13:21 +09:00
parent 8f1dfa33a2
commit 18bf690a30
2 changed files with 30 additions and 4 deletions

View File

@ -88,6 +88,10 @@ namespace osu.Game.Database
}
}
internal static bool CurrentThreadSubscriptionsAllowed => current_thread_subscriptions_allowed.Value;
private static readonly ThreadLocal<bool> current_thread_subscriptions_allowed = new ThreadLocal<bool>();
/// <summary>
/// Construct a new instance of a realm context factory.
/// </summary>
@ -222,6 +226,30 @@ namespace osu.Game.Database
}
}
/// <summary>
/// Run work on realm that will be run every time the update thread realm context gets recycled.
/// </summary>
/// <param name="action">The work to run.</param>
public void Register(Action<Realm> action)
{
if (!ThreadSafety.IsUpdateThread && context != null)
throw new InvalidOperationException(@$"{nameof(BlockAllOperations)} must be called from the update thread.");
if (ThreadSafety.IsUpdateThread)
{
current_thread_subscriptions_allowed.Value = true;
action(Context);
current_thread_subscriptions_allowed.Value = false;
}
else
{
current_thread_subscriptions_allowed.Value = true;
using (var realm = createContext())
action(realm);
current_thread_subscriptions_allowed.Value = false;
}
}
private Realm createContext()
{
if (isDisposed)

View File

@ -7,7 +7,6 @@ using System.Linq;
using System.Runtime.Serialization;
using AutoMapper;
using AutoMapper.Internal;
using osu.Framework.Development;
using osu.Game.Beatmaps;
using osu.Game.Input.Bindings;
using osu.Game.Models;
@ -272,9 +271,8 @@ namespace osu.Game.Database
public static IDisposable? QueryAsyncWithNotifications<T>(this IRealmCollection<T> collection, NotificationCallbackDelegate<T> callback)
where T : RealmObjectBase
{
// Subscriptions can only work on the main thread.
if (!ThreadSafety.IsUpdateThread)
throw new InvalidOperationException("Cannot subscribe for realm notifications from a non-update thread.");
if (!RealmContextFactory.CurrentThreadSubscriptionsAllowed)
throw new InvalidOperationException($"Make sure to call {nameof(RealmContextFactory)}.{nameof(RealmContextFactory.Register)}");
return collection.SubscribeForNotifications(callback);
}