1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 09:22:54 +08:00

Make BeatmapStore's BeatmapDatabase private

This commit is contained in:
Dean Herbert 2017-07-27 15:34:13 +09:00
parent 96b08b8777
commit cbe7b08642
8 changed files with 85 additions and 43 deletions

View File

@ -34,7 +34,7 @@ namespace osu.Desktop.VisualTests.Tests
store = new BeatmapStore(storage, null, backingDatabase, rulesets); store = new BeatmapStore(storage, null, backingDatabase, rulesets);
for (int i = 0; i < 100; i += 10) for (int i = 0; i < 100; i += 10)
store.Database.Add(createTestBeatmapSet(i)); store.Import(createTestBeatmapSet(i));
} }
Add(songSelect = new PlaySongSelect()); Add(songSelect = new PlaySongSelect());

View File

@ -3,7 +3,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
@ -15,14 +14,14 @@ namespace osu.Desktop.VisualTests.Tests
{ {
internal class TestCaseResults : TestCase internal class TestCaseResults : TestCase
{ {
private BeatmapStore db; private BeatmapStore beatmaps;
public override string Description => @"Results after playing."; public override string Description => @"Results after playing.";
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(BeatmapStore db) private void load(BeatmapStore beatmaps)
{ {
this.db = db; this.beatmaps = beatmaps;
} }
private WorkingBeatmap beatmap; private WorkingBeatmap beatmap;
@ -33,9 +32,9 @@ namespace osu.Desktop.VisualTests.Tests
if (beatmap == null) if (beatmap == null)
{ {
var beatmapInfo = db.Database.Query<BeatmapInfo>().FirstOrDefault(b => b.RulesetID == 0); var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0);
if (beatmapInfo != null) if (beatmapInfo != null)
beatmap = db.GetWorkingBeatmap(beatmapInfo); beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo);
} }
Add(new Results(new Score Add(new Results(new Score

View File

@ -119,8 +119,7 @@ namespace osu.Game.Tests.Beatmaps.IO
Action waitAction = () => Action waitAction = () =>
{ {
while (!(resultSets = store.Database. while (!(resultSets = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526)).Any())
Query<BeatmapSetInfo>().Where(s => s.OnlineBeatmapSetID == 241526)).Any())
Thread.Sleep(50); Thread.Sleep(50);
}; };
@ -136,16 +135,14 @@ namespace osu.Game.Tests.Beatmaps.IO
//if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet.
waitAction = () => waitAction = () =>
{ {
while ((resultBeatmaps = store.Database. while ((resultBeatmaps = store.QueryBeatmaps(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
QueryAndPopulate<BeatmapInfo>(s => s.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12)
Thread.Sleep(50); Thread.Sleep(50);
}; };
Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout),
@"Beatmaps did not import to the database in allocated time"); @"Beatmaps did not import to the database in allocated time");
var set = resultSets.First(); var set = store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526).First();
store.Database.Populate(set);
Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(), Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count(),
$@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count})."); $@"Incorrect database beatmap count post-import ({resultBeatmaps.Count()} but should be {set.Beatmaps.Count}).");

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Linq.Expressions;
using Ionic.Zip; using Ionic.Zip;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Logging; using osu.Framework.Logging;
@ -24,9 +25,6 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public class BeatmapStore public class BeatmapStore
{ {
// todo: make this private
public readonly BeatmapDatabase Database;
/// <summary> /// <summary>
/// Fired when a new <see cref="BeatmapSetInfo"/> becomes available in the database. /// Fired when a new <see cref="BeatmapSetInfo"/> becomes available in the database.
/// </summary> /// </summary>
@ -48,14 +46,16 @@ namespace osu.Game.Beatmaps
private readonly RulesetDatabase rulesets; private readonly RulesetDatabase rulesets;
private readonly BeatmapDatabase beatmaps;
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised) // ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private BeatmapIPCChannel ipc; private BeatmapIPCChannel ipc;
public BeatmapStore(Storage storage, FileDatabase files, SQLiteConnection connection, RulesetDatabase rulesets, IIpcHost importHost = null) public BeatmapStore(Storage storage, FileDatabase files, SQLiteConnection connection, RulesetDatabase rulesets, IIpcHost importHost = null)
{ {
Database = new BeatmapDatabase(connection); beatmaps = new BeatmapDatabase(connection);
Database.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s); beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s);
Database.BeatmapSetRemoved += s => BeatmapSetRemoved?.Invoke(s); beatmaps.BeatmapSetRemoved += s => BeatmapSetRemoved?.Invoke(s);
this.storage = storage; this.storage = storage;
this.files = files; this.files = files;
@ -106,14 +106,22 @@ namespace osu.Game.Beatmaps
public BeatmapSetInfo Import(ArchiveReader archiveReader) public BeatmapSetInfo Import(ArchiveReader archiveReader)
{ {
BeatmapSetInfo set = importToStorage(archiveReader); BeatmapSetInfo set = importToStorage(archiveReader);
Import(set);
//If we have an ID then we already exist in the database.
if (set.ID == 0)
Database.Add(set);
return set; return set;
} }
/// <summary>
/// Import a beatmap from a <see cref="BeatmapSetInfo"/>.
/// </summary>
/// <param name="beatmapSetInfo">The beatmap to be imported.</param>
public void Import(BeatmapSetInfo beatmapSetInfo)
{
// If we have an ID then we already exist in the database.
if (beatmapSetInfo.ID != 0) return;
beatmaps.Add(beatmapSetInfo);
}
/// <summary> /// <summary>
/// Delete a beatmap from the store. /// Delete a beatmap from the store.
/// Is a no-op for already deleted beatmaps. /// Is a no-op for already deleted beatmaps.
@ -121,7 +129,7 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapSet">The beatmap to delete.</param> /// <param name="beatmapSet">The beatmap to delete.</param>
public void Delete(BeatmapSetInfo beatmapSet) public void Delete(BeatmapSetInfo beatmapSet)
{ {
if (!Database.Delete(beatmapSet)) return; if (!beatmaps.Delete(beatmapSet)) return;
if (!beatmapSet.Protected) if (!beatmapSet.Protected)
files.Dereference(beatmapSet.Files); files.Dereference(beatmapSet.Files);
@ -134,7 +142,7 @@ namespace osu.Game.Beatmaps
/// <param name="beatmapSet">The beatmap to restore.</param> /// <param name="beatmapSet">The beatmap to restore.</param>
public void Undelete(BeatmapSetInfo beatmapSet) public void Undelete(BeatmapSetInfo beatmapSet)
{ {
if (!Database.Undelete(beatmapSet)) return; if (!beatmaps.Undelete(beatmapSet)) return;
files.Reference(beatmapSet.Files); files.Reference(beatmapSet.Files);
} }
@ -150,7 +158,7 @@ namespace osu.Game.Beatmaps
if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo) if (beatmapInfo == null || beatmapInfo == DefaultBeatmap?.BeatmapInfo)
return DefaultBeatmap; return DefaultBeatmap;
Database.Populate(beatmapInfo); beatmaps.Populate(beatmapInfo);
if (beatmapInfo.BeatmapSet == null) if (beatmapInfo.BeatmapSet == null)
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database."); throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetInfoID} is not in the local database.");
@ -170,7 +178,7 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public void Reset() public void Reset()
{ {
Database.Reset(); beatmaps.Reset();
} }
/// <summary> /// <summary>
@ -180,14 +188,43 @@ namespace osu.Game.Beatmaps
/// <returns>The first result for the provided query, or null if no results were found.</returns> /// <returns>The first result for the provided query, or null if no results were found.</returns>
public BeatmapSetInfo QueryBeatmapSet(Func<BeatmapSetInfo, bool> query) public BeatmapSetInfo QueryBeatmapSet(Func<BeatmapSetInfo, bool> query)
{ {
BeatmapSetInfo set = Database.Query<BeatmapSetInfo>().FirstOrDefault(query); BeatmapSetInfo set = beatmaps.Query<BeatmapSetInfo>().FirstOrDefault(query);
if (set != null) if (set != null)
Database.Populate(set); beatmaps.Populate(set);
return set; return set;
} }
/// <summary>
/// Perform a lookup query on available <see cref="BeatmapSetInfo"/>s.
/// </summary>
/// <param name="query">The query.</param>
/// <returns>Results from the provided query.</returns>
public List<BeatmapSetInfo> QueryBeatmapSets(Expression<Func<BeatmapSetInfo, bool>> query) => beatmaps.QueryAndPopulate(query);
/// <summary>
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
/// </summary>
/// <param name="query">The query.</param>
/// <returns>The first result for the provided query, or null if no results were found.</returns>
public BeatmapInfo QueryBeatmap(Func<BeatmapInfo, bool> query)
{
BeatmapInfo set = beatmaps.Query<BeatmapInfo>().FirstOrDefault(query);
if (set != null)
beatmaps.Populate(set);
return set;
}
/// <summary>
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
/// </summary>
/// <param name="query">The query.</param>
/// <returns>Results from the provided query.</returns>
public List<BeatmapInfo> QueryBeatmaps(Expression<Func<BeatmapInfo, bool>> query) => beatmaps.QueryAndPopulate(query);
/// <summary> /// <summary>
/// Creates an <see cref="ArchiveReader"/> from a valid storage path. /// Creates an <see cref="ArchiveReader"/> from a valid storage path.
/// </summary> /// </summary>
@ -229,11 +266,11 @@ namespace osu.Game.Beatmaps
var overallHash = hashable.GetMd5Hash(); var overallHash = hashable.GetMd5Hash();
var existing = Database.Query<BeatmapSetInfo>().FirstOrDefault(b => b.Hash == overallHash); var existing = beatmaps.Query<BeatmapSetInfo>().FirstOrDefault(b => b.Hash == overallHash);
if (existing != null) if (existing != null)
{ {
Database.Populate(existing); beatmaps.Populate(existing);
Undelete(existing); Undelete(existing);
return existing; return existing;
} }
@ -278,5 +315,18 @@ namespace osu.Game.Beatmaps
return beatmapSet; return beatmapSet;
} }
/// <summary>
/// Returns a list of all usable <see cref="BeatmapSetInfo"/>s.
/// </summary>
/// <param name="populate">Whether returned objects should be pre-populated with all data.</param>
/// <returns>A list of available <see cref="BeatmapSetInfo"/>.</returns>
public List<BeatmapSetInfo> GetAllUsableBeatmapSets(bool populate = true)
{
if (populate)
return beatmaps.QueryAndPopulate<BeatmapSetInfo>(b => !b.DeletePending).ToList();
else
return beatmaps.Query<BeatmapSetInfo>(b => !b.DeletePending).ToList();
}
} }
} }

