mirror of
https://github.com/ppy/osu.git
synced 2025-01-26 16:12:54 +08:00
Fix transactions not actually being committed
This commit is contained in:
parent
af1509d892
commit
8a08d3f4ef
@ -1,8 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
@ -92,19 +92,42 @@ namespace osu.Game.Database
|
||||
{
|
||||
}
|
||||
|
||||
public class RealmWriteUsage : InvokeOnDisposal<RealmContextFactory>
|
||||
/// <summary>
|
||||
/// A transaction used for making changes to realm data.
|
||||
/// </summary>
|
||||
public class RealmWriteUsage : IDisposable
|
||||
{
|
||||
public readonly Realm Context;
|
||||
public readonly Realm Realm;
|
||||
|
||||
public RealmWriteUsage(RealmContextFactory factory)
|
||||
: base(factory, usageCompleted)
|
||||
private readonly RealmContextFactory factory;
|
||||
private readonly Transaction transaction;
|
||||
|
||||
internal RealmWriteUsage(RealmContextFactory factory)
|
||||
{
|
||||
Context = factory.createContext();
|
||||
Context.BeginWrite();
|
||||
this.factory = factory;
|
||||
|
||||
Realm = factory.createContext();
|
||||
transaction = Realm.BeginWrite();
|
||||
}
|
||||
|
||||
private static void usageCompleted(RealmContextFactory factory)
|
||||
/// <summary>
|
||||
/// Commit all changes made in this transaction.
|
||||
/// </summary>
|
||||
public void Commit() => transaction.Commit();
|
||||
|
||||
/// <summary>
|
||||
/// Revert all changes made in this transaction.
|
||||
/// </summary>
|
||||
public void Rollback() => transaction.Rollback();
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this instance, calling the initially captured action.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// rollback if not explicitly committed.
|
||||
transaction?.Dispose();
|
||||
|
||||
Monitor.Exit(factory.writeLock);
|
||||
pending_writes.Value--;
|
||||
}
|
||||
|
@ -53,11 +53,8 @@ namespace osu.Game.Input
|
||||
{
|
||||
var instance = ruleset.CreateInstance();
|
||||
|
||||
using (realmFactory.GetForWrite())
|
||||
{
|
||||
foreach (var variant in instance.AvailableVariants)
|
||||
insertDefaults(instance.GetDefaultKeyBindings(variant), ruleset.ID, variant);
|
||||
}
|
||||
foreach (var variant in instance.AvailableVariants)
|
||||
insertDefaults(instance.GetDefaultKeyBindings(variant), ruleset.ID, variant);
|
||||
}
|
||||
|
||||
private void insertDefaults(IEnumerable<IKeyBinding> defaults, int? rulesetId = null, int? variant = null)
|
||||
@ -67,7 +64,7 @@ namespace osu.Game.Input
|
||||
// compare counts in database vs defaults
|
||||
foreach (var group in defaults.GroupBy(k => k.Action))
|
||||
{
|
||||
int count = usage.Context.All<RealmKeyBinding>().Count(k => k.RulesetID == rulesetId && k.Variant == variant && k.ActionInt == (int)group.Key);
|
||||
int count = usage.Realm.All<RealmKeyBinding>().Count(k => k.RulesetID == rulesetId && k.Variant == variant && k.ActionInt == (int)group.Key);
|
||||
int aimCount = group.Count();
|
||||
|
||||
if (aimCount <= count)
|
||||
@ -76,7 +73,7 @@ namespace osu.Game.Input
|
||||
foreach (var insertable in group.Skip(count).Take(aimCount - count))
|
||||
{
|
||||
// insert any defaults which are missing.
|
||||
usage.Context.Add(new RealmKeyBinding
|
||||
usage.Realm.Add(new RealmKeyBinding
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
KeyCombinationString = insertable.KeyCombination.ToString(),
|
||||
@ -86,6 +83,8 @@ namespace osu.Game.Input
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
usage.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,16 +330,16 @@ namespace osu.Game
|
||||
private void migrateDataToRealm()
|
||||
{
|
||||
using (var db = contextFactory.GetForWrite())
|
||||
using (var realm = realmFactory.GetForWrite())
|
||||
using (var usage = realmFactory.GetForWrite())
|
||||
{
|
||||
var existingBindings = db.Context.DatabasedKeyBinding;
|
||||
|
||||
// only migrate data if the realm database is empty.
|
||||
if (!realm.Context.All<RealmKeyBinding>().Any())
|
||||
if (!usage.Realm.All<RealmKeyBinding>().Any())
|
||||
{
|
||||
foreach (var dkb in existingBindings)
|
||||
{
|
||||
realm.Context.Add(new RealmKeyBinding
|
||||
usage.Realm.Add(new RealmKeyBinding
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
KeyCombinationString = dkb.KeyCombination.ToString(),
|
||||
@ -351,6 +351,8 @@ namespace osu.Game
|
||||
}
|
||||
|
||||
db.Context.RemoveRange(existingBindings);
|
||||
|
||||
usage.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,10 +129,12 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
var button = buttons[i++];
|
||||
button.UpdateKeyCombination(d);
|
||||
|
||||
using (var write = realmFactory.GetForWrite())
|
||||
using (var usage = realmFactory.GetForWrite())
|
||||
{
|
||||
var binding = write.Context.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)button.KeyBinding).ID);
|
||||
var binding = usage.Realm.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)button.KeyBinding).ID);
|
||||
binding.KeyCombinationString = button.KeyBinding.KeyCombinationString;
|
||||
|
||||
usage.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -294,8 +296,10 @@ namespace osu.Game.Overlays.KeyBinding
|
||||
{
|
||||
using (var write = realmFactory.GetForWrite())
|
||||
{
|
||||
var binding = write.Context.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)bindTarget.KeyBinding).ID);
|
||||
var binding = write.Realm.Find<RealmKeyBinding>(((IHasGuidPrimaryKey)bindTarget.KeyBinding).ID);
|
||||
binding.KeyCombinationString = bindTarget.KeyBinding.KeyCombinationString;
|
||||
|
||||
write.Commit();
|
||||
}
|
||||
|
||||
bindTarget.IsBinding = false;
|
||||
|
Loading…
Reference in New Issue
Block a user