View File

@ -77,8 +77,9 @@ namespace osu.Game.Overlays.Music
}, },
}; };
list.BeatmapSets = BeatmapSets = beatmaps.Database.QueryAndPopulate<BeatmapSetInfo>(b => !b.DeletePending).ToList(); list.BeatmapSets = BeatmapSets = beatmaps.GetAllUsableBeatmapSets();
// todo: these should probably be above the query.
beatmaps.BeatmapSetAdded += s => list.AddBeatmapSet(s); beatmaps.BeatmapSetAdded += s => list.AddBeatmapSet(s);
beatmaps.BeatmapSetRemoved += s => list.RemoveBeatmapSet(s); beatmaps.BeatmapSetRemoved += s => list.RemoveBeatmapSet(s);

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Database; using osu.Game.Database;
@ -54,7 +53,7 @@ namespace osu.Game.Rulesets.Scoring
var version = sr.ReadInt32(); var version = sr.ReadInt32();
/* score.FileChecksum = */ /* score.FileChecksum = */
var beatmapHash = sr.ReadString(); var beatmapHash = sr.ReadString();
score.Beatmap = beatmaps.Database.Query<BeatmapInfo>().FirstOrDefault(b => b.Hash == beatmapHash); score.Beatmap = beatmaps.QueryBeatmap(b => b.Hash == beatmapHash);
/* score.PlayerName = */ /* score.PlayerName = */
sr.ReadString(); sr.ReadString();
/* var localScoreChecksum = */ /* var localScoreChecksum = */

View File

@ -76,13 +76,9 @@ namespace osu.Game.Screens.Menu
if (!menuMusic) if (!menuMusic)
{ {
var query = beatmaps.Database.Query<BeatmapSetInfo>(b => !b.DeletePending); var sets = beatmaps.GetAllUsableBeatmapSets(false);
int count = query.Count(); if (sets.Count > 0)
if (count > 0) setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID);
{
setInfo = query.ElementAt(RNG.Next(0, count - 1));
beatmaps.Database.Populate(setInfo);
}
} }
if (setInfo == null) if (setInfo == null)

View File

@ -180,7 +180,7 @@ namespace osu.Game.Screens.Select
initialAddSetsTask = new CancellationTokenSource(); initialAddSetsTask = new CancellationTokenSource();
carousel.Beatmaps = store.Database.QueryAndPopulate<BeatmapSetInfo>(b => !b.DeletePending); carousel.Beatmaps = store.GetAllUsableBeatmapSets();
Beatmap.ValueChanged += beatmap_ValueChanged; Beatmap.ValueChanged += beatmap_ValueChanged;